MP3Diags-1.0.12.079/0000755000175000001440000000000012040502153012454 5ustar ciobiusersMP3Diags-1.0.12.079/mp3diags.pro0000644000175000001440000000013011200232050014670 0ustar ciobiusersSUBDIRS += src TEMPLATE = subdirs CONFIG += warn_on \ qt \ thread MP3Diags-1.0.12.079/CMakeLists.txt0000644000175000001440000000563011257151552015234 0ustar ciobiuserscmake_minimum_required(VERSION 2.6.0) # Avoid to include the CMakeLists.txt files themselves to the project to get rid # of the custom build step in Visual Studio that regenerates the project. set(CMAKE_SUPPRESS_REGENERATION TRUE) # Use relative instead of absolute paths in generated project files. set(CMAKE_USE_RELATIVE_PATHS TRUE) # Do not use whitespaces in the project name. set(name "MP3Diags") project(${name}) # Search for Qt in QTDIR first, then in C:\Qt\** (on Windows only). list(APPEND qt_glob_paths $ENV{QTDIR}) if(WIN32) file(GLOB dirs "C:/Qt/*") foreach(dir ${dirs}) if(IS_DIRECTORY ${dir}) list(APPEND qt_glob_paths ${dir}) endif() endforeach() # Search paths with higher version numbers first. list(SORT qt_glob_paths) list(REVERSE qt_glob_paths) endif() set(QT_SEARCH_PATHS ${qt_glob_paths} CACHE PATH "Paths where the Qt library is searched in.") set(CMAKE_PREFIX_PATH ${QT_SEARCH_PATHS}) # Try to find Qt, which on success provides QT_USE_FILE, which in turn provides # QT_LIBRARIES. find_package(Qt4 REQUIRED) file(GLOB_RECURSE sources "src/*.cpp") file(GLOB_RECURSE sources_h "src/*.h") file(GLOB_RECURSE sources_ui "src/*.ui") file(GLOB_RECURSE sources_qrc "src/*.qrc") # For some more info see e.g. http://qtnode.net/wiki/Qt_with_cmake qt4_wrap_cpp(sources_moc ${sources_h}) qt4_wrap_ui(sources_uic ${sources_ui}) qt4_add_resources(source_rcc ${sources_qrc}) # Enable the required Qt libraries. set(QT_USE_QTNETWORK 1) set(QT_USE_QTXML 1) include(${QT_USE_FILE}) # CMake places the ui_*.h files here. include_directories(${CMAKE_BINARY_DIR}) # Try to find Boost, probably requires BOOST_ROOT to be set. set(BOOST_SEARCH_PATHS "$ENV{BOOST_ROOT}" CACHE PATH "Paths where the Boost library is searched in.") set(ENV{BOOST_ROOT} ${BOOST_SEARCH_PATHS}) find_package(Boost REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) add_executable(${name} ${sources} ${sources_h} ${sources_moc} ${sources_uic} ${sources_qrc} ${source_rcc}) target_link_libraries(${name} ${QT_LIBRARIES} ${Boost_LIBRARIES}) if(WIN32) # We want to use the Unicode Windows API, dynamically link against Boost and suppress deprecation / security warnings. add_definitions(-D_UNICODE -DUNICODE -DBOOST_ALL_DYN_LINK -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) # Do not treat wchar_t as a built-in type (for compatibility with Qt). set_target_properties(${name} PROPERTIES COMPILE_FLAGS "/Zc:wchar_t-") # For "GetProcessMemoryInfo()". target_link_libraries(${name} psapi.lib) endif() # Hide a few variables from the CMake GUI. set(CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE INTERNAL "") set(QT_QMAKE_EXECUTABLE ${QT_QMAKE_EXECUTABLE} CACHE INTERNAL "") set(Boost_LIB_DIAGNOSTIC_DEFINITIONS ${Boost_LIB_DIAGNOSTIC_DEFINITIONS} CACHE INTERNAL "") MP3Diags-1.0.12.079/license.gplv3.txt0000644000175000001440000010360611107241715015706 0ustar ciobiusersGNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright © 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 .MP3Diags-1.0.12.079/COPYING0000644000175000001440000004313111200232050013502 0ustar ciobiusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. MP3Diags-1.0.12.079/pad_file.xml0000644000175000001440000001420312040502151014737 0ustar ciobiusers 3.10 Online PAD Generator 1.33 - http://www.padbuilder.com Portable Application Description, or PAD for short, is a data set that is used by shareware authors to disseminate information to anyone interested in their software products. To find out more go to http://www.asp-shareware.org/pad Marian Ciobanu Iasi Romania http://sourceforge.net/users/ciobi07 Marian Ciobanu ciobi@inbox.com Marian Ciobanu ciobi@inbox.com ciobi@inbox.com ciobi@inbox.com MP3 Diags 1.0.12.079 10 20 2012 Freeware Minor Update Install and Uninstall Linux,Win7 x32,Win7 x64,WinVista,WinXP English Audio Audio & Multimedia::Other N MP3, diagnosis, tag editor, tagger, normalize, repair, VBR Find and fix Problems in MP3 Files Find and fix Problems in MP3 Files Find and fix Problems in MP3 Files Find and fix Problems in MP3 Files MP3 Diags finds problems in MP3 files and helps the user to fix many of them. It looks at both the audio part (VBR info, quality, normalization) and the tags containing track information (ID3.) It has a tag editor, which can download album information (including cover art) from MusicBrainz and Discogs, as well as paste data from the clipboard. Track information can also be extracted from a file's name. Another component is the file renamer, which can rename files based on the fields in their ID3V2 tag (artist, track number, album, genre, ...) http://mp3diags.sourceforge.net/ http://mp3diags.sourceforge.net/010_getting_the_program.html http://mp3diags.sourceforge.net/004_screenshot01.html http://mp3diags.sourceforge.net/icon.png http://mp3diags.sourceforge.net/pad_file.xml http://sourceforge.net/projects/mp3diags/files/mp3diags-windows-setup/MP3DiagsSetup.exe http://sourceforge.net/projects/mp3diags/files/mp3diags-src/MP3Diags.tar.gz MP3 Diags can be freely distributed under the terms of the GNU General Public License Version 2 - http://www.gnu.org/licenses/gpl-2.0.html MP3Diags-1.0.12.079/src/0000755000175000001440000000000012040502151013241 5ustar ciobiusersMP3Diags-1.0.12.079/src/OsFile.h0000644000175000001440000002006611340210377014607 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef OsFileH #define OsFileH #include #include #define CB_LIB_CALL class FileSearcherImpl; class FileSearcher { CB_LIB_CALL FileSearcher(const FileSearcher&); FileSearcher& CB_LIB_CALL operator=(const FileSearcher&); std::auto_ptr m_pImpl; bool CB_LIB_CALL goToNextValidEntry(); // skips "." and "..", as well as any invalid item (usually file that has been removed after entryInfoList() got called) std::string m_strDir; public: CB_LIB_CALL FileSearcher(); CB_LIB_CALL FileSearcher(const std::string& strDirName); // accepts both "/"-terminated and non-'/'-terminated names CB_LIB_CALL ~FileSearcher(); //ttt2 this seems bad design: getName() & Co shouldn't be callable if the search is not open std::string CB_LIB_CALL getName() const; // returns the full name found; throws if nothing found std::string CB_LIB_CALL getShortName() const; // returns the short name found; throws if nothing found //ttt2 have short/long/default (default is for "../tst/1" and is what is implemented now; long should be "/dir/tst/1") int CB_LIB_CALL getAttribs() const; //ddd maybe filter out volume attributes / or include UNIX attribs long long CB_LIB_CALL getSize() const; //long long CB_LIB_CALL getCreationTime() const; //int64FromFileDateTime(sr.sr.FindData.ftCreationTime) //ttt2 replace "long long" with a class representing time with nanosecond resolution, with conversions to what various OSs are using for various tasks long long CB_LIB_CALL getChangeTime() const; //int64FromFileDateTime(sr.sr.FindData.ftLastWriteTime), bool CB_LIB_CALL isFile() const; bool CB_LIB_CALL isDir() const; bool CB_LIB_CALL isSymLink() const; CB_LIB_CALL operator bool() const; // it's easier to use the constructor, but sometimes may be more convenient to leave the object in an outer loop bool CB_LIB_CALL findFirst(const std::string& strDirName); bool CB_LIB_CALL findNext(); void CB_LIB_CALL close(); struct InvalidOperation {}; }; // result is in UTC //TDateTime dateTimeFromFileDateTime(const FILETIME& utcFileTime); //long long int64FromFileDateTime(const FILETIME& utcFileTime); //FILETIME fileDateTimeFromint64(__int64 intTime); /*struct CantOpenFile// : public RuntimeError { // CB_LIB_CALL CantOpenFile(const char* szFileName, int nLn, const char* szFile, RuntimeError* pPrv = 0) : // RuntimeError(TMP_PARAM_CHG2, "Error opening file", "Couldn't open file " + strFileName, nLn, szFile, pPrv) {} };*/ void CB_LIB_CALL getFileInfo(const std::string& strFileName, long long& nChangeTime, long long& nSize); // throws NameNotFound // ttt2 currently doesn't really matter the format of nChangeTime, because it is only used in equality comparisons; so it uses time_t; however, this should be reviewed and probably choose nanoseconds from 01.01.1970 (QDateTime is better avoided, because of several issues, like serialization or low resolution) void CB_LIB_CALL setFileDate(const std::string& strFileName, long long nChangeTime); struct CannotCreateDir { std::string m_strDir; CannotCreateDir(const std::string& strDir) : m_strDir(strDir) {} }; // creates all intermediate dirs; throws CannotCreateDir on failure (if the directory already exists it's a success) void CB_LIB_CALL createDir(const std::string& strDirName); void CB_LIB_CALL createDirForFile(const std::string& strFileName); // creates the directory where the given file can be created std::string replaceDriveLetter(const std::string& strFileName); // does nothing on Linux; replaces "D:" with "/D" on Windows, only when "D:" isn't at the beggining of the string; // returns true if there is a file with that name; // returns false if the name doesn't exist or it's a directory; doesn't throw bool CB_LIB_CALL fileExists(const std::string& strFileName); // returns true if there is a directory with that name; // returns false if the name doesn't exist or it's a file; //ttt2 throws IncorrectDirName bool CB_LIB_CALL dirExists(const std::string& strDirName); struct IncorrectDirName {}; // invalid dir name (e.g. ends with a path separator) // throws IncorrectDirName if the name ends with a path separator void CB_LIB_CALL checkDirName(const std::string& strDirName); std::string getSepTerminatedDir(const std::string& strDirName); // adds a path separator at the end if none is present; throws IncorrectDirName on invalid file names std::string getNonSepTerminatedDir(const std::string& strDirName); // removes the path separator at the end if present; throws IncorrectDirName on invalid file names struct FoundDir {}; struct AlreadyExists {}; struct NameNotFound {}; struct CannotRenameFile {}; struct CannotCopyFile {}; // renames a file; // throws FoundDir, AlreadyExists, NameNotFound, CannotRenameFile, ?IncorrectDirName, void CB_LIB_CALL renameFile(const std::string& strOldName, const std::string& strNewName); // creates a copy a file; // doesn't preserve any attributes; // ttt2 add option // throws WriteError or EndOfFile from Helpers //ttt2 switch to: throws FoundDir, AlreadyExists, NameNotFound, CannotCopyFile, ?IncorrectDirName, void CB_LIB_CALL copyFile(const std::string& strSourceName, const std::string& strDestName /*, OverwriteOption eOverwriteOption*/); // throws FoundDir, AlreadyExists, NameNotFound, CannotCopyFile, ?IncorrectDirName, //ttt2 unify with copyFile(), or rather restructure all file operations (perhaps see what Qt has) void CB_LIB_CALL copyFile2(const std::string& strSourceName, const std::string& strDestName /*, OverwriteOption eOverwriteOption*/); // deletes a file; throws FoundDir, // CannotDeleteFile, ?IncorrectDirName; it is OK if the file didn't exist to begin with struct CannotDeleteFile {}; void CB_LIB_CALL deleteFile(const std::string& strFileName); // just a name that doesn't exist; the file won't be deleted automatically; normally the name is obtained by appending something to strMasterFileName, but a more generic temp is used if the name is too long on wnd std::string getTempFile(const std::string& strMasterFileName); std::string getParent(const std::string& strName); // the name of a parent directory; returns an empty string if no parent exists; may throw IncorrectDirName bool isInsideDir(const std::string& strName, const std::string& strDirName); // if strName is in strDirName or in one of its subdirectories; may throw IncorrectDirName for either param std::string getExistingDir(const std::string& strName); // if strName exists and is a dir, it is returned; otherwise it returns the closest ancestor that exists; accepts names ending with file separator #endif // #ifndef OsFileH MP3Diags-1.0.12.079/src/AlbumInfoDownloaderDlgImpl.h0000644000175000001440000002043511265042521020572 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef AlbumInfoDownloaderDlgImplH #define AlbumInfoDownloaderDlgImplH #include #include #include #include "ui_AlbumInfoDownloader.h" #include "CommonTypes.h" class QHttp; class QPixmap; class SessionSettings; struct WebAlbumInfoBase { WebAlbumInfoBase() : m_eVarArtists(AlbumInfo::VA_NOT_SUPP) {} virtual ~WebAlbumInfoBase() {} std::string m_strTitle; std::string m_strArtist; std::string m_strReleased; std::vector m_vTracks; // make sure they come in proper order std::vector m_vstrImageNames; // for Discogs - IDs; for MusicBrainz - full URLs std::string m_strFormat; // CD, tape, ... std::vector m_vpImages; // doesn't own the pointers; initially it contains 0s; this isn't used by MainFormDlgImpl, only internally by AlbumInfoDownloaderDlgImpl, which passes to MainFormDlgImpl at most an image, in a separate parameter std::vector m_vstrImageInfo; // size in pixels and bytes AlbumInfo::VarArtists m_eVarArtists; virtual void copyTo(AlbumInfo& dest) = 0; }; class QXmlDefaultHandler; class WebDwnldModel; // at any time there's at most 1 HTTP request pending // //class AlbumInfoDownloaderDlgImpl : public QDialog, private Ui::AlbumInfoDownloaderDlg class AlbumInfoDownloaderDlgImpl : public QDialog, protected Ui::AlbumInfoDownloaderDlg { Q_OBJECT void next(); // meant to be called only by retryNavigation() void previous(); bool m_bSaveResults; int m_nLastCount; time_t m_nLastTime; std::string getTempName(); // time-based, with no extension; doesn't check for existing names, but uses a counter, so files shouldn't get removed (except during daylight saving time changes) void saveDownloadedData(const char*, int nSize, const char* szExt); virtual char getReplacementChar() const = 0; protected: bool m_bSaveImageOnly; // for Discogs: pages have 20 entries (except for the last page), but among the entries there are artists, which should be ignored; // for MusicBrainz there's only 1 page; int m_nTotalPages, m_nLastLoadedPage; std::vector m_vpImages; // owns the pointers int m_nLoadingAlbum, m_nLoadingImage; ImageInfo::Compr m_eLoadingImageCompr; // for Discogs: e.g. http://www.discogs.com/search?type=all&q=beatles&f=xml, without page number; to be used by loadNextPage(); // for MusicBrainz it's a fixed, full, query; std::string m_strQuery; int m_nCrtAlbum, m_nCrtImage; //std::string m_strArtist; //std::string m_strAlbum; enum NavigDir { NONE, NEXT, PREV }; // navigation direction enum Waiting { NOTHING, IMAGE, SEARCH, ALBUM }; NavigDir m_eNavigDir; Waiting m_eWaiting; void setWaiting(Waiting eWaiting); bool m_bNavigateByAlbum; virtual std::string createQuery() = 0; void search(); virtual void loadNextPage() = 0; virtual void requestAlbum(int nAlbum) = 0; virtual void requestImage(int nAlbum, int nImage) = 0; virtual void reloadGui(); void onSearchLoaded(const QString& qstrXml); void onAlbumLoaded(const QString& qstrXml); void onImageLoaded(const QByteArray& comprImg, int nWidth, int nHeight, const QString& qstrInfo); // pPixmap may not be 0 void retryNavigation(); virtual bool initSearch(const std::string& strArtist, const std::string& strAlbum) = 0; static std::string removeParentheses(const std::string& s); void addNote(const char* szNote); void setImageType(const std::string& strName); virtual QHttp* getWaitingHttp() = 0; // the one QHttp object waiting for a reply; virtual void resetNavigation(); // clears pending HTTP requests, m_eNavigDir and m_eWaiting; restores the cursor if needed; virtual WebAlbumInfoBase& album(int i) = 0; virtual int getAlbumCount() const = 0; virtual QXmlDefaultHandler* getSearchXmlHandler() = 0; virtual QXmlDefaultHandler* getAlbumXmlHandler(int nAlbum) = 0; void updateTrackList(); virtual void saveSize() = 0; std::string replaceSymbols(std::string); // replaces everything besides letters and digits with getReplacementChar() WebDwnldModel* m_pModel; SessionSettings& m_settings; protected: QHttp* m_pQHttp; int m_nExpectedTracks; AlbumInfoDownloaderDlgImpl(QWidget* pParent, SessionSettings& settings, bool bSaveResults); static const char* NOT_FOUND_AT_AMAZON; public: ~AlbumInfoDownloaderDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ // pAlbumInfo is non-0 upon exit iff the return is true and the user closed with "Save All"; // pQPixmap is non-0 upon exit iff the return is true and there is a picture; // the pointers must be deallocated by the caller; // pAlbumInfo->m_imageInfo is not set; (the caller manually links the result returned in pImageInfo) // for Discogs: the other fields are set; // for MusicBrainz: pAlbumInfo->m_strComposer and pAlbumInfo->m_strNotes are not set; (they are not available) bool getInfo(const std::string& strArtist, const std::string& strAlbum, int nTrackCount, AlbumInfo*& pAlbumInfo, ImageInfo*& pImageInfo); virtual const WebAlbumInfoBase* getCrtAlbum() const = 0; // returns 0 if there's no album virtual int getColumnCount() const = 0; // really just for composer; 4 if the field exists and 4 if it doesn't; public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pPrevB_clicked(); void on_m_pNextB_clicked(); void on_m_pPrevAlbumB_clicked(); void on_m_pNextAlbumB_clicked(); void on_m_pSaveAllB_clicked(); void on_m_pSaveImageB_clicked(); void on_m_pCancelB_clicked(); //void onDone(bool bError); void onRequestFinished(int nId, bool bError); void onHelp(); private: }; void addIfMissing(std::string& strDest, const std::string& strSrc); // splits a string based on a separator, putting the components in a vector; trims the substrings; discards empty components; void split(const std::string& s, const std::string& sep, std::vector& v); //ttt2 move to Helpers, improve interface ... void addList(std::string& strDest, const std::string& strSrc); class WebDwnldModel : public QAbstractTableModel { Q_OBJECT AlbumInfoDownloaderDlgImpl& m_dwnld; QTableView& m_grid; //typedef Discogs::DiscogsAlbumInfo AlbumInfo; public: WebDwnldModel(AlbumInfoDownloaderDlgImpl&, QTableView&); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int nRole) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; void emitLayoutChanged() { emit layoutChanged(); } }; #endif // #ifndef AlbumInfoDownloaderDlgImplH MP3Diags-1.0.12.079/src/Id3V240Stream.cpp0000644000175000001440000005146611477013534016147 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "Id3V240Stream.h" #include "Helpers.h" using namespace std; using namespace pearl; //============================================================================================================ //============================================================================================================ //============================================================================================================ // !!! Note that the exceptions thrown by Id3V240Frame::Id3V240Frame() pass through Id3V240Stream, so they should have a type suited for this situation. // Also note that by the time Id3V240Frame::Id3V240Frame() gets executed, it was already decided that we deal with an Id3V240Stream. Now we should see if it is valid or broken. // since broken applications may use all 8 bits for size, although only 7 should be used, this tries to figure out if the size is correct bool Id3V240Frame::checkSize(istream& in, streampos posNext) { streampos pos (m_pos); pos += m_nDiskDataSize + m_nDiskHdrSize; if (pos > posNext) { return false; } if (pos == posNext) { return true; } in.seekg(pos); char bfr [ID3_FRAME_HDR_SIZE]; int nHdrBytesSkipped (0); int nRead (readID3V2(m_bHasUnsynch, in, bfr, ID3_FRAME_HDR_SIZE, posNext, nHdrBytesSkipped)); in.clear(); if (nRead < ID3_FRAME_HDR_SIZE) { // should be padding, which is always 0 for (int i = 0; i < nRead; ++i) { if (0 != bfr[i]) { return false; } } return true; } // check for frames: uppercase letters and digits for (int i = 0; i < 4; ++i) { char c (bfr[i]); if ((c < 'A' || c > 'Z') && (c < '0' || c > '9')) //ttt3 ASCII-specific { if (0 != c) { return false; } goto tryPadding; } } return true; // another frame seems to follow tryPadding: in.seekg(pos); int nSize (posNext - pos); char* a (new char[nSize]); ArrayPtrRelease rel (a); nRead = readID3V2(m_bHasUnsynch, in, a, nSize, posNext, nHdrBytesSkipped); in.clear(); if (nRead != nSize) { return false; } for (int i = 0; i < nRead; ++i) { if (0 != a[i]) { return false; } } return true; } /*override*/ int Id3V240Frame::getOffset() const { return 0 != (m_cFlag2 & 0x01) ? 4 : 0; // not quite OK if the flag is set but the frame is only several bytes, but that was invalid to begin with; anyway, it doesn't mess up loading from disk, since none is needed for such short frames } void Id3V240Frame::load(NoteColl& notes, istream& in, streampos posNext, bool bHasUnsynch) { StreamStateRestorer rst (in); if (m_nDiskDataSize < 0) { return; } if (m_nDiskDataSize > 5000000) { return; } // there are probably no frames over 5MB vector v (m_nDiskDataSize); m_vcData.clear(); //int nContentBytesSkipped (0); int nRead (read(in, &v[0], m_nDiskDataSize)); //readID3V2(bHasUnsynch, in, &v[0], m_nMemDataSize1 w, posNext, nContentBytesSkipped)); //m_nDiskDataSize1 = q m_nMemDataSize1 + nContentBytesSkipped; if (m_nDiskDataSize != nRead || !checkSize(in, posNext)) { return; } rst.setOk(); if (bHasUnsynch && !v.empty()) { for (int i = 0; i < cSize(v); ++i) { m_vcData.push_back(v[i]); if (char(0xff) == v[i] && i < cSize(v) - 1 && 0 == v[i + 1]) // !!! it's OK to run this on the Data length indicator, because it doesn't contain any 0xff { ++i; } } } else { v.swap(m_vcData); } m_nMemDataSize = cSize(m_vcData); if (getOffset() > 0 && m_nMemDataSize > 3) { // Data length indicator unsigned char* p (reinterpret_cast (&m_vcData[0])); //inspect(p, 50); int nDli ((p[0] << 21) + (p[1] << 14) + (p[2] << 7) + (p[3] << 0)); if (nDli != m_nMemDataSize - 4) { MP3_NOTE (m_pos, id3v240IncorrectDli); //ttt2 probably adjust m_nMemDataSize anyway; after all, the Data length indicator flag is still there } else { m_nMemDataSize -= 4; m_vcData.erase(m_vcData.begin(), m_vcData.begin() + 4); } } } void Id3V240Frame::load(NoteColl& notes, istream& in, streampos posNext) { load(notes, in, posNext, m_bHasUnsynch); if (-1 == m_nMemDataSize) { load(notes, in, posNext, !m_bHasUnsynch); if (-1 != m_nMemDataSize) { m_bHasUnsynch = !m_bHasUnsynch; MP3_NOTE (m_pos, id3v240IncorrectFrameSynch); } } } Id3V240Frame::Id3V240Frame(NoteColl& notes, istream& in, streampos pos, bool bHasUnsynch, streampos posNext, StringWrp* pFileName) : Id3V2Frame(pos, bHasUnsynch, pFileName) { in.seekg(pos); char bfr [ID3_FRAME_HDR_SIZE]; int nHdrBytesSkipped (0); int nRead (readID3V2(bHasUnsynch/*false*/, in, bfr, ID3_FRAME_HDR_SIZE, posNext, nHdrBytesSkipped)); MP3_CHECK (ID3_FRAME_HDR_SIZE == nRead || (nRead >= 1 && 0 == bfr[0]), pos, id3v2FrameTooShort, StreamIsBroken(Id3V240Stream::getClassDisplayName(), "Truncated ID3V2.4.0 tag.")); // in 2.4.0 bHasUnsynch shouldn't matter, because the frame header doesn't need unsynch; but unconforming apps use 8 bits for size, as opposed to 7, as they are supposed to unsigned char* p (reinterpret_cast (bfr)); if (0 == bfr[0]) { // padding //m_nMemDataSize = -1; // !!! not needed; the constructor makes it -1 //m_nDiskDataSize = -1; // !!! not needed; the constructor makes it -1 m_szName[0] = 0; return; } m_nDiskHdrSize = ID3_FRAME_HDR_SIZE + nHdrBytesSkipped; //inspect(bfr, ID3_FRAME_HDR_SIZE); strncpy(m_szName, bfr, 4); m_szName[4] = 0; { char c (m_szName[0]); MP3_CHECK (c >= 'A' && c <= 'Z', pos, id3v2InvalidName, StreamIsBroken(Id3V240Stream::getClassDisplayName(), "ID3V2.4.0 tag containing a frame with an invalid name: " + getReadableName() + ".")); for (int i = 1; i < 4; ++i) { char c (m_szName[i]); MP3_CHECK ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'), pos, id3v2InvalidName, StreamIsBroken(Id3V240Stream::getClassDisplayName(), "ID3V2.4.0 tag containing a frame with an invalid name: " + getReadableName() + ".")); //ttt3 ASCII-specific } } m_cFlag1 = bfr[8]; m_cFlag2 = bfr[9]; //inspect(bfr); MP3_CHECK (0 == (m_cFlag1 & ~0x60), pos, id3v2UnsuppFlags1, StreamIsUnsupported(Id3V240Stream::getClassDisplayName(), "ID3V2.4.0 tag containing a frame with an unsupported flag.")); // ignores "Tag alter preservation" and "File alter preservation" // ttt2 use them MP3_CHECK (0 == (m_cFlag2 & ~0x03), pos, id3v2UnsuppFlags2, StreamIsUnsupported(Id3V240Stream::getClassDisplayName(), "ID3V2.4.0 tag containing a frame with an unsupported flag.")); m_bHasUnsynch = (0 != (m_cFlag2 & ~0x02)); //m_bHasUnsynch = false; if (0 != (m_cFlag1 & 0x8f)) { MP3_NOTE (pos, id3v2IncorrectFlg1); } if (0 != (m_cFlag2 & 0xb0)) { MP3_NOTE (pos, id3v2IncorrectFlg2); } if (0 == (p[4] & 0x80) && 0 == (p[5] & 0x80) && 0 == (p[6] & 0x80) && 0 == (p[7] & 0x80)) { // by the specs it should be 7 bit unsynch m_nDiskDataSize = (p[4] << 21) + (p[5] << 14) + (p[6] << 7) + (p[7] << 0); load(notes, in, posNext); } if (-1 == m_nMemDataSize) { // failed to load as 7bit unsynch, so try 8bit m_nDiskDataSize = (p[4] << 24) + (p[5] << 16) + (p[6] << 8) + (p[7] << 0); load(notes, in, posNext); if (-1 == m_nMemDataSize) { MP3_THROW (pos, id3v240CantReadFrame, StreamIsBroken(Id3V240Stream::getClassDisplayName(), "Broken ID3V2.4.0 tag.")); } else { MP3_NOTE (pos, id3v240IncorrectSynch); } } try { try { getUtf8String(); if ('T' == m_szName[0]) { if (!isTxxx() && 0 == m_nMemDataSize) { // this is really invalid; text frames must have at least a byte; however, by doing these we make sure that an empty (i.e. having a single byte, for text encoding) frame gets copied if the tag is edited; m_vcData.clear(); m_vcData.push_back(0); m_nMemDataSize = cSize(m_vcData); MP3_NOTE_D (pos, id3v2EmptyTextFrame, Notes::id3v2EmptyTextFrame().getDescription() + string(" (Frame:") + m_szName + ")"); } else if (isTxxx() && m_nMemDataSize <= 1) { // this is really invalid; text frames must have at least a byte; however, by doing these we make sure that an empty (i.e. having a single byte, for text encoding) frame gets copied if the tag is edited; m_vcData.clear(); static const char* szInvalid ("INVALID"); m_vcData.push_back(0); // latin1 m_vcData.insert(m_vcData.end(), szInvalid, szInvalid + strlen(szInvalid)); // description m_vcData.push_back(0); // terminator m_vcData.insert(m_vcData.end(), szInvalid, szInvalid + strlen(szInvalid)); // value m_nMemDataSize = cSize(m_vcData); MP3_NOTE_D (pos, id3v2EmptyTextFrame, Notes::id3v2EmptyTextFrame().getDescription() + string(" (Frame:") + m_szName + ")"); // ttt2 actually TXXX is not text } //ttt2 add check for terminating 0 for TXXX, to split the value into descr and val } } catch (const NotId3V2Frame&) { MP3_THROW (pos, id3v2TextError, StreamIsBroken(Id3V240Stream::getClassDisplayName(), "ID3V2.4.0 tag containing a broken text frame named " + getReadableName() + ".")); } catch (const UnsupportedId3V2Frame&) { MP3_THROW (pos, id3v240UnsuppText, StreamIsUnsupported(Id3V240Stream::getClassDisplayName(), "ID3V2.4.0 tag containing a text frame named " + getReadableName() + " using unsupported characters or unsupported text encoding.")); //ttt2 not specific enough; this might need reviewing in the future } } catch (const std::bad_alloc&) { throw; } catch (...) { throw; } if (m_nMemDataSize > 150) // ttt2 perhaps make configurable { // if the frame needs a lot of space, erase the data from memory; it will be retrieved from the disk when needed; vector().swap(m_vcData); } } // may return multiple null characters; it's the job of getUtf8String() to deal with them; // chars after the first null are considered comments (or after the second null, for TXXX), so the nulls are replaced with commas, except for those at the end of the string (which are removed) and the first null in TXXX; string Id3V240Frame::getUtf8StringImpl() const { if ('T' != m_szName[0]) { return ""; } // have a "pos" to pass here and ability to log; could also be used for large tags, to not store them in memory yet have them available // also use pos below // or perhaps forget these and throw exceptions that have error messages, catch them and log/show dialogs // 2008.07.12 - actually all these proposals don't seem to work well: the callers don't catch the exceptions thrown here and wouldn't know what to do with them; there's no good place to display the errors (the end user isn't supposed to look at logs); it seems better to not throw, but return a string describing the problem; // 2008.07.12 - on a second thought - throw but call this on the constructor, where it can be logged properly; if it worked on the constructor it should work later too CB_CHECK1 (m_nMemDataSize > 0, NotId3V2Frame()); Id3V2FrameDataLoader wrp (*this); const char* pData (wrp.getData()); //ttt2 from http://www.id3.org/id3v2.4.0-frames - All text information frames supports multiple strings, stored as a null separated list string s; if (0 == pData[0]) { // Latin-1 for (int i = 1; i < m_nMemDataSize; ++i) { unsigned char c (pData[i]); if (c < 128) { // !!! 0 is OK s += char(c); } else { m_bHasLatin1NonAscii = true; unsigned char c1 (0xc0 | (c >> 6)); unsigned char c2 (0x80 | (c & 0x3f)); s += char(c1); s += char(c2); } } } else if (1 == pData[0]) { s = utf8FromBomUtf16(pData + 1, m_nMemDataSize - 1); } else if (3 == pData[0]) { s = string(pData + 1, m_nMemDataSize - 1); } else { if (2 == pData[0]) { CB_THROW1 (UnsupportedId3V2Frame()); //ttt2 add support for UTF-16BE (2 = "UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM"); } CB_THROW1 (NotId3V2Frame()); } { // deal with nulls int k (0); if (isTxxx()) { for (; k < cSize(s) && 0 != s[k]; ++k) {} ++k; } int i (cSize(s) - 1); for (; i >= k && 0 == s[i]; --i) { s.erase(i); } for (; i >= k; --i) { if (0 == s[i]) { //s.replace(i, 1, i > k ? ", " : ""); s.replace(i, 1, ", "); } } } return s; } /*override*/ bool Id3V240Frame::discardOnChange() const { return 0 != (m_cFlag1 & 0x60); } //============================================================================================================ //============================================================================================================ //============================================================================================================ Id3V240Stream::Id3V240Stream(int nIndex, NoteColl& notes, istream& in, StringWrp* pFileName, bool bAcceptBroken /*= false*/) : Id3V2StreamBase(nIndex, in, pFileName) { StreamStateRestorer rst (in); streampos pos (m_pos); char bfr [ID3_HDR_SIZE]; MP3_CHECK_T (ID3_HDR_SIZE == read(in, bfr, ID3_HDR_SIZE), pos, "Invalid ID3V2.4.0 tag. File too small.", NotId3V2()); MP3_CHECK_T ('I' == bfr[0] && 'D' == bfr[1] && '3' == bfr[2], pos, "Invalid ID3V2.4.0 tag. Invalid ID3V2 header.", NotId3V2()); MP3_CHECK_T (4 == bfr[3] && 0 == bfr[4], pos, "Invalid ID3V2.4.0 tag. Invalid ID3V2.4.0 header.", NotId3V2()); m_nTotalSize = getId3V2Size (bfr); m_cFlags = bfr[5]; MP3_CHECK (0 == (m_cFlags & 0x7f), pos, id3v2UnsuppFlag, StreamIsUnsupported(Id3V240Stream::getClassDisplayName(), "ID3V2 tag with unsupported flag.")); //ttt2 review, support streampos posNext (pos); posNext += m_nTotalSize; pos += ID3_HDR_SIZE; bool bHasLatin1NonAscii (false); // if it has a text frame that uses Latin1 encoding and has chars between 128 and 255 try { for (;;) { long long nDiff (pos - posNext); if (nDiff >= 0) { break; } Id3V240Frame* p (new Id3V240Frame(notes, in, pos, hasUnsynch(), posNext, m_pFileName)); bHasLatin1NonAscii = bHasLatin1NonAscii || p->m_bHasLatin1NonAscii; if (-1 == p->m_nMemDataSize) { // it encountered zeroes, which signals the beginning of padding //ttt2 should check that there's no garbage after the first zero m_nPaddingSize = posNext - pos; delete p; break; } m_vpFrames.push_back(p); pos += p->m_nDiskHdrSize + p->m_nDiskDataSize; } } catch (const std::bad_alloc&) { throw; } catch (...) { if (bAcceptBroken) { return; } clearPtrContainer(m_vpFrames); throw; } checkDuplicates(notes); checkFrames(notes); if (bHasLatin1NonAscii) { MP3_NOTE (m_pos, id3v2HasLatin1NonAscii); } if (0 != findFrame(KnownFrames::LBL_TIME_YEAR_230())) { if (0 != findFrame(KnownFrames::LBL_TIME_240())) { MP3_NOTE (m_pos, id3v240DeprTyerAndTdrc); // ttt2 check consistency among TYER and TDRC } else { MP3_NOTE (m_pos, id3v240DeprTyer); } } if (0 != findFrame(KnownFrames::LBL_TIME_DATE_230())) { if (0 != findFrame(KnownFrames::LBL_TIME_240())) { MP3_NOTE (m_pos, id3v240DeprTdatAndTdrc); // ttt2 check consistency among TDAT and TDRC } else { MP3_NOTE (m_pos, id3v240DeprTdat); } } preparePicture(notes); switch (m_eImageStatus) { case ImageInfo::NO_PICTURE_FOUND: MP3_NOTE (m_pos, id3v2NoApic); break; case ImageInfo::ERROR_LOADING: MP3_NOTE (m_pos, id3v2CouldntLoadPic); break; //case ImageInfo::USES_LINK: MP3_NOTE (m_pos, id3v2LinkNotSupported); break; // !!! already reported by id3v2LinkInApic, so no need for another note; case ImageInfo::LOADED_NOT_COVER: MP3_NOTE (m_pos, id3v2NotCoverPicture); break; default:; } if (m_vpFrames.empty()) { MP3_NOTE (m_pos, id3v2EmptyTag); } MP3_TRACE (m_pos, "Id3V240Stream built."); { pos = m_pos; pos += m_nTotalSize - 1; in.seekg(pos); char c; MP3_CHECK (1 == read(in, &c, 1), m_pos, id3v240CantReadFrame, NotId3V2()); } rst.setOk(); } /*override*/ TagReader::SuportLevel Id3V240Stream::getSupport(Feature eFeature) const { switch (eFeature) { case TITLE: case ARTIST: case TRACK_NUMBER: case TIME: case GENRE: case IMAGE: case ALBUM: case RATING: case COMPOSER: case VARIOUS_ARTISTS: return READ_ONLY; default: return NOT_SUPPORTED; } /*{ , , , , , , , }; enum SuportLevel { NOT_SUPPORTED, , READ_WRITE };*/ } /*override*/ TagTimestamp Id3V240Stream::getTime(bool* pbFrameExists /*= 0*/) const { //const Id3V240Frame* p (findFrame(KnownFrames::LBL_TIME_YEAR_230())); const Id3V2Frame* p (findFrame(KnownFrames::LBL_TIME_240())); if (0 != p) { try { TagTimestamp t (p->getUtf8String()); if (0 != pbFrameExists) { *pbFrameExists = true; } return t; } catch (const TagTimestamp::InvalidTime&) { // !!! nothing } } return get230TrackTime(pbFrameExists); } /* http://www.id3.org/id3v2.4.0-structure : The timestamp fields are based on a subset of ISO 8601. When being as precise as possible the format of a time string is yyyy-MM-ddTHH:mm:ss (year, "-", month, "-", day, "T", hour (out of 24), ":", minutes, ":", seconds), but the precision may be reduced by removing as many time indicators as wanted. Hence valid timestamps are yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddTHH, yyyy-MM-ddTHH:mm and yyyy-MM-ddTHH:mm:ss. All time stamps are UTC. For durations, use the slash character as described in 8601, and for multiple non- contiguous dates, use multiple strings, if allowed by the frame definition. */ //============================================================================================================ //============================================================================================================ //============================================================================================================ //ttt2 Banana%20Erectors%20-%20Disagreeable%20Sensation.mp3 - unsupported flag MP3Diags-1.0.12.079/src/src.pro0000644000175000001440000000554111506601715014573 0ustar ciobiusersSOURCES += \ Helpers.cpp \ main.cpp \ DiscogsDownloader.cpp \ DoubleList.cpp \ FileEnum.cpp \ FileRenamerDlgImpl.cpp \ FilesModel.cpp \ Id3Transf.cpp \ Id3V230Stream.cpp \ Id3V240Stream.cpp \ Id3V2Stream.cpp \ ImageInfoPanelWdgImpl.cpp \ LogModel.cpp \ LyricsStream.cpp \ MainFormDlgImpl.cpp \ Mp3Manip.cpp \ Mp3TransformThread.cpp \ MpegFrame.cpp \ MpegStream.cpp \ MultiLineTvDelegate.cpp \ MusicBrainzDownloader.cpp \ NormalizeDlgImpl.cpp \ NoteFilterDlgImpl.cpp \ Notes.cpp \ NotesModel.cpp \ OsFile.cpp \ PaletteDlgImpl.cpp \ RenamerPatternsDlgImpl.cpp \ ScanDlgImpl.cpp \ SessionEditorDlgImpl.cpp \ SessionsDlgImpl.cpp \ SongInfoParser.cpp \ StoredSettings.cpp \ StreamsModel.cpp \ StructuralTransformation.cpp \ TagEditorDlgImpl.cpp \ TagEdtPatternsDlgImpl.cpp \ TagReadPanel.cpp \ TagWriter.cpp \ ThreadRunnerDlgImpl.cpp \ Transformation.cpp \ UniqueNotesModel.cpp \ Widgets.cpp \ AboutDlgImpl.cpp \ AlbumInfoDownloaderDlgImpl.cpp \ ApeStream.cpp \ CheckedDir.cpp \ ColumnResizer.cpp \ CommonData.cpp \ CommonTypes.cpp \ ConfigDlgImpl.cpp \ DataStream.cpp \ DebugDlgImpl.cpp \ DirFilterDlgImpl.cpp \ Version.cpp \ fstream_unicode.cpp \ ExportDlgImpl.cpp \ SerSupport.cpp \ FullSizeImgDlg.cpp TEMPLATE = app CONFIG += warn_on \ thread \ qt \ debug_and_release TARGET = MP3Diags DESTDIR = ../bin QT += xml \ network RESOURCES += Mp3Diags.qrc HEADERS += AboutDlgImpl.h \ AlbumInfoDownloaderDlgImpl.h \ ApeStream.h \ CheckedDir.h \ ColumnResizer.h \ CommonData.h \ CommonTypes.h \ ConfigDlgImpl.h \ DataStream.h \ DebugDlgImpl.h \ DirFilterDlgImpl.h \ DiscogsDownloader.h \ DoubleList.h \ FileEnum.h \ FileRenamerDlgImpl.h \ FilesModel.h \ Helpers.h \ Id3Transf.h \ Id3V230Stream.h \ Id3V240Stream.h \ Id3V2Stream.h \ ImageInfoPanelWdgImpl.h \ LogModel.h \ LyricsStream.h \ MainFormDlgImpl.h \ Mp3Manip.h \ Mp3TransformThread.h \ MpegFrame.h \ MpegStream.h \ MultiLineTvDelegate.h \ MusicBrainzDownloader.h \ NormalizeDlgImpl.h \ NoteFilterDlgImpl.h \ Notes.h \ NotesModel.h \ OsFile.h \ PaletteDlgImpl.h \ RenamerPatternsDlgImpl.h \ ScanDlgImpl.h \ SerSupport.h \ SessionEditorDlgImpl.h \ SessionsDlgImpl.h \ SimpleSaxHandler.h \ SongInfoParser.h \ StoredSettings.h \ StreamsModel.h \ StructuralTransformation.h \ TagEditorDlgImpl.h \ TagEdtPatternsDlgImpl.h \ TagReadPanel.h \ TagWriter.h \ ThreadRunnerDlgImpl.h \ Transformation.h \ UniqueNotesModel.h \ Widgets.h \ fstream_unicode.h \ ExportDlgImpl.h \ FullSizeImgDlg.h FORMS += About.ui \ AlbumInfoDownloader.ui \ Config.ui \ Debug.ui \ DirFilter.ui \ DoubleListWdg.ui \ FileRenamer.ui \ ImageInfoPanel.ui \ MainForm.ui \ Normalize.ui \ NoteFilter.ui \ Palette.ui \ Patterns.ui \ Scan.ui \ SessionEditor.ui \ Sessions.ui \ TagEditor.ui \ ThreadRunner.ui \ Export.ui #CONFIG += console #DEFINES += DISABLE_CHECK_FOR_UPDATES LIBS += -lz \ -lboost_serialization-mt MP3Diags-1.0.12.079/src/StoredSettings.cpp0000644000175000001440000003624311267261014016750 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "StoredSettings.h" #include "Helpers.h" using namespace std; //================================================================================================================================================ //================================================================================================================================================ //================================================================================================================================================ SessionSettings::SessionSettings(const string& strIniFile) { m_pSettings = new QSettings(convStr(strIniFile), QSettings::IniFormat); } SessionSettings::~SessionSettings() { delete m_pSettings; } void SessionSettings::saveDirs(const vector& vstrIncludedDirs, const vector& vstrExcludedDirs) { saveVector("folders/included", vstrIncludedDirs); saveVector("folders/excluded", vstrExcludedDirs); } // returns false if there were inconsistencies in the settings bool SessionSettings::loadDirs(vector& vstrIncludedDirs, vector& vstrExcludedDirs) const { bool bRes1 (true), bRes2 (true); { vector v; vstrIncludedDirs = loadVector("folders/included", bRes1); for (int i = 0, n = cSize(vstrIncludedDirs); i < n; ++i) { string s (vstrIncludedDirs[i]); if (QFileInfo(convStr(s)).isDir()) { v.push_back(s); } else { bRes1 = false; } } v.swap(vstrIncludedDirs); } { vector v; vstrExcludedDirs = loadVector("folders/excluded", bRes2); for (int i = 0, n = cSize(vstrExcludedDirs); i < n; ++i) { string s (vstrExcludedDirs[i]); if (QFileInfo(convStr(s)).isDir()) { v.push_back(s); } else { bRes2 = false; } } v.swap(vstrExcludedDirs); } return bRes1 && bRes2; } void SessionSettings::saveScanAtStartup(bool b) { m_pSettings->setValue("main/scanAtStartup", b); } bool SessionSettings::loadScanAtStartup() const { return m_pSettings->value("main/scanAtStartup", true).toBool(); } bool SessionSettings::sync() { m_pSettings->sync(); return QSettings::NoError == m_pSettings->status(); } //================================================================================================================================================ //================================================================================================================================================ //================================================================================================================================================ void SessionSettings::saveMainSettings(int nWidth, int nHeight, int nNotesGW0, int nNotesGW2, int nStrmsGW0, int nStrmsGW1, int nStrmsGW2, int nStrmsGW3, int nUnotesGW0, const QByteArray& stateMainSpl, const QByteArray& stateLwrSpl, int nIconSize, int nScanWidth) { m_pSettings->setValue("main/width", nWidth); m_pSettings->setValue("main/height", nHeight); m_pSettings->setValue("main/notesGWidth0", nNotesGW0); m_pSettings->setValue("main/notesGWidth2", nNotesGW2); m_pSettings->setValue("main/streamsGWidth0", nStrmsGW0); m_pSettings->setValue("main/streamsGWidth1", nStrmsGW1); m_pSettings->setValue("main/streamsGWidth2", nStrmsGW2); m_pSettings->setValue("main/streamsGWidth3", nStrmsGW3); m_pSettings->setValue("main/uniqueNotesGWidth0", nUnotesGW0); /*QList l (m_pMainSplitter->sizes()); for (QList::iterator it = l.begin(), end = l.end(); it != end; ++it) { qDebug("l %d", *it); }*/ m_pSettings->setValue("main/splitterState", stateMainSpl); m_pSettings->setValue("main/lowerSplitterState", stateLwrSpl); m_pSettings->setValue("main/iconSize", nIconSize); m_pSettings->setValue("main/scanWidth", nScanWidth); } void SessionSettings::loadMainSettings(int& nWidth, int& nHeight, int& nNotesGW0, int& nNotesGW2, int& nStrmsGW0, int& nStrmsGW1, int& nStrmsGW2, int& nStrmsGW3, int& nUnotesGW0, QByteArray& stateMainSpl, QByteArray& stateLwrSpl, int& nIconSize, int& nScanWidth) const { nWidth = m_pSettings->value("main/width").toInt(); nHeight = m_pSettings->value("main/height").toInt(); nNotesGW0 = m_pSettings->value("main/notesGWidth0").toInt(); nNotesGW2= m_pSettings->value("main/notesGWidth2").toInt(); nStrmsGW0 = m_pSettings->value("main/streamsGWidth0").toInt(); nStrmsGW1 = m_pSettings->value("main/streamsGWidth1").toInt(); nStrmsGW2 = m_pSettings->value("main/streamsGWidth2").toInt(); nStrmsGW3 = m_pSettings->value("main/streamsGWidth3").toInt(); nUnotesGW0 = m_pSettings->value("main/uniqueNotesGWidth0").toInt(); stateMainSpl = m_pSettings->value("main/splitterState").toByteArray(); stateLwrSpl = m_pSettings->value("main/lowerSplitterState").toByteArray(); nIconSize = m_pSettings->value("main/iconSize", 0).toInt(); nScanWidth = m_pSettings->value("main/scanWidth").toInt(); } void SessionSettings::saveMusicBrainzSettings(int nWidth, int nHeight) { m_pSettings->setValue("musicbrainz/width", nWidth); m_pSettings->setValue("musicbrainz/height", nHeight); } void SessionSettings::loadMusicBrainzSettings(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("musicbrainz/width").toInt(); nHeight = m_pSettings->value("musicbrainz/height").toInt(); } void SessionSettings::saveDebugSettings(int nWidth, int nHeight) { m_pSettings->setValue("debug/width", nWidth); m_pSettings->setValue("debug/height", nHeight); } void SessionSettings::loadDebugSettings(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("debug/width").toInt(); nHeight = m_pSettings->value("debug/height").toInt(); } void SessionSettings::saveExportSettings(int nWidth, int nHeight, bool bSortByShortNames, const std::string& strFile, bool bUseVisible, const std::string& strM3uRoot, const std::string& strM3uLocale) { m_pSettings->setValue("export/width", nWidth); m_pSettings->setValue("export/height", nHeight); m_pSettings->setValue("export/sortByShortNames", bSortByShortNames); m_pSettings->setValue("export/fileName", convStr(strFile)); m_pSettings->setValue("export/useVisible", bUseVisible); m_pSettings->setValue("export/m3uRoot", convStr(strM3uRoot)); m_pSettings->setValue("export/m3uLocale", convStr(strM3uLocale)); } void SessionSettings::loadExportSettings(int& nWidth, int& nHeight, bool& bSortByShortNames, std::string& strFile, bool& bUseVisible, std::string& strM3uRoot, std::string& strM3uLocale) const { nWidth = m_pSettings->value("export/width").toInt(); nHeight = m_pSettings->value("export/height").toInt(); bSortByShortNames = m_pSettings->value("export/sortByShortNames", false).toBool(); QString s; s = m_pSettings->value("export/fileName", "").toString(); strFile = convStr(s); bUseVisible = m_pSettings->value("export/useVisible", true).toBool(); s = m_pSettings->value("export/m3uRoot", "").toString(); strM3uRoot = convStr(s); s = m_pSettings->value("export/m3uLocale", "System").toString(); strM3uLocale = convStr(s); } void SessionSettings::saveDirFilterSettings(int nWidth, int nHeight) { m_pSettings->setValue("dirFilter/width", nWidth); m_pSettings->setValue("dirFilter/height", nHeight); } void SessionSettings::loadDirFilterSettings(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("dirFilter/width").toInt(); nHeight = m_pSettings->value("dirFilter/height").toInt(); } void SessionSettings::saveDiscogsSettings(int nWidth, int nHeight, int nStyleOption) { m_pSettings->setValue("discogs/width", nWidth); m_pSettings->setValue("discogs/height", nHeight); m_pSettings->setValue("discogs/styleOption", nStyleOption); } void SessionSettings::loadDiscogsSettings(int& nWidth, int& nHeight, int& nStyleOption) const { nWidth = m_pSettings->value("discogs/width").toInt(); nHeight = m_pSettings->value("discogs/height").toInt(); nStyleOption = m_pSettings->value("discogs/styleOption").toInt(); } void SessionSettings::saveRenamerSettings(int nWidth, int nHeight, int nSaButton, int nVaButton, bool bKeepOrig, bool bUnratedAsDuplicate) { m_pSettings->setValue("fileRenamer/width", nWidth); m_pSettings->setValue("fileRenamer/height", nHeight); m_pSettings->setValue("fileRenamer/saButton", nSaButton); m_pSettings->setValue("fileRenamer/vaButton", nVaButton); m_pSettings->setValue("fileRenamer/keepOriginal", bKeepOrig); m_pSettings->setValue("fileRenamer/unratedAsDuplicate", bUnratedAsDuplicate); } void SessionSettings::loadRenamerSettings(int& nWidth, int& nHeight, int& nSaButton, int& nVaButton, bool& bKeepOrig, bool& bUnratedAsDuplicate) const { nWidth = m_pSettings->value("fileRenamer/width").toInt(); nHeight = m_pSettings->value("fileRenamer/height").toInt(); nSaButton = m_pSettings->value("fileRenamer/saButton").toInt(); nVaButton = m_pSettings->value("fileRenamer/vaButton").toInt(); bKeepOrig = m_pSettings->value("fileRenamer/keepOriginal", false).toBool(); bUnratedAsDuplicate = m_pSettings->value("fileRenamer/unratedAsDuplicate", false).toBool(); } void SessionSettings::saveNormalizeSettings(int nWidth, int nHeight) { m_pSettings->setValue("normalizer/width", nWidth); m_pSettings->setValue("normalizer/height", nHeight); } void SessionSettings::loadNormalizeSettings(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("normalizer/width").toInt(); nHeight = m_pSettings->value("normalizer/height").toInt(); } void SessionSettings::saveNoteFilterSettings(int nWidth, int nHeight) { m_pSettings->setValue("noteFilter/width", nWidth); m_pSettings->setValue("noteFilter/height", nHeight); } void SessionSettings::loadNoteFilterSettings(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("noteFilter/width").toInt(); nHeight = m_pSettings->value("noteFilter/height").toInt(); } void SessionSettings::saveRenamerPatternsSettings(int nWidth, int nHeight) { m_pSettings->setValue("fileRenamer/patterns/width", nWidth); m_pSettings->setValue("fileRenamer/patterns/height", nHeight); } void SessionSettings::loadRenamerPatternsSettings(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("fileRenamer/patterns/width").toInt(); nHeight = m_pSettings->value("fileRenamer/patterns/height").toInt(); } void SessionSettings::saveTagEdtSettings(int nWidth, int nHeight, int nArtistsCase, int nOthersCase) { m_pSettings->setValue("tagEditor/width", nWidth); m_pSettings->setValue("tagEditor/height", nHeight); m_pSettings->setValue("tagEditor/artistsCase", nArtistsCase); m_pSettings->setValue("tagEditor/othersCase", nOthersCase); } void SessionSettings::loadTagEdtSettings(int& nWidth, int& nHeight, int& nArtistCase, int& nOthersCase) const { nWidth = m_pSettings->value("tagEditor/width").toInt(); nHeight = m_pSettings->value("tagEditor/height").toInt(); nArtistCase = m_pSettings->value("tagEditor/artistsCase", -1).toInt(); nOthersCase = m_pSettings->value("tagEditor/othersCase", -1).toInt(); //splitterState = m_pSettings->value("tagEditor/splitterState").toByteArray(); } void SessionSettings::saveTagEdtPatternsSettings(int nWidth, int nHeight) { m_pSettings->setValue("tagEditor/patterns/width", nWidth); m_pSettings->setValue("tagEditor/patterns/height", nHeight); } void SessionSettings::loadTagEdtPatternsSettings(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("tagEditor/patterns/width").toInt(); nHeight = m_pSettings->value("tagEditor/patterns/height").toInt(); } void SessionSettings::saveVector(const string& strPath, const vector& v) { // not sure how beginReadArray() & Co handle error cases, so it seems safer this way (considering that the users may want to alter the config file manually) char bfr [50]; QString s (convStr(strPath)); m_pSettings->remove(s); int n (cSize(v)); m_pSettings->setValue(s + "/count", n); for (int i = 0; i < n; ++i) { sprintf(bfr, "/val%04d", i); m_pSettings->setValue(s + bfr, convStr(v[i])); } } // allows empty entries, but stops at the first missing entry, in which case sets bErr vector SessionSettings::loadVector(const string& strPath, bool& bErr) const { vector v; QString s (convStr(strPath)); bErr = false; int n (m_pSettings->value(s + "/count", 0).toInt()); char bfr [50]; for (int i = 0; i < n; ++i) { sprintf(bfr, "/val%04d", i); string strName (convStr(m_pSettings->value(s + bfr, "\2").toString())); if ("\2" == strName) { bErr = true; break; } v.push_back(strName); } return v; } //================================================================================================================================================ //================================================================================================================================================ //================================================================================================================================================ void SessionSettings::saveConfigSize(int nWidth, int nHeight) { m_pSettings->setValue("config/width", nWidth); m_pSettings->setValue("config/height", nHeight); } void SessionSettings::loadConfigSize(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("config/width").toInt(); nHeight = m_pSettings->value("config/height").toInt(); } MP3Diags-1.0.12.079/src/TagEditorDlgImpl.h0000644000175000001440000002356411265577777016621 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TagEditorDlgImplH #define TagEditorDlgImplH #include #include #include #include #include "ui_TagEditor.h" #include "CommonTypes.h" class CommonData; class QSettings; class QScrollArea; class TagWriter; class TagEditorDlgImpl; class TransfConfig; class QToolButton; namespace TagEditor { class CurrentAlbumModel : public QAbstractTableModel { Q_OBJECT TagEditorDlgImpl* m_pTagEditorDlgImpl; TagWriter* m_pTagWriter; const CommonData* m_pCommonData; public: //CurrentAlbumModel(CommonData* pCommonData); CurrentAlbumModel(TagEditorDlgImpl* pTagEditorDlgImpl); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; /*override*/ Qt::ItemFlags flags(const QModelIndex& index) const; /*override*/ bool setData(const QModelIndex& index, const QVariant& value, int nRole /*= Qt::EditRole*/); void emitLayoutChanged() { emit layoutChanged(); } }; class CurrentFileModel : public QAbstractTableModel { Q_OBJECT const TagEditorDlgImpl* m_pTagEditorDlgImpl; const TagWriter* m_pTagWriter; const CommonData* m_pCommonData; public: CurrentFileModel(const TagEditorDlgImpl* pTagEditorDlgImpl); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; void emitLayoutChanged() { emit layoutChanged(); } }; #if 0 class CurrentAlbumGDelegate : public QAbstractItemDelegate //class CurrentAlbumGDelegate : public QItemDelegate //class CurrentAlbumGDelegate : public MultiLineTvDelegate { Q_OBJECT public: //NotesGDelegate(CommonData* pCommonData, QObject* pParent) : QItemDelegate(pParent), m_pCommonData(pCommonData) {} NotesGDelegate(CommonData* pCommonData); /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; CommonData* m_pCommonData; }; #endif class CurrentFileDelegate : public QItemDelegate { Q_OBJECT protected: QTableView* m_pTableView; const CommonData* m_pCommonData; public: CurrentFileDelegate(QTableView* pTableView, const CommonData* pCommonData); /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; /*override*/ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; }; class CurrentAlbumDelegate : public QItemDelegate { Q_OBJECT protected: QTableView* m_pTableView; const TagEditorDlgImpl* m_pTagEditorDlgImpl; const TagWriter* m_pTagWriter; //const CommonData* m_pCommonData; mutable std::set m_spEditors; public: CurrentAlbumDelegate(QTableView* pTableView, TagEditorDlgImpl* pTagEditorDlgImpl); /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; // /*override*/ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; /*override*/ QWidget* createEditor(QWidget* pParent, const QStyleOptionViewItem&, const QModelIndex& index) const; bool closeEditor(); // closes the editor opened with F2, saving the data; returns false if there was some error and it couldn't close private slots: void onEditorDestroyed(QObject*); }; } // namespace TagEditor struct AssgnBtnWrp; class TagEditorDlgImpl : public QDialog, private Ui::TagEditorDlg { Q_OBJECT CommonData* m_pCommonData; void resizeTagEditor(); // resizes the widgets in the tag editor area: album table, image list; for file table and album table resizes the columns void resizeFile(); // resizes the "current file" grid; called by resizeTagEditor() and by onFileChanged(); QScrollArea* m_pImgScrollArea; TagWriter* m_pTagWriter; /*override*/ void resizeEvent(QResizeEvent* pEvent); /*override*/ void closeEvent(QCloseEvent* pEvent); void loadTagWriterInf(); void saveTagWriterInf(); AssgnBtnWrp* m_pAssgnBtnWrp; TagEditor::CurrentAlbumModel* m_pCurrentAlbumModel; TagEditor::CurrentFileModel* m_pCurrentFileModel; TagEditor::CurrentAlbumDelegate* m_pAlbumDel; bool m_bSectionMovedLock; void clearSelection(); void resizeIcons(); void selectMainCrt(); // selects the song that is current in the main window (to be called on the constructor); TransfConfig& m_transfConfig; enum SaveOpt { SAVED, DISCARDED, CANCELLED, PARTIALLY_SAVED }; enum { EXPLICIT, IMPLICIT }; SaveOpt save(bool bImplicitCall); // based on configuration, either just saves the tags or asks the user for confirmation; returns true iff all tags have been saved or if none needed saving; it should be followed by a reload(), either for the current or for the next/prev album; if bImplicitCall is false, the "ASK" option is turned into "SAVE"; bool closeEditor(/*const std::string& strAction*/) { return m_pAlbumDel->closeEditor(); } // closes the editor opened with F2, saving the data; returns false if there was some error and it couldn't close //ttt2 perhaps use strAction for a more personalize message /*override*/ bool eventFilter(QObject* pObj, QEvent* pEvent); std::vector > getSelFields() const; // returns the selceted fields, with the first elem as the song number and the second as the field index in TagReader::Feature (it converts columns to fields using TagReader::FEATURE_ON_POS); first column (file name) is ignored void eraseSelFields(); // erases the values in the selected fields bool m_bIsFastSaving; bool m_bIsSaving; bool m_bIsNavigating; bool& m_bDataSaved; bool m_bWaitingAlbumResize, m_bWaitingFileResize; // to avoid ColumnResizer being called lots of times void setupVarArtistsBtn(); void createPatternButtons(); std::vector m_vpPattButtons; TextCaseOptions m_eArtistsCase, m_eOthersCase; public: TagEditorDlgImpl(QWidget* pParent, CommonData* pCommonData, TransfConfig& transfConfig, bool& bDataSaved); // transfConfig is needed both to be able to instantiate the config dialog and for saving ID3V2 ~TagEditorDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ std::string run(); TagWriter* getTagWriter() const { return m_pTagWriter; } const CommonData* getCommonData() const { return m_pCommonData; } using Ui::TagEditorDlg::m_pCurrentAlbumG; using Ui::TagEditorDlg::m_pCurrentFileG; void updateAssigned(); // updates the state of "assigned" fields and the assign button bool isSaving() const { return m_bIsSaving; } bool isNavigating() const { return m_bIsNavigating; } public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pNextB_clicked(); void on_m_pPrevB_clicked(); void on_m_pQueryDiscogsB_clicked(); void on_m_pQueryMusicBrainzB_clicked(); void on_m_pEditPatternsB_clicked(); void on_m_pPaletteB_clicked(); void on_m_pToggleAssignedB_clicked(); void on_m_pReloadB_clicked(); void on_m_pVarArtistsB_clicked(); void on_m_pCaseB_clicked(); void on_m_pCopyFirstB_clicked(); void on_m_pSaveB_clicked(); void on_m_pPasteB_clicked(); void on_m_pSortB_clicked(); void on_m_pConfigB_clicked(); void onAlbSelChanged(); void onAlbCrtChanged(); void onFileSelSectionMoved(int nLogicalIndex, int nOldVisualIndex, int nNewVisualIndex); void onShow() { resizeTagEditor(); onShowPatternNote(); } void onAlbumChanged(/*bool bContentOnly*/); // the param was meant to determine if the selection should be kept (bContentOnly is true) or cleared (false); no longer needed, because the clearing the selection is done separately; //ttt2 perhaps put back, after restructuring the tag editor signals void onFileChanged(); void onImagesChanged(); // adds new ImageInfoPanelWdgImpl instances, connects assign button and calls resizeTagEditor() void onShowPatternNote(); void onResizeTagEditorDelayed(); void onResizeFileDelayed(); void onHelp(); void onVarArtistsUpdated(bool bVarArtists); void onPatternClicked(); }; #endif MP3Diags-1.0.12.079/src/UniqueNotesModel.h0000644000175000001440000000601111200236502016651 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef UniqueNotesModelH #define UniqueNotesModelH #include #include "MultiLineTvDelegate.h" //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class CommonData; // all notes struct UniqueNotesModel : public QAbstractTableModel { Q_OBJECT public: UniqueNotesModel(CommonData* pCommonData); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; CommonData* m_pCommonData; void selectTopLeft(); // makes current and selects the element in the top-left corner and emits a change signal regardless of the element that was selected before; makes current the default invalid index (-1,-1) if the table is empty }; class UniqueNotesGDelegate : public MultiLineTvDelegate { Q_OBJECT public: UniqueNotesGDelegate(CommonData* pCommonData); /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; CommonData* m_pCommonData; }; #endif // #ifndef UniqueNotesModelH MP3Diags-1.0.12.079/src/SerSupport.h0000644000175000001440000000430611200235743015552 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef SerSupportH #define SerSupportH //#include //#include #include #include #include // !!! the archive headers must be included before serialization; otherwise compiler errors are triggered; this looks like a Boost 1.33 bug /* #include #include #include #include #include #include */ #endif MP3Diags-1.0.12.079/src/DataStream.cpp0000644000175000001440000002525611345513462016022 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include "DataStream.h" #include "Helpers.h" #include "MpegFrame.h" #include "MpegStream.h" #include "CommonData.h" using namespace std; using namespace pearl; //====================================================================================================== //====================================================================================================== /*override*/ void SimpleDataStream::copy(std::istream& in, std::ostream& out) { appendFilePart(in, out, m_pos, m_nSize); } UnknownDataStreamBase::UnknownDataStreamBase(int nIndex, NoteColl& notes, istream& in, streamoff nSize) : SimpleDataStream(nIndex, in.tellg(), nSize) { StreamStateRestorer rst (in); STRM_ASSERT (in); STRM_ASSERT (nSize > 0); streamoff nBfrSize (min(streamoff(BEGIN_SIZE), nSize)); read(in, m_begin, nBfrSize); streampos pos (m_pos); pos += nSize - 1; in.seekg(pos); char c; MP3_CHECK (1 == read(in, &c, 1), m_pos, unknTooShort, BadUnknownStream()); rst.setOk(); } /*override*/ std::string UnknownDataStreamBase::getInfo() const { return "begins with: " + asHex(m_begin, min(int(BEGIN_SIZE), int(m_nSize))); } void UnknownDataStreamBase::append(const UnknownDataStreamBase& other) { streampos pos (m_pos); pos += m_nSize; STRM_ASSERT (pos == other.m_pos); if (m_nSize < BEGIN_SIZE) { int n (min(BEGIN_SIZE - m_nSize, other.m_nSize)); std::copy(other.m_begin, other.m_begin + n, m_begin + m_nSize); } m_nSize += other.m_nSize; } bool TruncatedMpegDataStream::hasSpace(std::streamoff nSize) const { return nSize < getExpectedSize() - getSize(); // "<" rather than "<="; if it gets full why would it be called "truncated" } TruncatedMpegDataStream::TruncatedMpegDataStream(MpegStream* pPrevMpegStream, int nIndex, NoteColl& notes, std::istream& in, std::streamoff nSize) : UnknownDataStreamBase(nIndex, notes, in, nSize), m_pFrame(0) { if (0 == pPrevMpegStream) { throw NotTruncatedMpegDataStream(); } in.seekg(m_pos); StreamStateRestorer rst (in); NoteColl tmpNotes (20); try { m_pFrame = new MpegFrameBase(tmpNotes, in); } catch (const MpegFrameBase::NotMpegFrame&) { throw NotTruncatedMpegDataStream(); } if (!pPrevMpegStream->isCompatible(*m_pFrame)) { delete m_pFrame; throw NotTruncatedMpegDataStream(); } streampos pos (m_pos); pos += nSize; in.seekg(pos); rst.setOk(); } TruncatedMpegDataStream::~TruncatedMpegDataStream() { delete m_pFrame; } /*override*/ std::string TruncatedMpegDataStream::getInfo() const { string s (decodeMpegFrame(m_begin, ", ")); return s; } int TruncatedMpegDataStream::getExpectedSize() const { return m_pFrame->getSize(); } NullDataStream::NullDataStream(int nIndex, NoteColl& notes, std::istream& in) : DataStream(nIndex), m_nSize(0) { StreamStateRestorer rst (in); streampos pos (in.tellg()); m_pos = pos; const int BFR_SIZE (256); char bfr [BFR_SIZE]; for (;;) { streamsize nRead (read(in, bfr, BFR_SIZE)); for (int i = 0; i < nRead; ++i) { if (0 != bfr[i]) { m_nSize += i; goto e1; } } m_nSize += nRead; if (nRead < BFR_SIZE) { break; } } e1: MP3_CHECK_T (m_nSize >= 16, m_pos, "Not a NULL stream. File too short.", NotNullStream()); pos += m_nSize; in.clear(); in.seekg(pos); rst.setOk(); } /*override*/ void NullDataStream::copy(std::istream&, std::ostream& out) { const int BFR_SIZE (256); char bfr [BFR_SIZE]; for (int i = 0; i < BFR_SIZE; ++i) { bfr[i] = 0; } streamoff n (m_nSize); while (n > BFR_SIZE) { out.write(bfr, BFR_SIZE); n -= BFR_SIZE; } out.write(bfr, n); CB_CHECK1 (out, WriteError()); } /*override*/ std::string NullDataStream::getInfo() const { return ""; } UnsupportedDataStream::UnsupportedDataStream(int nIndex, NoteColl& notes, istream& in, streamoff nSize, const char* szBaseName, const string& strInfo) : UnknownDataStreamBase(nIndex, notes, in, nSize), m_strName(string("Unsupported ") + szBaseName), m_strBaseName(szBaseName), m_strInfo(UnknownDataStreamBase::getInfo()) { if (!strInfo.empty()) { string s1 (strInfo); if (endsWith(s1, ".") || endsWith(s1, ";")) { s1.erase(s1.size() - 1); } m_strInfo = s1 + " - " + m_strInfo; } } //====================================================================================================== //====================================================================================================== // /*static*/ /*bool TagReader::isTimeValid(const std::string& s) { } yyy-MM-ddTHH:mm:ss */ TagTimestamp::TagTimestamp(const std::string& strVal) { init(strVal); } TagTimestamp::TagTimestamp(const char* szVal /*= 0*/) { init(0 != szVal ? szVal : ""); } // if strVal is invalid it clears m_strVal, m_strYear and m_strDayMonth and throws InvalidTime void TagTimestamp::init(std::string s) { m_szVal[0] = 0; m_szYear[0] = 0; m_szDayMonth[0] = 0; int n (cSize(s)); if (n >= 11 && 'T' == s[10]) { s[10] = ' '; } static const char* szPatt ("****-**-** **:**:**X"); // 'X' is needed to avoid checking indexes CB_CHECK1 (n <= 19, InvalidTime()); CB_CHECK1 (0 == n || '*' != szPatt[n], InvalidTime()); for (int i = 0; i < n; ++i) { char c (szPatt[i]); if ('*' == c) { CB_CHECK1 (isdigit(s[i]), InvalidTime()); } else { CB_CHECK1 (szPatt[i] == s[i], InvalidTime()); } } //ttt2 check validity for years and dates strcpy(m_szVal, s.c_str()); if (n > 0) { strcpy(m_szYear, s.substr(0, 4).c_str()); if (n > 4) { strcpy(m_szDayMonth, ((n > 7 ? s.substr(8, 2) : "01") + s.substr(5, 2)).c_str()); } } } // text representation for each Feature /*static*/ const char* TagReader::getLabel(int n) { static const char* s_szTitle[] = { "Title", "Artist", "Track #", "Time", "Genre", "Picture", "Album", "Rating", "Composer", "VA" }; CB_ASSERT (n >= 0 && n < LIST_END); return s_szTitle[n]; } // orig: { TITLE, ARTIST, TRACK_NUMBER, TIME, GENRE, IMAGE, ALBUM, RATING, COMPOSER, VARIOUS_ARTISTS, LIST_END }; /*static*/ int TagReader::FEATURE_ON_POS[] = { TRACK_NUMBER, ARTIST, TITLE, ALBUM, VARIOUS_ARTISTS, TIME, GENRE, IMAGE, RATING, COMPOSER }; //ttt2 perhaps move to CommonData and make configurable, as long as discarding some columns (e.g. composer) // static int INV_FEATURE_ON_POS[]; // the "inverse" of FEATURE_ON_POS: what Feature appears in a given position // /*static*/ int TagReader::INV_FEATURE_ON_POS[] = { 1, 0, 2, 3, 4, 5, 6, 7, 8 }; // INV_FEATURE_ON_POS ~ POS_OF_FEATURE /*static*/ int TagReader::POS_OF_FEATURE[LIST_END]; namespace { struct Init { Init() { for (int i = 0; i < TagReader::LIST_END; ++i) { TagReader::POS_OF_FEATURE[TagReader::FEATURE_ON_POS[i]] = i; } } }; Init init; } // returns the corresponding feature converted to a string; if it's not supported, it returns an empty string; for IMAGE an empty string regardless of a picture being present or not std::string TagReader::getValue(Feature f) const { switch (f) { case TITLE: if (getSupport(TITLE)) { return getTitle(); } else { return ""; } case ARTIST: if (getSupport(ARTIST)) { return getArtist(); } else { return ""; } case TRACK_NUMBER: if (getSupport(TRACK_NUMBER)) { return getTrackNumber(); } else { return ""; } case TIME: if (getSupport(TIME)) { return getTime().asString(); } else { return ""; } case GENRE: if (getSupport(GENRE)) { return getGenre(); } else { return ""; } case IMAGE: return ""; case ALBUM: if (getSupport(ALBUM)) { return getAlbumName(); } else { return ""; } case RATING: if (getSupport(RATING)) { double r (getRating()); if (r >= 0) { char a [10]; sprintf(a, "%0.1f", r); return a; } } return ""; case COMPOSER: if (getSupport(COMPOSER)) { return getComposer(); } else { return ""; } case VARIOUS_ARTISTS: if (getSupport(VARIOUS_ARTISTS)) { int nVa (getVariousArtists()); string s; if (nVa & VA_ITUNES) { s += "i"; } if (nVa & VA_WMP) { s += "w"; } return s; } else { return ""; } default: return ""; } } /*static*/ string TagReader::getVarArtistsValue() // what getValue(VARIOUS_ARTISTS) returns for VA tags, based on global configuration { string s; const CommonData* pCommonData (getCommonData()); if (pCommonData->m_bItunesVarArtists) { s += "i"; } if (pCommonData->m_bWmpVarArtists) { s += "w"; } return s; } /*virtual*/ TagReader::~TagReader() { // qDebug("destroy TagReader at %p", this); } MP3Diags-1.0.12.079/src/TagEditor.ui0000644000175000001440000005413011265372133015502 0ustar ciobiusers TagEditorDlg 0 0 993 679 MP3 Diags - Tag editor true 0 0 0 0 0 40 40 40 40 Qt::NoFocus Save S :/images/document-save.svg 36 36 true 40 40 40 40 Qt::NoFocus Reset R :/images/edit-undo.svg 36 36 true Qt::Horizontal QSizePolicy::Fixed 15 15 40 40 40 40 Qt::NoFocus Previous [Ctrl+P] < :/images/go-previous.svg 36 36 Ctrl+P true Qt::NoArrow Qt::Horizontal QSizePolicy::Fixed 4 15 Folder true Qt::Horizontal QSizePolicy::Fixed 4 15 40 40 40 40 Qt::NoFocus Next [Ctrl+N] > :/images/go-next.svg 36 36 Ctrl+N true Qt::NoArrow Qt::Horizontal QSizePolicy::Fixed 15 15 40 40 40 40 Qt::NoFocus Query Discogs Q :/images/discogs.png 36 36 true 40 40 40 40 Qt::NoFocus Query MusicBrainz ... :/images/musicbrainz_logo1.svg 36 36 true Qt::Horizontal QSizePolicy::Fixed 15 15 40 40 40 40 Qt::NoFocus Toggle "Various Artists" V :/images/va_va.svg 36 36 true 40 40 40 40 Qt::NoFocus Change case automatically ... :/images/change-case.svg 36 36 true 40 40 40 40 Qt::NoFocus Copy field(s) from first line C :/images/duplicate_first.svg 36 36 true 40 40 40 40 Qt::NoFocus Sort by track number ... :/images/sort_asc.svg 36 36 true 40 40 40 40 Qt::NoFocus Toggle "assigned" state A :/images/assgn-some.svg 36 36 true 40 40 40 40 Qt::NoFocus Paste ... :/images/edit-paste.svg 36 36 Ctrl+V true 40 40 40 40 Qt::NoFocus Edit file patterns F :/images/patterns.svg 36 36 true Qt::Horizontal QSizePolicy::Fixed 15 15 40 40 40 40 Qt::NoFocus Background colors ... :/images/palette.svg 36 36 true 40 40 40 40 ... :/images/configure.svg 36 36 true 0 4 0 0 0 0 0 0 0 0 TextLabel 0 0 0 0 0 0 QAbstractItemView::NoSelection 0 0 0 0 TextLabel MP3Diags-1.0.12.079/src/Version.cpp0000644000175000001440000000010212040502151015363 0ustar ciobiusersconst char* APP_VER ("1.0.12.079"); const char* APP_BRANCH (""); MP3Diags-1.0.12.079/src/NoteFilterDlgImpl.cpp0000644000175000001440000002330511274017760017313 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "NoteFilterDlgImpl.h" #include "Helpers.h" #include "StoredSettings.h" #include "CommonData.h" using namespace std; using namespace pearl; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== /*override*/ std::string NoteListElem::getText(int nCol) const { if (0 == nCol) { //return m_pCommonData->getNoteLabel(m_pNote).toUtf8().constData(); return convStr(getNoteLabel(m_pNote)); } return m_pNote->getDescription(); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== NoteFilterDlgImpl::NoteFilterDlgImpl(CommonData* pCommonData, QWidget* pParent /*=0*/) : QDialog(pParent, getDialogWndFlags()), NoteListPainterBase(pCommonData, "") { TRACER("NoteFilterDlgImpl constr"); setupUi(this); m_pListHldr->setLayout(new QHBoxLayout()); for (int i = 0, n = pCommonData->getUniqueNotes().getCount(); i < n; ++i) { m_vpOrigAll.push_back(new NoteListElem(pCommonData->getUniqueNotes().get(i), m_pCommonData)); } for (int i = 0, n = cSize(pCommonData->m_filter.getNotes()); i < n; ++i) { int k (pCommonData->getUniqueNotes().getPos(pCommonData->m_filter.getNotes()[i])); if (k >= 0) { m_vOrigSel.push_back(k); } } m_vSel = m_vOrigSel; m_pDoubleList = new DoubleList( *this, DoubleList::ADD_ALL | DoubleList::DEL_ALL | DoubleList::RESTORE_OPEN, DoubleList::SINGLE_UNSORTABLE, "Available notes", "Include notes", this); m_pListHldr->layout()->addWidget(m_pDoubleList); m_pListHldr->layout()->setContentsMargins(0, 0, 0, 0); int nWidth, nHeight; m_pCommonData->m_settings.loadNoteFilterSettings(nWidth, nHeight); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } else { defaultResize(*this); } connect(m_pDoubleList, SIGNAL(avlDoubleClicked(int)), this, SLOT(onAvlDoubleClicked(int))); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } NoteFilterDlgImpl::~NoteFilterDlgImpl() { clearPtrContainer(m_vpOrigAll); } void NoteFilterDlgImpl::logState(const char* /*szPlace*/) const { /*cout << szPlace << ": m_filter.m_vSelDirs=" << m_pCommonData->m_filter.m_vSelDirs.size() << " m_availableDirs.m_vstrDirs=" << m_availableDirs.m_vstrDirs.size() << " m_selectedDirs.m_vSelDirs=" << m_selectedDirs.m_vstrDirs.size() << endl;*/ } //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- void NoteFilterDlgImpl::on_m_pOkB_clicked() { //logState("on_m_pOkB_clicked 1"); //m_pCommonData->m_filter.m_vpSelNotes = m_selectedNotes.m_vpNotes; vector v; //m_pCommonData->m_filter.m_vpSelNotes.clear(); for (int i = 0, n = cSize(m_vSel); i < n; ++i) { const NoteListElem* p (dynamic_cast(m_vpOrigAll[m_vSel[i]])); CB_ASSERT(0 != p); v.push_back(p->getNote()); } m_pCommonData->m_filter.setNotes(v); //ttt2 in other case changing a parent window before the modal dialog was closed led to incorrect resizing; however, here it seems OK //logState("on_m_pOkB_clicked 2"); m_pCommonData->m_settings.saveNoteFilterSettings(width(), height()); accept(); } void NoteFilterDlgImpl::on_m_pCancelB_clicked() { reject(); } void NoteFilterDlgImpl::onAvlDoubleClicked(int nRow) { //m_pCommonData->m_filter.m_vpSelNotes.clear(); vector v; const NoteListElem* p (dynamic_cast(m_vpOrigAll[getAvailable()[nRow]])); CB_ASSERT(0 != p); v.push_back(p->getNote()); m_pCommonData->m_filter.setNotes(v); accept(); } //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- /*override*/ string NoteFilterDlgImpl::getTooltip(TooltipKey eTooltipKey) const { switch (eTooltipKey) { case SELECTED_G: return "";//"Notes to be included"; case AVAILABLE_G: return "";//"Available notes"; case ADD_B: return "Add selected note(s)"; case DELETE_B: return "Remove selected note(s)"; case ADD_ALL_B: return "Add all notes"; case DELETE_ALL_B: return "Remove all notes"; case RESTORE_DEFAULT_B: return ""; case RESTORE_OPEN_B: return "Restore lists to the configuration they had when the window was open"; default: CB_ASSERT(false); } } /*override*/ void NoteFilterDlgImpl::reset() { CB_ASSERT(false); } void NoteFilterDlgImpl::onHelp() { openHelp("170_note_filter.html"); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== /*override*/ std::string NoteListPainterBase::getColTitle(int nCol) const { switch (nCol) { case 0: return "L"; case 1: return "Note"; default: return "???"; } } /*override*/ void NoteListPainterBase::getColor(int nIndex, int nColumn, bool bSubList, QColor& bckgColor, QColor& penColor, double& dGradStart, double& dGradEnd) const { LAST_STEP("NoteListPainterBase::getColor()"); const NoteListElem* p (dynamic_cast(getAll()[nIndex])); CB_ASSERT(0 != p); const Note* pNote (p->getNote()); { const SubList& v (getAvailable()); if (m_vpAvail.size() != v.size()) // !!! there's no need for a "dirty" flag; after the content of getAvailable() changes, a paint is executed, and when it gets here sizes will be different { m_vpAvail.clear(); for (int i = 0; i < cSize(v); ++i) { const NoteListElem* p (dynamic_cast(getAll()[v[i]])); m_vpAvail.push_back(p->getNote()); } } } { const SubList& v (getSel()); if (m_vpSel.size() != v.size()) { m_vpSel.clear(); for (int i = 0; i < cSize(v); ++i) { const NoteListElem* p (dynamic_cast(getAll()[v[i]])); m_vpSel.push_back(p->getNote()); } } } if (0 == nColumn) { if (Note::ERR == pNote->getSeverity()) { penColor = ERROR_PEN_COLOR(); } else if (Note::SUPPORT == pNote->getSeverity()) { penColor = SUPPORT_PEN_COLOR(); } } m_pCommonData->getNoteColor(*pNote, bSubList ? m_vpSel : m_vpAvail, bckgColor, dGradStart, dGradEnd); } // positive values are used for fixed widths, while negative ones are for "stretched" /*override*/ int NoteListPainterBase::getColWidth(int nCol) const { switch (nCol) { case 0: return CELL_WIDTH + 10; case 1: return -1; } CB_ASSERT(false); } /*override*/ int NoteListPainterBase::getHdrHeight() const { return CELL_HEIGHT; } /*override*/ Qt::Alignment NoteListPainterBase::getAlignment(int nCol) const { if (0 == nCol) { //return Qt::AlignTop | Qt::AlignHCenter; return Qt::AlignVCenter | Qt::AlignHCenter; } return Qt::AlignTop | Qt::AlignLeft; } MP3Diags-1.0.12.079/src/NormalizeDlgImpl.cpp0000644000175000001440000002463011330116534017172 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include "NormalizeDlgImpl.h" #include "Widgets.h" #include "StoredSettings.h" #include "CommonData.h" ////#include // ttt remove using namespace std; /* ttt2 random 30-second freeze: norm completed but not detected; window was set to stay open; abort + close sort of worked, but the main window froze and the program had to be killed; on a second run it looked like the UI freeze is not permanent, but lasts 30 seconds (so waiting some more the first time might have unfrozen the app) What seems to happen is this: QProcess loses contact with the actual process (or perhaps the program becomes a zombie or something similar, not really finished but not running anymore either); then 2 things happen: first, waitForFinished() doesn't return for 30 seconds (which is the default timeout, and can be made smaller); then, when closing the norm window there's another 30 seconds freeze, probably caused by the dialog destructor's attempt to destroy the QProcess member (which again tries to kill a dead process) This might be fixed in newer versions of Qt. Might be related to the comment "!!! needed because sometimes" below, which also suggests that the issue is in Qt rather than MP3 Diags Note that this also happens during normal operation, even if "abort" is not pressed. The dialog might fail to detect that normalization is done. If that happens, the solution is to press Abort. ttt2 - perhaps detect that no output is coming from the program, so just assume it's dead; still, the destructor would have to be detached and put on a secondary thread, or just leave a memory leak; (having a timer "clean" a vector with QProcess objects doesn't work, because it would freeze whatever object it's attached to) ttt2 doc: might seem frozen at the end; just press abort and wait for at most a minute. i'm investigating the cause same may happen after pressing abort while the normalization is running */ NormalizeDlgImpl::NormalizeDlgImpl(QWidget* pParent, bool bKeepOpen, SessionSettings& settings, const CommonData* pCommonData) : QDialog(pParent, getDialogWndFlags()), Ui::NormalizeDlg(), m_pProc(0), m_bFinished(false), m_settings(settings), m_pCommonData(pCommonData) { setupUi(this); m_pKeepOpenCkM->setChecked(bKeepOpen); int nWidth, nHeight; m_settings.loadNormalizeSettings(nWidth, nHeight); if (nWidth > 400 && nHeight > 300) { resize(nWidth, nHeight); } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } NormalizeDlgImpl::~NormalizeDlgImpl() { CursorOverrider crs; delete m_pProc; } void logTransformation(const string& strLogFile, const char* szActionName, const string& strMp3File); void NormalizeDlgImpl::normalize(const QString& qstrProg1, const QStringList& lFiles) //ttt2 in Windows MP3Gain doesn't seem to care about Unicode (well, the GUI version does, but that doesn't help). aacgain doesn't work either; see if there's a good way to deal with this; doc about using short filenames { m_pProc = new QProcess(this); //m_pProc = new QProcess(); // !!! m_pProc is not owned; it will be destroyed connect(m_pProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onFinished())); connect(m_pProc, SIGNAL(readyReadStandardOutput()), this, SLOT(onOutputTxt())); connect(m_pProc, SIGNAL(readyReadStandardError()), this, SLOT(onErrorTxt())); if (m_pCommonData->m_bLogTransf) { for (int i = 0; i < lFiles.size(); ++i) { logTransformation(m_pCommonData->m_strTransfLog, "Normalize", convStr(lFiles[i])); } } // int k (1); for (; k < qstrProg1.size() && (qstrProg1[k - 1] != ' ' || (qstrProg1[k] != '-' && qstrProg1[k] != '/')); ++k) {} //ttt2 perhaps better: look for spaces from the end and stop when a dir exists from the beginning of the name till the current space QString qstrProg (qstrProg1.left(k).trimmed()); QString qstrArg (qstrProg1.right(qstrProg1.size() - k).trimmed()); //qDebug("prg <%s> arg <%s>", qstrProg.toUtf8().constData(), qstrArg.toUtf8().constData()); QStringList l (qstrArg.split(" ", QString::SkipEmptyParts)); // ttt2 perhaps accomodate params that contain spaces, but mp3gain doesn't seem to need them; //QString qstrName (l.front()); //l.removeFirst(); l << lFiles; m_pProc->start(qstrProg, l); if (!m_pProc->waitForStarted(5000)) { QMessageBox::critical(this, "Error", "Cannot start process. Check that the executable name and the parameters are correct."); return; } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence(Qt::Key_Escape)); connect(p, SIGNAL(triggered()), this, SLOT(on_m_pAbortB_clicked())); addAction(p); } exec(); m_settings.saveNormalizeSettings(width(), height()); } void NormalizeDlgImpl::onOutputTxt() { addText(m_pProc->readAllStandardOutput()); //ttt2 perhaps use different colors for std and err, or use 2 separate text boxes } void NormalizeDlgImpl::onErrorTxt() { //addText("####" + m_pProc->readAllStandardError()); QString s (m_pProc->readAllStandardError().trimmed()); if (s.isEmpty()) { return; } //qDebug("err %s", s.toUtf8().constData()); //inspect(s.toUtf8().constData(), s.size()); int n (s.lastIndexOf("\r")); if (n > 0) { s.remove(0, n + 1); } n = s.lastIndexOf("\n"); if (n > 0) { s.remove(0, n + 1); } //inspect(s.toUtf8().constData(), s.size()); while (!s.isEmpty() && s[0] == ' ') { s.remove(0, 1); } m_pDetailE->setText(s); } void NormalizeDlgImpl::addText(QString s) { s = s.trimmed(); if (s.isEmpty()) { return; } for (;;) { int n (s.indexOf("\n\n")); if (-1 == n) { break; } s.remove(n, 1); } m_qstrText = (m_qstrText.isEmpty() ? s : m_qstrText + "\n" + s); m_pOutM->setText(m_qstrText); QScrollBar* p (m_pOutM->verticalScrollBar()); if (p->isVisible()) { p->setValue(p->maximum()); } } void NormalizeDlgImpl::onFinished() { if (m_bFinished) { return; } // !!! needed because sometimes terminating with kill() triggers onFinished() and sometimes it doesn't m_bFinished = true; // !!! doesn't need to destroy m_pProc and QAction, because they will be destroyed anyway when the dialog will be destroyed, which is going to be pretty soon if (m_pKeepOpenCkM->isChecked()) { addText("==================================\nFinished"); m_pDetailE->setText(""); } else { reject(); } } void NormalizeDlgImpl::on_m_pCloseB_clicked() { if (!m_bFinished) { QMessageBox::warning(this, "Warning", "Cannot close while the normalization is running."); return; } accept(); } void NormalizeDlgImpl::on_m_pAbortB_clicked() { qDebug("proc state %d", int(m_pProc->state())); if (m_bFinished) { on_m_pCloseB_clicked(); return; } if (0 == showMessage(this, QMessageBox::Warning, 1, 1, "Confirm", "Stopping normalization may leave the files in an inconsistent state or may prevent temporary files from being deleted. Are you sure you want to abort the normalization?", "Yes, abort", "Don't abort")) { CursorOverrider crs; m_pProc->kill(); m_pProc->waitForFinished(5000); onFinished(); } } // !!! Can't allow the top-right close button or the ESC key to close the dialog, because that would kill the thread too and leave everything in an inconsistent state. So the corresponding events are intercepted and "ignore()"d and abort() is called instead /*override*/ void NormalizeDlgImpl::closeEvent(QCloseEvent* pEvent) { /* Not sure if this should work: from the doc for QDialog: Escape Key If the user presses the Esc key in a dialog, QDialog::reject() will be called. This will cause the window to close: The close event cannot be ignored. ttt2 see Qt::Key_Escape in MainFormDlgImpl for a different approach, decide which is better */ pEvent->ignore(); on_m_pCloseB_clicked(); // on_m_pAbortB_clicked(); } #if 0 /*override*/ void NormalizeDlgImpl::keyPressEvent(QKeyEvent* pEvent) { //qDebug("key prs %d", pEvent->key()); m_nLastKey = pEvent->key(); pEvent->ignore(); // ttt2 not sure this is the way to do it, but the point is to disable the ESC key } /*override*/ void NormalizeDlgImpl::keyReleaseEvent(QKeyEvent* pEvent) { //qDebug("key rel %d", pEvent->key()); if (Qt::Key_Escape == pEvent->key()) { on_m_pAbortB_clicked(); } pEvent->ignore(); // ttt2 not sure this is the way to do it, but the point is to disable the ESC key } #endif void NormalizeDlgImpl::onHelp() { openHelp("230_normalize.html"); } //ttt2 timer in normalizer //ttt2 look at normalized loudness in tracks, maybe warn //ttt1 non-ASCII characters are not shown correctly MP3Diags-1.0.12.079/src/MainForm.ui0000644000175000001440000011423411262647114015333 0ustar ciobiusers MainFormDlg 0 0 1000 685 630 440 Dialog true 12 0 0 0 0 40 40 40 40 Qt::NoFocus Scan folders for MP3 files [Ctrl+S] prc :/images/scan.svg 36 36 Ctrl+S true 0 0 0 0 0 40 40 40 40 Qt::NoFocus Close this window and open the Session editor ... :/images/session.svg 36 36 true 40 40 40 40 Qt::NoFocus Export ... ... :/images/export.svg 36 36 true 0 0 0 0 0 40 40 40 40 Qt::NoFocus Filter by notes nflt :/images/filter-note.svg 36 36 true false true 40 40 40 40 Qt::NoFocus Filter by folders dflt :/images/filter-folder.svg 36 36 true false true 0 0 0 0 0 40 40 40 40 Qt::NoFocus Show the full list of files (after applying the filters) ... :/images/mode_all.svg 36 36 true true true true 40 40 40 40 Qt::NoFocus Show one album (i.e. folder) at a time d :/images/mode_album.svg 36 36 true true true 40 40 40 40 Qt::NoFocus Show one song at a time f :/images/mode_file.svg 36 36 true false true true 3 0 0 0 0 40 40 40 40 Qt::NoFocus Previous [Ctrl+P] < :/images/go-previous.svg 36 36 Ctrl+P true Qt::NoArrow Folder true 40 40 40 40 Qt::NoFocus Next [Ctrl+N] > :/images/go-next.svg 36 36 Ctrl+N true Qt::NoArrow 0 0 0 0 0 40 40 40 40 Qt::NoFocus Apply a single transformation rep :/images/transform.svg 36 36 true 40 40 40 40 Qt::NoFocus Apply custom set of transforms #1 :/images/transform1.svg 36 36 true 40 40 40 40 Qt::NoFocus Apply custom set of transforms #2 :/images/transform2.svg 36 36 true 40 40 40 40 Qt::NoFocus Apply custom set of transforms #3 :/images/transform3.svg 36 36 true 40 40 40 40 Qt::NoFocus ... :/images/transform4.svg 36 36 true 40 40 40 40 Qt::NoFocus Tag editor ... :/images/tag_editor.svg 36 36 true 40 40 40 40 Qt::NoFocus Normalize ... :/images/normalize.svg 36 36 true 40 40 40 40 Qt::NoFocus Reload ... :/images/edit-undo.svg 36 36 true 40 40 40 40 Qt::NoFocus Rename files ... :/images/file-rename.svg 36 36 true 0 0 0 0 0 40 40 40 40 Qt::NoFocus Settings cfg :/images/configure.svg 36 36 true 40 40 40 40 Qt::NoFocus Debug ... :/images/debug.svg 36 36 true 40 40 40 40 Qt::NoFocus About ... :/images/about.svg 36 36 true Qt::Vertical false QAbstractItemView::ExtendedSelection 0 0 0 0 0 1 0 0 0 0 0 0 0 0 File info true true All notes true Tag details true Qt::Horizontal 40 20 0 10 0 0 0 0 Removable TextLabel 0 File info 0 0 0 0 Qt::Vertical false QAbstractItemView::ExtendedSelection QAbstractItemView::SelectRows false QAbstractItemView::SelectRows All notes 0 0 0 0 QAbstractItemView::NoSelection Tag details MP3Diags-1.0.12.079/src/ThreadRunnerDlgImpl.h0000644000175000001440000002074711252461427017314 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef ThreadRunnerDlgImplH #define ThreadRunnerDlgImplH #include #include #include #include #include #include #include "ui_ThreadRunner.h" typedef QList StrList; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== /* This class is supposed to be derived from to create the actual thread class, then instantiated and passed to a ThreadRunnerDlgImpl, which will handle the thread. Usage: A) The user thread calls "pause()", "resume()" or "abort()" as needed. B) The class derived from PausableThread must declare a CompleteNotif at the beginning of its "run()" function. C) The class derived from PausableThread should do these things periodically in run(): 1) have something like this: "if (isAborted()) return;" 2) call "checkPause()"; this call blocks if the user called "pause()" 3) emit "stepChanged()", to allow progress to be displayed in the associated dialog D) The class derived from PausableThread must call "setSuccess(true)" on the CompleteNotif variable just before exiting, if the execution was successful. Notes: - the user thread shouldn't make any assumptions about how long it would take for a step in PausableThread, but this should not be long (less than 0.1 s) - in order to help performance it is possible that one more step in PausableThread will be executed after sending pause(); (functionally this shouldn't matter, because it's the same as if pause() was called just after PausableThread checked if it should pause) */ class PausableThread : public QThread { Q_OBJECT QMutex m_mutex; QWaitCondition m_waitCondition; bool m_bPaused; // set by pause() / resume() ; derived classes should check it periodically by calling isPaused() bool m_bAborted; // set by abort() ; derived classes should check it periodically by calling isAborted() protected: //bool isPaused() const { return m_bPaused; } // !!! no synch needed class CompleteNotif { bool m_bSuccess; PausableThread* m_pThread; public: CompleteNotif(PausableThread* pThread) : m_bSuccess(false), m_pThread(pThread) {} ~CompleteNotif() { m_pThread->notifComplete(m_bSuccess); } void setSuccess(bool bSuccess) { m_bSuccess = bSuccess; } }; public: PausableThread(/*QObject* pParent = 0*/); virtual ~PausableThread(); bool isAborted() const { return m_bAborted; } // !!! no synch needed void checkPause(); // if m_bPaused is set, it waits until resume() or abort() get called; otherwise it returns immediately //void emitStepChanged(const QString& qstrLabel1, const QString& qstrLabel2 = "", const QString& qstrLabel3 = "", const QString& qstrLabel4 = "") { emit stepChanged(qstrLabel1, qstrLabel2, qstrLabel3, qstrLabel4); } void emitStepChanged(const StrList& v, int nStep = -1) { emit stepChanged(v, nStep); } //public slots: //private slots: void pause(); void resume(); void abort(); private: friend class ThreadRunnerDlgImpl; friend class PausableThread::CompleteNotif; void notifComplete(bool bSuccess) { emit completed(bSuccess); } signals: //void stepChanged(const QString& qstrLabel1, const QString& qstrLabel2, const QString& qstrLabel3, const QString& qstrLabel4); void stepChanged(const StrList& v, int nStep); // normally nStep should be -1, which causes the steps to be handled automatically; void completed(bool bSuccess); }; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== /* Takes a PausableThread* on the constructor and sets itself as the owner (so the thread should be created with "new()") The thread must not be already started. It starts the thread and has buttons for pause/resume and abort. Closes itself when the thread completes. ---------- There are 2 events that can't be allow to work as usual: 1) clicking the top-right "Close" button 2) pressing ESC (which normally triggers the closing) Allowing the window ro close would kill the thread too and leave everything in an inconsistent state. So on_m_pAbortB_clicked() is called instead. To deal with Close, closeEvent() is overridden. To prevent ESC from closing the dialog, Qt::Key_Escape is set as a shortcut for on_m_pAbortB_clicked(). (Alternatively, keyPressEvent and keyReleaseEvent could be used, but it's more complicated.) */ class ThreadRunnerDlgImpl : public QDialog, private Ui::ThreadRunnerDlg { Q_OBJECT PausableThread* m_pThread; bool m_bSuccess; QTimer m_closeTimer; QTimer m_updateTimer; int m_nCounter; bool m_bShowCounter; time_t m_tRealBegin; time_t m_tRunningBegin; time_t m_tPauseBegin; StrList m_vStepInfo; bool m_bShowPauseAbort; bool m_bFirstTime; public: enum TruncatePos { TRUNCATE_BEGIN, TRUNCATE_MIDDLE, TRUNCATE_END }; private: /*override*/ void closeEvent(QCloseEvent* pEvent); // needed to sort of disable the close button; the event gets ignored and on_m_pAbortB_clicked() gets called instead #if 0 int m_nLastKey; /*override*/ void keyPressEvent(QKeyEvent* pEvent); /*override*/ void keyReleaseEvent(QKeyEvent* pEvent); #endif TruncatePos m_eTruncatePos; QString truncateLarge(const QString& s, int nKeepFirst = 0); // truncates strings that are too wide to display without resizing; uses m_eTruncatePos to determine where to truncate public: enum { HIDE_COUNTER, SHOW_COUNTER }; enum { HIDE_PAUSE_ABORT, SHOW_PAUSE_ABORT }; //ThreadRunnerDlgImpl(PausableThread* pThread, bool bShowCounter, QWidget* pParent = 0, Qt::WFlags fl = 0); ThreadRunnerDlgImpl(QWidget* pParent, Qt::WFlags flags, PausableThread* pThread, bool bShowCounter, TruncatePos eTruncatePos, bool bShowPauseAbort = true); ~ThreadRunnerDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ //void startThread(); // !!! start automatically /*void pauseThread(); void resumeThread(); void abortThread();*/ public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ private slots: void onThreadCompleted(bool bSuccess); void on_m_pPauseResumeB_clicked(); void on_m_pAbortB_clicked(); //void onStepChanged(const QString& qstrLabel1, const QString& qstrLabel2 = "", const QString& qstrLabel3 = "", const QString& qstrLabel4 = ""); void onStepChanged(const StrList& v, int nStep); void onCloseTimer(); void onUpdateTimer(); void onHelp(); }; #endif // #ifndef ThreadRunnerDlgImplH MP3Diags-1.0.12.079/src/AboutDlgImpl.h0000644000175000001440000000361111230111215015733 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef AboutDlgImplH #define AboutDlgImplH #include #include "ui_About.h" class AboutDlgImpl : public QDialog, private Ui::AboutDlg { Q_OBJECT void initText(QTextBrowser* p, const char* szFileName); public: AboutDlgImpl(QWidget* pParent = 0); ~AboutDlgImpl(); protected slots: void on_m_pOkB_clicked() { accept(); } void onHelp(); }; #endif MP3Diags-1.0.12.079/src/DirFilterDlgImpl.h0000644000175000001440000000620111230111215016543 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DirFilterDlgImplH #define DirFilterDlgImplH #include "ui_DirFilter.h" #include "DoubleList.h" class CommonData; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class DirFilterDlgImpl : public QDialog, private Ui::DirFilterDlg, public ListPainter { Q_OBJECT CommonData* m_pCommonData; void logState(const char* szPlace) const; void populateLists(); /*override*/ int getColCount() const { return 1; } /*override*/ std::string getColTitle(int /*nCol*/) const { return "Folder"; } /*override*/ void getColor(int /*nIndex*/, int /*nColumn*/, bool /*bSubList*/, QColor& /*bckgColor*/, QColor& /*penColor*/, double& /*dGradStart*/, double& /*dGradEnd*/) const { } /*override*/ int getColWidth(int /*nCol*/) const { return -1; } // positive values are used for fixed widths, while negative ones are for "stretched" /*override*/ int getHdrHeight() const; /*override*/ std::string getTooltip(TooltipKey eTooltipKey) const; /*override*/ Qt::Alignment getAlignment(int nCol) const; /*override*/ void reset(); public: DirFilterDlgImpl(CommonData* pCommonData, QWidget *pParent = 0); ~DirFilterDlgImpl(); private slots: void on_m_pOkB_clicked(); void on_m_pCancelB_clicked(); void onAvlDoubleClicked(int nRow); void onHelp(); }; #endif // #ifndef DirFilterDlgImplH MP3Diags-1.0.12.079/src/CheckedDir.h0000644000175000001440000000610611200236011015376 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef CheckedDirH #define CheckedDirH #include #include #include class QTreeView; class CheckedDirModel : public QDirModel { /*override*/ int columnCount(const QModelIndex&) const { return 1; } /*override*/ Qt::ItemFlags flags(const QModelIndex& ndx) const { return QDirModel::flags(ndx) | (m_bUserCheckable ? Qt::ItemIsUserCheckable | Qt::ItemIsTristate : Qt::ItemIsTristate); } /*override*/ QVariant data(const QModelIndex& index, int nRole = Qt::DisplayRole) const; bool setData(const QModelIndex& index, const QVariant& value, int nRole /*= Qt::EditRole*/); // non-reflexive (isDescendant(s, s) is false) // order: "" is above "/"; "/" is above the rest; bool isDescendant(const QString& s1, const QString& s2) const; bool m_bUserCheckable; std::vector m_vCheckedDirs; // strings are not terminated with the path separator, excepting for the root std::vector m_vUncheckedDirs; void expandNode(const QString& s, QTreeView* pTreeView); public: enum { NOT_USER_CHECKABLE, USER_CHECKABLE }; CheckedDirModel(QObject* pParent, bool bUserCheckable) : QDirModel(pParent), m_bUserCheckable(bUserCheckable) {} void setDirs(const std::vector& vstrCheckedDirs, const std::vector& vstrUncheckedDirs, QTreeView* pTreeView); // besides assigning the vectors, also expands the tree to show them std::vector getCheckedDirs() const; std::vector getUncheckedDirs() const; void expandNodes(QTreeView* pTreeView); }; #endif MP3Diags-1.0.12.079/src/Id3V230Stream.cpp0000644000175000001440000010372511345514173016141 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "Id3V230Stream.h" #include "Id3V240Stream.h" #include "Helpers.h" #include "Id3Transf.h" #include "CommonData.h" using namespace std; using namespace pearl; //============================================================================================================ //============================================================================================================ //============================================================================================================ // !!! Note that the exceptions thrown by Id3V230Frame::Id3V230Frame() pass through Id3V230Stream, so they should have a type suited for this situation. // Also note that by the time Id3V230Frame::Id3V230Frame() gets executed, it was already decided that we deal with an Id3V230Stream. Now we should see if it is valid or broken. Id3V230Frame::Id3V230Frame(NoteColl& notes, istream& in, streampos pos, bool bHasUnsynch, streampos posNext, StringWrp* pFileName) : Id3V2Frame(pos, bHasUnsynch, pFileName) { in.seekg(pos); char bfr [ID3_FRAME_HDR_SIZE]; int nHdrBytesSkipped (0); int nRead (readID3V2(bHasUnsynch, in, bfr, ID3_FRAME_HDR_SIZE, posNext, nHdrBytesSkipped)); MP3_CHECK (ID3_FRAME_HDR_SIZE == nRead || (nRead >= 1 && 0 == bfr[0]), pos, id3v2FrameTooShort, StreamIsBroken(Id3V230Stream::getClassDisplayName(), "Truncated ID3V2.3.0 tag.")); unsigned char* p (reinterpret_cast (bfr)); if (0 == bfr[0]) { // padding //m_nMemDataSize = -1; // !!! not needed; the constructor makes it -1 //m_nDiskDataSize = -1; // !!! not needed; the constructor makes it -1 m_szName[0] = 0; return; } //inspect(bfr, ID3_FRAME_HDR_SIZE); strncpy(m_szName, bfr, 4); m_szName[4] = 0; m_nMemDataSize = (p[4] << 24) + (p[5] << 16) + (p[6] << 8) + (p[7] << 0); MP3_CHECK (m_nMemDataSize >= 0 && m_nMemDataSize < 5000000, pos, id3v230CantReadFrame, StreamIsBroken(Id3V230Stream::getClassDisplayName(), "Broken ID3V2.3.0 tag.")); { char c (m_szName[0]); MP3_CHECK (c >= 'A' && c <= 'Z', pos, id3v2InvalidName, StreamIsBroken(Id3V230Stream::getClassDisplayName(), "ID3V2.3.0 tag containing a frame with an invalid name: " + getReadableName() + ".")); for (int i = 1; i < 4; ++i) { char c (m_szName[i]); MP3_CHECK ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'), pos, id3v2InvalidName, StreamIsBroken(Id3V230Stream::getClassDisplayName(), "ID3V2.3.0 tag containing a frame with an invalid name: " + getReadableName() + ".")); //ttt3 ASCII-specific } } m_cFlag1 = bfr[8]; m_cFlag2 = bfr[9]; //MP3_CHECK (0 == (m_cFlag1 & ~(0x40 | 0x1f)), pos, "Invalid ID3V2.3.0 frame. Flags1 not supported.", Id3V230Stream::NotId3V2()); // !!! 0x1f is for flags that are supposed to be always 0 but aren't; the best way to deal with them seems to be to ignore them // 2008.08.25 - seems best to just ignore these flags ("Tag alter preservation", "File alter preservation" and "Read only") //ttt2 revisit this decision MP3_CHECK (0 == (m_cFlag2 & ~(0x00 | 0x1f)), pos, id3v2UnsuppFlags2, StreamIsUnsupported(Id3V230Stream::getClassDisplayName(), "ID3V2.3.0 tag containing a frame with an unsupported flag.")); if (0 != (m_cFlag1 & 0x1f)) { MP3_NOTE (pos, id3v2IncorrectFlg1); } if (0 != (m_cFlag2 & 0x1f)) { MP3_NOTE (pos, id3v2IncorrectFlg2); } m_vcData.resize(m_nMemDataSize); int nContentBytesSkipped (0); nRead = 0; if (m_nMemDataSize > 0) { nRead = readID3V2(bHasUnsynch, in, &m_vcData[0], m_nMemDataSize, posNext, nContentBytesSkipped); } if (m_nMemDataSize != nRead) { vector().swap(m_vcData); MP3_THROW (pos, id3v2FrameTooShort, StreamIsBroken(Id3V230Stream::getClassDisplayName(), "Truncated ID3V2.3.0 tag.")); } m_nDiskHdrSize = ID3_FRAME_HDR_SIZE + nHdrBytesSkipped; m_nDiskDataSize = m_nMemDataSize + nContentBytesSkipped; try { try { getUtf8String(); Id3V2FrameDataLoader wrp (*this); const char* pData (wrp.getData()); if ('T' == m_szName[0]) { if (!isTxxx() && 0 == m_nMemDataSize) { // this is really invalid; text frames must have at least a byte; however, by doing these we make sure that an empty (i.e. having a single byte, for text encoding) frame gets copied if the tag is edited; m_vcData.clear(); m_vcData.push_back(0); m_nMemDataSize = cSize(m_vcData); MP3_NOTE_D (pos, id3v2EmptyTextFrame, Notes::id3v2EmptyTextFrame().getDescription() + string(" (Frame:") + m_szName + ")"); } else if (isTxxx() && m_nMemDataSize <= 1) { // this is really invalid; text frames must have at least a byte; however, by doing these we make sure that an empty (i.e. having a single byte, for text encoding) frame gets copied if the tag is edited; m_vcData.clear(); static const char* szInvalid ("INVALID"); m_vcData.push_back(0); // latin1 m_vcData.insert(m_vcData.end(), szInvalid, szInvalid + strlen(szInvalid)); // description m_vcData.push_back(0); // terminator m_vcData.insert(m_vcData.end(), szInvalid, szInvalid + strlen(szInvalid)); // value m_nMemDataSize = cSize(m_vcData); MP3_NOTE_D (pos, id3v2EmptyTextFrame, Notes::id3v2EmptyTextFrame().getDescription() + string(" (Frame:") + m_szName + ")"); // ttt2 actually TXXX is not text } else { if (3 == pData[0]) { //MP3_NOTE (pos, id3v230UsesUtf8); MP3_NOTE_D (pos, id3v230UsesUtf8, Notes::id3v230UsesUtf8().getDescription() + string(" (Frame:") + m_szName + ")"); // perhaps drop the frame name if too many such notes get generated } } //ttt2 add check for embedded 0 for TXXX, to split the value into descr and val } } catch (const NotId3V2Frame&) { MP3_THROW (pos, id3v2TextError, StreamIsBroken(Id3V230Stream::getClassDisplayName(), "ID3V2.3.0 tag containing a broken text frame named " + getReadableName() + ".")); } catch (const UnsupportedId3V2Frame&) { MP3_THROW (pos, id3v230UnsuppText, StreamIsUnsupported(Id3V230Stream::getClassDisplayName(), "ID3V2.3.0 tag containing a text frame named " + getReadableName() + " using unsupported characters.")); //ttt2 NotSupported is not specific enough; this might need reviewing in the future } } catch (const std::bad_alloc&) { throw; } catch (...) { vector().swap(m_vcData); throw; } if (m_nMemDataSize > 150) // ttt2 perhaps make configurable { // if the frame needs a lot of space, erase the data from memory; it will be retrieved from the disk when needed; vector().swap(m_vcData); } } // needed by Id3V230StreamWriter::addBinaryFrame(), so objects created with this constructor don't get serialized; destroys vcData by doing a swap for its own representation Id3V230Frame::Id3V230Frame(const std::string& strName, vector& vcData) : Id3V2Frame(0, Id3V2Frame::NO_UNSYNCH, 0) { CB_CHECK1 (4 == cSize(strName), NotId3V2Frame()); strcpy(m_szName, strName.c_str()); m_nMemDataSize = cSize(vcData); m_nDiskDataSize = -1; m_nDiskHdrSize = -1; m_cFlag1 = 0; m_cFlag2 = 0; // m_pos = ...; //m_szFileName = 0; //m_bHasUnsynch = false; vcData.swap(m_vcData); } /*override*/ Id3V230Frame::~Id3V230Frame() { //qDebug("Id3V230Frame destr %p", this); //qDebug(" Id3V230Frame destr %p", m_pData); } // may return multiple null characters; it's the job of getUtf8String() to deal with them; // chars after the first null are considered comments (or after the second null, for TXXX); string Id3V230Frame::getUtf8StringImpl() const { if ('T' != m_szName[0]) { return ""; } // have a "pos" to pass here and ability to log; could also be used for large tags, to not store them in memory yet have them available // also use pos below // or perhaps forget these and throw exceptions that have error messages, catch them and log/show dialogs // 2008.07.12 - actually all these proposals don't seem to work well: the callers don't catch the exceptions thrown here and wouldn't know what to do with them; there's no good place to display the errors (the end user isn't supposed to look at logs); it seems better to not throw, but return a string describing the problem; // 2008.07.12 - on a second thought - throw but call this on the constructor, where it can be logged properly; if it worked on the constructor it should work later too CB_CHECK1 (m_nMemDataSize > 0, NotId3V2Frame()); //ttt2 perhaps other excp Id3V2FrameDataLoader wrp (*this); const char* pData (wrp.getData()); string s; if (0 == pData[0]) { // Latin-1 for (int i = 1; i < m_nMemDataSize; ++i) { unsigned char c (pData[i]); if (c < 128) { // !!! 0 is OK s += char(c); } else { m_bHasLatin1NonAscii = true; unsigned char c1 (0xc0 | (c >> 6)); unsigned char c2 (0x80 | (c & 0x3f)); s += char(c1); s += char(c2); } } } else if (1 == pData[0]) { s = utf8FromBomUtf16(pData + 1, m_nMemDataSize - 1); } else if (3 == pData[0]) // not valid, but used by some tools; a note will get generated in this case { s = string(pData + 1, m_nMemDataSize - 1); } else { // pData[0] has an invalid value CB_THROW1 (NotId3V2Frame()); } return s; } /*override*/ bool Id3V230Frame::discardOnChange() const { return 0 != (m_cFlag1 & 0xc0); } //============================================================================================================ //============================================================================================================ //============================================================================================================ Id3V230Stream::Id3V230Stream(int nIndex, NoteColl& notes, istream& in, StringWrp* pFileName, bool bAcceptBroken /*= false*/) : Id3V2StreamBase(nIndex, in, pFileName) { StreamStateRestorer rst (in); streampos pos (m_pos); char bfr [ID3_HDR_SIZE]; MP3_CHECK_T (ID3_HDR_SIZE == read(in, bfr, ID3_HDR_SIZE), pos, "Invalid ID3V2.3.0 tag. File too small.", NotId3V2()); MP3_CHECK_T ('I' == bfr[0] && 'D' == bfr[1] && '3' == bfr[2], pos, "Invalid ID3V2.3.0 tag. Invalid ID3V2 header.", NotId3V2()); MP3_CHECK ((3 == bfr[3] || 4 == bfr[3]) && 0 == bfr[4], pos, id3v2UnsuppVer, StreamIsUnsupported(Id3V2StreamBase::getClassDisplayName(), "Unsupported version of ID3V2 tag" + ((bfr[3] >= 0 && bfr[3] <=9 && bfr[4] >= 0 && bfr[4] <=9) ? string(": ID3V2.") + char('0' + bfr[3]) + '.' + char('0' + bfr[4]) : "."))); // !!! tests for both 2.3.0 and 2.4.0 to make sure a SUPPORT message is generated (as opposed to TRACE); this test could be done either here or in ID3V240 (or in a separate function); MP3_CHECK_T (3 == bfr[3] && 0 == bfr[4], pos, "Invalid ID3V2.3.0 tag. Invalid ID3V2.3.0 header.", NotId3V2()); m_nTotalSize = getId3V2Size (bfr); m_cFlags = bfr[5]; MP3_CHECK (0 == (m_cFlags & 0x7f), pos, id3v2UnsuppFlag, StreamIsUnsupported(Id3V230Stream::getClassDisplayName(), "ID3V2 tag with unsupported flag.")); //ttt2 review, support streampos posNext (pos); posNext += m_nTotalSize; pos += ID3_HDR_SIZE; bool bHasLatin1NonAscii (false); // if it has a text frame that uses Latin1 encoding and has chars between 128 and 255 try { for (;;) { long long nDiff (pos - posNext); if (nDiff >= 0) { break; } Id3V230Frame* p (new Id3V230Frame(notes, in, pos, hasUnsynch(), posNext, m_pFileName)); bHasLatin1NonAscii = p->m_bHasLatin1NonAscii || bHasLatin1NonAscii; if (-1 == p->m_nMemDataSize) { // it encountered zeroes, which signals the beginning of padding //ttt2 should check that there's no garbage after the first zero m_nPaddingSize = posNext - pos; delete p; break; } m_vpFrames.push_back(p); pos += p->m_nDiskHdrSize + p->m_nDiskDataSize; } } catch (const std::bad_alloc&) { throw; } catch (...) { if (bAcceptBroken) { preparePicture(notes); return; } clearPtrContainer(m_vpFrames); throw; } preparePicture(notes); checkDuplicates(notes); checkFrames(notes); if (bHasLatin1NonAscii) { MP3_NOTE (m_pos, id3v2HasLatin1NonAscii); } switch (m_eImageStatus) { case ImageInfo::NO_PICTURE_FOUND: MP3_NOTE (m_pos, id3v2NoApic); break; case ImageInfo::ERROR_LOADING: MP3_NOTE (m_pos, id3v2CouldntLoadPic); break; //case ImageInfo::USES_LINK: MP3_NOTE (m_pos, id3v2LinkNotSupported); break; // !!! already reported by id3v2LinkInApic, so no need for another note; case ImageInfo::LOADED_NOT_COVER: MP3_NOTE (m_pos, id3v2NotCoverPicture); break; default:; } if (m_nPaddingSize > Id3V230StreamWriter::DEFAULT_EXTRA_SPACE + 4096) //ttt2 hard-coded { MP3_NOTE (m_pos + (getSize() - m_nPaddingSize), id3v2PaddingTooLarge); } if (m_vpFrames.empty()) { MP3_NOTE (m_pos, id3v2EmptyTag); } MP3_TRACE (m_pos, "Id3V230Stream built."); { pos = m_pos; pos += m_nTotalSize - 1; in.seekg(pos); char c; MP3_CHECK (1 == read(in, &c, 1), m_pos, id3v230CantReadFrame, NotId3V2()); } rst.setOk(); } /*override*/ TagReader::SuportLevel Id3V230Stream::getSupport(Feature eFeature) const { switch (eFeature) { case TITLE: case ARTIST: case TRACK_NUMBER: case TIME: case GENRE: case IMAGE: case ALBUM: case RATING: case COMPOSER: case VARIOUS_ARTISTS: return READ_ONLY; default: return NOT_SUPPORTED; } /*{ , , , , , , , }; enum SuportLevel { NOT_SUPPORTED, , READ_WRITE };*/ } /*override*/ TagTimestamp Id3V230Stream::getTime(bool* pbFrameExists /*= 0*/) const { return get230TrackTime(pbFrameExists); } //============================================================================================================ //============================================================================================================ //============================================================================================================ Id3V230StreamWriter::~Id3V230StreamWriter() { /*for (int i = 0; i < cSize(m_vpOwnFrames); ++i) { qDebug("remove %p", m_vpOwnFrames[i]); //qDebug(" remove %p", m_vpOwnFrames[i]->m_pData); }*/ clearPtrContainer(m_vpOwnFrames); } Id3V230StreamWriter::Id3V230StreamWriter(bool bKeepOneValidImg, bool bFastSave, Id3V2StreamBase* p, const std::string& strDebugFileName) : m_bKeepOneValidImg(bKeepOneValidImg), m_bFastSave(bFastSave), m_strDebugFileName(strDebugFileName) { if (0 != p) { if (m_bKeepOneValidImg) { const Id3V2Frame* pPic (0); for (int i = 0; i < cSize(p->getFrames()); ++i) { const Id3V2Frame* q (p->getFrames()[i]); CB_ASSERT1 ((0 == strcmp(q->m_szName, KnownFrames::LBL_IMAGE())) ^ (Id3V2Frame::NO_APIC == q->m_eApicStatus), m_strDebugFileName); if (Id3V2Frame::NO_APIC == q->m_eApicStatus) { bool bCopyFrame (true); if ('T' == q->m_szName[0] && q->m_nMemDataSize > 0 && 0 != dynamic_cast(q)) { // check for UTF-8 encoding Id3V2FrameDataLoader ldr (*q); const char* pData (ldr.getData()); if (3 == pData[0]) { // UTF-8 bCopyFrame = false; addTextFrame(q->m_szName, q->getRawUtf8String()); } } if (bCopyFrame) { m_vpAllFrames.push_back(q); } } else { if ((0 == pPic && q->m_eApicStatus > Id3V2Frame::ERR) || (0 != pPic && pPic->m_eApicStatus < q->m_eApicStatus)) { pPic = q; } } } if (0 != pPic) { m_vpAllFrames.push_back(pPic); } } else { m_vpAllFrames.insert(m_vpAllFrames.end(), p->getFrames().begin(), p->getFrames().end()); } TagTimestamp time; try { time = p->getTime(); } catch (const TagTimestamp::InvalidTime&) { } setRecTime(time); } } void Id3V230StreamWriter::setRecTime(const TagTimestamp& time) { removeFrames(KnownFrames::LBL_TIME_YEAR_230()); removeFrames(KnownFrames::LBL_TIME_DATE_230()); removeFrames(KnownFrames::LBL_TIME_240()); if (0 == time.getYear()[0]) { return; } addTextFrame(KnownFrames::LBL_TIME_YEAR_230(), time.getYear()); if (0 == time.getDayMonth()[0]) { return; } addTextFrame(KnownFrames::LBL_TIME_DATE_230(), time.getDayMonth()); } // this only changes the frames that correspond to the active settings in the configuration; // if WMP handling is disabled, TPE2 is left untouched; if WMP handling is enabled, TPE2 is either removed or set to "Various Artists", based on "b" // if iTunes handling is disabled, TCON is left untouched; if WMP handling is enabled, TCON is either removed or set to "1", based on "b" void Id3V230StreamWriter::setVariousArtists(bool b) { const CommonData* pCommonData (getCommonData()); if (pCommonData->m_bWmpVarArtists) { removeFrames(KnownFrames::LBL_WMP_VAR_ART()); if (b) { addTextFrame(KnownFrames::LBL_WMP_VAR_ART(), "Various Artists"); } } if (pCommonData->m_bItunesVarArtists) { removeFrames(KnownFrames::LBL_ITUNES_VAR_ART()); if (b) { addTextFrame(KnownFrames::LBL_ITUNES_VAR_ART(), "1"); } } } #ifdef MASWDEFWDWDWDW namespace { void view(QString q) { qDebug("str=%s, sz=%d", q.toUtf8().data(), q.size()); { qDebug("utf16()"); const ushort* pUtf16 (q.utf16()); for (int i = 0; 0 != pUtf16[i]; ++i) { qDebug(" %d", int(pUtf16[i])); } } { qDebug("toUcs4()"); QVector v (q.toUcs4()); for (int i = 0; i < v.size(); ++i) { qDebug(" %d", int(v[i])); } } } void testUnicode() //ttt2 retest this; for now it looks like everything is truncated to 16 bits { QString q; q += QChar(49); view(q); q += QChar(int(65536 + 65)); q += QChar(int(65536 + 650)); q += QChar(int(65536 + 6500)); q += QChar(int(65536 + 35000)); view(q); //q += QChar(int(0xd801)); // surrogate //view(q); } } #endif BOOST_STATIC_ASSERT(2 == sizeof(ushort)); // strVal is UTF8; the frame will use ASCII if possible and UTF16 otherwise (so if there's a char with a code above 127, UTF16 gets used, to avoid codepage issues for codes between 128 and 255); nothing is added if strVal is empty; all zeroes are saved and not considered terminators; void Id3V230StreamWriter::addTextFrame(const std::string& strName, const std::string& strVal) { //http://www.id3.org/id3v2.3.0#head-1a37d4a15deafc294208ccfde950f77e47000bca bool bIsAscii (true); int n (cSize(strVal)); for (int i = 0; i < n; ++i) { unsigned char c (strVal[i]); if (c >= 128) { bIsAscii = false; break; } } vector vcData; int nSize (0); if (bIsAscii) { nSize = n + 1; // strings are not null-terminated, but there's the "text encoding" byte vcData.resize(nSize); //qDebug("add %p", p); vcData[0] = 0; copy(strVal.c_str(), strVal.c_str() + nSize - 1, &vcData[0] + 1); } else { QString s (convStr(strVal)); const ushort* pUtf16 (s.utf16()); //int nUtf16Size (0); //while (0 != pUtf16[nUtf16Size++]) {} // there is probably some strlen equivalent, but wcslen isn't that, because it uses wchar_t instead of ushort, which on Unix is usually 4-byte //--nUtf16Size; int nUtf16Size (s.size()); //ttt2 not quite right, but it seems that QString truncates Unicode to 16 bits anyway, in which case it's fine; see testUnicode(), above nSize = 2*nUtf16Size + 3; // "text encoding" byte, BOM, no null terminator vcData.resize(nSize); vcData[0] = 1; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN int nOrder (1); // x86 #else int nOrder (0); #endif vcData[2 - nOrder] = char(0xff); vcData[1 + nOrder] = char(0xfe); const char* pcUtf16 (reinterpret_cast(pUtf16)); copy(pcUtf16, pcUtf16 + nSize - 3, &vcData[0] + 3); } //inspect(p, nSize); addBinaryFrame(strName, vcData); } // destroys vcData by doing a swap for its own representation; asserts that strName is not APIC void Id3V230StreamWriter::addBinaryFrame(const std::string& strName, vector& vcData) { Id3V230Frame* p (new Id3V230Frame(strName, vcData)); CB_ASSERT1 (0 != strcmp(KnownFrames::LBL_IMAGE(), p->m_szName), m_strDebugFileName); addNonOwnedFrame(p); m_vpOwnFrames.push_back(p); } //ttt2 perhaps something like this: if there's 1 "Other" pic and a "Cover" is added; based on config: 1) delete "Other"; 2) delete "cover"; 3) keep both; //ttt2 the option should be used to mark an "Other" pic as "Cover" in the tag editor, so it doesn't trigger saving. // the image type is ignored; images are always added as cover; // if there is an APIC frame with the same image, it is removed (it doesn't matter if it has different type, description ...); // ttt2 description should be counted too, if used // if cover image already exists it is removed; void Id3V230StreamWriter::addImg(std::vector& vcData) { int n (cSize(vcData)); CB_ASSERT1 (n > 100, m_strDebugFileName); char* p (&vcData[0]); CB_ASSERT1 (0 == *p || 3 == *p, m_strDebugFileName); // text encoding // this should be kept in synch with Id3V2StreamBase::decodeApic() //ttt1 triggered according to mail; might have been caused by SmallerImageRemover::apply() incorrectly assuming that an invalid APIC frame is a large picture; the test using the frame name was replaced after the assert with a test using m_eApicStatus; will have to wait until some MP3 is received that triggered this to be sure char* q (p + 1); for (; q < p + 90 && 0 != *q; ++q) {} CB_ASSERT1 (0 == *q, m_strDebugFileName); ++q; *q = Id3V2Frame::PT_COVER; ++q; for (; q < p + n && 0 != *q; ++q) {} CB_ASSERT1 (0 == *q, m_strDebugFileName); ++q; // now q points to the beginning of the actual image int nOffs (q - p); int nImgSize (n - nOffs); removeFrames(KnownFrames::LBL_IMAGE(), Id3V2Frame::PT_COVER); { e1: for (int i = 0; i < cSize(m_vpAllFrames); ++i) { const Id3V2Frame* pFrm (m_vpAllFrames[i]); if (0 == strcmp(KnownFrames::LBL_IMAGE(), pFrm->m_szName)) { if (pFrm->m_nImgSize == nImgSize) { Id3V2FrameDataLoader ldr (*pFrm); if (0 == memcmp(&vcData[nOffs], ldr.getData() + pFrm->m_nImgOffset, nImgSize)) // !!! related to ImageInfo::operator==() status is ignored in both places //ttt2 review decision to ignore status { removeFrames(KnownFrames::LBL_IMAGE(), pFrm->m_nPictureType); goto e1; } } } } } { Id3V230Frame* p (new Id3V230Frame(KnownFrames::LBL_IMAGE(), vcData)); p->m_nPictureType = Id3V2Frame::PT_COVER; // probably pointless, because the frame is only used internally and what gets written is vcData, regardless of p->m_nPictureType addNonOwnedFrame(p); m_vpOwnFrames.push_back(p); } } // for UTF8 text frames, a new, owned, frame will be added instead void Id3V230StreamWriter::addNonOwnedFrame(const Id3V2Frame* p) { //qDebug("add %p", p); //qDebug(" add %p", pData); if (0 == strcmp(KnownFrames::LBL_IMAGE(), p->m_szName) || !KnownFrames::canHaveDuplicates(p->m_szName)) { removeFrames(p->m_szName, p->m_nPictureType); // m_vpAllFrames.insert(m_vpAllFrames.begin(), p); //ttt2 putting a front cover image after a back cover might not be the best idea; see if it makes sense to sort the frames; (perhaps have something to sort all frames before saving) } if ('T' == p->m_szName[0] && p->m_nMemDataSize > 0 && 0 != dynamic_cast(p)) { // check for UTF-8 encoding; for UTF8 an owned frame will be added instead Id3V2FrameDataLoader ldr (*p); const char* pData (ldr.getData()); if (3 == pData[0]) { // UTF-8 addTextFrame(p->m_szName, p->getRawUtf8String()); return; } } m_vpAllFrames.push_back(p); } // if multiple frames with the same name exist, they are all removed; asserts that nPictureType is -1 for non-APIC frames; if nPictureType is -1 and strName is APIC, it removes all APIC frames void Id3V230StreamWriter::removeFrames(const std::string& strName, int nPictureType /*= -1*/) { const Id3V2Frame* p; for (int i = cSize(m_vpAllFrames) - 1; i >= 0; --i) { p = m_vpAllFrames[i]; CB_ASSERT1 (-1 == nPictureType || KnownFrames::LBL_IMAGE() == strName, m_strDebugFileName); if (p->m_szName == strName && (p->m_nPictureType == nPictureType || m_bKeepOneValidImg || -1 == nPictureType)) { m_vpAllFrames.erase(m_vpAllFrames.begin() + i); } } for (int i = cSize(m_vpOwnFrames) - 1; i >= 0; --i) { p = m_vpOwnFrames[i]; CB_ASSERT1 (-1 == nPictureType || KnownFrames::LBL_IMAGE() == strName, m_strDebugFileName); if (p->m_szName == strName && (p->m_nPictureType == nPictureType || m_bKeepOneValidImg || -1 == nPictureType)) { delete p; m_vpOwnFrames.erase(m_vpOwnFrames.begin() + i); } } } //ttt2 after rescanning when note text changed, the refound error was not visible once (couldn't replicate) static int getUnsynchVal(int x) { return (x & 0x0000007f) | ((x & 0x00003f80) << 1) | ((x & 0x001fc000) << 2) | ((x & 0x0fe00000) << 3); } /*static*/ const int Id3V230StreamWriter::DEFAULT_EXTRA_SPACE (1024); // throws WriteError if it cannot write, including the case when nTotalSize is too small; // if nTotalSize is >0, the padding will be be whatever is left; // if nTotalSize is <0 and m_bFastSave is true, there will be a padding of around ImageInfo::MAX_IMAGE_SIZE+Id3V2Expander::EXTRA_SPACE; // if (nTotalSize is <0 and m_bFastSave is false) or if nTotalSize is 0 (regardless of m_bFastSave), there will be a padding of between DEFAULT_EXTRA_SPACE and DEFAULT_EXTRA_SPACE + 511; // (0 discards extra padding regardless of m_bFastSave) void Id3V230StreamWriter::write(ostream& out, int nTotalSize /*= -1*/) const { int n (cSize(m_vpAllFrames)); //if (0 == n) { return; } char bfr [Id3V230Stream::ID3_HDR_SIZE] = "ID3\3\0\0"; // no unsynch, no extended header, no experimental int nSize (0); for (int i = 0; i < n; ++i) { const Id3V2Frame* p (m_vpAllFrames[i]); if (!p->discardOnChange()) { nSize += Id3V2Frame::ID3_FRAME_HDR_SIZE + m_vpAllFrames[i]->m_nMemDataSize; } } //if (0 == nSize) { return; } // all frames have discardOnChange int nPaddedSize; if (nTotalSize > 0) { nPaddedSize = nTotalSize; } else if (0 == nTotalSize || !m_bFastSave) { nPaddedSize = ((nSize + (512 - 1) + DEFAULT_EXTRA_SPACE)/512)*512; } else { // <0 and m_bFastSave set nPaddedSize = nSize + ImageInfo::MAX_IMAGE_SIZE + Id3V2Expander::EXTRA_SPACE; } //if (nExtraSpace < 0) { nExtraSpace = ; } //int nPaddedSize (((nSize + (512 - 1) + nExtraSpace)/512)*512); nPaddedSize -= Id3V230Stream::ID3_HDR_SIZE; CB_CHECK1 (nPaddedSize >= nSize, WriteError()); //put32BitBigEndian(1, &bfr[6]); put32BitBigEndian(getUnsynchVal(nPaddedSize), &bfr[6]); out.write(bfr, 10); struct LdrPtrList { LdrPtrList(int n) : m_vpLdr(n) {} ~LdrPtrList() { clearPtrContainer(m_vpLdr); } vector m_vpLdr; }; LdrPtrList ldrList (n); for (int i = 0; i < n; ++i) { const Id3V2Frame* p (m_vpAllFrames[i]); if (!p->discardOnChange()) { ldrList.m_vpLdr[i] = new Id3V2FrameDataLoader (*p); // this loads the data, if it's not already loaded } } for (int i = 0; i < n; ++i) { const Id3V2Frame* p (m_vpAllFrames[i]); if (!p->discardOnChange()) { out.write(p->m_szName, 4); put32BitBigEndian(p->m_nMemDataSize, &bfr[0]); bfr[4] = 0; //bfr[4] = p->m_cFlag1; //ttt2 use flags if any makes sense bfr[5] = 0; //bfr[5] = p->m_cFlag2; out.write(bfr, 6); //Id3V2FrameDataLoader wrp (*p); // this loads the data, if it's not already loaded out.write(ldrList.m_vpLdr[i]->getData(), p->m_nMemDataSize); } } writeZeros(out, nPaddedSize - nSize); CB_CHECK1 (out, WriteError()); } namespace { struct SortFrm { bool operator()(const Id3V2Frame* p1, const Id3V2Frame* p2) { int n (strcmp(p1->m_szName, p2->m_szName)); if (0 != n) { return n < 0; } if (p1->m_nMemDataSize != p2->m_nMemDataSize) { return p1->m_nMemDataSize < p2->m_nMemDataSize; } Id3V2FrameDataLoader wrp1 (*p1); Id3V2FrameDataLoader wrp2 (*p2); n = memcmp(wrp1.getData(), wrp2.getData(), p1->m_nMemDataSize); return n < 0; } }; } // returns true if all of these happen: pId3V2Stream is ID3V2.3.0, no unsynch is used, the frames are identical except for their order; padding is ignored; /*bool Id3V230StreamWriter::equalTo(Id3V2StreamBase* p) const { if (0 == p) { //qDebug("diff ver"); return false; } if (p->hasUnsynch()) { //qDebug("diff unsynch"); return false; } return contentEqualTo(p); }*/ bool Id3V230StreamWriter::contentEqualTo(Id3V2StreamBase* p) const { const vector& v (p->getFrames()); if (cSize(m_vpAllFrames) != cSize(v)) { //qDebug("diff frame cnt"); return false; } vector v1 (m_vpAllFrames); vector v2; v2.insert(v2.end(), v.begin(), v.end()); SortFrm s; sort(v1.begin(), v1.end(), s); sort(v2.begin(), v2.end(), s); /*for (int i = 0, n = cSize(v1); i < n; ++i) { qDebug("frm %s %d %s %d", v1[i]->m_szName, v1[i]->m_nMemDataSize, v2[i]->m_szName, v2[i]->m_nMemDataSize); }//Id3V2Frame p; p.*/ for (int i = 0, n = cSize(v1); i < n; ++i) { if (s(v1[i], v2[i]) || s(v2[i], v1[i])) { //qDebug("diff content %s (%s) / %s (%s)", v1[i]->m_szName, v1[i]->getUtf8String1().c_str(), v2[i]->m_szName, v2[i]->getUtf8String1().c_str()); return false; } } return true; } //============================================================================================================ //============================================================================================================ //============================================================================================================ /* struct KOKO { KOKO() { Id3V230StreamWriter w; w.addTextFrame("TGRF", "abcd"); QString s ("ab\xfeg"); w.addTextFrame("TQQW", convStr(s)); ofstream_utf8 out ("/r/temp/1/tmp2/e/qqq.mp3", ios::binary); w.write(out); } }; KOKO qwerqwr; */ MP3Diags-1.0.12.079/src/ColumnResizer.cpp0000644000175000001440000005666611265042626016607 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "ColumnResizer.h" //#define PRINT_SIZES #ifdef PRINT_SIZES #include "fstream_unicode.h" #endif using namespace std; //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== SimpleQTableViewWidthInterface::SimpleQTableViewWidthInterface(QTableView& tbl) : TableWidthInterface(tbl.model()->columnCount()), m_tbl(tbl), m_pModel(tbl.model()) { int nCols (m_pModel->columnCount()); m_vbBold.resize(nCols); QFont font (m_tbl.font()); font.setBold(true); QFontMetrics fontMetrics (font); QHeaderView* pHdr (tbl.horizontalHeader()); for (int j = 0; j < nCols; ++j) { if (pHdr->isSectionHidden(j)) { setFixedWidth(j, 0); } else { m_vnHdrWidth[j] = fontMetrics.width(m_pModel->headerData(j, Qt::Horizontal).toString()) + 8/*2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth)*/; // PM_DefaultFrameWidth is not THE thing to use, but it's one way to get some spacing for the header; (well it turned up to be too small, so it got replaced by 8; probably look at the source to see what should be used) } } } /*override*/ int SimpleQTableViewWidthInterface::getRequestedWidth(int nRow, int nCol) const { if (hasFixedWidth(nCol)) { return m_vnMinWidth[nCol]; } int nMargin (QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1); // this "1" should probably be another "metric" constant QFont font (m_tbl.font()); font.setBold(m_vbBold.at(nCol)); QFontMetrics fontMetrics (font); QString qstrVal (m_pModel->data(m_pModel->index(nRow, nCol)).toString()); int nWidth (fontMetrics.width(qstrVal)); return nWidth + 2*nMargin + 1; // the "+1" is for the width of the line separating columns } /*override*/ int SimpleQTableViewWidthInterface::getTableWidth() const // space available for data columns { int nRes (m_tbl.width() - m_tbl.verticalHeader()->sizeHint().width() - 2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth)); // ttt2 not sure if PM_DefaultFrameWidth is the right param; perhaps looking at the sources might clarify this if (m_tbl.verticalScrollBar()->isVisible()) { nRes -= QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent); // nothing; // Plastique // nRes -= 6; ??? to test //Oxygen // nRes -= 2; // CDE // nRes -= 4; // Motif if (0 != QApplication::style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) { nRes -= 2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, &m_tbl); //ttt2 Qt 4.4 (and below) - specific; in 4.5 there's a QStyle::PM_ScrollView_ScrollBarSpacing } } return nRes; } /*override*/ bool SimpleQTableViewWidthInterface::isHidden(int nCol) const { return m_tbl.horizontalHeader()->isSectionHidden(nCol); } /*override*/ void SimpleQTableViewWidthInterface::setWidth(int nCol, int nWidth) { m_tbl.horizontalHeader()->resizeSection(nCol, nWidth); } /*override*/ int SimpleQTableViewWidthInterface::getRowCount() const { return m_pModel->rowCount(); } /*override*/ int SimpleQTableViewWidthInterface::getColumnCount() const { return m_pModel->columnCount(); } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== SimpleQTreeWidgetWidthInterface::SimpleQTreeWidgetWidthInterface(QTreeWidget& tbl) : TableWidthInterface(tbl.columnCount()), m_tbl(tbl) { int nCols (m_tbl.columnCount()); m_vbBold.resize(nCols); QFont font (m_tbl.font()); font.setBold(true); QFontMetrics fontMetrics (font); QHeaderView* pHdr (tbl.header()); for (int j = 0; j < nCols; ++j) { if (pHdr->isSectionHidden(j)) { setFixedWidth(j, 0); } else { m_vnHdrWidth[j] = fontMetrics.width(m_tbl.headerItem()->text(j)) + 8/*2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth)*/; // PM_DefaultFrameWidth is not THE thing to use, but it's one way to get some spacing for the header; (well it turned up to be too small, so it got replaced by 8; probably look at the source to see what should be used) } } } /*override*/ int SimpleQTreeWidgetWidthInterface::getRequestedWidth(int nRow, int nCol) const { if (hasFixedWidth(nCol)) { return m_vnMinWidth[nCol]; } int nMargin (QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1); // this "1" should probably be another "metric" constant QFont font (m_tbl.font()); font.setBold(m_vbBold.at(nCol)); QFontMetrics fontMetrics (font); QString qstrVal (m_tbl.topLevelItem(nRow)->text(nCol)); int nWidth (fontMetrics.width(qstrVal)); return nWidth + 2*nMargin; } /*override*/ int SimpleQTreeWidgetWidthInterface::getTableWidth() const // space available for data columns { int nRes (m_tbl.width() //- m_tbl.verticalHeader()->sizeHint().width() - 2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth)); // ttt2 not sure if PM_DefaultFrameWidth is the right param; perhaps looking at the sources might clarify this /*if (m_tbl.verticalScrollBar()->isVisible()) { nRes -= QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent); }*/ nRes -= QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent); // just assume that the scrollbar is visible //ttt2 detect somehow when the scrollbar is visible return nRes; } /*override*/ bool SimpleQTreeWidgetWidthInterface::isHidden(int nCol) const { return m_tbl.header()->isSectionHidden(nCol); } /*override*/ void SimpleQTreeWidgetWidthInterface::setWidth(int nCol, int nWidth) { m_tbl.header()->resizeSection(nCol, nWidth); } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== //ttt2 maybe separate text width calculations from resizing, to avoid unneeded calls to QFontMetrics (useful only when resizing a window, so perhaps can be dropped) ColumnResizer::ColumnResizer(TableWidthInterface& intf, int nMaxRows /*= 80*/, bool bFill /*= false*/, bool bConsistentResults /*= false*/) : m_intf(intf), m_nMaxRows(nMaxRows), m_bConsistentResults(bConsistentResults) // if bFill is true, colums are resized wider than needed, so they fill the whole area of the table { autoSize(bFill); } // how many rows from a column can be shown completely for a given size int ColumnResizer::getFitCount(int nCol, int nWidth) const { const vector& v (m_vvAllWidths[nCol]); vector::const_iterator it (lower_bound(v.begin(), v.end(), nWidth)); return it - v.begin(); } double ColumnResizer::SequenceGen::rnd() const { if (RAND_MAX == 32767) { return (0.0 + rand() + rand()*32768)/32768/32768; } return rand()*1.0/RAND_MAX; } ColumnResizer::SequenceGen::SequenceGen(int nTotalRows, int nTargetRows) : m_nCrt(0) { if (nTargetRows > nTotalRows || nTotalRows <= 0) { throw invalid_argument("Invalid params for SequenceGen"); } if (nTotalRows == nTargetRows) { m_vn.resize(nTargetRows); for (int i = 0; i < nTotalRows; ++i) { m_vn[i] = i; } return; } m_vn.reserve(nTargetRows); if (nTotalRows > nTargetRows*2) { set s; while ((int)s.size() < nTargetRows) { int n (int(rnd()*nTotalRows)); if (0 == s.count(n)) { s.insert(n); } } m_vn.insert(m_vn.end(), s.begin(), s.end()); return; } // total not much bigger than target; proceed by elimination; for (int i = 0; i < nTotalRows; ++i) { m_vn.push_back(i); } set s (m_vn.begin(), m_vn.end()); while ((int)s.size() > nTargetRows) { int n (int(rnd()*nTotalRows)); if (0 != s.count(n)) { s.erase(int(rnd()*nTotalRows)); } } m_vn.clear(); m_vn.insert(m_vn.end(), s.begin(), s.end()); } /*struct QQQ { QQQ() { { int tot (20); int tgt (20); ColumnResizer::SequenceGen seq (tot, tgt); for (int i = 0; i < tgt; ++i) cout << seq.getNext() << " "; cout << endl; } { int tot (30); int tgt (20); ColumnResizer::SequenceGen seq (tot, tgt); for (int i = 0; i < tgt; ++i) cout << seq.getNext() << " "; cout << endl; } { int tot (100); int tgt (20); ColumnResizer::SequenceGen seq (tot, tgt); for (int i = 0; i < tgt; ++i) cout << seq.getNext() << " "; cout << endl; } } }; QQQ qqq;//*/ #ifdef PRINT_SIZES void ColumnResizer::printWidths(const char* szLabel) { ofstream_utf8 out ("/home/ciobi/yast.txt", ios_base::app); // !!! has to log to a file for when it's running in a library out << szLabel << ": " << m_nTableWidth << " / "; int qq (0); for (int j = 0; j < m_nCols; ++j) { if (m_intf.isHidden(j)) { out << "[" << m_vColInfo[j].m_nWidth << "] "; } else { out << m_vColInfo[j].m_nWidth << " "; } qq += m_vColInfo[j].m_nWidth; } out << " / " << m_nTotalWidth << "=" << qq << endl; } void ColumnResizer::printCellInfo(const char* szLabel) { ofstream_utf8 out ("/home/ciobi/yast.txt", ios_base::app); // !!! has to log to a file for when it's running in a library out << szLabel << ": " << m_nTableWidth << endl; for (int j = 0; j < m_nCols; ++j) { ColInfo& inf (m_vColInfo[j]); if (m_intf.isHidden(j)) { out << "[" << m_vColInfo[j].m_nWidth << "] "; } else { out << m_vColInfo[j].m_nWidth << " "; } out << ", " << inf.m_nMinWidth << ", " << inf.m_nLargeAvg << ",, " << inf.m_nAskSmall << ", " << inf.m_nAskLarge << ",, " << inf.m_dLargeDev << ",, **" << inf.m_dPrioSmall << "**, " << inf.m_dPrioLarge << endl; } } #else //inline void ColumnResizer::printWidths(const char*) {} //inline void ColumnResizer::printCellInfo(const char*) {} #define printWidths(X) #define printCellInfo(X) #endif void ColumnResizer::readAllWidths() { for (int j = 0; j < m_nCols; ++j) { vector& v (m_vvAllWidths[j]); v.resize(m_nUsedRows); SequenceGen seq (m_nTotalRows, m_nUsedRows); for (int i = 0; i < m_nUsedRows; ++i) { v[i] = m_intf.isHidden(j) ? 0 : m_intf.getRequestedWidth(seq.getNext(), j); // !!! getRequestedWidth() returns the fixed width for "fixed width" columns, so no special test is needed } sort(v.begin(), v.end()); if (!m_intf.hasFixedWidth(j) && !m_intf.isHidden(j) && m_intf.getMinWidthDataHdr(j) > m_vvAllWidths[j][m_nUsedRows - 1]) { m_vvAllWidths[j][m_nUsedRows - 1] = m_intf.getMinWidthDataHdr(j); // this way we avoid doing a lot of "max(m_intf.getMinWidthDataHdr(j), m_vvAllWidths[j][nRows - 1])"; it doesn't matter that the value is destroyed; } } m_nTotalMax = 0; for (int j = 0; j < m_nCols; ++j) { m_nTotalMax += m_vvAllWidths[j][m_nUsedRows - 1]; } } void ColumnResizer::computeColInfo() { int nBeg (m_nUsedRows / 2); int nLargeElemsCnt (m_nUsedRows - nBeg); if (nLargeElemsCnt > 34) { nLargeElemsCnt = nLargeElemsCnt*90/100; // cut 10% } else if (nLargeElemsCnt > 20) { nLargeElemsCnt -= 3; } else if (nLargeElemsCnt > 10) { nLargeElemsCnt -= 2; } else if (nLargeElemsCnt > 3) { nLargeElemsCnt -= 1; } m_nTotalWidth = 0; for (int j = 0; j < m_nCols; ++j) { // assign LargeAvg for width vector& v (m_vvAllWidths[j]); // this contains only zeroes for hidden columns int nSum (0); int nDev (0); for (int i = nBeg; i < nBeg + nLargeElemsCnt; ++i) { nSum += v[i]; int x (v[i] - v[nBeg]); //nDev += x*x; nDev += x; } ColInfo& inf (m_vColInfo[j]); inf.m_nLargeAvg = int(nSum*1.0/nLargeElemsCnt); inf.m_dLargeDev = nDev*1.0/nSum; inf.m_nMinWidth = m_intf.getMinWidthDataHdr(j); if (inf.m_nLargeAvg < inf.m_nMinWidth) { inf.m_nLargeAvg = inf.m_nMinWidth; } if (m_intf.hasFixedWidth(j)) { inf.m_dPrioSmall = inf.m_dPrioLarge = 0; } else { inf.m_nAskSmall = int(inf.m_nLargeAvg*(1 + inf.m_dLargeDev/2)); inf.m_dPrioSmall = 1 - inf.m_dLargeDev*0.8; //inf.m_dPrioSmall *= log(5) - log(inf.m_nLargeAvg*1.0 / m_nTableWidth + 0.02) + 0.5; // narrow colums get increased priority inf.m_nAskLarge = int(inf.m_nLargeAvg*(1 + inf.m_dLargeDev*2)); inf.m_dPrioLarge = 1 - inf.m_dLargeDev*0.8; } } printCellInfo("computeColInfo"); } void ColumnResizer::setUpMaxWidths() { m_nTotalWidth = 0; for (int j = 0; j < m_nCols; ++j) { ColInfo& inf (m_vColInfo[j]); inf.m_nWidth = m_vvAllWidths[j][m_nUsedRows - 1]; m_nTotalWidth += inf.m_nWidth; } printWidths("after setUpMaxWidths"); } void ColumnResizer::setUpAvgWidths() { m_nTotalWidth = 0; for (int j = 0; j < m_nCols; ++j) { ColInfo& inf (m_vColInfo[j]); inf.m_nWidth = inf.m_nLargeAvg; m_nTotalWidth += inf.m_nWidth; } printWidths("after setUpAvgWidths"); } // if MinWidth wasn't specified, LargeAvg is used instead void ColumnResizer::setUpMinWidths() { m_nTotalWidth = 0; for (int j = 0; j < m_nCols; ++j) { ColInfo& inf (m_vColInfo[j]); if (!m_intf.hasFixedWidth(j) && m_intf.getMinWidth(j) > 0) // !!! "m_intf.getMinWidth(inf.m_nCol) > 0" means that a minWidth was explicitely specified (inf.m_nMinWidth also includes the header) { inf.m_nWidth = inf.m_nMinWidth; } else { inf.m_nWidth = inf.m_nLargeAvg; } m_nTotalWidth += inf.m_nWidth; } printWidths("after setUpMinWidths"); } void ColumnResizer::distributeAskSmall() { if (m_nTotalWidth >= m_nTableWidth) { return; } // distribute AskSmall according to prioriries int nAskSmallDiffTotal (0); double dPrioSum (0); for (int j = 0; j < m_nCols; ++j) { if (!m_intf.hasFixedWidth(j)) { ColInfo& inf (m_vColInfo[j]); int nDiff (inf.m_nAskSmall - inf.m_nWidth); nAskSmallDiffTotal += nDiff; // !!! inf.m_nAskSmall >= inf.m_nWidth always dPrioSum += inf.m_dPrioSmall*nDiff; } } if (nAskSmallDiffTotal + m_nTotalWidth <= m_nTableWidth) { // assign all for (int j = 0; j < m_nCols; ++j) { if (!m_intf.hasFixedWidth(j)) { ColInfo& inf (m_vColInfo[j]); inf.m_nWidth = inf.m_nAskSmall; } } m_nTotalWidth += nAskSmallDiffTotal; } else { // use priorities to assign all remaining space to AskSmall for (int j = 0; j < m_nCols; ++j) { if (!m_intf.hasFixedWidth(j)) { ColInfo& inf (m_vColInfo[j]); int nDiff (inf.m_nAskSmall - inf.m_nWidth); //int nAdd (int(nDiff*inf.m_dPrioSmall/dPrioSum)); int nAdd (int(nDiff*inf.m_dPrioSmall*(m_nTableWidth - m_nTotalWidth)/dPrioSum)); inf.m_nWidth += nAdd; m_nTotalWidth += nAdd; } } } printWidths("after distributeAskSmall"); } void ColumnResizer::distributeAskLarge() { if (m_nTotalWidth >= m_nTableWidth) { return; } // distribute AskLarge according to prioriries int nAskLargeDiffTotal (0); double dPrioSum (0); for (int j = 0; j < m_nCols; ++j) { if (!m_intf.hasFixedWidth(j)) { ColInfo& inf (m_vColInfo[j]); int nDiff (inf.m_nAskLarge - inf.m_nWidth); if (nDiff > 0) // !!! while initially we had "inf.m_nAskLarge >= inf.m_nWidth", inf.m_nWidth might have been increased in the meantime { nAskLargeDiffTotal += nDiff; dPrioSum += inf.m_dPrioLarge*nDiff; } } } if (nAskLargeDiffTotal + m_nTotalWidth <= m_nTableWidth) { // assign all for (int j = 0; j < m_nCols; ++j) { if (!m_intf.hasFixedWidth(j)) { ColInfo& inf (m_vColInfo[j]); inf.m_nWidth = inf.m_nAskLarge; } } m_nTotalWidth += nAskLargeDiffTotal; } else { // use priorities to assign all remaining space to AskLarge for (int j = 0; j < m_nCols; ++j) { if (!m_intf.hasFixedWidth(j)) { ColInfo& inf (m_vColInfo[j]); int nDiff (inf.m_nAskLarge - inf.m_nWidth); if (nDiff > 0) { //int nAdd (int(nDiff*inf.m_dPrioLarge/dPrioSum)); //int nAdd (int(nDistr*inf.m_dPrioLarge/dPrioSum*nDiff/nAskLargeDiffTotal)); int nAdd (int(nDiff*inf.m_dPrioLarge*(m_nTableWidth - m_nTotalWidth)/dPrioSum)); inf.m_nWidth += nAdd; m_nTotalWidth += nAdd; } } } } printWidths("after distributeAskLarge"); } void ColumnResizer::distributeRemaining() // several pixels might remain undistributed after distributeAskSmall() and distributeAskLarge() because of rounding errors; they are dealt with here; { printWidths("before distributeRemaining"); if (m_nTotalWidth >= m_nTableWidth) { return; } // distribute what's left int nLeft (m_nTableWidth - m_nTotalWidth); int nVarCols (m_nCols - m_nFixedWidthCount); int nStep (nLeft/nVarCols); for (int j = 0; j < m_nCols; ++j) { if (!m_intf.hasFixedWidth(j)) { m_vColInfo[j].m_nWidth += nStep; } } nLeft -= nVarCols*nStep; for (int j = 0; nLeft > 0; ++j) { if (!m_intf.hasFixedWidth(j)) { ++m_vColInfo[j].m_nWidth; --nLeft; } } m_nTotalWidth = m_nTableWidth; printWidths("after distributeRemaining"); } void ColumnResizer::setWidths() { for (int j = 0; j < m_nCols; ++j) { if (!m_intf.isHidden(j)) { m_intf.setWidth(j, m_vColInfo[j].m_nWidth); } } printWidths(" setWidths"); } void ColumnResizer::autoSize(bool bFill) { m_nTotalRows = m_intf.getRowCount(); m_nUsedRows = min(m_nTotalRows, m_nMaxRows); m_nCols = m_intf.getColumnCount(); if (0 == m_nTotalRows || 0 == m_nCols) { return; } // not sure if m_nCols can be 0; ... whatever m_vvAllWidths.resize(m_nCols); m_nFixedWidthCount = 0; for (int j = 0; j < m_nCols; ++j) { if (m_intf.hasFixedWidth(j)) { ++m_nFixedWidthCount; } } m_vColInfo.resize(m_nCols); if (m_nFixedWidthCount == m_nCols) { // all columns have fixed size for (int j = 0; j < m_nCols; ++j) { m_vColInfo[j].m_nWidth = m_intf.getMinWidth(j); } } else { if (!m_bConsistentResults && m_nTotalRows != m_nUsedRows) { srand(11); //ttt2 not such a good idea, as it interferes with other uses of rand(); OTOH, it's better to use it, because then we always get the same results for the same data, even if the selection process is random; seems better to use a separate generator; } readAllWidths(); m_nTableWidth = m_intf.getTableWidth(); computeColInfo(); if (m_nTotalMax <= m_nTableWidth) { setUpMaxWidths(); if (!bFill) { m_nTotalWidth = m_nTableWidth; // so columns won't get expanded } } else { setUpAvgWidths(); if (m_nTotalWidth > m_nTableWidth) { // if still too wide, cut to minWidth, if one was set (header width doesn't count) setUpMinWidths(); } } if (m_nTotalWidth < m_nTableWidth) { distributeAskSmall(); if (m_nTotalWidth < m_nTableWidth) { distributeAskLarge(); if (m_nTotalWidth < m_nTableWidth) { distributeRemaining(); } } } } setWidths(); } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== /*override*/ int SimpleQTreeWidgetWidthInterface::getRowCount() const { return m_tbl.topLevelItemCount(); } /*override*/ int SimpleQTreeWidgetWidthInterface::getColumnCount() const { return m_tbl.columnCount(); } MP3Diags-1.0.12.079/src/FileEnum.h0000644000175000001440000001007211265050316015127 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef FileEnumH #define FileEnumH #include #include #include "Helpers.h" struct FileEnumerator { virtual ~FileEnumerator() {} virtual std::string next() = 0; // returns an empty string if there's nothing next virtual void reset() = 0; }; /* Returns a list with all the files in the "include directories", discarding the ones in the "exclude directories". If the directories have redundant information, an InvalidDirs is thrown. Here's how they should be: - a directory may be "included" iff it has no ancestors OR its closest ancestor is "excluded"; - a directory may be "excluded" iff it has ancestors AND its closest ancestor is "included"; - duplicates are not allowed; Assumes there are no "." or ".." in the paths, but doesn't check. // ttt2 perhaps check What is really on the disk is not important, in the sense that names of directories that don't exist or of files are ignored. Ending of directory names with the path separator is optional and it doesn't have to be consistent. */ class DirTreeEnumerator : public FileEnumerator { struct DirTreeEnumeratorImpl; DirTreeEnumeratorImpl* m_pImpl; NoDefaults m_noDefaults; public: DirTreeEnumerator(const std::vector& vstrIncludeDirs, const std::vector& vstrExcludeDirs); DirTreeEnumerator(); /*override*/ ~DirTreeEnumerator(); /*override*/ void reset(); void reset(const std::vector& vstrIncludeDirs, const std::vector& vstrExcludeDirs); /*override*/ std::string next(); // returns an empty string if there's nothing next bool isIncluded(const std::string& strFile); struct InvalidDirs {}; }; #if 0 class DirEnumerator : public FileEnumerator { struct DirEnumeratorImpl; DirEnumeratorImpl* m_pImpl; NoDefaults m_noDefaults; int m_nCrt; public: DirEnumerator(const std::string& strDir); ~DirEnumerator(); /*override*/ void reset() { m_nCrt = 0; } /*override*/ std::string next(); // returns an empty string if there's nothing next }; #endif class ListEnumerator : public FileEnumerator { //struct ListEnumeratorImpl; //ListEnumeratorImpl* m_pImpl; NoDefaults m_noDefaults; std::vector m_vstrFiles; int m_nCrt; public: ListEnumerator(const std::vector& vstrFiles); ListEnumerator(const std::string& strDir); /*override*/ ~ListEnumerator() {} /*override*/ void reset() { m_nCrt = 0; } /*override*/ std::string next(); // returns an empty string if there's nothing next }; #endif // #ifndef FileEnumH MP3Diags-1.0.12.079/src/DebugDlgImpl.h0000644000175000001440000000452011257657123015735 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DebugDlgImplH #define DebugDlgImplH #include #include #include "ui_Debug.h" class CommonData; class QSettings; class LogModel; class DebugDlgImpl : public QDialog, private Ui::DebugDlg { Q_OBJECT CommonData* m_pCommonData; void exportAsText(const std::string& strFileName); void exportLog(const std::string& strFileName); LogModel* m_pLogModel; public: DebugDlgImpl(QWidget* pParent, CommonData* pCommonData); ~DebugDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ void run(); public slots: /*$PUBLIC_SLOTS$*/ void on_m_pSaveLogB_clicked(); void on_m_pTst01B_clicked(); void on_m_pDecodeMpegFrameB_clicked(); protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pCloseB_clicked(); void onHelp(); }; #endif MP3Diags-1.0.12.079/src/StructuralTransformation.h0000644000175000001440000002703111503722135020525 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef StructuralTransformationH #define StructuralTransformationH #include #include "Transformation.h" class DataStream; //=================================================================================================================== // Searches for unknown streams following audio streams. If found, it toggles each bit of the 4 bytes of such a stream, to see if this leads to a compatible frame. If it does, it transforms the file by actually toggling that bit class SingleBitRepairer : public Transformation { static bool isUnknown(const DataStream*); public: /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Sometimes a bit gets flipped in a file. This tries to identify places having this issue in audio frame headers. If found, it fixes the problem. It is most likely to apply to files that have 2 audio streams."; } static const char* getClassName() { return "Restore flipped bit in audio"; } // ttt1 "getClassName" is misleading and should be renamed }; //=================================================================================================================== // base class for stream removal class GenericRemover : public Transformation { virtual bool matches(DataStream*) const = 0; // if this returns true the stream must be removed public: virtual ~GenericRemover() {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); }; // removes all streams between audio streams class InnerNonAudioRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; std::set m_spStreamsToDiscard; void setupDiscarded(const Mp3Handler& h); public: /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all non-audio data that is found between audio streams. In this context, VBRI streams are considered audio streams (while Xing streams are not.)"; } static const char* getClassName() { return "Remove inner non-audio"; } }; class UnknownDataStreamRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all unknown streams."; } static const char* getClassName() { return "Remove unknown streams"; } }; class BrokenDataStreamRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all broken streams."; } static const char* getClassName() { return "Remove broken streams"; } }; class UnsupportedDataStreamRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all unsupported streams."; } static const char* getClassName() { return "Remove unsupported streams"; } }; class TruncatedMpegDataStreamRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all truncated audio streams."; } static const char* getClassName() { return "Remove truncated audio streams"; } }; class NullStreamRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all null streams."; } static const char* getClassName() { return "Remove null streams"; } }; #if 0 class StreamRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all streams that are broken, truncated, unsupported or have some errors making them unusable."; } static const char* getClassName() { return "General cleanup"; } }; #endif class BrokenId3V2Remover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes broken ID3V2 streams."; } static const char* getClassName() { return "Remove broken ID3V2 streams"; } }; class UnsupportedId3V2Remover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes unsupported ID3V2 streams."; } static const char* getClassName() { return "Remove unsupported ID3V2 streams"; } }; class MultipleId3StreamRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; std::set m_spStreamsToDiscard; void setupDiscarded(const Mp3Handler& h); public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "If a file has multiple ID3 streams it keeps only the last ID3V1 and the first ID3V2 stream."; } static const char* getClassName() { return "Remove multiple ID3 streams"; } /*override*/ Transformation::Result apply(const Mp3Handler& h, const TransfConfig& cfg, const std::string& strOrigSrcName, std::string& strTempName) { setupDiscarded(h); return GenericRemover::apply(h, cfg, strOrigSrcName, strTempName); } }; class MismatchedXingRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; std::set m_spStreamsToDiscard; void setupDiscarded(const Mp3Handler& h); public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Sometimes the number of frames in an audio stream is different from the number of frames in a preceding Xing (or Lame) header, usually because the audio stream was damaged. It's probably best for the Xing header to be removed in this case. If the audio is VBR, you may want to try \"Repair VBR data\" first."; } static const char* getClassName() { return "Remove mismatched Xing headers"; } /*override*/ Transformation::Result apply(const Mp3Handler& h, const TransfConfig& cfg, const std::string& strOrigSrcName, std::string& strTempName) { setupDiscarded(h); return GenericRemover::apply(h, cfg, strOrigSrcName, strTempName); } }; class Id3V1Remover : public GenericRemover { /*override*/ bool matches(DataStream* p) const; public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all ID3V1 streams."; } static const char* getClassName() { return "Remove all ID3V1 streams"; } }; //=================================================================================================================== class TruncatedAudioPadder : public Transformation { public: /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Pads truncated audio frames with 0 to the right. Its usefulness hasn't been determined yet (it might be quite low.)"; } static const char* getClassName() { return "Pad truncated audio"; } }; //=================================================================================================================== class VbrRepairerBase : public Transformation { protected: enum { DONT_FORCE_REBUILD, FORCE_REBUILD }; Transformation::Result repair(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName, bool bForceRebuild); }; class VbrRepairer : public VbrRepairerBase { public: /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "If a file contains VBR audio but doesn't have a Xing header, one such header is added. If a VBRI header exists, it is removed. If a Xing header exists but is determined to be incorrect, it is corrected or replaced. Only the first audio stream is considered; if a file contains more than one audio stream, this should be fixed first."; } static const char* getClassName() { return "Repair VBR data"; } }; class VbrRebuilder : public VbrRepairerBase { public: /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "If a file contains VBR audio, any existing VBRI or Xing headers are removed and a new Xing header is created. Only the first audio stream is considered; if a file contains more than one audio stream, this should be fixed first."; } static const char* getClassName() { return "Rebuild VBR data"; } }; #endif // #ifndef StructuralTransformationH MP3Diags-1.0.12.079/src/Id3Transf.h0000644000175000001440000002451711304424255015232 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef Id3TransfH #define Id3TransfH #include "fstream_unicode.h" #include "Transformation.h" class CommonData; class Id3V2StreamBase; class Id3V2Cleaner : public Transformation { bool processId3V2Stream(Id3V2StreamBase& frm, ofstream_utf8& out); CommonData* m_pCommonData; public: Id3V2Cleaner(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes all ID3V2 frames that aren't used by MP3 Diags. You normally don't want to do such a thing, but it may help if some other program misbehaves because of invalid or unknown frames in an ID3V2 tag."; } static const char* getClassName() { return "Remove non-basic ID3V2 frames"; } }; class Id3V2Rescuer : public Transformation { bool processId3V2Stream(Id3V2StreamBase& frm, ofstream_utf8* pOut); // nothing gets written if pOut is 0 CommonData* m_pCommonData; public: Id3V2Rescuer(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Copies only ID3V2 frames that seem valid or can be made valid, discarding those that are invalid and can't be fixed (e.g. an APIC frame claiming to hold a picture although it doesn't.) Handles both loadable and broken ID3V2 tags, in the latter case copying being stopped when a fatal error occurs."; } static const char* getClassName() { return "Discard invalid ID3V2 data"; } }; class Id3V2UnicodeTransformer : public Transformation { void processId3V2Stream(Id3V2StreamBase& frm, ofstream_utf8& out); CommonData* m_pCommonData; mutable std::string m_strActionName; // contains the current codepage public: Id3V2UnicodeTransformer(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getVisibleActionName() const; /*override*/ const char* getDescription() const { return "Transforms text frames in ID3V2 encoded as Latin1 to Unicode (UTF16.) The reason to do this is that sometimes non-conforming software treats these frames as they are encoded in a different code page, causing other programs to display unexpected data."; } static const char* getClassName() { return "Convert non-ASCII ID3V2 text frames to Unicode"; } }; class Id3V2CaseTransformer : public Transformation { bool processId3V2Stream(Id3V2StreamBase& frm, ofstream_utf8& out); CommonData* m_pCommonData; mutable std::string m_strActionName; public: Id3V2CaseTransformer(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getVisibleActionName() const; /*override*/ const char* getDescription() const { return "Transforms the case of text frames in ID3V2 tags, according to global settings."; } static const char* getClassName() { return "Change case for ID3V2 text frames"; } }; class Id3V1Stream; class Id3V1ToId3V2Copier : public Transformation { bool processId3V2Stream(Id3V2StreamBase& frm, ofstream_utf8& out, Id3V1Stream* pId3V1Stream); CommonData* m_pCommonData; public: Id3V1ToId3V2Copier(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Copies frames from ID3V1 to ID3V2 if those tags don't exist in the destination or if the destination doesn't exist at all."; } static const char* getClassName() { return "Copy missing ID3V2 frames from ID3V1"; } }; class Id3V2ComposerAdder : public Transformation { CommonData* m_pCommonData; public: Id3V2ComposerAdder(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Adds the value of the composer field to the beginning of the artist field in ID3V2 frames. Useful for players that don't use the composer field."; } static const char* getClassName() { return "Add composer field to the artist field in ID3V2 frames"; } }; class Id3V2ComposerRemover : public Transformation { CommonData* m_pCommonData; public: Id3V2ComposerRemover(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "\"Undo\" for \"adding composer field.\" Removes the value of the composer field from the beginning of the artist field in ID3V2 frames, if it was previously added."; } static const char* getClassName() { return "Remove composer field from the artist field in ID3V2 frames"; } }; class Id3V2ComposerCopier : public Transformation { CommonData* m_pCommonData; public: Id3V2ComposerCopier(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Copies to the \"Composer\" field the beginning of an \"Artist\" field that is formatted as \"Composer [Artist]\". Does nothing if the \"Artist\" field doesn't have this format."; } static const char* getClassName() { return "Fill in composer field based on artist in ID3V2 frames"; } }; class SmallerImageRemover : public Transformation { CommonData* m_pCommonData; public: SmallerImageRemover(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Keeps only the biggest (and supposedly the best) image in a file. The image type is set to Front Cover. (This may result in the replacement of the Front Cover image.)"; } static const char* getClassName() { return "Make the largest image \"Front Cover\" and remove the rest"; } }; class Id3V2Expander : public Transformation { CommonData* m_pCommonData; public: Id3V2Expander(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Adds extra spacing to the ID3V2 tag. This allows subsequent saving from the tag editor to complete quicker."; } static const char* getClassName() { return "Reserve space in ID3V2 for fast tag editing"; } static const int EXTRA_SPACE; // this gets added to whatever the current frames alrady occupy; }; class Id3V2Compactor : public Transformation { CommonData* m_pCommonData; public: Id3V2Compactor(CommonData* pCommonData) : m_pCommonData(pCommonData) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes large unused blocks from ID3V2 tags. (Usually these have been reserved for fast tag editing, in which case they should be removed only after the ID3V2 tag has all the right values.)"; } static const char* getClassName() { return "Remove extra space from ID3V2"; } }; #endif // ifndef Id3TransfH MP3Diags-1.0.12.079/src/MusicBrainzDownloader.h0000644000175000001440000000773311252461427017707 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MusicBrainzDownloaderH #define MusicBrainzDownloaderH #include "AlbumInfoDownloaderDlgImpl.h" namespace MusicBrainz { struct SearchXmlHandler; struct MusicBrainzAlbumInfo : public WebAlbumInfoBase { MusicBrainzAlbumInfo() : m_nTrackCount(-1) {} //std::string m_strComposer; // !!! no Composer at MusicBrainz; see http://musicbrainz.org/doc/ClassicalMusicFAQ //std::string m_strGenre; // !!! no Genre at MusicBrainz: http://musicbrainz.org/doc/GeneralFAQ#head-6488c5c2fb7503b4ae26f3e234304e07c2b172fb //std::string m_strNotes; // !!! no Notes at MusicBrainz std::string m_strId; int m_nTrackCount; std::string m_strAsin; std::string m_strAmazonLink; /*override*/ void copyTo(AlbumInfo& dest); }; }; class MusicBrainzDownloader : public AlbumInfoDownloaderDlgImpl { Q_OBJECT std::vector m_vAlbums; friend struct MusicBrainz::SearchXmlHandler; void delay(); long long getTime(); // time in milliseconds long long m_nLastReqTime; void clear(); QHttp* m_pImageQHttp; /*override*/ bool initSearch(const std::string& strArtist, const std::string& strAlbum); /*override*/ std::string createQuery(); /*override*/ void loadNextPage(); /*override*/ void requestAlbum(int nAlbum); /*override*/ void requestImage(int nAlbum, int nImage); /*override*/ void reloadGui(); /*override*/ QHttp* getWaitingHttp(); /*override*/ void resetNavigation(); /*override*/ WebAlbumInfoBase& album(int i); /*override*/ int getAlbumCount() const; /*override*/ QXmlDefaultHandler* getSearchXmlHandler(); /*override*/ QXmlDefaultHandler* getAlbumXmlHandler(int nAlbum); /*override*/ const WebAlbumInfoBase* getCrtAlbum() const; // returns 0 if there's no album /*override*/ int getColumnCount() const { return 3; } /*override*/ void saveSize(); /*override*/ char getReplacementChar() const { return ' '; } QString getAmazonText() const; public: MusicBrainzDownloader(QWidget* pParent, SessionSettings& settings, bool bSaveResults); ~MusicBrainzDownloader(); /*$PUBLIC_FUNCTIONS$*/ static const char* SOURCE_NAME; public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pSearchB_clicked(); void onAmazonLinkActivated(const QString&); private: }; #endif // #ifndef MusicBrainzDownloaderH MP3Diags-1.0.12.079/src/Id3V240Stream.h0000644000175000001440000000756511273770534015621 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef Id3V240StreamH #define Id3V240StreamH #include "Id3V2Stream.h" // Frame of an ID3V2.4.0 tag struct Id3V240Frame : public Id3V2Frame { Id3V240Frame(NoteColl& notes, std::istream& in, std::streampos pos, bool bHasUnsynch, std::streampos posNext, StringWrp* pFileName); private: bool checkSize(std::istream& in, std::streampos posNext); // since broken applications may use all 8 bits for size, although only 7 should be used, this tries to figure out if the size is correct /*override*/ bool discardOnChange() const; // may return multiple null characters; it's the job of getUtf8String() to deal with them; // chars after the first null are considered comments (or after the second null, for TXXX), so the nulls are replaced with commas, except for those at the end of the string (which are removed) and the first null in TXXX; /*override*/ std::string getUtf8StringImpl() const; /*override*/ int getOffset() const; void load(NoteColl& notes, std::istream& in, std::streampos posNext, bool bHasUnsynch); void load(NoteColl& notes, std::istream& in, std::streampos posNext); private: friend class boost::serialization::access; Id3V240Frame() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); } }; class Id3V240Stream : public Id3V2StreamBase { public: Id3V240Stream(int nIndex, NoteColl& notes, std::istream& in, StringWrp* pFileName, bool bAcceptBroken = false); //typedef typename Id3V2Stream::NotId3V2 NotId3V240; DECL_RD_NAME("ID3V2.4.0"); /*override*/ TagTimestamp getTime(bool* pbFrameExists = 0) const; /*override*/ void setTrackTime(const TagTimestamp&) { throw NotSupportedOp(); } /*override*/ SuportLevel getSupport(Feature) const; private: friend class boost::serialization::access; Id3V240Stream() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); } }; #endif // ifndef Id3V240StreamH MP3Diags-1.0.12.079/src/fstream_unicode.cpp0000644000175000001440000001225211274017760017135 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef __GNUC__ #include "fstream_unicode.h" #include // might want to look at basic_file_stdio.cc or ext/stdio_filebuf.h // http://www2.roguewave.com/support/docs/leif/sourcepro/html/stdlibref/basic-ifstream.html // STLPort // MSVC // Dinkumware - not // http://www.aoc.nrao.edu/~tjuerges/ALMA/STL/html/class____gnu__cxx_1_1stdio__filebuf.html //ttt2 perhaps add flush() /* ttt2 see about file flushing: http://support.microsoft.com/default.aspx/kb/148505 - fdatasync() - like fsync() but doesn't change metadata (e.g. mtime) so it's faster - since the C++ Library has nothing to do flushing, perhaps this would work: standalone "commit(const ofstream_utf8&)" and/or "commit(const string&)" ; also, we don't want to commit all the files; or perhaps "commit(ofstream_utf8&)" is needed, which would first close the file - there's also out.rdbud()->pubsync(), but what it does is OS-dependent - use external disk / flash, to see the LED, for testing */ // converts __mode to flags that can be used by the POSIX open() function int getOpenFlags(std::ios_base::openmode __mode) { int nAcc; if (std::ios_base::in & __mode) { if (std::ios_base::out & __mode) { nAcc = O_RDWR | O_CREAT; } else { nAcc = O_RDONLY; } } else if (std::ios_base::out & __mode) { nAcc = O_RDWR | O_CREAT; } else { throw 1; // ttt2 } #ifdef O_LARGEFILE nAcc |= O_LARGEFILE; #endif if (std::ios_base::trunc & __mode) { nAcc |= O_TRUNC; } if (std::ios_base::app & __mode) { nAcc |= O_APPEND; } #ifdef O_BINARY if (std::ios_base::binary & __mode) { nAcc |= O_BINARY; } #endif return nAcc; } /* template<> int unicodeOpenHlp(const QString& s, std::ios_base::openmode __mode) { int nFd (open(s.toUtf8().constData(), getOpenFlags(__mode), S_IREAD | S_IWRITE)); return nFd; } */ #ifndef WIN32 template<> int unicodeOpenHlp(const char* const& szUtf8Name, std::ios_base::openmode __mode) { int nAcc (getOpenFlags(__mode)); int nFd (open(szUtf8Name, nAcc, S_IREAD | S_IWRITE)); //qDebug("fd %d %s acc=%d", nFd, szUtf8Name, nAcc); return nFd; } #if 0 template<> int unicodeOpenHlp(const wchar_t* const& /*wszUtf16Name*/, std::ios_base::openmode /*__mode*/) { throw 1; //ttt2 add if needed } #endif #else // #ifndef WIN32 #include #include #include using namespace std; static wstring wstrFromUtf8(const string& s) { vector w (s.size() + 1); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, &w[0], w.size()); //inspect(&w[0], w.size()*2); return &w[0]; } template<> int unicodeOpenHlp(const wchar_t* const& wszUtf16Name, std::ios_base::openmode __mode) { int nAcc (getOpenFlags(__mode)); int nFd (_wopen(wszUtf16Name, nAcc, S_IREAD | S_IWRITE)); //int nFd (open(szUtf8Name, nAcc, S_IREAD | S_IWRITE)); //qDebug("fd %d %s acc=%d", nFd, szUtf8Name, nAcc); return nFd; } template<> int unicodeOpenHlp(const char* const& szUtf8Name, std::ios_base::openmode __mode) { return unicodeOpenHlp(wstrFromUtf8(szUtf8Name).c_str(), __mode); } #endif // #ifndef WIN32 / #else template<> int unicodeOpenHlp(const int& fd, std::ios_base::openmode /*__mode*/) { return fd; } //ttt2 review O_SHORT_LIVED #else // #ifdef __GNUC__ // nothing to do for now; the MSVC version is fully inline and no ports to other compilers exist #endif // #ifdef __GNUC__ MP3Diags-1.0.12.079/src/Patterns.ui0000644000175000001440000000740611233521762015423 0ustar ciobiusers PatternsDlg 0 0 744 528 Patterns true 10 0 true false 9 0 0 0 0 0 Add predefined patterns 0 0 0 0 Qt::Horizontal 40 20 Line 1, Col 1 Qt::Horizontal 40 20 O&K Cancel MP3Diags-1.0.12.079/src/MpegFrame.h0000444000175000001440000001140111476664262015300 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MpegFrameH #define MpegFrameH #include #include #include #include "SerSupport.h" struct Note; class NoteColl; // based on http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm struct MpegFrameBase { enum Version { MPEG1, MPEG2 }; enum Layer { LAYER1, LAYER2, LAYER3 }; enum ChannelMode { STEREO, JOINT_STEREO, DUAL_CHANNEL, SINGLE_CHANNEL }; enum { MPEG_FRAME_HDR_SIZE = 4 }; private: //void init(const unsigned char* pHeader, std::istream* pIn, std::streampos pos, int nRelPos); //bool hasXingHdr(); //bool hasVbriHdr(); // Amarok doesn't seem to care about this, so the Xing header must be used anyway for VBR void init(NoteColl& notes, const char* bfr); char m_header[4]; protected: Version m_eVersion; Layer m_eLayer; int m_nBitrate; int m_nFrequency; int m_nPadding; ChannelMode m_eChannelMode; int m_nSize; bool m_bCrc; std::streampos m_pos; public: //MpegFrame(const unsigned char* pHeader, std::istream& in, std::streampos pos, int nRelPos); //MpegFrame(const char* pHeader, std::istream& in, std::streampos pos, int nRelPos); //MpegFrame(std::istream& in, std::streampos pos); //MpegFrame(std::istream& in, std::streampos pos); MpegFrameBase(NoteColl& notes, std::istream& in); MpegFrameBase(); MpegFrameBase(NoteColl& notes, std::streampos pos, const char* bfr); std::ostream& write(std::ostream& out) const; Version getVersion() const { return m_eVersion; } Layer getLayer() const { return m_eLayer; } ChannelMode getChannelMode() const { return m_eChannelMode; } int getBitrate() const { return m_nBitrate; } int getFrequency() const { return m_nFrequency; } int getSize() const { return m_nSize; } // total size, including the header bool getCrcUsage() const { return m_bCrc; } std::streampos getPos() const { return m_pos; } const char* getSzVersion() const; const char* getSzLayer() const; const char* getSzChannelMode() const; const char* getHeader() const { return m_header; } int getSideInfoSize() const; // needed by Xing #ifdef GENERATE_TOC MpegFrameBase getBigBps() const; // returns a "similar" frame to "this" but with a bigger bps, so it can hold a Xing TOC #endif struct NotMpegFrame {}; // exception private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } //ar & boost::serialization::base_object(*this); ar & m_header; ar & m_eVersion; ar & m_eLayer; ar & m_nBitrate; ar & m_nFrequency; ar & m_nPadding; ar & m_eChannelMode; ar & m_nSize; ar & m_bCrc; ar & m_pos; } }; struct MpegFrame : public MpegFrameBase { struct PrematurelyEndedMpegFrame // exception { std::string m_strInfo; PrematurelyEndedMpegFrame(const std::string& strInfo) : m_strInfo(strInfo) {} }; MpegFrame(NoteColl& notes, std::istream& in); MpegFrame() {} }; std::ostream& operator<<(std::ostream& out, const MpegFrameBase& frm); #endif // ifndef MpegFrameH MP3Diags-1.0.12.079/src/CommonData.h0000644000175000001440000007221211273617200015451 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef CommonDataH #define CommonDataH #include #include //#include #include #include #include "SerSupport.h" #include "Notes.h" #include "Mp3Manip.h" #include "Helpers.h" #include "FileEnum.h" #include "CommonTypes.h" //class QFont; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class QToolButton; class FilesModel; struct NotesModel; struct StreamsModel; struct UniqueNotesModel; extern int CELL_WIDTH; // ttt2 perhaps replace with functions extern int CELL_HEIGHT; extern const int CUSTOM_TRANSF_CNT; // search for this to find all places that need changes to add another custom transform list // Holds together a collection of Notes (All) and a subset of it (Flt). Flt is used when filtering, when All holds all the notes that exist in all the handlers (CommonData::m_vpAllHandlers), while Flt holds the notes from the handlers that are selected by the current filter (CommonData::m_vpFltHandlers). // Uses both a vector and a set to provide fast access, althought this doesn't seem like the best idea. //ttt2 perhaps switch from to a treap class UniqueNotes { // all pointers are from Notes::, so none are owned; std::set m_spAll; // owns the pointers std::set m_spFlt; // subset of m_spAll, so it doesn't own these pointers mutable std::vector m_vpAll; // only has elements of m_spAll, so it doesn't own these pointers mutable std::vector m_vpFlt; // only has elements of m_spAll, so it doesn't own these pointers mutable bool m_bAllDirty; mutable bool m_bFltDirty; void updateVAll() const; void updateVFlt() const; public: UniqueNotes(); //UniqueNotes(const UniqueNotes&); ~UniqueNotes(); void clear(); void clearFlt() { m_spFlt.clear(); m_bFltDirty = true; } bool addNote(const Note* pNote); // if the note doesn't exist in m_spAll, it adds the corresponding note from Notes; returns true if the param really was added; //void add(const std::vector& vpNotes); //void add(const std::vector& vpNotes); // returns true if anything got added template bool addColl(const T& coll) { bool bRes (false); for (typename T::const_iterator it = coll.begin(), end = coll.end(); it != end; ++it) { if (0 == m_spAll.count(*it)) { const Note* p (Notes::getMaster(*it)); CB_ASSERT (0 != p); m_spAll.insert(p); m_bAllDirty = true; bRes = true; } } return bRes; } void _selectAll() { m_spFlt = m_spAll; m_bFltDirty = true; } // throws NoteNotFound if a note is not in m_spAll; template void setFlt(const T& coll) { m_spFlt.clear(); m_bFltDirty = true; for (typename T::const_iterator it = coll.begin(), end = coll.end(); it != end; ++it) { int nPos (getPos(*it)); CB_CHECK1 (-1 != nPos, NoteNotFound()); m_spFlt.insert(get(nPos)); } } struct NoteNotFound {}; int getFltCount() const { return cSize(m_spFlt); } const Note* getFlt(int n) const; int getCount() const { return cSize(m_spAll); } const Note* get(int n) const; int getPos(const Note*) const; // position in the "all" notes; -1 if the note wasn't found; int getFltPos(const Note*) const; // position in the "flt" notes; -1 if the note wasn't found; const std::vector& getAllVec() const { updateVAll(); return m_vpAll; } const std::vector& getFltVec() const { updateVFlt(); return m_vpFlt; } }; // Owners for notes: // DescrOwnerNote::m_spAll owns DescrOwnerNote* // Mp3Handler owns Note*, through NoteColl // // Filter::m_vpSelNotes references CommonData::m_uniqueNotes.m_spAll // DescrOwnerNote::m_spSel, DescrOwnerNote::m_spSel and DescrOwnerNote::m_spSel all referece the notes in DescrOwnerNote::m_spAll class Filter : public QObject { Q_OBJECT bool m_bNoteFilter; bool m_bDirFilter; bool m_bSavedNoteFilter; bool m_bSavedDirFilter; std::vector m_vstrDirs; std::vector m_vpNotes; // doesn't own the pointers, because it is just a subset of CommonData::m_uniqueNotes.getAllVec(), which in turn uses pointers from Notes:: // !!! it's OK for this to be a vector (rather than a set), because the way it is used most of the time, namely to determine if the intersection of 2 sets (represented as sorted vectors) is empty or not public: Filter() : m_bNoteFilter(false), m_bDirFilter(false), m_bSavedNoteFilter(false), m_bSavedDirFilter(false) {} const std::vector& getDirs() const { return m_vstrDirs; } const std::vector& getNotes() const { return m_vpNotes; } void setDirs(const std::vector&); void setNotes(const std::vector&); void disableDir(); // !!! needed because we need m_vstrDirs next time we press the filter button, so we don't want to delete it with a "setDirs(vector())", but just ignore it void disableNote(); void disableAll(); // saves m_bNoteFilter to m_bSavedNoteFilter and m_bDirFilter to m_bSavedDirFilter, then disables the filters void restoreAll(); // loads m_bNoteFilter from m_bSavedNoteFilter and m_bDirFilter from m_bSavedDirFilter, then enables the filters, if they are true bool isNoteEnabled() const { return m_bNoteFilter; } bool isDirEnabled() const { return m_bDirFilter; } signals: void filterChanged(); private: friend class boost::serialization::access; /*template void serialize(Archive& ar, const unsigned int / *nVersion* /) { ar & m_bNoteFilter; ar & m_bDirFilter; ar & m_bSavedNoteFilter; ar & m_bSavedDirFilter; ar & m_vstrDirs; ar & m_vpNotes; }*/ template void save(Archive& ar, const unsigned int nVersion) const { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar << m_bNoteFilter; ar << m_bDirFilter; ar << m_bSavedNoteFilter; ar << m_bSavedDirFilter; ar << m_vstrDirs; //qDebug("saved dirs sz %d", cSize(m_vstrDirs)); //ar << m_vpNotes; //ttt2 weird behaviour: this compiles and doesn't trigger runtime errros, and neither does the loading, but when loading a vector it always ends up empty; it's probably some incorrect use of the ser library (share / global / const pointers), but the library is broken too, because it should have failed to compile or at least crashed when running instead of just failing to load anything (the files are different, so something is saved) //ar << (const std::vector&)m_vpNotes; qDebug("saved notes sz %d", cSize(m_vpNotes)); std::vector v; for (int i = 0; i < cSize(m_vpNotes); ++i) { v.push_back(m_vpNotes[i]->getDescription()); } ar << (const std::vector&)v;//*/ } template void load(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar >> m_bNoteFilter; ar >> m_bDirFilter; ar >> m_bSavedNoteFilter; ar >> m_bSavedDirFilter; ar >> m_vstrDirs; /*qDebug("loaded flt dirs size %d", cSize(m_vstrDirs)); for (int i = 0; i < cSize(m_vstrDirs); ++i) { qDebug("flt dir %d: %s", i, m_vstrDirs[i].c_str()); }*/ /*std::vector v; ar >> v; qDebug("loaded note sz %d", cSize(v)); for (int i = 0; i < cSize(v); ++i) { const Note* p (Notes::getMaster(v[i])); CB_ASSERT (0 != p); m_vpNotes.push_back(p); } pearl::clearPtrContainer(v);// */ std::vector v; ar >> v; //qDebug("loaded note sz %d", cSize(v)); for (int i = 0; i < cSize(v); ++i) { const Note* p (Notes::getNote(v[i])); if (0 != p) // !!! when a new version loads an old one's data, some notes might be gone { m_vpNotes.push_back(p); } }// */ } BOOST_SERIALIZATION_SPLIT_MEMBER(); }; class ImageInfoPanelWdgImpl; class SessionSettings; class Transformation; class QTableView; // doesn't own the QTableView pointers; // doesn't own the model pointers class CommonData : public QObject { Q_OBJECT public: CommonData( SessionSettings& settings, QTableView* pFilesG, QTableView* pNotesG, QTableView* pStreamsG, QTableView* pUniqueNotesG, QToolButton* pNoteFilterB, QToolButton* pDirFilterB, QToolButton* pModeAllB, QToolButton* pModeAlbumB, QToolButton* pModeSongB, bool bUniqueSession); ~CommonData(); std::string save(const std::string& strFile) const; // returns an error message (or empty string if there's no error) std::string load(const std::string& strFile); // returns an error message (or empty string if there's no error) FilesModel* m_pFilesModel; NotesModel* m_pNotesModel; StreamsModel* m_pStreamsModel; UniqueNotesModel* m_pUniqueNotesModel; QTableView* m_pFilesG; QTableView* m_pNotesG; QTableView* m_pStreamsG; QTableView* m_pUniqueNotesG; const std::deque& getViewHandlers() const { return m_vpViewHandlers; } const std::deque& getSelHandlers(); // results are sorted const UniqueNotes& getUniqueNotes() const { return m_uniqueNotes; } // "albums" for the tag editor; independent of the main window; void setCrtAlbum(const std::string& strName) const; std::deque getCrtAlbum() const; bool nextAlbum() const; bool prevAlbum() const; // finds the position of a note in the global vector with notes sorted by severity and description; // the position can then be used to find the corresponding label; // returns -1 if the note is not found; (needed because trace and info notes aren't shown in the grid, so they are not found) int findPos(const Note* pNote) const; bool m_bChangeGuard; // used with a NonblockingGuard to avoid recursive calls when updating the UI int getFilesGCrtRow() const; // returns -1 if no current element exists (e.g. because the table is empty) int getFilesGCrtCol() const; // returns -1 if no current element exists (e.g. because the table is empty) const std::vector& getCrtNotes() const { return m_vpCrtNotes; } // notes for the "current" file const std::vector& getCrtStreams() const; const std::vector& getAllTransf() const { return m_vpAllTransf; } const QualThresholds& getQualThresholds() const { return m_qualThresholds; } void setQualThresholds(const QualThresholds&); const std::vector >& getCustomTransf() const { return m_vvnCustomTransf; } void setCustomTransf(const std::vector >&); void setCustomTransf(int nTransf, const std::vector&); const std::vector& getVisibleTransf() const { return m_vnVisibleTransf; } void setVisibleTransf(const std::vector&); const std::vector& getIgnoredNotes() const { return m_vnIgnoredNotes; } void setIgnoredNotes(const std::vector&); int getTransfPos(const char* szTransfName) const; // the index in m_vpAllTransf for a transformation with a given name; throws if the name doesn't exist; std::set getAllDirs() const; // needed by the dir filter enum KeepWhenUpdate { NOTHING = 0x00, CURRENT = 0x01, SEL = 0x02 }; void mergeHandlerChanges(const std::vector& vpAdd, const std::vector& vpDel, int nKeepWhenUpdate); // elements from vpAdd that are not "included" are discarded; when a new version of a handler is in vpAdd, the old version may be in vpDel, but this is optional; takes ownership of elements from vpAdd; deletes the pointers from vpDel; enum ViewMode { ALL, FOLDER, FILE }; // although the current elem can be identified (so it shouldn't be passed) and most of the time pMp3Handler will be just that, sometimes it will deliberately be 0, so a param is actually needed; void setViewMode(ViewMode eViewMode, const Mp3Handler* pMp3Handler = 0); ViewMode getViewMode() const { return m_eViewMode; } const Mp3Handler* getCrtMp3Handler() const; // returns 0 if the list is empty // called after config change or filter change or mergeHandlerChanges(), mainly to update unique notes (which is reflected in columns in the file grid and in lines in the unique notes list); also makes sure that something is displayed if there are any files in m_vpFltHandlers (e.g. if a transform was applied that removed all the files in an album, the next album gets loaded); // this is needed after transforms/normalization/tag editing, but there's no need for an explicit call, because all these call mergeHandlerChanges() (directly or through MainFormDlgImpl::scan()) void updateWidgets(const std::string& strCrtName = "", const std::vector& vstrSel = std::vector()); void next(); void previous(); void resizeFilesGCols(); // resizes the first column to use all the available space; doesn't shrink it to less than 400px, though void setSongInCrtAlbum(); const std::vector& getIncludeDirs() const { return m_vstrIncludeDirs; } const std::vector& getExcludeDirs() const { return m_vstrExcludeDirs; } void setDirectories(const std::vector& vstrIncludeDirs, const std::vector& vstrExcludeDirs); // keeps existing handlers as long as they are still "included" DirTreeEnumerator m_dirTreeEnum; void resetFileEnum() { m_dirTreeEnum.reset(); } const Mp3Handler* getHandler(const std::string& strName) const; // looks in m_vpAllHandlers; returns 0 if there's no such handler const std::string& getCrtName() const; // returns the file name of the current handler; returns "" if the list is empty void setFontInfo(const std::string& strGenName, int nGenSize, int nLabelFontSizeDecr, const std::string& strFixedName, int nFixedSize); const QFont& getGeneralFont() const { CB_ASSERT (!m_strGenFontName.empty()); return m_generalFont; } const QFont& getLabelFont() const { CB_ASSERT (!m_strFixedFontName.empty()); return m_labelFont; } const QFont& getFixedFont() const { CB_ASSERT (!m_strGenFontName.empty()); return m_fixedFont; } int getLabelFontSizeDecr() const { return m_nLabelFontSizeDecr; } QFont getNewGeneralFont() const; QFont getNewFixedFont() const; void setCrtAtStartup() { updateWidgets(m_strLoadCrtName); } // to be called from the main thread at startup //QString getNoteLabel(int nPosInFlt); // gets the label of a note based on its position in m_uniqueNotes.m_vpFlt // color is normally the category color, but for support notes it's a "support" color; if the note isn't found in vpNoteSet, dGradStart and dGradEnd are set to -1, but normally they get a segment obtained by dividing [0, 1] in equal parts; void getNoteColor(const Note& note, const std::vector& vpNoteSet, QColor& color, double& dGradStart, double& dGradEnd) const; bool isUniqueSession() const { return m_bUniqueSession; } enum { DONT_UPDATE_TRANSFORMS, UPDATE_TRANSFORMS }; void setFastSave(bool bFastSave, bool bUpdateTransforms); bool useFastSave() const { return m_bFastSave; } public: TextCaseOptions m_eCaseForArtists; TextCaseOptions m_eCaseForOthers; bool m_bWarnOnNonSeqTracks, m_bWarnPastingToNonSeqTracks; bool m_bShowExport, m_bShowDebug, m_bShowSessions; bool m_bScanAtStartup; std::string m_strNormalizeCmd; bool m_bKeepNormWndOpen; QByteArray m_locale; QTextCodec* m_pCodec; Filter m_filter; enum Save { SAVE, DISCARD, ASK }; Save m_eAssignSave; Save m_eNonId3v2Save; //AssgnBtnWrp m_assgnBtnWrp; bool m_bUseAllNotes; bool m_bTraceEnabled; void trace(const std::string& s); void clearLog(); const std::deque& getLog() const { return m_vLogs; } bool m_bAutoSizeIcons; int m_nMainWndIconSize; SessionSettings& m_settings; bool m_bKeepOneValidImg; bool m_bWmpVarArtists; bool m_bItunesVarArtists; std::string m_strTransfLog; // log file with transformations; bool m_bLogTransf; bool m_bSaveDownloadedData; enum { COLOR_ALB_NORM, COLOR_ALB_NONID3V2, COLOR_ALB_ASSIGNED, COLOR_FILE_NORM, COLOR_FILE_TAG_MISSING, COLOR_FILE_NA, COLOR_FILE_NO_DATA, COLOR_COL_CNT }; std::vector m_vTagEdtColors; std::vector m_vNoteCategColors; bool m_bWarnedAboutSel; bool m_bWarnedAboutBackup; bool m_bToldAboutPatterns; // see also s_bToldAboutPatternsInCrtRun bool m_bToldAboutSupport; // see also s_bToldAboutSupportInCrtRun std::string m_strCheckForNewVersions; // really an enum with 3 values QDateTime m_timeLastNewVerCheck; std::string m_strDontTellAboutVer; bool isTraceToFileEnabled() const { return m_bTraceToFile; } void setTraceToFile(bool bTraceToFile); // also removes the file std::string m_strRenamerInvalidChars; std::string m_strRenamerReplacementString; private: std::deque m_vpAllHandlers; // owns the pointers; sorted by CmpMp3HandlerPtrByName; std::deque m_vpFltHandlers; // filtered m_vpHandlers (so it doesn't own the pointers); std::deque m_vpViewHandlers; // subset of m_vpFltHandlers (so it doesn't own the pointers), containing the handlers that are currently visible; depending on the view mode, it may be equal to m_vpFltHandlers, contain a single directory or a single file std::deque m_vpSelHandlers; // subset of m_vpViewHandlers (so it doesn't own the pointers), containing the handlers that are currently selected; it is not regularly kept up-to-date, instead being updated only when needed, with updateSelList() // !!! m_vpAllHandlers, m_vpFltHandlers and m_vpViewHandlers must be kept sorted at all times, so binary search can be run on them std::vector getSelNames(); // calls updateSelList() and returns the names ot the selected files; void updateSelList(); UniqueNotes m_uniqueNotes; // a copy of every "relevant" note; basically notes with a severity other than TRACE; also, notes that should be ignored don't get added here; "Sel" contains the notes that are shown after filtering (by note or by dir) is applied (so by default "Sel" is equal to "All"); has pointers from Notes:: not dynamically created ones; std::vector m_vnIgnoredNotes; // indexes into Notes::getAllNotes(); not sorted; std::vector m_vpCrtNotes; // notes for the "current" file std::vector m_vpAllTransf; // owns the pointers QualThresholds m_qualThresholds; // copies to spUniqueNotes all the unique notes from commonData.m_vpFltHandlers, with comparison done by CmpNotePtrById; // ignored notes (given by m_vnIgnoredNotes) are not included; // not actual pointers from vpHandlers are stored, but the corresponding ones from given by Notes::getMaster(); so they must not be freed; void getUniqueNotes(const std::deque& vpHandlers, std::set& spUniqueNotes); void printFilesCrt() const; // for debugging; prints what's current in m_pFilesG, using several methods std::vector > m_vvnCustomTransf; std::vector m_vnVisibleTransf; enum { APPROX_MATCH, EXACT_MATCH }; // if bExactMatch is false, it finds the nearest position in m_vpViewHandlers (so even if a file was deleted, it still finds something close); // returns -1 only if not found (either m_vpViewHandlers is empty or bExactMatch is true and the file is missing); int getPosInView(const std::string& strName/*, bool bUsePrevIfNotFound = true*/, bool bExactMatch = false) const; void updateCurrentStreams(); // resizes the rows to fit the data and notifies that the model has changed and there are new streams void updateCurrentNotes(); // updates m_pCommonData->m_vpCrtNotes, to hold the notes corresponding to the current file and resizes the rows to fit the data // returns the position of the "current" elem in m_vpViewHandlers (so it can be selected in the grid); if m_vpViewHandlers is empty, it returns -1; if pMp3Handler is 0, it returns 0 (unless m_vpViewHandlers is empty); int setViewModeHlp(ViewMode eViewMode, const Mp3Handler* pMp3Handler); int nextHlp(); // returns the position of the "current" elem in m_vpViewHandlers (see setViewMode() for details) int previousHlp(); void updateUniqueNotes(); // updates m_uniqueNotes to reflect the current m_vpAllHandlers and m_vpFltHandlers; mutable int m_nSongInCrtAlbum; // index into m_vpAllHandlers; something in the "current album" used by the tag editor; might be first, last or in the middle; std::string m_strGenFontName; int m_nGenFontSize; int m_nLabelFontSizeDecr; std::string m_strFixedFontName; int m_nFixedFontSize; QFont m_generalFont; QFont m_fixedFont; QFont m_labelFont; std::string m_strLoadCrtName; // needed by setCrtAtStartup(), because calling updateWidgets() from a secondary thread has issues; so instead, the name of the current file is saved here for later, to be set from the main thread, through setCrtAtStartup() //bool m_bDirty; // seemed like a good idea, but since we also save filters and what's current, pretty much all the time the data will need to be saved bool m_bUniqueSession; // if there is a single or several known sessions; if this is false (so there are several sessions) the Sessions button is shown by default bool m_bFastSave; bool m_bTraceToFile; private: ViewMode m_eViewMode; int getPosInFlt(const Mp3Handler* pMp3Handler) const; // finds the position in m_vpFltHandlers; returns -1 if not found; 0 is a valid argument, in which case -1 is returned; needed by next() and previous(), to help with navigation when going into "folder" mode QToolButton* m_pNoteFilterB; QToolButton* m_pDirFilterB; QToolButton* m_pModeAllB; QToolButton* m_pModeAlbumB; QToolButton* m_pModeSongB; std::deque m_vLogs; std::vector m_vstrIncludeDirs, m_vstrExcludeDirs; public slots: void onCrtFileChanged(); void onFilterChanged(); // updates m_vpFltHandlers and m_vpViewHandlers; also updates the state of the filter buttons (deselecting them if the user chose empty filters) private: friend class boost::serialization::access; template void save(Archive& ar, const unsigned int nVersion) const; template void load(Archive& ar, const unsigned int nVersion); BOOST_SERIALIZATION_SPLIT_MEMBER(); }; CommonData* getCommonData(); // the only CommonData that exists at a given moment QWidget* getMainForm(); //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== // For the vertical header of a QTableView whose labels are the current row number, it determines the width necessary to accomodate any of those labels. // Currently it uses a hard-coded value to add to the width. //ttt2 fix // It makes 2 assumptions: // - the TableView uses the same FontMetrics as the ones returned by QApplication::fontMetrics() (this is intended to be called from a TableModel's headerData(), for which finding the table is not easy; and anyway, a model can be connected to several tables) // - digits in the font have the same size, or at least there is no digit with a size larger than that of '9'; (in many fonts all the digits do have the same size, so it should be OK most of the time) // Only the width is calculated; the height is returned as "1". This allows the content of a cell to determine the width of a row. Returning the height actually needed to draw the label would cause the rows to be to large, because significant spacing is added to the result. This is the opposite of what happens to the width, where a big number of pixels must be added by getNumVertHdrSize() just to have everything displayed. // ttt3 is this a Qt bug? (adds spacing where it's not needed and doesn't add it where it should) // // If nRowCount<=0 it behaves as if nRowCount==1 // // Returns QVariant() for horizontal headers. // // The real reason this is needed: Qt can easily resize the header to accomodate all the header labels, and that's enough for fixed-height rows, whose height is set with verticalHeader()->setDefaultSectionSize(). However, if resizeRowsToContents() gets called (and it seems that it must be called to get variable-height working, and some flag to enable this doesn't seem to exist) the height of each row's header becomes too big. Using getNumVertHdrSize() we force the height to be 1, thus allowing the data cells to tell the height (the final height is the maximum between data cells and the header cell for each row). //ttt2 At some point it seemed that rows would get larger even without calling getNumVertHdrSize(). This should be looked at again. QVariant getNumVertHdrSize(int nRowCount, Qt::Orientation eOrientation); // ttt2 add optional param QTableView to take the metrics from //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== // returns a label for a note; first 26 notes get labels "a" .. " z", next 26 get "A" .. "Z", then "aa" .. "az", "aA" .. "aZ", "ba", ... QString getNoteLabel(const Note* pNote); class QColor; const QColor& ERROR_PEN_COLOR(); const QColor& SUPPORT_PEN_COLOR(); //QColor getNoteColor(const Note& note); // color based on severity void defaultResize(QDialog& dlg); // resizes a dialog with inexisting/invalid size settings, so it covers an area slightly smaller than MainWnd; however, if the dialog is alrady bigger than that, it doesn't get shrinked QColor getDefaultBkgCol(); //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== void printFontInfo(const char* szLabel, const QFont& font); // adjusts the global font so it displays legible characters (on Windows it is possible under some unclear circumstances for all characters to be shown as small rectangles) void fixAppFont(QFont& font, std::string& strNewFont, int& nNewSize); #endif // #ifndef CommonDataH MP3Diags-1.0.12.079/src/TagReadPanel.cpp0000644000175000001440000002701211310373306016245 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "TagReadPanel.h" #include "DataStream.h" #include "Helpers.h" #include "Widgets.h" extern int CELL_HEIGHT; using namespace std; TagReadPanel::TagReadPanel(QWidget* pParent, TagReader* pTagReader) : QFrame(pParent) { QVBoxLayout* pLayout (new QVBoxLayout(this)); pLayout->setSpacing(6); pLayout->setContentsMargins(0, 10, 0, 0); setMaximumWidth(400); { QLabel* pLabel (new QLabel(pTagReader->getName(), this)); QFont font (pLabel->font()); int nSize (font.pixelSize()); if (-1 == nSize) { nSize = font.pointSize(); if (-1 != nSize) { nSize = nSize*4/3; font.setPointSize(nSize); } } else { nSize = nSize*4/3; font.setPixelSize(nSize); } font.setBold(true); pLabel->setFont(font); pLayout->addWidget(pLabel); } QColor gray (palette().color(QPalette::Window)); { QTableWidget* pTable (new QTableWidget(this)); pTable->setVerticalHeader(new NoCropHeaderView(pTable)); pTable->setEditTriggers(QAbstractItemView::NoEditTriggers); pTable->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); pTable->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); pTable->horizontalHeader()->setStretchLastSection(true); const int ROW_CNT (9); pTable->setRowCount(ROW_CNT); pTable->setColumnCount(1); QStringList lLabels; //lLabels << "Title" << "Artist" << "Track#" << "Time" << "Genre" << "Composer" << "Album" << "VA" << "Rating"; lLabels <<"Track#" << "Artist" << "Title" << "Album" << "VA" << "Time" << "Genre" << "Rating" << "Composer"; pTable->setVerticalHeaderLabels(lLabels); pTable->horizontalHeader()->hide(); //pTable->setMinimumHeight(300); int nHeight (CELL_HEIGHT*ROW_CNT + 2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, pTable)); pTable->setMaximumHeight(nHeight); pTable->setMinimumHeight(nHeight); //pTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); pTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); //pTable->setFrameShape(QFrame::NoFrame); QTableWidgetItem* pItem; pItem = new QTableWidgetItem(); // !!! from doc: The table takes ownership of the item. switch (pTagReader->getSupport(TagReader::TRACK_NUMBER)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: pItem->setText(convStr(pTagReader->getTrackNumber())); } pTable->setItem(0, 0, pItem); pItem = new QTableWidgetItem(); switch (pTagReader->getSupport(TagReader::ARTIST)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: pItem->setText(convStr(pTagReader->getArtist())); } pTable->setItem(1, 0, pItem); pItem = new QTableWidgetItem(); switch (pTagReader->getSupport(TagReader::TITLE)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: pItem->setText(convStr(pTagReader->getTitle())); } pTable->setItem(2, 0, pItem); pItem = new QTableWidgetItem(); switch (pTagReader->getSupport(TagReader::ALBUM)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: pItem->setText(convStr(pTagReader->getAlbumName())); } pTable->setItem(3, 0, pItem); pItem = new QTableWidgetItem(); switch (pTagReader->getSupport(TagReader::VARIOUS_ARTISTS)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: pItem->setText(convStr(pTagReader->getValue(TagReader::VARIOUS_ARTISTS))); } pTable->setItem(4, 0, pItem); pItem = new QTableWidgetItem(); switch (pTagReader->getSupport(TagReader::TIME)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: pItem->setText(pTagReader->getTime().asString()); } pTable->setItem(5, 0, pItem); pItem = new QTableWidgetItem(); switch (pTagReader->getSupport(TagReader::GENRE)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: pItem->setText(convStr(pTagReader->getGenre())); } pTable->setItem(6, 0, pItem); pItem = new QTableWidgetItem(); switch (pTagReader->getSupport(TagReader::RATING)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: { double d (pTagReader->getRating()); if (d >= 0) { pItem->setText(QString().sprintf("%1.1f", d)); } } } pTable->setItem(7, 0, pItem); pItem = new QTableWidgetItem(); switch (pTagReader->getSupport(TagReader::COMPOSER)) { case TagReader::NOT_SUPPORTED: pItem->setBackground(gray); break; default: pItem->setText(convStr(pTagReader->getComposer())); } pTable->setItem(8, 0, pItem); pLayout->addWidget(pTable); //ttt2 Oxygen shows regular cells under mouse with diferent background color } { // ttt2 perhaps use QScrollArea vector vImg (pTagReader->getImages()); m_pImgWidget = 0; QHBoxLayout* pImgWidgetLayout (0); for (int i = 0; i < cSize(vImg); ++i) { const ImageInfo& img (vImg[i]); if (0 == m_pImgWidget) { m_pImgWidget = new QWidget (this); pImgWidgetLayout = new QHBoxLayout(m_pImgWidget); pImgWidgetLayout->setContentsMargins(0, 0, 0, 0); //pImgWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); m_pImgWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); //pImgWidget->setMaximumHeight(40); } ImageInfoPanel* p (new ImageInfoPanel (this, img)); m_vpImgPanels.push_back(p); pImgWidgetLayout->addWidget(p); } if (0 != m_pImgWidget) { pImgWidgetLayout->addStretch(); pLayout->addWidget(m_pImgWidget); } } { QTextEdit* pOtherInfoM (new QTextEdit(this)); pOtherInfoM->setPlainText(convStr(pTagReader->getOtherInfo())); //pOtherInfoM->setTabStopWidth(fontMetrics().width("aBcDeF")); pOtherInfoM->setTabStopWidth(fontMetrics().width("F")); //pOtherInfoM->setEnabled(false); QPalette grayPalette (pOtherInfoM->palette()); grayPalette.setColor(QPalette::Base, gray); pOtherInfoM->setPalette(grayPalette); pOtherInfoM->setReadOnly(true); pOtherInfoM->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //pOtherInfoM->setFrameShape(QFrame::NoFrame); pLayout->addWidget(pOtherInfoM); } if (0 != m_pImgWidget) { QTimer::singleShot(1, this, SLOT(onCheckSize())); } } void TagReadPanel::onCheckSize() { QSize hint (m_pImgWidget->sizeHint()); QSize act (m_pImgWidget->size()); //qDebug("pImgWidget %dx%d %dx%d", hint.width(), hint.height(), act.width(), act.height()); if (hint.width() > act.width()) { int n (cSize(m_vpImgPanels)); int nNewSize ((act.width() + m_pImgWidget->layout()->spacing()) / n - m_pImgWidget->layout()->spacing() - 8); //ttt2 hard-coded "8"; it's for the frame drawn around auto-raise buttons; minimum value that works is 6, but not sure where to get it from; using 8 just in case) if (nNewSize > 64) { nNewSize = 64; } //qDebug("new sz %d", nNewSize); for (int i = 0; i < n; ++i) { m_vpImgPanels[i]->resize(nNewSize); } } } ImageInfoPanel::ImageInfoPanel(QWidget* pParent, const ImageInfo& imageInfo) : QFrame(pParent), m_imageInfo(imageInfo) //ttt1 name conflict with ImageInfoPanelWdgImpl { QVBoxLayout* pLayout (new QVBoxLayout(this)); pLayout->setContentsMargins(0, 0, 0, 0); pLayout->setSpacing(4); pLayout->addStretch(); createButton(64); m_pInfoLabel = new QLabel("", this); m_pInfoLabel->setText(m_imageInfo.getTextDescr()); m_pInfoLabel->setAlignment(Qt::AlignHCenter); pLayout->addWidget(m_pInfoLabel, 0, Qt::AlignHCenter); //setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); } void ImageInfoPanel::onShowFull() { m_imageInfo.showFull(this); } void ImageInfoPanel::createButton(int nSize) { QVBoxLayout* pLayout (dynamic_cast(layout())); const int BTN_SIZE (nSize); const int ICON_SIZE (BTN_SIZE - 2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth) - 2); //ttt2 not sure PM_DefaultFrameWidth is right m_pBtn = new QToolButton(this); m_pBtn->setIcon(QPixmap::fromImage(m_imageInfo.getImage(ICON_SIZE))); m_pBtn->setMaximumSize(BTN_SIZE, BTN_SIZE); m_pBtn->setMinimumSize(BTN_SIZE, BTN_SIZE); m_pBtn->setAutoRaise(true); m_pBtn->setToolTip("Click to see larger image"); m_pBtn->setIconSize(QSize(ICON_SIZE, ICON_SIZE)); pLayout->addWidget(m_pBtn, 0, Qt::AlignHCenter); connect(m_pBtn, SIGNAL(clicked(bool)), this, SLOT(onShowFull())); } void ImageInfoPanel::resize(int nSize) { delete m_pBtn; delete m_pInfoLabel; createButton(nSize); QVBoxLayout* pLayout (dynamic_cast(layout())); // ttt2 see why is this needed (otherwise the button isn't shown) m_pInfoLabel = new QLabel("", this); m_pInfoLabel->setMaximumSize(100, 1); pLayout->addWidget(m_pInfoLabel, 0, Qt::AlignHCenter); pLayout->setSpacing(0); } MP3Diags-1.0.12.079/src/PaletteDlgImpl.cpp0000644000175000001440000000776111230121556016635 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "PaletteDlgImpl.h" #include "TagEditorDlgImpl.h" #include "Helpers.h" PaletteDlgImpl::PaletteDlgImpl(CommonData* pCommonData, QWidget* pParent) : QDialog(pParent, getNoResizeWndFlags()), Ui::PaletteDlg(), m_pCommonData(pCommonData) // not a "thread window", but doesn't need resizing anyway { setupUi(this); m_vpColButtons.push_back(m_pCol0B); m_vpColButtons.push_back(m_pCol1B); m_vpColButtons.push_back(m_pCol2B); m_vpColButtons.push_back(m_pCol3B); m_vpColButtons.push_back(m_pCol4B); m_vpColButtons.push_back(m_pCol5B); m_vpColButtons.push_back(m_pCol6B); for (int i = 0; i < cSize(m_vpColButtons); ++i) { setBtnColor(i); } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } PaletteDlgImpl::~PaletteDlgImpl() { } /*$SPECIALIZATION$*/ void PaletteDlgImpl::on_m_pOkB_clicked() { accept(); } void PaletteDlgImpl::setBtnColor(int n) { /*QPalette pal (m_vpColButtons[n]->palette()); //QPalette pal (m_pCol0B->palette()); pal.setBrush(QPalette::Button, m_pCommonData->m_vTagEdtColors.at(n)); pal.setBrush(QPalette::Window, m_pCommonData->m_vTagEdtColors[n]); //pal.setBrush(QPalette::Midlight, QColor(255, 0, 0)); //pal.setBrush(QPalette::Dark, QColor(255, 0, 0)); //pal.setBrush(QPalette::Mid, QColor(255, 0, 0)); //pal.setBrush(QPalette::Shadow, QColor(255, 0, 0)); m_vpColButtons[n]->setPalette(pal);*/ int f (QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, m_vpColButtons.at(n)) + 2); //ttt2 hard-coded "2" int w (m_vpColButtons[n]->width() - f), h (m_vpColButtons[n]->height() - f); QPixmap pic (w, h); QPainter pntr (&pic); pntr.fillRect(0, 0, w, h, m_pCommonData->m_vTagEdtColors.at(n)); m_vpColButtons[n]->setIcon(pic); m_vpColButtons[n]->setIconSize(QSize(w, h)); /* QPixmap pic (21, 21); QPainter pntr (&pic); QRect r (0, 0, 21, 21); pntr.fillRect(r, QColor(255, 255, 0)); pntr.drawText(r, Qt::AlignCenter, "i"); m_vpColButtons[n]->setIcon(pic); m_vpColButtons[n]->setIconSize(QSize(21, 21));*/ } void PaletteDlgImpl::onButtonClicked(int n) { QColor c (QColorDialog::getColor(m_pCommonData->m_vTagEdtColors.at(n), this)); if (!c.isValid()) { return; } m_pCommonData->m_vTagEdtColors[n] = c; setBtnColor(n); } void PaletteDlgImpl::onHelp() { //openHelp("index.html"); } MP3Diags-1.0.12.079/src/ImageInfoPanel.ui0000644000175000001440000001541111232261463016432 0ustar ciobiusers ImageInfoPanelWdg 0 0 116 121 0 0 Form true QFrame::Panel QFrame::Raised 4 3 4 4 Thumb 0 0 0 0 0 Pos Dim Size Qt::Vertical 49 3 28 28 28 28 View full-size image ... :/images/zoom-in.png 22 22 true 0 30 0 0 0 0 0 28 28 28 28 Assign picture to songs ... :/images/assign.png 22 22 true 28 28 28 28 Erase local file ... :/images/remove_file.png 22 22 true Qt::Horizontal QSizePolicy::MinimumExpanding 1 20 MP3Diags-1.0.12.079/src/Mp3Manip.cpp0000644000175000001440000011706111345524562015420 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "Mp3Manip.h" #include "Helpers.h" #include "DataStream.h" #include "MpegStream.h" #include "ApeStream.h" #include "LyricsStream.h" #include "Id3V230Stream.h" #include "Id3V240Stream.h" #include "OsFile.h" using namespace std; using namespace pearl; //============================================================================================================ //============================================================================================================ //============================================================================================================ //#define VERBOSE //#define TRACE_FRAME_INFO //============================================================================================================ //============================================================================================================ //============================================================================================================ //============================================================================================================ //============================================================================================================ //============================================================================================================ static string s_strCrtMp3Handler; static string s_strPrevMp3Handler; string getGlobalMp3HandlerName() // a hack to get the name of the current file from inside various streams without storing the name there //ttt2 review { return s_strCrtMp3Handler + " (" + s_strPrevMp3Handler + ")"; } Mp3Handler::Mp3Handler(const string& strFileName, bool bStoreTraceNotes, const QualThresholds& qualThresholds) : m_pFileName(new StringWrp(strFileName)), m_pId3V230Stream(0), m_pId3V240Stream(0), m_pId3V1Stream(0), m_pLameStream(0), m_pXingStream(0), m_pVbriStream(0), m_pMpegStream(0), m_pApeStream(0), m_pLyricsStream(0), m_notes(1000), //ttt2 hard-coded m_nFastSaveTime(0) { s_strPrevMp3Handler = s_strCrtMp3Handler; s_strCrtMp3Handler = strFileName; TRACER("Mp3Handler constr: " + strFileName); ifstream_utf8 in (m_pFileName->s.c_str(), ios::binary); if (!in) { qDebug("Couldn't open file \"%s\"", strFileName.c_str()); //inspect(strFileName.c_str(), cSize(strFileName) + 1); trace("Couldn't open file: " + strFileName); CB_THROW1(FileNotFound()); } ostringstream out; time_t t (time(0)); out << "************************* " << strFileName << " ************************* memory: " << getMemUsage() << "; time: " << ctime(&t); string s (out.str()); s.erase(s.size() - 1); // needed because ctime() uses a terminating '\n' trace(""); trace(s); cout << s << endl; parse(in); m_notes.resetCounter(); analyze(qualThresholds); if (!bStoreTraceNotes) { m_notes.removeTraceNotes(); } getFileInfo(strFileName, m_nTime, m_nSize); } Mp3Handler::~Mp3Handler() { TRACER("Mp3Handler destr: " + m_pFileName->s); //qDebug("begin destroying Mp3Handler at %p", this); /*delete m_pId3V230Stream; delete m_pId3V240Stream; delete m_pId3V1Stream; delete m_pLameStream; delete m_pXingStream; delete m_pMpegStream; delete m_pApeStream; clearPtrContainer(m_vpNullStreams); clearPtrContainer(m_vpUnknownStreams);*/ clearPtrContainer(m_vpAllStreams); delete m_pFileName; //qDebug("done destroying Mp3Handler at %p", this); //clearPtrContainer(m_notes); } const Id3V2StreamBase* Mp3Handler::getId3V2Stream() const { if (0 != m_pId3V230Stream) { return m_pId3V230Stream; } return m_pId3V240Stream; } // what looks like the last frame in an MPEG stream may actually be truncated and somewhere inside it an ID3V1 or Ape tag may actually begin; if that's the case, that "frame" is removed from the stream; then most likely an "Unknown" stream will be detected, followed by an ID3V1 or Ape stream //ttt2 make sure that that is the case; a possibility is that the standard allows the last frame to be shorter than the calculated size, if some condition is met; this seems unlikely, though void Mp3Handler::checkLastFrameInMpegStream(ifstream_utf8& in) { STRM_ASSERT (!m_vpAllStreams.empty()); MpegStream* pStream (dynamic_cast(m_vpAllStreams.back())); if (0 == pStream) { return; } streampos pos (pStream->getLastFramePos()); streampos posNext (pStream->getPos()); posNext += pStream->getSize(); NoteColl notes (0); for (;;) { if (posNext - pos <= 0) { //clearPtrContainer(vpNotes); return; } in.clear(); in.seekg(pos); try { DataStream* p (new Id3V240Stream(0, notes, in, m_pFileName)); delete p; break; } catch (const std::bad_alloc&) { throw; } catch (...) //ttt2 replace "..." with something app-specific, to avoid catching system exceptions { in.clear(); in.seekg(pos); } in.seekg(pos); try { DataStream* p (new ApeStream(0, notes, in)); delete p; break; } catch (const std::bad_alloc&) { throw; } catch (...) //ttt2 replace "..." with something app-specific, to avoid catching system exceptions { in.clear(); in.seekg(pos); } in.seekg(pos); try { DataStream* p (new Id3V1Stream(0, notes, in)); delete p; break; } catch (const std::bad_alloc&) { throw; } catch (...) //ttt2 replace "..." with something app-specific, to avoid catching system exceptions { in.clear(); in.seekg(pos); } in.seekg(pos); try { DataStream* p (new LyricsStream(0, notes, in, m_pFileName->s)); delete p; break; } catch (const std::bad_alloc&) { throw; } catch (...) //ttt2 replace "..." with something app-specific, to avoid catching system exceptions { in.clear(); in.seekg(pos); } try { pos = getNextStream(in, pos); } catch (const EndOfFile&) { return; } } //clearPtrContainer(notes); pStream->removeLastFrame(); } void Mp3Handler::parse(ifstream_utf8& in) // ttt2 this function is a mess; needs rethinking { in.seekg(0, ios::end); m_posEnd = in.tellg(); in.seekg(0, ios::beg); STRM_ASSERT (in); int nIndex (0); //NoteColl& notes (m_notes); streampos pos (0); while (pos < m_posEnd) { in.clear(); in.seekg(pos); //if (m_vpAllStreams.size() > 48) if (cSize(m_vpAllStreams) > 100) //ttt2 perhaps make this configurable { { m_notes.resetCounter(); NoteColl& notes (m_notes); MP3_NOTE (pos, tooManyStreams); } UnknownDataStream* p (new UnknownDataStream(nIndex, m_notes, in, m_posEnd - pos)); UnknownDataStream* pPrev (m_vpAllStreams.empty() ? 0 : dynamic_cast(m_vpAllStreams.back())); if (0 != pPrev) { // last stream is "unknown" too pPrev->append(*p); delete p; } else { m_vpAllStreams.push_back(p); ++nIndex; } pos = m_posEnd; break; } bool bBrokenMpegFrameFound (false); int nBrokenMpegFrameCount (0); string strBrokenInfo; const char* szBrokenName (0); string strUnsupportedInfo; const char* szUnsupportedName (0); try { m_vpAllStreams.push_back(new Id3V230Stream(nIndex, m_notes, in, m_pFileName)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new Id3V240Stream(nIndex, m_notes, in, m_pFileName)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new LameStream(nIndex, m_notes, in)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const MpegFrame::PrematurelyEndedMpegFrame& ex) { // this could as well be in the Xing, Vbri or MPEG block and the program would perform pretty much the same (the only difference is that more exceptions would be thrown and caught as "...", with no side effect, if one of the other blocks is used); the exception means that what began as an MPEG frame should be longer than what is left in the file bBrokenMpegFrameFound = true; szBrokenName = MpegStream::getClassDisplayName(); strBrokenInfo = ex.m_strInfo; goto e1; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new XingStream(nIndex, m_notes, in)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new VbriStream(nIndex, m_notes, in)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new MpegStream(nIndex, m_notes, in)); trace("enter checkLastFrameInMpegStream()"); checkLastFrameInMpegStream(in); trace("exit checkLastFrameInMpegStream()"); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const MpegStream::StreamTooShort& ex) { // not 100% correct, but most likely it gets here after in the previous step it managed to read an MPEG stream which had a truncated last frame, which was removed from that stream and now it has thrown this exception; quite similar to what PrematurelyEndedMpegFrame as caught in the LameStream block above is doing, the difference here being that there are enough bytes left in the file to read a full "frame", while there it's EOF; both cases are likely to have some other streams inside them bBrokenMpegFrameFound = true; szBrokenName = MpegStream::getClassDisplayName(); strBrokenInfo = ex.m_strInfo; nBrokenMpegFrameCount = ex.m_nFrameCount; goto e1; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new ApeStream(nIndex, m_notes, in)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new Id3V1Stream(nIndex, m_notes, in)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new LyricsStream(nIndex, m_notes, in, m_pFileName->s)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); try { m_vpAllStreams.push_back(new NullDataStream(nIndex, m_notes, in)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; continue; } catch (const StreamIsBroken& ex) { if (0 == szBrokenName) { szBrokenName = ex.getStreamName(); strBrokenInfo = ex.getInfo(); } } catch (const StreamIsUnsupported& ex) { if (0 == szUnsupportedName) { szUnsupportedName = ex.getStreamName(); strUnsupportedInfo = ex.getInfo(); } } catch (const std::bad_alloc&) { throw; } catch (...) {} //ttt2 replace "..." with something app-specific, to avoid catching system exceptions in.clear(); in.seekg(pos); //------------------------------------------------------------------ e1: streampos posNextFrame; try { posNextFrame = getNextStream(in, pos); } catch (const EndOfFile&) { posNextFrame = m_posEnd; in.clear(); } //try { bool bAdded (false); if (bBrokenMpegFrameFound) //ttt2 review this: "bBrokenMpegFrameFound gets set if MpegStream::StreamTooShort is thrown"; it's probably OK { try { MpegStream* pPrev (m_vpAllStreams.empty() ? 0 : dynamic_cast(m_vpAllStreams.back())); m_vpAllStreams.push_back(new TruncatedMpegDataStream(pPrev, nIndex, m_notes, in, posNextFrame - pos)); pos += m_vpAllStreams.back()->getSize(); ++nIndex; bAdded = true; } catch (const TruncatedMpegDataStream::NotTruncatedMpegDataStream&) { in.clear(); in.seekg(pos); /* ttt2 perhaps add limit of 10 broken streams per file keep in mind that a transformation that removes broken streams will have trouble processing a file with "10 broken streams", because after it removes the first, a new one will get created, always having 10 of them */ } } //ttt2 consider this: there's a stream beginning identified at 1000 and the next one is at 8000; if the first begins with a valid MPEG frame and the second is something else, the whole block from 1000 up to 7999 is identified as "broken mpeg"; this isn't quite right: since no other mpeg frame can be found in the block (if it could, it would be the second stream beginning), there's a lot of other data in the stream besides an mpeg frame; this doesn't feel right; if (!bAdded) { streamoff nSize (posNextFrame - pos); if (0 != szUnsupportedName) { m_vpAllStreams.push_back(new UnsupportedDataStream(nIndex, m_notes, in, nSize, szUnsupportedName, strUnsupportedInfo)); //pos += m_vpAllStreams.back()->getSize(); ++nIndex; } else { // either broken or unknown; these have little useful information, so try to append to the previous one, in these cases: both broken and unknown can be appended to truncated and unknown alone can be appended to unknown DataStream* pPrev (m_vpAllStreams.empty() ? 0 : m_vpAllStreams.back()); TruncatedMpegDataStream* pPrevTrunc (dynamic_cast(pPrev)); UnknownDataStream* pPrevUnkn (dynamic_cast(pPrev)); if (MpegStream::getClassDisplayName() == szBrokenName && 1 == nBrokenMpegFrameCount) { // a "broken audio" with a single sense doesn't make much sense at this point (but it mattered above, to add a truncated audio stream) szBrokenName = 0; } if (0 != pPrevTrunc && pPrevTrunc->hasSpace(nSize)) { // append to truncated UnknownDataStream* p (new UnknownDataStream(nIndex, m_notes, in, nSize)); pPrevTrunc->append(*p); delete p; } else if (0 != szBrokenName) { // create broken m_vpAllStreams.push_back(new BrokenDataStream(nIndex, m_notes, in, nSize, szBrokenName, strBrokenInfo)); //pos += m_vpAllStreams.back()->getSize(); ++nIndex; } else if (0 != pPrevUnkn) { // append to unknown UnknownDataStream* p (new UnknownDataStream(nIndex, m_notes, in, nSize)); pPrevUnkn->append(*p); delete p; } else { // create unknown UnknownDataStream* p (new UnknownDataStream(nIndex, m_notes, in, nSize)); m_vpAllStreams.push_back(p); ++nIndex; } } pos += nSize; } } /*catch (...) // !!! DON'T catch anything; there's no point; the file is changed or something else pretty bad happened, because creating an Unknown stream shouldn't throw; most likely the existing streams became invalid too; also, there's a chance that the implementation of UnknownDataStream has a bug and an infinite loop will be entered, as all the constructors fail and the position in the file doesn't advance { in.clear(); in.seekg(pos); not ok }*/ } //cout << "=======================\n"; //CB_ASSERT (!m_vpAllStreams.empty()); STRM_ASSERT (pos == m_posEnd); pos = 0; for (int i = 0; i < cSize(m_vpAllStreams); ++i) { DataStream* p (m_vpAllStreams[i]); //cout << p->getInfo() << endl; STRM_ASSERT (p->getPos() == pos); pos += p->getSize(); } STRM_ASSERT (pos == m_posEnd); } // checks the streams for issues (missing ID3V2, Unknown streams, inconsistencies, ...) void Mp3Handler::analyze(const QualThresholds& qualThresholds) { NoteColl& notes (m_notes); // for MP3_NOTE() for (int i = 0, n = cSize(m_vpAllStreams); i < n; ++i) { DataStream* pDs (m_vpAllStreams[i]); { Id3V230Stream* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pId3V230Stream) m_pId3V230Stream = p; else MP3_NOTE (p->getPos(), twoId3V230); } } { Id3V240Stream* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pId3V240Stream) m_pId3V240Stream = p; else MP3_NOTE (p->getPos(), twoId3V240); } } { Id3V1Stream* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pId3V1Stream) m_pId3V1Stream = p; else MP3_NOTE (p->getPos(), twoId3V1); } } { LameStream* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pLameStream) m_pLameStream = p; else MP3_NOTE (p->getPos(), twoLame); } } { XingStreamBase* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pXingStream) { m_pXingStream = p; if (i < n - 2 && p->isBrokenByMp3Fixer(m_vpAllStreams[i + 1], m_vpAllStreams[i + 2])) { MP3_NOTE (p->getPos(), xingAddedByMp3Fixer); } if (i < n - 1) { MpegStream* q (dynamic_cast(m_vpAllStreams[i + 1])); if (0 != q && p->getFrameCount() != q->getFrameCount()) { MP3_NOTE (p->getPos(), xingFrameCountMismatch); } } } else MP3_NOTE (p->getPos(), twoXing); } } { VbriStream* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pVbriStream) m_pVbriStream = p; else MP3_NOTE (p->getPos(), twoVbri); } } { MpegStream* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pMpegStream) m_pMpegStream = p; else MP3_NOTE (p->getPos(), twoAudio); //const MpegFrame& frm (p->getFirstFrame()); if (p->isVbr()) { switch (p->getChannelMode()) { // ttt2 should be possible that changing qual thresholds in config triggers notes being added / removed case MpegFrame::STEREO: if (p->getBitrate() < qualThresholds.m_nStereoVbr) { MP3_NOTE (p->getPos(), lowQualAudio); } break; case MpegFrame::JOINT_STEREO: if (p->getBitrate() < qualThresholds.m_nJointStereoVbr) { MP3_NOTE (p->getPos(), lowQualAudio); } break; case MpegFrame::DUAL_CHANNEL: if (p->getBitrate() < qualThresholds.m_nDoubleChannelVbr) { MP3_NOTE (p->getPos(), lowQualAudio); } break; case MpegFrame::SINGLE_CHANNEL: if (p->getBitrate() < qualThresholds.m_nDoubleChannelVbr / 2) { MP3_NOTE (p->getPos(), lowQualAudio); } break; } } else { switch (p->getChannelMode()) { case MpegFrame::STEREO: if (p->getBitrate() < qualThresholds.m_nStereoCbr) { MP3_NOTE (p->getPos(), lowQualAudio); } break; case MpegFrame::JOINT_STEREO: if (p->getBitrate() < qualThresholds.m_nJointStereoCbr) { MP3_NOTE (p->getPos(), lowQualAudio); } break; case MpegFrame::DUAL_CHANNEL: if (p->getBitrate() < qualThresholds.m_nDoubleChannelCbr) { MP3_NOTE (p->getPos(), lowQualAudio); } break; case MpegFrame::SINGLE_CHANNEL: if (p->getBitrate() < qualThresholds.m_nDoubleChannelCbr / 2) { MP3_NOTE (p->getPos(), lowQualAudio); } break; } } } } { ApeStream* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pApeStream) m_pApeStream = p; else MP3_NOTE (p->getPos(), twoApe); } } { LyricsStream* p (dynamic_cast(pDs)); if (0 != p) { if (0 == m_pLyricsStream) m_pLyricsStream = p; else MP3_NOTE (p->getPos(), twoLyr); } } { NullDataStream* p (dynamic_cast(pDs)); if (0 != p) { m_vpNullStreams.push_back(p); } } { UnknownDataStream* p (dynamic_cast(pDs)); if (0 != p) { m_vpUnknownStreams.push_back(p); } } { BrokenDataStream* p (dynamic_cast(pDs)); if (0 != p) { m_vpBrokenStreams.push_back(p); } } { UnsupportedDataStream* p (dynamic_cast(pDs)); if (0 != p) { m_vpUnsupportedStreams.push_back(p); } } { TruncatedMpegDataStream* p (dynamic_cast(pDs)); if (0 != p) { m_vpTruncatedMpegStreams.push_back(p); } } } if (0 == m_pMpegStream) { MP3_NOTE (-1, noAudio); } if (0 == m_pId3V230Stream) { MP3_NOTE (-1, noId3V230); } if (0 != m_pId3V230Stream && 0 != m_pId3V240Stream) { MP3_NOTE (m_pId3V240Stream->getPos(), bothId3V230_V240); } if (0 != m_pVbriStream) { MP3_NOTE (m_pVbriStream->getPos(), vbriFound); } //if (0 != m_pLyricsStream) { MP3_NOTE (m_pLyricsStream->getPos(), lyricsNotSupported); } if (0 != m_pId3V1Stream && 0 == m_pId3V230Stream && 0 == m_pId3V240Stream && 0 == m_pApeStream) { MP3_NOTE (m_pId3V1Stream->getPos(), onlyId3V1); } if (0 == m_pId3V1Stream && 0 == m_pId3V230Stream && 0 == m_pId3V240Stream && 0 == m_pApeStream) { MP3_NOTE (-1, noInfoTag); } if (!m_vpNullStreams.empty()) { MP3_NOTE (m_vpNullStreams[0]->getPos(), foundNull); } if (0 != m_pVbriStream && 0 != m_pXingStream) { MP3_NOTE (m_pVbriStream->getPos(), foundVbriAndXing); } if (0 != m_pXingStream && 0 != m_pMpegStream && m_pXingStream->getIndex() != m_pMpegStream->getIndex() - 1) { MP3_NOTE (m_pXingStream->getPos(), xingNotBeforeAudio); } if (0 != m_pXingStream && 0 != m_pMpegStream && !m_pXingStream->matchesStructure(*m_pMpegStream)) { MP3_NOTE (m_pXingStream->getPos(), incompatXing); } if (0 != m_pId3V1Stream && 0 != m_pMpegStream && m_pId3V1Stream->getIndex() < m_pMpegStream->getIndex()) { MP3_NOTE (m_pId3V1Stream->getPos(), id3v1BeforeAudio); } if (0 != m_pId3V230Stream && 0 != m_pId3V230Stream->getIndex()) { MP3_NOTE (m_pId3V230Stream->getPos(), id3v230AfterAudio); } if (0 == m_pXingStream && 0 != m_pMpegStream && m_pMpegStream->isVbr()) { MP3_NOTE (m_pMpegStream->getPos(), missingXing); } if (0 != m_pMpegStream && m_pMpegStream->isVbr() && (MpegFrame::MPEG1 != m_pMpegStream->getFirstFrame().getVersion() || MpegFrame::LAYER3 != m_pMpegStream->getFirstFrame().getLayer())) { MP3_NOTE (m_pMpegStream->getPos(), vbrUsedForNonMpg1L3); } if ( (0 != m_pMpegStream) && (0 == m_pApeStream || !m_pApeStream->hasMp3Gain()) && (0 == m_pId3V230Stream || !m_pId3V230Stream->hasReplayGain()) && (0 == m_pId3V240Stream || !m_pId3V240Stream->hasReplayGain())) //ttt2 not quite OK when mutliple ID3V2 streams are found { MP3_NOTE (m_pMpegStream->getPos(), noMp3Gain); } if (!m_vpBrokenStreams.empty()) { if (1 == cSize(m_vpBrokenStreams) && m_vpBrokenStreams.back() == m_vpAllStreams.back()) { MP3_NOTE (m_vpBrokenStreams.back()->getPos(), brokenAtTheEnd); } else { MP3_NOTE (m_vpBrokenStreams.back()->getPos(), brokenInTheMiddle); } } if (!m_vpUnknownStreams.empty()) { if (1 == cSize(m_vpUnknownStreams) && m_vpUnknownStreams.back() == m_vpAllStreams.back()) { MP3_NOTE (m_vpUnknownStreams.back()->getPos(), unknownAtTheEnd); } else { MP3_NOTE (m_vpUnknownStreams.back()->getPos(), unknownInTheMiddle); } } if (!m_vpUnsupportedStreams.empty()) { MP3_NOTE (m_vpUnsupportedStreams.back()->getPos(), unsupportedFound); } if (!m_vpTruncatedMpegStreams.empty()) { if (1 == cSize(m_vpTruncatedMpegStreams) && m_vpTruncatedMpegStreams.back() == m_vpAllStreams.back()) { MP3_NOTE (m_vpTruncatedMpegStreams.back()->getPos(), truncAudioWithWholeFile); } else { MP3_NOTE (m_vpTruncatedMpegStreams.back()->getPos(), truncAudio); } } m_notes.sort(); //sort(m_notes.begin(), m_notes.end(), notePtrCmp); } // removes the ID3V2 tag and the notes associated with it and scans the file again, but only the new ID3V2 tag; // asserts that there was an existing ID3V2 tag at the beginning and it had the same size as the new one; // this isn't really const, but it seems better to have a const_cast in the only place where it is needed rather than remove the const restriction from many places void Mp3Handler::reloadId3V2() const { const_cast(this)->reloadId3V2Hlp(); } void Mp3Handler::reloadId3V2Hlp() { STRM_ASSERT (!m_vpAllStreams.empty()); Id3V2StreamBase* pOldId3V2 (dynamic_cast(m_vpAllStreams[0])); STRM_ASSERT (0 != pOldId3V2); m_notes.removeNotes(pOldId3V2->getPos(), pOldId3V2->getPos() + pOldId3V2->getSize()); ifstream_utf8 in (m_pFileName->s.c_str(), ios::binary); STRM_ASSERT (in); // ttt2 not quite right; could have been deleted externally Id3V230Stream* pNewId3V2; try { pNewId3V2 = new Id3V230Stream(0, m_notes, in, m_pFileName); } catch (const std::bad_alloc&) { throw; } catch (...) { STRM_ASSERT (false); } STRM_ASSERT (pOldId3V2->getSize() == pNewId3V2->getSize()); delete pOldId3V2; m_vpAllStreams[0] = pNewId3V2; if (m_pId3V240Stream == pOldId3V2) { m_pId3V240Stream = 0; } m_pId3V230Stream = pNewId3V2; m_notes.addFastSaveWarn(); m_notes.sort(); } static bool isMpegHdr(unsigned char* p) { bool b; decodeMpegFrame(reinterpret_cast(p), " ", &b); return b; } // finds the position where the next ID3V2, MPEG, Xing, Lame or Ape stream begins; "pos" is not considered; the search starts at pos+1; throws if no stream is found streampos getNextStream(istream& in, streampos pos) { StreamStateRestorer rst (in); static const int BFR_SIZE (1024); char bfr [BFR_SIZE]; static const int MPEG_HDR_SIZE (4); static const char* ID3V2_HDR ("ID3"); static const int ID3V2_HDR_SIZE (strlen(ID3V2_HDR)); static const char* ID3V1_HDR ("TAG"); static const int ID3V1_HDR_SIZE (strlen(ID3V1_HDR)); static const char* APE_HDR ("APETAGEX"); static const int APE_HDR_SIZE (strlen(APE_HDR)); static const char* LYRICS_HDR ("LYRICSBEGIN"); static const int LYRICS_HDR_SIZE (strlen(LYRICS_HDR)); static const int MAX_HDR_SIZE (max(MPEG_HDR_SIZE, max(ID3V2_HDR_SIZE, max(ID3V1_HDR_SIZE, max(APE_HDR_SIZE, LYRICS_HDR_SIZE))))); pos += 1; int i (0); in.clear(); for (;;) { in.seekg(pos); int nRead (read(in, bfr, BFR_SIZE)); if (0 == nRead) { throw EndOfFile(); } for (i = 0; i < nRead; ++i) { unsigned char* p (reinterpret_cast(bfr + i)); //if (nRead - i >= MPEG_HDR_SIZE && 0xff == *p && 0xe0 == (0xe0 & *(p + 1))) { goto e1; } if (nRead - i >= MPEG_HDR_SIZE && isMpegHdr(p)) { goto e1; } // MPEG, Xing, Lame // older comment: "ff ff" is not a valid MPEG beginning, so it shouldn't pass // 2008.08.06: actually it's valid: "MPEG1, Layer 1, No CRC"; however, "ff e?", "ff f0", "ff f1", "ff f8" and "ff f9" are invalid, and they are tested by isMpegHdr if (nRead - i >= ID3V2_HDR_SIZE && 0 == strncmp(ID3V2_HDR, bfr + i, ID3V2_HDR_SIZE)) { goto e1; } // ID3V2 (2.3, 2.2, 2.4) if (nRead - i >= ID3V1_HDR_SIZE && 0 == strncmp(ID3V1_HDR, bfr + i, ID3V1_HDR_SIZE)) { goto e1; } // ID3V1 if (nRead - i >= APE_HDR_SIZE && 0 == strncmp(APE_HDR, bfr + i, APE_HDR_SIZE)) { goto e1; } // Ape V2 if (nRead - i >= APE_HDR_SIZE && 0 == strncmp(LYRICS_HDR, bfr + i, LYRICS_HDR_SIZE)) { goto e1; } // Lyrics } pos += BFR_SIZE - MAX_HDR_SIZE + 1; } e1: pos += i; /*if (g_bVerbose)*/ { TRACE("stream found at 0x" << hex << pos << dec); } // !!! no need to call rst.setOk(); we want the read pointer to be restored return pos; } /*void Mp3Handler::logStreamInfo() const { //cout << endl; for (vector::const_iterator it = m_vpAllStreams.begin(), end = m_vpAllStreams.end(); it != end; ++it) { //cout << " " << (*it)->getName(); TRACE((*it)->getInfo()); } //cout << endl; } void Mp3Handler::logStreamInfo(std::ostream& out) const { for (vector::const_iterator it = m_vpAllStreams.begin(), end = m_vpAllStreams.end(); it != end; ++it) { out << (*it)->getInfo() << endl; } } */ long long Mp3Handler::getSize() const { return m_posEnd; //ttt3 doesn't work for large files } QString Mp3Handler::getUiName() const // uses native separators { return toNativeSeparators(convStr(getName())); } string Mp3Handler::getShortName() const { string::size_type n (m_pFileName->s.rfind(getPathSep())); STRM_ASSERT (string::npos != n); return m_pFileName->s.substr(n + 1); } string Mp3Handler::getDir() const { return getParent(m_pFileName->s); } // if the underlying file seems changed (or removed); looks at time and size, as well as FastSaveWarn and Notes::getMissingNote(); a difference in size always makes this return true; if bConsiderFastSave is true, both m_nFastSaveTime and m_nTime are tested, while m_notes.hasFastSaveWarn() and Notes::getMissingNote() are ignored; if it is false, m_nFastSaveTime is ignored, while m_nTime, m_notes.hasFastSaveWarn(), and Notes::getMissingNote() are tested bool Mp3Handler::needsReload(bool bUseFastSave) const { long long nSize, nTime; try { getFileInfo(m_pFileName->s, nTime, nSize); } catch (const NameNotFound&) { return true; } if (nSize != m_nSize) { return true; } if (bUseFastSave) { return nTime != m_nTime && nTime != m_nFastSaveTime; } if (nTime != m_nTime || m_notes.hasFastSaveWarn()) { return true; } const vector& vpNotes (m_notes.getList()); return !vpNotes.empty() && vpNotes[0]->getDescription() == Notes::getMissingNote()->getDescription(); } //============================================================================================================ //============================================================================================================ //============================================================================================================ bool CmpMp3HandlerPtrByName::operator()(const Mp3Handler* p1, const std::string& strName2) const { return cmp(p1->getName(), strName2); } bool CmpMp3HandlerPtrByName::operator()(const std::string& strName1, const Mp3Handler* p2) const { return cmp(strName1, p2->getName()); } bool CmpMp3HandlerPtrByName::operator()(const Mp3Handler* p1, const Mp3Handler* p2) const { return cmp(p1->getName(), p2->getName()); } bool CmpMp3HandlerPtrByName::cmp(const std::string& strName1, const std::string& strName2) const { const std::string strDir1 (getParent(strName1)); const std::string strDir2 (getParent(strName2)); if (strDir1 == strDir2) { return strName1 < strName2; } // ttt3 maybe make comparison locale-dependant return strDir1 < strDir2; } MP3Diags-1.0.12.079/src/ApeStream.h0000644000175000001440000001145311261077516015317 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef ApeStreamH #define ApeStreamH #include #include #include "DataStream.h" //struct ApeItem; struct ApeItem // !!! needs to be public for serialization { ApeItem(NoteColl& notes, std::istream& in); ~ApeItem() {} unsigned char m_cFlags1; unsigned char m_cFlags2; unsigned char m_cFlags3; unsigned char m_cFlags4; std::string m_strName; std::vector m_vcValue; // raw value; may be binary or UTF8 enum Type { UTF8, BINARY }; // ttt2 add UTF8LIST, DATE, ... Type m_eType; std::string getUtf8String() const; int getTotalSize() const { return 4 + 4 + int(m_strName.size()) + 1 + int(m_vcValue.size()); } private: friend class boost::serialization::access; ApeItem() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & m_cFlags1; ar & m_cFlags2; ar & m_cFlags3; ar & m_cFlags4; ar & m_strName; ar & m_vcValue; ar & m_eType; } }; class ApeStream : public DataStream, public TagReader { int m_nVersion; std::streampos m_pos; std::streamoff m_nSize; std::vector m_vpItems; void readKeys(NoteColl& notes, std::istream& in); ApeItem* findItem(const char* szFrameName); const ApeItem* findItem(const char* szFrameName) const; public: ApeStream(int nIndex, NoteColl& notes, std::istream& in); ~ApeStream(); /*override*/ void copy(std::istream& in, std::ostream& out); DECL_RD_NAME("Ape"); /*override*/ std::string getInfo() const; /*override*/ std::streampos getPos() const { return m_pos; } /*override*/ std::streamoff getSize() const { return m_nSize; } //enum Mp3Gain { NONE = 0x00, TRACK = 0x01, ALBUM = 0x02, BOTH = 0x03 }; //Mp3Gain getMp3GainStatus() const; bool hasMp3Gain() const; struct NotApeStream {}; struct NotApeHeader {}; struct NotApeFooter {}; struct HeaderFooterMismatch {}; // ================================ TagReader ========================================= /*override*/ std::string getTitle(bool* pbFrameExists = 0) const; /*override*/ std::string getArtist(bool* pbFrameExists = 0) const; /*override*/ std::string getTrackNumber(bool* pbFrameExists = 0) const; /*override*/ TagTimestamp getTime(bool* pbFrameExists = 0) const; /*override*/ std::string getGenre(bool* pbFrameExists = 0) const; /*override*/ ImageInfo getImage(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } /*override*/ std::string getAlbumName(bool* pbFrameExists = 0) const; /*override*/ std::string getOtherInfo() const; /*override*/ SuportLevel getSupport(Feature) const; private: friend class boost::serialization::access; ApeStream() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); ar & m_nVersion; ar & m_pos; ar & m_nSize; ar & m_vpItems; } }; #endif // ifndef ApeStreamH MP3Diags-1.0.12.079/src/CheckedDir.cpp0000644000175000001440000002730011310261030015731 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #ifndef WIN32 #else #include #endif #include "CheckedDir.h" #include "Helpers.h" using namespace std; /*override*/ QVariant CheckedDirModel::data(const QModelIndex& index, int nRole /*= Qt::DisplayRole*/) const { //qDebug("CheckedDirModel::data(%d, %d, role=%d)", index.row(), index.column(), nRole); LAST_STEP("CheckedDirModel::data()"); if (Qt::CheckStateRole == nRole) { //QString s (getDir(index)); QString s (filePath(index)); bool bIsChecked (false), bIsUnchecked (false), bHasUncheckedDescendant (false); QString qstrClosestCheckedAncestor, qstrClosestUncheckedAncestor; for (int i = 0, n = cSize(m_vCheckedDirs); i < n; ++i) { QString s1 (m_vCheckedDirs[i]); if (s == s1) { bIsChecked = true; } if (isDescendant(s, s1)) { if (isDescendant(s1, qstrClosestCheckedAncestor)) { qstrClosestCheckedAncestor = s1; } } } for (int i = 0, n = cSize(m_vUncheckedDirs); i < n; ++i) { QString s1 (m_vUncheckedDirs[i]); if (s == s1) { bIsUnchecked = true; } if (isDescendant(s, s1)) { if (isDescendant(s1, qstrClosestUncheckedAncestor)) { qstrClosestUncheckedAncestor = s1; } } if (isDescendant(s1, s)) { bHasUncheckedDescendant = true; } } if ( !bIsChecked && (bIsUnchecked || qstrClosestCheckedAncestor.isEmpty() || isDescendant(qstrClosestUncheckedAncestor, qstrClosestCheckedAncestor)) ) { return Qt::Unchecked; } return bHasUncheckedDescendant ? Qt::PartiallyChecked : Qt::Checked; } #ifndef WIN32 #else if (Qt::DisplayRole == nRole) { QVariant x (QDirModel::data(index, nRole)); if (!x.isNull()) { QString qs (x.toString()); if (2 == qs.size() && ':' == qs[1] && 'A' != qs[0] && 'B' != qs[0]) { // get the drive label, but not for floppies char szLabel [MAX_PATH + 1]; char szFsType [MAX_PATH + 1]; static bool s_bSetErrorModeCalled (false); //ttt2 perhaps see how long it takes and disable this if it's too long; OTOH all the drives get stat'ed anyway, so one more time isn't such a big deal if (!s_bSetErrorModeCalled) { s_bSetErrorModeCalled = true; SetErrorMode(SEM_FAILCRITICALERRORS); // so the user isn't told to insert the floppy or CD just to stat it; apparently this happens if set up so } if (GetVolumeInformationA(qs.toUtf8().constData(), szLabel, MAX_PATH + 1, 0, 0, 0, szFsType, MAX_PATH + 1)) { //return qs + " " + szLabel + " " + szFsType; return qs + " [" + szLabel + "]"; } } } } /*if (0 == index.row() && 0 == index.column()) // failed attempt to get rid of scanning A: the thing is that more than just data() needs to be overridden (e.g. roCount()) { return QVariant(); }*/ #endif return QDirModel::data(index, nRole); } bool CheckedDirModel::setData(const QModelIndex& index, const QVariant& value, int nRole /*= Qt::EditRole*/) { Qt::CheckState eCheck ((Qt::CheckState)value.toInt()); if (Qt::PartiallyChecked == eCheck) { eCheck = Qt::Checked == (Qt::CheckState)data(index, Qt::CheckStateRole).toInt() ? Qt::Unchecked : Qt::Checked; } if (Qt::CheckStateRole == nRole) { bool hasClosestAncestorChecked (false); QString sClosestAncestor; QString s (filePath(index)); //if (3 == s.size()) { return false; } vector v; // remove s and its descendants from m_vCheckedDirs, if any are there; compute sClosestAncestor; for (int i = 0, n = cSize(m_vCheckedDirs); i < n; ++i) { QString s1 (m_vCheckedDirs[i]); //qDebug("s1=%s, s=%s", s1.toUtf8().data(), s.toUtf8().constData()); if (!isDescendant(s1, s) && s != s1) { v.push_back(s1); if (isDescendant(s1, sClosestAncestor) && isDescendant(s, s1)) { sClosestAncestor = s1; hasClosestAncestorChecked = true; } } } v.swap(m_vCheckedDirs); v.clear(); // remove s and its descendants from m_vUncheckedDirs, if any are there; compute sClosestAncestor; for (int i = 0, n = cSize(m_vUncheckedDirs); i < n; ++i) { QString s1 (m_vUncheckedDirs[i]); if (!isDescendant(s1, s) && s != s1) { v.push_back(s1); if (isDescendant(s1, sClosestAncestor) && isDescendant(s, s1)) { sClosestAncestor = s1; hasClosestAncestorChecked = false; } } } v.swap(m_vUncheckedDirs); switch (eCheck) { case Qt::Checked: if (!hasClosestAncestorChecked) { m_vCheckedDirs.push_back(s); } break; case Qt::Unchecked: if (hasClosestAncestorChecked) { m_vUncheckedDirs.push_back(s); } break; default: CB_ASSERT (false); } /*for (;;) //ttt2 { if all children of a checked node are unchecked, remove the node from the checked list; repeat until there's nothing to change; must check all in the tree; 2009.04.13 - or maybe not: more directories may be added later; more importantly, the node might have files itself }*/ emit layoutChanged(); return true; } return QDirModel::setData(index, eCheck, nRole); } /*QString CheckedDirModel::getDir(const QModelIndex& index) const { if (!index.isValid()) { return "root"; } // !!! using "root" rather than an empty dir to distinguish between an unassigned string and one that holds the root dir QString s (getDir(index.parent()) + "/" + data(index).toString()); //qDebug("%s", s.toUtf8().constData()); return s; } */ // non-reflexive (isDescendant(s, s) is false) // order: "" is above "/"; "/" is above the rest; bool CheckedDirModel::isDescendant(const QString& s1, const QString& s2) const { if (s1.isEmpty()) { return false; } return s2.isEmpty() || (s2 == "/" && s1.size() > 1) || // ttt3 linux-specific (s1.startsWith(s2) && s1.size() > s2.size() && s1[s2.size()] == '/') #ifndef WIN32 #else || (s1.startsWith(s2) && s1.size() > s2.size() && 3 == s2.size() && ':' == s1[1] && ':' == s2[1]) #endif ; } // besides assigning the vectors, also expands the tree to show them void CheckedDirModel::setDirs(const vector& vstrCheckedDirs, const vector& vstrUncheckedDirs, QTreeView* pTreeView) { m_vCheckedDirs = convStr(vstrCheckedDirs); m_vUncheckedDirs = convStr(vstrUncheckedDirs); expandNodes(pTreeView); } void CheckedDirModel::expandNodes(QTreeView* pTreeView) { for (int i = cSize(m_vUncheckedDirs) - 1; i >= 0; --i) { expandNode(m_vUncheckedDirs[i], pTreeView); } for (int i = cSize(m_vCheckedDirs) - 1; i >= 0; --i) { expandNode(m_vCheckedDirs[i], pTreeView); } emit layoutChanged(); } void CheckedDirModel::expandNode(const QString& s, QTreeView* pTreeView) { pTreeView->expand(index("/")); int n (1); for (;;) { n = s.indexOf('/', n); if (-1 == n) { break; } pTreeView->expand(index(s.left(n))); ++n; } //qDebug("%d %d", pTreeView->width(), pTreeView->height()); pTreeView->scrollTo(index(s), QAbstractItemView::PositionAtCenter); pTreeView->horizontalScrollBar()->setValue(0); // !!! needed because PositionAtCenter scrolls horizontally as well, which is strange for dirs with large names //pTreeView->scrollTo(index(s), QAbstractItemView::EnsureVisible); //pTreeView->scrollTo(index(s), QAbstractItemView::PositionAtTop); //pTreeView->scrollTo(index(s), QAbstractItemView::PositionAtBottom); } std::vector CheckedDirModel::getCheckedDirs() const { return convStr(m_vCheckedDirs); } std::vector CheckedDirModel::getUncheckedDirs() const { return convStr(m_vUncheckedDirs); } #ifdef jiLPojiojsdjoiHJIOHIO //#include "CheckedDir.h" CheckedDirModel* pModel (new CheckedDirModel(this)); pModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::Drives); //pModel->setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::Drives); //QStringList lst; //lst << "/r/temp/1/tmp2/z/pic"; //pModel->setNameFilters(lst); pModel->setSorting(QDir::IgnoreCase); treeView->setModel(pModel); //treeView->setRootIndex(pModel->index("/r/temp/1/tmp2/z/pic")); treeView->expand(pModel->index("/")); treeView->expand(pModel->index("/r")); treeView->expand(pModel->index("/r/temp")); treeView->expand(pModel->index("/r/temp/1")); treeView->expand(pModel->index("/r/temp/1/tmp2")); treeView->expand(pModel->index("/r/temp/1/tmp2/z")); treeView->expand(pModel->index("/r/temp/1/tmp2/z/pic")); treeView->scrollTo(pModel->index("/r/temp/1/tmp2/z/pic", QAbstractItemView::PositionAtCenter)); #endif //ttt2 perhaps replace QDirModel with QFileSystemModel on Qt>4.4. See also https://sourceforge.net/apps/mantisbt/mp3diags/view.php?id=34 ; at least should be more responsive when there are network and floppy drives; see also http://lists.trolltech.com/qt-interest/2007-12/thread00336-0.html and http://www.qtcentre.org/forum/f-qt-programming-2/t-disable-floppy-reading-in-a-qfiledialog-1799.html //ttt2 perhaps use QDirModel::lazyChildCount; or maybe not; it will show that all dirs have children //ttt2 ? use QFileSystemWatcher MP3Diags-1.0.12.079/src/FileRenamerDlgImpl.h0000644000175000001440000001511011267343013017064 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef FileRenamerDlgImplH #define FileRenamerDlgImplH #include #include #include #include #include #include #include "ui_FileRenamer.h" class CommonData; class QSettings; class FileRenamerDlgImpl; class Mp3Handler; class Renamer; namespace FileRenamer { // current album / filtered handlers; class HndlrListModel : public QAbstractTableModel { Q_OBJECT FileRenamerDlgImpl* m_pFileRenamerDlgImpl; const CommonData* m_pCommonData; const Renamer* m_pRenamer; bool m_bUseCurrentView; /*override*/ Qt::ItemFlags flags(const QModelIndex& index) const; /*override*/ bool setData(const QModelIndex& index, const QVariant& value, int nRole /*= Qt::EditRole*/); public: HndlrListModel(CommonData* pCommonData, FileRenamerDlgImpl* pFileRenamerDlgImpl, bool bUseCurrentView); ~HndlrListModel(); //HndlrListModel(TagEditorDlgImpl* pTagEditorDlgImpl); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; // /*override*/ Qt::ItemFlags flags(const QModelIndex& index) const; const Renamer* getRenamer() const { return m_pRenamer; } void setRenamer(const Renamer*); void setUnratedAsDuplicates(bool bUnratedAsDuplicate); const std::deque getHandlerList() const; // returns either m_pCommonData->getCrtAlbum() or m_pCommonData->getViewHandlers(), based on m_bUseCurrentView void emitLayoutChanged() { emit layoutChanged(); } }; class CurrentAlbumDelegate : public QItemDelegate { Q_OBJECT const HndlrListModel* m_pHndlrListModel; public: CurrentAlbumDelegate(QWidget* pParent, HndlrListModel* pHndlrListModel); /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; // /*override*/ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; }; struct SequencePattern; class InvalidCharsReplacer; } // namespace FileRenamer class ModifInfoToolButton; class FileRenamerDlgImpl : public QDialog, private Ui::FileRenamerDlg { Q_OBJECT CommonData* m_pCommonData; FileRenamer::HndlrListModel* m_pHndlrListModel; void reloadTable(); void resizeUi(); std::vector m_vstrPatterns; void loadPatterns(); void savePatterns(); void updateButtons(); void createButtons(); void selectPattern(); // selects the appropriate pattern for a new album, based on whether it's VA or SA; sets m_nCrtPattern and checks the right button; assumes m_eState is properly set up; int m_nVaButton, m_nSaButton; int m_nBtnId; int m_nCrtPattern; enum State { SINGLE, SINGLE_ERR, VARIOUS, VARIOUS_ERR, ERR }; // ERR is for when all songs lack ID3V2 State m_eState; bool isSingleArtist() const { return SINGLE == m_eState || SINGLE_ERR == m_eState; } //bool m_bSingleArtist; // if there are a QButtonGroup* m_pButtonGroup; ModifInfoToolButton* m_pModifRenameB; bool m_bUseCurrentView; //std::vector m_pInvalidCharsReplacer; public: Renamer(const std::string& strPattern, const CommonData* pCommonData, bool bUnratedAsDuplicate); ~Renamer(); const std::string& getPattern() const { return m_strPattern; } //const FileRenamer::SequencePattern* getSeq() const { return m_pRoot; } std::string getNewName(const Mp3Handler*) const; bool isSameDir() const { return m_bSameDir; } struct InvalidPattern { const std::string m_strErr; InvalidPattern(const std::string& strPattern, const std::string& strErr) : m_strErr("Pattern \"" + strPattern + "\" is invalid. " + strErr) {} }; mutable bool m_bUnratedAsDuplicate; mutable std::map m_mValues; // only has entries for custom-modified values }; #endif MP3Diags-1.0.12.079/src/LyricsStream.cpp0000644000175000001440000003011111414036150016367 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include "LyricsStream.h" #include "Helpers.h" #include "Widgets.h" using namespace std; namespace { const char* LYR_BEGIN ("LYRICSBEGIN"); const int LYR_BEGIN_SIZE (strlen(LYR_BEGIN)); const char* LYR_END ("LYRICS200"); const int LYR_END_SIZE (strlen(LYR_END)); } LyricsStream::LyricsStream() { m_bHasTitle = m_bHasArtist = m_bHasGenre = m_bHasImage = m_bHasAlbum = false; } LyricsStream::LyricsStream(int nIndex, NoteColl& notes, std::istream& in, const std::string& strFileName) : DataStream(nIndex), m_pos(in.tellg()), m_strFileName(strFileName) { StreamStateRestorer rst (in); m_bHasTitle = m_bHasArtist = m_bHasGenre = m_bHasImage = m_bHasAlbum = false; //const int BFR_SIZE (256); //char bfr [BFR_SIZE]; vector vcBfr (256); streamoff nRead (read(in, &vcBfr[0], LYR_BEGIN_SIZE + LYR_END_SIZE)); MP3_CHECK_T (nRead >= LYR_BEGIN_SIZE + LYR_END_SIZE && 0 == strncmp(LYR_BEGIN, &vcBfr[0], LYR_BEGIN_SIZE), m_pos, "Invalid Lyrics stream tag. Header not found.", NotLyricsStream()); streampos pos (m_pos); int nTotalSize (LYR_BEGIN_SIZE); pos += LYR_BEGIN_SIZE; for (;;) { in.seekg(pos); vcBfr.resize(8 + 1); streamoff nRead (read(in, &vcBfr[0], 8)); MP3_CHECK (8 == nRead, pos, lyrTooShort, NotLyricsStream()); char* pLast; int nSize; if (isdigit(vcBfr[0])) { // the size, folowed by the end vcBfr.resize(6 + LYR_END_SIZE); nRead = read(in, &vcBfr[8], 6 + LYR_END_SIZE - 8); MP3_CHECK (6 + LYR_END_SIZE - 8 == nRead, pos, lyrTooShort, NotLyricsStream()); char c (vcBfr[6]); vcBfr[6] = 0; nSize = int(strtol(&vcBfr[0], &pLast, 10)); vcBfr[6] = c; MP3_CHECK (pLast == &vcBfr[6], pos, invalidLyr, NotLyricsStream()); MP3_CHECK (nTotalSize == nSize, pos, invalidLyr, NotLyricsStream()); MP3_CHECK (0 == strncmp(LYR_END, &vcBfr[6], LYR_END_SIZE), pos, invalidLyr, NotLyricsStream()); pos += 6 + LYR_END_SIZE; break; } MP3_CHECK (isalnum(vcBfr[0]) && isalnum(vcBfr[1]) && isalnum(vcBfr[2]), pos, invalidLyr, NotLyricsStream()); string strField (&vcBfr[0], &vcBfr[0] + 3); vcBfr[8] = 0; nSize = int(strtol(&vcBfr[3], &pLast, 10)); MP3_CHECK (pLast == &vcBfr[8], pos, invalidLyr, NotLyricsStream()); MP3_CHECK (nSize >= 0 && nSize < 15000000, pos, invalidLyr, NotLyricsStream()); vcBfr.resize(nSize); nRead = read(in, &vcBfr[0], nSize); MP3_CHECK (nSize == nRead, pos, lyrTooShort, NotLyricsStream()); vcBfr.push_back(0); string strVal (convStr(QString::fromLatin1(&vcBfr[0]))); //qDebug("field %s, size %d, pos %x, val %s", strField.c_str(), nSize, int(pos), strVal.c_str()); if ("LYR" == strField) { if (m_strLyrics.empty()) { m_strLyrics = strVal; //QQQ = true; } else { MP3_NOTE (m_pos, duplicateFields); //ttt2 perhaps differentiate between various dup fields m_strOther += "Additional LYR field: " + strVal + "\n\n"; } } else if ("INF" == strField) { MP3_NOTE (m_pos, infInLyrics); m_strOther += "INF field: " + strVal + "\n\n"; } else if ("AUT" == strField) { if (m_strAuthor.empty()) { m_strAuthor = strVal; //QQQ = true; } else { MP3_NOTE (m_pos, duplicateFields); m_strOther += "Additional AUT field: " + strVal + "\n\n"; } } else if ("EAL" == strField) { if (m_strAlbum.empty()) { m_strAlbum = strVal; m_bHasAlbum = true; } else { MP3_NOTE (m_pos, duplicateFields); m_strOther += "Additional EAL field: " + strVal + "\n\n"; } } else if ("EAR" == strField) { if (m_strArtist.empty()) { m_strArtist = strVal; m_bHasArtist = true; } else { MP3_NOTE (m_pos, duplicateFields); m_strOther += "Additional EAR field: " + strVal + "\n\n"; } } else if ("ETT" == strField) { if (m_strTitle.empty()) { m_strTitle = strVal; m_bHasTitle = true; } else { MP3_NOTE (m_pos, duplicateFields); m_strOther += "Additional ETT field: " + strVal + "\n\n"; } } else if ("IMG" == strField) { if (m_strImageFiles.empty()) { m_strImageFiles = strVal; m_bHasImage = true; //MP3_NOTE (m_pos, imgInLyrics); } else { MP3_NOTE (m_pos, duplicateFields); m_strOther += "Additional IMG field: " + strVal + "\n\n"; } } else if ("GRE" == strField) { if (m_strGenre.empty()) { m_strGenre = strVal; m_bHasGenre = true; } else { MP3_NOTE (m_pos, duplicateFields); m_strOther += "Additional GRE field: " + strVal + "\n\n"; } } else if ("IND" == strField) { if (m_strInd.empty()) { m_strInd = strVal; } else { MP3_NOTE (m_pos, duplicateFields); m_strOther += "Additional IND field: " + strVal + "\n\n"; } } else { m_strOther += strField + " field: " + strVal + "\n\n"; } nTotalSize += 8 + nSize; pos += 8 + nSize; } in.seekg(pos); m_nSize = pos - m_pos; //m_strOther=string(512, 'a'); m_strOther[391] = 10; // err //m_strOther=string(512, 'a'); m_strOther[303] = 10; // err //m_strOther=string(512, 'a'); m_strOther[302] = 10; // ok //m_strOther=string(511, 'a'); m_strOther[303] = 10; // ok MP3_TRACE (m_pos, "LyricsStream built."); rst.setOk(); } /*override*/ void LyricsStream::copy(std::istream& in, std::ostream& out) { appendFilePart(in, out, m_pos, m_nSize); } /*override*/ std::string LyricsStream::getInfo() const { return ""; } /*override*/ std::string LyricsStream::getTitle(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasTitle; } return m_strTitle; } /*override*/ std::string LyricsStream::getArtist(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasArtist; } return m_strArtist; } /*override*/ std::string LyricsStream::getGenre(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasGenre; } return m_strGenre; } ImageInfo LyricsStream::readImage(const QString& strRelName) const //ttt2 perhaps move to Helpers and use for ID3V2 links as well; keep in mind that in many places link is considered invalid, so they would need updating; { QString qs (QFileInfo(convStr(m_strFileName)).dir().filePath(strRelName)); //qs = convStr(m_strFileName) + getPathSep() + qs; QFile f (qs); bool bRes (false); if (f.open(QIODevice::ReadOnly)) { CursorOverrider crsOv; int nSize ((int)f.size()); QByteArray comprImg (f.read(nSize)); QImage pic; //ttt1 rename QImage variables as "img" if (pic.loadFromData(comprImg)) { bRes = true; ImageInfo::Compr eCompr; int nWidth, nHeight; if (nSize <= ImageInfo::MAX_IMAGE_SIZE) { nWidth = pic.width(); nHeight = pic.height(); eCompr = qs.endsWith(".png", Qt::CaseInsensitive) ? ImageInfo::PNG : (qs.endsWith(".jpg", Qt::CaseInsensitive) || qs.endsWith(".jpeg", Qt::CaseInsensitive) ? ImageInfo::JPG : ImageInfo::INVALID); //ttt2 add more cases if supporting more image types } else { QImage scaledImg; ImageInfo::compress(pic, scaledImg, comprImg); nWidth = scaledImg.width(); nHeight = scaledImg.height(); eCompr = ImageInfo::JPG; } ImageInfo img (-1, ImageInfo::OK, eCompr, comprImg, nWidth, nHeight); return img; } } return ImageInfo(-1, ImageInfo::ERROR_LOADING); } /*override*/ ImageInfo LyricsStream::getImage(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasImage; } if (m_bHasImage) { // http://www.id3.org/Lyrics3v2 // http://www.mpx.cz/mp3manager/tags.htm QString qs (convStr(m_strImageFiles)); { int k (qs.indexOf("\r\n")); if (-1 != k) { qs.remove(k, qs.size()); } } return readImage(qs); } return ImageInfo(); } /*override*/ std::vector LyricsStream::getImages() const { vector v; if (m_strImageFiles.empty()) { return v; } QString qs (convStr(m_strImageFiles) + "\r\n"); for (;;) { int k (qs.indexOf("\r\n")); if (-1 == k) { return v; } v.push_back(readImage(qs.left(k))); qs.remove(0, k + 2); } } /*override*/ std::string LyricsStream::getAlbumName(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasAlbum; } return m_strAlbum; } /*override*/ std::string LyricsStream::getOtherInfo() const { string s; if (!m_strInd.empty()) { s += "IND field: " + m_strInd + "\n\n"; } if (!m_strImageFiles.empty()) { s += "IMG field: " + m_strImageFiles + "\n\n"; } if (!m_strAuthor.empty()) { s += "AUT field: " + m_strAuthor + "\n\n"; } if (!m_strLyrics.empty()) { s += "LYR field: " + m_strLyrics + "\n\n"; } if (!m_strOther.empty()) { s += m_strOther + "\n\n"; } return s; } #if 1 //... /*override*/ TagReader::SuportLevel LyricsStream::getSupport(Feature eFeature) const { switch (eFeature) { case TITLE: case ARTIST: case GENRE: case IMAGE: case ALBUM: return READ_ONLY; default: return NOT_SUPPORTED; } } #endif //ttt2 perhaps remove \r MP3Diags-1.0.12.079/src/MainFormDlgImpl.h0000644000175000001440000001630011257656201016412 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MainFormDlgImplH #define MainFormDlgImplH #include #include #include "ui_MainForm.h" #include "StructuralTransformation.h" #include "CommonData.h" #include "StoredSettings.h" class ModifInfoToolButton; class TagWriter; class QScrollArea; class QStackedLayout; class QHttp; class QHttpResponseHeader; struct FileEnumerator; /** @author ciobi */ class MainFormDlgImpl : public QDialog, private Ui::MainFormDlg { Q_OBJECT public: MainFormDlgImpl(const std::string& strSession, bool bUniqueSession); ~MainFormDlgImpl(); /*override*/ void resizeEvent(QResizeEvent* pEvent); /*override*/ void keyPressEvent(QKeyEvent* pEvent); /*override*/ void keyReleaseEvent(QKeyEvent* pEvent); /*override*/ void closeEvent(QCloseEvent* pEvent); enum CloseOption { EXIT, OPEN_SESS_DLG }; CloseOption run(); public slots: /*$PUBLIC_SLOTS$*/ void on_m_pScanB_clicked(); void on_m_pSessionsB_clicked(); void on_m_pNoteFilterB_clicked(); void on_m_pDirFilterB_clicked(); void on_m_pConfigB_clicked(); void on_m_pModeAllB_clicked(); void on_m_pModeAlbumB_clicked(); void on_m_pModeSongB_clicked(); void on_m_pPrevB_clicked(); void on_m_pNextB_clicked(); void on_m_pTransformB_clicked(); void on_m_pCustomTransform1B_clicked() { applyCustomTransf(0); } void on_m_pCustomTransform2B_clicked() { applyCustomTransf(1); } void on_m_pCustomTransform3B_clicked() { applyCustomTransf(2); } void on_m_pCustomTransform4B_clicked() { applyCustomTransf(3); } void on_m_pNormalizeB_clicked(); void on_m_pReloadB_clicked(); void on_m_pViewFileInfoB_clicked(); void on_m_pViewAllNotesB_clicked(); void on_m_pViewTagDetailsB_clicked(); void on_m_pAboutB_clicked(); void on_m_pTagEdtB_clicked(); void on_m_pRenameFilesB_clicked(); void on_m_pDebugB_clicked(); void on_m_pExportB_clicked(); void emptySlot() {} // needed to disable exiting on ESCAPE void onCrtFileChanged(); void testSlot(); void onShow(); void onShowAssert(); void onHelp(); void onMenuHovered(QAction*); void onNewVersionQueryFinished(int, bool); void onNewVersionQueryFinished2(); // needed because some bug in Qt4.3.1, 4.4.3 and some others, resulting in a segfault if onNewVersionQueryFinished() lasts 14 seconds or more void readResponseHeader(const QHttpResponseHeader&); void onFixCurrentNote(); private: void scan(FileEnumerator& fileEnum, bool bForce, std::deque vpExisting, int nKeepWhenUpdate); // a subset of vpExisting gets copied to vpDel in the m_pCommonData->mergeHandlerChanges() call; so if vpExisting is empty, vpDel will be empty too; if bForce is true, thw whole vpExisting is copied to vpDel; void scan(bool bForce); enum { IGNORE_SEL = 0, USE_SEL = 1 }; //enum { KEEP_FLT = 0, DISABLE_FLT = 1 }; //enum ReloadSrc { SEL, ALL_KEEP_FLT, ALL_REMOVE_FLT }; enum { DONT_FORCE = 0, FORCE = 1 }; //void reload(ReloadSrc eReloadSrc, bool bForce); void reload(bool bSelOnly, bool bForce); void fullReload(bool bForceReload); SessionSettings m_settings; int m_nLastKey; friend void trace(const std::string& s); CommonData* m_pCommonData; QWidget* m_pTagDetailsW; // this gets erased and recreated each time the current file changes QHBoxLayout* m_pTagDetailsLayout; QStackedLayout* m_pLowerHalfLayout; TransfConfig m_transfConfig; void saveIgnored(); void loadIgnored(); void saveCustomTransf(int k); void loadCustomTransf(int k); void saveVisibleTransf(); void loadVisibleTransf(); enum Subset { SELECTED, ALL, CURRENT }; void transform(std::vector& vpTransf, Subset eSubset); std::vector m_vpTransfButtons; void setTransfTooltip(int k); void setTransfTooltips() { for (int i = 0; i < CUSTOM_TRANSF_CNT; ++i) { setTransfTooltip(i); } } void applyCustomTransf(int k); ModifInfoToolButton* m_pModifNormalizeB; ModifInfoToolButton* m_pModifReloadB; ModifInfoToolButton* m_pModifRenameFilesB; std::string m_strSession; void resizeIcons(); void updateUi(const std::string& strCrt); // strCrt may be empty /*override*/ bool eventFilter(QObject* pObj, QEvent* pEvent); void initializeUi(); bool m_bShowMaximized; int m_nScanWidth; void showBackupWarn(); void showSelWarn(); void showRestartAfterCrashMsg(const QString& qstrText, const QString& qstrCloseBtn); void checkForNewVersion(); // returns immediately; when the request completes it will send a signal void fixCurrentNoteOneFile(); void fixCurrentNoteAllFiles(int nCol); std::vector getFixes(const Note* pNote, const Mp3Handler* pHndl) const; // what might fix a note void showFixes(std::vector& vpTransf, Subset eSubset); QHttp* m_pQHttp; QString m_qstrNewVer; // needed by onNewVersionQueryFinished2() int m_nGlobalX, m_nGlobalY; // needed so fixCurrentNote() can be called on a timer, rather than directly (which seems to guarantee that tooltips are shown for menus in Linux; with a direct call it's sort of random; well, right-clicking on a non-current cell rather than left click followed by right click incresases the odds of the tooltips not being shown) signals: void tagEditorClosed(); }; class AssertSender : public QObject { Q_OBJECT //MainFormDlgImpl* m_pDlg; public: AssertSender(MainFormDlgImpl* pDlg) { connect(this, SIGNAL(showAssertMsg()), pDlg, SLOT(onShowAssert())); emit showAssertMsg(); } //void emitAssrt() { emit assrt(); } signals: void showAssertMsg(); }; #endif // #ifndef MainFormDlgImplH MP3Diags-1.0.12.079/src/DirFilter.ui0000644000175000001440000000316311227440147015503 0ustar ciobiusers DirFilterDlg 0 0 725 415 Folder filter true 6 0 0 0 0 Qt::Horizontal 131 10 OK Cancel MP3Diags-1.0.12.079/src/SessionsDlgImpl.h0000644000175000001440000000710411252461427016511 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef SessionsDlgImplH #define SessionsDlgImplH #include #include #include "ui_Sessions.h" class QSettings; ////#include class CheckedDirModel; class SessionsModel : public QAbstractTableModel { Q_OBJECT //TagEditorDlgImpl* m_pTagEditorDlgImpl; //TagWriter* m_pTagWriter; //const CommonData* m_pCommonData; std::vector& m_vstrSessions; public: SessionsModel(std::vector& vstrSessions); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const { return 1; } /*override*/ QVariant data(const QModelIndex&, int nRole = Qt::DisplayRole) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; void emitLayoutChanged() { emit layoutChanged(); } }; class SessionsDlgImpl : public QDialog, private Ui::SessionsDlg { Q_OBJECT std::vector m_vstrSessions; //QSettings& m_settings; SessionsModel m_sessionsModel; //QSettings* m_pSettings; CheckedDirModel* m_pCheckedDirModel; std::string getCrtSession() const; // returns empty str if there's no session std::string getCrtSessionDir() const; //bool m_bOpenLast; void removeCrtSession(); void selectSession(const std::string& strLast); void addSession(const std::string&); public: SessionsDlgImpl(QWidget* pParent /*, QSettings& settings*/); ~SessionsDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ std::string run(); public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void onCrtSessChanged(); void on_m_pNewB_clicked(); void on_m_pEditB_clicked(); void on_m_pEraseB_clicked(); void on_m_pSaveAsB_clicked(); void on_m_pHideB_clicked(); void on_m_pLoadB_clicked(); void on_m_pOpenB_clicked(); void on_m_pCancelB_clicked(); //void on_ _clicked(); void onShow(); void onSessDoubleClicked(const QModelIndex& index); void onHelp(); }; #endif MP3Diags-1.0.12.079/src/Notes.h0000644000175000001440000010501111335446574014526 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef NotesH #define NotesH #include #include #include #include #include #include "SerSupport.h" #include /* Stores a message that is added while parsing a file. Multiple messages may be added, depending on the issues found. Notes are added to an Mp3Handler: 1) while creating (or attempting to create) new streams 2) after the streams were created, addressing the relations between streams (this may include non-existing streams that should have been present). Calling MP3_CHECK(), MP3_THROW() or MP3_NOTE() adds a note to an Mp3Handler. Notes have a "Severity": ERR: Something was seriously wrong and it should be reported to the user. WARNING: There may be some issues, in some cases. SUPPORT: A stream tries to use a feature that is not currently supported. The program needs an update. TRACE: Meant for debugging only. Most operations generate TRACE notes, so that it should be easy to follow the steps that led to an unexpected situation while processing a given file. A note may be attached to a stream. This happens implicitly, by using the "pos" value: if this is -1, the note is non-attached; otherwise it is attached to the stream that contains that address. As a result, it is possible for ERR and SUPPORT notes to be attached to apparently unrelated streams (usually they would be "Unknown" streams). This happens because they belong to streams that can't be constructed, because they are either broken or not currently supported. When the construction fails, "Unknown" streams are most likely to be constructed instead, and the note gets attached to them. Note that not all exceptions thrown on streams' constructors with MP3_CHECK() or MP3_THROW are ERR. Indeed, most are TRACE. This is because the algorithm for identifying the streams simply tries to construct all known streams (for a given position). If the actual stream doesn't match the constructor, a TRACE exception is thrown and the constructor for the next stream type is called. On the other hand, if the stream can be identified as matching by the constructor but has errors preventing the constructor to complete successfully, ERR is the severity that should be used by the note. (And similarly for not supported features, but depending on the particular case, it may be decided to continue loading with that support missing and partial functionality.) SUPPORT notes end up in the UI, so care should be taken to avoid false positives (e.g. if "MPEG 2.5 not supported" is thrown as SUPPORT, we should check that an MPEG 2.5 stream is present, not just a few bits at the beginning"; anyway, for this reason, "MPEG 2.5 not supported" is thrown as TRACE). Since SUPPORT notes are usually attached to "Unknown" streams, the original stream (which couldn't be constructed because of the unsupported feature) should be identifiable from the error message. The same is true for ERR exceptions thrown on the constructors, but it isn't necessary for the other notes (at least for those that are linked to streams). Reformulated: there are 2 situations for exceptions in constructors: 1) obviously not the stream that was expected, no need to report it; use TRACE; 2) the beginning was OK, several checks went OK, but then something went wrong; should be reported, and the type of the stream should be specified in the message; use ERR or SUPPORT; "Detail" is better avoided, because it takes space. It is supposed to provide context-dependent detail for "description", but most of the time the only detail that matters is the position, which is already available. The code that uses Note should call getDetail() first, and if that returns an empty string use getDescription() to present the user with all the information available. */ struct Note { enum Severity { ERR, WARNING, SUPPORT, TRACE }; // !!! the reason "ERR" is used (and not "ERROR") is that "ERROR" is a macro in MSVC enum Category { AUDIO, XING, VBRI, ID3V2, APIC, ID3V230, ID3V240, ID3V1, BROKEN, TRUNCATED, UNKNOWN, LYRICS, APE, MISC, CUSTOM, CATEG_CNT }; // !!! CUSTOM must be just before CATEG_CNT (which is just a counter) struct SharedData // the purpose of this is to make the Note class as small as possible, by storing shared info only once { Severity m_eSeverity; Category m_eCategory; int m_nLabelIndex; // position in a given category int m_nNoteId; // position in the global vector for non-trace notes; -1 for trace bool m_bAllowErase; // needed for the option to remove offending streams; std::string m_strDescription; SharedData(const std::string& strDescription, bool bAllowErase) : m_eSeverity(TRACE), m_eCategory(CUSTOM), m_nLabelIndex(-1), m_nNoteId(-1), m_bAllowErase(bAllowErase), m_strDescription(strDescription) {} private: friend struct Notes; SharedData(Severity eSeverity, Category eCategory, const std::string& strDescription, bool bAllowErase) : m_eSeverity(eSeverity), m_eCategory(eCategory), m_nLabelIndex(-1), m_nNoteId(-1), m_bAllowErase(bAllowErase), m_strDescription(strDescription) {} private: friend class boost::serialization::access; SharedData() {} template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & m_strDescription; // !!! don't care about other attributes, because after loading, a SharedData object is replaced with one from Notes::getNote(strDescr) } }; Note(const Note&, std::streampos pos, const std::string& strDetail = ""); Note(SharedData& sharedData, std::streampos pos, const std::string& strDetail = ""); // Severity is forced to TRACE ~Note(); private: friend struct Notes; Note(SharedData& sharedData); SharedData* m_pSharedData; // !!! can't be const because Notes needs to set indexes when adding notes to vectors, and also because of serialization public: //id // to sort columns const char* getDescription() const { return m_pSharedData->m_strDescription.c_str(); } std::string getDetail() const { return m_strDetail; } std::streampos getPos() const { return m_pos; } std::string getPosHex() const; // returns an empty string for an invalid position (i.e. one initialized from -1) Severity getSeverity() const { return m_pSharedData->m_eSeverity; } Category getCategory() const { return m_pSharedData->m_eCategory; } int getLabelIndex() const { return m_pSharedData->m_nLabelIndex; } // index in a given category; used for displaying a label int getNoteId() const { return m_pSharedData->m_nNoteId; } // index across categories; used for sorting bool allowErase() const { return m_pSharedData->m_bAllowErase; } //bool operator<(const Note&) const; // error before warning, ... ; alpha by descr ; alpha by detail bool operator==(const Note& other) const; protected: std::streampos m_pos; std::string m_strDetail; //mutable char m_szPosBfr [20]; private: friend class boost::serialization::access; Note(); /*template void serialize(Archive& ar, const unsigned int / *nVersion* /) { }*/ template void save(Archive& ar, const unsigned int nVersion) const; template void load(Archive& ar, const unsigned int nVersion); BOOST_SERIALIZATION_SPLIT_MEMBER(); }; /* The order of DECL_NOTE_INFO() in struct Notes is irrelevant. What matters is what happens in initVec(). The current approach is to group together related notes, regardless of their severity. So audio-related notes come first, then Xing, then ID3V2 ... The labels are used for convenience. They may change between releases, and are not used internally for anything (e.g. "ignored" notes are stored as full-text in the config file, so they remain ignored as long as their text doesn't change, even if their label changes.) For a given color / severity the labels should be ordered alphabetically, though (well, as long as there are enough letters; then it depends on what m_nLabelIndex gets mapped to) */ #define DECL_NOTE_INFO(NAME, SEV, CATEG, MSG, ALLOW_ERASE) static Note& NAME() { static Note::SharedData d (Note::SEV, Note::CATEG, MSG, ALLOW_ERASE); static Note n (d); return n; } struct Notes { static const Note* getNote(const std::string& strDescr); // returns 0 if not found static const Note* getNote(int n); // returns 0 if n is out of range static const Note* getMaster(const Note* p); // asserts there is a master static const Note* getMissingNote(); // to be used by serialization: if a description is no longer found, the note gets replace with a default, "missing", one static void addToDestroyList(Note::SharedData* p) { s_spDestroyList.insert(p); } // while loading from disk, Notes replace the SharedData objects from the disk with instances from getNote(strDescr); after the loading is done, the list (actually a set) must be cleared; static void clearDestroyList(); // destoys the pointers added by addToDestroyList(); to be called after loading is complete; // a list with all known notes static const std::vector& getAllNotes(); static const std::vector& getDefaultIgnoredNoteIds(); // audio // a DECL_NOTE_INFO(twoAudio, ERR, AUDIO, "Two MPEG audio streams found, but a file should have exactly one.", false); // a DECL_NOTE_INFO(lowQualAudio, WARNING, AUDIO, "Low quality MPEG audio stream. (What is considered \"low quality\" can be changed in the configuration dialog, under \"Quality thresholds\".)", false); // b DECL_NOTE_INFO(noAudio, ERR, AUDIO, "No MPEG audio stream found.", false); // c DECL_NOTE_INFO(vbrUsedForNonMpg1L3, WARNING, AUDIO, "VBR with audio streams other than MPEG1 Layer III might work incorrectly.", false); // d DECL_NOTE_INFO(incompleteFrameInAudio, ERR, AUDIO, "Incomplete MPEG frame at the end of an MPEG stream.", false); // e DECL_NOTE_INFO(validFrameDiffVer, ERR, AUDIO, "Valid frame with a different version found after an MPEG stream.", false); // f DECL_NOTE_INFO(validFrameDiffLayer, ERR, AUDIO, "Valid frame with a different layer found after an MPEG stream.", false); // g DECL_NOTE_INFO(validFrameDiffMode, ERR, AUDIO, "Valid frame with a different channel mode found after an MPEG stream.", false); // h DECL_NOTE_INFO(validFrameDiffFreq, ERR, AUDIO, "Valid frame with a different frequency found after an MPEG stream.", false); // i DECL_NOTE_INFO(validFrameDiffCrc, ERR, AUDIO, "Valid frame with a different CRC policy found after an MPEG stream.", false); // j DECL_NOTE_INFO(audioTooShort, ERR, AUDIO, "Invalid MPEG stream. Stream has fewer than 10 frames.", false); // k DECL_NOTE_INFO(diffBitrateInFirstFrame, ERR, AUDIO, "Invalid MPEG stream. First frame has different bitrate than the rest.", false); // l DECL_NOTE_INFO(noMp3Gain, WARNING, AUDIO, "No normalization undo information found. The song is probably not normalized by MP3Gain or a similar program. As a result, it may sound too loud or too quiet when compared to songs from other albums.", false); // n DECL_NOTE_INFO(untestedEncoding, SUPPORT, AUDIO, "Found audio stream in an encoding other than \"MPEG-1 Layer 3\" or \"MPEG-2 Layer 3.\" While MP3 Diags understands such streams, very few tests were run on files containing them (because they are not supposed to be found inside files with the \".mp3\" extension), so there is a bigger chance of something going wrong while processing them.", false); // o // xing // b DECL_NOTE_INFO(twoLame, ERR, XING, "Two Lame headers found, but a file should have at most one of them.", true); // a DECL_NOTE_INFO(xingAddedByMp3Fixer, WARNING, XING, "Xing header seems added by Mp3Fixer, which makes the first frame unusable and causes a 16-byte unknown or null stream to be detected next.", false); // b DECL_NOTE_INFO(xingFrameCountMismatch, ERR, XING, "Frame count mismatch between the Xing header and the audio stream.", false); // c DECL_NOTE_INFO(twoXing, ERR, XING, "Two Xing headers found, but a file should have at most one of them.", false); // d DECL_NOTE_INFO(xingNotBeforeAudio, ERR, XING, "The Xing header should be located immediately before the MPEG audio stream.", false); // e DECL_NOTE_INFO(incompatXing, ERR, XING, "The Xing header should be compatible with the MPEG audio stream, meaning that their MPEG version, layer and frequency must be equal.", false); // f DECL_NOTE_INFO(missingXing, WARNING, XING, "The MPEG audio stream uses VBR but a Xing header wasn't found. This will confuse some players, which won't be able to display the song duration or to seek.", false); // g // vbri // c DECL_NOTE_INFO(twoVbri, ERR, VBRI, "Two VBRI headers found, but a file should have at most one of them.", true); // a DECL_NOTE_INFO(vbriFound, WARNING, VBRI, "VBRI headers aren't well supported by some players. They should be replaced by Xing headers.", true); // b DECL_NOTE_INFO(foundVbriAndXing, WARNING, VBRI, "VBRI header found alongside Xing header. The VBRI header should probably be removed.", true); // c // id3 v2 // d DECL_NOTE_INFO(id3v2FrameTooShort, ERR, ID3V2, "Invalid ID3V2 frame. File too short.", false); // a DECL_NOTE_INFO(id3v2InvalidName, ERR, ID3V2, "Invalid frame name in ID3V2 tag.", true); // b DECL_NOTE_INFO(id3v2IncorrectFlg1, WARNING, ID3V2, "Flags in the first flag group that are supposed to always be 0 are set to 1. They will be ignored.", true); // c DECL_NOTE_INFO(id3v2IncorrectFlg2, WARNING, ID3V2, "Flags in the second flag group that are supposed to always be 0 are set to 1. They will be ignored.", true); // d DECL_NOTE_INFO(id3v2TextError, ERR, ID3V2, "Error decoding the value of a text frame while reading an Id3V2 Stream.", true); // e DECL_NOTE_INFO(id3v2HasLatin1NonAscii, WARNING, ID3V2, "ID3V2 tag has text frames using Latin-1 encoding that contain characters with a code above 127. While this is valid, those frames may have their content set or displayed incorrectly by software that uses the local code page instead of Latin-1. Conversion to Unicode (UTF16) is recommended.", true); // f DECL_NOTE_INFO(id3v2EmptyTcon, WARNING, ID3V2, "Empty genre frame (TCON) found.", true); // g DECL_NOTE_INFO(id3v2MultipleFramesWithSameName, WARNING, ID3V2, "Multiple frame instances found, but only the first one will be used.", true); // h DECL_NOTE_INFO(id3v2PaddingTooLarge, WARNING, ID3V2, "The padding in the ID3V2 tag is too large, wasting space. (Large padding improves the tag editor saving speed, if fast saving is enabled, so you may want to delay compacting the tag until after you're done with the tag editor.)", false); // i DECL_NOTE_INFO(id3v2UnsuppVer, SUPPORT, ID3V2, "Unsupported ID3V2 version.", true); // j DECL_NOTE_INFO(id3v2UnsuppFlag, SUPPORT, ID3V2, "Unsupported ID3V2 tag. Unsupported flag.", true); // k DECL_NOTE_INFO(id3v2UnsuppFlags1, SUPPORT, ID3V2, "Unsupported value for Flags1 in ID3V2 frame. (This may also indicate that the file contains garbage where it was supposed to be zero.)", true); // l DECL_NOTE_INFO(id3v2UnsuppFlags2, SUPPORT, ID3V2, "Unsupported value for Flags2 in ID3V2 frame. (This may also indicate that the file contains garbage where it was supposed to be zero.)", true); // n DECL_NOTE_INFO(id3v2DuplicatePopm, SUPPORT, ID3V2, "Multiple instances of the POPM frame found in ID3V2 tag. The current version discards all the instances except the first when processing this tag.", true); // o DECL_NOTE_INFO(id3v2EmptyTag, WARNING, ID3V2, "ID3V2 tag contains no frames, which is invalid. This note will disappear once you add track information in the tag editor.", true); //p DECL_NOTE_INFO(id3v2EmptyTextFrame, WARNING, ID3V2, "ID3V2 tag contains an empty text frame, which is invalid.", true); //q // apic // e DECL_NOTE_INFO(id3v2NoApic, WARNING, APIC, "ID3V2 tag doesn't have an APIC frame (which is used to store images).", true); // a DECL_NOTE_INFO(id3v2CouldntLoadPic, WARNING, APIC, "ID3V2 tag has an APIC frame (which is used to store images), but the image couldn't be loaded.", true); // b DECL_NOTE_INFO(id3v2NotCoverPicture, WARNING, APIC, "ID3V2 tag has at least one valid APIC frame (which is used to store images), but no frame has a type that is associated with an album cover.", true); // c DECL_NOTE_INFO(id3v2ErrorLoadingApic, WARNING, APIC, "Error loading image in APIC frame.", true); // d DECL_NOTE_INFO(id3v2ErrorLoadingApicTooShort, WARNING, APIC, "Error loading image in APIC frame. The frame is too short anyway to have space for an image.", true); // e DECL_NOTE_INFO(id3v2DuplicatePic, ERR, APIC, "ID3V2 tag has multiple APIC frames with the same picture type.", true); // f DECL_NOTE_INFO(id3v2MultipleApic, WARNING, APIC, "ID3V2 tag has multiple APIC frames. While this is valid, players usually use only one of them to display an image, discarding the others.", true); // g //DECL_NOTE_INFO(id3v2LinkNotSupported, SUPPORT, APIC, "ID3V2 tag has an APIC frame (which is used to store images), but it uses a link to an external file, which is not supported.", false); DECL_NOTE_INFO(id3v2UnsupApicTextEnc, SUPPORT, APIC, "Unsupported text encoding for APIC frame in ID3V2 tag.", true); // h DECL_NOTE_INFO(id3v2LinkInApic, SUPPORT, APIC, "APIC frame uses a link to a file as a MIME Type, which is not supported.", true); // i DECL_NOTE_INFO(id3v2PictDescrIgnored, SUPPORT, APIC, "Picture description is ignored in the current version.", true); // j // id3 v2.3.0 // f DECL_NOTE_INFO(noId3V230, WARNING, ID3V230, "No ID3V2.3.0 tag found, although this is the most popular tag for storing song information.", false); // a DECL_NOTE_INFO(twoId3V230, ERR, ID3V230, "Two ID3V2.3.0 tags found, but a file should have at most one of them.", true); // b DECL_NOTE_INFO(bothId3V230_V240, WARNING, ID3V230, "Both ID3V2.3.0 and ID3V2.4.0 tags found, but there should be only one of them.", true); // c DECL_NOTE_INFO(id3v230AfterAudio, ERR, ID3V230, "The ID3V2.3.0 tag should be the first tag in a file.", true); // d DECL_NOTE_INFO(id3v230UsesUtf8, WARNING, ID3V230, "ID3V2.3.0 tag contains a text frame encoded as UTF-8, which is valid in ID3V2.4.0 but not in ID3V2.3.0.", true); // e DECL_NOTE_INFO(id3v230UnsuppText, SUPPORT, ID3V230, "Unsupported value of text frame while reading an Id3V2 Stream.", true); // f DECL_NOTE_INFO(id3v230CantReadFrame, ERR, ID3V230, "Invalid ID3V2.3.0 frame. Incorrect frame size or file too short.", true); // g // id3 v2.4.0 // g DECL_NOTE_INFO(twoId3V240, ERR, ID3V240, "Two ID3V2.4.0 tags found, but a file should have at most one of them.", true); // a DECL_NOTE_INFO(id3v240CantReadFrame, ERR, ID3V240, "Invalid ID3V2.4.0 frame. Incorrect frame size or file too short.", true); // b DECL_NOTE_INFO(id3v240IncorrectSynch, WARNING, ID3V240, "Invalid ID3V2.4.0 frame. Frame size is supposed to be stored as a synchsafe integer, which uses only 7 bits in a byte, but the size uses all 8 bits, as in ID3V2.3.0. This will confuse some applications", true); // c DECL_NOTE_INFO(id3v240DeprTyerAndTdrc, WARNING, ID3V240, "Deprecated TYER frame found in 2.4.0 tag alongside a TDRC frame.", true); // d DECL_NOTE_INFO(id3v240DeprTyer, WARNING, ID3V240, "Deprecated TYER frame found in 2.4.0 tag. It's supposed to be replaced by a TDRC frame.", true); // e DECL_NOTE_INFO(id3v240DeprTdatAndTdrc, WARNING, ID3V240, "Deprecated TDAT frame found in 2.4.0 tag alongside a TDRC frame.", true); // f DECL_NOTE_INFO(id3v240DeprTdat, WARNING, ID3V240, "Deprecated TDAT frame found in 2.4.0 tag. It's supposed to be replaced by a TDRC frame.", true); // g DECL_NOTE_INFO(id3v240IncorrectDli, WARNING, ID3V240, "Invalid ID3V2.4.0 frame. Mismatched Data length indicator. Frame value is probably incorrect", true); // h DECL_NOTE_INFO(id3v240IncorrectFrameSynch, WARNING, ID3V240, "Invalid ID3V2.4.0 frame. Incorrect unsynchronization bit.", true); // i DECL_NOTE_INFO(id3v240UnsuppText, SUPPORT, ID3V240, "Unsupported value of text frame while reading an Id3V2.4.0 stream. It may be using an unsupported text encoding.", true); // j // id3 v1 // h DECL_NOTE_INFO(onlyId3V1, WARNING, ID3V1, "The only supported tag found that is capable of storing song information is ID3V1, which has pretty limited capabilities.", false); // a DECL_NOTE_INFO(id3v1BeforeAudio, ERR, ID3V1, "The ID3V1 tag should be located after the MPEG audio stream.", true); // b DECL_NOTE_INFO(id3v1TooShort, ERR, ID3V1, "Invalid ID3V1 tag. File too short.", false); // c DECL_NOTE_INFO(twoId3V1, ERR, ID3V1, "Two ID3V1 tags found, but a file should have at most one of them.", true); // d //DECL_NOTE_INFO(zeroInId3V1, WARNING, ID3V1, "ID3V1 tag contains characters with the code 0, although this is not allowed by the standard (yet used by some tools).", false); DECL_NOTE_INFO(mixedPaddingInId3V1, WARNING, ID3V1, "ID3V1 tag contains fields padded with spaces alongside fields padded with zeroes. The standard only allows zeroes, but some tools use spaces. Even so, zero-padding and space-padding shouldn't be mixed.", true); // e DECL_NOTE_INFO(mixedFieldPaddingInId3V1, WARNING, ID3V1, "ID3V1 tag contains fields that are padded with spaces mixed with zeroes. The standard only allows zeroes, but some tools use spaces. Even so, one character should be used for padding for the whole tag.", true); // f DECL_NOTE_INFO(id3v1InvalidName, ERR, ID3V1, "Invalid ID3V1 tag. Invalid characters in Name field.", true); // g DECL_NOTE_INFO(id3v1InvalidArtist, ERR, ID3V1, "Invalid ID3V1 tag. Invalid characters in Artist field.", true); // h DECL_NOTE_INFO(id3v1InvalidAlbum, ERR, ID3V1, "Invalid ID3V1 tag. Invalid characters in Album field.", true); // i DECL_NOTE_INFO(id3v1InvalidYear, ERR, ID3V1, "Invalid ID3V1 tag. Invalid characters in Year field.", true); // j DECL_NOTE_INFO(id3v1InvalidComment, ERR, ID3V1, "Invalid ID3V1 tag. Invalid characters in Comment field.", true); // k // broken // i DECL_NOTE_INFO(brokenAtTheEnd, ERR, BROKEN, "Broken stream found.", true); // a DECL_NOTE_INFO(brokenInTheMiddle, ERR, BROKEN, "Broken stream found. Since other streams follow, it is possible that players and tools will have problems using the file. Removing the stream is recommended.", true); // b // trunc // j DECL_NOTE_INFO(truncAudioWithWholeFile, ERR, TRUNCATED, "Truncated MPEG stream found. The cause for this seems to be that the file was truncated.", false); // a DECL_NOTE_INFO(truncAudio, ERR, TRUNCATED, "Truncated MPEG stream found. Since other streams follow, it is possible that players and tools will have problems using the file. Removing the stream or padding it with 0 to reach its declared size is strongly recommended.", false); // b // unknown // k DECL_NOTE_INFO(unknTooShort, WARNING, UNKNOWN, "Not enough remaining bytes to create an UnknownDataStream.", false); // a DECL_NOTE_INFO(unknownAtTheEnd, ERR, UNKNOWN, "Unknown stream found.", true); // b DECL_NOTE_INFO(unknownInTheMiddle, ERR, UNKNOWN, "Unknown stream found. Since other streams follow, it is possible that players and tools will have problems using the file. Removing the stream is recommended.", true); // c DECL_NOTE_INFO(foundNull, WARNING, UNKNOWN, "File contains null streams.", true); // d // lyrics // l DECL_NOTE_INFO(lyrTooShort, ERR, LYRICS, "Invalid Lyrics stream tag. File too short.", false); // a DECL_NOTE_INFO(twoLyr, SUPPORT, LYRICS, "Two Lyrics tags found, but only one is supported.", true); // b // ttt2 see if this is error //DECL_NOTE_INFO(lyricsNotSupported, SUPPORT, LYRICS, "Lyrics tags cannot be processed in the current version. Some players don't understand them.", false); DECL_NOTE_INFO(invalidLyr, ERR, LYRICS, "Invalid Lyrics stream tag. Unexpected characters found.", false); // c DECL_NOTE_INFO(duplicateFields, SUPPORT, LYRICS, "Multiple fields with the same name were found in a Lyrics tag, but only one is supported.", true); // d //DECL_NOTE_INFO(imgInLyrics, SUPPORT, LYRICS, "Currently images referenced from Lyrics tags are ignored.", true); // (e) DECL_NOTE_INFO(infInLyrics, SUPPORT, LYRICS, "Currently INF fields in Lyrics tags are not fully supported.", true); // e // ape // n DECL_NOTE_INFO(apeItemTooShort, ERR, APE, "Invalid Ape Item. File too short.", false); // a DECL_NOTE_INFO(apeItemTooBig, ERR, APE, "Ape Item seems too big. Although the size may be any 32-bit integer, 256 bytes should be enough in practice. If this note is determined to be incorrect, it will be removed in the future.", false); // b DECL_NOTE_INFO(apeMissingTerminator, ERR, APE, "Invalid Ape Item. Terminator not found for item name.", false); // c DECL_NOTE_INFO(apeFoundFooter, ERR, APE, "Invalid Ape tag. Header expected but footer found.", false); // d DECL_NOTE_INFO(apeTooShort, ERR, APE, "Not an Ape tag. File too short.", false); // e DECL_NOTE_INFO(apeFoundHeader, ERR, APE, "Invalid Ape tag. Footer expected but header found.", false); // f DECL_NOTE_INFO(apeHdrFtMismatch, ERR, APE, "Invalid Ape tag. Mismatch between header and footer.", false); // g DECL_NOTE_INFO(twoApe, SUPPORT, APE, "Two Ape tags found, but only one is supported.", true); // h // ttt2 see if this is error DECL_NOTE_INFO(apeFlagsNotSupported, SUPPORT, APE, "Ape item flags not supported.", false); // i DECL_NOTE_INFO(apeUnsupported, SUPPORT, APE, "Unsupported Ape tag. Currently a missing header or footer are not supported.", false); // j // misc // o DECL_NOTE_INFO(fileWasChanged, WARNING, MISC, "The file seems to have been changed in the (short) time that passed between parsing it and the initial search for pictures. If you think that's not the case, report a bug.", false); // a DECL_NOTE_INFO(noInfoTag, WARNING, MISC, "No supported tag found that is capable of storing song information.", false); // b DECL_NOTE_INFO(tooManyTraceNotes, WARNING, MISC, "Too many TRACE notes added. The rest will be discarded.", false); // c DECL_NOTE_INFO(tooManyNotes, WARNING, MISC, "Too many notes added. The rest will be discarded.", false); // d DECL_NOTE_INFO(tooManyStreams, WARNING, MISC, "Too many streams found. Aborting processing.", false); // e DECL_NOTE_INFO(unsupportedFound, WARNING, MISC, "Unsupported stream found. It may be supported in the future if there's a real need for it.", false); // f DECL_NOTE_INFO(rescanningNeeded, WARNING, MISC, "The file was saved using the \"fast\" option. While this improves the saving speed, it may leave the notes in an inconsistent state, so you should rescan the file.", false); // g struct CompNoteByName // needed for searching { bool operator()(const Note* p1, const Note* p2) const; }; typedef std::set NoteSet; private: //static std::vector s_vpErrNotes; // pointers are to static variables defined in DECL_NOTE_INFO //static std::vector s_vpWarnNotes; // pointers are to static variables defined in DECL_NOTE_INFO //static std::vector s_vpSuppNotes; // pointers are to static variables defined in DECL_NOTE_INFO static std::vector > s_vpNotesByCateg; static std::vector s_vpAllNotes; // pointers are to static variables defined in DECL_NOTE_INFO static NoteSet s_spAllNotes; // pointers are to static variables defined in DECL_NOTE_INFO static void addNote(Note* p); static void initVec(); static std::set s_spDestroyList; // !!! sorted by pointers }; //============================================================================================================ template inline void Note::save(Archive& ar, const unsigned int nVersion) const { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar << m_pSharedData; ar << m_pos; ar << m_strDetail; } template inline void Note::load(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } SharedData* pSharedData; ar >> pSharedData; ar >> m_pos; ar >> m_strDetail; Notes::addToDestroyList(pSharedData); const Note* pNote (Notes::getNote(pSharedData->m_strDescription)); m_pSharedData = 0 == pNote ? Notes::getMissingNote()->m_pSharedData : pNote->m_pSharedData; } //============================================================================================================ //============================================================================================================ //============================================================================================================ // notes associated with a Mp3Handler (but is used stand-alone too, to pass as a param to some functions and then discard the results) class NoteColl { std::vector m_vpNotes; // owns the pointers int m_nCount; int m_nTraceCount; int m_nMaxTrace; public: NoteColl(int nMaxTrace) : m_nCount(0), m_nTraceCount(0), m_nMaxTrace(nMaxTrace) {} NoteColl() {} // serialization-only constructor ~NoteColl(); void add(Note*); const std::vector& getList() const { return m_vpNotes; } void resetCounter() { m_nCount = 0; } // normally only 200 notes are added and anything following is discarded; this allows to reset the counter void sort(); // sorts by CmpNotePtrById, which is needed for filtering void removeTraceNotes(); bool hasFastSaveWarn() const; void addFastSaveWarn(); void removeNotes(const std::streampos& posFrom, const std::streampos& posTo); // removes notes with addresses in the given range; posFrom is included, but posTo isn't private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & m_vpNotes; // these don't really matter, but they don't take a lot of space and can be useful at debugging ar & m_nCount; ar & m_nTraceCount; ar & m_nMaxTrace; } }; /*struct CmpNotePtrBySevAndLabel { bool operator()(const Note* p1, const Note* p2) const { if (p1->getSeverity() < p2->getSeverity()) { return true; } if (p1->getSeverity() > p2->getSeverity()) { return false; } if (p1->getNoteId() < p2->getNoteId()) { return true; } return false; } static bool equals(const Note* p1, const Note* p2) { if (p1->getSeverity() != p2->getSeverity() || p1->getNoteId() != p2->getNoteId()) { return false; } return true; } };*/ struct CmpNotePtrById // needed for unique notes, where equality doesn't include the position { bool operator()(const Note* p1, const Note* p2) const { if (p1->getNoteId() < p2->getNoteId()) { return true; } return false; } static bool equals(const Note* p1, const Note* p2) { if (p1->getNoteId() != p2->getNoteId()) { return false; } return true; } }; /* struct CmpNotePtrBySevLabelAndPos { bool operator()(const Note* p1, const Note* p2) const { if (p1->getSeverity() < p2->getSeverity()) { return true; } if (p1->getSeverity() > p2->getSeverity()) { return false; } if (p1->getNoteId() < p2->getNoteId()) { return true; } if (p1->getNoteId() > p2->getNoteId()) { return false; } if (p1->getPos() < p2->getPos()) { return true; } return false; } };*/ /*struct CmpNotePtrByPosSevAndLabel { bool operator()(const Note* p1, const Note* p2) const { if (p1->getPos() < p2->getPos()) { return true; } if (p1->getPos() > p2->getPos()) { return false; } if (p1->getSeverity() < p2->getSeverity()) { return true; } if (p1->getSeverity() > p2->getSeverity()) { return false; } if (p1->getNoteId() < p2->getNoteId()) { return true; } return false; } };*/ /* struct CmpNotePtrByIdAndPos { bool operator()(const Note* p1, const Note* p2) const { if (p1->getNoteId() < p2->getNoteId()) { return true; } if (p1->getNoteId() > p2->getNoteId()) { return false; } if (p1->getPos() < p2->getPos()) { return true; } return false; } };*/ struct CmpNotePtrByPosAndId { bool operator()(const Note* p1, const Note* p2) const { if (p1->getPos() < p2->getPos()) { return true; } if (p1->getPos() > p2->getPos()) { return false; } if (p1->getNoteId() < p2->getNoteId()) { return true; } return false; } }; // allows strings to be shared (as pointers) struct StringWrp { std::string s; StringWrp(const std::string& s) : s(s) {} private: friend class boost::serialization::access; StringWrp() {} template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & s; } }; //BOOST_CLASS_TRACKING(StringWrp, boost::serialization::track_always); //BOOST_CLASS_TRACKING(StringWrp, boost::serialization::track_never); #endif // #ifndef NotesH MP3Diags-1.0.12.079/src/Widgets.h0000644000175000001440000001260611260645742015046 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef WidgetsH #define WidgetsH #include #include #include #include //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== // A menu that makes available the "modifier" keys that were pressed when an item was selected. Currently only used to determine if SHIFT was pressed. // // To achieve the same result without using the keyboard, selecting with the right button will also tag SHIFT as pressed. // // (an alternative approch that would usually work is to query the keyboard status immediately after something is selected; however, this approach may lead to incorrect results if significant time passes between selection and query; besides, Qt doesn't seem to offer any means to query the keyboard and posts on the net suggest to use X or Windows-specific means (XQueryKeymap or GetAsyncKeyState), which is neither portable nor particularly obvious class ModifInfoMenu : public QMenu { Q_OBJECT /*override*/ void mousePressEvent(QMouseEvent* pEvent); Qt::KeyboardModifiers m_modif; public: ModifInfoMenu(QWidget* pParent = 0) : QMenu(pParent) {} Qt::KeyboardModifiers getModifiers() const { return m_modif; } }; // A ToolButton that makes available the "modifier" keys that were pressed when it was clicked. Currently only used to determine if SHIFT or CTRL were pressed. // // To achieve the same result without using the keyboard, the following sequence will also tag SHIFT as pressed: left button down > right button down > left button up (it doesn't matter when the right button is released). // // On the constructor it replaces an existing QToolButton with itself, copying some of the properties, such as icon or size. // // ttt2 perhaps turn this class into something generic, by duplicating all the properties and handling other layouts class ModifInfoToolButton : public QToolButton { Q_OBJECT /*override*/ void mousePressEvent(QMouseEvent* pEvent); /*override*/ void keyPressEvent(QKeyEvent* pEvent); Qt::KeyboardModifiers m_modif; void contextMenuEvent(QContextMenuEvent* pEvent); public: ModifInfoToolButton(QToolButton* pOldBtn); Qt::KeyboardModifiers getModifiers() const { return m_modif; } }; int showMessage(QWidget* pParent, QMessageBox::Icon icon, int nDefault, int nEscape, const QString& qstrTitle, const QString& qstrMessage, const QString& qstrButton0, const QString& qstrButton1 = "", const QString& qstrButton2 = "", const QString& qstrButton3 = ""); class QDialog; class HtmlMsg : public QObject { Q_OBJECT int m_nBtn; QDialog* m_pDlg; HtmlMsg(QDialog* pDlg, int nBtn) : m_nBtn(nBtn), m_pDlg(pDlg) {} public: static int msg(QWidget* pParent, int nDefault, int nEscape, bool* pbGotTheMessage, int nFlags, const QString& qstrTitle, const QString& qstrMessage, int nWidth, int nHeight, const QString& qstrButton0, const QString& qstrButton1 = "", const QString& qstrButton2 = "", const QString& qstrButton3 = ""); enum Flags { DEFAULT = 0, STAY_ON_TOP = 1, SHOW_SYS_INFO = 2, CRITICAL = 4, VERT_BUTTONS = 8 }; public slots: void onClick0(); void onClick1(); void onClick2(); void onClick3(); }; // switches the cursor to hourglass on the constructor and back to normal on the destructor struct CursorOverrider { CursorOverrider(Qt::CursorShape crs = Qt::BusyCursor); ~CursorOverrider(); }; class NoCropHeaderView : public QHeaderView { Q_OBJECT /*override*/ void paintSection(QPainter* pPainter, const QRect& rect, int nLogicalIndex) const; public: NoCropHeaderView(QWidget* pParent) : QHeaderView(Qt::Vertical, pParent) {} }; #endif // #ifndef WidgetsH MP3Diags-1.0.12.079/src/TagWriter.h0000644000175000001440000005603311265404655015353 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TagWriterH #define TagWriterH #include #include #include #include "DataStream.h" #include "CommonTypes.h" class QToolButton; class TagWriter; class ImageInfoPanelWdgImpl; // wrapper for the 3-state "Assign" button in the tag editor struct AssgnBtnWrp { enum State { ALL_ASSGN, SOME_ASSGN, NONE_ASSGN }; void setState(State eState); // sets m_eState and changes the button icon accordingly State getState() const { return m_eState; } AssgnBtnWrp(QToolButton* pButton) : m_pButton(pButton) { setState(NONE_ASSGN); } private: State m_eState; QToolButton* m_pButton; }; struct TagWrtImageInfo { ImageInfo m_imageInfo; std::set m_sstrFiles; bool operator==(const ImageInfo& imgInf) const { return m_imageInfo == imgInf; } TagWrtImageInfo(const ImageInfo& imageInfo, const std::string& strFile) : m_imageInfo(imageInfo) { if (!strFile.empty()) { m_sstrFiles.insert(strFile); } } }; class ImageColl { std::vector m_vTagWrtImageInfo; std::vector m_vpWidgets; int m_nCurrent; public: ImageColl(); int addImage(const ImageInfo& img, const std::string& strFile = ""); // returns the index of the image; if it already exists it's not added again; if it's invalid returns -1 void addWidget(ImageInfoPanelWdgImpl*); // first addImage gets called by TagWriter and after it's done it tells MainFormDlgImpl to create widgets, which calls this; void clear(); // clears both m_vTagWrtImageInfo and m_vpWidgets void select(int n); // -1 deselects all const TagWrtImageInfo& operator[](int n) const { return m_vTagWrtImageInfo.at(n); } int find(const ImageInfo& img) const; int size() const { return (int)m_vTagWrtImageInfo.size(); } const TagWrtImageInfo& back() const { return m_vTagWrtImageInfo.at(size() - 1); } }; namespace SongInfoParser { class TrackTextParser; } // There's one of these for each pair of in the current album (or rather , because patterns are not seen directly). They merely "use" the corresponding TrackTextParser to set up the data in the constructor, so the hierarchy of Reader objects is kept only once, in TagWriter. A TrackTextReader extracts track information from a string, which is either a file name or a single line from a multi-line string pasted from the clipboard. class TrackTextReader : public TagReader { std::string m_strTitle; std::string m_strArtist; std::string m_strTrackNumber; TagTimestamp m_timeStamp; std::string m_strGenre; std::string m_strAlbumName; double m_dRating; std::string m_strComposer; bool m_bHasTitle; bool m_bHasArtist; bool m_bHasTrackNumber; bool m_bHasTimeStamp; bool m_bHasGenre; bool m_bHasAlbumName; bool m_bHasRating; bool m_bHasComposer; const char* m_szType; public: /*override*/ std::string getTitle(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasTitle; } return m_strTitle; } /*override*/ std::string getArtist(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasArtist; } return m_strArtist; } /*override*/ std::string getTrackNumber(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasTrackNumber; } return m_strTrackNumber; } /*override*/ TagTimestamp getTime(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasTimeStamp; } return m_timeStamp; } /*override*/ std::string getGenre(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasGenre; } return m_strGenre; } /*override*/ ImageInfo getImage(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } /*override*/ std::string getAlbumName(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasAlbumName; } return m_strAlbumName; } /*override*/ double getRating(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasRating; } return m_dRating; } /*override*/ std::string getComposer(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_bHasComposer; } return m_strComposer; } /*override*/ SuportLevel getSupport(Feature) const; DECL_RD_NAME("Pattern"); const char* getType() const { return m_szType; } TrackTextReader(SongInfoParser::TrackTextParser* pTrackTextParser, const std::string& s); /*override*/ ~TrackTextReader(); }; // information downloaded from sites and passed in AlbumInfo class WebReader : public TagReader { std::string m_strTitle; std::string m_strArtist; std::string m_strTrackNumber; TagTimestamp m_timeStamp; std::string m_strGenre; ImageInfo m_imageInfo; std::string m_strAlbumName; double m_dRating; std::string m_strComposer; AlbumInfo::VarArtists m_eVarArtists; //bool m_bSuppTitle; //bool m_bSuppArtist; //bool m_bSuppTrackNumber; //bool m_bSuppTimeStamp; bool m_bSuppGenre; //bool m_bSuppAlbumName; //bool m_bSuppRating; bool m_bSuppComposer; bool m_bSuppVarArtists; std::string m_strType; int convVarArtists() const; // converts m_eVarArtists to an int is either 0 or contains all VA-enabled values, based on configuration public: /*override*/ std::string getTitle(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = !m_strTitle.empty(); } return m_strTitle; } /*override*/ std::string getArtist(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = !m_strArtist.empty(); } return m_strArtist; } /*override*/ std::string getTrackNumber(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = !m_strTrackNumber.empty(); } return m_strTrackNumber; } /*override*/ TagTimestamp getTime(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = 0 != *m_timeStamp.asString(); } return m_timeStamp; } /*override*/ std::string getGenre(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = !m_strGenre.empty(); } return m_strGenre; } /*override*/ ImageInfo getImage(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = !m_imageInfo.isNull(); } return m_imageInfo; } /*override*/ std::string getAlbumName(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = !m_strAlbumName.empty(); } return m_strAlbumName; } /*override*/ double getRating(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = m_dRating >= 0; } return m_dRating; } /*override*/ std::string getComposer(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = !m_strComposer.empty(); } return m_strComposer; } /*override*/ int getVariousArtists(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = AlbumInfo::VA_NOT_SUPP != m_eVarArtists; } return convVarArtists(); } /*override*/ SuportLevel getSupport(Feature) const; DECL_RD_NAME("Web"); const std::string& getType() const { return m_strType; } WebReader(const AlbumInfo& albumInfo, int nTrackNo); // nTrackNo is 0-based, just an index in albumInfo.m_vTracks ~WebReader(); }; class Mp3Handler; class CommonData; // tag data for a file/Mp3Handler // fields are in the order given by TagReader::Feature, and not FEATURE_ON_POS, so UI components must use FEATURE_ON_POS themselves to determine the "row" they are passing class Mp3HandlerTagData { Mp3HandlerTagData(const Mp3HandlerTagData&); Mp3HandlerTagData& operator=(const Mp3HandlerTagData&); public: Mp3HandlerTagData(TagWriter* pTagWriter, const Mp3Handler* pMp3Handler, int nCrtPos, int nOrigPos, const std::string& strPastedVal); ~Mp3HandlerTagData(); enum Status { EMPTY, ID3V2_VAL, NON_ID3V2_VAL, ASSIGNED }; std::string getData(int nField) const { return m_vValueInfo[nField].m_strValue; } int getImage() const; // 0-based; -1 if there-s no image; double getRating() const; Status getStatus(int nField) const { return m_vValueInfo[nField].m_eStatus; } void setData(int nField, const std::string& s); // may throw InvalidValue void setStatus(int nField, Status); std::string getData(int nField, int k) const; // returns the data corresponding to the k-th element in m_pTagWriter->m_vTagReaderInfo; returns "\n" if it doesn't have a corresponding stream (e.g. 2nd ID3V1 tag) or if the given feature is not supported (e.g. picture in ID3V1) // nField is the "internal" row for which data is retrieved, so TagReader::FEATURE_ON_POS[] has to be used by the UI caller const Mp3Handler* getMp3Handler() const { return m_pMp3Handler; } void refreshReaders(); // updates m_vpTagReader to reflect m_pTagWriter->m_vTagReaderInfo, then updates unassigned values void print(std::ostream&) const; int getOrigPos() const { return m_nOrigPos; } const TagReader* getMatchingReader(int i) const; // returns 0 if i is out of range void adjustVarArtists(bool b); // if VARIOUS_ARTISTS is not ASSIGNED, sets m_strValue and m_eStatus struct InvalidValue {}; private: void setUp(); // to be called initially and each time the priority of tag readers changes TagWriter* m_pTagWriter; const Mp3Handler* m_pMp3Handler; int m_nCrtPos; int m_nOrigPos; // m_nOrigSong gives the position in m_pCommonData->m_vpViewHandlers; the current position may change after sorting by track number std::vector m_vpTagReaders; // needed for the "current album" grid; tag readers used to get the data for track, title, ... ; doesn't own the pointers; there are 2 related differences between it and m_vpMatchingTagReaders: 1) m_vpTagReaders doesn't contain null elements; 2) some of the null entries in m_vpMatchingTagReaders are replaced with other entries in m_vpTagReaders /* there is a file that has 2 ID3V1 tags in the current album, so 2 ID3V1 columns appear, along with an ID3V2 and an Ape; the user chooses this order "ID3V1 2", "ID3V2", "Ape", "ID3V1 1" (which internally are seen as "ID3V1 1", "ID3V2 0", "Ape 0", "ID3V1 0", because counting starts at 0) the current file only has an ID3V1 and an ID3V2 m_vpMatchingTagReaders will end up with: , "ID3V2 0", , "ID3V1 0" (matching m_pTagWriter->m_vTagReaderInfo's size of 4) m_vpTagReaders will end up with: "ID3V1 0", "ID3V2 0", "ID3V1 0" (size is 3) see also the big comment in refreshReaders() */ std::vector m_vpMatchingTagReaders; // needed for the "current file" grid; has the same size as m_pTagWriter->m_vTagReaderInfo; some elements are null, if there is no corresponding reader; doesn't own the pointers; std::vector m_vTrackTextReaders; // pointers to TrackTextReader need to be owned, so it's easiest to put the objects in a vector, while also putting the pointers in m_vpTagReaders std::vector m_vWebReaders; // pointers to TrackTextReader need to be owned, so it's easiest to put the objects in a vector, while also putting the pointers in m_vpTagReaders struct ValueInfo { std::string m_strValue; Status m_eStatus; ValueInfo() : m_eStatus(EMPTY) {} }; std::vector m_vValueInfo; // PictureIndex is stored as a string std::string m_strPastedVal; // cleared on reload(), assigned when pasting multi-line content from the clipboard mutable std::vector m_vstrImgCache; }; struct TagReaderInfo { std::string m_strName; int m_nPos; // usually this is 0; has other values if there are more than 1 instance of a TagReader type (e.g. TrackTextReader, Id3V230Stream, ...), to tell them apart bool m_bAlone; // if it's the only TagReaderInfo with its name enum { ONE_OF_MANY, ALONE }; TagReaderInfo(const std::string& strName, int nPos, bool bAlone) : m_strName(strName), m_nPos(nPos), m_bAlone(bAlone) {} bool operator==(const TagReaderInfo& other) const { return m_nPos == other.m_nPos && m_strName == other.m_strName; } }; class TagWriter : public QObject { Q_OBJECT std::vector m_vSortedKnownTagReaders; // used to remember the sort order between albums and/or sessions; after m_vTagReaderInfo is populated, it should be sorted so that it matches the order in m_vSortedKnownTagReaders, if possible; items not found are to be added to the end void sortTagReaders(); // sorts m_vTagReaderInfo so that it matches m_vSortedKnownTagReaders std::vector m_vpTrackTextParsers; // one TrackTextParser for each pattern std::set m_snActivePatterns; std::vector m_vAlbumInfo; // one AlbumInfo for every album data downloaded from structured web sites // "original value" of a selected field; not necessarily related to the fields in a file's tags, but merely holds whatever happened to be in a given field when it gets selected; the "original value" from Mp3HandlerTagData's point of view is not stored anywhere, but it is recovered as needed, because toggleAssigned() calls "reloadAll("", DONT_CLEAR)" struct OrigValue { int m_nSong, m_nField; // nField is an index in TagReader::Feature, not affected by TagReader::FEATURE_ON_POS std::string m_strVal; Mp3HandlerTagData::Status m_eStatus; OrigValue(int nSong, int nField, const std::string& strVal, Mp3HandlerTagData::Status eStatus) : m_nSong(nSong), m_nField(nField), m_strVal(strVal), m_eStatus(eStatus) {} bool operator<(const OrigValue& other) const { if (m_nSong < other.m_nSong) { return true; } if (other.m_nSong < m_nSong) { return false; } return m_nField < other.m_nField; } }; friend std::ostream& operator<<(std::ostream& out, const TagWriter::OrigValue& val); std::set m_sSelOrigVal; // original values for selected fields (so it can also be used to determine which fields are selected) bool m_bSomeSel; bool m_bNonStandardTrackNo; std::vector m_vnMovedTo; // the position on screen corresponding to m_pCommonData->m_vpViewHandlers elements after they are sorted by track number void sortSongs(); // sorts by track number; shows a warning if issues are detected (should be exactly one track number, from 1 to the track count) bool addImgFromFile(const QString& qs, bool bConsiderAssigned); // see also addImage() std::vector m_vstrPastedValues; CommonData* m_pCommonData; QWidget* m_pParentWnd; // for QMessageBox int m_nCurrentFile; ImageColl m_imageColl; bool m_bShowedNonSeqWarn; std::set m_snUnassignedImages; const bool& m_bIsFastSaving; bool m_bShouldShowPatternsNote; int m_nFileToErase; bool m_bVariousArtists; bool m_bAutoVarArtists; // true at first, until the "toggle" button is clicked void adjustVarArtists(); bool m_bDelayedAdjVarArtists; bool m_bWaitingChangeNotif; public: TagWriter(CommonData* pCommonData, QWidget* pParentWnd, const bool& bIsFastSaving, const TextCaseOptions& eArtistCase, const TextCaseOptions& eTitleCase); ~TagWriter(); enum ClearData { DONT_CLEAR_DATA, CLEAR_DATA }; enum ClearAssigned { DONT_CLEAR_ASSGN, CLEAR_ASSGN }; // called in 3 cases: 1) when going to a new album; 2) when changing the order of readers; 3) when adding/changing/removing TrackTextReaders; all require the reader list to be updated (there are 3 kinds of readers: 1) those that the current album uses, which are stored in Mp3Handler; 2) TrackTextReader instances, which are built manually from m_vpTrackTextParsers; and 3) those with data read from the web); // nPos tells which should be the current file; if nPos is <0 it is ignored and the current file remains the same; a value <0 should only be used when changing reader priorities; // if eReloadOption is CLEAR, everyting is reloaded; if it's something else, the call is supposed to be for the same album, after changing tag priorities, so ASSIGNED values shouldn't change; if it's UPDATE_SEL, the selection is changed to the first cell for the current song; if it's DONT_UPDATE_SEL the selection isn't changed // if strCrt is empty and eReloadOption is DONT_CLEAR, the current position is kept; if strCrt is empty and eReloadOption is CLEAR, the current position is first song; //void reloadAll(std::string strCrt, ReloadOption eReloadOption/*, bool bKeepUnassgnImg*/); // bKeepUnassgnImg matters only if eReloadOption is CLEAR void reloadAll(std::string strCrt, bool bClearData, bool bClearAssgn); void setCrt(const std::string& strCrt); // makes current a file with a given name; if name is not found (may also be empty), makes current the first file; doesn't cause the grid selection to change; void setCrt(int nCrt); // asserts nCrt is valid; doesn't cause the grid selection to change; std::vector m_vpMp3HandlerTagData; // one for each file in the current album std::vector m_vTagReaderInfo; // has only readers that correspond to the current album, so it's a subset of m_vSortedKnownTagReaders; (sortTagReaders() adds to m_vSortedKnownTagReaders whatever new Readers are found in m_vTagReaderInfo) SongInfoParser::TrackTextParser* getTrackTextParser(int n) { return m_vpTrackTextParsers.at(n); } int getTrackTextParsersCnt() const { return (int)m_vpTrackTextParsers.size(); } const AlbumInfo& getAlbumInfo(int n) const { return m_vAlbumInfo.at(n); } int getAlbumInfoCnt() const { return (int)m_vAlbumInfo.size(); } int getIndex(const ImageInfo&) const; // asserts that the picture exists const Mp3Handler* getCurrentHndl() const; // returns 0 if there's no current handler std::string getCurrentName() const; // returns "" if there's no current handler const Mp3HandlerTagData* getCrtMp3HandlerTagData() const; // returns 0 if there's no current handler void moveReader(int nOldVisualIndex, int nNewVisualIndex); void addKnownInf(const std::vector& v); // should be called on startup by MainFormDlgImpl, to get config data; asserts that m_vSortedKnownTagReaders is empty; const std::vector& getSortedKnownTagReaders() const { return m_vSortedKnownTagReaders; } // the int tells which position a given pattern occupied before; (it's -1 for new patterns); // doesn't throw, but invalid patterns are discarded; it returns false if at least one pattern was discarded; bool updatePatterns(const std::vector >&); std::vector getPatterns() const; void setActivePatterns(const std::set&); std::set getActivePatterns() const { return m_snActivePatterns; } // model-based nField; UI components should pass the UI index through TagReader::FEATURE_ON_POS[] before calling this Mp3HandlerTagData::Status getStatus(int nSong, int nField) const { return m_vpMp3HandlerTagData[nSong]->getStatus(nField); } std::string getData(int nSong, int nField) const { return m_vpMp3HandlerTagData[nSong]->getData(nField); } void setData(int nSong, int nField, const std::string& s) { m_vpMp3HandlerTagData[nSong]->setData(nField, s); } // may throw InvalidValue void setStatus(int nSong, int nField, Mp3HandlerTagData::Status eStatus) { m_vpMp3HandlerTagData[nSong]->setStatus(nField, eStatus); } void hasUnsaved(int nSong, bool& bAssigned, bool& bNonId3V2); // sets bAssigned and bNonId3V2 if at least one field has the corresponding status; void hasUnsaved(bool& bAssigned, bool& bNonId3V2); // sets bAssigned and bNonId3V2 if at least one field in at least a song has the corresponding status; void getAlbumInfo(std::string& strArtist, std::string& strAlbum); // artist and album for the current song; empty if they don't exist void addAlbumInfo(const AlbumInfo&); // should be called when the selection changes; updates m_sSelOrigVal and returns the new state of m_pAssignedB; AssgnBtnWrp::State updateAssigned(const std::vector >& vFields); // should be called when the user clicks on the assign button; changes status of selected cells and returns the new state of m_pAssignedB AssgnBtnWrp::State toggleAssigned(AssgnBtnWrp::State eCrtState); void copyFirst(); void paste(); void sort(); void eraseFields(const std::vector >& vFields); bool isFastSaving() const { return m_bIsFastSaving; } bool shouldShowPatternsNote() const { return m_bShouldShowPatternsNote; } enum ConsiderAssigned { CONSIDER_UNASSIGNED, CONSIDER_ASSIGNED }; int addImage(const ImageInfo& img, bool bConsiderAssigned); // returns the index of the image; if it already exists it's not added again; if it's invalid returns -1 // "unassigned" images cause warnings when going to another album void addImgWidget(ImageInfoPanelWdgImpl*); const ImageColl& getImageColl() const { return m_imageColl; } void selectImg(int n); void clearShowedNonSeqWarn() { m_bShowedNonSeqWarn = false; } int getUnassignedImagesCount() const { return int(m_snUnassignedImages.size()); } void toggleVarArtists(); void delayedAdjVarArtists(); const TextCaseOptions& m_eArtistCase; const TextCaseOptions& m_eTitleCase; private slots: void onAssignImage(int); void onEraseFile(int); void onEraseFileDelayed(); void onDelayedTrackSeqWarn(); void onDelayedAdjVarArtists(); void onDelayedChangeNotif(); signals: void albumChanged(/*bool bContentOnly*/); // the selection may be kept iff bContentOnly is true void fileChanged(); void imagesChanged(); void requestSave(); void varArtistsUpdated(bool bVarArtists); }; #endif // #ifndef TagWriterH MP3Diags-1.0.12.079/src/StreamsModel.h0000644000175000001440000000606611200236431016023 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef StreamsModelH #define StreamsModelH #include #include "MultiLineTvDelegate.h" //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class CommonData; // current streams struct StreamsModel : public QAbstractTableModel { Q_OBJECT public: StreamsModel(CommonData* pCommonData); ~StreamsModel() {} /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; CommonData* m_pCommonData; //void matchSelToMain(); void matchSelToNotes(); void emitLayoutChanged() { emit layoutChanged(); } public slots: void onStreamsGSelChanged(); }; class StreamsGDelegate : public MultiLineTvDelegate { Q_OBJECT public: //StreamsGDelegate(CommonData* pCommonData, QObject* pParent) : QItemDelegate(pParent), m_pCommonData(pCommonData) {} StreamsGDelegate(CommonData* pCommonData); /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; CommonData* m_pCommonData; }; #endif // #ifndef StreamsModelH MP3Diags-1.0.12.079/src/FilesModel.cpp0000644000175000001440000005114511261073134016006 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include "FilesModel.h" #include "CommonData.h" #include "NotesModel.h" #include "StreamsModel.h" using namespace std; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== FilesModel::FilesModel(CommonData* pCommonData) : QAbstractTableModel(pCommonData->m_pFilesG), m_nPrevCurrentRow(-1), m_pCommonData(pCommonData) { } //static int RR (0); //#define USE_10000 // not quite OK to use, but allows some quick testing /*override*/ int FilesModel::rowCount(const QModelIndex&) const { #ifdef USE_10000 return 10000; #else return cSize(m_pCommonData->getViewHandlers()); #endif } /*override*/ int FilesModel::columnCount(const QModelIndex&) const { return m_pCommonData->getUniqueNotes().getFltCount() + 1; } /*extern*/ int CELL_WIDTH (1); // these get calculated based on the current font; however, they are also used /*extern*/ int CELL_HEIGHT (1); /*override*/ QVariant FilesModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("FilesModel::headerData"); if (!index.isValid()) { return QVariant(); } int j (index.column()); if (nRole == Qt::SizeHintRole && j > 0) { return QSize(CELL_WIDTH - 1, CELL_HEIGHT - 1); } // !!! "-1" so one pixel can be used to draw the grid //qDebug("cw %d", CELL_WIDTH); #ifdef USE_10000 if (index.row() >= cSize(m_pCommonData->getFltHandlers())) { return QVariant(); } #endif const Mp3Handler* pHndl (m_pCommonData->getViewHandlers()[index.row()]); if (nRole == Qt::ToolTipRole && 0 == j) { QString s (pHndl->getUiName()); //QFontMetrics fm (QApplication::fontMetrics()); QFontMetrics fm (m_pCommonData->m_pFilesG->fontMetrics()); // !!! no need to use "QApplication::fontMetrics()" int nWidth (fm.width(s)); if (nWidth + 10 < m_pCommonData->m_pFilesG->horizontalHeader()->sectionSize(0)) // ttt2 "10" is hard-coded { //return QVariant(); return ""; // !!! with "return QVariant()" the previous tooltip remains until the cursor moves over another cell that has a tooltip }//*/ return s; } if (nRole != Qt::DisplayRole && nRole != Qt::ToolTipRole) { return QVariant(); } if (0 == j) { return pHndl->getUiName(); } const NoteColl& notes (pHndl->getNotes()); for (int i = 0, n = cSize(notes.getList()); i < n; ++i) // ttt2 poor performance { const Note* pNote (notes.getList()[i]); if (j - 1 == m_pCommonData->findPos(pNote)) { return nRole == Qt::ToolTipRole ? makeMultiline(m_pCommonData->getUniqueNotes().getFlt(j - 1)->getDescription()) : "x"; } } return ""; } /*override*/ QVariant FilesModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("FilesModel::headerData"); #if 0 // 2008.07.28: no longer used because resizeColumnsToContents() cannot be called (it takes too long) if (nRole == Qt::SizeHintRole) { /*QVariant v (QAbstractTableModel::headerData(nSection, eOrientation, nRole)); // !!! doesn't work because QAbstractTableModel::headerData always returns an invalid value [...] */ if (eOrientation == Qt::Vertical) { /*QFontMetrics fm (m_pCommonData->m_pFilesG->fontMetrics()); double d (1.01 + log10(double(m_pCommonData->getFltHandlers().size()))); int n (d); QString s (n, QChar('9')); //QSize size (fm.boundingRect(r, Qt::AlignTop | Qt::TextWordWrap, s).size()); int nWidth (fm.width(s)); //return QSize(50, CELL_HEIGHT); return QSize(nWidth + 10, CELL_HEIGHT); //tttx perhaps use data cell height of 17 (fontMetrics().height()) (so header cell height is 18 ("+1" to account for the grid) //ttt2 hard-coded "10"*/ getNumVertHdrSize ... } return QVariant(); } #endif if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { if (0 == nSection) { return "File name"; } const vector& v (m_pCommonData->getUniqueNotes().getFltVec()); int nSize (cSize(v)); if (nSection > nSize) { return ""; //ttt2 see why is this needed; it wasn't so until version 134 (handling of MainFormDlgImpl::resizeEvent() or of MainFormDlgImpl::on_m_pMainTabWidget_currentChanged() seem to have something to do with this) } return getNoteLabel(v[nSection - 1]); } return nSection + 1; } // makes current and selects the specified row and emits a change signal regardless of the element that was selected before; makes current the default invalid index (-1,-1) if the table is empty; void FilesModel::selectRow(int nRow, const vector& vnSel /*= std::vector()*/) { QItemSelectionModel* pSelModel (m_pCommonData->m_pFilesG->selectionModel()); //m_pCommonData->printFilesCrt(); { NonblockingGuard g (m_pCommonData->m_bChangeGuard); if (!g) { return; } pSelModel->clear(); // 2008.07.08: this doesn't work quite as expected: it does trigger SelectionChanged, but it changes the current item after emitting the signal, so whoever catches it, doesn't know what the current item is (it's probably in the second param of CurrentChanged, but that doesn't help SelectionChanged, which has QItemSelection params, which don't seem to offer any way to get at the "current" index) } //m_pCommonData->printFilesCrt(); emit layoutChanged(); m_nPrevCurrentRow = -2; // to make sure that onFilesGSelChanged() updates the notes and streams regardless of whether there are any files in m_pFilesG or not if (!m_pCommonData->getViewHandlers().empty()) { //pSelModel->select(index(0, 0), QItemSelectionModel::Current); //pSelModel->select(index(0, 0), QItemSelectionModel::Select); //m_pCommonData->printFilesCrt(); m_pCommonData->m_pFilesG->setCurrentIndex(index(nRow, 0)); // this sometimes calls onFilesGSelChanged(), but not always; //m_pCommonData->printFilesCrt(); } if (-2 == m_nPrevCurrentRow) { onFilesGSelChanged(); } for (int i = 0, n = cSize(vnSel); i < n; ++i) { pSelModel->select(pSelModel->model()->index(vnSel[i], 0), QItemSelectionModel::Select); } } // this gets called more often than expected: besides the cases when it gets called recursively and exits immediately, it is called on MousePressed, MouseReleased and Clicked (which is sent at the later stage of MouseReleased processing) void FilesModel::onFilesGSelChanged() { NonblockingGuard g (m_pCommonData->m_bChangeGuard); if (!g) { return; } //m_pCommonData->printFilesCrt(); int nGridCrt (m_pCommonData->getFilesGCrtRow()); if (m_nPrevCurrentRow != nGridCrt) { //m_pCommonData->m_pNotesModel->updateCurrentNotes(); //m_pCommonData->m_pStreamsModel->updateCurrentStreams(); emit currentFileChanged(); m_nPrevCurrentRow = nGridCrt; } fixSelection(); m_pCommonData->m_pNotesModel->matchSelToMain(); m_pCommonData->m_pStreamsModel->matchSelToNotes(); } void FilesModel::fixSelection() // deselects cells that are selected but are on a different row from the "current" cell and selects the file name { // it works OK when getFltHandlers() is empty QItemSelectionModel* pSelModel (m_pCommonData->m_pFilesG->selectionModel()); QModelIndexList lstSel (pSelModel->selection().indexes()); QModelIndex crt (m_pCommonData->m_pFilesG->selectionModel()->currentIndex()); int nCrtRow (crt.row()); int nCrtCol (crt.column()); if (0 == nCrtCol) { for (QModelIndexList::iterator it = lstSel.begin(), end = lstSel.end(); it != end; ++it) { if (0 != it->column()) { pSelModel->select(*it, QItemSelectionModel::Deselect); } } } else { set sSelectableColumns; sSelectableColumns.insert(0); for (int i = 0, n = cSize(m_pCommonData->getCrtNotes()); i < n; ++i) // ttt2 poor performance { const Note* pNote (m_pCommonData->getCrtNotes()[i]); sSelectableColumns.insert(m_pCommonData->findPos(pNote) + 1); } for (QModelIndexList::iterator it = lstSel.begin(), end = lstSel.end(); it != end; ++it) { if ((it->row() != nCrtRow && 0 != it->column()) || 0 == sSelectableColumns.count(it->column())) { pSelModel->select(*it, QItemSelectionModel::Deselect); } } if (nCrtRow >= 0) { pSelModel->select(index(nCrtRow, 0), QItemSelectionModel::Select); } } } void FilesModel::matchSelToNotes() { QItemSelectionModel* pNotesSelModel (m_pCommonData->m_pNotesG->selectionModel()); QModelIndexList notesLstSel (pNotesSelModel->selection().indexes()); set sSel; for (QModelIndexList::iterator it = notesLstSel.begin(), end = notesLstSel.end(); it != end; ++it) { //cout << "cell sel at " << it->row() << "x" << it->column() << endl; const Note* pNote (m_pCommonData->getCrtNotes()[it->row()]); int nPos (m_pCommonData->findPos(pNote)); sSel.insert(nPos); } m_pCommonData->m_pFilesG->selectionModel()->clearSelection(); for (set::const_iterator it = sSel.begin(), end = sSel.end(); it != end; ++it) { m_pCommonData->m_pFilesG->selectionModel()->select(index(m_pCommonData->getFilesGCrtRow(), *it + 1), QItemSelectionModel::Select); //cout << "selecting " << m_pCommonData->getFilesGCrtRow() << "x" << *it + 1 << endl; } m_pCommonData->m_pFilesG->selectionModel()->select(index(m_pCommonData->getFilesGCrtRow(), 0), QItemSelectionModel::Select); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== /*override*/ void FilesGDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { // adapted from Trolltech's Pixelator (GPL V2 or V3) http://doc.trolltech.com/4.3/itemviews-pixelator.html int nCol (index.column()); if (0 == nCol) { return QItemDelegate::paint(pPainter, option, index); } //int nRow (index.row()); double r ((index.model()->data(index, Qt::DisplayRole).toString() == "" ? 0 : (CELL_HEIGHT - 0)/5)); pPainter->save(); pPainter->setRenderHint(QPainter::Antialiasing, true); pPainter->setPen(Qt::NoPen); const Note* pNote (m_pCommonData->getUniqueNotes().getFlt(nCol - 1)); bool bSel (0 != (QStyle::State_Selected & option.state)); bool bCrt (0 != (QStyle::State_HasFocus & option.state)); bool bActive (0 != (QStyle::State_Active & option.state)); // "active" is true if the parent window has keyboard focus /*QColor colSev (getNoteColor(*pNote)); //ttt2 perhaps try to derive all these colors from the global pallette (e.g. option.palette.highlight(), option.palette.highlightedText(), ...) QColor colBkg (colSev); QColor colFg (option.palette.color(QPalette::Active, QPalette::Highlight)); //ttt3 not necessarily "Active" //QColor colFg (Qt::black); //ttt3 not necessarily "Active" if (colFg.green() >= 160 && colFg.red() >= 160) { colFg = QColor(0, 0, 0); } if (bSel) { QColor c (colBkg); colBkg = colFg; colFg = c; }*/ //ttt2 perhaps try to derive all these colors from the global pallette (e.g. option.palette.highlight(), option.palette.highlightedText(), ...) QColor colNote; double dGradStart, dGradEnd; m_pCommonData->getNoteColor(*pNote, m_pCommonData->getUniqueNotes().getFltVec(), colNote, dGradStart, dGradEnd); QColor colSel (option.palette.color(QPalette::Active, QPalette::Highlight)); //ttt3 not necessarily "Active" //qDebug("gr %f %f", dGradStart, dGradEnd); QColor colFg, colBkg; colBkg = bSel ? colSel : colNote; if (colSel.green() >= 160 && colSel.red() >= 160) { // for better contrast we use something dark if the "highlight" color is light //colFg = QColor(0, 0, 0); colFg = option.palette.color(QPalette::Active, QPalette::HighlightedText); } else { colFg = bSel ? colNote : colSel; } //colBkg = QColor(220, 255, 230); QLinearGradient grad (option.rect.x(), 0, option.rect.x() + option.rect.width(), 0); /*switch(nCol % 4) { case 0: grad.setColorAt(0, colBkg.lighter(120)); grad.setColorAt(0.4, colBkg); grad.setColorAt(0.6, colBkg); grad.setColorAt(1, colBkg.darker(120)); break; case 1: grad.setColorAt(0, colBkg.lighter(120)); grad.setColorAt(0.4, colBkg); grad.setColorAt(0.6, colBkg); grad.setColorAt(1, colBkg); break; case 2: grad.setColorAt(0, colBkg); grad.setColorAt(0.4, colBkg); grad.setColorAt(0.6, colBkg); grad.setColorAt(1, colBkg); break; case 3: grad.setColorAt(0, colBkg); grad.setColorAt(0.4, colBkg); grad.setColorAt(0.6, colBkg); grad.setColorAt(1, colBkg.darker(120)); break; }*/ /* switch(nCol % 4) { case 0: configureGradient(grad, colBkg, 0, 1); break; case 1: configureGradient(grad, colBkg, 0, 0.33); break; case 2: configureGradient(grad, colBkg, 0.33, 0.67); break; case 3: configureGradient(grad, colBkg, 0.67, 1); break; } */ configureGradient(grad, colBkg, dGradStart, dGradEnd); //pPainter->fillRect(option.rect, colBkg); pPainter->fillRect(option.rect, grad); if (0 != r) { pPainter->setBrush(QBrush(colFg)); pPainter->drawEllipse( QRectF(option.rect.x() + option.rect.width()/2.0 - r, option.rect.y() + option.rect.height()/2.0 - r, 2*r, 2*r)); } if (bCrt && bActive) { pPainter->setRenderHint(QPainter::Antialiasing, false); const int ADJ (0); QRect r (option.rect); r.adjust(ADJ, ADJ, -ADJ - 1, -ADJ - 1); pPainter->setBrush(QBrush(Qt::NoBrush)); QPen pen (pPainter->pen()); pen.setStyle(Qt::DotLine); //pen.setColor(Qt::black); pen.setColor(colFg); pPainter->setPen(pen); pPainter->drawRect(r); } pPainter->restore(); } /*override*/ QSize FilesGDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { if (!index.isValid()) { return QSize(); } if (index.column() > 0) { return QItemDelegate::sizeHint(option, index); } int nMargin (QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1); int j (index.column()); int nColWidth (((const QTableView*)parent())->horizontalHeader()->sectionSize(j)); QRect r (0, 0, nColWidth - 2*nMargin - 1, 10000); QSize res (option.fontMetrics.boundingRect(r, Qt::AlignTop | Qt::TextWordWrap, index.data(Qt::DisplayRole).toString()).size()); res.setWidth(nColWidth); return res; } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== FileHeaderView::FileHeaderView(CommonData* pCommonData, QWidget* pParent) : QHeaderView(Qt::Horizontal, pParent), m_pCommonData(pCommonData) { } /*override*/ void FileHeaderView::mouseMoveEvent(QMouseEvent* pEvent) { int k (logicalIndexAt(pEvent->x(), pEvent->y())); if (k <= 0) { setToolTip(""); return; } --k; setToolTip(makeMultiline(m_pCommonData->getUniqueNotes().getFlt(k)->getDescription())); } static int s_nCut (0); int getHeaderDrawOffset() { return s_nCut; } /*override*/ void FileHeaderView::paintSection(QPainter* pPainter, const QRect& r, int nLogicalIndex) const { if (0 == nLogicalIndex) { pPainter->save(); QFont f (pPainter->font()); f.setWeight(QFont::Bold); pPainter->setFont(f); QHeaderView::paintSection(pPainter, r, nLogicalIndex); pPainter->restore(); return; } pPainter->save(); // partial copy from Qt's implementation of QHeaderView (qheaderview.cpp) QStyleOptionHeader opt; initStyleOption(&opt); opt.rect = r; opt.section = nLogicalIndex; int nVisual (visualIndex(nLogicalIndex)); if (count() == 1) opt.position = QStyleOptionHeader::OnlyOneSection; else if (nVisual == 0) opt.position = QStyleOptionHeader::Beginning; else if (nVisual == count() - 1) opt.position = QStyleOptionHeader::End; else opt.position = QStyleOptionHeader::Middle; opt.selectedPosition = QStyleOptionHeader::NotAdjacent; style()->drawControl(QStyle::CE_Header, &opt, pPainter, this); static bool s_bCutInit (false); if (!s_bCutInit) { s_bCutInit = true; int n (r.width()), m (r.height()); QRect r1 (0, 0, n, m); QImage img (n, m, QImage::Format_RGB32); QPainter pntr (&img); pntr.fillRect(r1, QColor(255, 255, 255)); opt.rect = r1; style()->drawControl(QStyle::CE_Header, &opt, &pntr); //img.save("/home/ciobi/tmp/3/hdr1.png"); m /= 2; double v1 (QColor(img.pixel(n - 3, m)).valueF()); double v2 (QColor(img.pixel(n - 2, m)).valueF()); double v3 (QColor(img.pixel(n - 1, m)).valueF()); //qDebug("%f %f %f", v1, v2, v3); if ((v1 > v2 + 0.07 && v3 > v2 + 0.07) || (v1 < v2 - 0.07 && v3 < v2 - 0.07)) { s_nCut = 3; //ttt2 hard-coded, must be kept in synch with CELL_WIDTH } // qDebug("cut: %d", s_nCut); } pPainter->restore(); pPainter->save(); pPainter->setFont(m_pCommonData->getLabelFont()); { // bold for selected QModelIndexList l (m_pCommonData->m_pFilesG->selectionModel()->selection().indexes()); for (QModelIndexList::iterator it = l.begin(); it != l.end(); ++it) { const QModelIndex& ndx (*it); if (ndx.column() == nLogicalIndex) { QFont f (pPainter->font()); f.setWeight(QFont::Bold); pPainter->setFont(f); break; } } } const Note* p (m_pCommonData->getUniqueNotes().getFltVec().at(nLogicalIndex - 1)); if (Note::ERR == p->getSeverity()) { pPainter->setPen(ERROR_PEN_COLOR()); } else if (Note::SUPPORT == p->getSeverity()) { pPainter->setPen(SUPPORT_PEN_COLOR()); } QRect r1 (r); r1.adjust(0, 0, -s_nCut, 0); pPainter->drawText(r1, Qt::AlignCenter, getNoteLabel(p)); pPainter->restore(); } MP3Diags-1.0.12.079/src/MainFormDlgImpl.cpp0000644000175000001440000034526211570151211016746 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef MSVC_QMAKE #pragma warning (disable : 4100) #endif #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef WIN32 //#include #else #include #include #endif #include "MainFormDlgImpl.h" #include "DirFilterDlgImpl.h" #include "NoteFilterDlgImpl.h" #include "Helpers.h" #include "OsFile.h" #include "FilesModel.h" #include "NotesModel.h" #include "StreamsModel.h" #include "UniqueNotesModel.h" #include "TagReadPanel.h" #include "ThreadRunnerDlgImpl.h" #include "ConfigDlgImpl.h" #include "AboutDlgImpl.h" #include "Widgets.h" #include "DataStream.h" #include "NormalizeDlgImpl.h" #include "DebugDlgImpl.h" #include "TagEditorDlgImpl.h" #include "Mp3TransformThread.h" #include "FileRenamerDlgImpl.h" #include "ScanDlgImpl.h" #include "SessionEditorDlgImpl.h" #include "Id3Transf.h" #include "ExportDlgImpl.h" using namespace std; using namespace pearl; //#define LOG_ANYWAY //ttt2 try to switch from QDialog to QWidget, to see if min/max in gnome show up; or add Qt::Dialog flag (didn't seem to work, though) MainFormDlgImpl* getGlobalDlg(); //ttt2 review void trace(const string& s) { MainFormDlgImpl* p (getGlobalDlg()); //p->m_pContentM->append(convStr(s)); //p->m_pCommonData->m_qstrContent += convStr(s); //p->m_pCommonData->m_qstrContent += "\n"; if (0 != p && 0 != p->m_pCommonData) { p->m_pCommonData->trace(s); //ttt if p->m_pCommonData==0 or p==0 use logToGlobalFile(); 2009.09.08 - better not: this is "trace"; it makes sense to log errors before p->m_pCommonData is set up, but this is not the place to do it } } namespace { #ifndef WIN32 class NativeFile { string m_strFileName; public: NativeFile() {} bool open(const string& strFileName) // doesn't truncate the file { m_strFileName = strFileName; ofstream_utf8 out (m_strFileName.c_str(), ios_base::app); return out; } void close() { m_strFileName.clear(); } bool write(const string& s) { ofstream_utf8 out (m_strFileName.c_str(), ios_base::app); out << s; return out; } }; #else // #ifndef WIN32 void CB_LIB_CALL displayOsErrorIfExists(const char* szTitle) { unsigned int nErr (GetLastError()); if (0 == nErr) return; LPVOID lpMsgBuf; FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, nErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPSTR) &lpMsgBuf, 0, NULL ); string strRes ((LPSTR)lpMsgBuf); // Free the buffer. LocalFree(lpMsgBuf); unsigned int nSize ((unsigned int)strRes.size()); if (nSize - 2 == strRes.rfind("\r\n")) { strRes.resize(nSize - 2); } QMessageBox::critical(0, szTitle, convStr(strRes)); } class NativeFile { HANDLE m_hStepFile; public: NativeFile() : m_hStepFile (INVALID_HANDLE_VALUE) {} bool open(const string& strFileName) { m_hStepFile = CreateFileA(strFileName.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_ALWAYS, //CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, //FILE_ATTRIBUTE_NORMAL, 0); if (INVALID_HANDLE_VALUE == m_hStepFile) { displayOsErrorIfExists("Error"); return false; } SetFilePointer(m_hStepFile, 0, 0, FILE_END); return true; } void close() { CloseHandle(m_hStepFile); m_hStepFile = INVALID_HANDLE_VALUE; } bool write(const string& s) { DWORD dwWrt; //WriteFile(s_hStepFile, a, strlen(a), &dwWrt, 0); WriteFile(m_hStepFile, s.c_str(), s.size(), &dwWrt, 0); //WriteFile(s_hStepFile, "\r\n", 2, &dwWrt, 0); return (dwWrt == s.size()); } }; #endif // #ifndef WIN32 class FileTracer { string m_strTraceFile; vector m_vstrStepFile; bool m_bEnabled1, m_bEnabled2; // both have to be true for the trace to actually be enabled; they are not symmetrical: changing m_bEnabled2 while m_bEnabled1 is true also removes the files, but doesn't happen the other way; the reason for doing this is that we want trace files from previous run deleted (regardless of how it finished) but we don't want them deleted too early, so the user has a chance to mail them; to complicate the things, there is loading the settings, which may call enable2(true); int m_nStepFile; int m_nCrtStepSize; int m_nPage; int m_nStepLevel; int m_nTraceLevel; NativeFile m_stepFile; void setupFiles(); void removeFiles(); NativeFile m_traceFile; public: FileTracer() : m_bEnabled1(false), m_bEnabled2(false), m_nStepFile(-1), m_nCrtStepSize(-1), m_nPage(-1), m_nStepLevel(-1), m_nTraceLevel(-1) { } //void setupTraceToFile(bool bEnable); void setName(const string& strNameRoot); // also disables void enable1(bool); // used as a master control, by MainFormDlgImpl and assert; if m_bEnabled1 is true, changing m_bEnabled2 triggers the removal of files void enable2(bool); // set based on config //void removeFilesIfDisabled(); void traceToFile(const string& s, int nLevelChange); void traceLastStep(const string& s, int nLevelChange); const string& getTraceFile() const { return m_strTraceFile; } const vector& getStepFiles() const { return m_vstrStepFile; } }; void FileTracer::traceToFile(const string& s, int nLevelChange) { if (!m_bEnabled1 || !m_bEnabled2 || m_strTraceFile.empty()) { return; } static QMutex mutex; QMutexLocker lck (&mutex); m_nTraceLevel += nLevelChange; if (m_nTraceLevel < 0) { m_nTraceLevel = 20; } string s1 (m_nTraceLevel, ' '); // !!! may happen in this case: trace gets enabled by assert, then the Tracer destructor runs, trying to decrease what was never increased s1 += s; QTime t (QTime::currentTime()); char a [15]; sprintf(a, "%02d:%02d:%02d.%03d", t.hour(), t.minute(), t.second(), t.msec()); //ofstream_utf8 out (m_strTraceFile.c_str(), ios_base::app); //out << a << s1 << endl; #ifndef WIN32 m_traceFile.write(a + s1 + "\n"); #else m_traceFile.write(a + s1 + "\r\n"); #endif } void FileTracer::traceLastStep(const string& s, int nLevelChange) { if (!m_bEnabled1 || !m_bEnabled2 || m_strTraceFile.empty()) { return; } static QMutex mutex; QMutexLocker lck (&mutex); m_nStepLevel += nLevelChange; if (m_nStepLevel < 0) { m_nStepLevel = 20; } // !!! may happen in this case: trace gets enabled by assert, then the LastStepTracer destructor runs, trying to decrease what was never increased string s1 (m_nStepLevel, ' '); //string s1; char b [20]; sprintf(b, "%d", s_nLevel); s1 = b; s1 += s; char a [15]; a[0] = 0; //QTime t (QTime::currentTime()); sprintf(a, "%02d:%02d:%02d.%03d ", t.hour(), t.minute(), t.second(), t.msec()); #ifndef WIN32 m_stepFile.write(a + s1 + "\n"); m_nCrtStepSize += s1.size() + 1; #else m_stepFile.write(a + s1 + "\r\n"); m_nCrtStepSize += s1.size() + 2; #endif if (m_nCrtStepSize > 50000) { m_stepFile.close(); m_nCrtStepSize = 0; m_nStepFile = 1 - m_nStepFile; try { deleteFile(m_vstrStepFile[m_nStepFile]); } catch (...) { //ttt2 } { ofstream_utf8 out (m_vstrStepFile[m_nStepFile].c_str(), ios_base::app); out << "page " << ++m_nPage << endl; } m_stepFile.open(m_vstrStepFile[m_nStepFile]); } } void FileTracer::setName(const string& strNameRoot) { m_stepFile.close(); m_traceFile.close(); m_bEnabled1 = m_bEnabled2 = false; CB_ASSERT (!strNameRoot.empty()); m_strTraceFile = strNameRoot + "_trace.txt"; m_vstrStepFile.clear(); m_vstrStepFile.push_back(strNameRoot + "_step1.txt"); m_vstrStepFile.push_back(strNameRoot + "_step2.txt"); } /*void FileTracer::removeFilesIfDisabled() { if (!m_bEnabled1 || !m_bEnabled2) { removeFiles(); } }*/ void FileTracer::removeFiles() { m_nStepFile = 0; m_nCrtStepSize = 0; m_nPage = 0; m_nStepLevel = 0; m_nTraceLevel = 0; try { deleteFile(m_strTraceFile); deleteFile(m_vstrStepFile[0]); deleteFile(m_vstrStepFile[1]); } catch (...) { //ttt2 } } void FileTracer::setupFiles() { if (!m_bEnabled1 || !m_bEnabled2) { if (m_bEnabled1) { removeFiles(); } return; } removeFiles(); m_stepFile.open(m_vstrStepFile[0]); m_traceFile.open(m_strTraceFile); traceToFile(convStr(getSystemInfo()), 0); traceLastStep(convStr(getSystemInfo()), 0); } void FileTracer::enable1(bool b) { if (b == m_bEnabled1 || m_vstrStepFile.empty()) { return; } m_bEnabled1 = b; setupFiles(); } void FileTracer::enable2(bool b) { if (b == m_bEnabled2 || m_vstrStepFile.empty()) { return; } m_bEnabled2 = b; setupFiles(); } FileTracer s_fileTracer; } void traceToFile(const string& s, int nLevelChange) { s_fileTracer.traceToFile(s, nLevelChange); } void setupTraceToFile(bool b) { s_fileTracer.enable2(b); } void traceLastStep(const string& s, int nLevelChange) { s_fileTracer.traceLastStep(s, nLevelChange); } //ttt2 add checkbox to uninst on wnd to remove data and settings; //ttt2 uninst should remove log file as well, including the file created when "debug/log transf" is turned on //static QString s_strAssertTitle ("Assertion failure"); //static QString s_strCrashWarnTitle ("Crash detected"); static QString s_qstrErrorMsg; static bool s_bMainAssertOut; static void showAssertMsg(QWidget* pParent) { HtmlMsg::msg(pParent, 0, 0, 0, HtmlMsg::SHOW_SYS_INFO, "Assertion failure", Qt::escape(s_qstrErrorMsg) + "

" + ( s_fileTracer.getStepFiles().empty() ? "Plese report this problem to the project's Issue Tracker at http://sourceforge.net/apps/mantisbt/mp3diags/" : "Please restart the application for instructions about how to report this issue" ) + "

", 750, 300, "Exit"); } void MainFormDlgImpl::showRestartAfterCrashMsg(const QString& qstrText, const QString& qstrCloseBtn) { HtmlMsg::msg(this, 0, 0, 0, HtmlMsg::SHOW_SYS_INFO, "Restarting after crash", qstrText, 750, 450, qstrCloseBtn); } void logAssert(const char* szFile, int nLine, const char* szCond) { //QMessageBox::critical(0, "Assertion failure", QString("Assertion failure in file %1, line %2: %3").arg(szFile).arg(nLine).arg(szCond), QMessageBox::Close); /*QMessageBox dlg (QMessageBox::Critical, "Assertion failure", QString("Assertion failure in file %1, line %2: %3").arg(szFile).arg(nLine).arg(szCond), QMessageBox::Close, getThreadLocalDlgList().getDlg(), Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);*/ s_qstrErrorMsg = QString("Assertion failure in file %1, line %2: %3. The program will exit.").arg(szFile).arg(nLine).arg(szCond); s_fileTracer.enable1(true); s_fileTracer.enable2(true); traceToFile(convStr(s_qstrErrorMsg), 0); qDebug("Assertion failure in file %s, line %d: %s", szFile, nLine, szCond); s_fileTracer.enable1(false); // !!! to avoid logging irrelevant info about cells drawn after the message was shown (there is some risk of not detecting that messages aren't shown although they shoul be, but this has never been reported, while trace files full of FilesModel::headerData and the like are common) MainFormDlgImpl* p (getGlobalDlg()); if (0 != p) { s_bMainAssertOut = false; //QTimer::singleShot(1, p, SLOT(onShowAssert())); //ttt2 see why this doesn't work AssertSender s (p); for (;;) { if (s_bMainAssertOut) { break; } //sleep(1); #ifndef WIN32 timespec ts; ts.tv_sec = 0; ts.tv_nsec = 100000000; // 0.1s nanosleep(&ts, 0); #else Sleep(100); #endif } } else { /*QMessageBox dlg (QMessageBox::Critical, s_strAssertTitle, s_strErrorMsg, QMessageBox::Close, 0, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint); // ttt2 this might fail / crash, as it may be called from a secondary thread dlg.exec();*/ showAssertMsg(0); } } void logAssert(const char* szFile, int nLine, const char* szCond, const std::string& strAddtlInfo) { string s (string(szCond) + "; additional info: " + strAddtlInfo); logAssert(szFile, nLine, s.c_str()); } void MainFormDlgImpl::onShowAssert() { /*QMessageBox dlg (QMessageBox::Critical, s_strAssertTitle, s_strErrorMsg, QMessageBox::Close, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint); dlg.exec();*/ showAssertMsg(this); s_bMainAssertOut = true; } // resizes a dialog with inexisting/invalid size settings, so it covers an area slightly smaller than MainWnd; however, if the dialog is alrady bigger than that, it doesn't get shrinked void defaultResize(QDialog& dlg) { QSize s (dlg.size()); QDialog& mainDlg (*getGlobalDlg()); s.rwidth() = max(s.rwidth(), mainDlg.width() - 100); //ttt2 doesn't do what it should for the case when working with small fonts and small resolutions s.rheight() = max(s.rheight(), mainDlg.height() - 100); dlg.resize(s.width(), s.height()); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== void MainFormDlgImpl::showBackupWarn() { if (m_pCommonData->m_bWarnedAboutBackup) { return; } HtmlMsg::msg(this, 0, 0, &m_pCommonData->m_bWarnedAboutBackup, HtmlMsg::CRITICAL, "Warning", "

Because MP3 Diags changes the content of your MP3 files if asked to, it has a significant destructive potential, especially in cases where the user doesn't read the documentation and simply expects the program to do other things than what it was designed to do.

Therefore, it is highly advisable to back up your files first.

Also, although MP3 Diags is very stable on the developer's computer, who hasn't experienced a crash in a long time and never needed to restore MP3 files from a backup, there are several crash reports that haven't been addressed, as the developer couldn't reproduce the crashes and those who reported the crashes didn't answer the developer's questions that might have helped isolate the problem.

", 520, 300, "O&K"); if (!m_pCommonData->m_bWarnedAboutBackup) { return; } m_settings.saveMiscConfigSettings(m_pCommonData); } void MainFormDlgImpl::showSelWarn() { if (m_pCommonData->m_bWarnedAboutSel) { return; } HtmlMsg::msg(this, 0, 0, &m_pCommonData->m_bWarnedAboutSel, HtmlMsg::DEFAULT, "Note", "If you simply left-click, all the visible files get processed. However, it is possible to process only the selected files. To do that, either keep SHIFT pressed down while clicking or use the right button, as described at http://mp3diags.sourceforge.net/140_main_window_tools.html", 520, 300, "O&K"); //ttt1 different for "unstable" if (!m_pCommonData->m_bWarnedAboutSel) { return; } m_settings.saveMiscConfigSettings(m_pCommonData); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== void MainFormDlgImpl::saveIgnored() { const vector& v (m_pCommonData->getIgnoredNotes()); vector u; for (int i = 0, n = cSize(v); i < n; ++i) { u.push_back(Notes::getNote(v[i])->getDescription()); } m_settings.saveVector("ignored/list", u); } void MainFormDlgImpl::loadIgnored() { bool bRes (true); //ttt2 ? use vector v (m_settings.loadVector("ignored/list", bRes)); vector vnIgnored; vector vstrNotFoundNotes; int n (cSize(v)); if (0 == n) { // use default vnIgnored = Notes::getDefaultIgnoredNoteIds(); } else { for (int i = 0; i < n; ++i) { const string& strDescr (v[i]); //qDebug("%s", strDescr.c_str()); const Note* pNote (Notes::getNote(strDescr)); if (0 == pNote) { vstrNotFoundNotes.push_back(strDescr); } else { vnIgnored.push_back(pNote->getNoteId()); } } } { m_pCommonData->setIgnoredNotes(vnIgnored); int n (cSize(vstrNotFoundNotes)); if (n > 0) { QString s; if (1 == n) { s = "An unknown note was found in the configuration. This note wasn't found:\n\n" + convStr(vstrNotFoundNotes[0]); } else { s = "An unknown note was found in the configuration. These notes weren't found:\n\n"; for (int i = 0; i < n; ++i) { s += convStr(vstrNotFoundNotes[i]); if (i < n - 1) { s += "\n"; } } } QMessageBox::warning(this, "Error setting up the \"ignored notes\" list", s + "\n\nYou may want to check again the list and add any notes that you want to ignore.\n\n(If you didn't change the settings file manually, this is probably due to a code enhanement that makes some notes no longer needed, and you can safely ignore this message.)"); //ttt2 use MP3 Diags icon saveIgnored(); } } } static bool s_bToldAboutSupportInCrtRun (false); // to limit to 1 per run the number of times the user is told about support //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== /* Signals: currentFileChanged() - sent by m_pCommonData->m_pFilesModel and received by both MainFormDlgImpl (to create a new m_pTagDetailsW) and CommonData (to update current notes and streams, which calls m_pStreamsModel->emitLayoutChanged() and m_pNotesModel->emitLayoutChanged()) filterChanged() - sent by m_pCommonData->m_filter and received by m_pCommonData; it updates m_pCommonData->m_vpFltHandlers and calls m_pCommonData->updateWidgets(); updateWidgets() calls m_pFilesModel->selectRow(), which triggers currentFileChanged(), which causes the note and stream grids to be updated // ttt2 finish documenting the signal flow (mainly changing of "current" for both main window and tag editor); then check that it is properly implemented; pay attention to not calling signal handlers directly unless there's a very good reason to do so */ static MainFormDlgImpl* s_pGlobalDlg (0); //ttt2 review this MainFormDlgImpl* getGlobalDlg() { return s_pGlobalDlg; } QWidget* getMainForm() { return getGlobalDlg(); } static PausableThread* s_pSerThread; PausableThread* getSerThread() //ttt2 global function { return s_pSerThread; } namespace { struct SerLoadThread : public PausableThread { CommonData* m_pCommonData; const string& m_strSession; string& m_strErr; SerLoadThread(CommonData* pCommonData, const string& strSession, string& strErr) : m_pCommonData(pCommonData), m_strSession(strSession), m_strErr(strErr) {} /*override*/ void run() { try { CompleteNotif notif(this); bool bAborted (!load()); notif.setSuccess(!bAborted); } catch (...) { LAST_STEP("SerLoadThread::run()"); CB_ASSERT (false); } } bool load() { m_strErr = m_pCommonData->load(SessionEditorDlgImpl::getDataFileName(m_strSession)); //m_pCommonData->m_strTransfLog = SessionEditorDlgImpl::getLogFileName(m_strSession); //{ TRACER("001 m_strTransfLog=" + m_pCommonData->m_strTransfLog); } return true; } }; struct SerSaveThread : public PausableThread { CommonData* m_pCommonData; const string& m_strSession; string& m_strErr; SerSaveThread(CommonData* pCommonData, const string& strSession, string& strErr) : m_pCommonData(pCommonData), m_strSession(strSession), m_strErr(strErr) {} /*override*/ void run() { try { CompleteNotif notif(this); bool bAborted (!load()); notif.setSuccess(!bAborted); } catch (...) { LAST_STEP("SerSaveThread::run()"); CB_ASSERT (false); } } bool load() { m_strErr = m_pCommonData->save(SessionEditorDlgImpl::getDataFileName(m_strSession)); return true; } }; void listKnownFormats() { for (unsigned i = 0x240; i < 1024; ++i) // everything below 0x240 is invalid { unsigned x (0xffe00000); x += (i & 0x300) << (19 - 8); x += (i & 0x0c0) << (17 - 6); x += (i & 0x03c) << (12 - 2); x += (i & 0x003) << (6 - 0); qDebug("%x: %s", x, decodeMpegFrame(x, ", ").c_str()); } } } // namespace extern const char* APP_VER; MainFormDlgImpl::MainFormDlgImpl(const string& strSession, bool bUniqueSession) : QDialog(0, getMainWndFlags()), m_settings(strSession), m_nLastKey(0)/*, m_settings("Ciobi", "Mp3Diags_v01")*/ /*, m_nPrevTabIndex(-1), m_bTagEdtWasEntered(false)*/, m_pCommonData(0), m_strSession(strSession), m_bShowMaximized(false), m_nScanWidth(0), m_pQHttp(0), m_nGlobalX(0), m_nGlobalY(0) { //int x (2); CB_ASSERT(x > 4); //CB_ASSERT("345" == "ab"); //CB_ASSERT(false); s_fileTracer.setName(strSession.substr(0, m_strSession.size() - 4)); // also disables both flags s_pGlobalDlg = 0; setupUi(this); //listKnownFormats(); // ttt2 sizes for many formats seem way too low (e.g. "MPEG-1 Layer I, 44100Hz 32000bps" or "MPEG-2 Layer III, 22050Hz 8000bps") { /*KbdNotifTableView* pStreamsG (new KbdNotifTableView(m_pStreamsG)); connect(pStreamsG, SIGNAL(keyPressed(int)), this, SLOT(onStreamsGKeyPressed(int))); m_pStreamsG = pStreamsG;*/ m_pStreamsG->installEventFilter(this); m_pFilesG->installEventFilter(this); } m_pCommonData = new CommonData(m_settings, m_pFilesG, m_pNotesG, m_pStreamsG, m_pUniqueNotesG, /*m_pCurrentFileG, m_pCurrentAlbumG,*/ /*m_pLogG,*/ /*m_pAssignedB,*/ m_pNoteFilterB, m_pDirFilterB, m_pModeAllB, m_pModeAlbumB, m_pModeSongB, bUniqueSession); m_settings.loadMiscConfigSettings(m_pCommonData); m_pCommonData->m_bScanAtStartup = m_settings.loadScanAtStartup(); string strVersion; m_settings.loadVersion(strVersion); if (strVersion == APP_VER) { bool bDirty; m_settings.loadDbDirty(bDirty); bool bCrashedAtStartup; m_settings.loadCrashedAtStartup(bCrashedAtStartup); if (bDirty || bCrashedAtStartup) { if (m_pCommonData->isTraceToFileEnabled() || fileExists(s_fileTracer.getTraceFile())) // !!! fileExists(s_strTraceFile) allows new asserts to be reported (when m_pCommonData->isTraceToFileEnabled() would still return false) { if (fileExists(s_fileTracer.getTraceFile())) { vector v; if (fileExists(s_fileTracer.getTraceFile())) { v.push_back(s_fileTracer.getTraceFile()); } if (fileExists(s_fileTracer.getStepFiles()[0])) { v.push_back(s_fileTracer.getStepFiles()[0]); } if (fileExists(s_fileTracer.getStepFiles()[1])) { v.push_back(s_fileTracer.getStepFiles()[1]); } CB_ASSERT (!v.empty()); // really v should have at least 2 elements QString qs (v.size() > 1 ? "files" : "file"); qs += " " + Qt::escape(toNativeSeparators(convStr(v[0]))) + ""; if (v.size() > 1) { qs += (v.size() > 2 ? "," : " and"); qs += " " + Qt::escape(toNativeSeparators(convStr(v[1]))) + ""; if (v.size() > 2) { qs += ", and"; qs += " " + Qt::escape(toNativeSeparators(convStr(v[2]))) + ""; } } if (v.size() > 1) { showRestartAfterCrashMsg("

MP3 Diags is restarting after a crash. Information in the " + qs + " may help identify the cause of the crash, so please make them available to the developer by mailing them to ciobi@inbox.com, by reporting an issue to the project's Issue Tracker at http://sourceforge.net/apps/mantisbt/mp3diags/ and attaching the files to the report, or by some other means (like putting them on a file sharing site.)

These are plain text files, which you can review before sending, if you have privacy concerns.

After getting the files, the developer will probably want to contact you for more details, so please check back on the status of your report.

Note that these files will be removed when you close this window.

" + (m_pCommonData->isTraceToFileEnabled() ? "

If there is a name of an MP3 file at the end of " + Qt::escape(toNativeSeparators(convStr(v[0]))) + ", that might be a file that consistently causes a crash. Please check if it is so. Then, if confirmed, please make that file available by mailing it to ciobi@inbox.com or by putting it on a file sharing site.

" : "

Please also try to repeat the steps that led to the crash before reporting the crash, which will probably result in a new set of files being generated; these files are more likely to contain relevant information than the current set of files, because they will also have information on what happened before the crash, while the current files only tell where the crash occured.

") + "

You should include in your report any other details that seem relevant (what might have caused the failure, steps to reproduce it, ...)

", "Remove these files and continue"); //ttt3 as of 2009.10.24 there are 2 files that are expected to be found here, though sometimes there may be 3; if this is cut down to 1, a "them => it" would be needed } } else { showRestartAfterCrashMsg("

MP3 Diags is restarting after a crash. There was supposed to be some information about what led to the crash in the file " + Qt::escape(toNativeSeparators(convStr(s_fileTracer.getTraceFile()))) + ", but that file cannot be found. Please report this issue to the project's Issue Tracker at http://sourceforge.net/apps/mantisbt/mp3diags/

The developer will probably want to contact you for more details, so please check back on the status of your report.

Make sure to include the data below, as well as any other detail that seems relevant (what might have caused the failure, steps to reproduce it, ...)

", "OK"); } } if (!m_pCommonData->isTraceToFileEnabled()) { showRestartAfterCrashMsg("

MP3 Diags is restarting after a crash. To help determine the reason for the crash, the Log program state to _trace and _step files option has been activated. This logs to 3 files what the program is doing, which might make it slightly slower.

It is recommended to not process more than several thousand MP3 files while this option is turned on. You can turn it off manually, in the configuration dialog, in the Others tab, but keeping it turned on may provide very useful feedback to the developer, should the program crash again. With this feedback, future versions of MP3 Diags will get closer to being bug free.

", "OK"); m_pCommonData->setTraceToFile(true); m_settings.saveMiscConfigSettings(m_pCommonData); } // !!! don't change "dirty"; 1) there's no point; 2) ser needs it } // !!! nothing to do if not dirty } else { // it's a new version, so we start over //ttt2 perhaps also use some counter, like "20 runs without crash" m_pCommonData->setTraceToFile(false); m_settings.saveMiscConfigSettings(m_pCommonData); } #ifdef LOG_ANYWAY s_fileTracer.enable2(true); #else s_fileTracer.enable2(m_pCommonData->isTraceToFileEnabled()); // this might get called a second time (the first time is from within m_pCommonData->setTraceToFile()), but that's OK #endif s_fileTracer.enable1(true); // !!! after loadMiscConfigSettings(), so the previous files aren't deleted too early m_settings.saveVersion(APP_VER); TRACER("MainFormDlgImpl constr"); { m_pCommonData->m_pFilesModel = new FilesModel(m_pCommonData); m_pFilesG->setModel(m_pCommonData->m_pFilesModel); FilesGDelegate* pDel (new FilesGDelegate(m_pCommonData, m_pFilesG)); m_pFilesG->setItemDelegate(pDel); m_pFilesG->setHorizontalHeader(new FileHeaderView(m_pCommonData, m_pFilesG)); m_pFilesG->horizontalHeader()->setMinimumSectionSize(CELL_WIDTH); m_pFilesG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pFilesG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); connect(m_pFilesG->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), m_pCommonData->m_pFilesModel, SLOT(onFilesGSelChanged())); connect(m_pFilesG, SIGNAL(clicked(const QModelIndex &)), m_pCommonData->m_pFilesModel, SLOT(onFilesGSelChanged())); m_pFilesG->horizontalHeader()->setDefaultSectionSize(CELL_WIDTH); m_pFilesG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); m_pFilesG->verticalHeader()->setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter); connect(m_pCommonData->m_pFilesModel, SIGNAL(currentFileChanged()), this, SLOT(onCrtFileChanged())); connect(m_pCommonData->m_pFilesModel, SIGNAL(currentFileChanged()), m_pCommonData, SLOT(onCrtFileChanged())); } { m_pCommonData->m_pNotesModel = new NotesModel(m_pCommonData); m_pNotesG->setModel(m_pCommonData->m_pNotesModel); NotesGDelegate* pNotesGDelegate = new NotesGDelegate(m_pCommonData); m_pNotesG->setItemDelegate(pNotesGDelegate); m_pNotesG->horizontalHeader()->setMinimumSectionSize(CELL_WIDTH + 10); m_pNotesG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pNotesG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); m_pNotesG->verticalHeader()->setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter); connect(m_pNotesG->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), m_pCommonData->m_pNotesModel, SLOT(onNotesGSelChanged())); connect(m_pNotesG, SIGNAL(clicked(const QModelIndex &)), m_pCommonData->m_pNotesModel, SLOT(onNotesGSelChanged())); connect(m_pNotesG->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), m_pNotesG, SLOT(resizeRowsToContents())); } { m_pCommonData->m_pStreamsModel = new StreamsModel(m_pCommonData); m_pStreamsG->setModel(m_pCommonData->m_pStreamsModel); StreamsGDelegate* pStreamsGDelegate = new StreamsGDelegate(m_pCommonData); m_pStreamsG->setItemDelegate(pStreamsGDelegate); m_pStreamsG->horizontalHeader()->setMinimumSectionSize(CELL_WIDTH + 10); m_pStreamsG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pStreamsG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); m_pStreamsG->verticalHeader()->setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter); connect(m_pStreamsG->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), m_pCommonData->m_pStreamsModel, SLOT(onStreamsGSelChanged())); connect(m_pStreamsG, SIGNAL(clicked(const QModelIndex &)), m_pCommonData->m_pStreamsModel, SLOT(onStreamsGSelChanged())); connect(m_pStreamsG->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), m_pStreamsG, SLOT(resizeRowsToContents())); } { m_pCommonData->m_pUniqueNotesModel = new UniqueNotesModel(m_pCommonData); m_pUniqueNotesG->setModel(m_pCommonData->m_pUniqueNotesModel); UniqueNotesGDelegate* pDel = new UniqueNotesGDelegate(m_pCommonData); m_pUniqueNotesG->setItemDelegate(pDel); m_pUniqueNotesG->horizontalHeader()->setMinimumSectionSize(CELL_WIDTH + 10); m_pUniqueNotesG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pUniqueNotesG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); m_pUniqueNotesG->verticalHeader()->setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter); connect(m_pUniqueNotesG->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), m_pUniqueNotesG, SLOT(resizeRowsToContents())); } m_pTagDetailsLayout = new QHBoxLayout(m_pTagDetailsTab); m_pTagDetailsTab->setLayout(m_pTagDetailsLayout); m_pTagDetailsW = new QWidget(m_pTagDetailsTab); m_pTagDetailsLayout->addWidget(m_pTagDetailsW); //m_pTagDetailsLayout->setContentsMargins(1, 1, 1, 1); //m_pTagDetailsLayout->setContentsMargins(6, 6, 6, 6); m_pTagDetailsLayout->setContentsMargins(0, 0, 0, 0); /*connect(m_pFilesG->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), m_pCommonData->m_pFilesModel, SLOT(onFilesGSelChanged())); //ttt2 see if needed (in addition to selectionChanged); apparently not: this signal is sent "the next time", so first clicking in a grid doesn't send any message, regardless of what was "current" before; then, when the message is sent, the value in the model is not yet updated, so using "m_pCommonData->m_pNotesG->selectionModel()->selection().indexes()" returns the indexes from the last time; perhaps using the first QModelIndex parameter would allow getting to the "current" cell, but not to the whole selection anyway; connect(m_pNotesG->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), m_pCommonData->m_pNotesModel, SLOT(onNotesGSelChanged())); connect(m_pStreamsG->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), m_pCommonData->m_pStreamsModel, SLOT(onStreamsGSelChanged()));*/ /* !!! There's this use case: 1) the user selects a file that has multiple instances of the same error 2) the user clicks on one of the duplicates errors in m_pNotesG; the corresponding cell in m_pFilesG gets selected; 3) the user clicks on the selected cell in m_pFilesG; both of the duplicate errors should get selected; If nothing is done, nothing happens, and just one error stays selected; making m_pFilesG's current be (-1,-1) in FilesModel::matchSelToNotes() doesn't work anyaway because this doesn't change the selection either and it messes up keyboard navigation (assuming that it can be done). Instead, m_pFilesG's clicked() signal is connected to onFilesGSelChanged(). */ //cout << convStr(m_settings.fileName()) << endl; { ModifInfoToolButton* p (new ModifInfoToolButton(m_pCustomTransform1B)); m_vpTransfButtons.push_back(p); connect(p, SIGNAL(clicked()), this, SLOT(on_m_pCustomTransform1B_clicked())); m_pCustomTransform1B = p; } { ModifInfoToolButton* p (new ModifInfoToolButton(m_pCustomTransform2B)); m_vpTransfButtons.push_back(p); connect(p, SIGNAL(clicked()), this, SLOT(on_m_pCustomTransform2B_clicked())); m_pCustomTransform2B = p; } { ModifInfoToolButton* p (new ModifInfoToolButton(m_pCustomTransform3B)); m_vpTransfButtons.push_back(p); connect(p, SIGNAL(clicked()), this, SLOT(on_m_pCustomTransform3B_clicked())); m_pCustomTransform3B = p; } { ModifInfoToolButton* p (new ModifInfoToolButton(m_pCustomTransform4B)); m_vpTransfButtons.push_back(p); connect(p, SIGNAL(clicked()), this, SLOT(on_m_pCustomTransform4B_clicked())); m_pCustomTransform4B = p; } // CUSTOM_TRANSF_CNT { m_pModifNormalizeB = new ModifInfoToolButton(m_pNormalizeB); connect(m_pModifNormalizeB, SIGNAL(clicked()), this, SLOT(on_m_pNormalizeB_clicked())); m_pNormalizeB = m_pModifNormalizeB; } { m_pModifReloadB = new ModifInfoToolButton(m_pReloadB); connect(m_pModifReloadB, SIGNAL(clicked()), this, SLOT(on_m_pReloadB_clicked())); m_pReloadB = m_pModifReloadB; } { m_pModifRenameFilesB = new ModifInfoToolButton(m_pRenameFilesB); connect(m_pModifRenameFilesB, SIGNAL(clicked()), this, SLOT(on_m_pRenameFilesB_clicked())); m_pRenameFilesB = m_pModifRenameFilesB; } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } /*{ QAction* p (new QAction(this)); p->setShortcut(QKeySequence("Ctrl+N")); connect(p, SIGNAL(triggered()), this, SLOT(onNext())); addAction(p); } //p->setShortcutContext(Qt::ApplicationShortcut); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("Ctrl+P")); connect(p, SIGNAL(triggered()), this, SLOT(onPrev())); addAction(p); } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("Ctrl+V")); connect(p, SIGNAL(triggered()), this, SLOT(onPaste())); addAction(p); } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("Ctrl+S")); connect(p, SIGNAL(triggered()), this, SLOT(on_m_pScanB_clicked())); addAction(p); }*/ //{ QAction* p (new QAction(this)); p->setShortcut(QKeySequence(Qt::Key_Escape)); connect(p, SIGNAL(triggered()), this, SLOT(emptySlot())); addAction(p); } // !!! 2009.01.13 - no longer usable, because this also prevents edits in QTableView from exiting with ESC; so the m_nLastKey alternative is used; // 2009.03.31 - probably usable again, since the tag editor got moved to a separate window //m_pCurrentAlbumG->setEditTriggers(QAbstractItemView::AllEditTriggers);//EditKeyPressed); loadIgnored(); { if (!m_settings.loadTransfConfig(m_transfConfig)) { m_settings.saveTransfConfig(m_transfConfig); } for (int i = 0; i < CUSTOM_TRANSF_CNT; ++i) { loadCustomTransf(i); } } //ttt2 perhaps have "experimental" transforms, different color (or just have the names begin with "experimental") { loadVisibleTransf(); if (m_pCommonData->getVisibleTransf().empty()) { vector v; initDefaultVisibleTransf(v, m_pCommonData); m_pCommonData->setVisibleTransf(v); } } { initializeUi(); } setTransfTooltips(); { delete m_pRemovableL; delete m_pLowerHalfTablesW->layout(); m_pLowerHalfLayout = new QStackedLayout(m_pLowerHalfTablesW); //m_pLowerHalfLayout->setContentsMargins(0, 50, 50, 0); //m_pLowerHalfTablesW->setLayout(m_pLowerHalfLayout); m_pLowerHalfLayout->addWidget(m_pFileInfoTab); m_pLowerHalfLayout->addWidget(m_pAllNotesTab); m_pLowerHalfLayout->addWidget(m_pTagDetailsTab); delete m_pDetailsTabWidget; int nHeight (QApplication::fontMetrics().height() + 7); m_pLowerHalfBtnW->setMinimumHeight(nHeight); m_pLowerHalfBtnW->setMaximumHeight(nHeight); } connect(this, SIGNAL(tagEditorClosed()), m_pCommonData, SLOT(onFilterChanged())); // !!! needed because CommonData::mergeHandlerChanges() adds changed files that shouldn't normally be there in album / filter mode; the reason it does this is to allow comparisons after making changes, but this doesn't make much sense when those changes are done in the tag editor, (saving in the tag editor is different from regular transformations because album navigation is allowed) s_pGlobalDlg = this; { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("Ctrl+A")); connect(p, SIGNAL(triggered()), this, SLOT(emptySlot())); addAction(p); } // !!! needed because it takes a lot of time, during which the app seems frozen (caused by the cells being selected and unselected automatically) // ttt2 see if possible to disable selecting "note" cells with SHIFT pressed QTimer::singleShot(1, this, SLOT(onShow())); } /*override*/ void MainFormDlgImpl::keyPressEvent(QKeyEvent* pEvent) { //qDebug("key prs %x", pEvent->key()); m_nLastKey = pEvent->key(); pEvent->ignore(); } void MainFormDlgImpl::onHelp() { if (m_pViewFileInfoB->isChecked()) { openHelp("130_main_window.html"); } else if (m_pViewAllNotesB->isChecked()) { openHelp("150_main_window_all_notes.html"); } else if (m_pViewTagDetailsB->isChecked()) { openHelp("160_main_window_tag_details.html"); } else { CB_ASSERT(false); } } /*override*/ void MainFormDlgImpl::keyReleaseEvent(QKeyEvent* pEvent) { //qDebug("key rel %d", pEvent->key()); if (Qt::Key_Escape == pEvent->key()) { //on_m_pAbortB_clicked(); pEvent->ignore(); } else { QDialog::keyReleaseEvent(pEvent); } //pEvent->ignore(); // ttt2 not sure this is the way to do it, but the point is to disable the ESC key } void MainFormDlgImpl::initializeUi() { int nWidth, nHeight; int nNotesGW0, nNotesGW2, nStrmsGW0, nStrmsGW1, nStrmsGW2, nStrmsGW3, nUnotesGW0; int nIconSize; QByteArray stateMainSpl, stateLwrSpl; m_settings.loadMainSettings(nWidth, nHeight, nNotesGW0, nNotesGW2, nStrmsGW0, nStrmsGW1, nStrmsGW2, nStrmsGW3, nUnotesGW0, stateMainSpl, stateLwrSpl, nIconSize, m_nScanWidth); if (m_nScanWidth <= 400) { QRect r (QApplication::desktop()->availableGeometry()); m_nScanWidth = min(1600, r.width()); if (m_nScanWidth > 1200) { m_nScanWidth = m_nScanWidth*3/4; } else { m_nScanWidth = m_nScanWidth*4/5; } //qDebug("%d %d %d %d", r.x(), r.y(), r.width(), r.height()); } if (nWidth > 400 && nHeight > 400) { QRect r (QApplication::desktop()->availableGeometry()); const int nApprox (16); #ifndef WIN32 int nTitleHeight(0); #else int nTitleHeight(GetSystemMetrics(SM_CYSIZE)); // ttt2 actually there's a pixel missing but not obvious where to get it from; nApprox should allow enough tolerance, though #endif if (r.width() - nWidth < nApprox && r.height() - nHeight - nTitleHeight < nApprox) { m_bShowMaximized = true; } else { resize(nWidth, nHeight); } } else { //QRect r (QApplication::desktop()->availableGeometry()); //qDebug("%d %d %d %d", r.x(), r.y(), r.width(), r.height()); m_bShowMaximized = true; // ttt2 perhaps implement m_bShowMaximized for all windows } m_pCommonData->m_nMainWndIconSize = nIconSize; { if (nNotesGW0 < CELL_WIDTH + 8) { nNotesGW0 = CELL_WIDTH + 8; } if (nNotesGW2 < 10) { nNotesGW2 = 65; } m_pNotesG->horizontalHeader()->resizeSection(0, nNotesGW0); // ttt2 apparently a call to resizeColumnsToContents() in NotesModel::updateCurrentNotes() should make columns 0 and 2 have the right size, but that's not the case at all; (see further notes there) m_pNotesG->horizontalHeader()->resizeSection(2, nNotesGW2); m_pNotesG->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch); //m_pNotesG->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch); } { if (nStrmsGW0 < 10) { nStrmsGW0 = 80; } // ttt2 "80" hard-coded if (nStrmsGW1 < 10) { nStrmsGW1 = 80; } if (nStrmsGW2 < 10) { nStrmsGW2 = 80; } if (nStrmsGW3 < 10) { nStrmsGW3 = 110; } m_pStreamsG->horizontalHeader()->resizeSection(0, nStrmsGW0); m_pStreamsG->horizontalHeader()->resizeSection(1, nStrmsGW1); m_pStreamsG->horizontalHeader()->resizeSection(2, nStrmsGW2); m_pStreamsG->horizontalHeader()->resizeSection(3, nStrmsGW3); m_pStreamsG->horizontalHeader()->setResizeMode(4, QHeaderView::Stretch); } { if (nUnotesGW0 < CELL_WIDTH + 8) { nUnotesGW0 = CELL_WIDTH + 8; } // ttt2 replace CELL_WIDTH m_pUniqueNotesG->horizontalHeader()->resizeSection(0, nUnotesGW0); m_pUniqueNotesG->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch); } { if (!stateMainSpl.isNull()) { m_pMainSplitter->restoreState(stateMainSpl); } m_pMainSplitter->setOpaqueResize(false); if (!stateLwrSpl.isNull()) { m_pLowerSplitter->restoreState(stateLwrSpl); } } m_pCrtDirE->setFocus(); if (!m_pCommonData->m_bShowExport) { m_pExportB->hide(); } if (!m_pCommonData->m_bShowDebug) { m_pDebugB->hide(); } if (!m_pCommonData->m_bShowSessions) { m_pSessionsB->hide(); if (!m_pCommonData->m_bShowExport) { m_pOptBtn1W->hide(); } } resizeIcons(); } void MainFormDlgImpl::onShow() { TRACER("MainFormDlgImpl::onShow()"); bool bLoadErr (false); bool bCrashedAtStartup; m_pCommonData->m_strTransfLog = SessionEditorDlgImpl::getLogFileName(m_strSession); m_settings.loadCrashedAtStartup(bCrashedAtStartup); if (bCrashedAtStartup) { QMessageBox::critical(this, "Error", "MP3 Diags crashed while reading song data from the disk. The whole collection will be rescanned."); } else { m_settings.saveCrashedAtStartup(true); string strErr; SerLoadThread* p (new SerLoadThread(m_pCommonData, m_strSession, strErr)); ThreadRunnerDlgImpl dlg (this, getNoResizeWndFlags(), p, ThreadRunnerDlgImpl::SHOW_COUNTER, ThreadRunnerDlgImpl::TRUNCATE_BEGIN, ThreadRunnerDlgImpl::HIDE_PAUSE_ABORT); CB_ASSERT (m_nScanWidth > 400); dlg.resize(m_nScanWidth, dlg.height()); dlg.setWindowIcon(QIcon(":/images/logo.svg")); dlg.setWindowTitle("Loading data"); s_pSerThread = p; dlg.exec(); s_pSerThread = 0; m_nScanWidth = dlg.width(); m_pCommonData->setCrtAtStartup(); if (!strErr.empty()) { bLoadErr = true; QMessageBox::critical(this, "Error", "An error occured while loading the MP3 information. Your files will be rescanned.\n\n" + convStr(strErr)); } } m_settings.saveCrashedAtStartup(false); bool bDirty; m_settings.loadDbDirty(bDirty); if (bDirty) { /*s_strErrorMsg = "Rescanning files after crash."; showErrorDlg(this, false);*/ if (m_transfConfig.m_options.m_bKeepOrigTime) { QMessageBox::warning(this, "Warning", "It seems that MP3 Diags is restarting after a crash. Your files will be rescanned.\n\n(Since this may take a long time for large collections, you may want to abort the full rescanning and apply a filter to include only the files that you changed since the last time the program closed correctly, then manually rescan only those files.)"); } else { bDirty = false; // !!! if original time is not kept, any changes will be detected anyway, no need to force a full reload } } m_settings.saveDbDirty(true); if (m_pCommonData->m_bScanAtStartup || bDirty) { fullReload(bDirty || bLoadErr || bCrashedAtStartup ? FORCE : DONT_FORCE); } resizeEvent(0); // !!! without these the the file grid may look bad if it has a horizontal scrollbar and one of the last files is current string strCrt (m_pCommonData->getCrtName()); m_pFilesG->setCurrentIndex(m_pFilesG->model()->index(0, 0)); m_pCommonData->updateWidgets(strCrt); #ifndef DISABLE_CHECK_FOR_UPDATES checkForNewVersion(); #endif } void MainFormDlgImpl::fullReload(bool bForceReload) { CommonData::ViewMode eMode (m_pCommonData->getViewMode()); m_pCommonData->setViewMode(CommonData::ALL, m_pCommonData->getCrtMp3Handler()); m_pCommonData->m_filter.disableAll(); reload(IGNORE_SEL, bForceReload); m_pCommonData->m_filter.restoreAll(); m_pCommonData->setViewMode(eMode, m_pCommonData->getCrtMp3Handler()); } /*override*/ void MainFormDlgImpl::closeEvent(QCloseEvent*) { string strErr; SerSaveThread* p (new SerSaveThread(m_pCommonData, m_strSession, strErr)); //Qt::WindowStaysOnTopHint ThreadRunnerDlgImpl dlg (this, getNoResizeWndFlags(), p, ThreadRunnerDlgImpl::SHOW_COUNTER, ThreadRunnerDlgImpl::TRUNCATE_BEGIN, ThreadRunnerDlgImpl::HIDE_PAUSE_ABORT); CB_ASSERT (m_nScanWidth > 400); dlg.resize(m_nScanWidth, dlg.height()); dlg.setWindowIcon(QIcon(":/images/logo.svg")); dlg.setWindowTitle("Saving data"); s_pSerThread = p; dlg.exec(); s_pSerThread = 0; m_nScanWidth = dlg.width(); if (!strErr.empty()) { QMessageBox::critical(this, "Error", "An error occured while saving the MP3 information. You will have to scan your files again.\n\n" + convStr(strErr)); } } MainFormDlgImpl::~MainFormDlgImpl() { TRACER("MainFormDlgImpl destr"); s_pGlobalDlg = 0; m_settings.saveMainSettings( width(), height(), m_pNotesG->horizontalHeader()->sectionSize(0), m_pNotesG->horizontalHeader()->sectionSize(2), m_pStreamsG->horizontalHeader()->sectionSize(0), m_pStreamsG->horizontalHeader()->sectionSize(1), m_pStreamsG->horizontalHeader()->sectionSize(2), m_pStreamsG->horizontalHeader()->sectionSize(3), m_pUniqueNotesG->horizontalHeader()->sectionSize(0), m_pMainSplitter->saveState(), m_pLowerSplitter->saveState(), m_pCommonData->m_nMainWndIconSize, m_nScanWidth ); m_settings.saveDbDirty(false); // !!! it would seem better to delay marking the data clean until a full reload is completed; however, if the user aborted the rescan, it was probably for a good reason (e.g. to rescan only a part of the files), so it makes more sense to mark the data as clean regardless of how it was when it was loaded and if the rescan completed or not //QMessageBox dlg (this); dlg.show(); //CursorOverrider crs;// (Qt::ArrowCursor); delete m_pCommonData; } void SessionSettings::saveDbDirty(bool bDirty) { m_pSettings->setValue("main/dirty", bDirty); m_pSettings->sync(); } void SessionSettings::loadDbDirty(bool& bDirty) { bDirty = m_pSettings->value("main/dirty", false).toBool(); } void SessionSettings::saveCrashedAtStartup(bool bCrashedAtStartup) { m_pSettings->setValue("debug/crashedAtStartup", bCrashedAtStartup); m_pSettings->sync(); } void SessionSettings::loadCrashedAtStartup(bool& bCrashedAtStartup) { bCrashedAtStartup = m_pSettings->value("debug/crashedAtStartup", false).toBool(); } void SessionSettings::saveVersion(const string& strVersion) { m_pSettings->setValue("main/version", convStr(strVersion)); } void SessionSettings::loadVersion(string& strVersion) { strVersion = convStr(m_pSettings->value("main/version", "x").toString()); } MainFormDlgImpl::CloseOption MainFormDlgImpl::run() { if (m_bShowMaximized) { showMaximized(); } return QDialog::Accepted == exec() ? OPEN_SESS_DLG : EXIT; } void MainFormDlgImpl::onCrtFileChanged() { delete m_pTagDetailsW; m_pTagDetailsW = new QWidget(m_pTagDetailsTab); m_pTagDetailsLayout->addWidget(m_pTagDetailsW); int nCrtFile (m_pCommonData->getFilesGCrtRow()); if (-1 == nCrtFile) { m_pCrtDirE->setText(""); return; } QHBoxLayout* pLayout = new QHBoxLayout(); pLayout->setSpacing(12); //pLayout->setContentsMargins(6, 6, 6, 6); pLayout->setContentsMargins(1, 1, 1, 1); m_pTagDetailsW->setLayout(pLayout); //pLayout->setSpacing(1); const Mp3Handler* pMp3Handler (m_pCommonData->getViewHandlers()[nCrtFile]); const vector& vpStreams (pMp3Handler->getStreams()); if (m_pViewTagDetailsB->isChecked()) { for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* pStream (vpStreams[i]); TagReader* pReader (dynamic_cast(pStream)); if (0 != pReader) { TagReadPanel* pPanel (new TagReadPanel(m_pTagDetailsW, pReader)); pLayout->addWidget(pPanel, 10); } } } QString qs (toNativeSeparators(convStr(m_pCommonData->getViewHandlers()[nCrtFile]->getDir()))); #ifndef WIN32 #else if (2 == qs.size() && ':' == qs[1]) { qs += "\\"; } #endif m_pCrtDirE->setText(qs); pLayout->addStretch(0); } /*override*/ void MainFormDlgImpl::resizeEvent(QResizeEvent* pEvent) { if (m_pCommonData->m_bAutoSizeIcons || m_pCommonData->m_nMainWndIconSize < 16) { //const QRect& r (QApplication::desktop()->availableGeometry()); int w (width()); int k (w <= 800 ? 28 : w <= 1180 ? 32 : w <= 1400 ? 40 : w <= 1600 ? 48 : w <= 1920 ? 56 : 64); m_pCommonData->m_nMainWndIconSize = k; resizeIcons(); } m_pCommonData->resizeFilesGCols(); m_pUniqueNotesG->resizeRowsToContents(); m_pNotesG->resizeRowsToContents(); m_pStreamsG->resizeRowsToContents(); QDialog::resizeEvent(pEvent); } namespace { struct Mp3ProcThread : public PausableThread { FileEnumerator& m_fileEnum; bool m_bForce; CommonData* m_pCommonData; vector m_vpAdd, m_vpDel; deque m_vpExisting; // some (or all) of these will may get copied to m_vpDel vector m_vpKeep; // subset of m_vpExisting Mp3ProcThread(FileEnumerator& fileEnum, bool bForce, CommonData* pCommonData, deque vpExisting) : m_fileEnum(fileEnum), m_bForce(bForce), m_pCommonData(pCommonData), m_vpExisting(vpExisting) {} /*override*/ void run() { try { CompleteNotif notif(this); bool bAborted (!scan()); if (!bAborted) { sort(m_vpKeep.begin(), m_vpKeep.end(), CmpMp3HandlerPtrByName()); set_difference(m_vpExisting.begin(), m_vpExisting.end(), m_vpKeep.begin(), m_vpKeep.end(), back_inserter(m_vpDel), CmpMp3HandlerPtrByName()); } notif.setSuccess(!bAborted); } catch (...) { LAST_STEP("Mp3ProcThread::run()"); CB_ASSERT (false); } } bool scan(); }; // a subset of m_vpExisting gets copied to m_vpDel; so if m_vpExisting is empty, m_vpDel will be empty too; bool Mp3ProcThread::scan() { //cout << "################### procRec(" << strDir << ")\n"; //FileSearcher fs ((strDir + "/*").c_str()); m_fileEnum.reset(); for (;;) { string strName (m_fileEnum.next()); if (strName.empty()) { return true; } QString qs; if (strName.size() > 4) { qs = convStr(strName.substr(strName.size() - 4)).toLower(); } if (qs == ".mp3" || qs == ".id3") { if (isAborted()) { return false; } checkPause(); StrList l; l.push_back(toNativeSeparators(convStr(strName))); emit stepChanged(l, -1); if (!m_bForce) { deque::iterator it (lower_bound(m_vpExisting.begin(), m_vpExisting.end(), strName, CmpMp3HandlerPtrByName())); if (m_vpExisting.end() != it && (*it)->getName() == strName && !(*it)->needsReload(Mp3Handler::DONT_USE_FAST_SAVE)) { m_vpKeep.push_back(*it); continue; } } try { const Mp3Handler* p (new Mp3Handler(strName, m_pCommonData->m_bUseAllNotes, m_pCommonData->getQualThresholds())); m_vpAdd.push_back(p); } catch (const Mp3Handler::FileNotFound&) //ttt2 see if it should catch more { } } } } } // namespace //ttt2 perhaps: Too many notes that you don't care about are cluttering your screen? You can hide such notes, so you don't see them again. To do this, open the configuration dialog and go to the "Ignored notes" tab. See more details at ... //ttt2 album detection: folder / tags /both void MainFormDlgImpl::scan(FileEnumerator& fileEnum, bool bForce, deque vpExisting, int nKeepWhenUpdate) { m_pCommonData->clearLog(); //m_pModeAllB->setChecked(true); vector vpAdd, vpDel; { Mp3ProcThread* p (new Mp3ProcThread(fileEnum, bForce, m_pCommonData, vpExisting)); ThreadRunnerDlgImpl dlg (this, getNoResizeWndFlags(), p, ThreadRunnerDlgImpl::SHOW_COUNTER, ThreadRunnerDlgImpl::TRUNCATE_BEGIN); CB_ASSERT (m_nScanWidth > 400); dlg.resize(m_nScanWidth, dlg.height()); dlg.setWindowIcon(QIcon(":/images/logo.svg")); dlg.setWindowTitle("Scanning MP3 files"); dlg.exec(); //ttt2 perhaps see if it ended with ok/reject and clear all on reject m_nScanWidth = dlg.width(); vpAdd = p->m_vpAdd; vpDel = p->m_vpDel; } m_pCommonData->mergeHandlerChanges(vpAdd, vpDel, nKeepWhenUpdate); if (!m_pCommonData->m_bToldAboutSupport && !s_bToldAboutSupportInCrtRun) { const vector& v (m_pCommonData->getUniqueNotes().getFltVec()); vector::const_iterator it (lower_bound(v.begin(), v.end(), &Notes::unsupportedFound(), CmpNotePtrById())); if (v.end() != it && &Notes::unsupportedFound() == *it) { s_bToldAboutSupportInCrtRun = true; HtmlMsg::msg(this, 0, 0, &m_pCommonData->m_bToldAboutSupport, HtmlMsg::DEFAULT, "Info", "

Your files are not fully supported by the current version of MP3 Diags. The main reason for this is that the developer is aware of some MP3 features but doesn't have actual MP3 files to implement support for those features and test the code.

" "

You can help improve MP3 Diags by making files with unsupported notes available to the developer. The preferred way to do this is to report an issue on the project's Issue Tracker at http://sourceforge.net/apps/mantisbt/mp3diags/, after checking if others made similar files available. To actually send the files, you can mail them to ciobi@inbox.com or put them on a file sharing site. It would be a good idea to make sure that you have the latest version of MP3 Diags.

" "

You can identify unsupported notes by the blue color that is used for their labels.

", 750, 300, "OK"); if (m_pCommonData->m_bToldAboutSupport) { m_settings.saveMiscConfigSettings(m_pCommonData); } } } } void MainFormDlgImpl::on_m_pScanB_clicked() { bool bForce; bool bOk; { ScanDlgImpl dlg (this, m_pCommonData); bOk = dlg.run(bForce); } if (!bOk) { return; } scan(bForce); } void MainFormDlgImpl::scan(bool bForce) { long nPrevMem(getMemUsage()); m_pCommonData->m_filter.disableNote(); m_pCommonData->m_filter.setDirs(vector()); m_pCommonData->setViewMode(CommonData::ALL); //scan(m_pCommonData->m_dirTreeEnum, bForce, m_pCommonData->getViewHandlers(), CommonData::SEL | CommonData::CURRENT); scan(m_pCommonData->m_dirTreeEnum, bForce, m_pCommonData->getViewHandlers(), CommonData::NOTHING); long nCrtMem(getMemUsage()); ostringstream out; time_t t (time(0)); out << "current memory used by the whole program: " << nCrtMem << "; memory used by the current data (might be very inaccurate): " << nCrtMem - nPrevMem << "; time: " << ctime(&t); string s (out.str()); s.erase(s.size() - 1); // needed because ctime() uses a terminating '\n' qDebug("%s", s.c_str()); trace(""); trace("************************* " + s); //exportAsText(); } void MainFormDlgImpl::on_m_pNoteFilterB_clicked() { if (m_pCommonData->m_filter.isNoteEnabled()) { m_pCommonData->m_filter.disableNote(); return; } NoteFilterDlgImpl dlg (m_pCommonData, this); if (QDialog::Accepted == dlg.exec()) { // !!! no need to do anything with m_pCommonData->m_filter, because dlg.exec() took care of that } else { m_pNoteFilterB->setChecked(false); // !!! no guard needed, because the event that calls the filter is "clicked", not "checked" } } void MainFormDlgImpl::on_m_pDirFilterB_clicked() { if (m_pCommonData->m_filter.isDirEnabled()) { m_pCommonData->m_filter.disableDir(); return; } DirFilterDlgImpl dlg (m_pCommonData, this); if (QDialog::Accepted == dlg.exec()) { // !!! no need to do anything with m_pCommonData->m_filter, because dlg.exec() took care of that } else { m_pDirFilterB->setChecked(false); // !!! no guard needed, because the event that calls the filter is "clicked", not "checked" } } //ttt2 ? operation to "add null frame", which would allow to rescue some frames in case of overwriting void MainFormDlgImpl::saveCustomTransf(int k) { const vector& v (m_pCommonData->getCustomTransf()[k]); int n (cSize(v)); vector vstrActionNames; for (int i = 0; i < n; ++i) { vstrActionNames.push_back(m_pCommonData->getAllTransf()[v[i]]->getActionName()); } char bfr [50]; sprintf(bfr, "customTransf/set%04d", k); m_settings.saveVector(bfr, vstrActionNames); } void MainFormDlgImpl::loadCustomTransf(int k) { char bfr [50]; sprintf(bfr, "customTransf/set%04d", k); //vector vstrNames (m_settings.loadCustomTransf(k)); bool bErr; vector vstrNames (m_settings.loadVector(bfr, bErr)); vector v; const vector& u (m_pCommonData->getAllTransf()); int m (cSize(u)); for (int i = 0, n = cSize(vstrNames); i < n; ++i) { string strName (vstrNames[i]); int j (0); for (; j < m; ++j) { if (u[j]->getActionName() == strName) { v.push_back(j); break; } } if (j == m) { QMessageBox::warning(this, "Error setting up custom transformations", "Couldn't find a transformation with the name \"" + convStr(strName) + "\". The program will proceed, but you should review the custom transformations lists."); } } if (v.empty()) { vector > vv (CUSTOM_TRANSF_CNT); initDefaultCustomTransf(k, vv, m_pCommonData); v = vv[k]; } m_pCommonData->setCustomTransf(k, v); } void MainFormDlgImpl::saveVisibleTransf() { const vector& v (m_pCommonData->getVisibleTransf()); int n (cSize(v)); vector vstrActionNames; for (int i = 0; i < n; ++i) { vstrActionNames.push_back(m_pCommonData->getAllTransf()[v[i]]->getActionName()); } m_settings.saveVector("visibleTransf", vstrActionNames); } void MainFormDlgImpl::loadVisibleTransf() { bool bErr; vector vstrNames (m_settings.loadVector("visibleTransf", bErr)); vector v; const vector& u (m_pCommonData->getAllTransf()); int m (cSize(u)); for (int i = 0, n = cSize(vstrNames); i < n; ++i) { string strName (vstrNames[i]); int j (0); for (; j < m; ++j) { if (u[j]->getActionName() == strName) { v.push_back(j); break; } } if (j == m) { QMessageBox::warning(this, "Error setting up visible transformations", "Couldn't find a transformation with the name \"" + convStr(strName) + "\". The program will proceed, but you should review the visible transformations list."); } } m_pCommonData->setVisibleTransf(v); } //ttt2 keyboard shortcuts: next, prev, ... ; //ttt3 set focus on some edit box when changing tabs; //ttt2 perhaps add "whatsThis" texts //ttt2 perhaps add "what's this" tips void MainFormDlgImpl::on_m_pTransformB_clicked() //ttt2 an alternative is to use QToolButton::setMenu(); see if that is really simpler { showBackupWarn(); showSelWarn(); ModifInfoMenu menu; vector vpAct; const vector& vpTransf (m_pCommonData->getAllTransf()); const vector& vnVisualNdx (m_pCommonData->getVisibleTransf()); for (int i = 0, n = cSize(vnVisualNdx); i < n; ++i) { Transformation* pTransf (vpTransf.at(vnVisualNdx[i])); QAction* pAct (new QAction(pTransf->getVisibleActionName(), &menu)); pAct->setToolTip(makeMultiline(pTransf->getDescription())); //connect(pAct, SIGNAL(triggered()), this, SLOT(onExecTransform(i))); // !!! Qt doesn't seem to support parameter binding menu.addAction(pAct); vpAct.push_back(pAct); } connect(&menu, SIGNAL(hovered(QAction*)), this, SLOT(onMenuHovered(QAction*))); QAction* p (menu.exec(m_pTransformB->mapToGlobal(QPoint(0, m_pTransformB->height())))); if (0 != p) { int nIndex (std::find(vpAct.begin(), vpAct.end(), p) - vpAct.begin()); vector v; v.push_back(vpTransf.at(vnVisualNdx[nIndex])); transform(v, 0 == (Qt::ShiftModifier & menu.getModifiers()) ? ALL : SELECTED); } } void MainFormDlgImpl::onMenuHovered(QAction* pAction) { QToolTip::showText(QCursor::pos(), ""); QToolTip::showText(QCursor::pos(), pAction->toolTip()); // see http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg17214.html and http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg17245.html ; apparently there's some inconsistency in when the menus are shown } void MainFormDlgImpl::on_m_pNormalizeB_clicked() { showBackupWarn(); showSelWarn(); bool bSel (0 != (Qt::ShiftModifier & m_pModifNormalizeB->getModifiers())); const deque& vpHndlr (bSel ? m_pCommonData->getSelHandlers() : m_pCommonData->getViewHandlers()); QStringList l; for (int i = 0, n = cSize(vpHndlr); i < n; ++i) { l << vpHndlr[i]->getUiName(); } if (l.isEmpty()) { QMessageBox::critical(this, "Error", "There are no files to normalize."); return; } int nIssueCount (0); QString qstrWarn; if (bSel && cSize(m_pCommonData->getViewHandlers()) != cSize(m_pCommonData->getSelHandlers())) { ++nIssueCount; qstrWarn += "\n- you are requesting to normalize only some of the files"; } if (CommonData::FOLDER != m_pCommonData->getViewMode()) { ++nIssueCount; qstrWarn += "\n- the \"Album\" mode is not selected"; } if (m_pCommonData->m_filter.isNoteEnabled() || m_pCommonData->m_filter.isDirEnabled()) { ++nIssueCount; if (m_pCommonData->m_filter.isNoteEnabled() && m_pCommonData->m_filter.isDirEnabled()) { qstrWarn += "\n- filters are applied"; } else { qstrWarn += "\n- a filter is applied"; } } if (cSize(vpHndlr) > 50) { ++nIssueCount; qstrWarn += "\n- the normalization will process more than 50 files, which is more than what an album usually has"; } if (0 != nIssueCount) { QString s ("Normalization should process one whole album at a time, so it should only be run in \"Album\" mode, when no filters are active, and it should be applied to all the files in that album. But in the current case"); if (1 == nIssueCount) { qstrWarn.remove(0, 2); s += qstrWarn; s += "."; } else { s += " there are some issues:\n" + qstrWarn; } int k (showMessage(this, QMessageBox::Warning, 1, 1, "Warning", s + "\n\nNormalize anyway?", "Normalize", "Cancel")); if (k != 0) { return; } } if (0 == nIssueCount) { if (0 != showMessage(this, QMessageBox::Question, 1, 1, "Confirm", "Normalize all the files in the current album? (Note that normalization is done \"in place\", by an external program, so it doesn't care about the transformation settings for original and modified files.)", "Normalize", "Cancel")) { return; } } NormalizeDlgImpl dlg (this, m_pCommonData->m_bKeepNormWndOpen, m_settings, m_pCommonData); dlg.normalize(convStr(m_pCommonData->m_strNormalizeCmd), l); reload(bSel, FORCE); } void MainFormDlgImpl::on_m_pReloadB_clicked() { bool bSel (0 != (Qt::ShiftModifier & m_pModifReloadB->getModifiers())); bool bForce (0 != (Qt::ControlModifier & m_pModifReloadB->getModifiers())); reload(bSel, bForce); } void MainFormDlgImpl::reload(bool bSelOnly, bool bForce) { auto_ptr ptr; FileEnumerator* pEnum; const deque* pvpExisting; bool bNoteFlt (m_pCommonData->m_filter.isNoteEnabled()); bool bDirFlt (m_pCommonData->m_filter.isDirEnabled()); if (bSelOnly || bNoteFlt || bDirFlt) { vector v; const deque& vpHndlr (bSelOnly ? m_pCommonData->getSelHandlers() : m_pCommonData->getViewHandlers()); for (int i = 0, n = cSize(vpHndlr); i < n; ++i) { v.push_back(vpHndlr[i]->getName()); } pEnum = new ListEnumerator(v); ptr.reset(pEnum); } else { CB_ASSERT (!m_pCommonData->m_filter.isNoteEnabled() && !m_pCommonData->m_filter.isDirEnabled()); const deque& vpHndlr (m_pCommonData->getViewHandlers()); switch (m_pCommonData->getViewMode()) { case CommonData::ALL: pEnum = &m_pCommonData->m_dirTreeEnum; break; case CommonData::FOLDER: pEnum = new ListEnumerator(vpHndlr[0]->getDir()); ptr.reset(pEnum); break; case CommonData::FILE: { vector v; v.push_back(vpHndlr[0]->getName()); pEnum = new ListEnumerator(v); ptr.reset(pEnum); } break; default: CB_ASSERT (false); } } pvpExisting = &(bSelOnly ? m_pCommonData->getSelHandlers() : m_pCommonData->getViewHandlers()); scan(*pEnum, bForce, *pvpExisting, CommonData::CURRENT | CommonData::SEL); if (bNoteFlt || bDirFlt) { m_pCommonData->m_filter.disableAll(); m_pCommonData->m_filter.restoreAll(); if (!m_pCommonData->m_filter.isNoteEnabled() && !m_pCommonData->m_filter.isDirEnabled() && !bSelOnly) { // the filter got removed, because nothing matched; so wee need to repeat; (otherwise the user has to press twice: once to remove the filter and a second time to see what's new) reload(false, bForce); } } } void MainFormDlgImpl::applyCustomTransf(int k) { showBackupWarn(); showSelWarn(); vector v; for (int i = 0, n = cSize(m_pCommonData->getCustomTransf()[k]); i < n; ++i) { v.push_back(m_pCommonData->getAllTransf()[m_pCommonData->getCustomTransf()[k][i]]); } transform(v, 0 == (Qt::ShiftModifier & m_vpTransfButtons[k]->getModifiers()) ? ALL : SELECTED); } // The file list is updated in the sense that if a file was changed or removed, this is reflected in the UI. However, new files are not seen. For one thing, rebuilding a 10000-file list takes a lot of time. OTOH perhaps just the new files could be added. Also, perhaps the user could be asked about updating the list. //ttt2 review void MainFormDlgImpl::transform(std::vector& vpTransf, Subset eSubset) { if (m_pCommonData->getViewHandlers().empty()) { QMessageBox::warning(this, "Warning", "The file list is empty, therefore no transformations can be applied.\n\nExiting ..."); return; } QString qstrListInfo; switch (eSubset) { case ALL: { char bfr [10]; int nCnt (cSize(m_pCommonData->getViewHandlers())); if (nCnt < 10) { strcpy(bfr, "the"); } else { sprintf(bfr, "%d", nCnt); } qstrListInfo = QString("all %1 files shown in the file list").arg(bfr); break; } case SELECTED: { int nCnt (cSize(m_pCommonData->getSelHandlers())); if (0 == nCnt) { QMessageBox::warning(this, "Warning", "No file is selected, therefore no transformations can be applied.\n\nExiting ..."); return; } else if (1 == nCnt) { qstrListInfo = "\"" + convStr(m_pCommonData->getSelHandlers()[0]->getShortName()) + "\""; } else if (2 == nCnt) { qstrListInfo = "\"" + convStr(m_pCommonData->getSelHandlers()[0]->getShortName()) + QString("\" and the other selected file"); } else { qstrListInfo = "\"" + convStr(m_pCommonData->getSelHandlers()[0]->getShortName()) + QString("\" and the other %1 selected files").arg(nCnt - 1); } break; } case CURRENT: { CB_ASSERT (0 != m_pCommonData->getCrtMp3Handler()); qstrListInfo = "\"" + convStr(m_pCommonData->getCrtMp3Handler()->getShortName()) + "\""; break; } default: CB_ASSERT (false); } QString qstrConf; if (vpTransf.empty()) { if (TransfConfig::Options::UPO_DONT_CHG == m_transfConfig.m_options.m_eUnprocOrigChange) { QMessageBox::warning(this, "Warning", "The transformation list is empty.\n\nBased on the configuration, it is possible for changes to the files in the list to be performed, even in this case (the files may still be moved, renamed or erased). However, the current settings are to leave the original files unchanged, so currently there's no point in applying an empty transformation list.\n\nExiting ..."); return; } qstrConf = "Apply an empty transformation list to all the files shown in the file list? (Note that even if no transformations are performed, the files may still be moved, renamed or erased, based on the current settings.)"; } else if (1 == cSize(vpTransf)) { qstrConf = (convStr(string("Apply transformation \"") + vpTransf[0]->getVisibleActionName() + "\" to ")) + qstrListInfo + "?"; } else { qstrConf = "Apply the following transformations to " + qstrListInfo + "?"; for (int i = 0, n = cSize(vpTransf); i < n; ++i) { qstrConf += "\n "; qstrConf += vpTransf[i]->getVisibleActionName(); } } { const char* aOrig[] = { "don't change", "erase", "move", "move", "rename", "move if destination doesn't exist" }; if ((m_transfConfig.m_options.m_eProcOrigChange != TransfConfig::Options::PO_MOVE_OR_ERASE && m_transfConfig.m_options.m_eProcOrigChange != TransfConfig::Options::PO_ERASE) || m_transfConfig.m_options.m_eUnprocOrigChange != TransfConfig::Options::UPO_DONT_CHG) //ttt2 improve { qstrConf += "\n\nActions to be taken:"; if (!vpTransf.empty()) { qstrConf += "\n- original file that has been transformed: "; qstrConf += aOrig[m_transfConfig.m_options.m_eProcOrigChange]; } qstrConf += "\n- original file that has not been transformed: "; qstrConf += aOrig[m_transfConfig.m_options.m_eUnprocOrigChange]; } } QMessageBox::StandardButton res (QMessageBox::question(this, "Confirmation", qstrConf, QMessageBox::Yes | QMessageBox::No)); if (QMessageBox::Yes != res) { return; } deque vpCrt; const deque* pvpHandlers; switch (eSubset) { case SELECTED: pvpHandlers = &m_pCommonData->getSelHandlers(); break; case ALL: pvpHandlers = &m_pCommonData->getViewHandlers(); break; case CURRENT: vpCrt.push_back(m_pCommonData->getCrtMp3Handler()); pvpHandlers = &vpCrt; break; default: CB_ASSERT (false); } ::transform(*pvpHandlers, vpTransf, "Applying transformations to MP3 files", this, m_pCommonData, m_transfConfig); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== void MainFormDlgImpl::on_m_pConfigB_clicked() { ConfigDlgImpl dlg (m_transfConfig, m_pCommonData, this, ConfigDlgImpl::ALL_TABS); string s (m_pCommonData->getCrtName()); if (dlg.run()) { m_settings.saveMiscConfigSettings(m_pCommonData); m_settings.saveScanAtStartup(m_pCommonData->m_bScanAtStartup); m_settings.saveTransfConfig(m_transfConfig); // transformation updateUi(s); } } void MainFormDlgImpl::setTransfTooltip(int k) { QString s1; s1.sprintf("Apply custom transformation list #%d\n", k + 1); QString s2; for (int i = 0, n = cSize(m_pCommonData->getCustomTransf()[k]); i < n; ++i) { s2 += " "; s2 += m_pCommonData->getAllTransf()[m_pCommonData->getCustomTransf()[k][i]]->getVisibleActionName(); if (i < n - 1) { s2 += "\n"; } } if (s2.isEmpty()) { s2 = " \n\n(you can edit the list in the Settings dialog)"; } // well; at startup it will get repopulated, so the only way for this to be empty is if it was configured like this in the current session m_vpTransfButtons[k]->setToolTip(s1 + s2); } void MainFormDlgImpl::on_m_pModeAllB_clicked() { m_pCommonData->setViewMode(CommonData::ALL, m_pCommonData->getCrtMp3Handler()); m_pFilesG->setFocus(); } void MainFormDlgImpl::on_m_pModeAlbumB_clicked() { m_pCommonData->setViewMode(CommonData::FOLDER, m_pCommonData->getCrtMp3Handler()); m_pFilesG->setFocus(); } void MainFormDlgImpl::on_m_pModeSongB_clicked() { m_pCommonData->setViewMode(CommonData::FILE, m_pCommonData->getCrtMp3Handler()); m_pFilesG->setFocus(); } void MainFormDlgImpl::on_m_pPrevB_clicked() { //LAST_STEP("MainFormDlgImpl::on_m_pPrevB_clicked"); //CB_ASSERT("345" == "ab"); //traceLastStep("tsterr", 0); char* p (0); *p = 11; //throw 1; //int x (2), y (3); CB_ASSERT(x >= y); m_pCommonData->previous(); //updateWidgets(); m_pFilesG->setFocus(); } void MainFormDlgImpl::on_m_pNextB_clicked() { m_pCommonData->next(); //updateWidgets(); m_pFilesG->setFocus(); } void MainFormDlgImpl::on_m_pTagEdtB_clicked() { showBackupWarn(); if (m_pCommonData->getViewHandlers().empty()) { QMessageBox::critical(this, "Error", "The file list is empty. You need to populate it before opening the tag editor."); return; } m_pCommonData->setSongInCrtAlbum(); bool bDataSaved (false); TagEditorDlgImpl dlg (this, m_pCommonData, m_transfConfig, bDataSaved); //if (QDialog::Accepted == dlg.exec()) bool bToldAboutPatterns (m_pCommonData->m_bToldAboutPatterns); string strCrt (dlg.run()); if (!bToldAboutPatterns && m_pCommonData->m_bToldAboutPatterns) { m_settings.saveMiscConfigSettings(m_pCommonData); } updateUi(strCrt); // needed because the tag editor might have called the config and changed things; it would be nicer to send a signal when config changes, but IIRC in Qt 4.3.1 resizing things in a dialog that opened another one doesn't work very well; (see also TagEditorDlgImpl::on_m_pQueryDiscogsB_clicked()) if (m_pCommonData->useFastSave()) { if (bDataSaved) { fullReload(DONT_FORCE); } } else { emit tagEditorClosed(); } } void MainFormDlgImpl::on_m_pRenameFilesB_clicked() { bool bUseCrtView (0 != (Qt::ControlModifier & m_pModifRenameFilesB->getModifiers())); if (m_pCommonData->getViewHandlers().empty()) { QMessageBox::critical(this, "Error", "The file list is empty. You need to populate it before opening the file rename tool."); return; } m_pCommonData->setSongInCrtAlbum(); FileRenamerDlgImpl dlg (this, m_pCommonData, bUseCrtView); //if (QDialog::Accepted == dlg.exec()) string strCrt (dlg.run()); updateUi(strCrt); } void MainFormDlgImpl::updateUi(const string& strCrt) // strCrt may be empty { saveIgnored(); { // custom transf for (int i = 0; i < CUSTOM_TRANSF_CNT; ++i) { saveCustomTransf(i); } setTransfTooltips(); } { saveVisibleTransf(); } if (m_pCommonData->m_bShowExport || m_pCommonData->m_bShowSessions) { m_pOptBtn1W->show(); } else { m_pOptBtn1W->hide(); } if (m_pCommonData->m_bShowExport) { m_pExportB->show(); m_pExportB->parentWidget()->layout()->update(); // it is probably a Qt bug the fact that this is needed; should have been automatic; } else { m_pExportB->hide(); } if (m_pCommonData->m_bShowDebug) { m_pDebugB->show(); m_pDebugB->parentWidget()->layout()->update(); // it is probably a Qt bug the fact that this is needed; should have been automatic; } else { m_pDebugB->hide(); } if (m_pCommonData->m_bShowSessions) { m_pSessionsB->show(); m_pSessionsB->parentWidget()->layout()->update(); // it is probably a Qt bug the fact that this is needed; should have been automatic; } else { m_pSessionsB->hide(); } resizeIcons(); m_pCommonData->updateWidgets(strCrt); // needed for filters and unique notes } void MainFormDlgImpl::on_m_pDebugB_clicked() { DebugDlgImpl dlg (this, m_pCommonData); dlg.run(); m_settings.saveMiscConfigSettings(m_pCommonData); } void MainFormDlgImpl::on_m_pExportB_clicked() { ExportDlgImpl dlg (this); dlg.run(); //ttt2 perhaps use ModifInfoToolButton m_settings.saveMiscConfigSettings(m_pCommonData); } void MainFormDlgImpl::on_m_pAboutB_clicked() { AboutDlgImpl dlg (this); dlg.exec(); } class AddrRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const { return m_spToRemove.count(p) > 0; } public: /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Removes selected streams."; } static const char* getClassName() { return "Remove selected stream(s)"; } set m_spToRemove; }; //void MainFormDlgImpl::onStreamsGKeyPressed(int nKey) /*override*/ bool MainFormDlgImpl::eventFilter(QObject* pObj, QEvent* pEvent) { //qDebug("type %d", pEvent->type()); //if (pObj == m_pFilesG) qDebug("type %d", pEvent->type()); QKeyEvent* pKeyEvent (dynamic_cast(pEvent)); int nKey (0 == pKeyEvent ? 0 : pKeyEvent->key()); if (m_pStreamsG == pObj && 0 != pKeyEvent && Qt::Key_Delete == nKey && QEvent::ShortcutOverride == pKeyEvent->type()) { showBackupWarn(); //showSelWarn(); //qDebug("type %d", pKeyEvent->type()); QItemSelectionModel* pSelModel (m_pStreamsG->selectionModel()); QModelIndexList lstSel (pSelModel->selection().indexes()); set sStreams; for (QModelIndexList::iterator it = lstSel.begin(), end = lstSel.end(); it != end; ++it) { sStreams.insert(it->row()); } if (sStreams.empty()) { return true; } AddrRemover rmv; for (set::iterator it = sStreams.begin(), end = sStreams.end(); it != end; ++it) { rmv.m_spToRemove.insert(m_pCommonData->getCrtStreams()[*it]); } vector v; v.push_back(&rmv); transform(v, CURRENT); return true; } else if (pObj == m_pFilesG) { //qDebug("type %d", pEvent->type()); QContextMenuEvent* pCtx (dynamic_cast(pEvent)); if (0 != pCtx) { m_nGlobalX = pCtx->globalX(); m_nGlobalY = pCtx->globalY(); QTimer::singleShot(1, this, SLOT(onFixCurrentNote())); } } return QDialog::eventFilter(pObj, pEvent); } void MainFormDlgImpl::on_m_pViewFileInfoB_clicked() { m_pLowerHalfLayout->setCurrentWidget(m_pFileInfoTab); m_pViewFileInfoB->setChecked(true); //ttt2 use autoExclusive instead m_pViewAllNotesB->setChecked(false); m_pViewTagDetailsB->setChecked(false); m_pNotesG->resizeRowsToContents(); m_pStreamsG->resizeRowsToContents(); } void MainFormDlgImpl::on_m_pViewAllNotesB_clicked() { m_pLowerHalfLayout->setCurrentWidget(m_pAllNotesTab); m_pViewFileInfoB->setChecked(false); m_pViewAllNotesB->setChecked(true); m_pViewTagDetailsB->setChecked(false); m_pUniqueNotesG->resizeRowsToContents(); } void MainFormDlgImpl::on_m_pViewTagDetailsB_clicked() { m_pLowerHalfLayout->setCurrentWidget(m_pTagDetailsTab); m_pViewFileInfoB->setChecked(false); m_pViewAllNotesB->setChecked(false); m_pViewTagDetailsB->setChecked(true); onCrtFileChanged(); // to populate m_pTagDetailsW } void MainFormDlgImpl::resizeIcons() { vector v; v.push_back(m_pScanB); v.push_back(m_pSessionsB); v.push_back(m_pNoteFilterB); v.push_back(m_pDirFilterB); v.push_back(m_pModeAllB); v.push_back(m_pModeAlbumB); v.push_back(m_pModeSongB); v.push_back(m_pPrevB); v.push_back(m_pNextB); v.push_back(m_pTransformB); v.push_back(m_pCustomTransform1B); v.push_back(m_pCustomTransform2B); v.push_back(m_pCustomTransform3B); v.push_back(m_pCustomTransform4B); v.push_back(m_pTagEdtB); v.push_back(m_pNormalizeB); v.push_back(m_pRenameFilesB); v.push_back(m_pReloadB); v.push_back(m_pConfigB); v.push_back(m_pDebugB); v.push_back(m_pAboutB); v.push_back(m_pExportB); int k (m_pCommonData->m_nMainWndIconSize); for (int i = 0, n = cSize(v); i < n; ++i) { QToolButton* p (v[i]); p->setMaximumSize(k, k); p->setMinimumSize(k, k); p->setIconSize(QSize(k - 4, k - 4)); } } void MainFormDlgImpl::on_m_pSessionsB_clicked() { closeEvent(0); accept(); } //ttt1 different for unstable void MainFormDlgImpl::checkForNewVersion() // returns immediately; when the request completes it will send a signal { const int MIN_INTERVAL_BETWEEN_CHECKS (24); // hours if ("yes" != m_pCommonData->m_strCheckForNewVersions && "no" != m_pCommonData->m_strCheckForNewVersions) { int nRes (HtmlMsg::msg(this, 0, 0, 0, HtmlMsg::DEFAULT, "Info", "

MP3 Diags can check at startup if a new version of the program has been released. Here's how this is supposed to work:" "

    " "
  • The check is done in the background, when the program starts, so there should be no performance penalties
  • " "
  • A notification message is displayed only if there's a new version available
  • " "
  • The update is manual. You are told that there is a new version and are offered links to see what's new, but nothing gets downloaded and / or installed automatically
  • " "
  • There is no System Tray process checking periodically for updates
  • " "
  • You can turn the notifications on and off from the configuration dialog
  • " "
  • If you restart the program withing a day after a check, no new check is done
  • " "
" "

" /*" "

QQQ

" "

QQQ

" "

QQQ

" */ , 750, 300, "Disable checking for new versions", "Enable checking for new versions")); qDebug("ret %d", nRes); m_pCommonData->m_strCheckForNewVersions = (1 == nRes ? "yes" : "no"); m_settings.saveMiscConfigSettings(m_pCommonData); } if ("yes" != m_pCommonData->m_strCheckForNewVersions) { return; } QDateTime t1 (QDateTime::currentDateTime()); t1 = t1.addSecs(-MIN_INTERVAL_BETWEEN_CHECKS*3600); //qDebug("ini: %s, crt: %s", m_pCommonData->m_timeLastNewVerCheck.toString().toUtf8().constData(), t1.toString().toUtf8().constData()); if (t1 < m_pCommonData->m_timeLastNewVerCheck) { return; } m_pCommonData->m_timeLastNewVerCheck = QDateTime(QDateTime::currentDateTime()); m_pQHttp = new QHttp (this); connect(m_pQHttp, SIGNAL(requestFinished(int, bool)), this, SLOT(onNewVersionQueryFinished(int, bool))); //connect(m_pQHttp, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(readResponseHeader(const QHttpResponseHeader&))); m_pQHttp->setHost("mp3diags.sourceforge.net"); //http://mp3diags.sourceforge.net/010_getting_the_program.html QHttpRequestHeader header ("GET", "/version.txt"); header.setValue("Host", "mp3diags.sourceforge.net"); //ttt1 use an "unstable" directory, have the app be aware that it's unstable for both "help" and new ver check //QHttpRequestHeader header ("GET", "/mciobanu/mp3diags/010_getting_the_program.html"); header.setValue("Host", "web.clicknet.ro"); m_pQHttp->request(header); } //mp3diags.sourceforge.net/010_getting_the_program.html //web.clicknet.ro/mciobanu/mp3diags/010_getting_the_program.html void MainFormDlgImpl::readResponseHeader(const QHttpResponseHeader& h) { qDebug("status %d", h.statusCode()); } void MainFormDlgImpl::onNewVersionQueryFinished(int /*nId*/, bool bError) { if (bError) { //ttt2 log something, tell user after a while qDebug("HTTP error"); return; } qint64 nAv (m_pQHttp->bytesAvailable()); if (0 == nAv) { // !!! JUST return; empty responses come for no identifiable requests and they should be just ignored return; } QByteArray b (m_pQHttp->readAll()); CB_ASSERT (b.size() == nAv); qDebug("ver: %s", b.constData()); m_qstrNewVer = b; m_qstrNewVer = m_qstrNewVer.trimmed(); if (m_qstrNewVer.size() > 50) { //ttt2 return; // most likely some error message } if (APP_VER == m_qstrNewVer) { return; } #if 0 //const int WAIT (15); //crashes //const int WAIT (12); // doesn't crash const int WAIT (14); //crashes #ifndef WIN32 qDebug("wait %d seconds", WAIT); sleep(WAIT); QMessageBox::critical(this, "resume", "resume resume resume resume resume"); // crashes //ttt2 see if this crash affects discogs dwnld //??? why doesn't crash if no message is shown? #else //Sleep(WAIT*1000); // Qt 4.5 doesn't seem to crash #endif #endif QTimer::singleShot(1, this, SLOT(onNewVersionQueryFinished2())); } void MainFormDlgImpl::onNewVersionQueryFinished2() { //QMessageBox::critical(this, "wait", "bb urv huervhuervhuerv erve rvhu ervervhuer vher vrhe rv evr ev erv erv"); //qDebug("ver: %s", b.constData()); //QMessageBox::critical(this, "resume", "bb urv huervhuervhuerv erve rvhu ervervhuer vher vrhe rv evr ev erv erv"); if (m_pCommonData->m_strDontTellAboutVer == convStr(m_qstrNewVer)) { return; } int nRes (HtmlMsg::msg(this, 0, 0, 0, HtmlMsg::VERT_BUTTONS, "Info", "

Version " + m_qstrNewVer + " has been published. You are running " + APP_VER + ". You can see what's new in the MP3 Diags blog. A more technical list with changes can be seen in the change log.

" //ttt1 different for "unstable" #ifndef WIN32 "

This notification is about the availability of the source code. Binaries may or may not be available at this time, depending on your particular platform.

" #else #endif "

You should review the changes and decide if you want to upgrade or not.

" "

Note: if you want to upgrade, you should close MP3 Diags first.

" "

Choose what do you want to do:

" /*"

QQQ

"*/ , 600, 400, "Just close this message", "Don't tell me about version " + m_qstrNewVer + " again", "Disable checking for new versions")); //qDebug("ret %d", nRes); switch (nRes) { case 0: m_pCommonData->m_strDontTellAboutVer.clear(); break; case 1: m_pCommonData->m_strDontTellAboutVer = convStr(m_qstrNewVer); break; case 2: m_pCommonData->m_strDontTellAboutVer.clear(); m_pCommonData->m_strCheckForNewVersions = "no"; break; default: CB_ASSERT (false); } m_settings.saveMiscConfigSettings(m_pCommonData); } //============================================================================================================================= //============================================================================================================================= //============================================================================================================================= namespace { struct CmpTransfAndName { const char* m_szName; CmpTransfAndName(const char* szName) : m_szName(szName) {} bool operator()(const Transformation* p) const { return 0 == strcmp(p->getActionName(), m_szName); } }; class FixedAddrRemover : public GenericRemover { /*override*/ bool matches(DataStream* p) const { return m_pStream == p; // !!! normally there might be an issue with comparing pointers, in case something else gets allocated at the same address as a deleted object; however, in this case the stream passed on setStream() doesn't get destroyed } streampos m_pos; string m_strDescr; const DataStream* m_pStream; public: FixedAddrRemover() : m_pos(-1), m_pStream(0) {} void setStream(const DataStream* p) { m_pStream = p; m_pos = p->getPos(); ostringstream out; out << "Remove stream " << p->getDisplayName() << " at address 0x" << hex << p->getPos(); m_strDescr = out.str(); } /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getVisibleActionName() const { return m_strDescr.c_str(); } /*override*/ const char* getDescription() const { return "Removes specified stream."; } static const char* getClassName() { return "Remove specified stream"; } }; } vector MainFormDlgImpl::getFixes(const Note* pNote, const Mp3Handler* pHndl) const // what might fix a note { //qDebug("strm %s", pStream ? pStream->getDisplayName() : ""); //CB_ASSERT (0 == pStream || (pNote->getPos() >= pStream->getPos() && pNote->getPos() < pStream->getPos() + pStream->getSize())); //CB_ASSERT (0 == pHndl || -1 != pNote->getPos()); static map > s_mFixes; static bool s_bInitialized (false); const vector& vpAllTransf (m_pCommonData->getAllTransf()); if (!s_bInitialized) { s_bInitialized = true; vector::const_iterator it; #define ADD_FIX(NOTE, TRANSF) \ it = find_if(vpAllTransf.begin(), vpAllTransf.end(), CmpTransfAndName(TRANSF::getClassName())); \ CB_ASSERT (vpAllTransf.end() != it); \ s_mFixes[Notes::NOTE().getNoteId()].push_back(*it); ADD_FIX(twoAudio, InnerNonAudioRemover); ADD_FIX(twoAudio, SingleBitRepairer); ADD_FIX(incompleteFrameInAudio, TruncatedMpegDataStreamRemover); ADD_FIX(incompleteFrameInAudio, TruncatedAudioPadder); //ADD_FIX(twoLame, VbrRepairer); //ADD_FIX(twoLame, VbrRebuilder); ADD_FIX(xingAddedByMp3Fixer, VbrRepairer); ADD_FIX(xingFrameCountMismatch, VbrRepairer); ADD_FIX(xingFrameCountMismatch, MismatchedXingRemover); //ADD_FIX(twoXing, VbrRepairer); //ttt2 ADD_FIX(xingNotBeforeAudio, VbrRepairer); ADD_FIX(incompatXing, VbrRebuilder); ADD_FIX(missingXing, VbrRebuilder); ADD_FIX(vbriFound, VbrRepairer); ADD_FIX(foundVbriAndXing, VbrRepairer); ADD_FIX(id3v2FrameTooShort, Id3V2Rescuer); //ADD_FIX(id3v2FrameTooShort, Id3V2Cleaner); ADD_FIX(id3v2InvalidName, Id3V2Rescuer); //ADD_FIX(id3v2InvalidName, Id3V2Cleaner); ADD_FIX(id3v2TextError, Id3V2Rescuer); //ADD_FIX(id3v2TextError, Id3V2Cleaner); ADD_FIX(id3v2HasLatin1NonAscii, Id3V2UnicodeTransformer); ADD_FIX(id3v2EmptyTcon, Id3V2Rescuer); //ADD_FIX(id3v2EmptyTcon, Id3V2Cleaner); ADD_FIX(id3v2MultipleFramesWithSameName, Id3V2Rescuer); ADD_FIX(id3v2MultipleFramesWithSameName, Id3V2Cleaner); ADD_FIX(id3v2PaddingTooLarge, Id3V2Compactor); ADD_FIX(id3v2UnsuppVer, UnsupportedId3V2Remover); ADD_FIX(id3v2UnsuppFlag, UnsupportedDataStreamRemover); ADD_FIX(id3v2UnsuppFlags1, UnsupportedDataStreamRemover); ADD_FIX(id3v2UnsuppFlags2, UnsupportedDataStreamRemover); ADD_FIX(id3v2CouldntLoadPic, Id3V2Rescuer); //ADD_FIX(id3v2CouldntLoadPic, Id3V2Cleaner); ADD_FIX(id3v2NotCoverPicture, SmallerImageRemover); ADD_FIX(id3v2ErrorLoadingApic, Id3V2Rescuer); //ADD_FIX(id3v2ErrorLoadingApic, Id3V2Cleaner); ADD_FIX(id3v2ErrorLoadingApicTooShort, Id3V2Rescuer); //ADD_FIX(id3v2ErrorLoadingApicTooShort, Id3V2Cleaner); ADD_FIX(id3v2DuplicatePic, Id3V2Rescuer); ADD_FIX(id3v2DuplicatePic, Id3V2Cleaner); ADD_FIX(id3v2DuplicatePic, SmallerImageRemover); ADD_FIX(id3v2MultipleApic, Id3V2Rescuer); ADD_FIX(id3v2MultipleApic, Id3V2Cleaner); ADD_FIX(id3v2MultipleApic, SmallerImageRemover); ADD_FIX(id3v2UnsupApicTextEnc, Id3V2Rescuer); ADD_FIX(id3v2UnsupApicTextEnc, Id3V2Cleaner); ADD_FIX(id3v2LinkInApic, Id3V2Rescuer); ADD_FIX(id3v2LinkInApic, Id3V2Cleaner); ADD_FIX(twoId3V230, MultipleId3StreamRemover); ADD_FIX(bothId3V230_V240, MultipleId3StreamRemover); ADD_FIX(id3v230UsesUtf8, Id3V2Rescuer); //ADD_FIX(id3v230UsesUtf8, Id3V2Cleaner); ADD_FIX(twoId3V240, MultipleId3StreamRemover); ADD_FIX(id3v240IncorrectSynch, Id3V2Rescuer); ADD_FIX(id3v240IncorrectSynch, Id3V2Cleaner); ADD_FIX(id3v240DeprTyerAndTdrc, Id3V2Rescuer); ADD_FIX(id3v240DeprTyerAndTdrc, Id3V2Cleaner); ADD_FIX(id3v240DeprTyer, Id3V2Rescuer); ADD_FIX(id3v240DeprTyer, Id3V2Cleaner); ADD_FIX(id3v240DeprTdatAndTdrc, Id3V2Rescuer); ADD_FIX(id3v240DeprTdatAndTdrc, Id3V2Cleaner); ADD_FIX(id3v240DeprTdat, Id3V2Rescuer); ADD_FIX(id3v240DeprTdat, Id3V2Cleaner); ADD_FIX(twoId3V1, MultipleId3StreamRemover); ADD_FIX(brokenAtTheEnd, BrokenDataStreamRemover); ADD_FIX(brokenInTheMiddle, BrokenDataStreamRemover); ADD_FIX(truncAudioWithWholeFile, TruncatedMpegDataStreamRemover); ADD_FIX(truncAudioWithWholeFile, TruncatedAudioPadder); ADD_FIX(truncAudio, TruncatedMpegDataStreamRemover); ADD_FIX(truncAudio, TruncatedAudioPadder); ADD_FIX(unknownAtTheEnd, UnknownDataStreamRemover); ADD_FIX(unknownInTheMiddle, UnknownDataStreamRemover); ADD_FIX(foundNull, NullStreamRemover); } vector vpTransf (s_mFixes[pNote->getNoteId()]); /* if (0 != pStream) { if (pNote->getNoteId() == Notes::audioTooShort().getNoteId()) { if (pStream->getDisplayName() == TruncatedMpegDataStream::getClassDisplayName()) { vector::const_iterator it (find_if(vpAllTransf.begin(), vpAllTransf.end(), CmpTransfAndName(TruncatedMpegDataStreamRemover::getClassName()))); CB_ASSERT (vpAllTransf.end() != it); vpTransf.push_back(*it); } } }*/ #define ADD_CUSTOM_FIX(NOTE, STREAM, TRANSF) \ if (pNote->getNoteId() == Notes::NOTE().getNoteId()) \ { \ if (pCrtStream->getDisplayName() == STREAM::getClassDisplayName()) \ { \ vector::const_iterator it (find_if(vpAllTransf.begin(), vpAllTransf.end(), CmpTransfAndName(TRANSF::getClassName()))); \ CB_ASSERT (vpAllTransf.end() != it); \ Transformation* pTransf (*it); \ if (0 == spTransf.count(pTransf)) \ { \ vpTransf.push_back(pTransf); \ spTransf.insert(pTransf); \ } \ } \ } //ttt2 None of the ADD_CUSTOM_FIX fixes is shown for header (e.g. SingleBitRepairer is shown for validFrameDiffVer only when clicking on circle, not when clicking on header), maybe we should drop the stream test; OTOH the case of audioTooShort shows that it matters what stream the error is occuring on; so maybe drop the stream check only for some ... // workaround: see what's available for single song, then use the menu for all; //ttt2 other example: mismatched xing fixable by SingleBitRepairer to other stream; probably document that all the notes should be looked at; // or: add all transforms that in some context might fix a note // or: extend ADD_CUSTOM_FIX to look at the other notes, similarly to how it looks at the stream it's in; add some transform if some other note is present; (note: use a set to not have duplicates entered via different rules) // perhaps unknown size 16 between xing and audio -> repair vbr, but seems too specific // unknown between audio and audio -> restore flipped //ttt2 perhaps just this: if there's a chance that by using transf T the note N will disappear, show it; well, this is again context-dependant if (0 != pHndl) { // for each matching note, see if additional fixes exist that take into account the stream the note is in and (in the future) other streams, their sizes, ... const vector& vpHndlNotes (pHndl->getNotes().getList()); const vector& vpStreams (pHndl->getStreams()); set spTransf (vpTransf.begin(), vpTransf.end()); static vector s_vFixedAddrRemovers; s_vFixedAddrRemovers.clear(); set spRemovableStreams; for (int i = 0; i < cSize(vpHndlNotes); ++i) { if (-1 == vpHndlNotes[i]->getNoteId()) { goto e1; } // takes care of trace notes const Note* pCrtNote (vpHndlNotes[i]); if (pCrtNote->getNoteId() == pNote->getNoteId() && -1 != pCrtNote->getPos()) { for (int i = 0, n = cSize(vpStreams); i < n; ++i) { //qDebug("s %s", v[i]->getDisplayName()); if (n - 1 == i || pCrtNote->getPos() < vpStreams[i + 1]->getPos()) //ttt2 lower_bound { const DataStream* pCrtStream (vpStreams[i]); CB_ASSERT (pCrtNote->getPos() >= pCrtStream->getPos() && pCrtNote->getPos() < pCrtStream->getPos() + pCrtStream->getSize()); ADD_CUSTOM_FIX(validFrameDiffVer, UnknownDataStream, SingleBitRepairer); ADD_CUSTOM_FIX(validFrameDiffLayer, UnknownDataStream, SingleBitRepairer); ADD_CUSTOM_FIX(validFrameDiffMode, UnknownDataStream, SingleBitRepairer); ADD_CUSTOM_FIX(validFrameDiffFreq, UnknownDataStream, SingleBitRepairer); ADD_CUSTOM_FIX(validFrameDiffCrc, UnknownDataStream, SingleBitRepairer); ADD_CUSTOM_FIX(audioTooShort, TruncatedMpegDataStream, TruncatedMpegDataStreamRemover); ADD_CUSTOM_FIX(audioTooShort, TruncatedMpegDataStream, TruncatedAudioPadder); ADD_CUSTOM_FIX(audioTooShort, UnknownDataStream, UnknownDataStreamRemover); ADD_CUSTOM_FIX(audioTooShort, UnknownDataStream, SingleBitRepairer); // ADD_CUSTOM_FIX(brokenInTheMiddle, ??? , Id3V2Rescuer); //ttt2 see about this if (pCrtNote->allowErase() && 0 == spRemovableStreams.count(pCrtStream)) { spRemovableStreams.insert(pCrtStream); s_vFixedAddrRemovers.push_back(FixedAddrRemover()); s_vFixedAddrRemovers.back().setStream(pCrtStream); } break; } } } } e1:; for (int i = 0; i < cSize(s_vFixedAddrRemovers); ++i) { vpTransf.push_back(&s_vFixedAddrRemovers[i]); } } return vpTransf; } int getHeaderDrawOffset(); void MainFormDlgImpl::onFixCurrentNote() { LAST_STEP("MainFormDlgImpl::onFixCurrentNote()"); QPoint coords (m_pFilesG->mapFromGlobal(QPoint(m_nGlobalX, m_nGlobalY))); //int nHorHdrHght (); //if (coords.x() < nVertHdrWdth) { return; } int nCol (m_pFilesG->columnAt(coords.x() - m_pFilesG->verticalHeader()->width())); if (nCol < 1) { return; } // header or file name if (coords.y() < m_pFilesG->horizontalHeader()->height()) { int x (coords.x()); x -= 2; // hard-coded x += getHeaderDrawOffset() / 2; //ttt2 this "/2" doesn't make sense but it works best //qDebug("offs %d", getHeaderDrawOffset()); nCol = m_pFilesG->columnAt(x - m_pFilesG->verticalHeader()->width()); if (nCol != m_pFilesG->columnAt(x - m_pFilesG->verticalHeader()->width() - 3) || nCol != m_pFilesG->columnAt(x - m_pFilesG->verticalHeader()->width() + 3)) { // too close to adjacent cells; return to avoid confusions return; } fixCurrentNoteAllFiles(nCol - 1); } else { fixCurrentNoteOneFile(); } //qDebug("r %d, c %d", m_pFilesG->rowAt(coords.y() - nHorHdrHght), ); } void MainFormDlgImpl::fixCurrentNoteOneFile() { QModelIndex ndx (m_pFilesG->currentIndex()); if (!ndx.isValid() || 0 == ndx.column()) { return; } //qDebug("fixCurrentNoteOneFile %d %d", nGlobalX, nGlobalY); const Mp3Handler* pHndl (m_pCommonData->getCrtMp3Handler()); const vector& vpNotes (m_pCommonData->getUniqueNotes().getFltVec()); const Note* pNote (vpNotes.at(ndx.column() - 1)); //qDebug("fixing note '%s' for file '%s'", pNote->getDescription(), pHndl->getName().c_str()); //int nCnt (0); vector vpTransf (getFixes(pNote, pHndl)); if (vpTransf.empty()) { return; } showFixes(vpTransf, CURRENT); } void MainFormDlgImpl::fixCurrentNoteAllFiles(int nCol) { const vector& vpNotes (m_pCommonData->getUniqueNotes().getFltVec()); const Note* pNote (vpNotes.at(nCol)); vector vpTransf (getFixes(pNote, 0)); if (vpTransf.empty()) { return; } showFixes(vpTransf, ALL); } void MainFormDlgImpl::showFixes(vector& vpTransf, Subset eSubset) { ModifInfoMenu menu; vector vpAct; for (int i = 0, n = cSize(vpTransf); i < n; ++i) { Transformation* pTransf (vpTransf[i]); QAction* pAct (new QAction(pTransf->getVisibleActionName(), &menu)); pAct->setToolTip(makeMultiline(pTransf->getDescription())); //connect(pAct, SIGNAL(triggered()), this, SLOT(onExecTransform(i))); // !!! Qt doesn't seem to support parameter binding menu.addAction(pAct); vpAct.push_back(pAct); } connect(&menu, SIGNAL(hovered(QAction*)), this, SLOT(onMenuHovered(QAction*))); //QAction* p (menu.exec(m_pTransformB->mapToGlobal(QPoint(0, m_pTransformB->height())))); QAction* p (menu.exec(QPoint(m_nGlobalX, m_nGlobalY + 10))); if (0 != p) { int nIndex (std::find(vpAct.begin(), vpAct.end(), p) - vpAct.begin()); vector v; v.push_back(vpTransf.at(nIndex)); if (ALL == eSubset) { eSubset = 0 == (Qt::ShiftModifier & menu.getModifiers()) ? ALL : SELECTED; } transform(v, eSubset); } } //============================================================================================================================= //============================================================================================================================= //============================================================================================================================= void MainFormDlgImpl::testSlot() { static int c (0); qDebug("%d", c++); } //============================================================================================================================= //============================================================================================================================= //============================================================================================================================= struct TestThread01 : public PausableThread { /*override*/ void run() { CompleteNotif notif(this); for (int i = 0; i < 7; ++i) { if (isAborted()) return; checkPause(); QString s; s.sprintf("step %d", i); StrList l; l.push_back(s); emit stepChanged(l, -1); //qDebug("step %d", i); sleep(1); } notif.setSuccess(true); } }; //============================================================================================================================= //============================================================================================================================= //============================================================================================================================= /* ttt2 To look at: QDir QDirModel QFontComboBox QStyle ; ./myapplication -style motif */ //ttt2 ? option to discard errors in unknown streams: probably not; at any rate, that's the only chance to learn that there was an error there (instead of a really unknown stream) // ttt2 make sure that everything that doesn't take a "parent" on the constructor gets deleted; /* Development machine: -style=Plastique -style=Cleanlooks -style=CDE -style=Motif -style=Oxygen ?? Windows, Windows Vista, Plastik */ //ttt2 build: not sure is possible, but have the .pro file include another file, which is generated by a "pre-config" script, which figures out if the lib is installed //ttt2 perhaps a "consider unknown" function for streams; then it would be possible for a truncated id3v1 tag that seems ok to be marked as unknown, thus allowing the following tag's start to be detected (see "c09 Mark Knopfler - The Long Road.mp3") //ttt2 handle symbolic links to ancestors //ttt2 fix on right-click for notes table //ttt1 Settings/Configuration name: different tooltip and dlg name //ttt2 perhaps "open file manager" on right-click (QDesktopServices::openUrl seems to do it) //ttt0 look at /d/test_mp3/1/tmp4/tmp2/unsupported/bad-decoding MP3Diags-1.0.12.079/src/SerSupport.cpp0000644000175000001440000002330211265064404016107 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "CommonData.h" #include "SerSupport.h" //#include //#include //#include #include //#include "fstream_unicode.h" #include //#include //#include // headers needed only for serialization: #include "Id3V2Stream.h" #include "Id3V230Stream.h" #include "Id3V240Stream.h" #include "ApeStream.h" #include "MpegStream.h" #include "LyricsStream.h" // serialization for std::streampos // ttt2 perhaps put this in SerSupport.h, but it doesn't matter much; it needs to be visible only when instantiating the templates namespace boost { namespace serialization { //ttt2 see if a newer version of Boost handles std::streampos template inline void save(Archive& ar, const std::streampos& pos, const unsigned int /*nVersion*/) { long long n (pos); // ttt2 this conversion isn't quite right, but it's OK for MP3 files ar << n; } template inline void load(Archive& ar, std::streampos& pos, const unsigned int /*nVersion*/) { long long n; ar >> n; pos = n; } } // namespace serialization } // namespace boost BOOST_SERIALIZATION_SPLIT_FREE(std::streampos); using namespace std; using namespace pearl; #if 0 #if 1 // serialization for std::streampos namespace boost { namespace serialization { //ttt2 see if a newer version of Boost handles std::streampos template inline void save(Archive& ar, const std::streampos& pos, const unsigned int /*nVersion*/) { long long n (pos); // ttt2 this conversion isn't quite right, but it's OK for MP3 files ar << n; } template inline void load(Archive& ar, std::streampos& pos, const unsigned int /*nVersion*/) { long long n; ar >> n; pos = n; } } // namespace serialization } // namespace boost BOOST_SERIALIZATION_SPLIT_FREE(std::streampos); //BOOST_SERIALIZATION_SPLIT_FREE(std::fpos<__mbstate_t>); #endif struct MyClass { int a; }; struct MyClass2 { int b; template void save(Archive& ar, const unsigned int ) const { // note, version is always the latest when saving ar & b; } template void load(Archive& ar, const unsigned int ) { ar & b; } BOOST_SERIALIZATION_SPLIT_MEMBER(); }; namespace boost { namespace serialization { template inline void save(Archive& ar, const MyClass& x, const unsigned int /*nVersion*/) { long long n (x.a); // ttt2 this conversion isn't quite right, but it's OK for MP3 files ar << n; } template inline void load(Archive& ar, MyClass& x, const unsigned int /*nVersion*/) { long long n; ar >> n; x.a = n; } //BOOST_SERIALIZATION_SPLIT_FREE(std::streampos); } // namespace serialization } // namespace boost BOOST_SERIALIZATION_SPLIT_FREE(MyClass); namespace boost { namespace serialization { /*template void serialize1(Archive& ar, MyClass& x, const unsigned int version) { ar & x.a; }*/ template void serialize1(Archive& ar, MyClass& x, const unsigned int version) { split_free(ar, x, version); } BOOST_SERIALIZATION_SPLIT_FREE(MyClass); } // namespace serialization } #if 1 #include "fstream_unicode.h" struct BoostTstBase01 { BoostTstBase01(int n1) : m_n1(n1) {} virtual ~BoostTstBase01() { } int m_n1; std::streampos m_pos; MyClass m; MyClass2 m2; protected: BoostTstBase01() {} private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int /*nVersion*/) { ar & m_n1; ar & m_pos; ar & m; ar & m2; } }; void qwrqwrqsrq() { ifstream_utf8 in ("qqq"); boost::archive::text_iarchive iar (in); //boost::archive::text_iarchive iar (in); //iar >> m_vpAllHandlers; BoostTstBase01* p; iar >> p; } #endif #endif #define REGISTER_SER_TYPES0(ar) #define REGISTER_SER_TYPES(ar) \ { \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ \ ar.register_type(); \ } /* */ /* ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ ar.register_type(); \ */ template void CommonData::save(Archive& ar, const unsigned int nVersion) const { if (nVersion > 1) { throw std::runtime_error("invalid version of serialized file"); } int n1 (10); ar << n1; ar << getCrtName(); int n2 (20); ar << n2; ar << (const deque&)m_vpAllHandlers; ar << (const Filter&)m_filter; ar << m_eViewMode; //qDebug("save name %s", getCrtName().c_str()); } template void CommonData::load(Archive& ar, const unsigned int nVersion) { if (nVersion > 1) { throw std::runtime_error("invalid version of serialized file"); } int n1 (100); ar >> n1; //string strCrtName; ar >> m_strLoadCrtName; int n2 (100); ar >> n2; deque v; ar >> v; CB_ASSERT (m_vpAllHandlers.empty()); for (int i = 0; i < cSize(v); ++i) { v[i]->sortNotes(); // !!! ususally not needed, but there's an exception: when loading an older version, referencing notes that have been removed; they get replaced by Notes::getMissingNote(), which comes first in sorting by CmpNotePtrById; probably not worth the trouble of figuring if it's really needed or not; } m_vpAllHandlers.insert(m_vpAllHandlers.end(), v.begin(), v.end()); m_vpFltHandlers = m_vpAllHandlers; m_vpViewHandlers = m_vpAllHandlers; //qDebug("load name %s", strCrtName.c_str()); ar >> m_filter; if (nVersion >= 1) { ar >> m_eViewMode; } //updateWidgets(m_strLoadCrtName); } BOOST_CLASS_VERSION(CommonData, 1); // returns an error message (or empty string if there's no error) string CommonData::save(const string& strFile) const { try { ofstream_utf8 out (strFile.c_str()); if (!out) { return "Cannot open file \"" + strFile + "\""; } //boost::archive::binary_oarchive oar (out); boost::archive::text_oarchive oar (out); //boost::archive::xml_oarchive oar (out); // ttt3 would be nice to have this as an option, but doesn't seem possible unless we switch everything to XML, because while binary_oarchive can be used as a replacement for text_oarchive, xml_oarchive can't; the serialized classes need to be modified: http://www.boost.org/doc/libs/1_40_0/libs/serialization/doc/wrappers.html#nvp REGISTER_SER_TYPES(oar); oar << *this; } catch (const std::exception& ex) //ttt2 not sure if this is the way to catch errors { return ex.what(); } return ""; } //#include // returns an error message (or empty string if there's no error) string CommonData::load(const string& strFile) { try { ifstream_utf8 in (strFile.c_str()); if (!in) { return ""; } // !!! "no data" is not an error //boost::archive::binary_iarchive iar (in); boost::archive::text_iarchive iar (in); REGISTER_SER_TYPES(iar); iar >> *this; } //catch (const boost::archive::archive_exception&) catch (const std::exception& ex) { return ex.what(); } Notes::clearDestroyList(); return ""; } MP3Diags-1.0.12.079/src/LyricsStream.h0000644000175000001440000001101711264055144016047 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef LyricsStreamH #define LyricsStreamH #include #include #include "DataStream.h" class LyricsStream : public DataStream, public TagReader { std::streampos m_pos; std::streamoff m_nSize; public: LyricsStream(int nIndex, NoteColl& notes, std::istream& in, const std::string& strFileName); /*override*/ void copy(std::istream& in, std::ostream& out); DECL_RD_NAME("Lyrics3 V2.00"); /*override*/ std::string getInfo() const; /*override*/ std::streampos getPos() const { return m_pos; } /*override*/ std::streamoff getSize() const { return m_nSize; } struct NotLyricsStream {}; std::string m_strTitle; std::string m_strArtist; std::string m_strGenre; std::string m_strImageFiles; std::string m_strAlbum; std::string m_strAuthor; // composer std::string m_strLyrics; std::string m_strOther; // these are lost during transfer //ttt2 or maybe not, though not sure if transferring them to some "comment" field would be a good idea std::string m_strInd; std::string m_strFileName; bool m_bHasTitle; bool m_bHasArtist; bool m_bHasGenre; bool m_bHasImage; bool m_bHasAlbum; ImageInfo readImage(const QString& strRelName) const; private: friend class boost::serialization::access; LyricsStream(); // serialization-only constructor // ================================ TagReader ========================================= /*override*/ std::string getTitle(bool* pbFrameExists = 0) const; /*override*/ std::string getArtist(bool* pbFrameExists = 0) const; /*override*/ std::string getTrackNumber(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } /*override*/ TagTimestamp getTime(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } /*override*/ std::string getGenre(bool* pbFrameExists = 0) const; /*override*/ ImageInfo getImage(bool* pbFrameExists = 0) const; /*override*/ std::string getAlbumName(bool* pbFrameExists = 0) const; /*override*/ std::string getOtherInfo() const; /*override*/ SuportLevel getSupport(Feature) const; /*override*/ std::vector getImages() const; template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 1) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); ar & m_pos; ar & m_nSize; if (nVersion > 0) { ar & m_strTitle; ar & m_strArtist; ar & m_strGenre; ar & m_strImageFiles; ar & m_strAlbum; ar & m_strAuthor; ar & m_strLyrics; ar & m_strOther; ar & m_strInd; ar & m_strFileName; ar & m_bHasTitle; ar & m_bHasArtist; ar & m_bHasGenre; ar & m_bHasImage; ar & m_bHasAlbum; } } }; BOOST_CLASS_VERSION(LyricsStream, 1); #endif // ifndef LyricsStreamH MP3Diags-1.0.12.079/src/ConfigDlgImpl.cpp0000644000175000001440000015546211304460026016446 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "ConfigDlgImpl.h" #include "StructuralTransformation.h" #include "Transformation.h" #include "OsFile.h" #include "Helpers.h" #include "Id3Transf.h" #include "Id3V230Stream.h" #include "CommonData.h" #include "StoredSettings.h" ////#include //ttt remove using namespace std; using namespace pearl; //ttt2 simple / detailed files tab, with "simple" only allowing to "create backups in ..." //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class TransfListElem : public ListElem { /*override*/ std::string getText(int nCol) const; const Transformation* m_pTransformation; // doesn't own the pointer //CommonData* m_pCommonData; public: TransfListElem(const Transformation* pTransformation/*, CommonData* pCommonData*/) : m_pTransformation(pTransformation)/*, m_pCommonData(pCommonData)*/ {} const Transformation* getTransformation() const { return m_pTransformation; } }; /*override*/ std::string TransfListElem::getText(int nCol) const { if (0 == nCol) { return m_pTransformation->getActionName(); } return m_pTransformation->getDescription(); } class CustomTransfListPainter : public ListPainter { /*override*/ int getColCount() const { return 2; } /*override*/ std::string getColTitle(int nCol) const { return 0 == nCol ? "Action" : "Description"; } /*override*/ void getColor(int /*nIndex*/, int /*nColumn*/, bool /*bSubList*/, QColor& /*bckgColor*/, QColor& /*penColor*/, double& /*dGradStart*/, double& /*dGradEnd*/) const { } /*override*/ int getColWidth(int /*nCol*/) const { return -1; } // positive values are used for fixed widths, while negative ones are for "stretched" /*override*/ int getHdrHeight() const { return CELL_HEIGHT; } /*override*/ Qt::Alignment getAlignment(int /*nCol*/) const { return Qt::AlignTop | Qt::AlignLeft; } /*override*/ std::string getTooltip(TooltipKey eTooltipKey) const; /*override*/ void reset(); const SubList& m_vDefaultSel; // to be used by reset() public: CustomTransfListPainter(const CommonData* pCommonData, const SubList& vOrigSel, const SubList& vSel, const SubList& vDefaultSel); ~CustomTransfListPainter(); }; CustomTransfListPainter::CustomTransfListPainter(const CommonData* pCommonData, const SubList& vOrigSel, const SubList& vSel, const SubList& vDefaultSel) : ListPainter(""), m_vDefaultSel(vDefaultSel) { //qDebug("init CustomTransfListPainter with origsel %d and sel %d", cSize(vOrigSel), cSize(vSel)); for (int i = 0, n = cSize(pCommonData->getAllTransf()); i < n; ++i) { m_vpOrigAll.push_back(new TransfListElem(pCommonData->getAllTransf()[i])); } m_vpResetAll = m_vpOrigAll; // !!! no new pointers m_vOrigSel = vOrigSel; m_vSel = vSel; } CustomTransfListPainter::~CustomTransfListPainter() { clearPtrContainer(m_vpOrigAll); } /*override*/ string CustomTransfListPainter::getTooltip(TooltipKey eTooltipKey) const { switch (eTooltipKey) { case SELECTED_G: return "";//"Notes to be included"; case AVAILABLE_G: return "";//"Available notes"; case ADD_B: return "Add selected transformation(s)"; case DELETE_B: return "Remove selected transformation(s)"; case ADD_ALL_B: return "";//"Add all transformations"; case DELETE_ALL_B: return "";//"Remove all transformations"; case RESTORE_DEFAULT_B: return "Restore current list to its default value"; case RESTORE_OPEN_B: return "Restore current list to the configuration it had when the window was open"; default: CB_ASSERT(false); } } /*override*/ void CustomTransfListPainter::reset() { m_vSel = m_vDefaultSel; } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class VisibleTransfPainter : public ListPainter { /*override*/ int getColCount() const { return 2; } /*override*/ std::string getColTitle(int nCol) const { return 0 == nCol ? "Action" : "Description"; } /*override*/ void getColor(int /*nIndex*/, int /*nColumn*/, bool /*bSubList*/, QColor& /*bckgColor*/, QColor& /*penColor*/, double& /*dGradStart*/, double& /*dGradEnd*/) const { } /*override*/ int getColWidth(int /*nCol*/) const { return -1; } // positive values are used for fixed widths, while negative ones are for "stretched" /*override*/ int getHdrHeight() const { return CELL_HEIGHT; } /*override*/ Qt::Alignment getAlignment(int /*nCol*/) const { return Qt::AlignTop | Qt::AlignLeft; } /*override*/ std::string getTooltip(TooltipKey eTooltipKey) const; /*override*/ void reset(); const SubList& m_vDefaultSel; // to be used by reset() public: VisibleTransfPainter(const CommonData* pCommonData, const SubList& vOrigSel, const SubList& vSel, const SubList& vDefaultSel); ~VisibleTransfPainter(); }; VisibleTransfPainter::VisibleTransfPainter(const CommonData* pCommonData, const SubList& vOrigSel, const SubList& vSel, const SubList& vDefaultSel) : ListPainter(""), m_vDefaultSel(vDefaultSel) { const vector& v (pCommonData->getAllTransf()); for (int i = 0, n = cSize(v); i < n; ++i) { const Transformation* p (v[i]); m_vpOrigAll.push_back(new TransfListElem(p)); } m_vpResetAll = m_vpOrigAll; // !!! no new pointers m_vOrigSel = vOrigSel; m_vSel = vSel; } VisibleTransfPainter::~VisibleTransfPainter() { clearPtrContainer(m_vpOrigAll); } /*override*/ string VisibleTransfPainter::getTooltip(TooltipKey eTooltipKey) const { switch (eTooltipKey) { case SELECTED_G: return "";//"Notes to be included"; case AVAILABLE_G: return "";//"Available notes"; case ADD_B: return "Add selected transformation(s)"; case DELETE_B: return "Remove selected transformation(s)"; case ADD_ALL_B: return "";//"Add all transformations"; case DELETE_ALL_B: return "";//"Remove all transformations"; case RESTORE_DEFAULT_B: return "Restore current list to its default value"; case RESTORE_OPEN_B: return "Restore current list to the configuration it had when the window was open"; default: CB_ASSERT(false); } } /*override*/ void VisibleTransfPainter::reset() { m_vSel = m_vDefaultSel; } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== namespace BpsInfo { int s_aValidBps[] = { 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 288, 320, 10000 }; //int s_aValidBps[] = { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 10000 }; int getIndex(int nVal) { if (nVal >= 10000) { return 0; } int i (0); for (; s_aValidBps[i] < nVal; ++i) {} if (10000 == s_aValidBps[i]) { return i - 1; } return i; } const QStringList& getValueList() { static QStringList lst; if (lst.isEmpty()) { for (int i = 0; ; ++i) { if (10000 == s_aValidBps[i]) { break; } lst << QString::number(s_aValidBps[i]); } } return lst; } } // namespace BpsInfo //===================================================================================================================== /* class EventFilter : public QObject { bool eventFilter(QObject* pObj, QEvent* pEvent) { if (QEvent::Paint != pEvent->type()) { qDebug("%s %d", pObj->objectName().toUtf8().constData(), (int)pEvent->type()); } static bool b (true); if (QEvent::Hide == pEvent->type()) { b = !b; if (b) { qDebug("not allowed"); pEvent->ignore(); return true; } } return QObject::eventFilter(pObj, pEvent); } public: EventFilter(QObject* pParent) : QObject(pParent) {} }; */ ConfigDlgImpl::ConfigDlgImpl(TransfConfig& transfCfg, CommonData* pCommonData, QWidget* pParent, bool bFull) : QDialog(pParent, getDialogWndFlags()), Ui::ConfigDlg(), NoteListPainterBase(pCommonData, ""), m_transfCfg(transfCfg), m_pCommonData(pCommonData), m_pCustomTransfListPainter(0), m_pCustomTransfDoubleList(0), m_vvnCustomTransf(pCommonData->getCustomTransf()), m_nCurrentTransf(-1), m_vvnDefaultCustomTransf(CUSTOM_TRANSF_CNT), m_pVisibleTransfPainter(0), m_vnVisibleTransf(pCommonData->getVisibleTransf()) { setupUi(this); #ifdef DISABLE_CHECK_FOR_UPDATES m_pCheckForUpdatesCkB->hide(); #endif if (!bFull) { m_pMainTabWidget->removeTab(6); m_pMainTabWidget->removeTab(5); m_pMainTabWidget->removeTab(4); m_pMainTabWidget->removeTab(2); m_pMainTabWidget->removeTab(1); m_pLocaleGrp->hide(); m_pCaseGrp->hide(); //m_pRenameW->hide(); m_pOthersMiscGrp->hide(); //m_pScanAtStartupCkB->hide(); //m_pShowDebugCkB->hide(); //m_pShowSessCkB->hide(); //m_pIconConfW->hide(); //m_pFontsW->hide(); m_pNormalizeGrp->hide(); m_pRenamerGrp->hide(); } m_pSourceDirF->hide(); int nWidth, nHeight; m_pCommonData->m_settings.loadConfigSize(nWidth, nHeight); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } else { defaultResize(*this); } { // set text for ID3V2 codepage test QString qstr; const Mp3Handler* p (m_pCommonData->getCrtMp3Handler()); if (0 != p) { const vector& vpStreams (p->getStreams()); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); Id3V2StreamBase* pId3V2 (dynamic_cast(p)); if (0 != pId3V2) { const vector& vpFrames (pId3V2->getFrames()); for (int i = 0, n = cSize(vpFrames); i < n; ++i) { const Id3V2Frame* pFrm (vpFrames[i]); if ('T' == pFrm->m_szName[0] && pFrm->m_bHasLatin1NonAscii) { if (!qstr.isEmpty()) { qstr += '\n'; } qstr += convStr(pFrm->getUtf8String()); } } } } } if (qstr.isEmpty()) { qstr = "If you don't know exactly what codepage you want, it's better to make current a file having an ID3V2 tag that contains text frames using the Latin-1 encoding and having non-ASCII characters. Then the content of those frames will replace this text, allowing you to decide which codepage is a match for your file."; } m_codepageTestText = qstr.toLatin1(); } /*EventFilter* pEventFilter (new EventFilter(this)); tab->installEventFilter(pEventFilter); //tab_3->installEventFilter(pEventFilter); */ { { delete m_pRemovableL; delete m_pFileSettingsW->layout(); m_pFileSettingsLayout = new QStackedLayout(m_pFileSettingsW); //m_pFileSettingsLayout->setContentsMargins(0, 50, 50, 0); //m_pFileSettingsW->setLayout(m_pFileSettingsLayout); m_pFileSettingsLayout->addWidget(m_pSimpleViewTab); m_pFileSettingsLayout->addWidget(m_pFullViewTab); delete m_pDetailsTabWidget; } m_pPODestE->setText(toNativeSeparators(convStr(getSepTerminatedDir(transfCfg.getProcOrigDir())))); m_pPODest2E->setText(m_pPODestE->text()); m_pUODestE->setText(toNativeSeparators(convStr(getSepTerminatedDir(transfCfg.getUnprocOrigDir())))); m_pProcDestE->setText(toNativeSeparators(convStr(getSepTerminatedDir(transfCfg.getProcessedDir())))); m_pTempDestE->setText(toNativeSeparators(convStr(getSepTerminatedDir(transfCfg.getTempDir())))); m_pCompDestE->setText(toNativeSeparators(convStr(getSepTerminatedDir(transfCfg.getCompDir())))); m_pSrcDirE->setText(toNativeSeparators(convStr(getSepTerminatedDir(transfCfg.getSrcDir())))); //setSimpleViewOpt(transfCfg.m_options); //!!! pointless; doesn't work if keepTime is true; anyway, the on_m_pSimpleViewB_clicked() call below will select the right radiobutton setFullViewOpt(transfCfg.m_options); // !!! the buttons should be set for both views setSimpleViewOpt(transfCfg.m_options); TransfConfig::Options opt (transfCfg.m_options); if (opt.asBackup() == opt || opt.asNonBackup() == opt) { m_pSimpleViewB->setChecked(true); on_m_pSimpleViewB_clicked(); } else { m_pFullViewB->setChecked(true); on_m_pFullViewB_clicked(); } m_pKeepOrigTimeCkB->setChecked(transfCfg.m_options.m_bKeepOrigTime); } // -------------------------------------------- ignored ------------------------------------------------------ m_pIgnoredNotesListHldr->setLayout(new QHBoxLayout()); const vector& vpAllNotes (Notes::getAllNotes()); for (int i = 0, n = cSize(vpAllNotes); i < n; ++i) { m_vpOrigAll.push_back(new NoteListElem(vpAllNotes[i], m_pCommonData)); } m_vOrigSel = pCommonData->getIgnoredNotes(); //cout << "constr:\n"; printContainer(pCommonData->m_vnIgnoredNotes, cout); m_vSel = m_vOrigSel; m_pDoubleList = new DoubleList( *this, DoubleList::ADD_ALL | DoubleList::DEL_ALL | DoubleList::RESTORE_OPEN | DoubleList::RESTORE_DEFAULT, DoubleList::SINGLE_UNSORTABLE, "Other notes", "Ignore notes", this); m_pIgnoredNotesListHldr->layout()->addWidget(m_pDoubleList); m_pIgnoredNotesListHldr->layout()->setContentsMargins(0, 0, 0, 0); // -------------------------------------------- custom transformations ------------------------------------------------------ m_pTransfListHldr->setLayout(new QHBoxLayout()); m_pTransfListHldr->layout()->setContentsMargins(0, 0, 0, 0); m_vpTransfButtons.push_back(m_pCustomTransform1B); m_vpTransfButtons.push_back(m_pCustomTransform2B); m_vpTransfButtons.push_back(m_pCustomTransform3B); m_vpTransfButtons.push_back(m_pCustomTransform4B); // CUSTOM_TRANSF_CNT m_defaultPalette = m_pCustomTransform1T->palette(); m_wndPalette = m_pCustomTransform1T->palette(); m_wndPalette.setColor(QPalette::Base, m_wndPalette.color(QPalette::Disabled, QPalette::Window)); m_vpTransfLabels.push_back(m_pCustomTransform1T); m_vpTransfLabels.push_back(m_pCustomTransform2T); m_vpTransfLabels.push_back(m_pCustomTransform3T); m_vpTransfLabels.push_back(m_pCustomTransform4T); // CUSTOM_TRANSF_CNT for (int i = 0; i < CUSTOM_TRANSF_CNT; ++i) { m_vpTransfLabels[i]->setPalette(m_wndPalette); refreshTransfText(i); initDefaultCustomTransf(i, m_vvnDefaultCustomTransf, m_pCommonData); } selectCustomTransf(0); const QStringList& freqLst (BpsInfo::getValueList()); { m_pQualStCbrCbB->insertItems(0, freqLst); m_pQualStCbrCbB->setCurrentIndex(BpsInfo::getIndex(m_pCommonData->getQualThresholds().m_nStereoCbr/1000)); } { m_pQualJtStCbrCbB->insertItems(0, freqLst); m_pQualJtStCbrCbB->setCurrentIndex(BpsInfo::getIndex(m_pCommonData->getQualThresholds().m_nJointStereoCbr/1000)); } { m_pQualDlChCbrCbB->insertItems(0, freqLst); m_pQualDlChCbrCbB->setCurrentIndex(BpsInfo::getIndex(m_pCommonData->getQualThresholds().m_nDoubleChannelCbr/1000)); } // ttt2 try and create some custom widget based on QSpinBox for CBR, so only valid frequencies can be chosen; m_pQualStVbrSB->setValue(m_pCommonData->getQualThresholds().m_nStereoVbr/1000); m_pQualJtStVbrSB->setValue(m_pCommonData->getQualThresholds().m_nJointStereoVbr/1000); m_pQualDlChVbrSB->setValue(m_pCommonData->getQualThresholds().m_nDoubleChannelVbr/1000); { // locale QStringList lNames; set s; //set s1; QList l (QTextCodec::availableCodecs()); for (int i = 0, n = l.size(); i < n; ++i) { //lNames << QString::fromLatin1(l[i]); //lNames << QTextCodec::codecForName(l[i])->name(); s.insert(QTextCodec::codecForName(l[i])->name()); // a codec is known by several names; by doing this we eliminate redundant names and make the list a lot smaller //s.insert(QTextCodec::codecForName(l[i])->name() + QString::fromLatin1(l[i])); //qDebug("%s", (QString::fromLatin1(l[i]) + " / " + QTextCodec::codecForName(l[i])->name()).toUtf8().data()); //s1.insert(QTextCodec::codecForName(l[i])->name() + " / " + QString::fromLatin1(l[i])); } for (set::const_iterator it = s.begin(); it != s.end(); ++it) { lNames << *it; } //for (set::const_iterator it = s1.begin(); it != s1.end(); ++it) { qDebug("%s", it->toUtf8().data()); } //lNames.sort(); m_pLocaleCbB->addItems(lNames); int n (m_pLocaleCbB->findText(m_pCommonData->m_locale)); if (-1 == n) { n = 0; } m_pLocaleCbB->setCurrentIndex(n); } { // case QStringList lNames; /*lNames << "Lower case: first part. second part."; lNames << "Upper case: FIRST PART. SECOND PART."; lNames << "Title case: First Part. Second Part."; lNames << "Sentence case: First part. Second part.";*/ // ttt2 perhaps put this back; as of 2009.10.15, "." is no longer supported as a sentence ending lNames << "lower case"; lNames << "UPPER CASE"; lNames << "Title Case"; lNames << "Sentence case"; m_pArtistsCaseCbB->addItems(lNames); m_pOthersCaseCbB->addItems(lNames); m_pArtistsCaseCbB->setCurrentIndex((int)m_pCommonData->m_eCaseForArtists); m_pOthersCaseCbB->setCurrentIndex((int)m_pCommonData->m_eCaseForOthers); } { // colors m_vpColButtons.push_back(m_pCol0B); m_vpColButtons.push_back(m_pCol1B); m_vpColButtons.push_back(m_pCol2B); m_vpColButtons.push_back(m_pCol3B); m_vpColButtons.push_back(m_pCol4B); m_vpColButtons.push_back(m_pCol5B); m_vpColButtons.push_back(m_pCol6B); m_vpColButtons.push_back(m_pCol7B); m_vpColButtons.push_back(m_pCol8B); m_vpColButtons.push_back(m_pCol9B); m_vpColButtons.push_back(m_pCol10B); m_vpColButtons.push_back(m_pCol11B); m_vpColButtons.push_back(m_pCol12B); m_vpColButtons.push_back(m_pCol13B); m_vNoteCategColors = m_pCommonData->m_vNoteCategColors; for (int i = 0; i < cSize(m_vpColButtons); ++i) { setBtnColor(i); } } { // tag editor m_pWarnOnNonSeqTracksCkB->setChecked(m_pCommonData->m_bWarnOnNonSeqTracks); m_pWarnOnPasteToNonSeqTracksCkB->setChecked(m_pCommonData->m_bWarnPastingToNonSeqTracks); } { //misc m_pScanAtStartupCkB->setChecked(m_pCommonData->m_bScanAtStartup); m_pFastSaveCkB->setChecked(m_pCommonData->useFastSave()); m_pShowExportCkB->setChecked(m_pCommonData->m_bShowExport); m_pShowDebugCkB->setChecked(m_pCommonData->m_bShowDebug); m_pShowSessCkB->setChecked(m_pCommonData->m_bShowSessions); m_pNormalizerE->setText(convStr(m_pCommonData->m_strNormalizeCmd)); m_pKeepNormOpenCkB->setChecked(m_pCommonData->m_bKeepNormWndOpen); switch (m_pCommonData->m_eAssignSave) { case CommonData::SAVE: m_pAssgnSaveRB->setChecked(true); break; case CommonData::DISCARD: m_pAssgnDiscardRB->setChecked(true); break; case CommonData::ASK: m_pAssgnAskRB->setChecked(true); break; default: CB_ASSERT (false); } switch (m_pCommonData->m_eNonId3v2Save) { case CommonData::SAVE: m_pNonId3v2SaveRB->setChecked(true); break; case CommonData::DISCARD: m_pNonId3v2DiscardRB->setChecked(true); break; case CommonData::ASK: m_pNonId3v2AskRB->setChecked(true); break; default: CB_ASSERT (false); } m_pIconSizeSB->setValue(m_pCommonData->m_nMainWndIconSize); m_pAutoSizeIconsCkB->setChecked(m_pCommonData->m_bAutoSizeIcons); m_pKeepOneValidImgCkB->setChecked(m_pCommonData->m_bKeepOneValidImg); m_pWmpCkB->setChecked(m_pCommonData->m_bWmpVarArtists); m_pItunesCkB->setChecked(m_pCommonData->m_bItunesVarArtists); m_pMaxImgSizeSB->setValue(ImageInfo::MAX_IMAGE_SIZE/1024); m_pTraceToFileCkB->setChecked(m_pCommonData->isTraceToFileEnabled()); m_pInvalidCharsE->setText(convStr(m_pCommonData->m_strRenamerInvalidChars)); m_pInvalidReplacementE->setText(convStr(m_pCommonData->m_strRenamerReplacementString)); m_pCheckForUpdatesCkB->setChecked("yes" == m_pCommonData->m_strCheckForNewVersions); m_generalFont = m_pCommonData->getNewGeneralFont(); m_pDecrLabelFontSB->setValue(m_pCommonData->getLabelFontSizeDecr()); m_fixedFont = m_pCommonData->getNewFixedFont(); setFontLabels(); } { initDefaultVisibleTransf(m_vnDefaultVisibleTransf, m_pCommonData); m_pVisibleTransfPainter = new VisibleTransfPainter(m_pCommonData, m_pCommonData->getVisibleTransf(), m_vnVisibleTransf, m_vnDefaultVisibleTransf); m_pVisibleTransfDoubleList = new DoubleList( *m_pVisibleTransfPainter, DoubleList::RESTORE_OPEN | DoubleList::RESTORE_DEFAULT, DoubleList::SINGLE_SORTABLE, "Invisible transformations", "Visible transformations", this); m_pVisibleTransformsHndlr->setLayout(new QHBoxLayout()); m_pVisibleTransformsHndlr->layout()->setContentsMargins(0, 0, 0, 0); m_pVisibleTransformsHndlr->layout()->addWidget(m_pVisibleTransfDoubleList); } m_pSrcDirE->setFocus(); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } m_pInvalidCharsE->setToolTip("Characters in this list get replaced with the string below, in \"Replace with\"\n\n" "An underlined font is used to allow spaces to be seen"); m_pInvalidReplacementE->setToolTip("This string replaces invalid characters in the file renamer\"\n\n" "An underlined font is used to allow spaces to be seen"); } void ConfigDlgImpl::setBtnColor(int n) { // QPalette pal (m_vpColButtons[n]->palette()); //QPalette pal (m_pCol0B->palette()); /* pal.setBrush(QPalette::Button, m_vNoteCategColors[n]); pal.setBrush(QPalette::Window, m_vNoteCategColors[n]); pal.setBrush(QPalette::Midlight, QColor(255, 0, 0)); pal.setBrush(QPalette::Dark, QColor(255, 0, 0)); pal.setBrush(QPalette::Mid, QColor(255, 0, 0)); pal.setBrush(QPalette::Shadow, QColor(255, 0, 0));*/ //m_vpColButtons[n]->setPalette(pal); int f (QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, m_vpColButtons.at(n)) + 2); //ttt2 hard-coded "2" int w (m_vpColButtons[n]->width() - f), h (m_vpColButtons[n]->height() - f); QPixmap pic (w, h); QPainter pntr (&pic); pntr.fillRect(0, 0, w, h, m_vNoteCategColors.at(n)); m_vpColButtons[n]->setIcon(pic); m_vpColButtons[n]->setIconSize(QSize(w, h)); } void ConfigDlgImpl::onButtonClicked(int n) { QColor c (QColorDialog::getColor(m_vNoteCategColors.at(n), this)); if (!c.isValid()) { return; } m_vNoteCategColors[n] = c; setBtnColor(n); } void ConfigDlgImpl::on_m_pResetColorsB_clicked() { QColor c (getDefaultBkgCol()); for (int i = 0; i < cSize(m_vNoteCategColors) - 1; ++i) // !!! "-1" because there is no configuration for CUSTOM colors { m_vNoteCategColors[i] = c; setBtnColor(i); } } void SessionSettings::saveTransfConfig(const TransfConfig& transfConfig) { m_pSettings->remove("transformation"); m_pSettings->setValue("transformation/srcDir", convStr(transfConfig.getSrcDir())); m_pSettings->setValue("transformation/procOrigDir", convStr(transfConfig.getProcOrigDir())); m_pSettings->setValue("transformation/unprocOrigDir", convStr(transfConfig.getUnprocOrigDir())); m_pSettings->setValue("transformation/processedDir", convStr(transfConfig.getProcessedDir())); m_pSettings->setValue("transformation/tempDir", convStr(transfConfig.getTempDir())); m_pSettings->setValue("transformation/compDir", convStr(transfConfig.getCompDir())); m_pSettings->setValue("transformation/options", transfConfig.getOptions()); /*if (transfConfig.getOptions() != 14349) //ttt remove { qDebug("cfg changed: %x", transfConfig.getOptions()); }*/ } // returns false if there was some error while loading (so the user can be told about defaults being used and those defaults could get saved) bool SessionSettings::loadTransfConfig(TransfConfig& transfConfig) const { try { //TransfConfig tc ("/r/temp/1", "/r/temp/1", "/r/temp/1/proc", "/r/temp/1/temp_mp3"); TransfConfig tc ( convStr(m_pSettings->value("transformation/srcDir", "*").toString()), convStr(m_pSettings->value("transformation/procOrigDir", "*").toString()), convStr(m_pSettings->value("transformation/unprocOrigDir", "*").toString()), convStr(m_pSettings->value("transformation/processedDir", "*").toString()), convStr(m_pSettings->value("transformation/tempDir", "*").toString()), convStr(m_pSettings->value("transformation/compDir", "*").toString()), m_pSettings->value("transformation/options", -1).toInt() ); transfConfig = tc; return !tc.hadInitError(); } catch (const IncorrectDirName&) { TransfConfig tc ("*", "*", "*", "*", "*", "*", -1); transfConfig = tc; return false; } } bool ConfigDlgImpl::run() { TRACER("ConfigDlgImpl::run()"); if (QDialog::Accepted != exec()) { return false; } m_pCommonData->m_settings.saveConfigSize(width(), height()); return true; } void ConfigDlgImpl::on_m_pLocaleCbB_currentIndexChanged(int) { QTextCodec* pCodec (QTextCodec::codecForName(m_pLocaleCbB->currentText().toLatin1())); CB_ASSERT (0 != pCodec); QString qstrTxt (pCodec->toUnicode(m_codepageTestText)); m_pCodepageTestM->setText(qstrTxt); } //ttt2 treat "orig" and "proc" files as "orig" when processing them void initDefaultCustomTransf(int k, vector >& vv, CommonData* pCommonData) { vector& v (vv[k]); switch (k) { case 0: v.push_back(pCommonData->getTransfPos(SingleBitRepairer::getClassName())); v.push_back(pCommonData->getTransfPos(InnerNonAudioRemover::getClassName())); v.push_back(pCommonData->getTransfPos(TruncatedMpegDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(VbrRepairer::getClassName())); v.push_back(pCommonData->getTransfPos(MismatchedXingRemover::getClassName())); // !!! takes care of broken Xing headers for CBR files (VbrRepairer only deals with VBR files) break; case 1: v.push_back(pCommonData->getTransfPos(Id3V2Rescuer::getClassName())); v.push_back(pCommonData->getTransfPos(UnsupportedId3V2Remover::getClassName())); //v.push_back(pCommonData->getTransfPos(MultipleId3StreamRemover::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V1ToId3V2Copier::getClassName())); break; case 2: v.push_back(pCommonData->getTransfPos(InnerNonAudioRemover::getClassName())); v.push_back(pCommonData->getTransfPos(UnknownDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(BrokenDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(UnsupportedDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(TruncatedMpegDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(NullStreamRemover::getClassName())); //v.push_back(pCommonData->getTransfPos(MultipleId3StreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(MismatchedXingRemover::getClassName())); break; case 3: // CUSTOM_TRANSF_CNT v.push_back(pCommonData->getTransfPos(SingleBitRepairer::getClassName())); v.push_back(pCommonData->getTransfPos(InnerNonAudioRemover::getClassName())); v.push_back(pCommonData->getTransfPos(TruncatedMpegDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(VbrRepairer::getClassName())); v.push_back(pCommonData->getTransfPos(MismatchedXingRemover::getClassName())); // !!! takes care of broken Xing headers for CBR files (VbrRepairer only deals with VBR files) v.push_back(pCommonData->getTransfPos(Id3V2Rescuer::getClassName())); v.push_back(pCommonData->getTransfPos(UnsupportedId3V2Remover::getClassName())); v.push_back(pCommonData->getTransfPos(MultipleId3StreamRemover::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V1ToId3V2Copier::getClassName())); //v.push_back(pCommonData->getTransfPos(InnerNonAudioRemover::getClassName())); v.push_back(pCommonData->getTransfPos(UnknownDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(BrokenDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(UnsupportedDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(TruncatedMpegDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(NullStreamRemover::getClassName())); //v.push_back(pCommonData->getTransfPos(MultipleId3StreamRemover::getClassName())); //v.push_back(pCommonData->getTransfPos(MismatchedXingRemover::getClassName())); break; default: CB_ASSERT (false); } } void initDefaultVisibleTransf(vector& v, CommonData* pCommonData) { v.push_back(pCommonData->getTransfPos(SingleBitRepairer::getClassName())); v.push_back(pCommonData->getTransfPos(InnerNonAudioRemover::getClassName())); v.push_back(pCommonData->getTransfPos(UnknownDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(BrokenDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(UnsupportedDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(TruncatedMpegDataStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(NullStreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(BrokenId3V2Remover::getClassName())); v.push_back(pCommonData->getTransfPos(UnsupportedId3V2Remover::getClassName())); //v.push_back(pCommonData->getTransfPos(IdentityTransformation::getClassName())); v.push_back(pCommonData->getTransfPos(MultipleId3StreamRemover::getClassName())); v.push_back(pCommonData->getTransfPos(MismatchedXingRemover::getClassName())); v.push_back(pCommonData->getTransfPos(TruncatedAudioPadder::getClassName())); v.push_back(pCommonData->getTransfPos(VbrRepairer::getClassName())); v.push_back(pCommonData->getTransfPos(VbrRebuilder::getClassName())); v.push_back(pCommonData->getTransfPos(Id3V2Cleaner::getClassName())); v.push_back(pCommonData->getTransfPos(Id3V2Rescuer::getClassName())); v.push_back(pCommonData->getTransfPos(Id3V2UnicodeTransformer::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V2CaseTransformer::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V2ComposerAdder::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V2ComposerRemover::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V2ComposerCopier::getClassName())); //v.push_back(pCommonData->getTransfPos(SmallerImageRemover::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V1ToId3V2Copier::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V1Remover::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V2Compactor::getClassName())); //v.push_back(pCommonData->getTransfPos(Id3V2Expander::getClassName())); } ConfigDlgImpl::~ConfigDlgImpl() { clearPtrContainer(m_vpOrigAll); clearPtrContainer(m_vpResetAll); // doesn't matter if it was used or not, or if m_bResultInReset is true or false delete m_pVisibleTransfPainter; delete m_pCustomTransfListPainter; } void ConfigDlgImpl::refreshTransfText(int k) { QString s; for (int i = 0, n = cSize(m_vvnCustomTransf[k]); i < n; ++i) { s += m_pCommonData->getAllTransf()[m_vvnCustomTransf[k][i]]->getActionName(); if (i < n - 1) { s += "\n"; } } m_vpTransfLabels[k]->setText(s); } void ConfigDlgImpl::selectCustomTransf(int k) // 0 <= k <= 2 { getTransfData(); delete m_pCustomTransfDoubleList; delete m_pCustomTransfListPainter; m_pCustomTransfListPainter = new CustomTransfListPainter(m_pCommonData, m_pCommonData->getCustomTransf()[k], m_vvnCustomTransf[k], m_vvnDefaultCustomTransf[k]); m_pCustomTransfDoubleList = new DoubleList( *m_pCustomTransfListPainter, DoubleList::RESTORE_OPEN | DoubleList::RESTORE_DEFAULT, DoubleList::MULTIPLE, "All transformations", "Used transformations", this); m_pTransfListHldr->layout()->addWidget(m_pCustomTransfDoubleList); //m_pTransfListHldr->layout()->activate(); //?->300x358//m_pCustomTransfDoubleList->layout()->activate(); //m_pCustomTransfDoubleList->resizeOnShow(); //m_pDetailsTabWidget->setCurrentIndex(0); //m_pDetailsTabWidget->setCurrentIndex(2); for (int i = 0; i < CUSTOM_TRANSF_CNT; ++i) { m_vpTransfButtons[i]->setChecked(false); m_vpTransfLabels[i]->setPalette(m_wndPalette); } m_vpTransfButtons[k]->setChecked(true); m_vpTransfLabels[k]->setPalette(m_defaultPalette); m_nCurrentTransf = k; connect(m_pCustomTransfDoubleList, SIGNAL(dataChanged()), this, SLOT(onTransfDataChanged())); } void ConfigDlgImpl::onTransfDataChanged() { getTransfData(); } void ConfigDlgImpl::getTransfData() { if (-1 == m_nCurrentTransf) { return; } m_vvnCustomTransf[m_nCurrentTransf] = m_pCustomTransfListPainter->getSel(); //qDebug("transf %d at %d", cSize(m_vvnCustomTransf[m_nCurrentTransf]), m_nCurrentTransf); refreshTransfText(m_nCurrentTransf); } void ConfigDlgImpl::on_m_pOkB_clicked() { { string strInv (convStr(m_pInvalidCharsE->text())); string strRepl (convStr(m_pInvalidReplacementE->text())); if (!strInv.empty()) { string::size_type n (strRepl.find_first_of(strInv)); if (string::npos != n) { QMessageBox::critical(this, "Error", QString("You can't have '") + strRepl[n] + "' in both the list of invalid characters and the string that invalid characters are replaced with."); return; } } } //logState("on_m_pOkB_clicked 1"); try { TransfConfig::Options opt (getOpt()); TransfConfig cfg ( getNonSepTerminatedDir(convStr(fromNativeSeparators(m_pSrcDirE->text()))), getNonSepTerminatedDir(convStr(fromNativeSeparators((m_pSimpleViewB->isChecked() ? m_pPODest2E : m_pPODestE)->text()))), getNonSepTerminatedDir(convStr(fromNativeSeparators(m_pUODestE->text()))), getNonSepTerminatedDir(convStr(fromNativeSeparators(m_pProcDestE->text()))), getNonSepTerminatedDir(convStr(fromNativeSeparators(m_pTempDestE->text()))), getNonSepTerminatedDir(convStr(fromNativeSeparators(m_pCompDestE->text()))), opt.getVal() ); m_transfCfg = cfg; { // ignored m_pCommonData->setIgnoredNotes(m_vSel); //cout << "OK:\n"; printContainer(m_pCommonData->m_vnIgnoredNotes, cout); } { // custom transformations getTransfData(); m_pCommonData->setCustomTransf(m_vvnCustomTransf); } { //m_pCommonData->setVisibleTransf(m_vnVisibleTransf); m_pCommonData->setVisibleTransf(m_pVisibleTransfPainter->getSel()); } { QualThresholds q; q.m_nStereoCbr = BpsInfo::s_aValidBps[m_pQualStCbrCbB->currentIndex()]*1000; q.m_nJointStereoCbr = BpsInfo::s_aValidBps[m_pQualJtStCbrCbB->currentIndex()]*1000; q.m_nDoubleChannelCbr = BpsInfo::s_aValidBps[m_pQualDlChCbrCbB->currentIndex()]*1000; q.m_nStereoVbr = m_pQualStVbrSB->value()*1000; q.m_nJointStereoVbr = m_pQualJtStVbrSB->value()*1000; q.m_nDoubleChannelVbr = m_pQualDlChVbrSB->value()*1000; m_pCommonData->setQualThresholds(q); } { m_pCommonData->m_locale = m_pLocaleCbB->currentText().toLatin1(); m_pCommonData->m_pCodec = QTextCodec::codecForName(m_pCommonData->m_locale); CB_ASSERT (0 != m_pCommonData->m_pCodec); } { // case m_pCommonData->m_eCaseForArtists = (TextCaseOptions)m_pArtistsCaseCbB->currentIndex(); //ttt2 perhaps allow NONE m_pCommonData->m_eCaseForOthers = (TextCaseOptions)m_pOthersCaseCbB->currentIndex(); } { // colors m_pCommonData->m_vNoteCategColors = m_vNoteCategColors; } { // tag editor m_pCommonData->m_bWarnOnNonSeqTracks = m_pWarnOnNonSeqTracksCkB->isChecked(); m_pCommonData->m_bWarnPastingToNonSeqTracks = m_pWarnOnPasteToNonSeqTracksCkB->isChecked(); } { // misc m_pCommonData->m_bScanAtStartup = m_pScanAtStartupCkB->isChecked(); m_pCommonData->setFastSave(m_pFastSaveCkB->isChecked(), CommonData::UPDATE_TRANSFORMS); m_pCommonData->m_bShowExport = m_pShowExportCkB->isChecked(); m_pCommonData->m_bShowDebug = m_pShowDebugCkB->isChecked(); m_pCommonData->m_bShowSessions = m_pShowSessCkB->isChecked(); m_pCommonData->m_strNormalizeCmd = convStr(m_pNormalizerE->text()); m_pCommonData->m_bKeepNormWndOpen = m_pKeepNormOpenCkB->isChecked(); m_pCommonData->m_eAssignSave = m_pAssgnSaveRB->isChecked() ? CommonData::SAVE : m_pAssgnDiscardRB->isChecked() ? CommonData::DISCARD : CommonData::ASK; m_pCommonData->m_eNonId3v2Save = m_pNonId3v2SaveRB->isChecked() ? CommonData::SAVE : m_pNonId3v2DiscardRB->isChecked() ? CommonData::DISCARD : CommonData::ASK; m_pCommonData->m_nMainWndIconSize = m_pIconSizeSB->value(); m_pCommonData->m_bAutoSizeIcons = m_pAutoSizeIconsCkB->isChecked(); m_pCommonData->m_bKeepOneValidImg = m_pKeepOneValidImgCkB->isChecked(); m_pCommonData->m_bWmpVarArtists = m_pWmpCkB->isChecked(); m_pCommonData->m_bItunesVarArtists = m_pItunesCkB->isChecked(); ImageInfo::MAX_IMAGE_SIZE = m_pMaxImgSizeSB->value()*1024; //ttt2 inconsistent to keep this in static var and the others in CommonData; perhaps switch to a global CommonData that anybody can access, without passing it in params m_pCommonData->setTraceToFile(m_pTraceToFileCkB->isChecked()); m_pCommonData->setFontInfo(convStr(m_generalFont.family()), m_generalFont.pointSize(), m_pDecrLabelFontSB->value(), convStr(m_fixedFont.family()), m_fixedFont.pointSize()); m_pCommonData->m_strRenamerInvalidChars = convStr(m_pInvalidCharsE->text()); m_pCommonData->m_strRenamerReplacementString = convStr(m_pInvalidReplacementE->text()); m_pCommonData->m_strCheckForNewVersions = m_pCheckForUpdatesCkB->isChecked() ? "yes" : "no"; } accept(); } catch (const IncorrectDirName&) { QMessageBox::critical(this, "Invalid folder name", "A folder name is incorrect."); //ttt2 say which name } } void ConfigDlgImpl::on_m_pCancelB_clicked() { reject(); } void ConfigDlgImpl::on_m_pChangeGenFontB_clicked() { bool bOk; QFont font = QFontDialog::getFont(&bOk, m_generalFont, this); //ttt2 see if possible to remove "What's this" button if (!bOk) { return; } m_generalFont = font; setFontLabels(); } void ConfigDlgImpl::on_m_pChangeFixedFontB_clicked() { bool bOk; QFont font = QFontDialog::getFont(&bOk, m_fixedFont, this); if (!bOk) { return; } m_fixedFont = font; setFontLabels(); } void ConfigDlgImpl::setFontLabels() { m_pGeneralFontL->setText(QString("%1, %2pt").arg(m_generalFont.family()).arg(m_generalFont.pointSize())); m_pGeneralFontL->setFont(m_generalFont); m_pFixedFontL->setText(QString("%1, %2pt").arg(m_fixedFont.family()).arg(m_fixedFont.pointSize())); m_pFixedFontL->setFont(m_fixedFont); QFont f (m_fixedFont); f.setUnderline(true); m_pInvalidReplacementE->setFont(f); m_pInvalidCharsE->setFont(f); } void ConfigDlgImpl::logState(const char* /*szPlace*/) const { /*cout << szPlace << ": m_filter.m_vSelDirs=" << m_pCommonData->m_filter.m_vSelDirs.size() << " m_availableDirs.m_vstrDirs=" << m_availableDirs.m_vstrDirs.size() << " m_selectedDirs.m_vSelDirs=" << m_selectedDirs.m_vstrDirs.size() << endl;*/ } //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- /*override*/ string ConfigDlgImpl::getTooltip(TooltipKey eTooltipKey) const { switch (eTooltipKey) { case SELECTED_G: return "";//"Notes to be included"; case AVAILABLE_G: return "";//"Available notes"; case ADD_B: return "Add selected note(s)"; case DELETE_B: return "Remove selected note(s)"; case ADD_ALL_B: return "Add all notes"; case DELETE_ALL_B: return "Remove all notes"; case RESTORE_DEFAULT_B: return "Restore lists to their default value"; case RESTORE_OPEN_B: return "Restore lists to the configuration they had when the window was open"; default: CB_ASSERT(false); } } /*override*/ void ConfigDlgImpl::reset() { if (m_vpResetAll.empty()) { const vector& v (Notes::getAllNotes()); for (int i = 0, n = cSize(v); i < n; ++i) { const Note* p (v[i]); m_vpResetAll.push_back(new NoteListElem(p, m_pCommonData)); } } m_vSel = Notes::getDefaultIgnoredNoteIds(); } void ConfigDlgImpl::selectDir(QLineEdit* pEdt) { QString qstrStart (fromNativeSeparators(pEdt->text())); qstrStart = convStr(getExistingDir(convStr(qstrStart))); if (qstrStart.isEmpty()) { qstrStart = getTempDir(); } QFileDialog dlg (this, "Select folder", qstrStart, "All files (*)"); dlg.setFileMode(QFileDialog::Directory); if (QDialog::Accepted != dlg.exec()) { return; } QStringList fileNames (dlg.selectedFiles()); if (1 != fileNames.size()) { return; } QString s (fileNames.first()); QString s1 (getPathSep()); if ("//" == s) { s = "/"; } if (!s.endsWith(s1)) { s += s1; } pEdt->setText(toNativeSeparators(s)); } void ConfigDlgImpl::onHelp() { switch(m_pMainTabWidget->currentIndex()) { case 0: openHelp("250_config_files.html"); break; case 1: openHelp("260_config_ignored_notes.html"); break; case 2: openHelp("270_config_custom_transf.html"); break; case 3: openHelp("290_config_transf_params.html"); break; case 4: openHelp("292_config_visible_transf.html"); break; case 5: openHelp("295_config_quality.html"); break; case 6: openHelp("297_config_colors.html"); break; case 7: openHelp("300_config_others.html"); break; //tttr revise as needed default: /*openHelp("index.html");*/ break; } } void ConfigDlgImpl::on_m_pFastSaveCkB_stateChanged() { if (0 == m_pVisibleTransfPainter) { return; } if (m_pFastSaveCkB->isChecked()) { const vector& vnAvail (m_pVisibleTransfPainter->getAvailable()); const vector& vpAll (m_pVisibleTransfPainter->getAll()); set s; for (int i = 0; i < cSize(vnAvail); ++i) { const TransfListElem* p (dynamic_cast(vpAll.at(vnAvail.at(i)))); CB_ASSERT (0 != p); if (p->getTransformation()->getActionName() == string(Id3V2Compactor::getClassName()) || p->getTransformation()->getActionName() == string(Id3V2Expander::getClassName())) { s.insert(i); } } m_pVisibleTransfDoubleList->add(s); } else { const vector& vnSel (m_pVisibleTransfPainter->getSel()); const vector& vpAll (m_pVisibleTransfPainter->getAll()); set s; for (int i = 0; i < cSize(vnSel); ++i) { const TransfListElem* p (dynamic_cast(vpAll.at(vnSel.at(i)))); CB_ASSERT (0 != p); if (p->getTransformation()->getActionName() == string(Id3V2Compactor::getClassName()) || p->getTransformation()->getActionName() == string(Id3V2Expander::getClassName())) { s.insert(i); } } m_pVisibleTransfDoubleList->remove(s); } } TransfConfig::Options ConfigDlgImpl::getSimpleViewOpt() // doesn't set m_bKeepOrigTime { TransfConfig::Options opt (getFullViewOpt()); if (m_pBackupCustomRB->isChecked()) { return opt; } if (m_pDontCreateBackupRB->isChecked()) { return opt.asNonBackup(); } return opt.asBackup(); } TransfConfig::Options ConfigDlgImpl::getFullViewOpt() // doesn't set m_bKeepOrigTime { TransfConfig::Options opt; opt.m_eProcOrigChange = m_pPODontChangeRB->isChecked() ? TransfConfig::Options::PO_DONT_CHG : m_pPOEraseRB->isChecked() ? TransfConfig::Options::PO_ERASE : m_pPOMoveAlwaysChangeRB->isChecked() ? TransfConfig::Options::PO_MOVE_ALWAYS_RENAME : m_pPOMoveChangeIfNeededRB->isChecked() ? TransfConfig::Options::PO_MOVE_RENAME_IF_USED : m_pPOChangeNameRB->isChecked() ? TransfConfig::Options::PO_RENAME_SAME_DIR : m_pPOMoveOrEraseRB->isChecked() ? TransfConfig::Options::PO_MOVE_OR_ERASE : TransfConfig::Options::ProcOrig(7); CB_ASSERT (7 != opt.m_eProcOrigChange); opt.m_bProcOrigUseLabel = m_pPOUseLabelRB->isChecked(); opt.m_bProcOrigAlwayUseCounter = m_pPOAlwaysUseCounterRB->isChecked(); opt.m_eUnprocOrigChange = m_pUODontChangeRB->isChecked() ? TransfConfig::Options::UPO_DONT_CHG : m_pUOEraseRB->isChecked() ? TransfConfig::Options::UPO_ERASE : m_pUOMoveAlwaysChangeRB->isChecked() ? TransfConfig::Options::UPO_MOVE_ALWAYS_RENAME : m_pUOMoveChangeIfNeededRB->isChecked() ? TransfConfig::Options::UPO_MOVE_RENAME_IF_USED : m_pUOChangeNameRB->isChecked() ? TransfConfig::Options::UPO_RENAME_SAME_DIR : TransfConfig::Options::UnprocOrig(7); CB_ASSERT (7 != opt.m_eUnprocOrigChange); opt.m_bUnprocOrigUseLabel = m_pUOUseLabelRB->isChecked(); opt.m_bUnprocOrigAlwayUseCounter = m_pUOAlwaysUseCounterRB->isChecked(); opt.m_eProcessedCreate = m_pProcDontCreateRB->isChecked() ? TransfConfig::Options::PR_DONT_CREATE : m_pProcCreateAlwaysChangeRB->isChecked() ? TransfConfig::Options::PR_CREATE_ALWAYS_RENAME : m_pProcCreateChangeIfNeededRB->isChecked() ? TransfConfig::Options::PR_CREATE_RENAME_IF_USED : TransfConfig::Options::Processed(3); CB_ASSERT (3 != opt.m_eProcessedCreate); opt.m_bProcessedUseLabel = m_pProcUseLabelRB->isChecked(); opt.m_bProcessedAlwayUseCounter = m_pProcAlwaysUseCounterRB->isChecked(); opt.m_bProcessedUseSeparateDir = m_pProcUseSeparateDirRB->isChecked(); opt.m_bTempCreate = m_pTempCreateRB->isChecked(); opt.m_bCompCreate = m_pCompCreateRB->isChecked(); return opt; } TransfConfig::Options ConfigDlgImpl::getOpt() // has the correct m_bKeepOrigTime { TransfConfig::Options opt (m_pSimpleViewB->isChecked() ? getSimpleViewOpt() : getFullViewOpt()); opt.m_bKeepOrigTime = m_pKeepOrigTimeCkB->isChecked(); return opt; } void ConfigDlgImpl::setSimpleViewOpt(const TransfConfig::Options& opt) // m_bKeepOrigTime shouldn't be set { if (opt == opt.asNonBackup()) { m_pDontCreateBackupRB->setChecked(true); } else if (opt == opt.asBackup()) { m_pCreateBackupRB->setChecked(true); } else { m_pBackupCustomRB->setChecked(true); } } void ConfigDlgImpl::setFullViewOpt(const TransfConfig::Options& opt) // m_bKeepOrigTime is ignored { { // ProcOrig switch (opt.m_eProcOrigChange) { case TransfConfig::Options::PO_DONT_CHG: m_pPODontChangeRB->setChecked(true); break; case TransfConfig::Options::PO_ERASE: m_pPOEraseRB->setChecked(true); break; case TransfConfig::Options::PO_MOVE_ALWAYS_RENAME: m_pPOMoveAlwaysChangeRB->setChecked(true); break; case TransfConfig::Options::PO_MOVE_RENAME_IF_USED: m_pPOMoveChangeIfNeededRB->setChecked(true); break; case TransfConfig::Options::PO_RENAME_SAME_DIR: m_pPOChangeNameRB->setChecked(true); break; case TransfConfig::Options::PO_MOVE_OR_ERASE: m_pPOMoveOrEraseRB->setChecked(true); break; default: CB_ASSERT(false); // the constructor of TransfConfig should have detected it } if (opt.m_bProcOrigUseLabel) { m_pPOUseLabelRB->setChecked(true); } else { m_pPODontUseLabelRB->setChecked(true); } if (opt.m_bProcOrigAlwayUseCounter) { m_pPOAlwaysUseCounterRB->setChecked(true); } else { m_pPOUseCounterIfNeededRB->setChecked(true); } } { // UnprocOrig switch (opt.m_eUnprocOrigChange) { case TransfConfig::Options::UPO_DONT_CHG: m_pUODontChangeRB->setChecked(true); break; case TransfConfig::Options::UPO_ERASE: m_pUOEraseRB->setChecked(true); break; case TransfConfig::Options::UPO_MOVE_ALWAYS_RENAME: m_pUOMoveAlwaysChangeRB->setChecked(true); break; case TransfConfig::Options::UPO_MOVE_RENAME_IF_USED: m_pUOMoveChangeIfNeededRB->setChecked(true); break; case TransfConfig::Options::UPO_RENAME_SAME_DIR: m_pUOChangeNameRB->setChecked(true); break; default: CB_ASSERT(false); // the constructor of TransfConfig should have detected it } if (opt.m_bUnprocOrigUseLabel) { m_pUOUseLabelRB->setChecked(true); } else { m_pUODontUseLabelRB->setChecked(true); } if (opt.m_bUnprocOrigAlwayUseCounter) { m_pUOAlwaysUseCounterRB->setChecked(true); } else { m_pUOUseCounterIfNeededRB->setChecked(true); } } { // Processed switch (opt.m_eProcessedCreate) { case TransfConfig::Options::PR_DONT_CREATE: m_pProcDontCreateRB->setChecked(true); break; case TransfConfig::Options::PR_CREATE_ALWAYS_RENAME: m_pProcCreateAlwaysChangeRB->setChecked(true); break; case TransfConfig::Options::PR_CREATE_RENAME_IF_USED: m_pProcCreateChangeIfNeededRB->setChecked(true); break; default: CB_ASSERT(false); // the constructor of TransfConfig should have detected it } if (opt.m_bProcessedUseLabel) { m_pProcUseLabelRB->setChecked(true); } else { m_pProcDontUseLabelRB->setChecked(true); } if (opt.m_bProcessedAlwayUseCounter) { m_pProcAlwaysUseCounterRB->setChecked(true); } else { m_pProcUseCounterIfNeededRB->setChecked(true); } if (opt.m_bProcessedUseSeparateDir) { m_pProcUseSeparateDirRB->setChecked(true); } else { m_pProcUseSrcRB->setChecked(true); } } { // Temp if (opt.m_bTempCreate) { m_pTempCreateRB->setChecked(true); } else { m_pTempDontCreateRB->setChecked(true); } } { // Comp if (opt.m_bCompCreate) { m_pCompCreateRB->setChecked(true); } else { m_pCompDontCreateRB->setChecked(true); } } } void ConfigDlgImpl::on_m_pSimpleViewB_clicked() { m_pFileSettingsLayout->setCurrentWidget(m_pSimpleViewTab); m_pFullViewB->setChecked(false); m_pPODest2E->setText(m_pPODestE->text()); setSimpleViewOpt(getFullViewOpt()); } void ConfigDlgImpl::on_m_pFullViewB_clicked() { m_pFileSettingsLayout->setCurrentWidget(m_pFullViewTab); m_pSimpleViewB->setChecked(false); m_pPODestE->setText(m_pPODest2E->text()); setFullViewOpt(getSimpleViewOpt()); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== //ttt2 dir config: perhaps something simpler, with a "more options" button //ttt2 Font style is ignored (see DejaVu Sans / Light on machines with antialiased fonts) //ttt2 proxy: QNetworkProxyFactory::systemProxyForQuery; QNetworkProxy; http://www.dbits.be/index.php/pc-problems/65-vistaproxycfg https://sourceforge.net/projects/mp3diags/forums/forum/947207/topic/3415940 MP3Diags-1.0.12.079/src/CommonTypes.h0000644000175000001440000001317611310370662015710 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef CommonTypesH #define CommonTypesH #include #include //#include // ttt2 see why this includes QByteRef, which gives warnings for lots of functions returning "const char" or "const bool", saying that "const" is going to be ignored; perhaps #define something before "//#include "; QtGui and QPixmap avoid this issue, but take longer #include //#include // to avoid some dependencies and shorten the compilation time //ttt2 add more types here struct ImageInfo { enum Compr { INVALID, JPG, PNG }; enum Status { OK, LOADED_NOT_COVER, USES_LINK, ERROR_LOADING, NO_PICTURE_FOUND }; ImageInfo() : m_eCompr(INVALID), m_eStatus(NO_PICTURE_FOUND), m_nWidth(0), m_nHeight(0), m_nImageType(-1) {} //ImageInfo(Compr eCompr, QByteArray compressedImg) : m_eCompr(eCompr), m_eStatus(OK), m_compressedImg(compressedImg) {} ImageInfo(int nImageType, Status eStatus) : m_eCompr(INVALID), m_eStatus(eStatus), m_nWidth(0), m_nHeight(0), m_nImageType(nImageType) {} ImageInfo(int nImageType, Status eStatus, const QImage& pic); ImageInfo(int nImageType, Status eStatus, Compr eCompr, QByteArray compressedImg, int nWidth, int nHeight); bool isNull() const { return m_compressedImg.isEmpty(); } int getWidth() const { return m_nWidth; } int getHeight() const { return m_nHeight; } int getSize() const { return m_compressedImg.size(); } const char* getComprData() const { return m_compressedImg.constData(); } const char* getImageType() const; Status getStatus() const { return m_eStatus; } Compr getCompr() const { return m_eCompr; } // the picture is scaled down, keeping the aspect ratio, if the limits are exceeded; 0 and negative limits are ignored; // if nMaxWidth>0 and nMaxHeight<=0, nMaxHeight has the same value as nMaxWidth; QImage getImage(int nMaxWidth = -1, int nMaxHeight = -1) const; QString getTextDescr(const QString& qstrSep = "\n") const; void showFull(QWidget* pParent) const; //const QByteArray& getCompressedImg() const { return m_compressedImg; } bool operator==(const ImageInfo&) const; static int MAX_IMAGE_SIZE; static void compress(const QImage& origPic, QImage& scaledPic, QByteArray& comprImg); // scales down origPic and stores the pixmap in scaledPic, as well as a compressed version in comprImg; the algorithm coninues until comprImg becomes smaller than MAX_IMAGE_SIZE or until the width and the height of scaledPic get 150 or smaller; no scaling is done if comprImg turns out to be small enough for the original image; static const char* getImageType(int nImageType); static const char* getComprStr(Compr); private: Compr m_eCompr; Status m_eStatus; int m_nWidth, m_nHeight; QByteArray m_compressedImg; // this normally contains a downloaded image, but it may contain a recompressed image, if it got scaled down int m_nImageType; }; struct TrackInfo { TrackInfo() : m_dRating(-1) {} std::string m_strTitle; std::string m_strArtist; std::string m_strPos; std::string m_strComposer; double m_dRating; }; struct AlbumInfo { std::string m_strTitle; //std::string m_strArtist; // in order to show the artist and composer in the grid whatever info is given at album level gets copied to each track, so there's no need for AlbumInfo to store them //std::string m_strComposer; //std::string m_strFormat; // CD, tape, ... std::string m_strGenre; std::string m_strReleased; std::string m_strNotes; enum VarArtists { VA_NOT_SUPP, VA_SINGLE, VA_VARIOUS }; VarArtists m_eVarArtists; std::vector m_vTracks; std::string m_strSourceName; // Discogs, MusicBrainz, ... ; needed by MainFormDlgImpl; ImageInfo m_imageInfo; // a copy of an image in m_pCommonData->m_imageColl; AlbumInfo() : m_eVarArtists(VA_NOT_SUPP) {} }; std::ostream& operator<<(std::ostream&, const AlbumInfo&); enum TextCaseOptions { TC_NONE = -1, TC_LOWER = 0, TC_UPPER, TC_TITLE, TC_SENTENCE }; QString getCaseConv(const QString& s, TextCaseOptions eCase); const char* getCaseAsStr(TextCaseOptions e); #endif // #ifndef CommonTypesH MP3Diags-1.0.12.079/src/ImageInfoPanelWdgImpl.cpp0000644000175000001440000000711611310372540020062 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "ImageInfoPanelWdgImpl.h" #include "Helpers.h" //#include "Profiler.h" using namespace std; //using namespace pearl; static const int IMG_SIZE (110); ImageInfoPanelWdgImpl::ImageInfoPanelWdgImpl(QWidget* pParent, const TagWrtImageInfo& tagWrtImageInfo, int nPos) : QFrame(pParent, 0), Ui::ImageInfoPanelWdg(), m_tagWrtImageInfo(tagWrtImageInfo), m_nPos(nPos) { //PROF("ImageInfoPanelWdgImpl::ImageInfoPanelWdgImpl"); CB_ASSERT (nPos >= 0 /*&& nPos < cSize(vImageInfo)*/); setupUi(this); m_pPosL->setText(QString("# %1").arg(nPos + 1)); m_pSizeL->setText(QString("%1kB").arg(tagWrtImageInfo.m_imageInfo.getSize()/1024)); m_pDimL->setText(QString("%1x%2").arg(tagWrtImageInfo.m_imageInfo.getWidth()).arg(tagWrtImageInfo.m_imageInfo.getHeight())); //PROFD(4); m_pThumbL->setPixmap(QPixmap::fromImage(tagWrtImageInfo.m_imageInfo.getImage(IMG_SIZE))); //ttt2p performance issue; doesn't look like much can be done, though //PROFD(5); if (tagWrtImageInfo.m_sstrFiles.empty()) { m_pEraseB->hide(); } else { QString s; if (tagWrtImageInfo.m_sstrFiles.size() > 1) { s = "Erase these files:"; for (set::const_iterator it = tagWrtImageInfo.m_sstrFiles.begin(); it != tagWrtImageInfo.m_sstrFiles.end(); ++it) { s += "\n" + convStr(*it); } } else { s = "Erase " + convStr(*tagWrtImageInfo.m_sstrFiles.begin()); } m_pEraseB->setToolTip(s); } } ImageInfoPanelWdgImpl::~ImageInfoPanelWdgImpl() { } void ImageInfoPanelWdgImpl::on_m_pFullB_clicked() { m_tagWrtImageInfo.m_imageInfo.showFull(this); } void ImageInfoPanelWdgImpl::setNormalBackground() { QPalette pal; setPalette(pal); } void ImageInfoPanelWdgImpl::setHighlightBackground() { QPalette pal; //QPalette pal (palette()); //QPalette pal (QColor(255, 220, 190)); pal.setColor(QPalette::Window, pal.color(QPalette::Disabled, QPalette::Dark)); setPalette(pal); } MP3Diags-1.0.12.079/src/UniqueNotesModel.cpp0000644000175000001440000001307611244235321017223 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "UniqueNotesModel.h" #include "CommonData.h" using namespace std; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== UniqueNotesModel::UniqueNotesModel(CommonData* pCommonData) : QAbstractTableModel(pCommonData->m_pUniqueNotesG), m_pCommonData(pCommonData) { } /*override*/ int UniqueNotesModel::rowCount(const QModelIndex&) const { return m_pCommonData->getUniqueNotes().getFltCount(); } /*override*/ int UniqueNotesModel::columnCount(const QModelIndex&) const { return 2; } /*override*/ QVariant UniqueNotesModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("UniqueNotesModel::data()"); if (!index.isValid() || nRole != Qt::DisplayRole) { return QVariant(); } if (0 == index.column()) { const vector& v (m_pCommonData->getUniqueNotes().getFltVec()); return getNoteLabel(v[index.row()]); } return m_pCommonData->getUniqueNotes().getFlt(index.row())->getDescription(); } /*override*/ QVariant UniqueNotesModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("UniqueNotesModel::headerData"); if (nRole == Qt::SizeHintRole) { return getNumVertHdrSize(m_pCommonData->getUniqueNotes().getFltCount(), eOrientation); } if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { switch (nSection) { case 0: return "L"; case 1: return "Note"; default: CB_ASSERT (false); } } return nSection + 1; } void UniqueNotesModel::selectTopLeft() { QItemSelectionModel* pSelModel (m_pCommonData->m_pUniqueNotesG->selectionModel()); pSelModel->clear(); emit layoutChanged(); if (m_pCommonData->getUniqueNotes().getFltCount() > 0) { //pSelModel->select(index(0, 0), QItemSelectionModel::Current); //pSelModel->select(index(0, 0), QItemSelectionModel::Select); //m_pCommonData->printFilesCrt(); m_pCommonData->m_pUniqueNotesG->setCurrentIndex(index(0, 0)); //m_pCommonData->printFilesCrt(); } } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== UniqueNotesGDelegate::UniqueNotesGDelegate(CommonData* pCommonData) : MultiLineTvDelegate(pCommonData->m_pUniqueNotesG), m_pCommonData(pCommonData) { } /*override*/ void UniqueNotesGDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { pPainter->save(); QStyleOptionViewItemV2 myOption (option); const Note* pNote (m_pCommonData->getUniqueNotes().getFlt(index.row())); if (0 == index.column()) { myOption.displayAlignment |= Qt::AlignHCenter; if (Note::ERR == pNote->getSeverity()) { myOption.palette.setColor(QPalette::Text, ERROR_PEN_COLOR()); } else if (Note::SUPPORT == pNote->getSeverity()) { myOption.palette.setColor(QPalette::Text, SUPPORT_PEN_COLOR()); } } QColor colNote; double dGradStart, dGradEnd; m_pCommonData->getNoteColor(*pNote, m_pCommonData->getUniqueNotes().getFltVec(), colNote, dGradStart, dGradEnd); QLinearGradient grad (0, option.rect.y(), 0, option.rect.y() + option.rect.height()); configureGradient(grad, colNote, dGradStart, dGradEnd); pPainter->fillRect(option.rect, grad); MultiLineTvDelegate::paint(pPainter, myOption, index); pPainter->restore(); } MP3Diags-1.0.12.079/src/ThreadRunnerDlgImpl.cpp0000644000175000001440000002371511375551311017643 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include "ThreadRunnerDlgImpl.h" #include "Helpers.h" PausableThread::PausableThread(/*QObject* pParent = 0*/) : /*QThread(pParent),*/ m_bPaused(false), m_bAborted(false) { static bool s_bRegistered (false); if (!s_bRegistered) { s_bRegistered = true; qRegisterMetaType("StrList"); } } /*virtual*/ PausableThread::~PausableThread() { //qDebug("thread destroyed"); } void PausableThread::pause() { m_bPaused = true; // !!! no synch needed } void PausableThread::resume() { QMutexLocker lck(&m_mutex); m_bPaused = false; m_waitCondition.wakeAll(); } void PausableThread::abort() { QMutexLocker lck(&m_mutex); m_bAborted = true; m_waitCondition.wakeAll(); } void PausableThread::checkPause() // if m_bPaused is set, it waits until resume() or abort() get called; otherwise it returns immediately { if (!m_bPaused) { return; } QMutexLocker lck(&m_mutex); if (!m_bPaused) { return; } // !!! it was tested 2 lines above, but might have changed after that; now it's a different story, because it's protected by the mutex; if (m_bAborted) { return; } m_waitCondition.wait(&m_mutex); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== ThreadRunnerDlgImpl::ThreadRunnerDlgImpl(QWidget* pParent, Qt::WFlags flags, PausableThread* pThread, bool bShowCounter, TruncatePos eTruncatePos, bool bShowPauseAbort /*= true*/) : QDialog(pParent, flags), Ui::ThreadRunnerDlg(), m_pThread(pThread), m_nCounter(0), m_bShowCounter(bShowCounter), //m_nLastKey(0), m_tRealBegin(time(0)), m_tRunningBegin(time(0)), m_bShowPauseAbort(bShowPauseAbort), m_bFirstTime(true), m_eTruncatePos(eTruncatePos) { setupUi(this); if (!bShowPauseAbort) { m_pPauseResumeB->hide(); m_pAbortB->hide(); } pThread->setParent(this); connect(m_pThread, SIGNAL(stepChanged(const StrList&, int)), this, SLOT(onStepChanged(const StrList&, int))); connect(m_pThread, SIGNAL(completed(bool)), this, SLOT(onThreadCompleted(bool))); connect(&m_closeTimer, SIGNAL(timeout()), this, SLOT(onCloseTimer())); connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(onUpdateTimer())); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence(Qt::Key_Escape)); connect(p, SIGNAL(triggered()), this, SLOT(on_m_pAbortB_clicked())); addAction(p); } // !!! make ESC call on_m_pAbortB_clicked() instead of closing the dialog m_pCurrentL->setText(""); pThread->start(); m_updateTimer.start(500); // 0.5 sec { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } ThreadRunnerDlgImpl::~ThreadRunnerDlgImpl() { } void ThreadRunnerDlgImpl::onThreadCompleted(bool bSuccess) { m_bSuccess = bSuccess; // !!! can't just exit; should wait for the thread's "run()" metod to finish m_pCurrentL->setText("Completed"); m_pPauseResumeB->setEnabled(false); m_pAbortB->setEnabled(false); m_closeTimer.start(100); // 0.1 sec onCloseTimer(); // this may return immediately or not, depending on which thread gets executed after "PausableThread::notifComplete()" } void ThreadRunnerDlgImpl::on_m_pPauseResumeB_clicked() { if (!m_pThread->m_bPaused) { // currently running m_pPauseResumeB->setText("&Resume"); m_pThread->pause(); m_tPauseBegin = time(0); } else { // currently paused m_pPauseResumeB->setText("&Pause"); time_t t (time(0)); m_tRunningBegin = m_tRunningBegin + t - m_tPauseBegin; m_pThread->resume(); } } void ThreadRunnerDlgImpl::on_m_pAbortB_clicked() { m_pPauseResumeB->setEnabled(false); m_pAbortB->setEnabled(false); m_pThread->abort(); } QString ThreadRunnerDlgImpl::truncateLarge(const QString& s, int nKeepFirst /*= 0*/) // truncates strings that are too wide to display without resizing { QFontMetrics fontMetrics (m_pCurrentL->font()); const int MARGIN (8); // normally this should be 0 but in other cases Qt missed a few pixels when estimating how much space it needed, so it seems better to lose some pixels // ttt2 2009.04.30 - actually this is probably related to spacing; if this is true, the hard-coded value should be replaced by some query to QApplication::style()->pixelMetric() if (fontMetrics.width(s) < m_pCurrentL->width() - MARGIN) { return s; } int nSize (s.size() - 1); QString res (s); switch (m_eTruncatePos) { case TRUNCATE_BEGIN: { res.insert (nKeepFirst, "... "); nKeepFirst += 4; // size of "... " nSize -= nKeepFirst; while (nSize > 0 && fontMetrics.width(res) >= m_pCurrentL->width() - MARGIN) { res.remove(nKeepFirst, 1); --nSize; } return res; } case TRUNCATE_END: { while (nSize > 0 && fontMetrics.width(res + " ...") >= m_pCurrentL->width() - MARGIN) { res.truncate(nSize); --nSize; } return res + " ..."; } default: //CB_ASSERT (false); //ttt2 add support for TRUNCATE_MIDDLE throw false; } } //void ThreadRunnerDlgImpl::onStepChanged(const QString& qstrLabel1, const QString& qstrLabel2 /*= ""*/, const QString& qstrLabel3 /*= ""*/, const QString& qstrLabel4 /*= ""*/) void ThreadRunnerDlgImpl::onStepChanged(const StrList& v, int nStep) { //qDebug("step %s", qstrLabel.toStdString().c_str()); if (-1 == nStep) { ++m_nCounter; } else { m_nCounter = nStep; } m_vStepInfo = v; if (m_bFirstTime) { QTimer::singleShot(1, this, SLOT(onUpdateTimer())); m_bFirstTime = false; } } static QString getTimeFmt(int n) // n in seconds { int h (n / 3600); n -= h*3600; int m (n / 60); n -= m*60; QString q; q.sprintf("%d:%02d:%02d", h, m, n); return q; } void ThreadRunnerDlgImpl::onCloseTimer() { //qDebug("ThreadRunnerDlgImpl::onTimer()"); if (!m_pThread->isFinished()) { //qDebug("waithing for thread"); return; } m_closeTimer.stop(); m_updateTimer.stop(); if (m_bSuccess) { accept(); } else { reject(); } } void ThreadRunnerDlgImpl::onUpdateTimer() { QString s; if (m_bShowCounter) { static QLocale loc ("C"); s = loc.toString(m_nCounter) + ". "; } int n ((int)m_vStepInfo.size()); if (n >= 1) { s = truncateLarge(s + m_vStepInfo[0], s.size()); for (int i = 1; i < n; ++i) { s += "\n" + truncateLarge(m_vStepInfo[i]); } } time_t t (time(0)); if (m_bShowPauseAbort) { s += "\n\nTotal time: " + getTimeFmt(t - m_tRealBegin); // ttt1 show only if different from Running time s += "\nRunning time: " + getTimeFmt((m_pThread->m_bPaused ? m_tPauseBegin : t) - m_tRunningBegin); } else { s += "\n\nTime: " + getTimeFmt(t - m_tRealBegin); } m_pCurrentL->setText(s); } /*override*/ void ThreadRunnerDlgImpl::closeEvent(QCloseEvent* pEvent) { pEvent->ignore(); on_m_pAbortB_clicked(); } void ThreadRunnerDlgImpl::onHelp() { // openHelp("index.html"); //ttt2 see if anything more specific can be done } #if 0 /* Not sure if this should work: from the doc for QDialog: Escape Key If the user presses the Esc key in a dialog, QDialog::reject() will be called. This will cause the window to close: The close event cannot be ignored. ttt2 see Qt::Key_Escape in MainFormDlgImpl for a different approach, decide which is better */ /*override*/ void ThreadRunnerDlgImpl::keyPressEvent(QKeyEvent* pEvent) { //qDebug("key prs %d", pEvent->key()); m_nLastKey = pEvent->key(); pEvent->ignore(); } /*override*/ void ThreadRunnerDlgImpl::keyReleaseEvent(QKeyEvent* pEvent) { //qDebug("key rel %d", pEvent->key()); if (Qt::Key_Escape == pEvent->key()) { on_m_pAbortB_clicked(); } pEvent->ignore(); // ttt2 not sure this is the way to do it, but the point is to disable the ESC key } #endif MP3Diags-1.0.12.079/src/PaletteDlgImpl.h0000644000175000001440000000510311230111215016255 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef PaletteDlgImplH #define PaletteDlgImplH #include #include #include "ui_Palette.h" #include "CommonData.h" class PaletteDlgImpl : public QDialog, private Ui::PaletteDlg { Q_OBJECT std::vector m_vpColButtons; void setBtnColor(int n); void onButtonClicked(int n); CommonData* m_pCommonData; public: PaletteDlgImpl(CommonData* pCommonData, QWidget* pParent); ~PaletteDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pOkB_clicked(); void on_m_pCol0B_clicked() { onButtonClicked(0); } void on_m_pCol1B_clicked() { onButtonClicked(1); } void on_m_pCol2B_clicked() { onButtonClicked(2); } void on_m_pCol3B_clicked() { onButtonClicked(3); } void on_m_pCol4B_clicked() { onButtonClicked(4); } void on_m_pCol5B_clicked() { onButtonClicked(5); } void on_m_pCol6B_clicked() { onButtonClicked(6); } void onHelp(); }; #endif // #ifndef PaletteDlgImplH MP3Diags-1.0.12.079/src/NoteFilterDlgImpl.h0000644000175000001440000001024011252461427016751 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef NoteFilterDlgImplH #define NoteFilterDlgImplH #include #include "ui_NoteFilter.h" #include "DoubleList.h" struct Note; class CommonData; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class NoteListElem : public ListElem { /*override*/ std::string getText(int nCol) const; const Note* m_pNote; // doesn't own the pointer CommonData* m_pCommonData; public: NoteListElem(const Note* pNote, CommonData* pCommonData) : m_pNote(pNote), m_pCommonData(pCommonData) {} const Note* getNote() const { return m_pNote; } const CommonData* getCommonData() const { return m_pCommonData; } }; class NoteListPainterBase : public ListPainter { /*override*/ int getColCount() const { return 2; } /*override*/ std::string getColTitle(int nCol) const; /*override*/ int getColWidth(int nCol) const; // positive values are used for fixed widths, while negative ones are for "stretched" /*override*/ int getHdrHeight() const; /*override*/ Qt::Alignment getAlignment(int nCol) const; /*override*/ void getColor(int nIndex, int nColumn, bool bSubList, QColor& bckgColor, QColor& penColor, double& dGradStart, double& dGradEnd) const; mutable std::vector m_vpAvail, m_vpSel; protected: CommonData* m_pCommonData; public: NoteListPainterBase(CommonData* pCommonData, const std::string& strNothingSel) : ListPainter(strNothingSel), m_pCommonData(pCommonData) {} }; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class NoteFilterDlgImpl : public QDialog, private Ui::NoteFilterDlg, public NoteListPainterBase { Q_OBJECT void logState(const char* szPlace) const; /*override*/ std::string getTooltip(TooltipKey eTooltipKey) const; /*override*/ void reset(); public: /*$PUBLIC_FUNCTIONS$*/ NoteFilterDlgImpl(CommonData* pCommonData, QWidget *pParent); ~NoteFilterDlgImpl(); public slots: /*$PUBLIC_SLOTS$*/ void on_m_pOkB_clicked(); void on_m_pCancelB_clicked(); void onAvlDoubleClicked(int nRow); void onHelp(); }; #endif // #ifndef NoteFilterDlgImplH MP3Diags-1.0.12.079/src/Mp3Diags.qrc0000644000175000001440000000447111265372072015404 0ustar ciobiusers images/logo.svg images/configure.svg images/decode.svg images/filter-folder.svg images/filter-note.svg images/go-next.svg images/go-previous.svg images/mode_album.svg images/mode_all.svg images/mode_file.svg images/scan.svg images/session.svg images/test.svg images/transform1.svg images/transform2.svg images/transform3.svg images/transform4.svg images/transform.svg images/normalize.svg images/file-rename.svg images/arrow-left-double.svg images/arrow-left.svg images/arrow-right-double.svg images/arrow-right.svg images/reset_settings.svg images/undo_settings.svg images/save_log.svg images/save_notes.svg images/about.svg images/zoom-in.png images/assign.png images/remove_file.png images/assgn-all.svg images/assgn-none.svg images/assgn-some.svg images/change-case.svg images/document-save.svg images/discogs.png images/musicbrainz_logo1.svg images/duplicate_first.svg images/edit-paste.svg images/edit-undo.svg images/patterns.svg images/sort_asc.svg images/palette.svg images/debug.svg images/tag_editor.svg images/rename.svg images/export.svg images/va_sa.svg images/va_va.svg licences/gplv2.txt licences/gplv3.txt licences/lgplv3.txt licences/lgpl-2.1.txt licences/boost.txt licences/zlib.txt MP3Diags-1.0.12.079/src/DebugDlgImpl.cpp0000644000175000001440000006400211274017760016265 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include //#include "SerSupport.h" #include "DebugDlgImpl.h" #include "CommonData.h" #include "DataStream.h" #include "Helpers.h" #include "StoredSettings.h" #include "LogModel.h" //#include "Serializable.h" /*#include #include #include */ using namespace std; using namespace pearl; DebugDlgImpl::DebugDlgImpl(QWidget* pParent, CommonData* pCommonData) : QDialog(pParent, getDialogWndFlags()), Ui::DebugDlg(), m_pCommonData(pCommonData) { setupUi(this); int nWidth, nHeight; m_pCommonData->m_settings.loadDebugSettings(nWidth, nHeight); if (nWidth > 400 && nHeight > 200) { resize(nWidth, nHeight); } else { defaultResize(*this); } { m_pEnableTracingCkB->setChecked(m_pCommonData->m_bTraceEnabled); m_pUseAllNotesCkB->setChecked(m_pCommonData->m_bUseAllNotes); m_pLogTransfCkB->setChecked(m_pCommonData->m_bLogTransf); m_pSaveDownloadedDataCkB->setChecked(m_pCommonData->m_bSaveDownloadedData); } { m_pLogModel = new LogModel(m_pCommonData, m_pLogG); m_pLogG->setModel(m_pLogModel); m_pLogG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pLogG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); m_pLogG->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); m_pLogG->verticalHeader()->setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter); //m_pLogG->verticalHeader()->setResizeMode(QHeaderView::Fixed); m_pLogG->verticalHeader()->setResizeMode(QHeaderView::Interactive); } m_pUseAllNotesCkB->setToolTip( "If this is checked, ignored notes and trace notes\n" "are shown in the note list and exported, regardless\n" "of the \"Ignored\" settings.\n\n" "Note that if this is not checked, the trace notes\n" "are discarded during file scanning, so checking it\n" "later won't bring them back. A new scan is needed\n" "to see them."); m_pLogG->setFocus(); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } void DebugDlgImpl::run() { //if (QDialog::Accepted != exec()) { return false; } exec(); m_pCommonData->m_settings.saveDebugSettings(width(), height()); m_pCommonData->m_bTraceEnabled = m_pEnableTracingCkB->isChecked(); m_pCommonData->m_bUseAllNotes = m_pUseAllNotesCkB->isChecked(); m_pCommonData->m_bLogTransf = m_pLogTransfCkB->isChecked(); m_pCommonData->m_bSaveDownloadedData = m_pSaveDownloadedDataCkB->isChecked(); //return true; } DebugDlgImpl::~DebugDlgImpl() { } void DebugDlgImpl::on_m_pCloseB_clicked() { reject(); // !!! doesn't matter if it's accept() } void DebugDlgImpl::exportLog(const string& strFileName) { const deque& v (m_pCommonData->getLog()); ofstream_utf8 out (strFileName.c_str()); for (int i = 0, n = cSize(v); i < n; ++i) { out << v[i] << endl; } } void DebugDlgImpl::on_m_pSaveLogB_clicked() { QFileDialog dlg (this, "Choose destination file", "", "Text files (*.txt)"); dlg.setFileMode(QFileDialog::AnyFile); if (QDialog::Accepted != dlg.exec()) { return; } QStringList fileNames (dlg.selectedFiles()); if (1 != fileNames.size()) { return; } QString s (fileNames.first()); exportLog(convStr(s)); } void DebugDlgImpl::on_m_pDecodeMpegFrameB_clicked() { istringstream s (m_pFrameHdrE->text().toUtf8().constData()); s >> hex; unsigned int n; s >> n; QMessageBox::information(this, "Decoded MPEG frame header", convStr(decodeMpegFrame(n, "\n"))); } void DebugDlgImpl::onHelp() { openHelp("310_advanced.html"); } //======================================================================================================================================================== //======================================================================================================================================================== //======================================================================================================================================================== void tstFont(); void tstGenre(); void tstSer01(); void DebugDlgImpl::on_m_pTst01B_clicked() { //tstSer01(); //m_pLogModel->selectTopLeft(); /*TestThread01* p (new TestThread01()); ThreadRunnerDlgImpl dlg (p, true, this); dlg.exec();*/ /*bool b; QFont f (QFontDialog::getFont(&b, this)); //cout << "font: " << QFontInfo(myOption.font).family().toStdString() << endl; //cout << "font from dlg: " << f.toString().toStdString() << endl; printFontInfo("font from dlg", f); for (int i = 6; i < 18; ++i) { QFont f ("B&H LucidaTypewriter", i); QFontInfo info (f); cout << i << ": " << info.family().toStdString() << ", exactMatch:" << info.exactMatch() << ", fixedPitch:" << info.fixedPitch() << ", italic:" << info.italic() << ", pixelSize:" << info.pixelSize() << ", pointSize" << info.pointSize() << endl; } */ //tstFont(); /* { const char* a ("1998-10-04"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998-10"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998-1-4"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998-1"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("98"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998-10-04T11:12:13"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998-10-04 11:12:13"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998-10-04T11:12"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998-10-04T11"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } { const char* a ("1998-10-04T11:6"); QDateTime dt (QDateTime::fromString(a, Qt::ISODate)); if (!dt.isValid()) cout << a << " is invalid\n"; else cout << dt.toString(Qt::ISODate).toStdString() << endl; } */ //m_transfConfig.testRemoveSuffix(); //tstGenre(); /*m_pFilesModel->notifyModelChanged(); char a [100]; sprintf(a, "%d %d", m_pFilesModel->rowCount(QModelIndex()), m_pFilesModel->columnCount(QModelIndex())); m_pStreamsM->append(a);*/ //m_pContentM->setTextFormat(LogText); /* QItemSelectionModel* pSelModel (m_pCommonData->m_pFilesG->selectionModel()); m_pCommonData->printFilesCrt(); pSelModel->clear(); m_pCommonData->printFilesCrt(); if (m_pCommonData->getFilesGCrtRow() > 400000) exit(2); return; */ //resizeEvent(0); //m_pContentM->setReadOnly(TRUE); #if 0 static bool b1 (false); b1 = !b1; if (b1) { char a [100]; for (int i = 0; i < 10000; ++ i) { sprintf(a, "%d //Mp3Handler* pMp3Handler (new Mp3Handler(fs.getName())); Mp3Handler", i); m_pContentM->append(a); } /*char a [100]; string s; for (int i = 0; i < 1000; ++ i) { sprintf(a, "%d //Mp3Handler* pMp3Handler (new Mp3Handler(fs.getName())); Mp3Handler\n", i); s += a; } m_pContentM->append(s.c_str());*/ } else { m_pContentM->setText(""); } #endif } //======================================================================================================================================================== //======================================================================================================================================================== //======================================================================================================================================================== #if 0 #include struct Base { ciobi_ser::SerHelper m_serHelper; Base(ciobi_ser::Univ* pUniv, int n1) : m_serHelper(*this, pUniv), m_n1(n1) {} //template Base(T& obj, ciobi_ser::Univ* pUniv, int n1) : m_serHelper(obj, pUniv), m_n1(n1) {} Base(ciobi_ser::ForSerOnly*) : m_serHelper(*this, 0) {} virtual ~Base() { } int m_n1; virtual void print(ostream& out) const { out << "Base: " << m_n1 << endl; } virtual void save(const ciobi_ser::Univ& univ) { //univ.saveCPE(m_vpMasterDirs); univ.save(m_n1); cout << "saved base: " << m_n1 << endl; } virtual void load(ciobi_ser::Univ& univ) { //univ.loadCPE(m_vpMasterDirs); univ.load(m_n1); cout << "loaded base: " << m_n1 << endl; } virtual const char* getClassName() const { return ciobi_ser::ClassName::szClassName; } }; struct Der : public Base { //ciobi_ser::SerHelper m_serHelper; //Der(ciobi_ser::Univ* pUniv, int n1, int n2) : Base(pUniv, n1), m_serHelper(*this, pUniv), m_n2(n2) {} //Der(ciobi_ser::Univ* pUniv, int n1, int n2) : Base(*this, pUniv, n1), m_n2(n2) {} Der(ciobi_ser::Univ* pUniv, int n1, int n2) : Base(pUniv, n1), m_n2(n2) {} Der(ciobi_ser::ForSerOnly* p) : Base(p) {} int m_n2; /*override*/ void print(ostream& out) const { out << "Der: " << m_n1 << ", " << m_n2 << endl; } /*override*/ void save(const ciobi_ser::Univ& univ) { Base::save(univ); univ.save(m_n2); cout << "saved der: " << m_n1 << ", " << m_n2 << endl; } /*override*/ void load(ciobi_ser::Univ& univ) { Base::load(univ); univ.load(m_n2); cout << "loaded der: " << m_n1 << ", " << m_n2 << endl; } /*override*/ const char* getClassName() const { return ciobi_ser::ClassName::szClassName; } }; template<> /*static*/ const char* ciobi_ser::ClassName::szClassName ("Base"); template<> /*static*/ const char* ciobi_ser::ClassName::szClassName ("Der"); // explicit instantiation template class ciobi_ser::SerHelper; ostream& operator<<(ostream& out, const Base& o) { o.print(out); return out; } //================================================================================================================= struct Container { ciobi_ser::SerHelper m_serHelper; Container(ciobi_ser::Univ* pUniv, int n) : m_serHelper(*this, pUniv) { int k (1); for (int i = 0; i < n; ++i, k *= 2) { Base* p (i % 2 ? new Base(pUniv, k) : new Der(pUniv, k, k + 1)); //Base* p (new Base(pUniv, k)); m_v.push_back(p); } } Container(ciobi_ser::ForSerOnly*) : m_serHelper(*this, 0) {} virtual ~Container() { } vector m_v; void save(const ciobi_ser::Univ& univ) { //univ.saveCPE(m_vpMasterDirs); univ.saveCP(m_v); cout << "saved container: " << endl; } void load(ciobi_ser::Univ& univ) { //univ.loadCPE(m_vpMasterDirs); univ.loadCP(m_v); cout << "loaded container, size " << cSize(m_v) << endl; for (int i = 0; i < cSize(m_v); ++i) { cout << *m_v[i]; } } const char* getClassName() const { return ciobi_ser::ClassName::szClassName; } }; template<> /*static*/ const char* ciobi_ser::ClassName::szClassName ("Container"); void tstVec01(bool bSave) { ciobi_ser::Univ univ; univ.setDestroyOption(ciobi_ser::Univ::DO_NOTHING); // DELETE_SORTED_OBJECTS const char* szFile ("savePolymVec.tser"); if (bSave) { Container c (&univ, 4); ciobi_ser::SaveOptions so(ciobi_ser::SaveOptions::TEXT, 1, 1, ciobi_ser::SaveOptions::USE_OBJ_INFO, ciobi_ser::SaveOptions::DONT_USE_SEP, ciobi_ser::SaveOptions::USE_COMMENTS); univ.saveToFile(&c, szFile, "tst polym univ name", so); return; } Container* p; univ.loadFromFile(p, szFile); } //================================================================================================================= void tstBase01(bool bSave) { ciobi_ser::Univ univ; univ.setDestroyOption(ciobi_ser::Univ::DO_NOTHING); // DELETE_SORTED_OBJECTS const char* szFile ("saveBase01.tser"); if (bSave) { Base b1 (&univ, 3); ciobi_ser::SaveOptions so(ciobi_ser::SaveOptions::TEXT, 1, 1/*, ciobi_ser::SaveOptions::DONT_USE_OBJ_INFO, ciobi_ser::SaveOptions::DONT_USE_SEP, ciobi_ser::SaveOptions::DONT_USE_COMMENTS*/); //cout << 1 << endl; univ.saveToFile(&b1, szFile, "tst base 01 univ name", so); //cout << 2 << endl; return; } Base* pb1; univ.loadFromFile(pb1, szFile); } void tstDer01(bool bSave) { ciobi_ser::Univ univ; univ.setDestroyOption(ciobi_ser::Univ::DO_NOTHING); // DELETE_SORTED_OBJECTS const char* szFile ("saveDer01.tser"); if (bSave) { Der d (&univ, 4, 6); ciobi_ser::SaveOptions so(ciobi_ser::SaveOptions::TEXT, 1, 1); univ.saveToFile(&d, szFile, "tst der 01 univ name", so); return; } Der* p; univ.loadFromFile(p, szFile); } //================================================================================================================= //================================================================================================================= struct Emb { //ciobi_ser::SerHelper m_serHelper; Emb(int n1) : /*m_serHelper(*this, pUniv),*/ m_n1(n1) {} Emb(ciobi_ser::ForSerOnly*) /*m_serHelper(*this, 0)*/ {} int m_n1; void save(const ciobi_ser::Univ& univ) { univ.save(m_n1); } void load(ciobi_ser::Univ& univ) { univ.load(m_n1); } void print(ostream& out) const { out << "Emb: " << m_n1 << endl; } }; ostream& operator<<(ostream& out, const Emb& emb) { emb.print(out); return out; } struct Encl { ciobi_ser::SerHelper m_serHelper; Encl(ciobi_ser::Univ* pUniv, int n) : m_serHelper(*this, pUniv) { int k (1); for (int i = 0; i <= n; ++i) { Emb* p (new Emb(k)); m_v.push_back(p); k *= 2; } } Encl(ciobi_ser::ForSerOnly*) : m_serHelper(*this, 0) {} vector m_v; void save(const ciobi_ser::Univ& univ) { univ.saveCPE(m_v); cout << "saved encl\n"; } void load(ciobi_ser::Univ& univ) { univ.loadCPE(m_v); cout << "loaded encl:"; int n (cSize(m_v)); for (int i = 0; i < n; ++i) { cout << *m_v[i]; } cout << endl; } const char* getClassName() const { return ciobi_ser::ClassName::szClassName; } }; template<> /*static*/ const char* ciobi_ser::ClassName::szClassName ("Encl"); void tstEmbVec01(bool bSave) { ciobi_ser::Univ univ; univ.setDestroyOption(ciobi_ser::Univ::DO_NOTHING); // DELETE_SORTED_OBJECTS const char* szFile ("saveEncl01.tser"); if (bSave) { Encl e (&univ, 8); ciobi_ser::SaveOptions so(ciobi_ser::SaveOptions::TEXT, 1, 1); univ.saveToFile(&e, szFile, "tst encl univ name", so); return; } Encl* p; univ.loadFromFile(p, szFile); } #endif //======================================================================================================================================================== //======================================================================================================================================================== //======================================================================================================================================================== #if 0 #include struct BoostTstBase { BoostTstBase(int n1) : m_n1(n1) {} virtual ~BoostTstBase() { } int m_n1; virtual void print(ostream& out) const { out << "BoostTstBase: " << m_n1 << endl; } protected: BoostTstBase() {} private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int /*nVersion*/) { ar & m_n1; } }; struct BoostTstDer : public BoostTstBase { BoostTstDer(int n1, int n2) : BoostTstBase(n1), m_n2(n2) {} int m_n2; /*override*/ void print(ostream& out) const { out << "BoostTstDer: " << m_n1 << ", " << m_n2 << endl; } private: friend class boost::serialization::access; BoostTstDer() {} template void serialize(Archive& ar, const unsigned int /*nVersion*/) { ar & boost::serialization::base_object(*this); ar & m_n2; } }; ostream& operator<<(ostream& out, const BoostTstBase& o) { o.print(out); return out; } //================================================================================================================= struct BoostContainer { BoostContainer(int n) { int k (1); for (int i = 0; i < n; ++i, k *= 2) { BoostTstBase* p (i % 2 ? new BoostTstBase(k) : new BoostTstDer(k, k + 1)); m_v.push_back(p); } } virtual ~BoostContainer() { } vector m_v; /*void save() { //univ.saveCPE(m_vpMasterDirs); univ.saveCP(m_v); cout << "saved container: " << endl; } void load() { //univ.loadCPE(m_vpMasterDirs); univ.loadCP(m_v); }*/ private: friend class boost::serialization::access; BoostContainer() {} template void serialize(Archive& ar, const unsigned int /*nVersion*/) { ar & m_v; } }; void tstBoostVec01(bool bSave) { const char* szFile ("savePolymVec.boost.ser"); if (bSave) { BoostContainer* p (new BoostContainer(4)); ofstream_utf8 out (szFile); //boost::archive::text_oarchive oar (out); boost::archive::binary_oarchive oar (out); oar.register_type(); oar.register_type(); oar.register_type(); //BoostContainer* q (p); //BoostContainer* const q (p); //const BoostContainer* const q2 (p); //oar << const_cast(p); //oar << q; oar << (BoostContainer* const)p; //oar << q; return; } BoostContainer* p; ifstream_utf8 in (szFile); //boost::archive::text_iarchive iar (in); boost::archive::binary_iarchive iar (in); iar.register_type(); iar.register_type(); iar.register_type(); iar >> p; cout << "loaded container, size " << cSize(p->m_v) << endl; for (int i = 0; i < cSize(p->m_v); ++i) { cout << *p->m_v[i]; } } //================================================================================================================= #if 0 void tstBase01(bool bSave) { const char* szFile ("saveBase01.tser"); if (bSave) { BoostTstBase b1 (&univ, 3); univ.saveToFile(&b1, szFile, "tst base 01 univ name", so); //cout << 2 << endl; return; } BoostTstBase* pb1; univ.loadFromFile(pb1, szFile); } void tstDer01(bool bSave) { const char* szFile ("saveDer01.tser"); if (bSave) { BoostTstDer d (4, 6); univ.saveToFile(&d, szFile, "tst der 01 univ name", so); return; } BoostTstDer* p; univ.loadFromFile(p, szFile); } //================================================================================================================= //================================================================================================================= //================================================================================================================= struct Emb { Emb(int n1) : /*m_serHelper(*this, pUniv),*/ m_n1(n1) {} int m_n1; void save() { univ.save(m_n1); } void load() { univ.load(m_n1); } void print(ostream& out) const { out << "Emb: " << m_n1 << endl; } }; ostream& operator<<(ostream& out, const Emb& emb) { emb.print(out); return out; } struct Encl { Encl(int n) { int k (1); for (int i = 0; i <= n; ++i) { Emb* p (new Emb(k)); m_v.push_back(p); k *= 2; } } vector m_v; void save() { univ.saveCPE(m_v); cout << "saved encl\n"; } void load() { univ.loadCPE(m_v); cout << "loaded encl:"; int n (cSize(m_v)); for (int i = 0; i < n; ++i) { cout << *m_v[i]; } cout << endl; } }; void tstEmbVec01(bool bSave) { const char* szFile ("saveEncl01.tser"); if (bSave) { Encl e (&univ, 8); univ.saveToFile(&e, szFile, "tst encl univ name", so); return; } Encl* p; univ.loadFromFile(p, szFile); } #endif #endif //================================================================================================================= #if 0 #include "fstream_unicode.h" // include headers that implement a archive in simple text format #include #include ///////////////////////////////////////////////////////////// // gps coordinate // // illustrates serialization for a simple type // class gps_position { private: friend class boost::serialization::access; // When the class Archive corresponds to an output archive, the // & operator is defined similar to <<. Likewise, when the class Archive // is a type of input archive the & operator is defined similar to >>. template void serialize(Archive& ar, const unsigned int version) { ar & degrees; ar & minutes; ar & seconds; } int degrees; int minutes; float seconds; public: gps_position(){}; gps_position(int d, int m, float s) : degrees(d), minutes(m), seconds(s) {} }; int tutorial() { // create and open a character archive for output ofstream_utf8 ofs("filename"); // create class instance const gps_position g(35, 59, 24.567f); // save data to archive { boost::archive::text_oarchive oa(ofs); // write class instance to archive oa << g; // archive and stream closed when destructors are called } // ... some time later restore the class instance to its orginal state gps_position newg; { // create and open an archive for input ifstream_utf8 ifs("filename", std::ios::binary); boost::archive::text_iarchive ia(ifs); // read class state from archive ia >> newg; // archive and stream closed when destructors are called } return 0; } #endif #if 0 void tstSer01() { //tstBase01(1 == argc); //tstDer01(1 == argc); //tstVec01(true); //tstVec01(false); //tstEmbVec01(1 == argc); tstBoostVec01(true); tstBoostVec01(false); //tutorial(); } #endif /*struct TstSer { TstSer() { //tstBase01(1 == argc); //tstDer01(1 == argc); tstVec01(true); //tstVec01(false); //tstEmbVec01(1 == argc); ::exit(0); } }; TstSer tstSer01; */ // -lboost_serialization-mt-1_37 //ttt2 if "use all notes" is checked, it keeps rescanning at startup MP3Diags-1.0.12.079/src/MpegFrame.cpp0000644000175000001440000002245711476664303015646 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "MpegFrame.h" #include "DataStream.h" #include "Helpers.h" #include "Notes.h" using namespace std; //using namespace pearl; // based on http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm MpegFrameBase::MpegFrameBase(NoteColl& notes, istream& in) { m_pos = in.tellg(); const int BFR_SIZE (4); char bfr [BFR_SIZE]; MP3_CHECK_T (BFR_SIZE == read(in, bfr, BFR_SIZE), m_pos, "Not an MPEG frame. File too short.", NotMpegFrame()); init(notes, bfr); } MpegFrameBase::MpegFrameBase(NoteColl& notes, streampos pos, const char* bfr) { m_pos = pos; init(notes, bfr); } #ifdef GENERATE_TOC MpegFrameBase MpegFrameBase::getBigBps() const // returns a "similar" frame to "this" but with a bigger bps, so it can hold a Xing TOC { //char bfr [1000]; string s (&m_header[0], 4); //s[2] = (s[2] & 0x0f) | 0xe0; //ttt2 maybe use this; it provides maximum space; s[2] = (s[2] & 0x0f) | 0x90; s.resize(2000); NoteColl notes; istringstream in (s); MpegFrameBase res (notes, in); return res; } #endif void MpegFrameBase::init(NoteColl& notes, const char* bfr) //ttt2 should have some means to enforce bfr being large enough (perhaps switch to a vector) { memcpy(m_header, bfr, 4); //inspect(bfr, BFR_SIZE); //ttt2 check the CRC right after the header, if present (note that the size of a frame doesn't change as a result of using the CRC, as it can be seen in several files, e.g. "05 Are You Gonna Go My Way.mp3") const unsigned char* pHeader (reinterpret_cast(bfr)); MP3_CHECK_T (0xff == *pHeader && 0xe0 == (0xe0 & *(pHeader + 1)), m_pos, "Not an MPEG frame. Synch missing.", NotMpegFrame()/*"missing synch"*/); ++pHeader; { int nVer ((*pHeader & 0x18) >> 3); switch (nVer) {//TRACE case 0x00: MP3_THROW_T (m_pos, "Not an MPEG frame. Unsupported version (2.5).", NotMpegFrame()); //ttt2 see about supporting this: search for MPEG1 to find other places // ttt2 in a way it would make more sense to warn that it's not supported, with "MP3_THROW(SUPPORT, ...)", but before warn, make sure it's a valid 2.5 frame, followed by another frame ... case 0x02: m_eVersion = MPEG2; break; case 0x03: m_eVersion = MPEG1; break; default: MP3_THROW_T (m_pos, "Not an MPEG frame. Invalid version.", NotMpegFrame()); } } { int nLayer ((*pHeader & 0x06) >> 1); switch (nLayer) { case 0x01: m_eLayer = LAYER3; break; case 0x02: m_eLayer = LAYER2; break; case 0x03: m_eLayer = LAYER1; break; default: MP3_THROW_T (m_pos, "Not an MPEG frame. Invalid layer.", NotMpegFrame()); } } { m_bCrc = !(*pHeader & 0x01); } ++pHeader; { static int s_bitrates [14][5] = { { 32, 32, 32, 32, 8 }, { 64, 48, 40, 48, 16 }, { 96, 56, 48, 56, 24 }, { 128, 64, 56, 64, 32 }, { 160, 80, 64, 80, 40 }, { 192, 96, 80, 96, 48 }, { 224, 112, 96, 112, 56 }, { 256, 128, 112, 128, 64 }, { 288, 160, 128, 144, 80 }, { 320, 192, 160, 160, 96 }, { 352, 224, 192, 176, 112 }, { 384, 256, 224, 192, 128 }, { 416, 320, 256, 224, 144 }, { 448, 384, 320, 256, 160 } }; int nRateIndex ((*pHeader & 0xf0) >> 4); MP3_CHECK_T (nRateIndex >= 1 && nRateIndex <= 14, m_pos, "Not an MPEG frame. Invalid bitrate.", NotMpegFrame()/*"invalid bitrate"*/); //ttt3 add tests for invalid combinations of channel mode and bitrate (MPEG 1 Layer II only) int nTypeIndex (m_eVersion*3 + m_eLayer); if (nTypeIndex == 5) { nTypeIndex = 4; } m_nBitrate = s_bitrates[nRateIndex - 1][nTypeIndex]*1000; } { int nSmpl ((*pHeader & 0x0c) >> 2); switch (m_eVersion) { case MPEG1: switch (nSmpl) { case 0x00: m_nFrequency = 44100; break; case 0x01: m_nFrequency = 48000; break; case 0x02: m_nFrequency = 32000; break; default: MP3_THROW_T (m_pos, "Not an MPEG frame. Invalid frequency for MPEG1.", NotMpegFrame()); } break; case MPEG2: switch (nSmpl) { case 0x00: m_nFrequency = 22050; break; case 0x01: m_nFrequency = 24000; break; case 0x02: m_nFrequency = 16000; break; default: MP3_THROW_T (m_pos, "Not an MPEG frame. Invalid frequency for MPEG2.", NotMpegFrame()); } break; default: CB_ASSERT(false); // it should have thrown before getting here } } { m_nPadding = (0x02 & *pHeader) >> 1; } ++pHeader; { int nChMode ((*pHeader & 0xc0) >> 6); m_eChannelMode = (ChannelMode)nChMode; } switch (m_eLayer) { case LAYER1: m_nSize = (12*m_nBitrate/m_nFrequency + m_nPadding)*4; break; case LAYER2: m_nSize = 144*m_nBitrate/m_nFrequency + m_nPadding; break; case LAYER3: //cout << "m_nBitrate: " << m_nBitrate << endl; //cout << "m_nFrequency: " << m_nFrequency << endl; //cout << "m_nPadding: " << m_nPadding << endl; m_nSize = (MPEG1 == m_eVersion ? 144*m_nBitrate/m_nFrequency + m_nPadding : 72*m_nBitrate/m_nFrequency + m_nPadding); //MP3_CHECK (MPEG1 == m_eVersion, m_pos, "Temporary test for MPEG2. Remove after making sure the code works.", NotMpegFrame()/*"temporary"*/); // see http://www.codeproject.com/KB/audio-video/mpegaudioinfo.aspx break; default: CB_ASSERT(false); // it should have thrown before getting here } } MpegFrameBase::MpegFrameBase() : m_eVersion(MPEG1), m_eLayer(LAYER1), m_nBitrate(-1), m_nFrequency(-1), m_nPadding(-1), m_eChannelMode(SINGLE_CHANNEL), m_nSize(-1) {} const char* MpegFrameBase::getSzVersion() const { static const char* s_versionName[] = { "MPEG-1", "MPEG-2" }; return s_versionName[m_eVersion]; } const char* MpegFrameBase::getSzLayer() const { static const char* s_layerName[] = { "Layer I", "Layer II", "Layer III" }; return s_layerName[m_eLayer]; } const char* MpegFrameBase::getSzChannelMode() const { static const char* s_channelModeName[] = { "Stereo", "Joint stereo", "Dual channel", "Single channel" }; return s_channelModeName[m_eChannelMode]; } ostream& MpegFrameBase::write(ostream& out) const { out << getSzVersion() << " " << getSzLayer() << ", " << getSzChannelMode() << ", " << m_nFrequency << "Hz, " << m_nBitrate << "bps, CRC=" << boolAsYesNo(m_bCrc) << ", length=" << m_nSize << " (0x" << hex << m_nSize << dec << "), padding=" << boolAsYesNo(m_nPadding); return out; } ostream& operator<<(ostream& out, const MpegFrameBase& frm) { return frm.write(out); } int MpegFrameBase::getSideInfoSize() const // needed by Xing { return MpegFrame::MPEG1 == getVersion() ? (MpegFrame::SINGLE_CHANNEL == getChannelMode() ? 17 : 32) : (MpegFrame::SINGLE_CHANNEL == getChannelMode() ? 9 : 17); } MpegFrame::MpegFrame(NoteColl& notes, std::istream& in) : MpegFrameBase(notes, in) { streampos pos (m_pos); StreamStateRestorer rst (in); pos += m_nSize - 1; in.seekg(pos); char bfr [1]; if (1 != read(in, bfr, 1)) { ostringstream out; write(out); MP3_THROW_T (pos, "Not an MPEG frame. File too short.", PrematurelyEndedMpegFrame(out.str())); } rst.setOk(); } MP3Diags-1.0.12.079/src/SessionsDlgImpl.cpp0000644000175000001440000003403511265064404017045 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include "SessionsDlgImpl.h" #include "Helpers.h" #include "StoredSettings.h" #include "CheckedDir.h" #include "SessionEditorDlgImpl.h" #include "OsFile.h" #include "Widgets.h" using namespace std; //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== SessionsModel::SessionsModel(std::vector& vstrSessions) : m_vstrSessions(vstrSessions) { } /*override*/ int SessionsModel::rowCount(const QModelIndex&) const { return cSize(m_vstrSessions); } /*override*/ QVariant SessionsModel::data(const QModelIndex& index, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("SessionsModel::data()"); if (!index.isValid()) { return QVariant(); } int i (index.row()); //int j (index.column()); // ttt2 perhaps Qt::ToolTipRole if (Qt::DisplayRole != nRole) { return QVariant(); } return toNativeSeparators(convStr(m_vstrSessions.at(i))); } /*override*/ QVariant SessionsModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { return "File name"; } return nSection + 1; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== extern int CELL_HEIGHT; const QFont& getDefaultFont(); SessionsDlgImpl::SessionsDlgImpl(QWidget* pParent) : QDialog(pParent, getMainWndFlags()), Ui::SessionsDlg(), m_sessionsModel(m_vstrSessions) { { QApplication::setFont(getDefaultFont()); CELL_HEIGHT = QApplication::fontMetrics().height() + 3; //ttt2 hard-coded } setupUi(this); vector vstrSess; string strLast; //m_pSettings = SessionSettings::getGlobalSettings(); GlobalSettings st; bool bOpenLast; st.loadSessions(m_vstrSessions, strLast, bOpenLast); m_pOpenLastCkB->setChecked(bOpenLast); m_pSessionsG->verticalHeader()->setResizeMode(QHeaderView::Interactive); m_pSessionsG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT + 1); m_pSessionsG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT + 1);//*/ m_pSessionsG->setModel(&m_sessionsModel); m_pSessionsG->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); m_pSessionsG->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); m_pSessionsG->horizontalHeader()->hide(); m_pCheckedDirModel = new CheckedDirModel(this, CheckedDirModel::NOT_USER_CHECKABLE); m_pDirectoriesT->header()->hide(); m_pDirectoriesT->setModel(m_pCheckedDirModel); m_pCheckedDirModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::Drives); m_pCheckedDirModel->setSorting(QDir::IgnoreCase); m_pDirectoriesT->header()->setStretchLastSection(false); m_pDirectoriesT->header()->setResizeMode(0, QHeaderView::ResizeToContents); QPalette grayPalette (m_pDirectoriesT->palette()); grayPalette.setColor(QPalette::Base, grayPalette.color(QPalette::Disabled, QPalette::Window)); m_pDirectoriesT->setPalette(grayPalette); //m_sessionsModel.emitLayoutChanged(); connect(m_pSessionsG->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(onCrtSessChanged())); connect(m_pSessionsG, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onSessDoubleClicked(const QModelIndex&))); //m_pSessionsG->setCurrentIndex(m_sessionsModel.index(nLast, 0)); if (strLast.empty() && !m_vstrSessions.empty()) { strLast = m_vstrSessions.back(); } if (!strLast.empty()) { selectSession(strLast); } { int nWidth, nHeight; st.loadSessionsDlgSize(nWidth, nHeight); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } QTimer::singleShot(1, this, SLOT(onShow())); } SessionsDlgImpl::~SessionsDlgImpl() { GlobalSettings st; st.saveSessionsDlgSize(width(), height()); { vector vstrSess; string strLast; //m_pSettings = SessionSettings::getGlobalSettings(); //GlobalSettings st; vector v; bool bOpenLast; st.loadSessions(v, strLast, bOpenLast); st.saveSessions(m_vstrSessions, getCrtSession(), m_pOpenLastCkB->isChecked()); } } // ttt2 generic inconsistency in what is saved depending on the user clicking the "x" button, pressing ESC, clicking other button ... void SessionsDlgImpl::onShow() { m_pCheckedDirModel->expandNodes(m_pDirectoriesT); } string SessionsDlgImpl::run() { if (QDialog::Accepted != exec()) { return ""; } return getCrtSession(); } void GlobalSettings::saveSessionsDlgSize(int nWidth, int nHeight) { m_pSettings->setValue("sessions/width", nWidth); m_pSettings->setValue("sessions/height", nHeight); } void GlobalSettings::loadSessionsDlgSize(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("sessions/width").toInt(); nHeight = m_pSettings->value("sessions/height").toInt(); } void GlobalSettings::saveSessionEdtSize(int nWidth, int nHeight) { m_pSettings->setValue("sessionEditor/width", nWidth); m_pSettings->setValue("sessionEditor/height", nHeight); } void GlobalSettings::loadSessionEdtSize(int& nWidth, int& nHeight) const { nWidth = m_pSettings->value("sessionEditor/width").toInt(); nHeight = m_pSettings->value("sessionEditor/height").toInt(); } void SessionsDlgImpl::onCrtSessChanged() { int i (m_pSessionsG->selectionModel()->currentIndex().row()); int n (cSize(m_vstrSessions)); if (i < 0 || i >= n) { return; } SessionSettings st (m_vstrSessions[i]); vector vstrCheckedDirs, vstrUncheckedDirs; bool bOk (st.loadDirs(vstrCheckedDirs, vstrUncheckedDirs)); if (!bOk) { //ttt2 some warning } m_pCheckedDirModel->setDirs(vstrCheckedDirs, vstrUncheckedDirs, m_pDirectoriesT); } void SessionsDlgImpl::selectSession(const string& strLast) { vector::iterator it (std::find(m_vstrSessions.begin(), m_vstrSessions.end(), strLast)); CB_ASSERT (m_vstrSessions.end() != it); int k (it - m_vstrSessions.begin()); m_sessionsModel.emitLayoutChanged(); m_pSessionsG->setCurrentIndex(m_sessionsModel.index(k, 0)); onCrtSessChanged(); } string SessionsDlgImpl::getCrtSession() const { int i (m_pSessionsG->currentIndex().row()); if (i < 0 || i >= cSize(m_vstrSessions)) { return ""; } return m_vstrSessions[i]; } string SessionsDlgImpl::getCrtSessionDir() const { string s (getCrtSession()); if (!s.empty()) { s = getParent(s); } return s; } void SessionsDlgImpl::addSession(const std::string& strSession) { int n (cSize(m_vstrSessions)); for (int i = 0; i < n; ++i) { if (m_vstrSessions[i] == strSession) //ttt2 ignore case on windows { m_vstrSessions.erase(m_vstrSessions.begin() + i); --n; break; } } m_vstrSessions.push_back(strSession); selectSession(strSession); GlobalSettings st; st.saveSessions(m_vstrSessions, strSession, m_pOpenLastCkB->isChecked()); } void SessionsDlgImpl::on_m_pNewB_clicked() { string strSession; { SessionEditorDlgImpl dlg (this, getCrtSessionDir(), SessionEditorDlgImpl::NOT_FIRST_TIME); strSession = dlg.run(); if (strSession.empty()) { return; } } addSession(strSession); } void SessionsDlgImpl::on_m_pEditB_clicked() { string strSession (getCrtSession()); if (strSession.empty()) { return; } SessionEditorDlgImpl dlg (this, strSession); dlg.run(); //m_sessionsModel.emitLayoutChanged(); onCrtSessChanged(); } void SessionsDlgImpl::removeCrtSession() { int k (m_pSessionsG->currentIndex().row()); int n (cSize(m_vstrSessions)); if (k < 0 || k >= n) { return; } m_vstrSessions.erase(m_vstrSessions.begin() + k); //m_sessionsModel.emitLayoutChanged(); if (k == n - 1) { --k; } string strCrtSess; if (k >= 0) { strCrtSess = m_vstrSessions[k]; selectSession(strCrtSess); } else { vector v; m_pCheckedDirModel->setDirs(v, v, m_pDirectoriesT); // to uncheck all dirs } GlobalSettings st; st.saveSessions(m_vstrSessions, strCrtSess, m_pOpenLastCkB->isChecked()); } void SessionsDlgImpl::on_m_pEraseB_clicked() { if (m_vstrSessions.empty()) { return; } if (0 != showMessage(this, QMessageBox::Question, 1, 1, "Confirm", "Do you really want to erase the current session?", "Erase", "Cancel")) { return; } string s (getCrtSession()); removeCrtSession(); try { deleteFile(s); deleteFile(SessionEditorDlgImpl::getDataFileName(s)); if (fileExists(SessionEditorDlgImpl::getLogFileName(s))) { deleteFile(SessionEditorDlgImpl::getLogFileName(s)); } } catch (const std::bad_alloc&) { throw; } catch (...) //ttt2 use specific exceptions { QMessageBox::critical(this, "Error", "Failed to remove the data files associated with this session"); // maybe the files were already deleted ... return; } } //ttt2 perhaps: when choosing dirs show them in the title bar or a label void SessionsDlgImpl::on_m_pSaveAsB_clicked() { if (m_vstrSessions.empty()) { return; } //string s (getCrtSession()); QFileDialog dlg (this, "Save session as ...", convStr(getCrtSessionDir()), "INI files (*.ini)"); dlg.setAcceptMode(QFileDialog::AcceptSave); if (QDialog::Accepted != dlg.exec()) { return; } QStringList fileNames (dlg.selectedFiles()); if (1 != fileNames.size()) { return; } string s (convStr(fileNames.first())); if (!endsWith(s, ".ini")) { s += ".ini"; } string strCrt (getCrtSession()); if (s == strCrt) { return; } try { copyFile2(strCrt, s); copyFile2(SessionEditorDlgImpl::getDataFileName(strCrt), SessionEditorDlgImpl::getDataFileName(s)); if (fileExists(SessionEditorDlgImpl::getLogFileName(strCrt))) { copyFile2(SessionEditorDlgImpl::getLogFileName(strCrt), SessionEditorDlgImpl::getLogFileName(s)); } } catch (const std::bad_alloc&) { throw; } catch (...) { //ttt2 show errors } addSession(s); } void SessionsDlgImpl::on_m_pHideB_clicked() { if (m_vstrSessions.empty()) { return; } if (0 != showMessage(this, QMessageBox::Question, 1, 1, "Confirm", "Do you really want to hide the current session?", "Hide", "Cancel")) { return; } removeCrtSession(); } void SessionsDlgImpl::on_m_pLoadB_clicked() { QFileDialog dlg (this, "Choose a session file", convStr(getCrtSessionDir()), "INI files (*.ini)"); dlg.setAcceptMode(QFileDialog::AcceptOpen); if (QDialog::Accepted != dlg.exec()) { return; } QStringList fileNames (dlg.selectedFiles()); if (1 != fileNames.size()) { return; } string s (convStr(fileNames.first())); CB_ASSERT (endsWith(s, ".ini")); for (int i = 0, n = cSize(m_vstrSessions); i < n; ++i) { if (m_vstrSessions[i] == s) { QMessageBox::critical(this, "Error", "The session named \"" + toNativeSeparators(convStr(s)) + "\" is already part of the session list"); return; } } addSession(s); } void SessionsDlgImpl::on_m_pOpenB_clicked() { if (getCrtSession().empty()) { QMessageBox::critical(this, "Error", "The session list is empty. You must create a new session or load an existing one."); return; } accept(); } void SessionsDlgImpl::on_m_pCancelB_clicked() { reject(); } void SessionsDlgImpl::onSessDoubleClicked(const QModelIndex& index) { selectSession(m_vstrSessions.at(index.row())); on_m_pOpenB_clicked(); } void SessionsDlgImpl::onHelp() { openHelp("310_advanced.html"); } MP3Diags-1.0.12.079/src/ReadMe0000644000175000001440000000052611200232050014317 0ustar ciobiusersREAD THIS IN ORDER TO COMPILE THE Qt4 TEMPLATE ---------------------------------------------- Before compiling, check the Qt Options, go to Project->Project Options->C++ Support and open the Qt Options tab. Check that the Qt installation directory is correct for the Qt version you've chosen. ------------------ Andreas Pakulat July 2006 MP3Diags-1.0.12.079/src/LogModel.h0000644000175000001440000000511111200236210015107 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef LogModelH #define LogModelH #include //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class CommonData; class QTableView; // all files class LogModel : public QAbstractTableModel { Q_OBJECT CommonData* m_pCommonData; QTableView* m_pLogG; public: LogModel(CommonData* pCommonData, QTableView* pLogG); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int nRole) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; //void selectTopLeft(); private: //public slots: //void onLoGSelChanged(); }; #endif // #ifndef LogModelH MP3Diags-1.0.12.079/src/ApeStream.cpp0000644000175000001440000003202711332565000015637 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "ApeStream.h" #include "Helpers.h" using namespace std; using namespace pearl; namespace { //ttt3 these might get used uninitialized, if read before main() const char* LBL_TITLE ("Title"); const char* LBL_ARTIST ("Artist"); //ttt2 may be list //const char* LBL_TRACK_NUMBER ("TRCK"); //const char* LBL_TRACK_YEAR ("TYER"); //const char* LBL_TRACK_DATE ("TDAT"); const char* LBL_GENRE ("Genre"); //ttt2 may be list //const char* LBL_IMAGE ("APIC"); const char* LBL_ALBUM ("Album"); const set& getUtf8Keys() { static bool bFirstTime (true); static set sUtf8Keys; if (bFirstTime) { sUtf8Keys.insert(LBL_TITLE); sUtf8Keys.insert(LBL_ARTIST); //sUtf8Keys.insert(LBL_TRACK_NUMBER); //sUtf8Keys.insert(LBL_TRACK_YEAR); //sUtf8Keys.insert(LBL_TRACK_DATE); sUtf8Keys.insert(LBL_GENRE); //sUtf8Keys.insert(LBL_IMAGE); sUtf8Keys.insert(LBL_ALBUM); bFirstTime = false; } return sUtf8Keys; } const set& getUsedKeys() { static bool bFirstTime (true); static set sUsedFrames; if (bFirstTime) { sUsedFrames.insert(LBL_TITLE); sUsedFrames.insert(LBL_ARTIST); // ttt2 really list //sUsedFrames.insert(LBL_TRACK_NUMBER); //sUsedFrames.insert(LBL_TRACK_YEAR); //sUsedFrames.insert(LBL_TRACK_DATE); sUsedFrames.insert(LBL_GENRE); //sUsedFrames.insert(LBL_IMAGE); sUsedFrames.insert(LBL_ALBUM); bFirstTime = false; } return sUsedFrames; } } //============================================================================================================ //============================================================================================================ //============================================================================================================ ApeItem::ApeItem(NoteColl& notes, istream& in) : m_eType(BINARY) { StreamStateRestorer rst (in); streampos pos (in.tellg()); const int BFR_SIZE (4 + 4 + 255 + 1); // key name is up to 255 chars char bfr [BFR_SIZE]; streamsize nRead (read(in, bfr, BFR_SIZE)); MP3_CHECK (nRead >= 4 + 4 + 2 + 1, pos, apeItemTooShort, ApeStream::NotApeStream()); unsigned char* pUnsgBfr (reinterpret_cast(bfr)); m_cFlags1 = pUnsgBfr[4]; m_cFlags2 = pUnsgBfr[5]; m_cFlags3 = pUnsgBfr[6]; m_cFlags4 = pUnsgBfr[7]; MP3_CHECK (0 == m_cFlags1 && 0 == m_cFlags2 && 0 == m_cFlags3 && 0 == m_cFlags4, pos, apeFlagsNotSupported, StreamIsUnsupported(ApeStream::getClassDisplayName(), "Ape stream whose items have unsupported flags.")); //MP3_CHECK (0 == (m_cFlags1 & 0xf8u) && 0 == m_cFlags2 && 0 == m_cFlags3 && 0 == m_cFlags4, pos, apeFlagsNotSupported, StreamIsUnsupported(ApeStream::getClassDisplayName(), "Ape stream whose items have unsupported flags.")); // ttt1 allow this; see 02_-_Brave_-_Driven.mp3, which has a "BINARY" value (hence the "2" flag, which is also larger than 256) //inspect(bfr, BFR_SIZE); int nDataSize (pUnsgBfr[0] + (pUnsgBfr[1] << 8) + (pUnsgBfr[2] << 16) + (pUnsgBfr[3] << 24)); char* p (bfr + 8); for (; 0 != *p && p < bfr + nRead; ++p) {} MP3_CHECK (p < bfr + nRead, pos, apeMissingTerminator, ApeStream::NotApeStream()); m_strName = string(bfr + 8, p); if (nDataSize > 256) { ostringstream out; out << "Ape Item seems too big. Although the size may be any 32-bit integer, 256 bytes should be enough in practice. If this message is determined to be mistaken, it will be removed in the future. Item key: " << m_strName << "; item size: " << nDataSize; MP3_NOTE_D (pos, apeItemTooBig, out.str()); throw ApeStream::NotApeStream(); //ttt1 actually it's possible; see 02_-_Brave_-_Driven.mp3 } m_vcValue.resize(nDataSize); pos += getTotalSize() - nDataSize; in.clear(); in.seekg(pos); MP3_CHECK (nDataSize == read(in, &m_vcValue[0], nDataSize), pos, apeItemTooShort, ApeStream::NotApeStream()); if (getUtf8Keys().count(m_strName) > 0) { m_eType = UTF8; } if (UTF8 != m_eType) { if (nDataSize <= 256) { for (int i = 0; i < nDataSize; ++i) { if (m_vcValue[i] < 32 || m_vcValue[i] > 126) { goto e1; } } } m_eType = UTF8; e1:; } rst.setOk(); //inspect(m_aValue, m_nDataSize); } string ApeItem::getUtf8String() const { switch (m_eType) { case BINARY: return ""; case UTF8: return string(&m_vcValue[0], &m_vcValue[0] + cSize(m_vcValue)); } CB_ASSERT(false); } //============================================================================================================ //============================================================================================================ //============================================================================================================ ApeStream::ApeStream(int nIndex, NoteColl& notes, istream& in) : DataStream(nIndex) { StreamStateRestorer rst (in); m_pos = in.tellg(); //const int APE_LABEL_SIZE (8); //const int BFR_SIZE (32);//(APE_LABEL_SIZE + 4 + 4); char bfr [32]; streamsize nRead (read(in, bfr, 32)); MP3_CHECK_T (32 == nRead, m_pos, "Not an Ape tag. File too short.", NotApeStream()); //inspect (bfr, m_pos); MP3_CHECK_T (0 == strncmp("APETAGEX", bfr, 8), m_pos, "Not an Ape tag. Invalid header.", NotApeStream()); m_nVersion = *reinterpret_cast(bfr + 8); // ttt2 assume 32-bit int + little-endian m_nSize = *reinterpret_cast(bfr + 12); // ttt2 assume 32-bit int + little-endian MP3_CHECK (0x80 == (0xc0 & (unsigned char)bfr[23]), m_pos, apeUnsupported, StreamIsUnsupported(ApeStream::getClassDisplayName(), "Tag missing header or footer.")); //ttt2 assumes both header & footer are present, but they are optional; MP3_CHECK (0 != (0x20 & bfr[23]), m_pos, apeFoundFooter, NotApeHeader()); streampos posEnd (m_pos); posEnd += m_nSize; m_nSize += 32; // account for header in.seekg(posEnd); char bfr2 [32]; nRead = read(in, bfr2, 32); MP3_CHECK (32 == nRead, m_pos, apeTooShort, NotApeStream()); MP3_CHECK (0 == (0x20 & bfr2[23]), m_pos, apeFoundHeader, NotApeFooter()); bfr2[23] |= 0x20; //inspect (bfr2, posEnd); for (int i = 0; i < 32; ++i) { MP3_CHECK (bfr[i] == bfr2[i], m_pos, apeHdrFtMismatch, HeaderFooterMismatch()); } readKeys(notes, in); MP3_TRACE (m_pos, "ApeStream built."); rst.setOk(); } ApeStream::~ApeStream() { clearPtrContainer(m_vpItems); } /*override*/ void ApeStream::copy(std::istream& in, std::ostream& out) { appendFilePart(in, out, m_pos, m_nSize); } /*override*/ std::string ApeStream::getInfo() const { return ""; } void ApeStream::readKeys(NoteColl& notes, std::istream& in) { streampos posEnd (m_pos); posEnd += m_nSize - 32; // where the footer begins streampos posCrt (m_pos); posCrt += 32; in.seekg(posCrt); while (posCrt < posEnd) { ApeItem* p (new ApeItem(notes, in)); posCrt += p->getTotalSize(); m_vpItems.push_back(p); } } ApeItem* ApeStream::findItem(const char* szFrameName) //ttt2 finds the first item, but doesn't care about duplicates; not sure how Ape views duplicate keys { for (int i = 0, n = cSize(m_vpItems); i < n; ++i) { ApeItem* p = m_vpItems[i]; if (szFrameName == p->m_strName) { return p; } } return 0; } const ApeItem* ApeStream::findItem(const char* szFrameName) const //ttt2 finds the first item, but doesn't care about duplicates; not sure how Ape views duplicate keys { for (int i = 0, n = cSize(m_vpItems); i < n; ++i) { const ApeItem* p = m_vpItems[i]; if (szFrameName == p->m_strName) { return p; } } return 0; } //Mp3Gain ApeStream::getMp3GainStatus() const /* There are MP3GAIN and REPLAYGAIN. Not sure how they are related, because the program mp3gain creates both MP3GAIN and REPLAYGAIN entries. Here's a newly generated tag: MP3GAIN_MINMAX="139,240", MP3GAIN_UNDO="+005,+005,N", REPLAYGAIN_TRACK_GAIN="-0.205000 dB", REPLAYGAIN_TRACK_PEAK="0.466454 and an older one: MP3GAIN_MINMAX="089,179", MP3GAIN_ALBUM_MINMAX="000,196", MP3GAIN_UNDO="+005,+005,N", REPLAYGAIN_TRACK_GAIN="+6.915000 dB", REPLAYGAIN_TRACK_PEAK="0.289101", REPLAYGAIN_ALBUM_GAIN="+6.600000 dB", REPLAYGAIN_ALBUM_PEAK="0.886662" It seems that MP3GAIN is about changing audio data (for which there is an undo as long as the Ape tag is not deleted), while REPLAYGAIN only adds tags, which require compatible players. Not sure how to tell from these if album and/or track info are found. Currently (2009.03.14) it doesn't matter, so a bool is better. */ bool ApeStream::hasMp3Gain() const { return 0 != findItem("MP3GAIN_MINMAX") || 0 != findItem("MP3GAIN_ALBUM_MINMAX") || 0 != findItem("REPLAYGAIN_TRACK_GAIN") || 0 != findItem("REPLAYGAIN_ALBUM_GAIN"); } // ================================ TagReader ========================================= /*override*/ TagReader::SuportLevel ApeStream::getSupport(Feature eFeature) const { switch (eFeature) { case TITLE: case ARTIST: //case TRACK_NUMBER: //case TRACK_YEAR: //case TRACK_DATE: case GENRE: //case PICTURE: case ALBUM: return READ_ONLY; default: return NOT_SUPPORTED; } // enum SuportLevel { NOT_SUPPORTED, , READ_WRITE }; } /*override*/ std::string ApeStream::getTitle(bool* pbFrameExists /*= 0*/) const { const ApeItem* p (findItem(LBL_TITLE)); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } /*override*/ std::string ApeStream::getArtist(bool* pbFrameExists /*= 0*/) const { const ApeItem* p (findItem(LBL_ARTIST)); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } /*override*/ std::string ApeStream::getTrackNumber(bool* /*pbFrameExists*/ /*= 0*/) const { /*const ApeItem* p (findItem(LBL_TRACK_NUMBER)); if (0 == p) { return ""; } return p->getUtf8String();*/ throw NotSupportedOp(); } /*override*/ TagTimestamp ApeStream::getTime(bool* /*= 0*/) const { throw NotSupportedOp(); } /*override*/ std::string ApeStream::getGenre(bool* pbFrameExists /*= 0*/) const { const ApeItem* p (findItem(LBL_GENRE)); // not always correct; the specs say it's a "numeric string"; usually a descriptive string seems to be used though, not a number; anyway, "Cenaclul Flacara 3/c06 Anda Calugareanu - Noi, nu.mp3" has a "(80)" in this field if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } /*override*/ std::string ApeStream::getAlbumName(bool* pbFrameExists /*= 0*/) const { const ApeItem* p (findItem(LBL_ALBUM)); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } /*override*/ std::string ApeStream::getOtherInfo() const { const set& sUsedKeys (getUsedKeys()); set sUsedFrames; ostringstream out; bool b (false); for (int i = 0, n = cSize(m_vpItems); i < n; ++i) { ApeItem* p = m_vpItems[i]; if (sUsedKeys.count(p->m_strName) > 0 && sUsedFrames.count(p->m_strName) == 0) { sUsedFrames.insert(p->m_strName); } else { if (b) { out << ", "; } out << p->m_strName << "=\"" << p->getUtf8String() << "\""; b = true; } } return out.str(); } MP3Diags-1.0.12.079/src/FullSizeImgDlg.h0000644000175000001440000000351211304150114016234 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef FullSizeImgDlgH #define FullSizeImgDlgH #include #include "CommonTypes.h" class FullSizeImgDlg : public QDialog { Q_OBJECT const ImageInfo& m_imageInfo; public: FullSizeImgDlg(QWidget* pParent, const ImageInfo& imageInfo); public slots: void onCopy(); }; #endif // #ifndef WidgetsH MP3Diags-1.0.12.079/src/MpegStream.h0000644000175000001440000002716011261077516015504 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MpegStreamH #define MpegStreamH #include "DataStream.h" #include "MpegFrame.h" #include "Helpers.h" // reads a single frame class MpegStreamBase : public DataStream { StreamStateRestorer* m_pRst; protected: MpegStreamBase() : m_pRst(0) {} // serialization-only constructor MpegFrame m_firstFrame; std::streampos m_pos; MpegStreamBase(int nIndex, NoteColl& notes, std::istream& in); void setRstOk() { m_pRst->setOk(); releasePtr(m_pRst); // destroy and set to 0 } public: ~MpegStreamBase(); /*override*/ void copy(std::istream& in, std::ostream& out); // copies "m_firstFrame"; derived classes should decide if it's good enough for them /*override*/ std::streampos getPos() const { return m_pos; } /*override*/ std::streamoff getSize() const { return m_firstFrame.getSize(); } const MpegFrame& getFirstFrame() const { return m_firstFrame; } private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); ar & m_firstFrame; ar & m_pos; //ar & m_pRst; // 2009.04.24 - shouldn't be needed, because it's only used by the "real" constructor } }; class MpegStream : public MpegStreamBase { std::streamoff m_nSize; int m_nBitrate; bool m_bVbr; int m_nFrameCount; std::streampos m_posLastFrame; MpegFrame m_lastFrame; long long m_nTotalBps; bool m_bRemoveLastFrameCalled; enum { MIN_FRAME_COUNT = 10 }; public: MpegStream(int nIndex, NoteColl& notes, std::istream& in); /*override*/ void copy(std::istream& in, std::ostream& out); DECL_NAME("MPEG Audio"); /*override*/ std::string getInfo() const; /*override*/ std::streampos getPos() const { return m_pos; } /*override*/ std::streamoff getSize() const { return m_nSize; } int getBitrate() const { return m_nBitrate; } bool isVbr() const { return m_bVbr; } using MpegStreamBase::getFirstFrame; std::streampos getLastFramePos() const { return m_posLastFrame; } void removeLastFrame(); // this can only be called once; the second call will throw (it's harder and quite pointless to allow more than one call) bool isCompatible(const MpegFrameBase& frame); int getFrameCount() const { return m_nFrameCount; } MpegFrame::ChannelMode getChannelMode() const { return m_firstFrame.getChannelMode(); } bool findNextCompatFrame(std::istream& in, std::streampos posMax); // moves the read pointer to the first frame compatible with the stream; returns "false" if no such frame is found std::string getDuration() const; struct StreamTooShort // exception thrown if a stream has less than 10 frames { std::string m_strInfo; int m_nFrameCount; StreamTooShort(const std::string& strInfo, int nFrameCount) : m_strInfo(strInfo), m_nFrameCount(nFrameCount) {} }; struct UnknownHeader {}; // exception thrown if the first frame seems to be part of a (Lame) header, having a different framerate in an otherwise CBR stream void createXing(std::ostream& out); private: friend class boost::serialization::access; MpegStream() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); ar & m_nSize; ar & m_nBitrate; ar & m_bVbr; ar & m_nFrameCount; ar & m_posLastFrame; ar & m_lastFrame; ar & m_nTotalBps; ar & m_bRemoveLastFrameCalled; } }; void createXing(std::ostream& out, const MpegFrame& frame, int nFrameCount, std::streamoff nStreamSize); // throws if it can't write to the disk class XingStreamBase : public MpegStreamBase { unsigned char m_cFlags; int m_nFrameCount; int m_nByteCount; char m_toc [100]; int m_nQuality; protected: void getXingInfo(std::ostream&) const; XingStreamBase() {} // serialization-only constructor public: XingStreamBase(int nIndex, NoteColl& notes, std::istream& in); // /*override*/ void copy(std::istream& in, std::ostream& out); DECL_NAME("Xing Header"); /*override*/ std::string getInfo() const; std::string getInfoForXml() const; bool matchesStructure(const MpegStream&) const; // checks that there is a metch for version, layer, frequency bool matches(const MpegStream&) const; // checks that there is a metch for version, layer, frequency and frame count bool matches(const DataStream* pNext) const; // checks that pNext is MpegStream* in addition to matches(const MpegStream&) bool isBrokenByMp3Fixer(const DataStream* pNext, const DataStream* pAfterNext) const; const MpegFrame& getFrame() const { return m_firstFrame; } int getFrameCount() const { return m_nFrameCount; } using MpegStreamBase::getFirstFrame; struct NotXingStream {}; private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); ar & m_cFlags; ar & m_nFrameCount; ar & m_nByteCount; ar & m_toc; ar & m_nQuality; } }; class XingStream : public XingStreamBase { public: XingStream(int nIndex, NoteColl& notes, std::istream& in); private: friend class boost::serialization::access; XingStream() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); } }; class LameStream : public XingStreamBase //ttt2 read & interpret data from Lame tag { public: LameStream(int nIndex, NoteColl& notes, std::istream& in); // /*override*/ void copy(std::istream& in, std::ostream& out); DECL_NAME("Lame Header"); /*override*/ std::string getInfo() const; struct NotLameStream {}; private: friend class boost::serialization::access; LameStream() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); } }; class VbriStream : public MpegStreamBase // Amarok doesn't seem to care about this, so the Xing header must be used anyway for VBR to work { public: VbriStream(int nIndex, NoteColl& notes, std::istream& in); // /*override*/ void copy(std::istream& in, std::ostream& out); DECL_NAME("VBRI Header"); /*override*/ std::string getInfo() const; const MpegFrame& getFrame() const { return m_firstFrame; } struct NotVbriStream {}; private: friend class boost::serialization::access; VbriStream() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); } }; //------------------------------------------------------------------------------------------------------- class Id3V1Stream : public DataStream, public TagReader { char m_data [128]; std::streampos m_pos; // needed only to display info enum TestResult { BAD, ZERO_PADDED, SPACE_PADDED, MIXED_PADDED, NOT_PADDED }; static TestResult checkId3V1String(const char* p, int nSize); // makes sure that a valid string is stored at the address given, meaning no chars smaller than 32; well, except for 0: 0 isn't really valid, as the fields are supposed to be padded with spaces at the right, but some tools use 0 anyway static bool isLegal(char c); std::string getStr(int nAddr, int nMaxSize) const; // returns the string located at nAddr, removing trailing spaces; the result is in UTF8 format enum Version { V10, V11, V11b }; Version m_eVersion; int getCommSize() const; public: Id3V1Stream(int nIndex, NoteColl& notes, std::istream& in); /*override*/ void copy(std::istream& in, std::ostream& out); DECL_RD_NAME("ID3V1"); /*override*/ std::string getInfo() const; /*override*/ std::streampos getPos() const { return m_pos; } /*override*/ std::streamoff getSize() const { return 128; } const char* getVersion() const; struct NotId3V1Stream {}; // ================================ TagReader ========================================= /*override*/ std::string getTitle(bool* pbFrameExists = 0) const; /*override*/ std::string getArtist(bool* pbFrameExists = 0) const; /*override*/ std::string getTrackNumber(bool* pbFrameExists = 0) const; /*override*/ TagTimestamp getTime(bool* pbFrameExists = 0) const; /*override*/ std::string getGenre(bool* pbFrameExists = 0) const; /*override*/ ImageInfo getImage(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } /*override*/ std::string getAlbumName(bool* pbFrameExists = 0) const; /*override*/ std::string getOtherInfo() const; /*override*/ SuportLevel getSupport(Feature) const; private: friend class boost::serialization::access; Id3V1Stream() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); ar & m_data; ar & m_pos; ar & m_eVersion; } }; const char* getId3V1Genre(int n); // doesn't throw; for invalid params returns "" #endif // ifndef MpegStreamH MP3Diags-1.0.12.079/src/Scan.ui0000644000175000001440000000306211227440264014501 0ustar ciobiusers ScanDlg 0 0 542 579 Scan true Qt::Horizontal Rescan files that seem unchanged Qt::Horizontal 40 20 &Scan Cancel MP3Diags-1.0.12.079/src/Normalize.ui0000644000175000001440000000470311227440206015554 0ustar ciobiusers NormalizeDlg 0 0 834 447 Normalize true true QTextEdit::NoWrap true 0 0 0 0 Qt::Horizontal 40 20 Keep window open after completion Abort Close true m_pDetailE m_pKeepOpenCkM m_pAbortB m_pCloseB m_pOutM MP3Diags-1.0.12.079/src/Export.ui0000644000175000001440000001151411261050765015100 0ustar ciobiusers ExportDlg 0 0 988 370 Export true File name: ... Format 0 XML Text M3U Remove root: When creating an M3U file, this text gets removed from the beginning of the file names. Meant to be used for creating M3U files containing relative paths. Locale: Files to save 0 Visible files Selected files Qt::Horizontal 40 20 Sort by short names Qt::Vertical 20 31 Qt::Horizontal 40 20 Close Export true MP3Diags-1.0.12.079/src/SessionEditor.ui0000644000175000001440000000777311227440301016414 0ustar ciobiusers SessionEditorDlg 0 0 737 566 pppppppppppppp true Include directories Backup 0 Don't create backup for modified files Create backup for modified files in true ... Settings file name true ... Scan for new, modified, and deleted files at startup true Open last session at s&tartup true Open the main "Sessions" dialog, to load an existing session Qt::Horizontal 40 20 O&K true Cancel MP3Diags-1.0.12.079/src/FilesModel.h0000644000175000001440000001120511261073057015450 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef FilesModelH #define FilesModelH #include #include #include #include //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class CommonData; // all files class FilesModel : public QAbstractTableModel { Q_OBJECT int m_nPrevCurrentRow; // the "previous current" while processing the "current changed" event; used to determine if the current notes (m_vpCrtNotes) and streams need to be updated public: FilesModel(CommonData* pCommonData); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int nRole) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; CommonData* m_pCommonData; //void selectTopLeft(); // makes current and selects the element in the top-left corner and emits a change signal regardless of the element that was selected before; makes current the default invalid index (-1,-1) if the table is empty void selectRow(int nCrtRow, const std::vector& vnSel = std::vector()); // makes current and selects the specified row and emits a change signal regardless of the element that was selected before; makes current the default invalid index (-1,-1) if the table is empty //void matchSelToStreams(); void matchSelToNotes(); void fixSelection(); // deselects cells that are selected but are on a different row from the "current" cell and selects the file name signals: void currentFileChanged(); public slots: void onFilesGSelChanged(); }; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== //class FilesGDelegate : public QAbstractItemDelegate class FilesGDelegate : public QItemDelegate { Q_OBJECT public: FilesGDelegate(CommonData* pCommonData, QObject* pParent) : QItemDelegate(pParent), m_pCommonData(pCommonData) {} /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; /*override*/ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; CommonData* m_pCommonData; }; class FileHeaderView : public QHeaderView { Q_OBJECT /*override*/ void paintSection(QPainter* pPainter, const QRect& rect, int nLogicalIndex) const; /*override*/ void mouseMoveEvent(QMouseEvent* pEvent); CommonData* m_pCommonData; public: FileHeaderView(CommonData* pCommonData, QWidget* pParent); }; #endif // #ifndef FilesModelH MP3Diags-1.0.12.079/src/Id3V230Stream.h0000644000175000001440000001612011274217504015575 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef Id3V230StreamH #define Id3V230StreamH #include "Id3V2Stream.h" // Frame of an ID3V2.3.0 tag struct Id3V230Frame : public Id3V2Frame { Id3V230Frame(NoteColl& notes, std::istream& in, std::streampos pos, bool bHasUnsynch, std::streampos posNext, StringWrp* pFileName); Id3V230Frame(const std::string& strName, std::vector& vcData); // needed by Id3V230StreamWriter::addBinaryFrame(), so objects created with this constructor don't get serialized; destroys vcData by doing a swap for its own representation /*override*/ ~Id3V230Frame(); /*override*/ bool discardOnChange() const; private: // may return multiple null characters; it's the job of getUtf8String() to deal with them; // chars after the first null are considered comments (or after the second null, for TXXX); /*override*/ std::string getUtf8StringImpl() const; friend class boost::serialization::access; Id3V230Frame() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); } }; class Id3V230Stream : public Id3V2StreamBase { public: Id3V230Stream(int nIndex, NoteColl& notes, std::istream& in, StringWrp* pFileName, bool bAcceptBroken = false); //typedef typename Id3V2Stream::NotId3V2 NotId3V230; DECL_RD_NAME("ID3V2.3.0"); /*override*/ TagTimestamp getTime(bool* pbFrameExists = 0) const; /*override*/ void setTrackTime(const TagTimestamp&) { throw NotSupportedOp(); } /*override*/ SuportLevel getSupport(Feature) const; private: friend class boost::serialization::access; Id3V230Stream() {} // serialization-only constructor template void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object(*this); } }; class Id3V240Stream; class CommonData; class Id3V230StreamWriter { std::vector m_vpOwnFrames; std::vector m_vpAllFrames; bool m_bKeepOneValidImg; bool m_bFastSave; const std::string m_strDebugFileName; // used only to show debug info from asserts public: enum { KEEP_ALL_IMG, KEEP_ONE_VALID_IMG }; Id3V230StreamWriter(bool bKeepOneValidImg, bool bFastSave, Id3V2StreamBase*, const std::string& strDebugFileName); // if bKeepOneValidImg is true, at most an APIC frame is kept, and it has to be valid or at least link; Id3V2StreamBase* may be 0; ~Id3V230StreamWriter(); void removeFrames(const std::string& strName, int nPictureType = -1); // if multiple frames with the same name exist, they are all removed; asserts that nPictureType is -1 for non-APIC frames; if nPictureType is -1 and strName is APIC, it removes all APIC frames //void removeApicFrames(const std::vector& vcData, int nPictureType); // an APIC frame is removed iff it has the image in vcData or the type nPictureType (or both) void addTextFrame(const std::string& strName, const std::string& strVal); // strVal is UTF8; the frame will use ASCII if possible and UTF16 otherwise (so if there's a char with a code above 127, UTF16 gets used, to avoid codepage issues for codes between 128 and 255); nothing is added if strVal is empty; all zeroes are saved and not considered terminators; void addBinaryFrame(const std::string& strName, std::vector& vcData); // destroys vcData by doing a swap for its own representation; asserts that strName is not APIC // the image type is ignored; images are always added as cover; // if there is an APIC frame with the same image, it is removed (it doesn't matter if it has different type, description ...); // if cover image already exists it is removed; void addImg(std::vector& vcData); void addNonOwnedFrame(const Id3V2Frame* p); void setRecTime(const TagTimestamp& time); // this only changes the frames that correspond to the active settings in the configuration; // if WMP handling is disabled, TPE2 is left untouched; if WMP handling is enabled, TPE2 is either removed or set to "Various Artists", based on "b" // if iTunes handling is disabled, TCON is left untouched; if WMP handling is enabled, TCON is either removed or set to "1", based on "b" void setVariousArtists(bool b); // throws WriteError if it cannot write, including the case when nTotalSize is too small; // if nTotalSize is >0, the padding will be be whatever is left; // if nTotalSize is <0 and m_bFastSave is true, there will be a padding of around ImageInfo::MAX_IMAGE_SIZE+Id3V2Expander::EXTRA_SPACE; // if (nTotalSize is <0 and m_bFastSave is false) or if nTotalSize is 0 (regardless of m_bFastSave), there will be a padding of between DEFAULT_EXTRA_SPACE and DEFAULT_EXTRA_SPACE + 511; // (0 discards extra padding regardless of m_bFastSave) void write(std::ostream& out, int nTotalSize = -1) const; //bool equalTo(Id3V2StreamBase* pId3V2Stream) const; // returns true if all of these happen: pId3V2Stream is ID3V2.3.0, no unsynch is used, the frames are identical except for their order; padding is ignored; bool contentEqualTo(Id3V2StreamBase* pId3V2Stream) const; // returns true if the frames are identical except for their order; padding, unsynch and version is ignored; bool isEmpty() const { return m_vpAllFrames.empty(); } static const int DEFAULT_EXTRA_SPACE; }; #endif // ifndef Id3V230StreamH MP3Diags-1.0.12.079/src/SongInfoParser.h0000644000175000001440000003053711252461427016337 0ustar ciobiusers/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef SongInfoParserH #define SongInfoParserH #include #include namespace SongInfoParser { /* Getting song details from file names: The main class is TrackTextParser, but it is mereley an interface to other classes: Reader, BoundReader StaticReader RatingReader TrackNoReader YearReader UnboundReader SequenceReader OptionalReader Reader is the base class in the hierarchy, representing the idea of "something" that can match (or not) a part of a string. I declares 2 main functions: 1) init(const char* pcLeft, const char* pcRight, bool bLeftFirst) - tries to match the string beggining at pcLeft and ending at pcRight and sets the internal state accordingly (m_pcLeft, m_pcRight, m_eLeftBound, m_eRightBound, m_eState). The matching doesn't always have to cover the whole string. A substring is sufficient in many cases. bLeftFirst indicates where the search for a substring should start. 2) set(vector& v) may be called only if init() succeeded; v's size must be "TagReader::LIST_END+1", one element for each supported field and an additional one for ignored strings; each Reader has at most 1 corresponding field; set() changes v's element that corresponds to that field (the order is given by TagReader::Feature); note that some Reader's don't have a field, so they don't change anything. Readers that have a corresponding field are either UnboundReader or something derived from BoundReader. BoundReader is for fields that have clearly identifiable limits (track number, year, rating or some static string), while UnboundReader is for fields without such limits (artist, album, track name). Usage: TagWriter has a list of "patterns". For each pattern it creates a FileTagReader, for which init() gets called, filling in field values, which are then displayed. A FileTagReader has a list of trees of Reader instances, and while it processes its init() it calls init() and set() for those Reader's. To build the tree, a pattern is parsed. First of all it is split at the file separator limit; for each segment a top-level SequenceReader gets created, and the segment is further parsed to determine what will be part of the SequenceReader. When assign() is called for a particular file name, it too is split by file separators and each of the top-level SequenceReader tries a match for its corresponding name segment when init() is called. The match may fail or succeed. If it succeeds, set() is then called, to assign values to fields. A failure in one top-level SequenceReader doesn't affect the others. Patterns are strings containing file name separators, static text and these placeholder: %n track number %a artist %t title %b album %y year %g genre %r rating (a lowercase letter) %c composer %i ignored (there's no predefined field that would take this value) For example "%a/%b/%n.-.%t" is a pattern made up of these elements: %a (artist placeholder) / (file name separator) %b (album) / (file name separator) %n (track number) .-. (static text) %t (title) During matching, corresponding file name separators and static texts are identified, and what's left must match the placeholders and give the name of the corresponding fields. By matching "%a/%b/%n.-.%t" to a file named ".../dir1/artist1/album1.(1995)/02.-.track1.mp3" we get: title = track1 track number = 02 album = album1.(1995) artist = artist1 Matching "%a/%b/%n.-.%t" to a file named ".../dir1/artist1/album1.(1995)/02.track1.mp3" we get: album = album1.(1995) artist = artist1 The last segment caused an error, because "02.track1.mp3" doesn't contain ".-." . Now this pattern would give the same results as in the previous case: "%a/%b/%n.%t" To be able to deal with the different naming conventions that are likely to be used for different albums, 2 options are available: 1) Have more instances of TrackTextParser, to accomodate those conventions. 2) Include optional elements in some of those TrackTextParser instances. Optional elements are delimited by '[' and ']'. For example "%a/%b/%n.[-.]%t" matches correctly ".../dir1/artist1/album1 (1995)/02.-.track1.mp3" as well as ".../dir1/artist1/album1 (1995)/02.track1.mp3". That is, if you consider "album1 (1995)" as a proper album name. Probably makes more sense to use "%a/%b (%y)/%n.[-.]%t" instead, which gives: title = track1 track number = 02 album = album1 artist = artist1 year = 1995 If some albums end with the year enclosed in parantheses and some don't have a year in the directory name, this may work for all the cases: "%a/%b[.(%y)]/%n.[-.]%t" An OptionalReader has a single field, which is a SequenceReader. It's not worth the trouble to have the option to include some other fields, even though in many cases the SequenceReader will only contain an element. Objects created for "%a/%b[.(%y)]/%n.[-.]%t" : TrackTextParser SequenceReader "%a" UnboundReader SequenceReader "%b[.(%y)]" UnboundReader OptionalReader SequenceReader ".(%y)" StaticReader ".(" YearReader StaticReader ")" SequenceReader (%n.[-.]%t) TrackNoReader StaticReader "." OptionalReader SequenceReader "-." StaticReader "-." UnboundReader SequenceReader is a lot more complex than the others, because it has all the different Readers that is has to determine recursively if they match or not. So this is how it basically works: First, it sorts the readers in a way that allows them to be processed sequentially (bounded readers should be matched before unbounded ones, but it's not so simple, because a reader may be bound at none, one or both sides). Then it calls init() on all of them, marking some as failed, if needed. A failure in a non-optional reader makes the whole SequenceReader fail. Any gap in the string to be matched makes the whole SequenceReader fail (but remaining substrings at the margins are OK). While the other readers are either bound or unbound, a SequenceReader may be bound at one side and unbound at the other ("%n %t" corresponds to a SequenceReader that's bound at the left and unbound at the right.) Optional readers may be nested. However, more complex patterns may be harder to understand and to get right. Also, there are limitations, as some backtracking would make sense, but it's not currently implemented. //ttt2 implement Consider the case of "[[.].]%t" : for ".tst1.mp3" the title will be ".tst1", while for "..tst1.mp3" it will be "tst1" . This happens because the inner optional reader first takes up the '.' on the right, so the outer optional doesn't have a "." for itself, which makes the outer reader to fail. What should happen is this: the outer optional reader should discard the inner reader and try again without it, in which case it would succeed. However, this looks time consuming and doesn't provide such great benefits: "[.[.]]%t" achieves what "[[.].]%t" tries to do without backtracking and making the second "." optional is what it takes to do the trick. Sure, this doesn't work in all cases, but it seems to be good enough. Some patterns may look OK but are invalid. Aside from mismatched '[' and ']', which should come in pairs, there's this issue with a succesfully parsed pattern: a SequenceReader isn't allowed to have 2 consecutive readers r1 and r2 if r1 is unbound to the right and r2 is unbound to the left, because there's no way to tell where one ends and the other begins. Optional readers are considered both as missing and present. So these are invalid: "%a%b" "%a[%b]" "%a[-]%b" "[%a][%b]" while these are valid "%a-%b" "%a[-%b]" "[%a-]%b" Since "%", "[" and "]" are used as special characters, they can't appear on their own in patterns. To include them in a pattern, they should be preceded by another "%": "%%", "%[" and "%]" */ struct SequenceReader; struct Reader; // gets track info from a full file name or from a generic string, normally a line from a multi-line track listing // if m_bSplitAtPathSep is true, the string passed to assign is broken into independent pieces, matching the independent pieces from m_strPattern, which may fail individually without triggering the failure of the whole; if it's false, the whole strPattern must match the pattern; the decision to make m_bSplitAtPathSep true or false is based on the pattern containing an unescaped path separator (keeping in mind that to include such a separator in a "table line parser" it has to be escaped) class TrackTextParser { std::vector<SequenceReader*> m_vpSeqReaders; std::vector<Reader*> m_vpAllReaders; // all instances of Reader-derived classes, to be easily deleted void construct(const std::string& strPattern); std::string m_strPattern; bool m_bSplitAtPathSep; public: TrackTextParser(const std::string& strPattern); // throws InvalidPattern for invalid pattern ~TrackTextParser(); // parses strFileName, identifying track info details and setting v accordingly; v's size must be TagReader::LIST_END+1, with elements in the order given by TagReader::Feature, while the last one is reserved for "ignored"; v is not erased; if there is no value for a field, the corresponding element doesn't change; void assign(const std::string& s, std::vector<std::string>& v); std::string getPattern() const { return m_strPattern; } bool isFileNameBased() const { return m_bSplitAtPathSep; } struct InvalidPattern { int m_nPos; InvalidPattern(int nPos) : m_nPos(nPos) {} }; }; /* // gets track info from a string, normally a line from a multi-line track listing class TrackTextParser { SequenceReader* m_pSeqReader; std::vector<Reader*> m_vpAllReaders; // all instances of Reader-derived classes, to be easily deleted void construct(const std::string& strPattern); std::string m_strPattern; public: TrackTextParser(const std::string& strPattern); // throws InvalidPattern for invalid pattern ~TrackTextParser(); // parses strTrackInfo, identifying track info details and setting v accordingly; v's size must be TagReader::LIST_END+1, with elements in the order given by TagReader::Feature, while the last one is reserved for "ignored"; v is not erased; if there is no value for a field, the corresponding element doesn't change; void assign(const std::string& strTrackInfo, std::vector<std::string>& v); std::string getPattern() const { return m_strPattern; } struct InvalidPattern { int m_nPos; InvalidPattern(int nPos) : m_nPos(nPos) {} }; }; */ std::string testPattern(const std::string& strPattern); // returns an empty string if the pattern is valid and an error message (including the column) if it's invalid } // namespace SongInfoParser #endif // #ifndef SongInfoParserH �����������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/ExportDlgImpl.cpp�����������������������������������������������������������0000644�0001750�0000144�00000055577�11274233750�016540� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <algorithm> #include <iomanip> #include <QFileDialog> #include <QTextDocument> #include <QTextCodec> #include "ExportDlgImpl.h" #include "Helpers.h" #include "CommonData.h" #include "Widgets.h" #include "StoredSettings.h" #include "DataStream.h" #include "fstream_unicode.h" #include "Id3V2Stream.h" #include "MpegStream.h" #include "ApeStream.h" #include "LyricsStream.h" using namespace std; ExportDlgImpl::ExportDlgImpl(QWidget* pParent) : QDialog(pParent, getDialogWndFlags()), Ui::ExportDlg() { setupUi(this); int nWidth, nHeight; bool bSortByShortNames; string strFile; bool bUseVisible; string strM3uRoot; string strLocale; getCommonData()->m_settings.loadExportSettings(nWidth, nHeight, bSortByShortNames, strFile, bUseVisible, strM3uRoot, strLocale); if (nWidth > 400 && nHeight > 300) { resize(nWidth, nHeight); } else { //defaultResize(*this); } m_pSortByShortNamesCkB->setChecked(bSortByShortNames); m_pFileNameE->setText(toNativeSeparators(convStr(strFile))); (bUseVisible ? m_pVisibleRB : m_pSelectedRB)->setChecked(true); m_pM3uRootE->setText(toNativeSeparators(convStr(strM3uRoot))); { // locale QStringList lNames; set<QString> s; QList<QByteArray> l (QTextCodec::availableCodecs()); for (int i = 0, n = l.size(); i < n; ++i) { s.insert(QTextCodec::codecForName(l[i])->name()); // a codec is known by several names; by doing this we eliminate redundant names and make the list a lot smaller } for (set<QString>::const_iterator it = s.begin(); it != s.end(); ++it) { lNames << *it; } m_pLocaleCbB->addItems(lNames); int n (m_pLocaleCbB->findText(strLocale.c_str())); if (-1 == n) { n = 0; } m_pLocaleCbB->setCurrentIndex(n); } m_pM3uRB->setChecked(true); setFormatBtn(); } ExportDlgImpl::~ExportDlgImpl() { } void ExportDlgImpl::run() { if (QDialog::Accepted != exec()) { return; } getCommonData()->m_settings.saveExportSettings(width(), height(), m_pSortByShortNamesCkB->isChecked(), convStr(fromNativeSeparators(m_pFileNameE->text())), m_pVisibleRB->isChecked(), convStr(fromNativeSeparators(m_pM3uRootE->text())), m_pLocaleCbB->currentText().toUtf8().constData()); } QString ExportDlgImpl::getFileName() { QString qs (fromNativeSeparators(m_pFileNameE->text())); if (qs.isEmpty()) { QMessageBox::critical(this, "Error", "The file name cannot be empty. Exiting ..."); return ""; } if (QFileInfo(qs).isAbsolute()) { return qs; } if (!m_pM3uRB->isChecked()) { QMessageBox::critical(this, "Error", "You need to specify an absolute file name when exporting to formats other than .m3u. Exiting ..."); return ""; } QString qstrRoot (fromNativeSeparators(m_pM3uRootE->text())); if (qstrRoot.isEmpty()) { QMessageBox::critical(this, "Error", "The root cannot be empty if the file name is relative. Exiting ..."); return ""; } if (!QFileInfo(qstrRoot).isAbsolute()) { QMessageBox::critical(this, "Error", "The root must be an absolute directory name. Exiting ..."); return ""; } if (!qstrRoot.endsWith(getPathSep())) { qstrRoot += getPathSep(); } if (!QFileInfo(qstrRoot).isDir()) { QMessageBox::critical(this, "Error", "The root doesn't exist. Exiting ..."); return ""; } return qstrRoot + qs; } void ExportDlgImpl::on_m_pExportB_clicked() { QString qs (getFileName()); if (qs.isEmpty()) { return; } if (QFileInfo(qs).isFile()) { if (0 != HtmlMsg::msg(this, 1, 1, 0, 0, "Warning", "A file called \"" + toNativeSeparators(qs) + "\" already exists. Do you want to overwrite it?", 600, 200, "Overwrite", "Cancel")) { return; } } bool b (false); { CursorOverrider crs; string s (convStr(qs)); if (m_pTextRB->isChecked()) { b = exportAsText(s); } else if (m_pM3uRB->isChecked()) { b = exportAsM3u(s); } else if (m_pXmlRB->isChecked()) { b = exportAsXml(s); } else { CB_ASSERT(false); } } if (b) { HtmlMsg::msg(this, 0, 0, 0, 0, "Info", "Successfully created file \"" + toNativeSeparators(qs) + "\"", 600, 200, "OK"); } else { HtmlMsg::msg(this, 0, 0, 0, 0, "Error", "There was an error writing to the file \"" + toNativeSeparators(qs) + "\"", 600, 200, "OK"); } } void ExportDlgImpl::on_m_pChooseFileB_clicked() { QString qstrDir (QFileInfo(fromNativeSeparators(m_pFileNameE->text())).path()); QFileDialog dlg (this, "Choose destination file", qstrDir, "XML files (*.xml);;Text files (*.txt);;M3U files (*.m3u)"); /*QStringList filters; filters << "Text files (*.txt)" << "M3U files (*.m3u)"; dlg.setFilters(filters);*/ dlg.setFileMode(QFileDialog::AnyFile); if (QDialog::Accepted != dlg.exec()) { return; } QStringList fileNames (dlg.selectedFiles()); if (1 != fileNames.size()) { return; } QString s (fileNames.first()); QString flt (dlg.selectedFilter()); if (flt.endsWith("xml)") && !s.endsWith(".xml")) { s += ".xml"; } else if (flt.endsWith("txt)") && !s.endsWith(".txt")) { s += ".txt"; } else if (flt.endsWith("m3u)") && !s.endsWith(".m3u")) { s += ".m3u"; } m_pFileNameE->setText(toNativeSeparators(s)); setFormatBtn(); } void ExportDlgImpl::setFormatBtn() { QString qs (m_pFileNameE->text()); if (qs.endsWith(".xml")) { m_pXmlRB->setChecked(true); } else if (qs.endsWith(".txt")) { m_pTextRB->setChecked(true); } else if (qs.endsWith(".m3u")) { m_pM3uRB->setChecked(true); } } void ExportDlgImpl::setExt(const char* szExt) { CB_ASSERT (3 == strlen(szExt)); QString s (m_pFileNameE->text()); int n (s.size() - 4); if (n > 0 && '.' == s[n]) { QString s1 (s); s1.remove(n + 1, 3); s1 += szExt; if (s1 != s) { m_pFileNameE->setText(s1); } } } /*$SPECIALIZATION$*/ namespace { struct CmpMp3HandlerByShortNameAndSize { bool operator()(const Mp3Handler* p1, const Mp3Handler* p2) { if (p1->getShortName() < p2->getShortName()) { return true; } if (p2->getShortName() < p1->getShortName()) { return false; } if (p1->getSize() < p2->getSize()) { return true; } if (p2->getSize() < p1->getSize()) { return false; } return p1->getName() < p2->getName(); } }; } void ExportDlgImpl::getHandlers(vector<const Mp3Handler*>& v) { v.clear(); const deque<const Mp3Handler*>& vpHndl (m_pVisibleRB->isChecked() ? getCommonData()->getViewHandlers() : getCommonData()->getSelHandlers()); v.insert(v.end(), vpHndl.begin(), vpHndl.end()); if (m_pSortByShortNamesCkB->isChecked()) { sort(v.begin(), v.end(), CmpMp3HandlerByShortNameAndSize()); } } bool ExportDlgImpl::exportAsText(const string& strFileName) { vector<const Mp3Handler*> v; getHandlers(v); ofstream_utf8 out (strFileName.c_str()); const char* aSeverity = "EWST"; for (int i = 0, n = cSize(v); i < n; ++i) { const Mp3Handler* p (v[i]); out << toNativeSeparators(p->getName()) << " "; out << p->getSize() << endl; const vector<DataStream*>& vpStreams (p->getStreams()); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); out << " " << hex << p->getPos() << "-" << (p->getPos() + (p->getSize() - 1)) << dec << " (" << p->getSize() << ") " << p->getDisplayName(); const string& s (p->getInfo()); if (!s.empty()) { out << ": " << s; } out << endl; } const NoteColl& notes (p->getNotes()); out << " --------------------------------------------\n"; vector<const Note*> vpNotes (notes.getList().begin(), notes.getList().end()); sort(vpNotes.begin(), vpNotes.end(), CmpNotePtrByPosAndId()); for (int i = 0, n = cSize(vpNotes); i < n; ++i) { const Note* p (vpNotes[i]); if (getCommonData()->m_bUseAllNotes || getCommonData()->findPos(p) >= 0) // !!! "ignored" notes shouldn't be exported unless UseAllNotes is checked, so there is consistency between what is shown on the screen and what is saved { out << " " << aSeverity[p->getSeverity()] << " "; const string& q (p->getPosHex()); if (!q.empty()) { out << q << " "; } const string& s (p->getDetail()); if (s.empty()) // ttt2 perhaps show descr anyway { out << p->getDescription(); } else { out << s; } out << endl; } } out << "\n\n"; } return out; } bool ExportDlgImpl::exportAsM3u(const std::string& strFileName) { QTextCodec* pCodec (QTextCodec::codecForName(m_pLocaleCbB->currentText().toUtf8())); CB_ASSERT (0 != pCodec); vector<const Mp3Handler*> v; getHandlers(v); string strRoot (convStr(fromNativeSeparators(m_pM3uRootE->text()))); if (!strRoot.empty() && !endsWith(strRoot, getPathSepAsStr())) { strRoot += getPathSepAsStr(); } int nRootSize (cSize(strRoot)); ofstream_utf8 out (strFileName.c_str()); for (int i = 0, n = cSize(v); i < n; ++i) { const Mp3Handler* p (v[i]); string s (toNativeSeparators(p->getName())); if (nRootSize > 0) { if (beginsWith(s, strRoot)) { s.erase(0, nRootSize); } else { CursorOverrider crs (Qt::ArrowCursor); QMessageBox::critical(this, "Error", "The file named \"" + convStr(s) + "\" isn't inside the specified root. Exiting ..."); return false; } } QString qs (convStr(s)); if (!pCodec->canEncode(qs)) { CursorOverrider crs (Qt::ArrowCursor); QMessageBox::critical(this, "Error", "The file named \"" + qs + "\" cannot be encoded in the selected locale. Exiting ..."); return false; } out << pCodec->fromUnicode(qs).constData() << endl; } return out; } namespace { string escapeXml(const string& s) { QString qs (Qt::escape(convStr(s))); qs.replace(QString("\""), """); qs.replace(QString("#"), "#"); return convStr(qs); } void printDataStream(ostream& out, DataStream* p) { out << " type=\"" << p->getDisplayName() << "\" begin=\"0x" << hex << p->getPos() << "\" end=\"0x" << (p->getPos() + (p->getSize() - 1)) << "\" size=\"" << dec << p->getSize() << "\""; } void printTagReader(ostream& out, TagReader* p) { bool b; string s; if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::TITLE)) { s = p->getTitle(&b); if (b) { out << " title=\"" << escapeXml(s) << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::ARTIST)) { s = p->getArtist(&b); if (b) { out << " artist=\"" << escapeXml(s) << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::TRACK_NUMBER)) { s = p->getTrackNumber(&b); if (b) { out << " trackNo=\"" << escapeXml(s) << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::TIME)) { p->getTime(&b); if (b) { out << " time=\"" << p->getValue(TagReader::TIME) << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::GENRE)) { s = p->getGenre(&b); if (b) { out << " genre=\"" << escapeXml(s) << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::IMAGE)) { s = p->getImageData(&b); if (b) { out << " image=\"" << escapeXml(s) << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::ALBUM)) { s = p->getAlbumName(&b); if (b) { out << " album=\"" << escapeXml(s) << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::RATING)) { double d (p->getRating(&b)); if (b) { out << " rating=\"" << setprecision(1) << d << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::COMPOSER)) { s = p->getComposer(&b); if (b) { out << " composer=\"" << escapeXml(s) << "\""; } } if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::VARIOUS_ARTISTS)) { p->getVariousArtists(&b); if (b) { out << " variousArtists=\"" << p->getValue(TagReader::VARIOUS_ARTISTS) << "\""; } } } enum { DONT_PRINT_BPS, PRINT_BPS }; void printMpegInfo(ostream& out, const MpegFrame& frm, bool bPrintBps) { out << " version=\"" << frm.getSzVersion() << "\"" << " layer=\"" << frm.getSzLayer() << "\"" << " channelMode=\"" << frm.getSzChannelMode() << "\"" << " frequency=\"" << frm.getFrequency() << "\""; if (bPrintBps) { out << " bps=\"" << frm.getBitrate() << "\""; } out << " crc=\"" << boolAsYesNo(frm.getCrcUsage()) << "\""; } } // namespace bool ExportDlgImpl::exportAsXml(const std::string& strFileName) { vector<const Mp3Handler*> v; getHandlers(v); ofstream_utf8 out (strFileName.c_str()); out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<files>\n"; /*{ string x; for (int i = 32; i < 128; ++i) x += char(i); out << "<abc x=\"" << escapeXml(x) << "\">\n" << escapeXml(x) << "\n</abc>\n"; }*/ const char* aszSeverity[] = { "error", "warning", "support", "trace" }; for (int i = 0, n = cSize(v); i < n; ++i) { const Mp3Handler* p (v[i]); out << " <file name=\"" << escapeXml(toNativeSeparators(p->getName())) << "\" size=\"" << p->getSize() << "\">\n"; out << " <streams>\n"; const vector<DataStream*>& vpStreams (p->getStreams()); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (0 != dynamic_cast<Id3V2StreamBase*>(p)) { Id3V2StreamBase* p1 (dynamic_cast<Id3V2StreamBase*>(p)); out << " <id3V2Stream"; printDataStream(out, p1); printTagReader(out, p1); out << ">\n"; vector<Id3V2Frame*> vpFrames (p1->getFrames()); for (int i = 0, n = cSize(vpFrames); i < n; ++i) { Id3V2Frame* p (vpFrames[i]); if (Id3V2Frame::NO_APIC != p->m_eApicStatus) { out << " <pictureFrame name=\"" << p->getReadableName() << "\" size=\"" << p->m_nDiskDataSize << "\" width=\"" << p->m_nWidth << "\" height=\"" << p->m_nHeight << "\" type=\"" << p->getImageType() << "\" status=\"" << p->getImageStatus() << "\" compr=\"" << ImageInfo::getComprStr(p->m_eCompr) << "\"/>\n"; } else if ('T' == p->m_szName[0]) // ttt2 not quite right for TXXX { out << " <textFrame name=\"" << p->getReadableName() << "\" size=\"" << p->m_nDiskDataSize << "\">\n"; out << " " << escapeXml(p->getUtf8String()) << "\n"; out << " </textFrame>\n"; } else if (0 == strcmp(KnownFrames::LBL_RATING(), p->m_szName)) { out << " <ratingFrame name=\"" << p->getReadableName() << "\" size=\"" << p->m_nDiskDataSize << "\" normalizedValue=\"" << setprecision(1) << p->getRating() << "\"/>\n"; } else { out << " <binaryFrame name=\"" << p->getReadableName() << "\" size=\"" << p->m_nDiskDataSize << "\"/>\n"; } } out << " </id3V2Stream>\n"; } else if (0 != dynamic_cast<Id3V1Stream*>(p)) { Id3V1Stream* p1 (dynamic_cast<Id3V1Stream*>(p)); out << " <id3V1Stream version=\"" << p1->getVersion() << "\""; printDataStream(out, p); printTagReader(out, p1); out << "/>\n"; } else if (0 != dynamic_cast<MpegStream*>(p)) { MpegStream* p1 (dynamic_cast<MpegStream*>(p)); out << " <mpegAudioStream"; printDataStream(out, p); out << " duration=\"" << p1->getDuration() << "\""; printMpegInfo(out, p1->getFirstFrame(), DONT_PRINT_BPS); out << " bitrate=\"" << p1->getBitrate() << "\"" << " vbr=\"" << boolAsYesNo(p1->isVbr()) << "\"" << " frameCount=\"" << p1->getFrameCount() << "\""; // << " bitrate=\"" << p1->getBitrate() << "\"" (m_bRemoveLastFrameCalled ? " removed; it was" : "") << " located at 0x" << hex << m_posLastFrame out << "/>\n"; } else if (0 != dynamic_cast<XingStream*>(p)) { XingStream* p1 (dynamic_cast<XingStream*>(p)); out << " <xingStream"; printDataStream(out, p); printMpegInfo(out, p1->getFirstFrame(), PRINT_BPS); out << p1->getInfoForXml() << "/>\n"; } else if (0 != dynamic_cast<LameStream*>(p)) { LameStream* p1 (dynamic_cast<LameStream*>(p)); out << " <lameStream"; printDataStream(out, p); printMpegInfo(out, p1->getFirstFrame(), PRINT_BPS); out << p1->getInfoForXml() << "/>\n"; } else if (0 != dynamic_cast<VbriStream*>(p)) { VbriStream* p1 (dynamic_cast<VbriStream*>(p)); out << " <vbriStream"; printDataStream(out, p); printMpegInfo(out, p1->getFirstFrame(), PRINT_BPS); out << "/>\n"; } else if (0 != dynamic_cast<TruncatedMpegDataStream*>(p)) { TruncatedMpegDataStream* p1 (dynamic_cast<TruncatedMpegDataStream*>(p)); out << " <truncatedMpegAudioStream"; printDataStream(out, p); out << decodeMpegFrameAsXml(p1->getBegin(), 0); out << "/>\n"; } else if (0 != dynamic_cast<ApeStream*>(p)) { ApeStream* p1 (dynamic_cast<ApeStream*>(p)); out << " <apeStream"; printDataStream(out, p); printTagReader(out, p1); out << "/>\n"; } else if (0 != dynamic_cast<LyricsStream*>(p)) { LyricsStream* p1 (dynamic_cast<LyricsStream*>(p)); out << " <lyricsStream"; printDataStream(out, p); printTagReader(out, p1); out << "/>\n"; } else { out << " <stream"; printDataStream(out, p); out << ">\n"; const string& s (p->getInfo()); if (!s.empty()) { out << " <info>\n"; out << " " << escapeXml(s) << "\n"; out << " </info>\n"; } out << " </stream>\n"; } } out << " </streams>\n"; const NoteColl& notes (p->getNotes()); out << " <notes>\n"; vector<const Note*> vpNotes (notes.getList().begin(), notes.getList().end()); sort(vpNotes.begin(), vpNotes.end(), CmpNotePtrByPosAndId()); for (int i = 0, n = cSize(vpNotes); i < n; ++i) { const Note* p (vpNotes[i]); if (getCommonData()->m_bUseAllNotes || getCommonData()->findPos(p) >= 0) // !!! "ignored" notes shouldn't be exported unless UseAllNotes is checked, so there is consistency between what is shown on the screen and what is saved { out << " <note type=\"" << aszSeverity[p->getSeverity()] << "\""; const string& q (p->getPosHex()); if (!q.empty()) { out << " pos=\"" << q << "\""; } out << " description=\"" << escapeXml(p->getDescription()) << "\""; const string& s (p->getDetail()); if (!s.empty()) { out << " detail=\"" << escapeXml(s) << "\""; } out << "/>\n"; } } out << " </notes>\n"; out << " </file>\n"; } out << "</files>\n"; return out; } ���������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/AlbumInfoDownloaderDlgImpl.cpp����������������������������������������������0000644�0001750�0000144�00000106073�11500244755�021135� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <memory> #include <zlib.h> #ifndef WIN32 #include <sys/time.h> #else #include <ctime> #endif #include <QHttp> #include <QMessageBox> #include <QXmlSimpleReader> #include <QBuffer> #include <QPainter> #include <QScrollBar> #include <QHeaderView> #include <QTime> #include "AlbumInfoDownloaderDlgImpl.h" #include "Helpers.h" #include "ColumnResizer.h" #include "fstream_unicode.h" using namespace std; using namespace pearl; // /*extern*/ int CELL_WIDTH (22); extern int CELL_HEIGHT; AlbumInfoDownloaderDlgImpl::AlbumInfoDownloaderDlgImpl(QWidget* pParent, SessionSettings& settings, bool bSaveResults) : QDialog(pParent, getDialogWndFlags()), Ui::AlbumInfoDownloaderDlg(), m_bSaveResults(bSaveResults), m_nLastCount(0), m_nLastTime(0), m_settings(settings) { setupUi(this); m_pQHttp = new QHttp (this); connect(m_pQHttp, SIGNAL(requestFinished(int, bool)), this, SLOT(onRequestFinished(int, bool))); m_pTrackListG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pTrackListG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } AlbumInfoDownloaderDlgImpl::~AlbumInfoDownloaderDlgImpl() { } bool AlbumInfoDownloaderDlgImpl::getInfo(const std::string& strArtist, const std::string& strAlbum, int nTrackCount, AlbumInfo*& pAlbumInfo, ImageInfo*& pImageInfo) { LAST_STEP("AlbumInfoDownloaderDlgImpl::getInfo"); m_nExpectedTracks = nTrackCount; pAlbumInfo = 0; pImageInfo = 0; if (initSearch(strArtist, strAlbum)) { search(); } bool bRes (QDialog::Accepted == exec()); if (bRes) { saveSize(); CB_ASSERT (0 != getAlbumCount()); if (!m_bSaveImageOnly) { pAlbumInfo = new AlbumInfo(); album(m_nCrtAlbum).copyTo(*pAlbumInfo); //pAlbumInfo->m_strReleased = convStr(m_pRealeasedE->text()); //ttt2 maybe allow users to overwrite fields in edit boxes, esp. genre; however, most of the cases it's almost as easy to make any changes in the tag editor (well, there's an F2 and then "copy form first"); there are several issues in implementing this: 1) going to prev/next album; 2) artist name gets copied to each track; 3) consistency: if the edit boxes are editable why not the table? so, better without if (m_pVolumeCbB->isEnabled() && m_pVolumeCbB->currentIndex() != m_pVolumeCbB->count() - 1) { vector<TrackInfo> vTracks; string s (convStr(m_pVolumeCbB->itemText(m_pVolumeCbB->currentIndex()))); int k (cSize(s)); for (int i = 0, n = cSize(pAlbumInfo->m_vTracks); i < n; ++i) { if (beginsWith(pAlbumInfo->m_vTracks[i].m_strPos, s)) { vTracks.push_back(pAlbumInfo->m_vTracks[i]); vTracks.back().m_strPos.erase(0, k); } } vTracks.swap(pAlbumInfo->m_vTracks); } } if (m_nCrtImage >= 0) { pImageInfo = new ImageInfo(*album(m_nCrtAlbum).m_vpImages[m_nCrtImage]); } } return bRes; } // clears pending HTTP requests, m_eNavigDir and m_eWaiting; restores the cursor if needed; /*virtual*/ void AlbumInfoDownloaderDlgImpl::resetNavigation() { LAST_STEP("AlbumInfoDownloaderDlgImpl::resetNavigation"); m_pQHttp->clearPendingRequests(); setWaiting(NOTHING); m_eNavigDir = NONE; } string AlbumInfoDownloaderDlgImpl::replaceSymbols(string s) // replaces everything besides letters and digits with getReplacementChar() { LAST_STEP("AlbumInfoDownloaderDlgImpl::replaceSymbols"); char c (getReplacementChar()); for (int i = 0; i < cSize(s); ++i) { if ((unsigned char)(s[i]) < 128 && '\'' != s[i] && !isalnum(s[i])) { s[i] = c; } } return s; } /*static*/ const char* AlbumInfoDownloaderDlgImpl::NOT_FOUND_AT_AMAZON = "not found at amazon.com"; void AlbumInfoDownloaderDlgImpl::search() { LAST_STEP("AlbumInfoDownloaderDlgImpl::search"); m_pResArtistE->setText(""); m_pResAlbumE->setText(""); m_pDownloadsM->setText(""); m_pAlbumNotesM->setText(""); m_pFormatE->setText(""); m_pRealeasedE->setText(""); m_pResultNoL->setText(""); updateTrackList(); m_pVolumeCbB->clear(); m_pImageL->setPixmap(0); m_pImageL->setText(""); m_pImgSizeL->setText("\n"); m_pViewAtAmazonL->setText(NOT_FOUND_AT_AMAZON); m_strQuery = escapeHttp(createQuery()); // e.g. http://www.discogs.com/search?type=all&q=beatles&f=xml&api_key=f51e9c8f6c, without page number; to be used by loadNextPage(); m_nTotalPages = 1; m_nLastLoadedPage = -1; m_nCrtAlbum = -1; m_nCrtImage = -1; resetNavigation(); //m_eNavigDir = NEXT; m_eNavigDir = NEXT; m_bNavigateByAlbum = false; addNote("searching ..."); m_pGenreE->setText(""); //next(); //loadNextPage(); retryNavigation(); } void AlbumInfoDownloaderDlgImpl::on_m_pPrevB_clicked() { LAST_STEP("AlbumInfoDownloaderDlgImpl::on_m_pPrevB_clicked"); if (0 == getAlbumCount() || NOTHING != m_eWaiting) { return; } m_bNavigateByAlbum = false; m_eNavigDir = PREV; retryNavigation(); } void AlbumInfoDownloaderDlgImpl::on_m_pNextB_clicked() { LAST_STEP("AlbumInfoDownloaderDlgImpl::on_m_pNextB_clicked"); if (0 == getAlbumCount() || NOTHING != m_eWaiting) { return; } m_bNavigateByAlbum = false; m_eNavigDir = NEXT; retryNavigation(); } void AlbumInfoDownloaderDlgImpl::on_m_pPrevAlbumB_clicked() { LAST_STEP("AlbumInfoDownloaderDlgImpl::on_m_pPrevAlbumB_clicked"); if (0 == getAlbumCount() || NOTHING != m_eWaiting) { return; } m_bNavigateByAlbum = true; m_eNavigDir = PREV; retryNavigation(); } void AlbumInfoDownloaderDlgImpl::on_m_pNextAlbumB_clicked() { LAST_STEP("AlbumInfoDownloaderDlgImpl::on_m_pNextAlbumB_clicked"); if (0 == getAlbumCount() || NOTHING != m_eWaiting) { return; } m_bNavigateByAlbum = true; m_eNavigDir = NEXT; retryNavigation(); } void AlbumInfoDownloaderDlgImpl::on_m_pSaveAllB_clicked() { LAST_STEP("AlbumInfoDownloaderDlgImpl::on_m_pSaveAllB_clicked"); if (NOTHING != m_eWaiting) { QMessageBox::critical(this, "Error", "You cannot save the results now, because a request is still pending"); return; } if (0 == getAlbumCount()) { QMessageBox::critical(this, "Error", "You cannot save the results now, because no album is loaded"); return; } int nCnt (0); CB_ASSERT (m_nCrtAlbum >= 0 && m_nCrtAlbum < getAlbumCount()); const WebAlbumInfoBase& albumInfo (album(m_nCrtAlbum)); if (m_pVolumeCbB->isEnabled() && m_pVolumeCbB->currentIndex() != m_pVolumeCbB->count() - 1) { string s (convStr(m_pVolumeCbB->itemText(m_pVolumeCbB->currentIndex()))); for (int i = 0, n = cSize(albumInfo.m_vTracks); i < n; ++i) { if (beginsWith(albumInfo.m_vTracks[i].m_strPos, s)) { ++nCnt; } } } else { nCnt = cSize(albumInfo.m_vTracks); } if (nCnt != m_nExpectedTracks) { QString s; const char* szVolMsg ( m_pVolumeCbB->isEnabled() && ( (nCnt > m_nExpectedTracks && m_pVolumeCbB->currentIndex() == m_pVolumeCbB->count() - 1) || (nCnt < m_nExpectedTracks && m_pVolumeCbB->currentIndex() != m_pVolumeCbB->count() - 1) ) ? "You may want to use a different volume selection on this multi-volume release.\n\n" : ""); if (nCnt > m_nExpectedTracks) { s = QString("A number of %1 tracks were expected, but your selection contains %2. Additional tracks will be discarded.\n\n%3Save anyway?").arg(m_nExpectedTracks).arg(nCnt).arg(szVolMsg); } else { s = QString("A number of %1 tracks were expected, but your selection only contains %2. Remaining tracks will get null values.\n\n%3Save anyway?").arg(m_nExpectedTracks).arg(nCnt).arg(szVolMsg); } QMessageBox::StandardButton eRes (QMessageBox::question(this, "Count inconsistency", s, QMessageBox::Cancel | QMessageBox::Save)); if (QMessageBox::Save != eRes) { return; } } m_bSaveImageOnly = false; accept(); } void AlbumInfoDownloaderDlgImpl::on_m_pSaveImageB_clicked() { LAST_STEP("AlbumInfoDownloaderDlgImpl::on_m_pSaveImageB_clicked"); if (NOTHING != m_eWaiting) { QMessageBox::critical(this, "Error", "You cannot save the results now, because a request is still pending"); return; } if (0 == getAlbumCount() || -1 == m_nCrtImage) { QMessageBox::critical(this, "Error", "You cannot save any image now, because there is no image loaded"); return; } // ttt2 perhaps shouldn't save an "error" image m_bSaveImageOnly = true; accept(); //ttt2 perhaps allow multiple images to be saved, by adding a button to "add to save list"; see https://sourceforge.net/projects/mp3diags/forums/forum/947207/topic/4006484 } void AlbumInfoDownloaderDlgImpl::on_m_pCancelB_clicked() { LAST_STEP("AlbumInfoDownloaderDlgImpl::on_m_pCancelB_clicked"); reject(); } //========================================================================================================================== //========================================================================================================================== //========================================================================================================================== // what may happen: // 1) there is a "next" element and it is in memory; then the GUI is updated and that is all (this calls resetNavigation() ); // 2) there is a "next" element but it is not loaded; album info or picture are missing, or there's another page with search results that wasn't loaded yet; then a request is made for what's missing to be downloaded, and the state is updated to reflect that; when the request completes, retryNavigation() will get called, which will call again next() // 3) there is no "next"; nothing happens in this case; // // if there's nothing to wait for, retryNavigation() calls resetNavigation() after next() exits; (retryNavigation() is the only function that is supposed to call next() ); // // if no new HTTP request is sent, either setWaiting(NOTHING) or reloadGui() should be called, to leave m_eWaiting in a consistent state; // void AlbumInfoDownloaderDlgImpl::next() { LAST_STEP("AlbumInfoDownloaderDlgImpl::next"); //if (NONE != m_eNavigDir) { return; } CB_ASSERT (NEXT == m_eNavigDir); int nNextAlbum (m_nCrtAlbum); int nNextImage (m_nCrtImage); for (;;) { if (nNextAlbum >= 0 && nNextImage < cSize(album(nNextAlbum).m_vstrImageNames) - 1 && (-1 == nNextImage || !m_bNavigateByAlbum)) { ++nNextImage; } else if (nNextAlbum + 1 < getAlbumCount()) { // m_vAlbums contains a "next" album, which may or may not be loaded if (album(nNextAlbum + 1).m_strTitle.empty()) { requestAlbum(nNextAlbum + 1); return; } else { ++nNextAlbum; nNextImage = album(nNextAlbum).m_vstrImageNames.empty() ? -1 : 0; } } else { // nothing left in m_vAlbums if (m_nLastLoadedPage == m_nTotalPages - 1) { // !!! there's no "next" at all; just exit; setWaiting(NOTHING); } else { loadNextPage(); } return; } // if it got here, we have a loaded album (pictures might be missing, though) if ((m_pImageFltCkB->isChecked() && album(nNextAlbum).m_vpImages.empty()) || (m_pCdFltCkB->isChecked() && string::npos == album(nNextAlbum).m_strFormat.find("CD")) || (m_pTrackCntFltCkB->isChecked() && m_nExpectedTracks != cSize(album(nNextAlbum).m_vTracks))) // ttt2 MusicBrainz could perform better here, because it knows how many tracks are in an album without actually loading it; ttt2 redo the whole next() / prev() thing in a more logical way; perhaps separate next() from nextAlbum(); { continue; } if (-1 != nNextImage && 0 == album(nNextAlbum).m_vpImages[nNextImage]) { requestImage(nNextAlbum, nNextImage); return; } m_nCrtAlbum = nNextAlbum; m_nCrtImage = nNextImage; reloadGui(); return; } } //ttt2 perhaps filter by durations (but see first how it works without it) // like next(), but here there's no need to load result pages; another difference is that when m_bNavigateByAlbum is set and we are at the first album and some other picture than the first, it goes to the first picture; in the similar case, next doesn't do anything (going to the last picture doesn't feel right) void AlbumInfoDownloaderDlgImpl::previous() { LAST_STEP("AlbumInfoDownloaderDlgImpl::previous"); CB_ASSERT (PREV == m_eNavigDir); //if (NONE != m_eNavigDir) { return; } int nPrevAlbum (m_nCrtAlbum); int nPrevImage (m_nCrtImage); for (;;) { if (nPrevImage > 0 && !m_bNavigateByAlbum) { --nPrevImage; } else if (nPrevAlbum > 0) { // m_vAlbums contains a "prev" album, which is loaded CB_ASSERT (!album(nPrevAlbum - 1).m_strTitle.empty()); --nPrevAlbum; int nImgCnt (cSize(album(nPrevAlbum).m_vstrImageNames)); nPrevImage = (m_bNavigateByAlbum && nImgCnt > 0) ? 0 : nImgCnt - 1; // !!! it's OK if images don't exist for that album } else { // nothing left in m_vAlbums if (m_bNavigateByAlbum && nPrevImage > 0) { m_nCrtAlbum = 0; m_nCrtImage = 0; reloadGui(); } else { setWaiting(NOTHING); } return; } // if it got here, we have a loaded album (pictures might be missing, though) if ((m_pImageFltCkB->isChecked() && album(nPrevAlbum).m_vpImages.empty()) || (m_pCdFltCkB->isChecked() && string::npos == album(nPrevAlbum).m_strFormat.find("CD")) || // Discogs has one format, but MusicBrainz may have several, so find() is used instead of "==" (m_pTrackCntFltCkB->isChecked() && m_nExpectedTracks != cSize(album(nPrevAlbum).m_vTracks))) { continue; } if (-1 != nPrevImage && 0 == album(nPrevAlbum).m_vpImages[nPrevImage]) { requestImage(nPrevAlbum, nPrevImage); return; } m_nCrtAlbum = nPrevAlbum; m_nCrtImage = nPrevImage; reloadGui(); return; } } void AlbumInfoDownloaderDlgImpl::setImageType(const string& strName) { LAST_STEP("AlbumInfoDownloaderDlgImpl::setImageType"); m_eLoadingImageCompr = ImageInfo::INVALID; string::size_type m (strName.rfind('.')); if (string::npos != m) { string s; ++m; for (; m < strName.size(); ++m) { s += tolower(strName[m]); } if (s == "jpg" || s == "jpeg") { m_eLoadingImageCompr = ImageInfo::JPG; } else if (s == "png") { m_eLoadingImageCompr = ImageInfo::PNG; } } } void AlbumInfoDownloaderDlgImpl::onRequestFinished(int /*nId*/, bool bError) { LAST_STEP("AlbumInfoDownloaderDlgImpl::onRequestFinished"); //cout << "received ID = " << nId << endl; //if (1 == nId) { return; } // some automatically generated request, which should be ignored if (bError) { addNote("request error"); resetNavigation(); return; } QHttp* pQHttp (getWaitingHttp()); qint64 nAv (pQHttp->bytesAvailable()); if (0 == nAv) { //addNote("received empty response"); //cout << "empty request returned\n"; //m_eState = NORMAL; // !!! DON'T set m_eWaiting to NOTHING; empty responses come for no identifiable requests and they should be just ignored return; } CB_ASSERT (NOTHING != m_eWaiting); { QString qstrMsg (QString("received %1 bytes").arg(nAv)); addNote(qstrMsg.toLatin1().constData()); } QString qstrXml; QByteArray b (pQHttp->readAll()); CB_ASSERT (b.size() == nAv); if (nAv < 10) { // too short addNote("received very short response; aborting request ..."); resetNavigation(); return; } if (IMAGE == m_eWaiting) { QString qstrInfo; QImage img; QByteArray comprImg (b); ImageInfo::Compr eOrigCompr (m_eLoadingImageCompr); if (img.loadFromData(b)) //ttt2 not sure what happens for huge images; { qstrInfo = QString("Original: %1kB, %2x%3").arg(nAv/1024).arg(img.width()).arg(img.height()); //cout << "image size " << img.width() << "x" << img.height() << endl; int nWidth (img.width()), nHeight (img.height()); if (nAv > ImageInfo::MAX_IMAGE_SIZE || m_eLoadingImageCompr == ImageInfo::INVALID) { QImage scaledImg; ImageInfo::compress(img, scaledImg, comprImg); nWidth = scaledImg.width(); nHeight = scaledImg.height(); m_eLoadingImageCompr = ImageInfo::JPG; //cout << "scaled image size " << img.width() << "x" << img.height() << endl; qstrInfo += QString("\nRecompressed to: %1kB, %2x%3").arg(comprImg.size()/1024).arg(img.width()).arg(img.height()); } else { qstrInfo += "\nNot recompressed"; } onImageLoaded(comprImg, nWidth, nHeight, qstrInfo); } else { QMessageBox::critical(this, "Error", "Failed to load the image"); const int SIZE (150); QImage errImg (SIZE, SIZE, QImage::Format_ARGB32); QPainter pntr (&errImg); pntr.fillRect(0, 0, SIZE, SIZE, QColor(255, 128, 128)); pntr.drawRect(0, 0, SIZE - 1, SIZE - 1); pntr.drawText(QRectF(0, 0, SIZE, SIZE), Qt::AlignCenter, "Error"); qstrInfo = "Error loading image\n"; comprImg.clear(); QBuffer bfr (&comprImg); errImg.save(&bfr, "png"); m_eLoadingImageCompr = ImageInfo::PNG; onImageLoaded(comprImg, SIZE, SIZE, qstrInfo); } if (m_bSaveResults) { saveDownloadedData(b.constData(), b.size(), (ImageInfo::JPG == eOrigCompr ? "jpg" : (ImageInfo::PNG == eOrigCompr ? "png" : "unkn"))); } return; } if (0x1f == (unsigned char)b[0] && 0x8b == (unsigned char)b[1]) { // gzip z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = 0; strm.next_in = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(b.constData())); strm.avail_in = nAv; vector<char> v (nAv); //int nRes (inflateInit(&strm)); int nRes (inflateInit2(&strm, 16 + 15)); // !!! see libz.h for details; "32" makes this able to handle both gzip and zlib, by auto-detecting the format; 16 is used to force gzip if (Z_OK != nRes) { addNote("init error"); goto e2; } strm.next_out = reinterpret_cast<unsigned char*>(&v[0]); strm.avail_out = v.size(); //cout << (void*)strm.next_in << " " << strm.avail_in << " " << (void*)strm.next_out << " " << strm.avail_out << endl; for (;;) { nRes = inflate(&strm, Z_SYNC_FLUSH); // Z_FINISH //cout << (void*)strm.next_in << " " << strm.avail_in << " " << (void*)strm.next_out << " " << strm.avail_out << endl; if (Z_STREAM_END == nRes) { break; } if (Z_OK == nRes) { // extend the buffer v.resize(v.size() + 128); strm.next_out = reinterpret_cast<unsigned char*>(&v[v.size() - 128]); strm.avail_out = 128; continue; } addNote("unexpected result"); goto e2; } { int nUncomprSize (reinterpret_cast<char*>(strm.next_out) - &v[0]); v.resize(nUncomprSize + 1); v[nUncomprSize] = 0; qstrXml = &v[0]; } e2: inflateEnd(&strm); } else { // it's not gzip, so perhaps it is ASCII; //ttt2 check that it's ASCII qstrXml = b; } if (qstrXml.isEmpty()) { addNote("empty string received"); } else { if (m_bSaveResults) { QByteArray b1 (qstrXml.toUtf8()); saveDownloadedData(b1.constData(), b1.size(), "xml"); } } switch (m_eWaiting) { case ALBUM: onAlbumLoaded(qstrXml); break; case SEARCH: onSearchLoaded(qstrXml); break; default: CB_ASSERT (false); } } string AlbumInfoDownloaderDlgImpl::getTempName() // time-based, with no extension; doesn't check for existing names, but uses a counter, so files shouldn't get removed (except during daylight saving time changes) { LAST_STEP("AlbumInfoDownloaderDlgImpl::getTempName"); time_t t (time(0)); if (t == m_nLastTime) { ++m_nLastCount; } else { m_nLastTime = t; m_nLastCount = 0; } char a [50]; #ifndef WIN32 ctime_r(&t, &a[0]); #else strcpy(a, ctime(&t)); //ttt2 try to get rid of ctime #endif string s; const char* p (&a[0]); for (; 0 != *p; ++p) { char c (*p); if ('\n' == c || '\r' == c) { break; } s += ':' == c ? '.' : c; } sprintf(a, ".%03d", m_nLastCount); return s; } void AlbumInfoDownloaderDlgImpl::retryNavigation() { LAST_STEP("AlbumInfoDownloaderDlgImpl::retryNavigation"); if (NEXT == m_eNavigDir) { next(); } else if (PREV == m_eNavigDir) { previous(); } else { CB_ASSERT (false); } if (NOTHING == m_eWaiting) { resetNavigation(); } // ttt2 perhaps add assert that either there are no pending requests and NOTHING==m_eWaiting or there is 1 pending request and NOTHING!=m_eWaiting (keep in mind that when the connection is opened there is a system-generated request); } void AlbumInfoDownloaderDlgImpl::onSearchLoaded(const QString& qstrXml) { LAST_STEP("AlbumInfoDownloaderDlgImpl::onSearchLoaded"); addNote("search results received"); QByteArray b (qstrXml.toLatin1()); QBuffer bfr (&b); //SearchXmlHandler hndl (*this); auto_ptr<QXmlDefaultHandler> pHndl (getSearchXmlHandler()); QXmlDefaultHandler& hndl (*pHndl); QXmlSimpleReader rdr; rdr.setContentHandler(&hndl); rdr.setErrorHandler(&hndl); QXmlInputSource src (&bfr); if (!rdr.parse(src)) { QMessageBox::critical(this, "Error", "Couldn't process the search result. (Usually this means that the server is busy, so trying later might work.)"); if (0 == getAlbumCount()) { m_nTotalPages = 0; m_nLastLoadedPage = -1; } resetNavigation(); return; } if (0 == getAlbumCount() && m_nLastLoadedPage == m_nTotalPages - 1) { QMessageBox::critical(this, "Error", "No results found"); } retryNavigation(); } void AlbumInfoDownloaderDlgImpl::onAlbumLoaded(const QString& qstrXml) { LAST_STEP("AlbumInfoDownloaderDlgImpl::onAlbumLoaded"); addNote("album info received"); QByteArray b (qstrXml.toLatin1()); QBuffer bfr (&b); //AlbumXmlHandler hndl (album(m_nLoadingAlbum)); auto_ptr<QXmlDefaultHandler> pHndl (getAlbumXmlHandler(m_nLoadingAlbum)); QXmlDefaultHandler& hndl (*pHndl); QXmlSimpleReader rdr; rdr.setContentHandler(&hndl); rdr.setErrorHandler(&hndl); QXmlInputSource src (&bfr); if (!rdr.parse(src)) { //CB_ASSERT (false); QMessageBox::critical(this, "Error", "Couldn't process the album information. (Usually this means that the server is busy, so trying later might work.)"); /*if (0 == getAlbumCount()) { m_nTotalPages = 0; m_nLastLoadedPage = -1; }*/ resetNavigation(); return; } //cout << album(m_nLoadingAlbum); retryNavigation(); } void AlbumInfoDownloaderDlgImpl::onImageLoaded(const QByteArray& comprImg, int nWidth, int nHeight, const QString& qstrInfo) { LAST_STEP("AlbumInfoDownloaderDlgImpl::onImageLoaded"); addNote("image received"); CB_ASSERT (0 == album(m_nLoadingAlbum).m_vpImages[m_nLoadingImage]); CB_ASSERT (ImageInfo::INVALID != m_eLoadingImageCompr); album(m_nLoadingAlbum).m_vpImages[m_nLoadingImage] = new ImageInfo(-1, ImageInfo::OK, m_eLoadingImageCompr, comprImg, nWidth, nHeight); album(m_nLoadingAlbum).m_vstrImageInfo[m_nLoadingImage] = convStr(qstrInfo); m_vpImages.push_back(album(m_nLoadingAlbum).m_vpImages[m_nLoadingImage]); retryNavigation(); } void AlbumInfoDownloaderDlgImpl::addNote(const char* szNote) { LAST_STEP("AlbumInfoDownloaderDlgImpl::addNote"); QString q (m_pDownloadsM->toPlainText()); if (!q.isEmpty()) { q += "\n"; } { QTime t (QTime::currentTime()); char a [15]; sprintf(a, "%02d:%02d:%02d.%03d ", t.hour(), t.minute(), t.second(), t.msec()); q += a; } q += szNote; m_pDownloadsM->setText(q); QScrollBar* p (m_pDownloadsM->verticalScrollBar()); if (p->isVisible()) { p->setValue(p->maximum()); } } void AlbumInfoDownloaderDlgImpl::setWaiting(Waiting eWaiting) { LAST_STEP("AlbumInfoDownloaderDlgImpl::setWaiting"); if (NOTHING == m_eWaiting && NOTHING != eWaiting) { QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); } if (NOTHING != m_eWaiting && NOTHING == eWaiting) { QApplication::restoreOverrideCursor(); } m_eWaiting = eWaiting; } void AlbumInfoDownloaderDlgImpl::reloadGui() { LAST_STEP("AlbumInfoDownloaderDlgImpl::reloadGui"); resetNavigation(); if (0 == getAlbumCount()) { return; } CB_ASSERT (m_nCrtAlbum >= 0 && m_nCrtAlbum < getAlbumCount()); //const MusicBrainzAlbumInfo& album (m_vAlbums[m_nCrtAlbum]); const WebAlbumInfoBase& albumInfo (album(m_nCrtAlbum)); m_pFormatE->setText(convStr(albumInfo.m_strFormat)); m_pRealeasedE->setText(convStr(albumInfo.m_strReleased)); //m_pTrackListL->clear(); updateTrackList(); set<string> sstrPrefixes; for (int i = 0, n = cSize(albumInfo.m_vTracks); i < n; ++i) { const TrackInfo& trk (albumInfo.m_vTracks[i]); const string& s1 (trk.m_strPos); string::size_type k (s1.find_last_not_of("0123456789")); if (string::npos != k && s1.size() - 1 != k) { sstrPrefixes.insert(s1.substr(0, k + 1)); } } m_pVolumeCbB->clear(); if (sstrPrefixes.empty() || sstrPrefixes.size() == albumInfo.m_vTracks.size()) { m_pVolumeCbB->setEnabled(false); m_pVolumeL->setEnabled(false); } else { m_pVolumeCbB->setEnabled(true); m_pVolumeL->setEnabled(true); for (set<string>::iterator it = sstrPrefixes.begin(); it != sstrPrefixes.end(); ++it) { m_pVolumeCbB->addItem(convStr(*it)); } m_pVolumeCbB->addItem("<All>"); } QString q1 (m_nTotalPages == m_nLastLoadedPage + 1 ? "" : "+"); QString s (QString("Album %1/%2%3, image %4/%5").arg(m_nCrtAlbum + 1).arg(getAlbumCount()).arg(q1).arg(m_nCrtImage + 1).arg(albumInfo.m_vpImages.size())); m_pResultNoL->setText(s); m_pResArtistE->setText(convStr(albumInfo.m_strArtist)); m_pResAlbumE->setText(convStr(albumInfo.m_strTitle)); if (-1 == m_nCrtImage || 0 == albumInfo.m_vpImages[m_nCrtImage]) { m_pImageL->setPixmap(0); m_pImageL->setText(""); m_pImgSizeL->setText("No image\n"); } else { m_pImageL->setPixmap(QPixmap::fromImage(albumInfo.m_vpImages[m_nCrtImage]->getImage(m_pImageL->width(), m_pImageL->height()))); m_pImgSizeL->setText(convStr(albumInfo.m_vstrImageInfo[m_nCrtImage])); } } /*override*/ void AlbumInfoDownloaderDlgImpl::updateTrackList() { LAST_STEP("AlbumInfoDownloaderDlgImpl::updateTrackList"); m_pModel->emitLayoutChanged(); SimpleQTableViewWidthInterface intf (*m_pTrackListG); ColumnResizer rsz (intf, 100, ColumnResizer::DONT_FILL, ColumnResizer::CONSISTENT_RESULTS); } /*static*/ string AlbumInfoDownloaderDlgImpl::removeParentheses(const string& s) { string r; int k1 (0), k2 (0), k3 (0), k4 (0); for (int i = 0, n = cSize(s); i < n; ++i) { char c (s[i]); if ('(' == c) { ++k1; } if ('[' == c) { ++k2; } if ('{' == c) { ++k3; } if ('<' == c) { ++k3; } if (0 == k1 && 0 == k2 && 0 == k3 && 0 == k4) { r += c; } if (')' == c) { --k1; } if (']' == c) { --k2; } if ('}' == c) { --k3; } if ('>' == c) { --k4; } } trim(r); return r; } void AlbumInfoDownloaderDlgImpl::saveDownloadedData(const char* p, int nSize, const char* szExt) { LAST_STEP("AlbumInfoDownloaderDlgImpl::saveDownloadedData"); string s (getTempName() + "." + szExt); ofstream_utf8 out (s.c_str(), ios::binary); out.write(p, nSize); } void AlbumInfoDownloaderDlgImpl::onHelp() { openHelp("200_discogs_query.html"); } //========================================================================================================================== //========================================================================================================================== //========================================================================================================================== void addIfMissing(string& strDest, const string& strSrc) { if (strDest.empty()) { strDest = strSrc; } else { if (string::npos == strDest.find(strSrc)) { strDest += ", " + strSrc; } } } // splits a string based on a separator, putting the components in a vector; trims the substrings; discards empty components; void split(const string& s, const string& sep, vector<string>& v) { v.clear(); string::size_type j (0), k; int n (cSize(s)); do { k = s.find(sep, j); if (string::npos == k) { k = n; } string s1 (s.substr(j, k - j)); trim(s1); if (!s1.empty()) { v.push_back(s1); } j = k + 1; } while ((int)k < n); } void addList(string& strDest, const string& strSrc) { if (strDest.empty()) { strDest = strSrc; } else { vector<string> v; split (strSrc, ",", v); for (int i = 0, n = cSize(v); i < n; ++i) { addIfMissing(strDest, v[i]); } } } //==================================================================================================================== //==================================================================================================================== //==================================================================================================================== WebDwnldModel::WebDwnldModel(AlbumInfoDownloaderDlgImpl& dwnld, QTableView& grid) : QAbstractTableModel(&dwnld), m_dwnld(dwnld), m_grid(grid) { } /*override*/ int WebDwnldModel::rowCount(const QModelIndex&) const { const WebAlbumInfoBase* p (m_dwnld.getCrtAlbum()); if (0 == p) { return 0; } return cSize(p->m_vTracks); } /*override*/ int WebDwnldModel::columnCount(const QModelIndex&) const { return m_dwnld.getColumnCount(); } /*override*/ QVariant WebDwnldModel::data(const QModelIndex& index, int nRole) const { //LAST_STEP("WebDwnldModel::data()"); if (!index.isValid()) { return QVariant(); } if (nRole != Qt::DisplayRole && nRole != Qt::ToolTipRole) { return QVariant(); } int i (index.row()), j (index.column()); //if (nRole == Qt::CheckStateRole && j == 2) { return Qt::Checked; } const WebAlbumInfoBase* p (m_dwnld.getCrtAlbum()); if (0 == p || i >= cSize(p->m_vTracks)) { if (nRole == Qt::ToolTipRole) { return ""; } return QVariant(); } const TrackInfo& t (p->m_vTracks[i]); string s; switch (j) { case 0: s = t.m_strPos; break; case 1: s = t.m_strTitle; break; case 2: s = t.m_strArtist; break; case 3: s = t.m_strComposer; break; default: CB_ASSERT (false); } QString qs (convStr(s)); if (nRole == Qt::ToolTipRole) { QFontMetrics fm (m_grid.fontMetrics()); // !!! no need to use "QApplication::fontMetrics()" int nWidth (fm.width(qs)); if (nWidth + 10 < m_grid.horizontalHeader()->sectionSize(j)) // ttt2 "10" is hard-coded { //return QVariant(); return ""; // !!! with "return QVariant()" the previous tooltip remains until the cursor moves over another cell that has a tooltip }//*/ return qs; } return qs; } /*override*/ QVariant WebDwnldModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { switch (nSection) { case 0: return "Pos"; case 1: return "Title"; case 2: return "Artist"; case 3: return "Composer"; default: CB_ASSERT (false); } } return nSection + 1; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/ConfigDlgImpl.h�������������������������������������������������������������0000644�0001750�0000144�00000015526�11271111565�016113� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef ConfigDlgImplH #define ConfigDlgImplH #include <QDialog> #include "ui_Config.h" #include "NoteFilterDlgImpl.h" // for NoteListElem and NoteListPainter //ttt2 perhaps move them in their own file #include "Transformation.h" //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- class TransfConfig; class CustomTransfListPainter; class VisibleTransfPainter; class QSettings; class QStackedLayout; class CommonData; void initDefaultCustomTransf(int k, std::vector<std::vector<int> >& vv, CommonData* pCommonData); void initDefaultVisibleTransf(std::vector<int>& v, CommonData* pCommonData); class ConfigDlgImpl : public QDialog, private Ui::ConfigDlg, public NoteListPainterBase // ttt2 NoteListPainterBase is used for the ignored notes, while for custom transforms there is a separate CustomTransfListPainter; this is confusing //ttt2 perhaps create IgnoredNotesPainter, but it's not straightforward, because of the use of protected members in NoteListPainterBase { Q_OBJECT TransfConfig& m_transfCfg; CommonData* m_pCommonData; void logState(const char* szPlace) const; /*override*/ std::string getTooltip(TooltipKey eTooltipKey) const; /*override*/ void reset(); CustomTransfListPainter* m_pCustomTransfListPainter; DoubleList* m_pCustomTransfDoubleList; std::vector<std::vector<int> > m_vvnCustomTransf; void selectCustomTransf(int k); // 0 <= k <= CUSTOM_TRANSF_CNT int m_nCurrentTransf; void getTransfData(); std::vector<QToolButton*> m_vpTransfButtons; std::vector<QTextEdit*> m_vpTransfLabels; void refreshTransfText(int k); // 0 <= k <= CUSTOM_TRANSF_CNT QPalette m_defaultPalette; QPalette m_wndPalette; std::vector<std::vector<int> > m_vvnDefaultCustomTransf; VisibleTransfPainter* m_pVisibleTransfPainter; DoubleList* m_pVisibleTransfDoubleList; std::vector<int> m_vnVisibleTransf; std::vector<int> m_vnDefaultVisibleTransf; void selectDir(QLineEdit*); QByteArray m_codepageTestText; QFont m_generalFont; QFont m_fixedFont; void setFontLabels(); std::vector<QToolButton*> m_vpColButtons; std::vector<QColor> m_vNoteCategColors; void setBtnColor(int n); void onButtonClicked(int n); QStackedLayout* m_pFileSettingsLayout; TransfConfig::Options getOpt(); // has the correct m_bKeepOrigTime TransfConfig::Options getSimpleViewOpt(); // doesn't set m_bKeepOrigTime TransfConfig::Options getFullViewOpt(); // doesn't set m_bKeepOrigTime void setSimpleViewOpt(const TransfConfig::Options& opt); // m_bKeepOrigTime shouldn't be set void setFullViewOpt(const TransfConfig::Options& opt); // m_bKeepOrigTime is ignored public: enum { SOME_TABS, ALL_TABS }; ConfigDlgImpl(TransfConfig& transfCfg, CommonData* pCommonData, QWidget* pParent, bool bFull); // bFull determines if all the tabs should be visible ~ConfigDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ bool run(); public slots: /*$PUBLIC_SLOTS$*/ void on_m_pOkB_clicked(); void on_m_pCancelB_clicked(); void on_m_pCustomTransform1B_clicked() { selectCustomTransf(0); } void on_m_pCustomTransform2B_clicked() { selectCustomTransf(1); } void on_m_pCustomTransform3B_clicked() { selectCustomTransf(2); } void on_m_pCustomTransform4B_clicked() { selectCustomTransf(3); } // CUSTOM_TRANSF_CNT void onTransfDataChanged(); void on_m_pSelectSrcDirB_clicked() { selectDir(m_pSrcDirE); } void on_m_pSelectTempDirB_clicked() { selectDir(m_pTempDestE); } void on_m_pSelectCompDirB_clicked() { selectDir(m_pCompDestE); } void on_m_pSelectOrigTransfDestDirB_clicked() { selectDir(m_pPODestE); } void on_m_pSelectOrigTransfDestDir2B_clicked() { selectDir(m_pPODest2E); } void on_m_pSelectOrigNotTransfDestDirB_clicked() { selectDir(m_pUODestE); } void on_m_pSelectTransfDestDirB_clicked() { selectDir(m_pProcDestE); } void on_m_pChangeGenFontB_clicked(); void on_m_pChangeFixedFontB_clicked(); void on_m_pLocaleCbB_currentIndexChanged(int); void on_m_pCol0B_clicked() { onButtonClicked(0); } void on_m_pCol1B_clicked() { onButtonClicked(1); } void on_m_pCol2B_clicked() { onButtonClicked(2); } void on_m_pCol3B_clicked() { onButtonClicked(3); } void on_m_pCol4B_clicked() { onButtonClicked(4); } void on_m_pCol5B_clicked() { onButtonClicked(5); } void on_m_pCol6B_clicked() { onButtonClicked(6); } void on_m_pCol7B_clicked() { onButtonClicked(7); } void on_m_pCol8B_clicked() { onButtonClicked(8); } void on_m_pCol9B_clicked() { onButtonClicked(9); } void on_m_pCol10B_clicked() { onButtonClicked(10); } void on_m_pCol11B_clicked() { onButtonClicked(11); } void on_m_pCol12B_clicked() { onButtonClicked(12); } void on_m_pCol13B_clicked() { onButtonClicked(13); } void on_m_pResetColorsB_clicked(); void on_m_pFastSaveCkB_stateChanged(); void on_m_pSimpleViewB_clicked(); void on_m_pFullViewB_clicked(); void onHelp(); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Id3V2Stream.cpp�������������������������������������������������������������0000644�0001750�0000144�00000142552�11330507760�015775� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <sstream> #include "fstream_unicode.h" #include "Id3V2Stream.h" #include "MpegStream.h" #include "Helpers.h" #include "CommonData.h" using namespace std; using namespace pearl; /* ID3V2.3 +-----------------------------+ | Header (10 bytes) | +-----------------------------+ | Extended Header | | (variable length, OPTIONAL) | +-----------------------------+ | Frames (variable length) | +-----------------------------+ | Padding | | (variable length, OPTIONAL) | +-----------------------------+ | Footer (10 bytes, OPTIONAL) | +-----------------------------+ http://osdir.com/ml/multimedia.id3v2/2007-08/msg00008.html : For v2.3 tags, you would read the first ten bytes (tag header) and then, if there is an extended header, read 4 bytes to get its size and then skip that many bytes. (The padding that is given in the extended header comes AFTER the frames.) For v2.4 tags, you would read the first ten bytes (tag header) and then, if there is an extended header, read 4 bytes to get its size and then skip (size - 4) bytes ahead. (I believe in v2.4 tags, the size given in the extended header includes the 4 bytes you would have already read.) And don't forget that in v2.4 tags, the extended header size is stored as a syncsafe integer. */ // the total size, including the 10-byte header int getId3V2Size(char* pId3Header) { unsigned char* p (reinterpret_cast<unsigned char*>(pId3Header)); return (p[6] << 21) + (p[7] << 14) + (p[8] << 7) + (p[9] << 0) + 10; } // reads nCount bytes into pDest; // if bHasUnsynch is true, it actually reads more bytes, applying the unsynchronization algorithm, so pDest gets nCount bytes; // returns the number of bytes it could read; // posNext is the position where the next block begins (might be EOF); nothing starting at that position should be read; needed to take care of an ID3V2 tag whose last frame ends with 0xff and has no padding; // asserts that posNext is not before the current position in the stream streamsize readID3V2(bool bHasUnsynch, istream& in, char* pDest, streamsize nCount, streampos posNext, int& nBytesSkipped) { nBytesSkipped = 0; if (0 == nCount) { return 0; } streampos posCrt (in.tellg()); STRM_ASSERT (posNext >= posCrt); // not always right if (nCount > posNext - posCrt) { nCount = posNext - posCrt; } if (!bHasUnsynch) { return read(in, pDest, nCount); } const int BFR_SIZE (256); char bfr [BFR_SIZE]; char cPrev (0); char* q (pDest); for (;;) { streamsize nTarget (min(streamsize(BFR_SIZE), streamsize(posNext - posCrt))); streamsize nRead (read(in, bfr, nTarget)); if (0 == nRead) { // doesn't matter what was read before; EOF reached goto e1; } char* p (bfr); for (;;) { if (posCrt >= posNext) { goto e1; } if (p >= bfr + nRead) { break; } if (0 == *p && char(0xff) == cPrev) { ++p; posCrt += 1; ++nBytesSkipped; cPrev = 0; if (posCrt >= posNext) { goto e1; } if (p >= bfr + nRead) { break; } } if (q >= pDest + nCount) { goto e1; } cPrev = *q++ = *p++; posCrt += 1; } } e1: in.clear(); in.seekg(posCrt); return streamsize(q - pDest); } //============================================================================================================ //============================================================================================================ //============================================================================================================ Id3V2Frame::Id3V2Frame(streampos pos, bool bHasUnsynch, StringWrp* pFileName) : m_nMemDataSize(-1), m_nDiskDataSize(-1), m_pos(pos), m_pFileName(pFileName), m_bHasUnsynch(bHasUnsynch), m_bHasLatin1NonAscii(false), m_eApicStatus(NO_APIC), m_nPictureType(-1), m_nImgOffset(-1), m_nImgSize(-1), m_eCompr(ImageInfo::INVALID), m_nWidth(-1), m_nHeight(-1) { } /*virtual*/ Id3V2Frame::~Id3V2Frame() { //qDebug("Id3V2Frame::~Id3V2Frame(%p)", this); } static bool isReadable(char c) { return c > 32 && c < 127; } // normally returns m_szName, but if it has invalid characters (<=32 or >=127), returns a hex representation string Id3V2Frame::getReadableName() const { if (isReadable(m_szName[0]) && isReadable(m_szName[1]) && isReadable(m_szName[2]) && isReadable(m_szName[3])) { return m_szName; } char a [32]; sprintf(a, "0x%02x 0x%02x 0x%02x 0x%02x", (unsigned)(unsigned char)m_szName[0], (unsigned)(unsigned char)m_szName[1], (unsigned)(unsigned char)m_szName[2], (unsigned)(unsigned char)m_szName[3]); return a; } static const char* findAfter(const char* p, unsigned char cEnc, const char* pLast) { //inspect(p, pLast - p); if (0 == p) { return 0; } switch (cEnc) { case 0: case 3: { while (p < pLast - 1 && 0 != *p) { ++p; } if (p + 1 < pLast) { return p + 1; } return 0; } case 1: case 2: { while (p < pLast - 2 && (0 != *p || 0 != *(p + 1))) { p += 2; //inspect(p, pLast - p); } if (p + 2 < pLast) { return p + 2; } return 0; } default: CB_ASSERT(false); } } void Id3V2Frame::print(ostream& out, bool bFullInfo) const { out << m_szName; if ('T' == m_szName[0]) { string s (getUtf8String()); if (!bFullInfo && cSize(s) > 100) { s.erase(90); s += " ..."; } out << "=\"" << s << "\""; //ttt2 probably specific to particular versions of Linux and GCC //cout << " value=\"" << getUtf8String() << "\""; //ttt2 probably specific to particular versions of Linux and GCC //out << " value=\"" << "RRRRRRRR" << "\""; } else if (bFullInfo && string("USLT") == m_szName) { Id3V2FrameDataLoader wrp (*this); const char* pData (wrp.getData()); //const char* q (pData + 1); out << ": "; int nBeg (1); { // skip description if (0 == pData[0] || 3 == pData[0]) { for (; nBeg < m_nMemDataSize && 0 != pData[nBeg]; ++nBeg) {} ++nBeg; } else { for (; nBeg < m_nMemDataSize - 1 && (0 != pData[nBeg] || 0 != pData[nBeg + 1]); ++nBeg) {} nBeg += 2; } } QString qs; switch (pData[0]) { case 0: // Latin-1 qs = QString::fromLatin1(pData + nBeg, m_nMemDataSize - nBeg); break; case 1: try { qs = QString::fromUtf8(utf8FromBomUtf16(pData + nBeg, m_nMemDataSize - nBeg).c_str()); } catch (const NotId3V2Frame&) { qs = "<< error decoding string >>"; } break; case 2: qs = "<< unsupported encoding >>"; break; case 3: qs = QString::fromUtf8(pData + nBeg, m_nMemDataSize - nBeg); // ttt3 not quite OK for ID3V2.3.0, but it's probably better this way break; } //qs.replace('\n', " / "); qs.replace('\r', ""); qs = "\n" + qs + "\n"; out << qs.toUtf8().constData(); } else { out << " size=" << m_nMemDataSize; } if (bFullInfo && string("GEOB") == m_szName) { // !!! "size" is already written //ttt2 perhaps try and guess the data type Id3V2FrameDataLoader wrp (*this); const char* pData (wrp.getData()); unsigned char cEnc (*pData); const char* pMime (0); const char* pFile (0); const char* pDescr (0); const char* pBinData (0); QString qstrMime, qstrFile, qstrDescr; if (cEnc > 3) { out << " invalid text encoding"; } else if (2 == cEnc) { out << " unsupported text encoding"; } else { const char* pLast (pData + m_nMemDataSize); // actually first after last pMime = pData + 1; pFile = findAfter(pMime, 0, pLast); // !!! mime is always UTF-8 pDescr = findAfter(pFile, cEnc, pLast); pBinData = findAfter(pDescr, cEnc, pLast); if (0 != pBinData) { qstrMime = QString::fromLatin1(pMime); switch (cEnc) { case 0: // Latin-1 qstrFile = QString::fromLatin1(pFile); qstrDescr = QString::fromLatin1(pDescr); break; case 1: try { qstrFile = QString::fromUtf8(utf8FromBomUtf16(pFile, pDescr - pFile).c_str()); } catch (const NotId3V2Frame&) { // invalid encoding qstrFile = "<encoding error>"; } try { qstrDescr = QString::fromUtf8(utf8FromBomUtf16(pDescr, pBinData - pDescr).c_str()); } catch (const NotId3V2Frame&) { // invalid encoding qstrDescr = "<encoding error>"; } break; /*case 2: qs = "<< unsupported encoding >>"; break;*/ case 3: // ttt3 not quite OK for ID3V2.3.0, but it's probably better this way qstrFile = QString::fromUtf8(pFile); qstrDescr = QString::fromUtf8(pDescr); break; default: CB_ASSERT1 (false, m_pFileName->s); } } if (0 == pBinData) { out << " invalid data"; } else { int nBinSize (pLast - pBinData); int nPrintedBinSize (min(1024, nBinSize)); out << " MIME=\"" << convStr(qstrMime) << "\" File=\"" << convStr(qstrFile) << "\" Descr=\"" << convStr(qstrDescr) << "\" Binary data size=" << pLast - pBinData << (nPrintedBinSize != nBinSize ? " Begins with: " : " Content: ") << asHex(pBinData, nPrintedBinSize); } } } if (Id3V2Frame::NO_APIC != m_eApicStatus) { out << " status=" << getImageStatus(); } } const char* Id3V2Frame::getImageType() const { return ImageInfo::getImageType(m_nPictureType); } const char* Id3V2Frame::getImageStatus() const { switch(m_eApicStatus) { case USES_LINK: return "link"; case NON_COVER: return "non-cover"; case ERR: return "error"; case COVER: return "cover"; default: CB_ASSERT1 (false, m_pFileName->s); } } double Id3V2Frame::getRating() const // asserts it's POPM { CB_ASSERT (0 == strcmp(KnownFrames::LBL_RATING(), m_szName)); Id3V2FrameDataLoader wrp (*this); const char* pData (wrp.getData()); int k (0); while (k < m_nMemDataSize && 0 != pData[k]) { ++k; } // skip email addr ++k; if (k >= m_nMemDataSize) { // error //ttt2 add warning on constructor return -1; } unsigned char c (pData[k]); return 5*(double(c) - 1)/254; // ttt2 not sure this is the best mapping } /*static*/ string Id3V2Frame::utf8FromBomUtf16(const char* pData, int nSize) { CB_CHECK1 (nSize > 1, NotId3V2Frame()); // UNICODE string entries must have a size of 3 or more." if (2 == nSize && 0 == *pData && 0 == *(pData + 1)) { return ""; } // not quite correct, but seems to happen; even if a string is null, it must begin with BOM //ttt1 add a note const unsigned char* p (reinterpret_cast<const unsigned char*> (pData)); CB_CHECK1 ((0xff == p[0] && 0xfe == p[1]) || (0xff == p[1] && 0xfe == p[0]), NotId3V2Frame()); //ttt2 perhaps use other exception #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN bool bIsFffeOk (true); // x86 #else bool bIsFffeOk (false); #endif pData += 2; vector<char> v; int nUSize ((nSize - 2)/2); // ttt3 maybe check that nSize is an even number, but not sure what to do if it isn't if ((0xff == *p && !bIsFffeOk) || (0xff != *p && bIsFffeOk)) { // swap bytes so QString would understand them; it might seem useful for QString to understand BOM, but it doesn't; so ... v.resize(nUSize*2); for (int i = 0; i < nUSize; ++i) { v[i*2] = pData[i*2 + 1]; v[i*2 + 1] = pData[i*2]; } pData = &v[0]; } const ushort* pUs (reinterpret_cast<const ushort*>(pData)); QString qs (QString::fromUtf16(pUs, nUSize)); string s (convStr(qs)); return s; } // for display / export; for frames in KnownFrames::getKnownFrames only the data up to the first 0 is used (effectively removing comments in 2.3.0), while for the others, including TXXX, nulls and all other characters with codes below 32 are replaced with spaces (as a result, both description and value are shown for TXXX), so in either case the return value doesn't contain nulls; // whitespaces at the end of the string are removed; string Id3V2Frame::getUtf8String() const { try { string s (getUtf8StringImpl()); if (0 == KnownFrames::getKnownFrames().count(m_szName) || isTxxx()) { // text frames may contain null characters, and what's after a null char isn't supposed to be displayed; however, for frames that aren't used we may want to see what's after the null // ttt2 null characters mean different things inside ID3V2.3.0 (comment follows) vs. ID3V2.4.0 (multiple values separated by 0); however, this doesn't matter in current implementation, because Id3V240Frame::getUtf8StringImpl() replaces nulls with commas for (int i = 0; i < cSize(s); ++i) { unsigned char c (s[i]); if (c < 32) // ttt3 ASCII only { s[i] = 32; } } } s = s.c_str(); // !!! so now s doesn't contain null chars rtrim(s); return s; } catch (const Id3V2FrameDataLoader::LoadFailure&) { return "<error loading frame>"; //ttt2 not sure if this is the best thing to do, but at least avoids crashes; } catch (const Id3V2Frame::NotId3V2Frame&) { return "<error decoding frame>"; //ttt2 not sure if this is the best thing to do, but at least avoids crashes; } } // for internal processing; similar to getUtf8String() but doesn't replace internal null characters with spaces; // removes trailing nulls and whitespaces, as well as 2.3.0 comments; string Id3V2Frame::getRawUtf8String() const { try { string s (getUtf8StringImpl()); int i (cSize(s) - 1); for (; i >= 0; --i) { unsigned char c (s[i]); if (0 != c && (c >= ' ' || (c < ' ' && QChar(c).isSpace()))) { break; } } ++i; if (i < cSize(s)) { s.erase(i); } return s; } catch (const Id3V2FrameDataLoader::LoadFailure&) { return "<error loading frame>"; //ttt2 not sure if this is the best thing to do, but at least avoids crashes; } catch (const Id3V2Frame::NotId3V2Frame&) { return "<error decoding frame>"; //ttt2 not sure if this is the best thing to do, but at least avoids crashes; } } bool Id3V2Frame::isTxxx() const { return 0 == strcmp(KnownFrames::LBL_TXXX(), m_szName); } //============================================================================================================ //============================================================================================================ //============================================================================================================ Id3V2FrameDataLoader::Id3V2FrameDataLoader(const Id3V2Frame& frame) : m_frame(frame) { if (cSize(frame.m_vcData) < m_frame.m_nMemDataSize) { int nDiscard (frame.getOffset()); // for DataLengthIndicator //m_bOwnsData = true; CB_ASSERT1 (frame.m_vcData.empty(), m_frame.m_pFileName->s); CB_ASSERT1 (0 != frame.m_pFileName, m_frame.m_pFileName->s); m_vcOwnData.resize(m_frame.m_nMemDataSize); ifstream_utf8 in (m_frame.m_pFileName->s.c_str(), ios::binary); in.seekg(m_frame.m_pos); in.seekg(m_frame.m_nDiskHdrSize, ios_base::cur); streampos posNext (m_frame.m_pos); posNext += m_frame.m_nDiskDataSize + m_frame.m_nDiskHdrSize; int nContentBytesSkipped (0); int nRead (0); in.seekg(nDiscard, ios_base::cur); nRead = readID3V2(m_frame.m_bHasUnsynch, in, &m_vcOwnData[0], cSize(m_vcOwnData), posNext, nContentBytesSkipped); //qDebug("nRead %d ; m_frame.m_nMemDataSize %d ; nContentBytesSkipped %d ", nRead, m_frame.m_nMemDataSize, nContentBytesSkipped); if (cSize(m_vcOwnData) != nRead) { throw LoadFailure(); } m_pData = &m_vcOwnData[0]; } else { if (frame.m_vcData.empty()) { static char c (0); m_pData = &c; } else { m_pData = &frame.m_vcData[0]; } } } Id3V2FrameDataLoader::~Id3V2FrameDataLoader() { } //============================================================================================================ //============================================================================================================ //============================================================================================================ /*static*/ const char* KnownFrames::LBL_TITLE() { return "TIT2"; } /*static*/ const char* KnownFrames::LBL_ARTIST() { return "TPE1"; } /*static*/ const char* KnownFrames::LBL_TRACK_NUMBER() { return "TRCK"; } /*static*/ const char* KnownFrames::LBL_TIME_YEAR_230() { return "TYER"; } /*static*/ const char* KnownFrames::LBL_TIME_DATE_230() { return "TDAT"; } /*static*/ const char* KnownFrames::LBL_TIME_240() { return "TDRC"; } /*static*/ const char* KnownFrames::LBL_GENRE() { return "TCON"; } /*static*/ const char* KnownFrames::LBL_IMAGE() { return "APIC"; } /*static*/ const char* KnownFrames::LBL_ALBUM() { return "TALB"; } /*static*/ const char* KnownFrames::LBL_RATING() { return "POPM"; } /*static*/ const char* KnownFrames::LBL_COMPOSER() { return "TCOM"; } /*static*/ const char* KnownFrames::LBL_WMP_VAR_ART() { return "TPE2"; } /*static*/ const char* KnownFrames::LBL_ITUNES_VAR_ART() { return "TCMP"; } /*static*/ const char* KnownFrames::LBL_TXXX() { return "TXXX"; } //============================================================================================================ //============================================================================================================ //============================================================================================================ Id3V2StreamBase::Id3V2StreamBase(int nIndex, istream& in, StringWrp* pFileName) : DataStream(nIndex), m_nPaddingSize(0), m_pos(in.tellg()), m_pFileName(pFileName), m_eImageStatus(ImageInfo::NO_PICTURE_FOUND), m_pPicFrame(0) { } /*override*/ Id3V2StreamBase::~Id3V2StreamBase() { clearPtrContainer(m_vpFrames); } bool Id3V2StreamBase::hasUnsynch() const { return 0 != (m_cFlags & 0x80); } void Id3V2StreamBase::printFrames(ostream& out) const { for (vector<Id3V2Frame*>::const_iterator it = m_vpFrames.begin(), end = m_vpFrames.end(); it != end; ++it) { (*it)->print(out, Id3V2Frame::FULL_INFO); //(*it)->print(cout); } } /*override*/ void Id3V2StreamBase::copy(std::istream& in, std::ostream& out) { appendFilePart(in, out, m_pos, m_nTotalSize); //ttt2 } /*override*/ std::string Id3V2StreamBase::getInfo() const { ostringstream out; out << "padding=" << m_nPaddingSize << ", unsynch=" << (hasUnsynch() ? "YES" : "NO") << "; frames: "; bool bFirst (true); for (vector<Id3V2Frame*>::const_iterator it = m_vpFrames.begin(), end = m_vpFrames.end(); it != end; ++it) { if (!bFirst) { out << ", "; } bFirst = false; (*it)->print(out, Id3V2Frame::SHORT_INFO); } string s (out.str()); //cout << s << endl; //printHex(s, cout, false); return s; } Id3V2Frame* Id3V2StreamBase::findFrame(const char* szFrameName) //ttt2 finds the first frame, but doesn't care about duplicates { for (int i = 0, n = cSize(m_vpFrames); i < n; ++i) { Id3V2Frame* p = m_vpFrames[i]; if (0 == strcmp(szFrameName, p->m_szName)) { return p; } } return 0; } const Id3V2Frame* Id3V2StreamBase::findFrame(const char* szFrameName) const //ttt2 finds the first frame, but doesn't care about duplicates { for (int i = 0, n = cSize(m_vpFrames); i < n; ++i) { const Id3V2Frame* p = m_vpFrames[i]; if (0 == strcmp(szFrameName, p->m_szName)) { return p; } } return 0; } /*override*/ std::string Id3V2StreamBase::getTitle(bool* pbFrameExists /*= 0*/) const { const Id3V2Frame* p (findFrame(KnownFrames::LBL_TITLE())); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } /*override*/ std::string Id3V2StreamBase::getArtist(bool* pbFrameExists /*= 0*/) const { const Id3V2Frame* p (findFrame(KnownFrames::LBL_ARTIST())); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } /*override*/ std::string Id3V2StreamBase::getTrackNumber(bool* pbFrameExists /*= 0*/) const { const Id3V2Frame* p (findFrame(KnownFrames::LBL_TRACK_NUMBER())); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } /*static bool isNum(const string& s) { if (s.empty()) { return false; } for (int i = 0, n = cSize(s); i < n; ++i) { if (!isdigit(s[i])) { return false; } } return true; }*/ static string decodeGenre(const string& s) { string strRes; const char* q (s.c_str()); while ('(' == *q && '(' != *(q + 1)) { const char* q1 (q + 1); if (!isdigit(*q1)) { return s; } // error for (; isdigit(*q1); ++q1) {} if (')' != *q1) { return s; } // error if (!strRes.empty()) { strRes += " / "; } strRes += getId3V1Genre(atoi(q + 1)); q = q1 + 1; } if ('(' == *q && '(' == *(q + 1)) { ++q; } if (0 != *q) { if (!strRes.empty()) { strRes += " / "; } strRes += q; } return strRes; } /*override*/ std::string Id3V2StreamBase::getGenre(bool* pbFrameExists /*= 0*/) const { const Id3V2Frame* p (findFrame(KnownFrames::LBL_GENRE())); // for valid formats see tstGenre() and http://www.id3.org/id3v2.3.0#head-42b02d20fb8bf48e38ec5415e34909945dd849dc if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } string s (p->getUtf8String()); /*int n (cSize(s)); if (n > 2 && '(' == s[0] && ')' == s[n - 1] && isNum(s.substr(1, n - 2))) { return getId3V1Genre(atoi(s.c_str() + 1)); } if (isNum(s)) { return getId3V1Genre(atoi(s.c_str())); }*/ return decodeGenre(s); } /* void tstGenre() //ttt2 remove { cout << "\nGenre test\n"; { string s ("gaga"); cout << "*" << s << "*" << decodeGenre(s) << "*\n"; } { string s ("(10)gaga"); cout << "*" << s << "*" << decodeGenre(s) << "*\n"; } { string s ("(10)(83)gaga"); cout << "*" << s << "*" << decodeGenre(s) << "*\n"; } { string s ("(10)(83)((gaga)"); cout << "*" << s << "*" << decodeGenre(s) << "*\n"; } { string s ("(10a)gaga"); cout << "*" << s << "*" << decodeGenre(s) << "*\n"; } { string s ("(b10)gaga"); cout << "*" << s << "*" << decodeGenre(s) << "*\n"; } } */ void Id3V2StreamBase::checkFrames(NoteColl& notes) // various checks to be called from derived class' constructor { const Id3V2Frame* p (findFrame(KnownFrames::LBL_GENRE())); if (0 != p) { string s (p->getUtf8String()); /*int n (cSize(s)); if (n > 2 && '(' == s[0] && ')' == s[n - 1] && isNum(s.substr(1, n - 2))) { MP3_NOTE (p->m_pos, "Numerical value between parantheses found as track genre. The standard specifies a numerical value, but most applications use a descriptive name instead."); } else if (isNum(s)) { MP3_NOTE (p->m_pos, "Numerical value found as track genre. While this is consistent with the standard, most applications use a descriptive name instead."); } else */if (s.empty()) { MP3_NOTE (p->m_pos, id3v2EmptyTcon); //ttt2 perhaps replace this with something more generic } } //ttt2 add other checks } //ttt2 perhaps use links to pictures in crt dir /*override*/ ImageInfo Id3V2StreamBase::getImage(bool* pbFrameExists /*= 0*/) const { //if (0 != pbFrameExists) { *pbFrameExists = false; } return ImageInfo(ImageInfo::NO_PICTURE_FOUND); if (0 != pbFrameExists) { const Id3V2Frame* p (findFrame(KnownFrames::LBL_IMAGE())); *pbFrameExists = 0 != p; } //ImageInfo res; //res.m_eStatus = m_eImageStatus; if (ImageInfo::OK != m_eImageStatus && ImageInfo::LOADED_NOT_COVER != m_eImageStatus) { CB_ASSERT1 (0 == m_pPicFrame, m_pFileName->s); return ImageInfo(-1, m_eImageStatus); } CB_ASSERT1 (0 != m_pPicFrame, m_pFileName->s); try { Id3V2FrameDataLoader wrp (*m_pPicFrame); const char* pCrtData (wrp.getData()); const char* pBinData (pCrtData + m_pPicFrame->m_nImgOffset); //CB_CHECK (pixmap.loadFromData(pBinData, m_nImgSize)); // make sure the data is still available and correct (the file might have been modified externally) if (-1 == m_pPicFrame->m_nWidth) { QPixmap pic; if (!pic.loadFromData(reinterpret_cast<const unsigned char*>(pBinData), m_pPicFrame->m_nImgSize)) // this takes a lot of time { goto e1; } m_pPicFrame->m_nWidth = short(pic.width()); m_pPicFrame->m_nHeight = short(pic.height()); } QByteArray b (QByteArray::fromRawData(pBinData, m_pPicFrame->m_nImgSize)); b.append('x'); b.resize(b.size() - 1); // !!! these are needed because fromRawData() doesn't create copies of the memory used for the byte array return ImageInfo(m_pPicFrame->m_nPictureType, m_eImageStatus, m_pPicFrame->m_eCompr, b, m_pPicFrame->m_nWidth, m_pPicFrame->m_nHeight); //QBuffer bfr (&res.m_compressedImg); //bfr. //res.m_compressedImg = QByteArray(fromRawData //delete pPictureInfo; } catch (const Id3V2FrameDataLoader::LoadFailure&) { //eImageStatus = ImageInfo::ERROR_LOADING; } e1: trace("The picture could be loaded before but now this is no longer possible. The most likely reason is that the file was moved or changed by an external application."); return ImageInfo(-1, ImageInfo::ERROR_LOADING); } /*override*/ vector<ImageInfo> Id3V2StreamBase::getImages() const { vector<ImageInfo> v; for (int i = 0; i < cSize(m_vpFrames); ++i) { Id3V2Frame* pFrame (m_vpFrames[i]); if (Id3V2Frame::NON_COVER == pFrame->m_eApicStatus || Id3V2Frame::COVER == pFrame->m_eApicStatus) { try { Id3V2FrameDataLoader wrp (*pFrame); const char* pCrtData (wrp.getData()); const char* pBinData (pCrtData + pFrame->m_nImgOffset); //CB_CHECK (pixmap.loadFromData(pBinData, m_nImgSize)); // make sure the data is still available and correct (the file might have been modified externally) if (-1 == pFrame->m_nWidth) { QPixmap pic; if (!pic.loadFromData(reinterpret_cast<const unsigned char*>(pBinData), pFrame->m_nImgSize)) // this takes a lot of time { v.push_back(ImageInfo(pFrame->m_nPictureType, ImageInfo::ERROR_LOADING)); continue; } pFrame->m_nWidth = short(pic.width()); pFrame->m_nHeight = short(pic.height()); } QByteArray b (QByteArray::fromRawData(pBinData, pFrame->m_nImgSize)); b.append('x'); b.resize(b.size() - 1); // !!! these are needed because fromRawData() doesn't create copies of the memory used for the byte array v.push_back(ImageInfo(pFrame->m_nPictureType, Id3V2Frame::COVER == pFrame->m_eApicStatus ? ImageInfo::OK : ImageInfo::LOADED_NOT_COVER, pFrame->m_eCompr, b, pFrame->m_nWidth, pFrame->m_nHeight)); } catch (const Id3V2FrameDataLoader::LoadFailure&) { v.push_back(ImageInfo(pFrame->m_nPictureType, ImageInfo::ERROR_LOADING)); } continue; } if (Id3V2Frame::ERR == pFrame->m_eApicStatus) { v.push_back(ImageInfo(pFrame->m_nPictureType, ImageInfo::ERROR_LOADING)); } if (Id3V2Frame::USES_LINK == pFrame->m_eApicStatus) { v.push_back(ImageInfo(pFrame->m_nPictureType, ImageInfo::USES_LINK)); } } return v; } /*override*/ std::string Id3V2StreamBase::getImageData(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = 0 != m_pPicFrame; } if (0 == m_pPicFrame) { return ""; } ostringstream out; out << "type:" << m_pPicFrame->getImageType() << ", status:" << m_pPicFrame->getImageStatus() << ", size:" << m_pPicFrame->m_nWidth << "x" << m_pPicFrame->m_nHeight << ", compr:" << ImageInfo::getComprStr(m_pPicFrame->m_eCompr); return out.str(); } /*static*/ const char* Id3V2StreamBase::decodeApic(NoteColl& notes, int nDataSize, streampos pos, const char* const pData, const char*& szMimeType, int& nPictureType, const char*& szDescription) { MP3_CHECK (0 == pData[0] || 3 == pData[0], pos, id3v2UnsupApicTextEnc, NotSupTextEnc()); // !!! there's no need for StreamIsUnsupported here, because this error is not fatal, and it isn't allowed to propagate, therefore doesn't cause a stream to be Unsupported; //ttt2 review, support szMimeType = pData + 1; // ttt3 type 0 is Latin1, while type 3 is UTF8, so this isn't quite right; however, MIME types should probably be plain ASCII, so it's the same; and anyway, we only recognize JPEG and PNG, which are ASCII //int nMimeSize (strnlen(pData, nDataSize)); const char* p (pData + 1); for (; p < pData + nDataSize && 0 != *p; ++p) {} MP3_CHECK (p < pData + nDataSize - 1, pos, id3v2UnsupApicTextEnc, ErrorDecodingApic()); // "-1" to account for szDescription CB_ASSERT (0 == *p); ++p; nPictureType = *p++; szDescription = p; for (; p < pData + nDataSize; ++p) { if (0 == *p) { return p + 1; } } throw ErrorDecodingApic(); } void Id3V2StreamBase::preparePictureHlp(NoteColl& notes, Id3V2Frame* pFrame, const char* pFrameData, const char* pImgData, const char* szMimeType) { if (0 == strcmp("-->", szMimeType)) { MP3_NOTE (pFrame->m_pos, id3v2LinkInApic); pFrame->m_eApicStatus = Id3V2Frame::USES_LINK; return; } //QPixmap img; // !!! QPixmap can only be used in GUI threads, so QImage must be used instead: http://lists.trolltech.com/qt-interest/2005-02/thread00008-0.html or http://lists.trolltech.com/qt-interest/2006-11/thread00045-0.html QImage img; const unsigned char* pBinData (reinterpret_cast<const unsigned char*>(pImgData)); int nSize (pFrame->m_nMemDataSize - (pImgData - pFrameData)); if (img.loadFromData(pBinData, nSize)) { pFrame->m_nImgSize = nSize; pFrame->m_nImgOffset = pImgData - pFrameData; pFrame->m_eApicStatus = pFrame->m_nPictureType == Id3V2Frame::PT_COVER ? Id3V2Frame::COVER : Id3V2Frame::NON_COVER; pFrame->m_nWidth = short(img.width()); pFrame->m_nHeight = short(img.height()); if (0 == strcmp("image/jpeg", szMimeType) || 0 == strcmp("image/jpg", szMimeType)) { pFrame->m_eCompr = ImageInfo::JPG; } else if (0 == strcmp("image/png", szMimeType)) { pFrame->m_eCompr = ImageInfo::PNG; } else { pFrame->m_eCompr = ImageInfo::INVALID; } //ttt2 perhaps support GIF or other formats; (well, GIFs can be loaded, but are recompressed when saving) return; } pFrame->m_eApicStatus = Id3V2Frame::ERR; if (pFrame->m_nMemDataSize > 100) { MP3_NOTE (pFrame->m_pos, id3v2ErrorLoadingApic); } else { MP3_NOTE (pFrame->m_pos, id3v2ErrorLoadingApicTooShort); } } void Id3V2StreamBase::preparePicture(NoteColl& notes) // initializes fields used by the APIC frame { const char* szMimeType; const char* szDescription; //Id3V2Frame* pFirstLoadableCover (0); Id3V2Frame* pFirstLoadableNonCover (0); Id3V2Frame* pFirstApic (0); // might have errors, might be link, ... for (int i = 0, n = cSize(m_vpFrames); i < n; ++i) { // go through the frame list and set m_eApicStatus Id3V2Frame* p = m_vpFrames[i]; if (0 == strcmp(KnownFrames::LBL_IMAGE(), p->m_szName)) { if (0 == pFirstApic) { pFirstApic = p; } // !!! regardless of what exceptions might get thrown, p will have an m_eApicStatus other than NO_APIC; that happens either in preparePictureHlp() or with explicit assignments try { Id3V2FrameDataLoader wrp (*p); const char* pData (wrp.getData()); const char* pCrtData (0); try { pCrtData = decodeApic(notes, p->m_nMemDataSize, p->m_pos, pData, szMimeType, p->m_nPictureType, szDescription); } catch (const NotSupTextEnc&) { p->m_eApicStatus = Id3V2Frame::ERR; continue; } catch (const ErrorDecodingApic&) { p->m_eApicStatus = Id3V2Frame::ERR; continue; } if (0 != *szDescription) { MP3_NOTE (p->m_pos, id3v2PictDescrIgnored); } preparePictureHlp(notes, p, pData, pCrtData, szMimeType); if (Id3V2Frame::COVER == p->m_eApicStatus) { if (0 == m_pPicFrame) { m_eImageStatus = ImageInfo::OK; m_pPicFrame = p; } } if (0 == pFirstLoadableNonCover && Id3V2Frame::NON_COVER == p->m_eApicStatus) { pFirstLoadableNonCover = p; } } catch (const Id3V2FrameDataLoader::LoadFailure&) { MP3_NOTE (p->m_pos, fileWasChanged); p->m_eApicStatus = Id3V2Frame::ERR; } } } if (ImageInfo::OK == m_eImageStatus) { return; } // no cover frame was found; just pick the first loadable APIC frame and use it CB_ASSERT (ImageInfo::NO_PICTURE_FOUND == m_eImageStatus); if (0 != pFirstLoadableNonCover) { m_eImageStatus = ImageInfo::LOADED_NOT_COVER; m_pPicFrame = pFirstLoadableNonCover; return; } if (0 == pFirstApic) { return; } switch (pFirstApic->m_eApicStatus) { case Id3V2Frame::USES_LINK: m_eImageStatus = ImageInfo::USES_LINK; return; case Id3V2Frame::ERR: m_eImageStatus = ImageInfo::ERROR_LOADING; return; default: CB_ASSERT1 (false, m_pFileName->s); // all cases should have been covered } } /*override*/ std::string Id3V2StreamBase::getAlbumName(bool* pbFrameExists /*= 0*/) const { const Id3V2Frame* p (findFrame(KnownFrames::LBL_ALBUM())); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } /*override*/ std::string Id3V2StreamBase::getComposer(bool* pbFrameExists /*= 0*/) const { const Id3V2Frame* p (findFrame(KnownFrames::LBL_COMPOSER())); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return ""; } return p->getUtf8String(); } // *pbFrameExists gets set if at least one frame exists /*override*/ int Id3V2StreamBase::getVariousArtists(bool* pbFrameExists /*= 0*/) const { int nRes (0); if (0 != pbFrameExists) { *pbFrameExists = false; } try { { const Id3V2Frame* p (findFrame(KnownFrames::LBL_WMP_VAR_ART())); if (0 != p) { if (0 != pbFrameExists) { *pbFrameExists = true; } if (0 == convStr(p->getUtf8String()).compare("VaRiOuS Artists", Qt::CaseInsensitive)) { nRes += TagReader::VA_WMP; } } } { const Id3V2Frame* p (findFrame(KnownFrames::LBL_ITUNES_VAR_ART())); if (0 != p) { if (0 != pbFrameExists) { *pbFrameExists = true; } if ("1" == p->getUtf8String()) { nRes += TagReader::VA_ITUNES; } } } } catch (const Id3V2Frame::NotId3V2Frame&) { // !!! nothing } catch (const Id3V2Frame::UnsupportedId3V2Frame&) { // !!! nothing } return nRes; } /*override*/ double Id3V2StreamBase::getRating(bool* pbFrameExists /*= 0*/) const { const Id3V2Frame* p (findFrame(KnownFrames::LBL_RATING())); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return -1; } return p->getRating(); } static const char* REPLAY_GAIN_ROOT ("replaygain"); //ttt1 mp3gain 1.5.1 can use ID3V2 instead of APE, so that should be tested as well; see TXXX="MP3GAIN_MINMAX[...]" in "Arctic Monkeys - 01 - My Propeller.mp3" (which also has TXXX="replaygain_track_gain[...]") bool Id3V2StreamBase::hasReplayGain() const { for (int i = 0; i < cSize(m_vpFrames); ++i) { const Id3V2Frame* pFrame (m_vpFrames[i]); if (pFrame->isTxxx()) { QString qs (convStr(pFrame->getUtf8String())); if (qs.startsWith(REPLAY_GAIN_ROOT, Qt::CaseInsensitive)) { return true; } } } return false; } static const char* getId3V2ClassDisplayName() // needed so pointer comparison can be performed for Id3V2StreamBase::getClassDisplayName() regardless of the template param { return "ID3V2"; } /*static*/ const char* Id3V2StreamBase::getClassDisplayName() { return getId3V2ClassDisplayName(); } // returns a frame with the given name; normally it returns the first such frame, but it may return another if there's a good reason; returns 0 if no frame was found; const Id3V2Frame* Id3V2StreamBase::getFrame(const char* szName) const { if (0 == strcmp(szName, KnownFrames::LBL_IMAGE())) { return m_pPicFrame; } return findFrame(szName); } /*static*/ const set<string>& KnownFrames::getExcludeFromInfoFrames() // frames that shouldn't be part of "other info"; doesn't include TXXX and "Various Artists" frames { static bool bFirstTime (true); static set<string> s; if (bFirstTime) { s.insert(KnownFrames::LBL_TITLE()); s.insert(KnownFrames::LBL_ARTIST()); s.insert(KnownFrames::LBL_TRACK_NUMBER()); s.insert(KnownFrames::LBL_TIME_YEAR_230()); s.insert(KnownFrames::LBL_TIME_DATE_230()); s.insert(KnownFrames::LBL_TIME_240()); //ttt2 perhaps this shouldn't be used for 2.3.0, but it covers cases like reading 2.4.0 and writing 2.3.0 or bugs by some tools s.insert(KnownFrames::LBL_GENRE()); s.insert(KnownFrames::LBL_IMAGE()); s.insert(KnownFrames::LBL_ALBUM()); s.insert(KnownFrames::LBL_RATING()); s.insert(KnownFrames::LBL_COMPOSER()); bFirstTime = false; } return s; } // includes "Various Artists" frames; doesn't include TXXX /*static*/ const set<string>& KnownFrames::getKnownFrames() { static bool bFirstTime (true); static set<string> sKnownFrames (getExcludeFromInfoFrames()); if (bFirstTime) { sKnownFrames.insert(KnownFrames::LBL_WMP_VAR_ART()); sKnownFrames.insert(KnownFrames::LBL_ITUNES_VAR_ART()); bFirstTime = false; } return sKnownFrames; } /*override*/ std::string Id3V2StreamBase::getOtherInfo() const { set<string> sUsedFrames; //string strRes; ostringstream out; bool b (false); for (int i = 0, n = cSize(m_vpFrames); i < n; ++i) { Id3V2Frame* p = m_vpFrames[i]; if (KnownFrames::getExcludeFromInfoFrames().count(p->m_szName) > 0 && sUsedFrames.count(p->m_szName) == 0) { sUsedFrames.insert(p->m_szName); } else { if (Id3V2Frame::NON_COVER != p->m_eApicStatus && Id3V2Frame::COVER != p->m_eApicStatus) // images that can be loaded are shown, so there shouldn't be another entry for them { if (b) { out << ", "; } b = true; p->print(out, Id3V2Frame::FULL_INFO); } } } return out.str(); } void Id3V2StreamBase::checkDuplicates(NoteColl& notes) const { // for some it's OK to be duplicated, e.g. for APIC and various "Picture type" pictures; set<pair<string, int> > sUsedFrames; int nImgCnt (0); streampos secondImgPos (-1); for (int i = 0, n = cSize(m_vpFrames); i < n; ++i) { Id3V2Frame* p = m_vpFrames[i]; //if (0 == strcmp("TDOR", p->m_szName)) { MP3_NOTE (p->m_pos, "TDOR found. See if it should be processed."); } //ttt remove //if (0 == strcmp("TDRC", p->m_szName)) { MP3_NOTE (p->m_pos, "TDRC found. See if it should be processed."); } //if (0 == strcmp("TDRL", p->m_szName)) { MP3_NOTE (p->m_pos, "TDRL found. See if it should be processed."); } if (KnownFrames::getKnownFrames().count(p->m_szName) > 0) { if (0 == strcmp(KnownFrames::LBL_IMAGE(), p->m_szName)) { ++nImgCnt; if (2 == nImgCnt) { secondImgPos = p->m_pos; } } if (sUsedFrames.count(make_pair(p->m_szName, p->m_nPictureType)) == 0) { sUsedFrames.insert(make_pair(p->m_szName, p->m_nPictureType)); } else { if (0 == strcmp(KnownFrames::LBL_IMAGE(), p->m_szName)) { MP3_NOTE (p->m_pos, id3v2DuplicatePic); } else if (0 == strcmp(KnownFrames::LBL_RATING(), p->m_szName)) { MP3_NOTE (p->m_pos, id3v2DuplicatePopm); } else { MP3_NOTE_D (p->m_pos, id3v2MultipleFramesWithSameName, Notes::id3v2MultipleFramesWithSameName().getDescription() + string(" (Frame:") + p->m_szName + ")"); //ttt2 m_pos should be replaced with the position of the second frame with this ID } } } } if (nImgCnt > 1) { MP3_NOTE (secondImgPos, id3v2MultipleApic); } } TagTimestamp Id3V2StreamBase::get230TrackTime(bool* pbFrameExists) const { const Id3V2Frame* p (findFrame(KnownFrames::LBL_TIME_YEAR_230())); if (0 != pbFrameExists) { *pbFrameExists = 0 != p; } if (0 == p) { return TagTimestamp(""); } string strYear (p->getUtf8String()); if (4 != cSize(strYear)) { return TagTimestamp(""); } p = findFrame(KnownFrames::LBL_TIME_DATE_230()); try { if (0 == p) { return TagTimestamp(strYear); } string strDate (p->getUtf8String()); if (4 != cSize(strDate)) { return TagTimestamp(strYear); } return TagTimestamp(strYear + "-" + strDate.substr(2, 2) + "-" + strDate.substr(0, 2)); } catch (const TagTimestamp::InvalidTime&) { return TagTimestamp(""); } } vector<const Id3V2Frame*> Id3V2StreamBase::getKnownFrames() const // to be used by Id3V2Cleaner; { vector<const Id3V2Frame*> v; for (int i = 0; i < cSize(m_vpFrames); ++i) { const Id3V2Frame* p (m_vpFrames[i]); if (KnownFrames::getKnownFrames().count(p->m_szName) > 0 || p->isTxxx()) { // add if known except if a picture with the same type was already added; don't add duplicates even if Id3V230StreamWriter could take care of them, because it keeps the last value and we want the first one bool bAdd (true); for (int j = 0; j < cSize(v); ++j) { if (p->m_nPictureType == v[j]->m_nPictureType && 0 == strcmp(v[j]->m_szName, p->m_szName)) { // !!! important for both image and non-image frames; while Id3V230StreamWriter would remove duplicates as configured, we want to get rid of them now, so the first value is kept; Id3V230StreamWriter removes old values as new ones are added, which would keep the last value //ttt2 not always right for multiple pictures if "keep one" is checked; bAdd = false; break; } } if (p->isTxxx()) { string s (p->getUtf8String()); QString qs (convStr(s)); if (qs.startsWith(REPLAY_GAIN_ROOT, Qt::CaseInsensitive)) { bAdd = true; //ttt2 perhaps check it's no duplicate; not sure about case } } if (bAdd && 0 == strcmp(KnownFrames::LBL_IMAGE(), p->m_szName) && Id3V2Frame::COVER != p->m_eApicStatus && Id3V2Frame::NON_COVER != p->m_eApicStatus) { // !!! get rid of broken pictures and links bAdd = false; } if (bAdd) { v.push_back(p); } } } return v; } //============================================================================================================ //============================================================================================================ //============================================================================================================ // explicit instantiation //template class Id3V2Stream<Id3V230Frame>; //template class Id3V2Stream<Id3V240Frame>; //============================================================================================================ //============================================================================================================ //============================================================================================================ /*static*/ const char* KnownFrames::getFrameName (int n) { switch (n) { case 0: return LBL_TITLE(); case 1: return LBL_ARTIST(); case 2: return LBL_TRACK_NUMBER(); case 3: return LBL_TIME_YEAR_230(); case 4: return LBL_TIME_DATE_230(); case 5: return LBL_TIME_240(); case 6: return LBL_GENRE(); case 7: return LBL_IMAGE(); case 8: return LBL_ALBUM(); case 9: return LBL_RATING(); case 10: return LBL_COMPOSER(); } CB_THROW1 (InvalidIndex()); } /*static*/ bool KnownFrames::canHaveDuplicates(const char* szName) { //ttt2 make this more sophisticated; maybe allow multiple LBL_RATING, each with its own email; //if (0 == strcmp(szName, LBL_IMAGE())) { return true; } if (1 == getKnownFrames().count(szName)) { return false; } // !!! OK for LBL_IMAGE, because when actually using this the image type should be compared as well return true; } //ttt2 note for mismatch between file name and rating ������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Helpers.cpp�����������������������������������������������������������������0000644�0001750�0000144�00000106074�12040502151�015357� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <iostream> #include "fstream_unicode.h" #include <sstream> #include <iomanip> #include <boost/version.hpp> #include <QDesktopServices> #ifndef WIN32 #include <QDir> #include <sys/utsname.h> #include <unistd.h> #else #include <windows.h> #include <psapi.h> #include <QSettings> #endif #include <QWidget> #include <QUrl> #include <QFileInfo> #include <QDir> #include "Helpers.h" #include "Widgets.h" #include "OsFile.h" using namespace std; void assertBreakpoint() { cout << endl; //qDebug("assert"); } void appendFilePart(istream& in, ostream& out, streampos pos, streamoff nSize) { const int BFR_SIZE (1024*128); char* pBfr (new char[BFR_SIZE]); pearl::ArrayPtrRelease<char> rel (pBfr); in.seekg(pos); for (; nSize > 0;) { streamoff nCrtRead (nSize > BFR_SIZE ? BFR_SIZE : nSize); CB_CHECK1 (nCrtRead == read(in, pBfr, nCrtRead), EndOfFile()); out.write(pBfr, nCrtRead); nSize -= nCrtRead; } CB_CHECK1 (out, WriteError()); } // prints to stdout the content of a memory location, as ASCII and hex; // GDB has a tendency to not see char arrays and other local variables; actually GCC seems to be the culprit (bug 34767); void inspect(const void* q, int nSize) { ostringstream out; const char* p ((const char*)q); for (int i = 0; i < nSize; ++i) { char c (p[i]); if (c < 32 || c > 126) { c = '.'; } out << c; } out << "\n("; out << hex << setfill('0'); bool b (false); for (int i = 0; i < nSize; ++i) { if (b) { out << " "; } b = true; unsigned char c (p[i]); out << setw(2) << (int)c; } out << dec << ")\n"; qDebug("%s", out.str().c_str()); //logToGlobalFile(out.str()); } int get32BitBigEndian(const char* bfr) { const unsigned char* p (reinterpret_cast<const unsigned char*>(bfr)); int n ((p[0] << 24) + (p[1] << 16) + (p[2] << 8) + (p[3] << 0)); return n; } void put32BitBigEndian(int n, char* bfr) { unsigned u (n); bfr[3] = u & 0xff; u >>= 8; bfr[2] = u & 0xff; u >>= 8; bfr[1] = u & 0xff; u >>= 8; bfr[0] = u & 0xff; } string utf8FromLatin1(const string& strSrc) { int i (0); int n (cSize(strSrc)); for (; i < n; ++i) { unsigned char c (strSrc[i]); if (c >= 128) { goto e1; } } return strSrc; e1: string s (strSrc.substr(0, i)); for (; i < n; ++i) { unsigned char c (strSrc[i]); if (c < 128) { s += char(c); } else { unsigned char c1 (0xc0 | (c >> 6)); unsigned char c2 (0x80 | (c & 0x3f)); s += char(c1); s += char(c2); } } return s; } // removes whitespaces at the end of the string bool CB_LIB_CALL rtrim(string& s) { int n (cSize(s)); int i (n - 1); for (; i >= 0; --i) { unsigned char c (s[i]); if (c >= 128 || !isspace(c)) { break; } //!!! isspace() returns true for some non-ASCII chars, e.g. 0x9f, at least on MinGW (it matters that char is signed) } if (i < n - 1) { s.erase(i + 1); return true; } return false; } // removes whitespaces at the beginning of the string bool CB_LIB_CALL ltrim(string& s) { int n (cSize(s)); int i (0); for (; i < n; ++i) { unsigned char c (s[i]); if (c >= 128 || !isspace(c)) { break; } //!!! isspace() returns true for some non-ASCII chars, e.g. 0x9f, at least on MinGW } if (i > 0) { s.erase(0, i); return true; } return false; } bool CB_LIB_CALL trim(string& s) { bool b1 (ltrim(s)); bool b2 (rtrim(s)); return b1 || b2; } /* // multi-line hex printing void printHex(const string& s, ostream& out, bool bShowAsciiCode = true) //ttt3 see if anybody needs this { int nSize (cSize(s)); int nCrt (0); for (;;) { if (nCrt >= nSize) { return; } int nMax (16); if (nCrt + nMax > nSize) { nMax = nSize - nCrt; } for (int i = 0; i < nMax; ++i) { char c (s[i + nCrt]); if (c < 32 || c >= 127) { c = '?'; } out << " " << c << " "; } out << endl; for (int i = 0; i < nMax; ++i) { unsigned int x ((unsigned char)s[i + nCrt]); if (!bShowAsciiCode && x >= 32 && x < 127) { out << " "; } else { out << setw(2) << hex << x << dec << " "; } } out << endl; nCrt += 16; } } */ std::string asHex(const char* p, int nSize) { ostringstream out; out << "\""; for (int i = 0; i < nSize; ++i) { char c (p[i]); out << (c >= 32 && c < 127 ? c : '.'); } out << "\" (" << hex; for (int i = 0; i < nSize; ++i) { if (i > 0) { out << " "; } unsigned char c (p[i]); out << setw(2) << setfill('0') << (int)c; } out << ")"; return out.str(); } // the total memory currently used by the current process, in kB long getMemUsage() { #ifndef WIN32 //pid_t int n ((int)getpid()); char a [30]; sprintf (a, "/proc/%d/status", n); // ttt2 linux-specific; not sure how version-specific this is; // sprintf (a, "/proc/self/status", n); // ttt2 try this (after checking portability) ifstream_utf8 in (a); string s; while (getline(in, s)) { if (0 == s.find("VmSize:")) { return atol(s.c_str() + 7); } } return 0; #else PROCESS_MEMORY_COUNTERS pmc; if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) { return pmc.WorkingSetSize; } return 0; #endif } void logToGlobalFile(const string& s) //tttc make sure it is disabled in public releases { #ifndef WIN32 ofstream_utf8 out ( "/tmp/Mp3DiagsLog.txt", ios_base::app); #else char a [500]; int n (GetModuleFileNameA(NULL, a, 500)); //ttt3 using GetModuleFileNameA isn't quite right, but since it's a debug function ... a[n - 4] = 0; ofstream_utf8 out ( //"C:/Mp3DiagsLog.txt", //"Mp3DiagsLog.txt", //"C:/temp/Mp3DiagsLog.txt", (string(a) + "Log.txt").c_str(), ios_base::app); #endif out << s << endl; } #define DECODE_CHECK(COND, MSG) { if (!(COND)) { bRes = false; return MSG; } } namespace { struct Decoder { enum Version { MPEG1, MPEG2 }; enum Layer { LAYER1, LAYER2, LAYER3 }; enum ChannelMode { STEREO, JOINT_STEREO, DUAL_CHANNEL, SINGLE_CHANNEL }; Version m_eVersion; Layer m_eLayer; int m_nBitrate; int m_nFrequency; int m_nPadding; ChannelMode m_eChannelMode; int m_nSize; bool m_bCrc; const char* getSzVersion() const; const char* getSzLayer() const; const char* getSzChannelMode() const; string initialize(const unsigned char* bfr, bool* pbIsValid); string decodeMpegFrame(const unsigned char* bfr, const char* szSep, bool* pbIsValid); string decodeMpegFrameAsXml(const unsigned char* bfr, bool* pbIsValid); }; const char* Decoder::getSzVersion() const { static const char* s_versionName[] = { "MPEG-1", "MPEG-2" }; return s_versionName[m_eVersion]; } const char* Decoder::getSzLayer() const { static const char* s_layerName[] = { "Layer I", "Layer II", "Layer III" }; return s_layerName[m_eLayer]; } const char* Decoder::getSzChannelMode() const { static const char* s_channelModeName[] = { "Stereo", "Joint stereo", "Dual channel", "Single channel" }; return s_channelModeName[m_eChannelMode]; } string Decoder::initialize(const unsigned char* bfr, bool* pbIsValid) //ttt2 perhaps unify with MpegFrameBase::MpegFrameBase(), using the char* constructor { bool b; bool& bRes (0 == pbIsValid ? b : *pbIsValid); bRes = true; const unsigned char* pHeader (bfr); //inspect(bfr, BFR_SIZE); DECODE_CHECK (0xff == *pHeader && 0xe0 == (0xe0 & *(pHeader + 1)), "Not an MPEG frame. Synch missing."); ++pHeader; { int nVer ((*pHeader & 0x18) >> 3); switch (nVer) {//TRACE case 0x00: bRes = false; return "Not an MPEG frame. Unsupported version (2.5)."; //ttt2 see about supporting this: search for MPEG1 to find other places // ttt2 in a way it would make more sense to warn that it's not supported, with "MP3_THROW(SUPPORT, ...)", but before warn, make sure it's a valid 2.5 frame, followed by another frame ... case 0x02: m_eVersion = MPEG2; break; case 0x03: m_eVersion = MPEG1; break; default: bRes = false; return "Not an MPEG frame. Invalid version."; } } { int nLayer ((*pHeader & 0x06) >> 1); switch (nLayer) { case 0x01: m_eLayer = LAYER3; break; case 0x02: m_eLayer = LAYER2; break; case 0x03: m_eLayer = LAYER1; break; default: bRes = false; return "Not an MPEG frame. Invalid layer."; } } { m_bCrc = !(*pHeader & 0x01); } ++pHeader; { static int s_bitrates [14][5] = { { 32, 32, 32, 32, 8 }, { 64, 48, 40, 48, 16 }, { 96, 56, 48, 56, 24 }, { 128, 64, 56, 64, 32 }, { 160, 80, 64, 80, 40 }, { 192, 96, 80, 96, 48 }, { 224, 112, 96, 112, 56 }, { 256, 128, 112, 128, 64 }, { 288, 160, 128, 144, 80 }, { 320, 192, 160, 160, 96 }, { 352, 224, 192, 176, 112 }, { 384, 256, 224, 192, 128 }, { 416, 320, 256, 224, 144 }, { 448, 384, 320, 256, 160 } }; int nRateIndex ((*pHeader & 0xf0) >> 4); DECODE_CHECK (nRateIndex >= 1 && nRateIndex <= 14, "Not an MPEG frame. Invalid bitrate."); int nTypeIndex (m_eVersion*3 + m_eLayer); if (nTypeIndex == 5) { nTypeIndex = 4; } m_nBitrate = s_bitrates[nRateIndex - 1][nTypeIndex]*1000; } { int nSmpl ((*pHeader & 0x0c) >> 2); switch (m_eVersion) { case MPEG1: switch (nSmpl) { case 0x00: m_nFrequency = 44100; break; case 0x01: m_nFrequency = 48000; break; case 0x02: m_nFrequency = 32000; break; default: bRes = false; return "Not an MPEG frame. Invalid frequency for MPEG1."; } break; case MPEG2: switch (nSmpl) { case 0x00: m_nFrequency = 22050; break; case 0x01: m_nFrequency = 24000; break; case 0x02: m_nFrequency = 16000; break; default: bRes = false; return "Not an MPEG frame. Invalid frequency for MPEG2."; } break; default: throw 1; // it should have thrown before getting here } } { m_nPadding = (0x02 & *pHeader) >> 1; } ++pHeader; { int nChMode ((*pHeader & 0xc0) >> 6); m_eChannelMode = (ChannelMode)nChMode; } switch (m_eLayer) { case LAYER1: m_nSize = (12*m_nBitrate/m_nFrequency + m_nPadding)*4; break; case LAYER2: m_nSize = 144*m_nBitrate/m_nFrequency + m_nPadding; break; case LAYER3: m_nSize = (MPEG1 == m_eVersion ? 144*m_nBitrate/m_nFrequency + m_nPadding : 72*m_nBitrate/m_nFrequency + m_nPadding); break; default: throw 1; // it should have thrown before getting here } return ""; } string Decoder::decodeMpegFrame(const unsigned char* bfr, const char* szSep, bool* pbIsValid) //ttt2 perhaps unify with MpegFrameBase::MpegFrameBase(), using the char* constructor { string s (initialize(bfr, pbIsValid)); if (!s.empty()) { return s; } ostringstream out; /*out << getSzVersion() << " " << getSzLayer() << ", " << m_nBitrate/1000 << "kbps, " << m_nFrequency << "Hz, " << getSzChannelMode() << ", padding=" << (m_nPadding ? "true" : "false") << ", length " << m_nSize << " (0x" << hex << m_nSize << dec << ")";*/ out << boolalpha << getSzVersion() << " " << getSzLayer() << szSep << getSzChannelMode() << szSep << m_nFrequency << "Hz" << szSep << m_nBitrate << "bps" << szSep << "CRC=" << boolAsYesNo(m_bCrc) << szSep << "length " << m_nSize << " (0x" << hex << m_nSize << dec << ")" << szSep << "padding=" << (m_nPadding ? "true" : "false"); return out.str(); } string Decoder::decodeMpegFrameAsXml(const unsigned char* bfr, bool* pbIsValid) //ttt2 perhaps unify with MpegFrameBase::MpegFrameBase(), using the char* constructor { string s (initialize(bfr, pbIsValid)); if (!s.empty()) { return s; } ostringstream out; out << " version=\"" << getSzVersion() << "\"" << " layer=\"" << getSzLayer() << "\"" << " channelMode=\"" << getSzChannelMode() << "\"" << " frequency=\"" << m_nFrequency << "\"" << " bps=\"" << m_nBitrate << "\"" << " crc=\"" << boolAsYesNo(m_bCrc) << "\"" << " mpegSize=\"" << m_nSize << "\"" << " padding=\"" << boolAsYesNo(m_nPadding) << "\""; return out.str(); } } // namespace string decodeMpegFrame(unsigned int x, const char* szSep, bool* pbIsValid /*= 0*/) { Decoder d; unsigned char bfr [4]; unsigned char* q (reinterpret_cast<unsigned char*>(&x)); bfr[0] = q[3]; bfr[1] = q[2]; bfr[2] = q[1]; bfr[3] = q[0]; return d.decodeMpegFrame(bfr, szSep, pbIsValid); } string decodeMpegFrame(const char* bfr, const char* szSep, bool* pbIsValid /*= 0*/) { Decoder d; const unsigned char* q (reinterpret_cast<const unsigned char*>(bfr)); return d.decodeMpegFrame(q, szSep, pbIsValid); } string decodeMpegFrameAsXml(const char* bfr, bool* pbIsValid /*= 0*/) { Decoder d; const unsigned char* q (reinterpret_cast<const unsigned char*>(bfr)); return d.decodeMpegFrameAsXml(q, pbIsValid); } StreamStateRestorer::StreamStateRestorer(istream& in) : m_in(in), m_pos(in.tellg()), m_bOk(false) { } StreamStateRestorer::~StreamStateRestorer() { if (!m_bOk) { m_in.clear(); m_in.seekg(m_pos); } m_in.clear(); } char getPathSep() { return '/'; // ttt2 linux-specific } const string& getPathSepAsStr() { static string s ("/"); return s; // ttt2 linux-specific // ttt look at QDir::fromNativeSeparators } streampos getSize(istream& in) { streampos crt (in.tellg()); in.seekg(0, ios_base::end); streampos size (in.tellg()); in.seekg(crt); return size; } void writeZeros(ostream& out, int nCnt) { char c (0); for (int i = 0; i < nCnt; ++i) //ttt2 perhaps make this faster { out.write(&c, 1); } CB_CHECK1 (out, WriteError()); } void listWidget(QWidget* p, int nIndent /*= 0*/) { //if (nIndent > 1) { return; } if (0 == nIndent) { cout << "\n----------------------------\n"; } cout << string(nIndent*2, ' ') << convStr(p->objectName()) << " " << p->x() << " " << p->y() << " " << p->width() << " " << p->height() << endl; QList<QWidget*> lst (p->findChildren<QWidget*>()); for (QList<QWidget*>::iterator it = lst.begin(); it != lst.end(); ++it) { QWidget* q (*it); if (q->parentWidget() == p) // !!! needed because findChildren() reurns all descendants, not only children { listWidget(q, nIndent + 1); } } } // replaces invalid HTTP characters like ' ' or '"' with their hex code (%20 or %22) string escapeHttp(const string& s) { QUrl url (convStr(s)); return convStr(QString(url.toEncoded())); } vector<string> convStr(const vector<QString>& v) { vector<string> u; for (int i = 0, n = cSize(v); i < n; ++i) { u.push_back(convStr(v[i])); } return u; } vector<QString> convStr(const vector<string>& v) { vector<QString> u; for (int i = 0, n = cSize(v); i < n; ++i) { u.push_back(convStr(v[i])); } return u; } namespace { struct DesktopDetector { enum Desktop { Unknown, Gnome2 = 1, Gnome3 = 2, Kde3 = 4, Kde4 = 8, Gnome = Gnome2 | Gnome3, Kde = Kde3 | Kde4 }; DesktopDetector(); Desktop m_eDesktop; const char* m_szDesktop; bool onDesktop(Desktop desktop) const { return (desktop & m_eDesktop) != 0; } }; #if defined(__linux__) // look for gnome-settings-daemon or gnome-settings-daemon-3.0 to determine if running in Gnome (3) and if so add close button // or run lsof and get the list DesktopDetector::DesktopDetector() : m_eDesktop(Unknown) { FileSearcher fs ("/proc"); string strBfr; bool bIsKde (false); bool bIsKde4 (false); while (fs) { if (fs.isDir()) { string strCmdLineName (fs.getName()); if (isdigit(strCmdLineName[6])) { #if 0 char szBfr[5000] = "mP3DiAgS"; szBfr[0] = 0; int k (readlink((strCmdLineName + "/exe").c_str(), szBfr, sizeof(szBfr))); if (k >= 0) { szBfr[k] = 0; } cout << strCmdLineName << " "; szBfr[5000 - 1] = 0; //if (0 != szBfr[0]) cout << szBfr << " |"; //cout << szBfr << endl;//*/ strCmdLineName += "/cmdline"; //cout << strCmdLineName << endl; ifstream in (strCmdLineName.c_str()); if (in) { getline(in, strBfr); //if (!strBfr.empty()) { cout << "<<< " << strBfr.c_str() << " >>>" << endl; } //if (!strBfr.empty()) { cout << strBfr.c_str() << endl; } cout << " " << strBfr.c_str(); if (string::npos != strBfr.find("gnome-settings-daemon")) { m_eDesktop = string::npos != strBfr.find("gnome-settings-daemon-3.") ? Gnome3 : Gnome2; break; } }//*/ cout << endl; #endif char szBfr[5000] = "mP3DiAgS"; szBfr[0] = 0; strCmdLineName += "/cmdline"; //cout << strCmdLineName << endl; ifstream in (strCmdLineName.c_str()); if (in) { getline(in, strBfr); //if (!strBfr.empty()) { cout << "<<< " << strBfr.c_str() << " >>>" << endl; } //if (!strBfr.empty()) { cout << strBfr.c_str() << endl; } //cout << strBfr.c_str() << endl; if (string::npos != strBfr.find("gnome-settings-daemon")) { m_eDesktop = string::npos != strBfr.find("gnome-settings-daemon-3.") ? Gnome3 : Gnome2; break; } if (string::npos != strBfr.find("kdeinit")) { bIsKde = true; } if (string::npos != strBfr.find("kde4/libexec")) { bIsKde4 = true; } }//*/ } } //if (string::npos != strBfr.find("kdeinit")) fs.findNext(); } if (m_eDesktop == Unknown) { if (bIsKde4) { m_eDesktop = Kde4; } else if (bIsKde) { m_eDesktop = Kde3; } } switch (m_eDesktop) { case Gnome2: m_szDesktop = "Gnome 2"; break; case Gnome3: m_szDesktop = "Gnome 3"; break; case Kde3: m_szDesktop = "KDE 3"; break; case Kde4: m_szDesktop = "KDE 4"; break; default: m_szDesktop = "Unknown"; } //cout << "desktop: " << m_eDesktop << endl; } #else DesktopDetector::DesktopDetector() : m_eDesktop(Unknown) {} #endif const DesktopDetector& getDesktopDetector() { static DesktopDetector desktopDetector; return desktopDetector; } } // namespace /* Gnome: Qt::Window - minimize, maximize, close; dialog gets its own taskbar entry Qt::WindowTitleHint - close Qt::Dialog - close Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint - nothing Qt::Dialog | Qt::WindowMaximizeButtonHint - nothing Qt::Window | Qt::WindowMaximizeButtonHint - maximize Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint - maximize, minimize Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint - nothing Ideally a modal dialog should minimize its parent. If that's not possible, it shouldn't be minimizable. */ #ifndef WIN32 //Qt::WindowFlags getMainWndFlags() { return isRunningOnGnome() ? Qt::Window : Qt::WindowTitleHint; } // !!! these are incorrect, but seem the best option; the values used for Windows are supposed to be OK; they work as expected with KDE but not with Gnome (asking for maximize button not only fails to show it, but causes the "Close" button to disappear as well); Since in KDE min/max buttons are shown when needed anyway, it's sort of OK // ttt2 see if there is workaround/fix Qt::WindowFlags getMainWndFlags() { const DesktopDetector& dd = getDesktopDetector(); return dd.onDesktop(DesktopDetector::Kde) ? Qt::WindowTitleHint : Qt::Window; } #if QT_VERSION >= 0x040500 Qt::WindowFlags getDialogWndFlags() { const DesktopDetector& dd = getDesktopDetector(); return dd.onDesktop(DesktopDetector::Kde) ? Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint : (dd.onDesktop(DesktopDetector::Gnome3) ? Qt::Window : Qt::WindowTitleHint); } #else Qt::WindowFlags getDialogWndFlags() { const DesktopDetector& dd = getDesktopDetector(); return dd.onDesktop(DesktopDetector::Gnome3) ? Qt::Window : Qt::WindowTitleHint; } // ttt0 perhaps better to make sure all dialogs have their ok/cancel buttons, so there's no need for a dedicated close button and let the app look more "native" #endif Qt::WindowFlags getNoResizeWndFlags() { return Qt::WindowTitleHint; } #else Qt::WindowFlags getMainWndFlags() { return Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint; } // minimize, maximize, no "what's this" Qt::WindowFlags getDialogWndFlags() { return Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint; } // minimize, no "what's this" Qt::WindowFlags getNoResizeWndFlags() { return Qt::WindowTitleHint; } // no "what's this" #endif #if 0 //ttt2 add desktop, distribution, WM, ... #ifndef WIN32 utsname info; uname(&info); cat /proc/version cat /etc/issue dmesg | grep "Linux version" cat /etc/*-release */ cat /etc/*_version */ #else // #endif #endif #ifndef WIN32 static void removeStr(string& main, const string& sub) { for (;;) { string::size_type n (main.find(sub)); if (string::npos == n) { return; } main.erase(n, sub.size()); } } #endif extern const char* APP_VER; QString getSystemInfo() //ttt2 perhaps store this at startup, so fewer things may go wrong fhen the assertion handler needs it { QString s ("OS: "); #ifndef WIN32 QDir dir ("/etc"); QStringList filters; filters << "*-release" << "*_version"; dir.setNameFilters(filters); QStringList lFiles (dir.entryList(QDir::Files)); utsname utsInfo; uname(&utsInfo); s += utsInfo.sysname; s += " "; s += utsInfo.release; s += " "; s += utsInfo.version; s += " "; for (int i = 0; i < lFiles.size(); ++i) { //qDebug("%s", lFiles[i].toUtf8().constData()); if ("lsb-release" != lFiles[i]) { QFile f ("/etc/" + lFiles[i]); if (f.open(QIODevice::ReadOnly)) { QByteArray b (f.read(1000)); s += b; s += " "; } } } QFile f ("/etc/issue"); if (f.open(QIODevice::ReadOnly)) { QByteArray b (f.read(1000)); string s1 (b.constData()); removeStr(s1, "Welcome to"); removeStr(s1, "Kernel"); trim(s1); string::size_type n (s1.find('\\')); if (string::npos != n) { s1.erase(n); } trim(s1); if (endsWith(s1, "-")) { s1.erase(s1.size() - 1); trim(s1); } s += convStr(s1); //qDebug("a: %s", s.toUtf8().constData()); /*for (;;) { string::size_type n (s.find('\n')); if (string::npos == n) { break; } s1[n] = ' '; }*/ //qDebug("b: %s", s.toUtf8().constData()); } //ttt2 search /proc for kwin, metacity, ... #else //qstrVer += QString(" Windows version ID: %1").arg(QSysInfo::WinVersion); QSettings settings ("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", QSettings::NativeFormat); //qstrVer += QString(" Windows version: %1").arg(WIN32); s += QString(" Windows version: %1 %2 Build %3 %4").arg(settings.value("ProductName").toString()) .arg(settings.value("CSDVersion").toString()) .arg(settings.value("CurrentBuildNumber").toString()) .arg(settings.value("BuildLab").toString()); #endif s.replace('\n', ' '); s = QString("Version: MP3 Diags %1.\nWord size: %2 bit.\nQt version: %3.\nBoost version: %4\n").arg(APP_VER).arg(QSysInfo::WordSize).arg(qVersion()).arg(BOOST_LIB_VERSION) + s; return s; } // sets colors at various points to emulate a non-linear gradient that better suits our needs; // dStart and dEnd should be between 0 and 1, with dStart < dEnd; they may also be both -1, in which case the gradient will have a solid color void configureGradient(QGradient& grad, const QColor& col, double dStart, double dEnd) { if (-1 == dStart && -1 == dEnd) { grad.setColorAt(0, col); grad.setColorAt(1, col); return; } CB_ASSERT (dStart < dEnd && 0 <= dStart && dEnd < 1.0001); static vector<double> vdPoints; static vector<double> vdValues; static bool s_bInit (false); static int SIZE; if (!s_bInit) { s_bInit = true; /* vdPoints.push_back(-0.1); vdValues.push_back(1.3); vdPoints.push_back(0.0); vdValues.push_back(1.3); vdPoints.push_back(0.1); vdValues.push_back(1.2); vdPoints.push_back(0.2); vdValues.push_back(1.15); vdPoints.push_back(0.8); vdValues.push_back(0.85); vdPoints.push_back(0.9); vdValues.push_back(0.8); vdPoints.push_back(1.0); vdValues.push_back(0.7); vdPoints.push_back(1.1); vdValues.push_back(0.7);*/ /*vdPoints.push_back(-0.1); vdValues.push_back(1.1); vdPoints.push_back(0.0); vdValues.push_back(1.1); vdPoints.push_back(0.1); vdValues.push_back(1.07); vdPoints.push_back(0.2); vdValues.push_back(1.03); vdPoints.push_back(0.8); vdValues.push_back(0.97); vdPoints.push_back(0.9); vdValues.push_back(0.93); vdPoints.push_back(1.0); vdValues.push_back(0.9); vdPoints.push_back(1.1); vdValues.push_back(0.9);*/ /*vdPoints.push_back(-0.1); vdValues.push_back(1.3); vdPoints.push_back(0.0); vdValues.push_back(1.3); vdPoints.push_back(0.1); vdValues.push_back(1.15); vdPoints.push_back(0.2); vdValues.push_back(1.03); vdPoints.push_back(0.8); vdValues.push_back(0.95); vdPoints.push_back(0.9); vdValues.push_back(0.9); vdPoints.push_back(1.0); vdValues.push_back(0.8); vdPoints.push_back(1.1); vdValues.push_back(0.8);*/ vdPoints.push_back(-0.1); vdValues.push_back(1.03); vdPoints.push_back(0.0); vdValues.push_back(1.03); vdPoints.push_back(0.1); vdValues.push_back(1.02); vdPoints.push_back(0.2); vdValues.push_back(1.01); vdPoints.push_back(0.8); vdValues.push_back(0.95); vdPoints.push_back(0.9); vdValues.push_back(0.9); vdPoints.push_back(1.0); vdValues.push_back(0.8); vdPoints.push_back(1.1); vdValues.push_back(0.8); SIZE = cSize(vdPoints); //findFont(); } #if 1 for (int i = 0; i < SIZE; ++i) { double x0 (vdPoints[i]), y0 (vdValues[i]), x1 (vdPoints[i + 1]), y1 (vdValues[i + 1]); double x; x = dStart; if (x0 <= x && x < x1) { double y (y0 + (y1 - y0)*(x - x0)/(x1 - x0)); grad.setColorAt((x - dStart)/(dEnd - dStart), col.lighter(int(100*y))); } if (dStart < x0 && x0 < dEnd) { grad.setColorAt((x0 - dStart)/(dEnd - dStart), col.lighter(int(100*y0))); } x = dEnd; if (x < x1) { double y (y0 + (y1 - y0)*(x - x0)/(x1 - x0)); grad.setColorAt((x - dStart)/(dEnd - dStart), col.lighter(int(100*y))); break; } } #else grad.setColorAt(0, col.lighter(dStart < 0.0001 ? 119 : 100)); //ttt2 perhaps use this or at least add an option grad.setColorAt(0.48, col); grad.setColorAt(0.52, col); grad.setColorAt(1, col.lighter(dEnd > 0.9999 ? 80 : 100)); #endif } vector<QString> getLocalHelpDirs() { static vector<QString> s_v; if (s_v.empty()) { #ifndef WIN32 s_v.push_back("/home/ciobi/cpp/Mp3Utils/mp3diags/doc/html/"); s_v.push_back("/usr/share/mp3diags-doc/html/"); s_v.push_back("/usr/share/doc/mp3diags/html/"); s_v.push_back("/usr/share/doc/mp3diags-1.0.12.079/html/"); #else wchar_t wszModule [200]; int nRes (GetModuleFileName(0, wszModule, 200)); //qDebug("%s", QString::fromWCharArray(wszModule).toUtf8().constData()); if (0 < nRes && nRes < 200) { s_v.push_back(QFileInfo( fromNativeSeparators(QString::fromWCharArray(wszModule))).dir().absolutePath() + "/doc/"); //qDebug("%s", s_v.back().toUtf8().constData()); } #endif } return s_v; } // opens a web page from the documentation in the default browser; // first looks in several places on the local computer; if the file can't be found there, it goes to SourceForge void openHelp(const string& strFileName) { const vector<QString>& v (getLocalHelpDirs()); QString strDir; for (int i = 0; i < cSize(v); ++i) { if (QFileInfo(v[i] + convStr(strFileName)).isFile()) { strDir = v[i]; break; } } QString qs (strDir); if (qs.isEmpty()) { qs = "http://mp3diags.sourceforge.net/"; //ttt1 different for "unstable" } else { qs = QUrl::fromLocalFile(qs).toString(); } qs = qs + convStr(strFileName); //qDebug("open %s", qs.toUtf8().constData()); //logToGlobalFile(qs.toUtf8().constData()); CursorOverrider ovr; QDesktopServices::openUrl(QUrl(qs, QUrl::TolerantMode)); } // meant for displaying tooltips; converts some spaces to \n, so the tooltips have several short lines instead of a single wide line QString makeMultiline(const char* szDescr) //ttt2 param should probably be changed for localized versions, so this takes and returns QString { QString s (szDescr); int SIZE (50); for (int i = SIZE; i < s.size(); ++i) { if (' ' == s[i]) { s[i] = '\n'; i += SIZE; } } return s; } QString toNativeSeparators(const QString& s) { return QDir::toNativeSeparators(s); } QString fromNativeSeparators(const QString& s) { return QDir::fromNativeSeparators(s); } QString getTempDir() { /* #ifndef WIN32 return "/tmp"; #else wchar_t wszTmp [200]; if (GetTempPath(200, wszTmp) > 1999) { return ""; } return QString::fromWCharArray(wszTmp); #endif*/ static QString s; // ttt3 these static variables are not really thread safe, but in this case it doesn't matter, because they all get called from a single thread (the UI thread) if (s.isEmpty()) { s = QDir::tempPath(); if (s.endsWith(getPathSep())) { s.remove(s.size() - 1, 1); } } return s; } //============================================================================================= //============================================================================================= //============================================================================================= Tracer::Tracer(const std::string& s) : m_s(s) { traceToFile("> " + s, 1); } Tracer::~Tracer() { traceToFile(" < " + m_s, -1); } //============================================================================================= LastStepTracer::LastStepTracer(const std::string& s) : m_s(s) { traceLastStep("> " + s, 1); } LastStepTracer::~LastStepTracer() { traceLastStep(" < " + m_s, -1); } //============================================================================================= //============================================================================================= //============================================================================================= //ttt2 F1 help was very slow on XP once, not sure why; later it was OK ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/TagEditorDlgImpl.cpp��������������������������������������������������������0000644�0001750�0000144�00000220660�11500504142�017110� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <algorithm> #include <QScrollArea> #include <QScrollBar> #include <QPainter> #include <QTimer> #include <QKeyEvent> #include <QHeaderView> #include "TagEditorDlgImpl.h" #include "Helpers.h" #include "TagWriter.h" #include "DataStream.h" #include "CommonData.h" #include "ConfigDlgImpl.h" #include "ColumnResizer.h" #include "TagEdtPatternsDlgImpl.h" #include "DiscogsDownloader.h" #include "MusicBrainzDownloader.h" #include "ImageInfoPanelWdgImpl.h" #include "PaletteDlgImpl.h" #include "Id3V230Stream.h" #include "Id3V240Stream.h" #include "MpegStream.h" #include "Widgets.h" #include "Transformation.h" #include "Mp3TransformThread.h" #include "StoredSettings.h" #include "Mp3Manip.h" #include "OsFile.h" using namespace std; using namespace pearl; using namespace TagEditor; //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== CurrentAlbumModel::CurrentAlbumModel(TagEditorDlgImpl* pTagEditorDlgImpl) : m_pTagEditorDlgImpl(pTagEditorDlgImpl), m_pTagWriter(pTagEditorDlgImpl->getTagWriter()), m_pCommonData(pTagEditorDlgImpl->getCommonData()) { } /*override*/ int CurrentAlbumModel::rowCount(const QModelIndex&) const { //qDebug("rowCount ret %d", cSize(m_pTagWriter->m_vpMp3HandlerTagData)); return cSize(m_pTagWriter->m_vpMp3HandlerTagData); } /*override*/ int CurrentAlbumModel::columnCount(const QModelIndex&) const { return TagReader::LIST_END + 1; } /*override*/ QVariant CurrentAlbumModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("CurrentAlbumModel::data()"); if (!index.isValid()) { return QVariant(); } int i (index.row()); int j (index.column()); //qDebug("ndx %d %d", i, j); if (Qt::DisplayRole != nRole && Qt::ToolTipRole != nRole && Qt::EditRole != nRole) { return QVariant(); } QString s; if (m_pTagEditorDlgImpl->isSaving()) { return "N/A"; } if (m_pTagEditorDlgImpl->isNavigating()) { return ""; } if (0 == j) { const Mp3Handler* p (m_pTagWriter->m_vpMp3HandlerTagData[i]->getMp3Handler()); s = convStr(p->getShortName()); } else { /*const Mp3HandlerTagData& d (*m_pTagWriter->m_vpMp3HandlerTagData[i]); s = convStr(d.getData(TagReader::FEATURE_ON_POS[j - 1]));*/ s = convStr(m_pTagWriter->getData(i, TagReader::FEATURE_ON_POS[j - 1])); } if (Qt::DisplayRole == nRole || Qt::EditRole == nRole) { return s; } QFontMetrics fm (m_pTagEditorDlgImpl->m_pCurrentAlbumG->fontMetrics()); // !!! no need to use "QApplication::fontMetrics()" int nWidth (fm.width(s)); int nMargin (QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1); // this "1" should probably be another "metric" constant if (nWidth + 2*nMargin + 1 <= m_pTagEditorDlgImpl->m_pCurrentAlbumG->horizontalHeader()->sectionSize(j)) // ttt2 not sure this "nMargin" is correct { //return QVariant(); return ""; // !!! with "return QVariant()" the previous tooltip remains until the cursor moves over another cell that has a tooltip } return s; } //ttt2 perhaps: "right click on crt file header moves to last; left click moves to first"; dragging the columns seems ok, though /*override*/ QVariant CurrentAlbumModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("CurrentAlbumModel::headerData"); if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { if (0 == nSection) { return "File name"; } return TagReader::getLabel(TagReader::FEATURE_ON_POS[nSection - 1]); } return nSection + 1; } /*override*/ Qt::ItemFlags CurrentAlbumModel::flags(const QModelIndex& /*index*/) const { return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; } /*override*/ bool CurrentAlbumModel::setData(const QModelIndex& index, const QVariant& value, int nRole /*= Qt::EditRole*/) { if (Qt::EditRole != nRole) { return false; } Mp3HandlerTagData* pData (m_pTagWriter->m_vpMp3HandlerTagData[index.row()]); try { pData->setData(TagReader::FEATURE_ON_POS[index.column() - 1], convStr(value.toString())); m_pTagEditorDlgImpl->updateAssigned(); return true; } catch (const Mp3HandlerTagData::InvalidValue&) { QMessageBox::critical(m_pTagEditorDlgImpl, "Error", "The data contained errors and couldn't be saved"); //ttt2 put focus on album table return false; // ttt2 if it gets here the data is lost; perhaps CurrentAlbumDelegate should be modified more extensively, to not close the editor on Enter if this returns false; } } //====================================================================================================================== //====================================================================================================================== CurrentFileModel::CurrentFileModel(const TagEditorDlgImpl* pTagEditorDlgImpl) : m_pTagEditorDlgImpl(pTagEditorDlgImpl), m_pTagWriter(pTagEditorDlgImpl->getTagWriter()), m_pCommonData(pTagEditorDlgImpl->getCommonData()) { } /*override*/ int CurrentFileModel::rowCount(const QModelIndex&) const { return TagReader::LIST_END; } /*override*/ int CurrentFileModel::columnCount(const QModelIndex&) const { return cSize(m_pTagWriter->m_vTagReaderInfo); } /*override*/ QVariant CurrentFileModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("CurrentFileModel::data()"); if (!index.isValid() || 0 == m_pTagWriter->getCurrentHndl()) { return QVariant(); } int i (index.row()); int j (index.column()); if (Qt::DisplayRole != nRole && Qt::ToolTipRole != nRole) { return QVariant(); } if (m_pTagEditorDlgImpl->isSaving()) { return "N/A"; } if (m_pTagEditorDlgImpl->isNavigating()) { return ""; } if (0 == m_pTagWriter->getCurrentHndl()) { return QVariant(); } // may happen in transient states (prev/next album) const Mp3HandlerTagData& d (*m_pTagWriter->getCrtMp3HandlerTagData()); string s1 (d.getData(TagReader::FEATURE_ON_POS[i], j)); QString s (convStr(s1)); if (Qt::DisplayRole == nRole) { return s; } QFontMetrics fm (m_pTagEditorDlgImpl->m_pCurrentFileG->fontMetrics()); // !!! no need to use "QApplication::fontMetrics()" int nWidth (fm.width(s)); int nMargin (QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1); // this "1" should probably be another "metric" constant if (nWidth + 2*nMargin + 1 <= m_pTagEditorDlgImpl->m_pCurrentFileG->horizontalHeader()->sectionSize(j)) // ttt2 not sure this "nMargin" is correct { //return QVariant(); return ""; // !!! with "return QVariant()" the previous tooltip remains until the cursor moves over another cell that has a tooltip } return s; } /*override*/ QVariant CurrentFileModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("CurrentFileModel::headerData"); //if (nRole == Qt::SizeHintRole) { return QSize(CELL_WIDTH - 1, CELL_HEIGHT); } if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { if (nSection >= cSize(m_pTagWriter->m_vTagReaderInfo)) { return QVariant(); } QString sSuff; const TagReaderInfo& inf (m_pTagWriter->m_vTagReaderInfo.at(nSection)); if ( 0 != m_pTagWriter->getCrtMp3HandlerTagData() && ( TrackTextReader::getClassDisplayName() == inf.m_strName || WebReader::getClassDisplayName() == inf.m_strName ) ) { const TagReader* p (m_pTagWriter->getCrtMp3HandlerTagData()->getMatchingReader(nSection)); if (0 != p) { if (TrackTextReader::getClassDisplayName() == inf.m_strName) { const TrackTextReader* pRd (dynamic_cast<const TrackTextReader*>(p)); CB_ASSERT (0 != pRd); sSuff = QString(" ") + pRd->getType(); } else if (WebReader::getClassDisplayName() == inf.m_strName) { const WebReader* pRd (dynamic_cast<const WebReader*>(p)); CB_ASSERT (0 != pRd); sSuff = " (" + convStr(pRd->getType()) + ")"; } } } QString s; if (inf.m_bAlone) { s = convStr(inf.m_strName) + sSuff; } else { s = QString("%1 %2").arg(convStr(inf.m_strName)).arg(inf.m_nPos + 1) + sSuff; } return s; } return TagReader::getLabel(TagReader::FEATURE_ON_POS[nSection]); } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== TagEditorDlgImpl::TagEditorDlgImpl(QWidget* pParent, CommonData* pCommonData, TransfConfig& transfConfig, bool& bDataSaved) : QDialog(pParent, getDialogWndFlags()), Ui::TagEditorDlg(), m_pCommonData(pCommonData), m_bSectionMovedLock(false), m_transfConfig(transfConfig), m_bIsFastSaving(false), m_bIsSaving(false), m_bIsNavigating(false), m_bDataSaved(bDataSaved), m_bWaitingAlbumResize(false), m_bWaitingFileResize(false), m_eArtistsCase(TC_NONE), m_eOthersCase(TC_NONE) { setupUi(this); m_bDataSaved = false; setupVarArtistsBtn(); m_pAssgnBtnWrp = new AssgnBtnWrp (m_pToggleAssignedB); { m_pTagWriter = new TagWriter(m_pCommonData, this, m_bIsFastSaving, m_eArtistsCase, m_eOthersCase); loadTagWriterInf(); connect(m_pTagWriter, SIGNAL(albumChanged()), this, SLOT(onAlbumChanged())); connect(m_pTagWriter, SIGNAL(fileChanged()), this, SLOT(onFileChanged())); connect(m_pTagWriter, SIGNAL(imagesChanged()), this, SLOT(onImagesChanged())); connect(m_pTagWriter, SIGNAL(requestSave()), this, SLOT(on_m_pSaveB_clicked())); connect(m_pTagWriter, SIGNAL(varArtistsUpdated(bool)), this, SLOT(onVarArtistsUpdated(bool))); } m_pCurrentAlbumModel = new CurrentAlbumModel(this); m_pCurrentFileModel = new CurrentFileModel(this); { m_pCurrentAlbumG->verticalHeader()->setResizeMode(QHeaderView::Interactive); m_pCurrentAlbumG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pCurrentAlbumG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT);//*/ m_pCurrentAlbumG->setModel(m_pCurrentAlbumModel); m_pAlbumDel = new CurrentAlbumDelegate(m_pCurrentAlbumG, this); m_pCurrentAlbumG->setItemDelegate(m_pAlbumDel); //connect(m_pCurrentAlbumG, SIGNAL(clicked(const QModelIndex &)), this, SLOT(onAlbSelChanged())); // ttt2 see if both this and next are needed (next seems enough) connect(m_pCurrentAlbumG->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(onAlbSelChanged())); connect(m_pCurrentAlbumG->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex &)), this, SLOT(onAlbCrtChanged())); } { m_pCurrentFileG->setVerticalHeader(new NoCropHeaderView(m_pCurrentFileG)); m_pCurrentFileG->verticalHeader()->setResizeMode(QHeaderView::Interactive); m_pCurrentFileG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pCurrentFileG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT);//*/ m_pCurrentFileG->setModel(m_pCurrentFileModel); CurrentFileDelegate* pDel (new CurrentFileDelegate(m_pCurrentFileG, m_pCommonData)); connect(m_pCurrentFileG->horizontalHeader(), SIGNAL(sectionMoved(int, int, int)), this, SLOT(onFileSelSectionMoved(int, int, int))); m_pCurrentFileG->setItemDelegate(pDel); m_pCurrentFileG->horizontalHeader()->setMovable(true); } { int nWidth, nHeight; int nArtistsCase, nOthersCase; m_pCommonData->m_settings.loadTagEdtSettings(nWidth, nHeight, nArtistsCase, nOthersCase); m_eArtistsCase = TextCaseOptions(nArtistsCase); m_eOthersCase = TextCaseOptions(nOthersCase); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } else { defaultResize(*this); } } { delete m_pRemovable1L; // m_pRemovableL's only job is to make m_pImagesW visible in QtDesigner QWidget* pWidget (new QWidget (this)); pWidget->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); QHBoxLayout* pScrlLayout (new QHBoxLayout (pWidget)); pWidget->setLayout(pScrlLayout); pWidget->layout()->setContentsMargins(0, 0, 0, 4 + 1); // "+1" added to look better, but don't know how to calculate m_pImgScrollArea = new QScrollArea (m_pImagesW); m_pImagesW->layout()->addWidget(m_pImgScrollArea); m_pImgScrollArea->setWidget(pWidget); m_pImgScrollArea->setFrameShape(QFrame::NoFrame); } { delete m_pRemovable2L; // m_pRemovable2L's only job is to make m_pPatternsW visible in QtDesigner createPatternButtons(); } //layout()->update(); /*layout()->update(); widget_4->layout()->update(); widget->layout()->update(); layout()->update(); widget_4->layout()->update(); widget->layout()->update();*/ m_pTagWriter->reloadAll("", TagWriter::CLEAR_DATA, TagWriter::CLEAR_ASSGN); selectMainCrt(); resizeIcons(); m_pCurrentAlbumG->installEventFilter(this); installEventFilter(this); { int nFileHght ((CELL_HEIGHT)*10 + m_pCurrentFileG->horizontalHeader()->height() + 2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, m_pCurrentFileG)); m_pCurrentFileG->setMaximumHeight(nFileHght); m_pCurrentFileG->setMinimumHeight(nFileHght); } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } QTimer::singleShot(1, this, SLOT(onShow())); // just calls resizeTagEditor(); !!! needed to properly resize the table columns; album and file tables have very small widths until they are actually shown, so calling resizeTagEditor() earlier is pointless; calling update() on various layouts seems pointless as well; (see also DoubleList::resizeEvent() ) } void TagEditorDlgImpl::createPatternButtons() { QBoxLayout* pLayout (dynamic_cast<QBoxLayout*>(m_pPatternsW->layout())); CB_ASSERT (0 != pLayout); QObjectList l (m_pPatternsW->children()); for (int i = 0, n = l.size(); i < n; ++i) { if (l[i] != pLayout) { delete l[i]; } } const set<int>& snActivePatterns (m_pTagWriter->getActivePatterns()); m_vpPattButtons.clear(); const vector<string>& vstrPatterns (m_pTagWriter->getPatterns()); int n (cSize(vstrPatterns)); for (int i = 0; i < n; ++i) { QToolButton* p (new QToolButton(m_pPatternsW)); p->setText(toNativeSeparators(convStr(vstrPatterns[i]))); p->setCheckable(true); m_vpPattButtons.push_back(p); if (snActivePatterns.count(i) > 0) { p->setChecked(true); } connect(p, SIGNAL(clicked()), this, SLOT(onPatternClicked())); pLayout->insertWidget(i, p); } pLayout->insertStretch(n); m_pPatternsW->setVisible(!m_vpPattButtons.empty()); } void TagEditorDlgImpl::onPatternClicked() { set<int> s; for (int i = 0; i < cSize(m_vpPattButtons); ++i) { if (m_vpPattButtons[i]->isChecked()) { s.insert(i); } } m_pTagWriter->setActivePatterns(s); } TagEditorDlgImpl::~TagEditorDlgImpl() { saveTagWriterInf(); m_pCommonData->m_settings.saveTagEdtSettings(width(), height(), int(m_eArtistsCase), int(m_eOthersCase)); delete m_pCurrentAlbumModel; delete m_pCurrentFileModel; delete m_pTagWriter; delete m_pAssgnBtnWrp; } string TagEditorDlgImpl::run() { TRACER("TagEditorDlgImpl::run()"); exec(); return m_pTagWriter->getCurrentName(); } void TagEditorDlgImpl::setupVarArtistsBtn() { m_pVarArtistsB->setEnabled(m_pCommonData->m_bItunesVarArtists || m_pCommonData->m_bWmpVarArtists); m_pVarArtistsB->setToolTip(m_pVarArtistsB->isEnabled() ? "Toggle \"Various Artists\"" : "To enable \"Various Artists\" you need to open the\n" "configuration dialog, go to the \"Others\" tab and\n" "check the corresponding checkbox(es)"); } void TagEditorDlgImpl::resizeTagEditor() { if (!m_bWaitingAlbumResize) { m_bWaitingAlbumResize = true; QTimer::singleShot(1, this, SLOT(onResizeTagEditorDelayed())); } } void TagEditorDlgImpl::onResizeTagEditorDelayed() // needed because it's pointless to call this while navigating, when the text for all cells is returned as "" { m_bWaitingAlbumResize = false; QWidget* pParent (m_pCurrentAlbumG->parentWidget()); //cout << "\n========================\n" << endl; listWidget(pParent); m_pImgScrollArea->widget()->adjustSize(); //m_pImgScrollArea->adjustSize(); int nHeight (m_pImgScrollArea->widget()->height() /*+ 10*/); if (m_pImgScrollArea->widget()->width() > m_pImgScrollArea->width()) { int nScrollBarWidth (QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent)); /*if (0 != QApplication::style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) // see if this is needed for Oxygen { nRes -= 2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, &m_tbl); //ttt2 Qt 4.4 (and below) - specific; in 4.5 there's a QStyle::PM_ScrollView_ScrollBarSpacing }*/ nHeight += nScrollBarWidth; } m_pImagesW->setMaximumSize(100000, nHeight); // ttt2 see about adding space for horizontal scrollbar pParent->layout()->activate(); // resize m_pCurrentAlbumG based on the image list being visible or not m_pCurrentAlbumModel->emitLayoutChanged(); // !!! force recalculation of the vertical scrollbar's visibility //m_pCurrentAlbumG->horizontalHeader()->hideSection(1); SimpleQTableViewWidthInterface intf1 (*m_pCurrentAlbumG); /*intf1.setMinWidth(2, 600); intf1.setMinWidth(0, 50); intf1.setMinWidth(1, 50);*/ /*intf1.setFixedWidth(0, 50); intf1.setFixedWidth(1, 50); intf1.setFixedWidth(2, 50); intf1.setFixedWidth(3, 50); intf1.setFixedWidth(4, 50); intf1.setFixedWidth(5, 50);*/ ColumnResizer rsz1 (intf1, 100, ColumnResizer::FILL, ColumnResizer::CONSISTENT_RESULTS); resizeFile(); } void TagEditorDlgImpl::resizeFile() // resizes the "current file" grid; called by resizeTagEditor() and by onFileChanged(); { if (!m_bWaitingFileResize) { m_bWaitingFileResize = true; QTimer::singleShot(1, this, SLOT(onResizeFileDelayed())); } } void TagEditorDlgImpl::onResizeFileDelayed() // resizes the "current file" grid; called by resizeTagEditor() and by onFileChanged(); { m_bWaitingFileResize = false; SimpleQTableViewWidthInterface intf2 (*m_pCurrentFileG); ColumnResizer rsz2 (intf2, 100, ColumnResizer::DONT_FILL, ColumnResizer::CONSISTENT_RESULTS); } /*override*/ void TagEditorDlgImpl::resizeEvent(QResizeEvent* pEvent) { resizeTagEditor(); QDialog::resizeEvent(pEvent); } void TagEditorDlgImpl::on_m_pQueryDiscogsB_clicked() { if (!closeEditor()) { return; } /*QPixmap pic ("/r/temp/1/tmp2/c pic/b/A/cg.jpg"); ImageInfo img (ImageInfo::OK, pic); m_pCommonData->m_imageColl.addImage(img); onTagWriterChanged(); //m_pCurrentAlbumG->adjustSize(); m_pTagWriter->resizeCols(); return;//*/ AlbumInfo* pAlbumInfo; ImageInfo* pImageInfo; bool bOk; { DiscogsDownloader dlg (this, m_pCommonData->m_settings, m_pCommonData->m_bSaveDownloadedData); //dlg.exec(); //dlg.getInfo("Beatles", "Help"); //dlg.getInfo("Roxette", "Tourism"); //if (dlg.getInfo("Kaplansky", "", 12, pAlbumInfo, pImageInfo)) string strArtist, strAlbum; m_pTagWriter->getAlbumInfo(strArtist, strAlbum); bOk = dlg.getInfo(strArtist, strAlbum, cSize(m_pTagWriter->m_vpMp3HandlerTagData), pAlbumInfo, pImageInfo); // !!! it's important that the dialog is in an enclosed scope; otherwise column resizing doesn't work well or m_pCurrentAlbumG gets shrinked to a really small size } if (bOk) { int nImgPos (-1); if (0 != pImageInfo) { nImgPos = m_pTagWriter->addImage(*pImageInfo, 0 == pAlbumInfo ? TagWriter::CONSIDER_UNASSIGNED : TagWriter::CONSIDER_ASSIGNED); delete pImageInfo; } if (0 != pAlbumInfo) { if (-1 != nImgPos) { pAlbumInfo->m_imageInfo = m_pTagWriter->getImageColl()[nImgPos].m_imageInfo; } pAlbumInfo->m_strSourceName = "Discogs"; m_pTagWriter->addAlbumInfo(*pAlbumInfo); delete pAlbumInfo; } //onTagWriterChanged(); // also calls resizeTagEditor(); } } void TagEditorDlgImpl::on_m_pQueryMusicBrainzB_clicked() { if (!closeEditor()) { return; } AlbumInfo* pAlbumInfo; ImageInfo* pImageInfo; bool bOk; { MusicBrainzDownloader dlg (this, m_pCommonData->m_settings, m_pCommonData->m_bSaveDownloadedData); //dlg.exec(); //dlg.getInfo("Beatles", "Help"); //dlg.getInfo("Roxette", "Tourism"); //if (dlg.getInfo("Kaplansky", "", 12, pAlbumInfo, pImageInfo)) string strArtist, strAlbum; m_pTagWriter->getAlbumInfo(strArtist, strAlbum); bOk = dlg.getInfo(strArtist, strAlbum, cSize(m_pTagWriter->m_vpMp3HandlerTagData), pAlbumInfo, pImageInfo); // !!! it's important that the dialog is in an enclosed scope; otherwise column resizing doesn't work well or m_pCurrentAlbumG gets shrinked to a really small size } if (bOk) { int nImgPos (-1); if (0 != pImageInfo) { nImgPos = m_pTagWriter->addImage(*pImageInfo, 0 == pAlbumInfo ? TagWriter::CONSIDER_UNASSIGNED : TagWriter::CONSIDER_ASSIGNED); //resizeTagEditor(); delete pImageInfo; } if (0 != pAlbumInfo) { if (-1 != nImgPos) { pAlbumInfo->m_imageInfo = m_pTagWriter->getImageColl()[nImgPos].m_imageInfo; } pAlbumInfo->m_strSourceName = "MusicBrainz"; m_pTagWriter->addAlbumInfo(*pAlbumInfo); delete pAlbumInfo; } //onTagWriterChanged(); // also calls resizeTagEditor(); } } void TagEditorDlgImpl::on_m_pEditPatternsB_clicked() { if (!closeEditor()) { return; } vector<pair<string, int> > v; vector<string> v1 (m_pTagWriter->getPatterns()); for (int i = 0, n = cSize(v1); i < n; ++i) { v.push_back(make_pair(v1[i], -1)); } vector<string> u; //u.push_back("%a/%b[[ ](%y)]/[[%r]%n][ ][-[ ]]%t"); /*u.push_back("%a/%b[[ ](%y)]/[[%r]%n][.][ ][-[ ]]%t"); //ttt OS specific u.push_back("%b[[ ](%y)]/[[%r]%n][.][ ]%a[ ]-[ ]%t"); u.push_back("%a - %b/[[%r]%n][.][ ][-[ ]]%t"); u.push_back("[%n][.][ ][-[ ]]%t");*/ u.push_back("%a/%b[(%y)]/[[%r]%n][.][ ][-]%t"); u.push_back("%b[(%y)]/[[%r]%n][.]%a-%t"); u.push_back("%a-%b/[[%r]%n][.][ ][-]%t"); u.push_back("/%n[.]%a-%t"); u.push_back("[%n][.][ ][-]%t"); TagEdtPatternsDlgImpl dlg (this, m_pCommonData->m_settings, u); if (dlg.run(v)) { m_pTagWriter->updatePatterns(v); createPatternButtons(); } } void TagEditorDlgImpl::on_m_pPaletteB_clicked() { if (!closeEditor()) { return; } PaletteDlgImpl dlg (m_pCommonData, this); dlg.exec(); m_pCommonData->m_settings.saveMiscConfigSettings(m_pCommonData); } // adds new ImageInfoPanelWdgImpl instances, connects assign button and calls resizeTagEditor() void TagEditorDlgImpl::onImagesChanged() { QLayout* pLayout (m_pImgScrollArea->widget()->layout()); const ImageColl& imgColl (m_pTagWriter->getImageColl()); int nVecCnt (imgColl.size()); int nPanelCnt (pLayout->count()); CB_ASSERT (nVecCnt >= nPanelCnt); for (int i = nPanelCnt; i < nVecCnt; ++i) { ImageInfoPanelWdgImpl* p (new ImageInfoPanelWdgImpl(this, imgColl[i], i)); pLayout->addWidget(p); p->show(); connect(p, SIGNAL(assignImage(int)), m_pTagWriter, SLOT(onAssignImage(int))); connect(p, SIGNAL(eraseFile(int)), m_pTagWriter, SLOT(onEraseFile(int))); m_pTagWriter->addImgWidget(p); } resizeTagEditor(); } void TagEditorDlgImpl::onVarArtistsUpdated(bool bVarArtists) { static QPixmap picSa (":/images/va_sa.svg"); static QPixmap picVa (":/images/va_va.svg"); m_pVarArtistsB->setIcon(bVarArtists ? picVa : picSa); } void TagEditorDlgImpl::onAlbumChanged(/*bool bContentOnly*/) { if (m_pTagWriter->m_vpMp3HandlerTagData.empty()) { // there were some files, the transform settings caused the files to be removed when saving; close the dialog; reject(); return; } resizeTagEditor(); m_pCurrentAlbumModel->emitLayoutChanged(); const Mp3Handler* p (m_pTagWriter->m_vpMp3HandlerTagData.at(0)->getMp3Handler()); QString qs (toNativeSeparators(convStr(p->getDir()))); #ifndef WIN32 #else if (2 == qs.size() && ':' == qs[1]) { qs += "\\"; } #endif m_pCrtDirTagEdtE->setText(qs); } void TagEditorDlgImpl::on_m_pConfigB_clicked() { if (!closeEditor()) { return; } SaveOpt eSaveOpt (save(IMPLICIT)); if (SAVED != eSaveOpt && DISCARDED != eSaveOpt) { return; } ConfigDlgImpl dlg (m_transfConfig, m_pCommonData, this, ConfigDlgImpl::SOME_TABS); if (dlg.run()) { m_pCommonData->m_settings.saveMiscConfigSettings(m_pCommonData); m_pCommonData->m_settings.saveTransfConfig(m_transfConfig); // transformation resizeIcons(); resizeTagEditor(); } m_pTagWriter->reloadAll("", TagWriter::CLEAR_DATA, TagWriter::CLEAR_ASSGN); // !!! regardless of the conf being cancelled, so it's consistent with the question asked at the beginning setupVarArtistsBtn(); } void TagEditorDlgImpl::onFileChanged() { m_pCurrentFileModel->emitLayoutChanged(); const Mp3HandlerTagData* p (m_pTagWriter->getCrtMp3HandlerTagData()); if (0 != p) { int nPic (p->getImage()); m_pTagWriter->selectImg(nPic); } //resizeTagEditor(); resizeFile(); } //======================================================================================================================================================== //======================================================================================================================================================== //======================================================================================================================================================== void TagEditorDlgImpl::loadTagWriterInf() { { // tags m_pTagWriter->clearShowedNonSeqWarn(); bool bErr1 (false), bErr2 (false); vector<string> vstrNames (m_pCommonData->m_settings.loadVector("tagWriter/tagNames", bErr1)); vector<string> vstrPositions (m_pCommonData->m_settings.loadVector("tagWriter/tagPositions", bErr2)); vector<TagReaderInfo> v; int n (min(cSize(vstrNames), cSize(vstrPositions))); for (int i = 0; i < n; ++i) { string strName (vstrNames[i]); int nPos (atoi(vstrPositions[i].c_str())); if (strName.empty() || nPos < 0) // ttt2 the test for nPos can be improved; we know that a value was found in the file, but it may even be non-numeric { bErr1 = true; break; } // ttt2 perhaps fix duplicate or missing positions, but it's no big deal; TagWriter takes care of duplicates itself and if something is missing it will get added back when needed v.push_back(TagReaderInfo(strName, nPos, TagReaderInfo::ONE_OF_MANY)); } if (bErr1 || bErr2) { QMessageBox::warning(this, "Error setting up the tag order", "An invalid value was found in the configuration file. You'll have to sort the tags again."); } if (v.empty()) { // use default v.push_back(TagReaderInfo(Id3V230Stream::getClassDisplayName(), 0, TagReaderInfo::ONE_OF_MANY)); v.push_back(TagReaderInfo(Id3V230Stream::getClassDisplayName(), 1, TagReaderInfo::ONE_OF_MANY)); v.push_back(TagReaderInfo(Id3V240Stream::getClassDisplayName(), 0, TagReaderInfo::ONE_OF_MANY)); v.push_back(TagReaderInfo(Id3V240Stream::getClassDisplayName(), 1, TagReaderInfo::ONE_OF_MANY)); v.push_back(TagReaderInfo(Id3V1Stream::getClassDisplayName(), 0, TagReaderInfo::ONE_OF_MANY)); v.push_back(TagReaderInfo(Id3V1Stream::getClassDisplayName(), 1, TagReaderInfo::ONE_OF_MANY)); } m_pTagWriter->addKnownInf(v); } { // pattern readers bool bErr (false); vector<string> vstrPatterns (m_pCommonData->m_settings.loadVector("tagWriter/patterns", bErr)); //if (bErr) { qDebug("error at loadVector(\"tagWriter/patterns\")"); } //ttt remove int n (cSize(vstrPatterns)); vector<pair<string, int> > v; { for (int i = 0; i < n; ++i) { string strPatt (vstrPatterns[i]); if (strPatt.empty()) { bErr = true; } v.push_back(make_pair(strPatt, -1)); } } /*if (v.empty()) { // use default (only if the user didn't remove all patterns on purpose) //v.push_back(make_pair(string("%a/%b[[ ](%y)]/[[%r]%n][ ][-[ ]]%t"), -1)); v.push_back(make_pair(string("%a/%b[[ ](%y)]/[[%r]%n][.][ ][-[ ]]%t"), -1)); //ttt OS specific v.push_back(make_pair(string("%b[[ ](%y)]/[[%r]%n][.][ ]%a[ ]-[ ]%t"), -1)); v.push_back(make_pair(string("%a - %b/[[%r]%n][.][ ][-[ ]]%t"), -1)); v.push_back(make_pair(string("[%n][.][ ][-[ ]]%t"), -1)); } else if (1 == cSize(v) && "*" == v[0].first) { v.clear(); }*/ bErr = !m_pTagWriter->updatePatterns(v) || bErr; bool bErr2; vector<string> vstrActivePatterns (m_pCommonData->m_settings.loadVector("tagWriter/activePatterns", bErr2)); set<int> snActivePatterns; for (int i = 0; i < cSize(vstrActivePatterns); ++i) { snActivePatterns.insert(atoi(vstrActivePatterns[i].c_str())); } m_pTagWriter->setActivePatterns(snActivePatterns); //if (bErr) { qDebug("error when reading patterns"); } //ttt remove if (bErr || bErr2) { QMessageBox::warning(this, "Error setting up patterns", "An invalid value was found in the configuration file. You'll have to set up the patterns manually."); } } } void TagEditorDlgImpl::saveTagWriterInf() { { vector<string> vstrNames, vstrPositions; const vector<TagReaderInfo>& v (m_pTagWriter->getSortedKnownTagReaders()); char a [15]; for (int i = 0, n = cSize(v); i < n; ++i) { vstrNames.push_back(v[i].m_strName); sprintf(a, "%d", v[i].m_nPos); vstrPositions.push_back(a); } m_pCommonData->m_settings.saveVector("tagWriter/tagNames", vstrNames); m_pCommonData->m_settings.saveVector("tagWriter/tagPositions", vstrPositions); } { vector<string> v (m_pTagWriter->getPatterns()); /*if (v.empty()) { v.push_back("*"); }*/ m_pCommonData->m_settings.saveVector("tagWriter/patterns", v); vector<string> u; char a [15]; const set<int>& snActivePatterns (m_pTagWriter->getActivePatterns()); for (set<int>::const_iterator it = snActivePatterns.begin(); it != snActivePatterns.end(); ++it) { sprintf(a, "%d", *it); u.push_back(a); } m_pCommonData->m_settings.saveVector("tagWriter/activePatterns", u); } } void TagEditorDlgImpl::on_m_pToggleAssignedB_clicked() { if (!closeEditor()) { return; } m_pAssgnBtnWrp->setState(m_pTagWriter->toggleAssigned(m_pAssgnBtnWrp->getState())); } void TagEditorDlgImpl::on_m_pReloadB_clicked() { if (!closeEditor()) { return; } bool bHasUnsavedAssgn (false); for (int i = 0, n = cSize(m_pTagWriter->m_vpMp3HandlerTagData); i < n; ++i) { bool bAssgn (false); bool bNonId3V2 (false); m_pTagWriter->hasUnsaved(i, bAssgn, bNonId3V2); bHasUnsavedAssgn = bHasUnsavedAssgn || bAssgn; } if (bHasUnsavedAssgn) { int k (showMessage(this, QMessageBox::Warning, 1, 1, "Warning", "Reloading the current album causes all unsaved changes to be lost. Really reload?", "Reload", "Cancel")); if (0 != k) { return; } } m_pTagWriter->reloadAll(m_pTagWriter->getCurrentName(), TagWriter::CLEAR_DATA, TagWriter::CLEAR_ASSGN); updateAssigned(); } //ttt2 perhaps transf to set recording time based on file date; another to set file date based on rec time // copies the values from the first row to the other rows for columns that have at least a cell selected (doesn't matter if more than 1 cells are selected); void TagEditorDlgImpl::on_m_pCopyFirstB_clicked() { if (!closeEditor()) { return; } m_pTagWriter->copyFirst(); } void TagEditorDlgImpl::on_m_pVarArtistsB_clicked() { if (!closeEditor()) { return; } m_pTagWriter->toggleVarArtists(); } void TagEditorDlgImpl::on_m_pCaseB_clicked() { QMenu menu; vector<QAction*> vpAct; QAction* pAct; for (int i = TC_NONE; i <= TC_SENTENCE; ++i) { pAct = new QAction(QString("Artists - ") + getCaseAsStr(TextCaseOptions(i)), &menu); menu.addAction(pAct); vpAct.push_back(pAct); } menu.addSeparator(); for (int i = TC_NONE; i <= TC_SENTENCE; ++i) { pAct = new QAction(QString("Others - ") + getCaseAsStr(TextCaseOptions(i)), &menu); menu.addAction(pAct); vpAct.push_back(pAct); } for (int i = 0; i < cSize(vpAct); ++i) { vpAct[i]->setCheckable(true); } CB_ASSERT(m_eArtistsCase >= TC_NONE && m_eArtistsCase <= TC_SENTENCE); CB_ASSERT(m_eOthersCase >= TC_NONE && m_eOthersCase <= TC_SENTENCE); vpAct[m_eArtistsCase - TC_NONE]->setChecked(true); vpAct[m_eOthersCase - TC_NONE + 5]->setChecked(true); QAction* p (menu.exec(m_pCaseB->mapToGlobal(QPoint(0, m_pCaseB->height())))); if (0 != p) { int nIndex (std::find(vpAct.begin(), vpAct.end(), p) - vpAct.begin()); if (nIndex < 5) { m_eArtistsCase = TextCaseOptions(nIndex - 1); } else { m_eOthersCase = TextCaseOptions(nIndex - 1 - 5); } m_pTagWriter->reloadAll(m_pTagWriter->getCurrentName(), TagWriter::DONT_CLEAR_DATA, TagWriter::DONT_CLEAR_ASSGN); } } void TagEditorDlgImpl::on_m_pSaveB_clicked() //ttt2 perhaps make this save selected list, by using SHIFT { if (!closeEditor()) { return; } save(EXPLICIT); //SaveOpt eRes save(true); /*if (SAVED == save(true)) { //m_pTagWriter->clearOrigVal(); }*/ } void TagEditorDlgImpl::on_m_pPasteB_clicked() { if (!closeEditor()) { return; } m_pTagWriter->paste(); } void TagEditorDlgImpl::on_m_pSortB_clicked() { if (!closeEditor()) { return; } clearSelection(); m_pTagWriter->sort(); //m_pCurrentAlbumModel->emitLayoutChanged(); } void TagEditorDlgImpl::onAlbSelChanged() { updateAssigned(); /*QItemSelectionModel* pSelModel (m_pCurrentAlbumG->selectionModel()); int n (pSelModel->currentIndex().row()); qDebug("onAlbSelChanged - CurrentFile=%d", n); m_pTagWriter->setCrt(n);*/ // !!! incorrect, because currentIndex() returns the previous index; that's why onAlbCrtChanged() is needed } void TagEditorDlgImpl::onAlbCrtChanged() { QItemSelectionModel* pSelModel (m_pCurrentAlbumG->selectionModel()); int n (pSelModel->currentIndex().row()); if (-1 == n) { return; } m_pTagWriter->setCrt(n); } void TagEditorDlgImpl::onFileSelSectionMoved(int /*nLogicalIndex*/, int nOldVisualIndex, int nNewVisualIndex) { NonblockingGuard sectionMovedGuard (m_bSectionMovedLock); if (!sectionMovedGuard) { return; } QItemSelectionModel* pSelModel (m_pCurrentAlbumG->selectionModel()); QModelIndex selNdx (pSelModel->currentIndex()); //QModelIndex topNdx (m_pCurrentAlbumG->indexAt(QPoint(0, 0))); int nHrzPos (m_pCurrentAlbumG->horizontalScrollBar()->value()); int nVertPos (m_pCurrentAlbumG->verticalScrollBar()->value()); m_pCurrentFileG->horizontalHeader()->moveSection(nNewVisualIndex, nOldVisualIndex); m_pTagWriter->moveReader(nOldVisualIndex, nNewVisualIndex); pSelModel->setCurrentIndex(selNdx, QItemSelectionModel::SelectCurrent); m_pCurrentAlbumG->horizontalScrollBar()->setValue(nHrzPos); m_pCurrentAlbumG->verticalScrollBar()->setValue(nVertPos); //ttt2 perhaps detect when files are removed/changed; while most tags in Id3V2 are stored with the handler, the longer ones (e.g. pictures, but others might be affected too) are dumped from memory by Id3V230Frame's constructor and retrieved from disk when needed; the user should be notified when something becomes unavailable; not sure where to do this, though: Id3V2StreamBase::getImage() is good for images, but other frames might need something similar; } void TagEditorDlgImpl::on_m_pNextB_clicked() { if (!closeEditor()) { return; } SaveOpt eSaveOpt (save(IMPLICIT)); if (SAVED != eSaveOpt && DISCARDED != eSaveOpt) { return; } if (m_pCommonData->nextAlbum()) { ValueRestorer<bool> rst1 (m_bIsNavigating); m_bIsNavigating = true; m_pTagWriter->clearShowedNonSeqWarn(); m_pTagWriter->reloadAll("", TagWriter::CLEAR_DATA, TagWriter::CLEAR_ASSGN); clearSelection(); // actually here it selects the first cell QTimer::singleShot(1, this, SLOT(onShowPatternNote())); } } void TagEditorDlgImpl::on_m_pPrevB_clicked() { if (!closeEditor()) { return; } SaveOpt eSaveOpt (save(IMPLICIT)); if (SAVED != eSaveOpt && DISCARDED != eSaveOpt) { return; } if (m_pCommonData->prevAlbum()) { ValueRestorer<bool> rst1 (m_bIsNavigating); m_bIsNavigating = true; m_pTagWriter->clearShowedNonSeqWarn(); m_pTagWriter->reloadAll("", TagWriter::CLEAR_DATA, TagWriter::CLEAR_ASSGN); clearSelection(); // actually here it selects the first cell QTimer::singleShot(1, this, SLOT(onShowPatternNote())); } } void TagEditorDlgImpl::clearSelection() { QItemSelectionModel* pSelModel (m_pCurrentAlbumG->selectionModel()); pSelModel->setCurrentIndex(m_pCurrentAlbumModel->index(0, 0), QItemSelectionModel::SelectCurrent); // !!! needed because otherwise pSelModel->clear() might trigger onAlbSelChanged() for an invalid cell (e.g. when current album has 15 songs, with 12th selected, and the next only has 10) pSelModel->clear(); pSelModel->setCurrentIndex(m_pCurrentAlbumModel->index(0, 0), QItemSelectionModel::SelectCurrent); // !!! needed to have a cell selected //ttt2 try and get rid of duplicate call to setCurrentIndex; } void TagEditorDlgImpl::selectMainCrt() // selects the song that is current in the main window (to be called on the constructor); { QItemSelectionModel* pSelModel (m_pCurrentAlbumG->selectionModel()); const Mp3Handler* pCrt (m_pCommonData->getCrtMp3Handler()); for (int i = 0, n = cSize(m_pTagWriter->m_vpMp3HandlerTagData); i < n; ++i) { const Mp3Handler* p (m_pTagWriter->m_vpMp3HandlerTagData[i]->getMp3Handler()); if (p == pCrt) { pSelModel->setCurrentIndex(m_pCurrentAlbumModel->index(i, 0), QItemSelectionModel::SelectCurrent); return; } } CB_ASSERT (false); } void TagEditorDlgImpl::updateAssigned() { m_pAssgnBtnWrp->setState(m_pTagWriter->updateAssigned(getSelFields())); } // returns the selceted fields, with the first elem as the song number and the second as the field index in TagReader::Feature (it converts columns to fields using TagReader::FEATURE_ON_POS); first column (file name) is ignored vector<pair<int, int> > TagEditorDlgImpl::getSelFields() const { QItemSelectionModel* pSelModel (m_pCurrentAlbumG->selectionModel()); QModelIndexList listSel (pSelModel->selectedIndexes()); vector<pair<int, int> > vFields; for (QModelIndexList::iterator it = listSel.begin(), end = listSel.end(); it != end; ++it) { QModelIndex ndx (*it); int nSong (ndx.row()); int nField (ndx.column()); if (nField > 0) { vFields.push_back(make_pair(nSong, TagReader::FEATURE_ON_POS[nField - 1])); } } return vFields; } void TagEditorDlgImpl::resizeIcons() { vector<QToolButton*> v; v.push_back(m_pPrevB); v.push_back(m_pNextB); v.push_back(m_pConfigB); v.push_back(m_pSaveB); v.push_back(m_pReloadB); v.push_back(m_pVarArtistsB); v.push_back(m_pCaseB); v.push_back(m_pCopyFirstB); v.push_back(m_pSortB); v.push_back(m_pToggleAssignedB); v.push_back(m_pPasteB); v.push_back(m_pEditPatternsB); v.push_back(m_pPaletteB); int k (m_pCommonData->m_nMainWndIconSize); for (int i = 0, n = cSize(v); i < n; ++i) { QToolButton* p (v[i]); p->setMaximumSize(k, k); p->setMinimumSize(k, k); p->setIconSize(QSize(k - 4, k - 4)); } { QToolButton* p (m_pQueryDiscogsB); int h ((k - 4)*2/3); //int w (h*135/49); int w (h*135/60); p->setMaximumSize(w + 4, k); p->setMinimumSize(w + 4, k); p->setIconSize(QSize(w, h)); } { QToolButton* p (m_pQueryMusicBrainzB); int h (k - 4); int w (h*171/118); p->setMaximumSize(w + 4, k); p->setMinimumSize(w + 4, k); p->setIconSize(QSize(w, h)); } } #if 0 /*override*/ bool TagEditorDlgImpl::eventFilter(QObject* pObj, QEvent* pEvent) { QKeyEvent* pKeyEvent (dynamic_cast<QKeyEvent*>(pEvent)); int nKey (0 == pKeyEvent ? 0 : pKeyEvent->key()); //static int s_nCnt (0); /*if (0 != pKeyEvent && Qt::Key_Escape == nKey) { qDebug("%d. %s %d", s_nCnt++, pObj->objectName().toUtf8().constData(), (int)pEvent->type()); //return QDialog::eventFilter(pObj, pEvent); }*/ static bool bIgnoreNextEsc (false); if (0 != pKeyEvent && Qt::Key_Escape == nKey && this == pObj && QEvent::ShortcutOverride == pEvent->type()) { //qDebug("kill esc"); //return true; //SaveOpt eSaveOpt (save(false)); if (SAVED != eSaveOpt && DISCARDED != eSaveOpt) { return true; } //if (this != pObj) { return true; } //qDebug("kill esc"); //return true; qDebug(" >> save"); //qDebug("%d. %s %d", s_nCnt++, pObj->objectName().toUtf8().constData(), (int)pEvent->type()); //return QDialog::eventFilter(pObj, pEvent); //if (this == pObj) { SaveOpt eSaveOpt (save(false)); if (SAVED == eSaveOpt || DISCARDED == eSaveOpt) { //bIgnoreNextEsc = false; goto e1; } } //qDebug(" ###### save"); //SaveOpt eSaveOpt (save(false)); if (SAVED != eSaveOpt && DISCARDED != eSaveOpt) { return true; } bIgnoreNextEsc = true; return true; } //if (0 == pKeyEvent || Qt::Key_Escape != nKey) { return QDialog::eventFilter(pObj, pEvent); } e1: if (0 != pKeyEvent && Qt::Key_Escape == nKey) { //qDebug("passed through: %d. %s %d", s_nCnt++, pObj->objectName().toUtf8().constData(), (int)pEvent->type()); } if (0 != pKeyEvent && Qt::Key_Escape == nKey && this == pObj && QEvent::KeyPress == pEvent->type()) { bool b (bIgnoreNextEsc); bIgnoreNextEsc = false; if (b) { qDebug(" KILL"); return true; } } return QDialog::eventFilter(pObj, pEvent); } #endif /*override*/ bool TagEditorDlgImpl::eventFilter(QObject* pObj, QEvent* pEvent) { QKeyEvent* pKeyEvent (dynamic_cast<QKeyEvent*>(pEvent)); int nKey (0 == pKeyEvent ? 0 : pKeyEvent->key()); /*static int s_nCnt (0); if (0 != pKeyEvent //&& Qt::Key_Escape == nKey ) { qDebug("%d. %s %d", s_nCnt++, pObj->objectName().toUtf8().constData(), (int)pEvent->type()); //return QDialog::eventFilter(pObj, pEvent); }//*/ if (0 != pKeyEvent && Qt::Key_Escape == nKey && this == pObj && QEvent::KeyPress == pEvent->type()) { SaveOpt eSaveOpt (save(IMPLICIT)); if (SAVED != eSaveOpt && DISCARDED != eSaveOpt) { return true; } } if (0 != pKeyEvent && Qt::Key_Delete == nKey && m_pCurrentAlbumG == pObj && QEvent::KeyPress == pEvent->type()) { eraseSelFields(); return true; } return QDialog::eventFilter(pObj, pEvent); } void TagEditorDlgImpl::eraseSelFields() // erases the values in the selected fields { vector<pair<int, int> > vSel (getSelFields()); m_pTagWriter->eraseFields(vSel); //m_pAssgnBtnWrp->setState(m_pTagWriter->updateAssigned(vector<pair<int, int> >())); m_pAssgnBtnWrp->setState(m_pTagWriter->updateAssigned(vSel)); m_pAssgnBtnWrp->setState(m_pTagWriter->updateAssigned(vector<pair<int, int> >())); // we don't want to keep any previous value updateAssigned(); // needed for the "assign" button to work, because the previous line cleared m_pTagWriter->m_sSelOrigVal m_pTagWriter->reloadAll(m_pTagWriter->getCurrentName(), TagWriter::DONT_CLEAR_DATA, TagWriter::DONT_CLEAR_ASSGN); //ttt2 way too many ugly calls, including 2 required calls to m_pAssgnBtnWrp->setState(); restructure the whole "assigned" thing; /* some details (not completely up-to-date): TagWriter::toggleAssigned() should be called when the user clicks on the assign button; changes status of selected cells and returns the new state of m_pToggleAssignedB TagWriter::updateAssigned() should be called when the selection changes; returns the new state of m_pToggleAssignedB; both TagEditorDlgImpl and TagWriter have updateAssigned(), which is confusing better have toggleAssigned() and updateAssigned() use signals (and perhaps guards) */ } /*override*/ void TagEditorDlgImpl::closeEvent(QCloseEvent* pEvent) { pEvent->ignore(); QCoreApplication::postEvent(this, new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier)); // ttt2 not sure is a KeyRelease pair is expected } //ttt2 disabled widgets should have tooltips saying why are they disabled / how to enable them //=================================================================================================================== class Id3V230Writer : public Transformation { //void processId3V2Stream(Id3V2StreamBase& strm, ofstream_utf8& out); const TagWriter* m_pTagWriter; bool m_bKeepOneValidImg; bool m_bFastSave; void setupWriter(Id3V230StreamWriter& wrt, const Mp3HandlerTagData* pMp3HandlerTagData); public: Id3V230Writer(const TagWriter* pTagWriter, bool bKeepOneValidImg, bool bFastSave) : m_pTagWriter(pTagWriter), m_bKeepOneValidImg(bKeepOneValidImg), m_bFastSave(bFastSave) {} /*override*/ Transformation::Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Saves user-edited ID3V2.3.0 tags."; } /*override*/ bool acceptsFastSave() const { return true; } static const char* getClassName() { return "Save ID3V2.3.0 tags"; } }; void Id3V230Writer::setupWriter(Id3V230StreamWriter& wrt, const Mp3HandlerTagData* pMp3HandlerTagData) { string s; s = pMp3HandlerTagData->getData(TagReader::TITLE); if (s.empty()) { wrt.removeFrames(KnownFrames::LBL_TITLE()); } else { wrt.addTextFrame(KnownFrames::LBL_TITLE(), s); } s = pMp3HandlerTagData->getData(TagReader::ARTIST); if (s.empty()) { wrt.removeFrames(KnownFrames::LBL_ARTIST()); } else { wrt.addTextFrame(KnownFrames::LBL_ARTIST(), s); } s = pMp3HandlerTagData->getData(TagReader::TRACK_NUMBER); if (s.empty()) { wrt.removeFrames(KnownFrames::LBL_TRACK_NUMBER()); } else { wrt.addTextFrame(KnownFrames::LBL_TRACK_NUMBER(), s); } s = pMp3HandlerTagData->getData(TagReader::GENRE); if (s.empty()) { wrt.removeFrames(KnownFrames::LBL_GENRE()); } else { wrt.addTextFrame(KnownFrames::LBL_GENRE(), s); } s = pMp3HandlerTagData->getData(TagReader::ALBUM); if (s.empty()) { wrt.removeFrames(KnownFrames::LBL_ALBUM()); } else { wrt.addTextFrame(KnownFrames::LBL_ALBUM(), s); } s = pMp3HandlerTagData->getData(TagReader::COMPOSER); if (s.empty()) { wrt.removeFrames(KnownFrames::LBL_COMPOSER()); } else { wrt.addTextFrame(KnownFrames::LBL_COMPOSER(), s); } s = pMp3HandlerTagData->getData(TagReader::VARIOUS_ARTISTS); wrt.setVariousArtists(!s.empty()); s = pMp3HandlerTagData->getData(TagReader::TIME); if (s.empty()) { wrt.removeFrames(KnownFrames::LBL_TIME_DATE_230()); wrt.removeFrames(KnownFrames::LBL_TIME_YEAR_230()); wrt.removeFrames(KnownFrames::LBL_TIME_240()); } else { wrt.setRecTime(TagTimestamp(s)); } s = pMp3HandlerTagData->getData(TagReader::IMAGE); if (s.empty()) { wrt.removeFrames(KnownFrames::LBL_IMAGE(), -1); // !!! this removes all APIC frames, including those non-cover frames that got assigned to Id3V2StreamBase::m_pPicFrame } else { int nImg (pMp3HandlerTagData->getImage()); CB_ASSERT (nImg >= 0); const ImageColl& imgColl (m_pTagWriter->getImageColl()); const ImageInfo& imgInfo (imgColl[nImg].m_imageInfo); int nImgSize (imgInfo.getSize()); const char* pImgData (imgInfo.getComprData()); QByteArray recomprImg; // to be used only for ImageInfo::INVALID const char* szEncoding (0); switch (imgInfo.getCompr()) { case ImageInfo::JPG: szEncoding = "image/jpg"; break; case ImageInfo::PNG: szEncoding = "image/png"; break; case ImageInfo::INVALID: { QImage scaledPic; ImageInfo::compress(imgInfo.getImage(), scaledPic, recomprImg); nImgSize = recomprImg.size(); pImgData = recomprImg.constData(); szEncoding = "image/jpg"; break; } default: CB_ASSERT (false); } int nEncSize (strlen(szEncoding)); int nSize (1 + nEncSize + 1 + 1 + 1 + nImgSize); vector<char> frm (nSize); char* q (&frm[0]); *q++ = 0; // enc strcpy(q, szEncoding); q += nEncSize + 1; // enc + term *q++ = Id3V2Frame::PT_COVER; *q++ = 0; // null-term descr memcpy(q, pImgData, nImgSize); wrt.addImg(frm); } { //s = pMp3HandlerTagData->getData(TagReader::RATING); double d (pMp3HandlerTagData->getRating()); CB_ASSERT (d <= 5); if (d < 0) { wrt.removeFrames(KnownFrames::LBL_RATING()); } else { d = 1 + d*254/5; vector<char> frm (2); frm[0] = 0; frm[1] = (int)d; // ttt2 signed char on some CPUs might have issues; OK on x86, though wrt.addBinaryFrame(KnownFrames::LBL_RATING(), frm); } } } //ttt2 when multiple id3v2 are found, the bkg color doesn't change if the 2 id3v2 are switched; probably ok, though, in the sense that if at least one field is assigned, all the others will be used when saving /*override*/ Transformation::Result Id3V230Writer::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { LAST_STEP("Id3V230Writer::apply() " + h.getName()); const vector<DataStream*>& vpStreams (h.getStreams()); const Mp3HandlerTagData* pMp3HandlerTagData (0); for (int i = 0, n = cSize(m_pTagWriter->m_vpMp3HandlerTagData); i < n; ++i) { const Mp3HandlerTagData* p (m_pTagWriter->m_vpMp3HandlerTagData[i]); if (p->getMp3Handler() == &h) { pMp3HandlerTagData = p; goto e1; } } //return NOT_CHANGED; CB_ASSERT (false); // only handlers from m_pTagWriter (that also need saving) are supposed to get here; e1: CB_ASSERT (0 != pMp3HandlerTagData); ifstream_utf8 in (h.getName().c_str(), ios::binary); { // temp Id3V2StreamBase* pId3V2Source (0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { pId3V2Source = dynamic_cast<Id3V2StreamBase*>(vpStreams[i]); if (0 != pId3V2Source) { break; } } Id3V230StreamWriter wrt (m_bKeepOneValidImg, m_bFastSave, pId3V2Source, h.getName()); // OK if pId3V2Source is 0 setupWriter(wrt, pMp3HandlerTagData); if (m_bFastSave && !vpStreams.empty() && pId3V2Source == vpStreams[0]) { try { long long nSize, nOrigTime; getFileInfo(h.getName(), nOrigTime, nSize); { fstream_utf8 f (h.getName().c_str(), ios::binary | ios_base::in | ios_base::out); wrt.write(f, int(pId3V2Source->getSize())); } h.reloadId3V2(); //ttt2 perhaps return the pointer to the old Id3V2 instead of destroying it, and keep it somewhere until saving is done; then m_bIsFastSaving won't be needed, and no "N/A"s will be displayed in ID3V2 fields when saving; OTOH those pointers can't be kept fully alive, because they can't retrieve their data from disk; so better leave it as is; if (transfConfig.m_options.m_bKeepOrigTime) { setFileDate(h.getName(), nOrigTime); } else { getFileInfo(h.getName(), nOrigTime, nSize); h.m_nFastSaveTime = nOrigTime; } return NOT_CHANGED; // !!! } catch (const WriteError&) { // !!! nothing: normally this gets triggered before changing the file in any way (the reason being that it doesn't fit), so we go on and create a temporary file; //ttt2 the exception might get thrown on versioned filesystems, that use copy-on-write, if the disk becomes full, bu even then there's not much that can be done; } } transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); wrt.write(out); // may throw, but it will be caught for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); bool bCopy (0 == dynamic_cast<Id3V2StreamBase*>(p)); BrokenDataStream* pBrk (dynamic_cast<BrokenDataStream*>(p)); if (bCopy && 0 != pBrk && (pBrk->getBaseName() == Id3V230Stream::getClassDisplayName() || pBrk->getBaseName() == Id3V240Stream::getClassDisplayName())) { bCopy = false; } if (bCopy) { p->copy(in, out); } } } return CHANGED_NO_RECALL; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== //ttt2 perhaps all licences in root dir // based on configuration, either just saves the tags or asks the user for confirmation; returns true iff all tags have been saved or if none needed saving; it should be followed by a reload(), either for the current or for the next/prev album; if bExplicitCall is true, the "ASK" option is turned into "SAVE"; TagEditorDlgImpl::SaveOpt TagEditorDlgImpl::save(bool bImplicitCall) { string strCrt (m_pTagWriter->getCurrentName()); deque<const Mp3Handler*> vpHndlr; bool bHasUnsavedAssgn (false); bool bHasUnsavedNonId3V2 (false); for (int i = 0, n = cSize(m_pTagWriter->m_vpMp3HandlerTagData); i < n; ++i) { //const Mp3Handler* p (m_pTagWriter->m_vpMp3HandlerTagData[i]->getMp3Handler()); bool bAssgn (false); bool bNonId3V2 (false); m_pTagWriter->hasUnsaved(i, bAssgn, bNonId3V2); if ( (bAssgn && (!bImplicitCall || CommonData::DISCARD != m_pCommonData->m_eAssignSave)) || (bNonId3V2 && (!bImplicitCall || CommonData::DISCARD != m_pCommonData->m_eNonId3v2Save)) ) { vpHndlr.push_back(m_pTagWriter->m_vpMp3HandlerTagData[i]->getMp3Handler()); } bHasUnsavedAssgn = bHasUnsavedAssgn || bAssgn; bHasUnsavedNonId3V2 = bHasUnsavedNonId3V2 || bNonId3V2; } //ttt2 perhaps separate setting for showing and saving non-id3v2 fields { int nUnassignedImagesCnt (m_pTagWriter->getUnassignedImagesCount()); if (bImplicitCall && nUnassignedImagesCnt > 0) { int nOpt (showMessage(this, QMessageBox::Question, 1, 1, "Confirm", (nUnassignedImagesCnt > 1 ? QString("You added %1 images but then you didn't assign them to any songs. What do you want to do?").arg(nUnassignedImagesCnt) : QString("You added an image but then you didn't assign it to any song. What do you want to do?")), "&Discard", "&Cancel")); if (1 == nOpt) { return CANCELLED; } } } if (vpHndlr.empty()) { return SAVED; } if ( bImplicitCall && ( (bHasUnsavedAssgn && CommonData::ASK == m_pCommonData->m_eAssignSave) || (bHasUnsavedNonId3V2 && CommonData::ASK == m_pCommonData->m_eNonId3v2Save) ) ) { // ask int nOpt; if ((bHasUnsavedAssgn && CommonData::ASK == m_pCommonData->m_eAssignSave) && (bHasUnsavedNonId3V2 && CommonData::DISCARD == m_pCommonData->m_eNonId3v2Save)) { nOpt = showMessage(this, QMessageBox::Question, 0, 2, "Confirm", "There are unsaved fields that you assigned a value to, as well as fields whose value doesn't match the ID3V2 value. What do you want to do?", "&Save", "&Discard", "&Cancel"); } else if (bHasUnsavedAssgn && CommonData::ASK == m_pCommonData->m_eAssignSave) { nOpt = showMessage(this, QMessageBox::Question, 0, 2, "Confirm", "There are unsaved fields that you assigned a value to. What do you want to do?", "&Save", "&Discard", "&Cancel"); } else { nOpt = showMessage(this, QMessageBox::Question, 0, 2, "Confirm", "There are fields whose value doesn't match the ID3V2 value. What do you want to do?", "&Save", "&Discard", "&Cancel"); } if (1 == nOpt) { return DISCARDED; } if (2 == nOpt) { return CANCELLED; } } m_bDataSaved = true; Id3V230Writer wrt (m_pTagWriter, m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave()); vector<Transformation*> vpTransf; vpTransf.push_back(&wrt); bool bRes; { ValueRestorer<bool> rst (m_bIsFastSaving); m_bIsFastSaving = m_pCommonData->useFastSave(); ValueRestorer<bool> rst1 (m_bIsSaving); m_bIsSaving = true; bRes = transform(vpHndlr, vpTransf, "Saving ID3V2.3.0 tags", this, m_pCommonData, m_transfConfig); } m_pTagWriter->reloadAll(strCrt, TagWriter::DONT_CLEAR_DATA, TagWriter::CLEAR_ASSGN); //m_pTagWriter->updateAssigned(vector<pair<int, int> >()); m_pAssgnBtnWrp->setState(m_pTagWriter->updateAssigned(vector<pair<int, int> >())); // we don't want to keep any previous value updateAssigned(); // needed for the "assign" button to work, because the previous line cleared m_pTagWriter->m_sSelOrigVal return bRes ? SAVED : PARTIALLY_SAVED; } //ttt2 hide VA column if not used void TagEditorDlgImpl::onHelp() { openHelp("190_tag_editor.html"); } extern bool s_bToldAboutPatternsInCrtRun; void TagEditorDlgImpl::onShowPatternNote() { if (m_pTagWriter->shouldShowPatternsNote()) { s_bToldAboutPatternsInCrtRun = true; HtmlMsg::msg(this, 0, 0, &m_pCommonData->m_bToldAboutPatterns, HtmlMsg::DEFAULT, "Info", "<p style=\"margin-bottom:1px; margin-top:12px; \">Some fields are missing or may be incomplete. While this is usually solved by downloading correct information, there are a cases when this approach doesn't work, like custom compilations, rare albums, or missing tracks.</p>" "<p style=\"margin-bottom:1px; margin-top:12px; \">If your current folder fits one of these cases or you simply have consistently named files that you would prefer to use as a source of track info, you may want to take a look at the tag editor's patterns, at <a href=\"http://mp3diags.sourceforge.net/220_tag_editor_patterns.html\">http://mp3diags.sourceforge.net/220_tag_editor_patterns.html</a>.</p>", 550, 300, "OK"); //ttt1 different for "unstable" } } //======================================================================================================================================================== //======================================================================================================================================================== //======================================================================================================================================================== CurrentFileDelegate::CurrentFileDelegate(QTableView* pTableView, const CommonData* pCommonData) : QItemDelegate(pTableView), m_pTableView(pTableView), m_pCommonData(pCommonData) { CB_CHECK1 (0 != pTableView, std::runtime_error("NULL QTableView not allowed")); //connect(pTableView->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), pTableView, SLOT(resizeRowsToContents())); } /*override*/ void CurrentFileDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { pPainter->save(); //pPainter->fillRect(option.rect, QBrush(m_listPainter.getColor(m_listPainter.getAvailable()[index.row()], index.column(), pPainter->background().color()))); //ttt2 make sure background() is the option to use /*QStyleOptionViewItemV2 myOption (option); myOption.displayAlignment = m_listPainter.getAlignment(index.column());*/ QString s (index.model()->data(index, Qt::DisplayRole).toString()); if ("\1" == s) { // tag not present pPainter->fillRect(option.rect, QBrush(m_pCommonData->m_vTagEdtColors[CommonData::COLOR_FILE_TAG_MISSING])); } else if ("\2" == s) { // not applicable pPainter->fillRect(option.rect, QBrush(m_pCommonData->m_vTagEdtColors[CommonData::COLOR_FILE_NA])); } else if ("\3" == s) { // applicable, but no data found pPainter->fillRect(option.rect, QBrush(m_pCommonData->m_vTagEdtColors[CommonData::COLOR_FILE_NO_DATA])); } else { pPainter->fillRect(option.rect, QBrush(m_pCommonData->m_vTagEdtColors[CommonData::COLOR_FILE_NORM])); QItemDelegate::paint(pPainter, option, index); } /* //ttt2 first 3 cases don't show the dotted line because QItemDelegate::paint() doesn't get called; perhaps drawDecoration() should be called, but copying these things from qitemdelegate.cpp didn't help: QVariant value; value = index.data(Qt::DecorationRole); QPixmap pixmap; pixmap = decoration(option, value); drawDecoration(pPainter, option, QRect(0, 0, 15, 15), pixmap); ??? or perhaps use QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect?, &option, pPainter); */ pPainter->restore(); } QSize CurrentFileDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { return QItemDelegate::sizeHint(option, index); /* if (!index.isValid()) { return QSize(); } //cout << option.rect.width() << "x" << option.rect.height() << " "; int nMargin (QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1); //cout << "margin=" << nMargin << endl; int j (index.column()); int nColWidth (m_pTableView->horizontalHeader()->sectionSize(j)); //QRect r (0, 0, nColWidth - 2*nMargin - 1, 10000); // !!! this "-1" is what's different from Qt's implementation //ttt2 see if this is fixed in 4.4 2008.30.06 - apparently it's not fixed and the workaround no longer works //QSize res (option.fontMetrics.boundingRect(r, Qt::AlignTop | Qt::TextWordWrap, index.data(Qt::DisplayRole).toString()).size()); //cout << "at (" << index.row() << "," << index.column() << "): " << res.width() << "x" << res.height(); QSize res (nColWidth, CELL_HEIGHT); //res.setWidth(nColWidth); //cout << " => " << res.width() << "x" << res.height() << endl; //QSize res (fontMetrics().size(0, text())); return res; */ }//*/ //ttt2 perhaps allow selected cells to show background color, so it's possible to know if a cell is assigned, id3v2 or non-id3v2 even when it's selected; options include replaceing background with a frame, background with a darkened color based on the normal background, negation of normal color, some pattern CurrentAlbumDelegate::CurrentAlbumDelegate(QTableView* pTableView, TagEditorDlgImpl* pTagEditorDlgImpl) : QItemDelegate(pTableView), m_pTableView(pTableView), m_pTagEditorDlgImpl(pTagEditorDlgImpl), m_pTagWriter(pTagEditorDlgImpl->getTagWriter()) { CB_CHECK1 (0 != pTableView, std::runtime_error("NULL QTableView not allowed")); //connect(pTableView->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), pTableView, SLOT(resizeRowsToContents())); } /*override*/ void CurrentAlbumDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (m_pTagEditorDlgImpl->isSaving() || m_pTagEditorDlgImpl->isNavigating()) { QItemDelegate::paint(pPainter, option, index); return; } pPainter->save(); //pPainter->fillRect(option.rect, QBrush(m_listPainter.getColor(m_listPainter.getAvailable()[index.row()], index.column(), pPainter->background().color()))); //ttt2 make sure background() is the option to use /*QStyleOptionViewItemV2 myOption (option); myOption.displayAlignment = m_listPainter.getAlignment(index.column());*/ //QString s (index.model()->data(index, Qt::DisplayRole).toString()); int nField (index.column()); Mp3HandlerTagData::Status eStatus (nField > 0 ? m_pTagWriter->getStatus(index.row(), TagReader::FEATURE_ON_POS[nField - 1]) : Mp3HandlerTagData::ID3V2_VAL); QColor col; switch (eStatus) { case Mp3HandlerTagData::EMPTY: case Mp3HandlerTagData::ID3V2_VAL: col = m_pTagEditorDlgImpl->getCommonData()->m_vTagEdtColors[CommonData::COLOR_ALB_NORM]; break; case Mp3HandlerTagData::NON_ID3V2_VAL: col = m_pTagEditorDlgImpl->getCommonData()->m_vTagEdtColors[CommonData::COLOR_ALB_NONID3V2]; break; case Mp3HandlerTagData::ASSIGNED: col = m_pTagEditorDlgImpl->getCommonData()->m_vTagEdtColors[CommonData::COLOR_ALB_ASSIGNED]; break; } //if (1 == index.column()) { pPainter->fillRect(option.rect, QBrush(col)); } //else { QItemDelegate::paint(pPainter, option, index); } pPainter->restore(); } //ttt2 2009.04.06 - for all delegates: see if they can be removed by using the standard delegate and adding more functionality to the models; see Qt::ForegroundRole, Qt::TextAlignmentRole, Qt::FontRole & Co /*override*/ QWidget* CurrentAlbumDelegate::createEditor(QWidget* pParent, const QStyleOptionViewItem& style, const QModelIndex& index) const { int nField (index.column()); if (0 == nField || 5 == nField || 8 == nField) { return 0; } QWidget* pEditor (QItemDelegate::createEditor(pParent, style, index)); //qDebug("%s", p->metaObject()->className()); connect(pEditor, SIGNAL(destroyed(QObject*)), this, SLOT(onEditorDestroyed(QObject*))); m_spEditors.insert(pEditor); //qDebug("create %p", pEditor); return pEditor; } void CurrentAlbumDelegate::onEditorDestroyed(QObject* p) { //qDebug("destroy %p", p); CB_ASSERT (1 == m_spEditors.count(p)); m_spEditors.erase(p); } bool CurrentAlbumDelegate::closeEditor() // closes the editor opened with F2, saving the data; returns false if there was some error and it couldn't close { CB_ASSERT (cSize(m_spEditors) <= 1); if (m_spEditors.empty()) { return true; } //delete m_pEditor; if (0 != showMessage(m_pTableView, QMessageBox::Warning, 1, 1, "Warning", "You are editing data in a cell. If you proceed that change will be lost. Proceed and lose the data?", "Proceed", "Cancel")) { return false; } //ttt2 try and post somehow the content of the editor (?? perhaps send it a keyboard message that ENTER was pressed) //ttt2 review this delete *m_spEditors.begin(); return true; } //ttt2 perhaps manufacture track numbers when pasting tables, if track numbers don't exist //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== /* tag editor performance: TagWriter::reloadAll() is called twice when going to a new album, but that's not very important, because reloading no longer takes a lot of time; if there are no images it's very fast, but even with images it's no big deal; most time is used in rescanning a modified file, in Mp3Handler::parse(), as this example of saving a modified song shows: save: 0.23" (copying streams from one file to another) read ID3: 0.29" (because it parses images) read MPEG audio: 1.10" OTOH TagWriter::reloadAll() typically takes less than 0.10" for a whole album, even when pictures are present; what makes this slower is having pictures in the current directory, because they get rescanned at each reload, while the ones inside the MP3s don't. So eliminating the duplicate call wouldn't achieve much. The duplicate was needed at some point in time because of some Qt bug (or so it looked like); not sure if it's really needed, but removing it is almost guaranteed to result in some bugs (like randomly resizing the image panel) that are not consistently reproducible.) Rescanning of saved files might be eliminated if speed is so important, but it seems a bad idea; the main reason is that without rescanning the notes and the streams are going to be out of synch, and this is fundamentally unsolvable. Marking such files as "dirty" doesn't seem a very good idea, and could be quite confusing and hard to get right. Not marking them is worse. Perhaps "fast editor" option ... A less important performance issue is in ImageInfoPanelWdgImpl::ImageInfoPanelWdgImpl(): assigning of an image to a label takes more than 0.2" */ //ttt2 in tag editor: magnify image for one album, Ctrl+C, go to another album, Ctrl+V -> format error ��������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Helpers.h�������������������������������������������������������������������0000644�0001750�0000144�00000032645�11350732732�015043� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef HelpersH #define HelpersH #include <iosfwd> #include <string> #include <stdexcept> #include <cstdlib> // for exit() #include <set> #include <vector> //#include <QString> #include <QStringList> // ttt2 what we really want is QString; however, by including QString directly, lots of warnings get displayed; perhaps some defines are needed but don't know which; so we just include QStringList to avoid the warnings void logToGlobalFile(const std::string& s); #define CB_CHECK1(COND, EXCP) { if (!(COND)) { ::trace(#EXCP); throw EXCP; } } //#define CB_THROW(MSG) { throw std::runtime_error(MSG); } #define CB_THROW1(EXCP) { ::trace(#EXCP); throw EXCP; } //#define CB_ASSERT(COND) { if (!(COND)) { ::trace("assert"); throw std::runtime_error("assertion failure"); } } #define CB_ASSERT(COND) { if (!(COND)) { assertBreakpoint(); ::trace("assert"); logAssert(__FILE__, __LINE__, #COND); ::exit(1); } } #define CB_ASSERT1(COND, MSG) { if (!(COND)) { assertBreakpoint(); ::trace("assert"); logAssert(__FILE__, __LINE__, #COND, MSG); ::exit(1); } } ////#include <CbLibCall.h> #define CB_LIB_CALL void assertBreakpoint(); /* Protocol for reading from files: - the file is always left in good state, no eof or fail - initializing objects with from a file: - the starting position is not passed, but it is the current position - if an error occurs and the constructor fails, the read pointer is restored (and the error flags are cleared); StreamStateRestorer can be used to do this - on success, the read pointer is left after the last byte that was used; (that may be EOF, but the eof flag should still be clear, because no attempt is made to actually read it after moving the pointer) - relying on a stream's flags should be avoided; (the flags are cleared most of the time anyway); the test should normally be to check if a desired number of bytes could be read; */ // !!! readsome seems to do the job but it only returns whatever is in buffer, without waiting for new data to be brought in. Therefore it is not usable in this case. // !!! doesn't leave the file with fail or eof set; the caller should check the returned value; inline std::streamsize read(std::istream& in, char* bfr, std::streamsize nCount) { in.read(bfr, nCount); std::streamsize nRes (in.gcount()); in.clear(); return nRes; } /* Usage: declare a StreamStateRestorer. Before it goes out of scope, call setOk() if everything went OK. On the destructor it checks if setOk() was called. If it wasn't, the read position is set to whatever was on the constructor. All flags of the stream are cleared in either case. */ class StreamStateRestorer { std::istream& m_in; std::streampos m_pos; bool m_bOk; public: StreamStateRestorer(std::istream& in); ~StreamStateRestorer(); void setOk() { m_bOk = true; } }; // on its destructor restores the value of the variable passed on the constructor unless setOk() gets called template <typename T> class ValueRestorer { T m_val; T& m_ref; bool m_bRestore; public: ValueRestorer(T& ref) : m_val(ref), m_ref(ref), m_bRestore(true) {} ~ValueRestorer() { if (m_bRestore) { m_ref = m_val; } } void setOk(bool b = true) { m_bRestore = !b; } }; template<typename T> void CB_LIB_CALL releasePtr(T*& p) { delete p; p = 0; } #define TRACE(A) { std::ostringstream sTrM; sTrM << A; ::trace(sTrM.str()); } void trace(const std::string& s); void logAssert(const char* szFile, int nLine, const char* szCond); void logAssert(const char* szFile, int nLine, const char* szCond, const std::string& strAddtlInfo); namespace pearl { template<class T> void CB_LIB_CALL clearPtrContainer(T& c) // calls delete on all the elements of a container of pointers, then sets its size to 0; shouldn't be used on sets { for (typename T::iterator it = c.begin(), end = c.end(); it != end; ++it) { delete *it; } c.clear(); } template<typename T> void CB_LIB_CALL clearPtrContainer(std::set<T*>& c) // specialization for sets { while (!c.empty()) { T* p; p = *c.begin(); //ddd see if it's better to remove from end / middle instead of front c.erase(c.begin()); delete p; } } // to make sure that an array is deallocated even when exceptions are thrown; similar to auto_ptr template<typename T> class ArrayPtrRelease { T* m_pArray; ArrayPtrRelease(); ArrayPtrRelease(const ArrayPtrRelease&); ArrayPtrRelease& operator=(const ArrayPtrRelease&); public: ArrayPtrRelease(T* pArray) : m_pArray(pArray) {} ~ArrayPtrRelease() { delete[] m_pArray; } T* get() { return m_pArray; } const T* get() const { return m_pArray; } }; } // namespace pearl template<class T> int CB_LIB_CALL cSize(const T& c) // returns the size of a container as an int { return (int)c.size(); } struct EndOfFile {}; struct WriteError {}; // throws WriteError or EndOfFile void appendFilePart(std::istream& in, std::ostream& out, std::streampos pos, std::streamoff nSize); // prints to cout the content of a memory location, as ASCII and hex; // GDB has a tendency to not see char arrays and other local variables; actually GCC seems to be the culprit (bug 34767); void inspect(const void* p, int nSize); template <typename T> void inspect(const T& x) { if (sizeof(x) == 1001) { return; } } // prints the elements of a container template <typename T> void printContainer(const T& s, std::ostream& out, const std::string& strSep = " ") { for (typename T::const_iterator it = s.begin(); it != s.end(); ++it) { out << *it << strSep; } out << std::endl; } std::string asHex(const char* p, int nSize); inline bool CB_LIB_CALL beginsWith(const std::string& strMain, const std::string& strSubstr) { if (strSubstr.size() > strMain.size()) return false; return strMain.substr(0, strSubstr.size()) == strSubstr; } inline bool CB_LIB_CALL endsWith(const std::string& strMain, const std::string& strSubstr) { if (strSubstr.size() > strMain.size()) return false; // !!! otherwise the next line might incorrectly return true if // strMain.size() = strSubstr.size() - 1 return strMain.rfind(strSubstr) == strMain.size() - strSubstr.size(); } bool CB_LIB_CALL rtrim(std::string& s); // removes whitespaces at the end of the string bool CB_LIB_CALL ltrim(std::string& s); // removes whitespaces at the beginning of the string bool CB_LIB_CALL trim(std::string& s); int get32BitBigEndian(const char*); void put32BitBigEndian(int n, char*); // The reference that is passed in the constructor (the "guard") should be accessible to all parties interested; it should be initialized to "false" first. When a piece of code wants access to resources protected by the guard, it should declare an NonblockingGuard variable, initialize it with the guard and then check if it went OK, by calling "operator()"; if "operator()" returns true, it means the guard was acquired, so it can proceed. // The major point is that it's a non-blocking call. // The intended use is with single-threaded applications (or rather to not share a guard among threads). This is useful to handle the situation where function f() may call g() and g() may call f(), but with the restriction that f() may call g() only if f() wasn't already called by g(). As this isn't designed for multi-threading, it doesn't need any system-specific code or porting. class NonblockingGuard { bool& m_bLock; bool m_bInitialState; public: CB_LIB_CALL NonblockingGuard(bool& bLock) : m_bLock(bLock), m_bInitialState(m_bLock) { m_bLock = true; // doesn't matter if it was true } CB_LIB_CALL ~NonblockingGuard() { m_bLock = m_bInitialState; } operator bool () const { return !m_bInitialState; } }; // takes a Latin1 string and converts it to UTF8 std::string utf8FromLatin1(const std::string&); // the total memory currently used by the current process, in kB long getMemUsage(); std::string decodeMpegFrame(unsigned int n, const char* szSep, bool* pbIsValid = 0); // on error doesn't throw, but returns an error string; szSep is used as separator for the output string std::string decodeMpegFrame(const char* bfr, const char* szSep, bool* pbIsValid = 0); std::string decodeMpegFrameAsXml(const char* bfr, bool* pbIsValid = 0); inline const char* boolAsYesNo(bool b) { return b ? "yes" : "no"; } char getPathSep(); const std::string& getPathSepAsStr(); std::streampos getSize(std::istream& in); // throws WriteError or EndOfFile void writeZeros(std::ostream& out, int nCnt); // needed because gdb has trouble setting breakpoints in template code inline void templateBreakpoint() { qDebug("breakpoint"); } // by including this as a member the compiler generated constructor / copy op. are disabled class NoDefaults { CB_LIB_CALL NoDefaults(); CB_LIB_CALL NoDefaults(const NoDefaults&); NoDefaults& CB_LIB_CALL operator=(NoDefaults&); //ttt2 see if there are other generated operations and include them all public: CB_LIB_CALL NoDefaults(int) {} }; class QWidget; void listWidget(QWidget* p, int nIndent = 0); //ttt2 move this elsewhere std::string escapeHttp(const std::string& s); // replaces invalid HTTP characters like ' ' or '"' with their hex code (%20 or %22) inline QString convStr(const std::string& s) { return QString::fromUtf8(s.c_str(), cSize(s)); } //ttt2 perhaps move inline std::string convStr(const QString& qs) { const QByteArray& b (qs.toUtf8()); return std::string(b.constData(), b.size()); } //ttt2 perhaps move std::vector<std::string> convStr(const std::vector<QString>&); std::vector<QString> convStr(const std::vector<std::string>&); Qt::WindowFlags getMainWndFlags(); // minimize, maximize, no "what's this" Qt::WindowFlags getDialogWndFlags(); // maximize, no "what's this" Qt::WindowFlags getNoResizeWndFlags(); // no "what's this"; the window may be resizable, but the min/max icons aren't shown QString getSystemInfo(); class QGradient; class QColor; // sets colors at various points to emulate a non-linear gradient that better suits our needs; // dStart and dEnd should be between 0 and 1, with dStart < dEnd; they may also be both -1, in which case the gradient will have a solid color void configureGradient(QGradient& grad, const QColor& col, double dStart, double dEnd); // opens a web page from the documentation in the default browser; // first looks in several places on the local computer; if the file can't be found there, it goes to SourceForge void openHelp(const std::string& strFileName); // meant for displaying tooltips; converts some spaces to \n, so the tooltips have several short lines instead of a single wide line QString makeMultiline(const char* szDescr); QString toNativeSeparators(const QString&); QString fromNativeSeparators(const QString&); inline std::string toNativeSeparators(const std::string& s) { return convStr(toNativeSeparators(convStr(s))); } inline std::string fromNativeSeparators(const std::string& s) { return convStr(fromNativeSeparators(convStr(s))); } QString getTempDir(); //====================================================================================================== //====================================================================================================== //====================================================================================================== void traceToFile(const std::string& s, int nLevelChange); struct Tracer { const std::string m_s; Tracer(const std::string& s); ~Tracer(); }; #define TRACER(X) Tracer FiLeTrAcEr (X); #define TRACER1(X, N) Tracer FiLeTrAcEr##N (X); #define TRACER1A(X, N) Tracer FiLeTrAcEr##N (X#N); void traceLastStep(const std::string& s, int nLevelChange); struct LastStepTracer { const std::string m_s; LastStepTracer(const std::string& s); ~LastStepTracer(); }; #define LAST_STEP(X) LastStepTracer LaStStEp (X); #define LAST_STEP1(X, N) LastStepTracer LaStStEp##N (X); #endif // ifndef HelpersH �������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/DataStream.h����������������������������������������������������������������0000644�0001750�0000144�00000053434�11265047277�015475� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DataStreamH #define DataStreamH #include <vector> #include "SerSupport.h" #include "Notes.h" #include "CommonTypes.h" #define MP3_CHECK(COND, POS, MSG_ID, EXCP) { if (!(COND)) { notes.add(new Note(Notes::MSG_ID(), POS)); throw EXCP; } } #define MP3_CHECK_T(COND, POS, MSG, EXCP) { if (!(COND)) { static Note::SharedData d (MSG, false); notes.add(new Note(d, POS)); throw EXCP; } } #define MP3_THROW(POS, MSG_ID, EXCP) { notes.add(new Note(Notes::MSG_ID(), POS)); throw EXCP; } #define MP3_THROW_T(POS, MSG, EXCP) { static Note::SharedData d (MSG, false); notes.add(new Note(d, POS)); throw EXCP; } #define MP3_NOTE(POS, MSG_ID) { notes.add(new Note(Notes::MSG_ID(), POS)); } #define MP3_NOTE_D(POS, MSG_ID, DETAIL) { notes.add(new Note(Notes::MSG_ID(), POS, DETAIL)); } #define MP3_TRACE(POS, MSG) { static Note::SharedData d (MSG, false); notes.add(new Note(d, POS)); } /* DataStream constructors may leave the input file in EOF or other invalid state and the read pointer with an arbitrary value, regardless of them succeeding or not. Therefore they the file state should be cleared by the user. */ //============================================================================================================ //============================================================================================================ //============================================================================================================ #define DECL_NAME(s) \ static const char* getClassDisplayName() { return s; } \ /*override*/ const char* getDisplayName() const { return getClassDisplayName(); } // this is to be used with TagReader descendants: #define DECL_RD_NAME(s) \ static const char* getClassDisplayName() { return s; } \ /*override*/ const char* getDisplayName() const { return getClassDisplayName(); } \ /*override*/ const char* getName() const { return getClassDisplayName(); } #define STRM_ASSERT(COND) { if (!(COND)) { assertBreakpoint(); ::trace("assert"); logAssert(__FILE__, __LINE__, #COND, getGlobalMp3HandlerName()); ::exit(1); } } std::string getGlobalMp3HandlerName(); // a hack to get the name of the current file from inside various streams without storing the name there //ttt2 review class DataStream { int m_nIndex; DataStream(const DataStream&); DataStream& operator=(const DataStream&); protected: DataStream(int nIndex) : m_nIndex(nIndex) {} DataStream() {} // serialization-only constructor public: virtual ~DataStream() {} // throws WriteError if there are errors writing to the file; derived classes have several options on implementing this, from simply copying content from the input to ignoring the input file completely; e.g. ID3V2 can change the size of the padding, drop some frames, replace others, ... virtual void copy(std::istream& in, std::ostream& out) = 0; virtual const char* getDisplayName() const = 0; virtual std::string getInfo() const = 0; virtual std::streampos getPos() const = 0; virtual std::streamoff getSize() const = 0; std::streampos getEnd() const { return getPos() + getSize(); } int getIndex() const { return m_nIndex; } private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & m_nIndex; } }; // simply copies content from the input file; stores position and size to be able to do so class SimpleDataStream : public DataStream { protected: std::streampos m_pos; std::streamoff m_nSize; SimpleDataStream(int nIndex, std::streampos pos, std::streamoff nSize) : DataStream(nIndex), m_pos(pos), m_nSize(nSize) {} SimpleDataStream() {} // serialization-only constructor public: // seeks "in" for its beginning and appends m_nSize bytes to "out"; /*override*/ void copy(std::istream& in, std::ostream& out); /*override*/ std::streampos getPos() const { return m_pos; } /*override*/ std::streamoff getSize() const { return m_nSize; } private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object<DataStream>(*this); ar & m_pos; ar & m_nSize; } }; class UnknownDataStreamBase : public SimpleDataStream // ttt2 perhaps unify with SimpleDataStream, as it's its only descendant; OTOH SimpleDataStream might get other descendants in the future, so maybe not // ttt2 not the best name, but others don't seem better { public: enum { BEGIN_SIZE = 32 }; protected: char m_begin [BEGIN_SIZE]; void append(const UnknownDataStreamBase&); UnknownDataStreamBase() {} // serialization-only constructor public: UnknownDataStreamBase(int nIndex, NoteColl& notes, std::istream& in, std::streamoff nSize); /*override*/ std::string getInfo() const; const char* getBegin() const { return m_begin; } struct BadUnknownStream {}; // e.g. there are not nSize chars left private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object<SimpleDataStream>(*this); ar & m_begin; } }; class UnknownDataStream : public UnknownDataStreamBase { public: UnknownDataStream(int nIndex, NoteColl& notes, std::istream& in, std::streamoff nSize) : UnknownDataStreamBase(nIndex, notes, in, nSize) {} DECL_NAME("Unknown"); using UnknownDataStreamBase::append; private: friend class boost::serialization::access; UnknownDataStream() {} // serialization-only constructor template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object<UnknownDataStreamBase>(*this); } }; class BrokenDataStream : public UnknownDataStreamBase { std::string m_strName; std::string m_strBaseName; std::string m_strInfo; public: BrokenDataStream(int nIndex, NoteColl& notes, std::istream& in, std::streamoff nSize, const char* szBaseName, const std::string& strInfo) : UnknownDataStreamBase(nIndex, notes, in, nSize), m_strName(std::string("Broken ") + szBaseName), m_strBaseName(szBaseName), m_strInfo(strInfo.empty() ? UnknownDataStreamBase::getInfo() : strInfo + "; " + UnknownDataStreamBase::getInfo()) {} /*override*/ const char* getDisplayName() const { return m_strName.c_str(); } // DECL_NAME doesn't work in this case /*override*/ std::string getInfo() const { return m_strInfo; } const std::string& getBaseName() const { return m_strBaseName; } private: friend class boost::serialization::access; BrokenDataStream() {} // serialization-only constructor template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object<UnknownDataStreamBase>(*this); ar & m_strName; ar & m_strBaseName; ar & m_strInfo; } }; class UnsupportedDataStream : public UnknownDataStreamBase // ttt3 perhaps merge code with BrokenDataStream in some base class { std::string m_strName; std::string m_strBaseName; std::string m_strInfo; public: UnsupportedDataStream(int nIndex, NoteColl& notes, std::istream& in, std::streamoff nSize, const char* szBaseName, const std::string& strInfo); /*override*/ const char* getDisplayName() const { return m_strName.c_str(); } // DECL_NAME doesn't work in this case /*override*/ std::string getInfo() const { return m_strInfo; } const std::string& getBaseName() const { return m_strBaseName; } private: friend class boost::serialization::access; UnsupportedDataStream() {} // serialization-only constructor template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object<UnknownDataStreamBase>(*this); ar & m_strName; ar & m_strBaseName; ar & m_strInfo; } }; class MpegStream; struct MpegFrameBase; // follows an MPEG stream and is compatible with it but it is truncated; some other frame begins before where it should end class TruncatedMpegDataStream : public UnknownDataStreamBase { MpegFrameBase* m_pFrame; TruncatedMpegDataStream(const TruncatedMpegDataStream&); TruncatedMpegDataStream& operator=(const TruncatedMpegDataStream&); public: TruncatedMpegDataStream(MpegStream* pPrevMpegStream, int nIndex, NoteColl& notes, std::istream& in, std::streamoff nSize); ~TruncatedMpegDataStream(); DECL_NAME("Truncated MPEG"); /*override*/ std::string getInfo() const; int getExpectedSize() const; struct NotTruncatedMpegDataStream {}; // thrown if pMpegStream is 0 or it points to an incompatible stream bool hasSpace(std::streamoff nSize) const; using UnknownDataStreamBase::append; private: friend class boost::serialization::access; TruncatedMpegDataStream() {} // serialization-only constructor template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object<UnknownDataStreamBase>(*this); ar & m_pFrame; } }; // simply copies content from the input file; stores pos and sizes to be able to do so class NullDataStream : public DataStream { std::streampos m_pos; std::streamoff m_nSize; public: NullDataStream(int nIndex, NoteColl& notes, std::istream& in); /*override*/ void copy(std::istream& in, std::ostream& out); DECL_NAME("Null"); /*override*/ std::string getInfo() const; /*override*/ std::streampos getPos() const { return m_pos; } /*override*/ std::streamoff getSize() const { return m_nSize; } struct NotNullStream {}; private: friend class boost::serialization::access; NullDataStream() {} // serialization-only constructor template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object<DataStream>(*this); ar & m_pos; ar & m_nSize; } }; //========================================================================== //========================================================================== struct NotSupportedOp {}; // operation is not currently supported /* While building a stream, by reading from a file, several situations can be encountered: - it is read OK and there are no issues - it is read OK but some parts are incorrect; warnings or errors will be displayed, but it is possible to work with the stream and correct the errors, or perhaps leave it as it is; - it begins as expected, but a serious error is then encountered, so the object cannot be built; - the beginning is incorrect, meaning that it's just a different kind of stream, end of story; nothing should happen in this case; StreamIsBroken is for the 3rd case. It should be thrown when it is pretty likely that a stream of the appropriate type begins at the current position in the file but the stream can't be read. Given that the reason a stream can't be read may actually be that the code is buggy or incomplete, it is possible for a StreamIsBroken to be thrown when an StreamIsUnsupported should have been thrown instead. */ struct StreamIsBroken { // doesn't own the pointer; param is supposed to be string literal StreamIsBroken(const char* szStreamName, const std::string& strInfo) : m_szStreamName(szStreamName), m_strInfo(strInfo) {} const char* getStreamName() const { return m_szStreamName; } const std::string& getInfo() const { return m_strInfo; } private: const char* m_szStreamName; const std::string m_strInfo; // may be empty, but it should have some details about what made it broken, if possible; or perhaps what could be decyphred from the stream before being being decided that it was broken }; // to be thrown from the constructor of a stream when it looks like an unsupported version of the stream was found in the input file. struct StreamIsUnsupported { // doesn't own the pointers; params are supposed to be string literals StreamIsUnsupported(const char* szStreamName, const std::string& strInfo) : m_szStreamName(szStreamName), m_strInfo(strInfo) {} const char* getStreamName() const { return m_szStreamName; } const std::string& getInfo() const { return m_strInfo; } private: const char* m_szStreamName; const std::string m_strInfo; // may be empty, but it should have some details about what made it unsupported, if possible }; // Normally streams that throw StreamIsUnsupported or StreamIsBroken end up as UnsupportedDataStream or BrokenDataStream //========================================================================== //========================================================================== //#include <QPixmap> // ttt2 would be nicer not to have to depend on Qt in this file, but some image library is needed anyway, so it might as well be Qt //========================================================================== //========================================================================== /* Times in ID3V2.4.0: TDRC - when the audio was recorded TDOR - when the original recording of the audio was released TDRL - when the audio was first released TDEN - when the audio was encoded TDTG - when the audio was tagged Format: subset of ISO 8601: yyyy-MM-ddTHH:mm:ss or shorter variants (truncated at the end) TDRC is the one used for TIME; corresponds to TYER and TDAT in ID3V2.3.0 */ //========================================================================== // uses strings in the format "yyyy-MM-ddTHH:mm:ss" or "yyyy-MM-dd HH:mm:ss" or any prefix truncated right after a group of digits; the empty string is valid, as is the null char* passed on constructor; // during initialization 'T' is changed to ' ' and then asString() uses this version, with ' ' class TagTimestamp { char m_szVal [20]; char m_szYear [5]; // either a 4-digit string or empty char m_szDayMonth [5]; // either a 4-digit string or empty; if m_strYear is empty, m_strDayMonth is empty too public: explicit TagTimestamp(const std::string&); // may throw InvalidTime; see init(); explicit TagTimestamp(const char* = 0); // may throw InvalidTime; see init(); const char* getYear() const { return m_szYear; } const char* getDayMonth() const { return m_szDayMonth; } const char* asString() const { return m_szVal; } void init(std::string strVal); // if strVal is invalid it clears m_strVal, m_strYear and m_strDayMonth and throws InvalidTime; the constructors call this too and let the exceptions propagate struct InvalidTime {}; }; struct TagReader { virtual ~TagReader(); enum Feature { TITLE, ARTIST, TRACK_NUMBER, TIME, GENRE, IMAGE, ALBUM, RATING, COMPOSER, VARIOUS_ARTISTS, LIST_END }; static const char* getLabel(int); // text representation for each Feature enum SuportLevel { NOT_SUPPORTED, READ_ONLY/*, READ_WRITE*/ }; struct FieldNotFound {}; // for variable field lists, to allow for the distinction between an empty field and a missing field virtual std::string getTitle(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // UTF8 virtual std::string getArtist(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // UTF8 virtual std::string getTrackNumber(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // this is string (and not int) because in ID3V2 it's not necessarily a (single) number; it can be 2/12 virtual TagTimestamp getTime(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } virtual std::string getGenre(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // UTF8 virtual ImageInfo getImage(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // !!! this must not be called from a non-GUI thread (see comment in Id3V2Stream<Frame>::preparePictureHlp); if there's a need to do so, perhaps switch from QPixmap to QImage virtual std::string getAlbumName(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // UTF8 virtual double getRating(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // 0 to 5 (5 for best); negative for unknown virtual std::string getComposer(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // UTF8 enum VariousArtists { VA_NONE = 0, VA_ITUNES = 1, VA_WMP = 2 }; virtual int getVariousArtists(bool* /*pbFrameExists*/ = 0) const { throw NotSupportedOp(); } // combination of VariousArtists flags; since several frames might be involved, *pbFrameExists is set to "true" if at least a frame exists virtual std::string getOtherInfo() const { return ""; } // non-editable tags virtual std::vector<ImageInfo> getImages() const { return std::vector<ImageInfo>(); } // all images, even those with errors virtual std::string getImageData(bool* pbFrameExists = 0) const { if (0 != pbFrameExists) { *pbFrameExists = false; } return ""; } virtual SuportLevel getSupport(Feature) const { return NOT_SUPPORTED; } virtual const char* getName() const = 0; std::string getValue(Feature) const; // returns the corresponding feature converted to a string; if it's not supported, it returns an empty string; for IMAGE an empty string regardless of a picture being present or not static std::string getVarArtistsValue(); // what getValue(VARIOUS_ARTISTS) returns for VA tags, based on global configuration static int FEATURE_ON_POS[]; // the order in which Features should appear in grids static int POS_OF_FEATURE[]; // the "inverse" of FEATURE_ON_POS: what Feature appears in a given position }; //========================================================================== //========================================================================== /* Position: std::streampos; actually should be using std::istream::pos_type, but streampos is shorter; if the traits template param for streams are not used, std::istream::pos_type is just a typedef for std::streampos; represents a position in a file as a class (not as some integral); has automatic convertion to std::streamoff, so arithmetic operations work, but not necessarily as expected; Relative position: std::streamoff; actually should be using std::istream::off_type, but streamoff is shorter; if the traits template param for streams are not used, std::istream::off_type is just a typedef for std::streamoff; signed integral, not necessarily big enough to represent any position in a file; the difference between 2 std::streampos objects is a streamoff; std::streamsize - count for I/O operations, e.g. bytes read; signed integral; may be smaller than streamoff // ttt2 perhaps replace "long long" with std::streamoff in file routines too, although "long long" seems well suited long-term and easier to deal with instead of the 3 types in std lib (it seems that the only reason the std lib doesn't just use "long long" is to avoid forcing 16bit and 32bit machines perform 64bit calculations); or, well, if we want to prepare for files with sizes exceeding 64bit, the type to use uniformly for positions, offsets and counts could be something implementation-specific that may be an integral type or a class that looks like a number (has +, -, *, /); on most systems it would just be defined to be "long long"; // 2008.09.08: actually streamoff is a typedef for fpos, which also cares about multi-byte characters, so a simple integral type may not be enough; still, it would be nice to be able to use streamoff everywhere for binary files and get rid of all the conversions and overflows; More: - Standard draft 27.4.4 - http://www.velocityreviews.com/forums/t287670-postype-how-to-define-it-.html */ #endif // #ifndef DataStreamH ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/NotesModel.h����������������������������������������������������������������0000644�0001750�0000144�00000006162�11200236325�015474� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef NotesModelH #define NotesModelH #include <QAbstractTableModel> #include "MultiLineTvDelegate.h" //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class CommonData; // current notes struct NotesModel : public QAbstractTableModel { Q_OBJECT public: NotesModel(CommonData* pCommonData); /*override*/ int rowCount(const QModelIndex&) const; /*override*/ int columnCount(const QModelIndex&) const; /*override*/ QVariant data(const QModelIndex&, int) const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; void matchSelToMain(); void matchSelToStreams(); CommonData* m_pCommonData; void emitLayoutChanged() { emit layoutChanged(); } public slots: void onNotesGSelChanged(); }; //class FilesGDelegate : public QAbstractItemDelegate //class NotesGDelegate : public QItemDelegate class NotesGDelegate : public MultiLineTvDelegate { Q_OBJECT public: //NotesGDelegate(CommonData* pCommonData, QObject* pParent) : QItemDelegate(pParent), m_pCommonData(pCommonData) {} NotesGDelegate(CommonData* pCommonData); /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; CommonData* m_pCommonData; }; #endif // #ifndef NotesModelH ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/ScanDlgImpl.h���������������������������������������������������������������0000644�0001750�0000144�00000004350�11230111215�015546� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef ScanDlgImplH #define ScanDlgImplH #include <QDialog> #include "ui_Scan.h" class CommonData; class CheckedDirModel; class ScanDlgImpl : public QDialog, private Ui::ScanDlg { Q_OBJECT CommonData* m_pCommonData; CheckedDirModel* m_pDirModel; public: ScanDlgImpl(QWidget* pParent, CommonData* pCommonData); bool run(bool& bForce); // if returning true, it also calls CommonData::setDirs() ~ScanDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pScanB_clicked() { accept(); } void on_m_pCancelB_clicked() { reject(); } void onShow(); void onHelp(); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/ColumnResizer.h�������������������������������������������������������������0000644�0001750�0000144�00000023532�11200236023�016217� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef ColumnResizerH #define ColumnResizerH #include <vector> class QTreeWidget; class QTableView; class QAbstractItemModel; /* ColumnResizer resizes the columns in a QTableView or a QTreeWidget, trying to maximize the number of cells that can be displayed without being truncated, while using no horizontal scrollbar. It can handle huge tables, because it doesn't read all the data in such a case. There is a threshold for the values in a column that are going to be considered (they are selected randomly). Of course, in some cases this may lead to less than optimal results, but that may happen anyway, because deciding which column is best to shrink and by how much is something quite subjective. A horizontal scrollbar may still be visible, if even after shrinking the columns need more space than the table has. To avoid such a thing, it is possible to manually assign fixed or minimum widths to various columns. This is done in a TableWidthInterface-derived object, which is what a ColumnResizer works with (it doesn't interact directly with QTableView or QTreeWidget). ColumnResizer doesn't really have an interface that the user calls. It does everything on its constructor. Note that for this to work correctly, all layouts must be applied before calling ColumnResizer, which may require a timer. See SimpleQTableViewWidthInterface for more details. The optional parameter bConsistentResults that is passed to ColumnResizer can be important if other parts of the current program use rand(). If there are more rows than nMaxRows, this triggers the pseudorandom selection of elements. If we want the same data to produce the same result, srand() must be called so the pseudorandom process always gives the same numbers. Calling srand() is something that other functions might not appreciate, which is why bConsistentResults is false by default. (A future version might use its own pseudorandom generator, which won't interfere with srand().) Usage sample: SimpleQTableViewWidthInterface intf1 (*tblView); intf1.setMinWidth(0, 50); intf1.setFixedWidth(2, 60); ColumnResizer rsz1 (intf1); */ //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== class TableWidthInterface { protected: //std::vector<double> m_vdFractionLimit; // fraction of the total table width (? min/max) std::vector<bool> m_vbFixedWidth; // if this is set, the width should be exactly getMinWidth() std::vector<int> m_vnMinWidth; std::vector<int> m_vnHdrWidth; public: TableWidthInterface(int nCols) { m_vbFixedWidth.resize(nCols); m_vnMinWidth.resize(nCols); m_vnHdrWidth.resize(nCols); } virtual ~TableWidthInterface() {} virtual int getTableWidth() const = 0; // space available for data columns virtual int getRowCount() const = 0; virtual int getColumnCount() const = 0; virtual int getRequestedWidth(int nRow, int nCol) const = 0; virtual bool isHidden(int nCol) const = 0; void setMinWidth(int nCol, int nLim) { m_vnMinWidth.at(nCol) = nLim; } void setFixedWidth(int nCol, int nLim) { m_vbFixedWidth.at(nCol) = true; m_vnMinWidth.at(nCol) = nLim; } bool hasFixedWidth(int nCol) const { return m_vbFixedWidth.at(nCol); } int getMinWidthDataHdr(int nCol) const // the minimum width required by the header or set explicitely { return std::max(m_vnMinWidth.at(nCol), m_vnHdrWidth.at(nCol)); } int getMinWidth(int nCol) const { return m_vnMinWidth.at(nCol); } virtual void setWidth(int nCol, int nWidth) = 0; // sets the column width for the underlying widget }; /* !!! Note that this class should be used after the table got displayed. There seems to be an issue in Qt 4.3 (and perhaps others), causing "resizeEvent()" to not get called after all the layouts are applied. As a result, incorrect sizes and scrollbars get used. The workaround is to use QTimer to do the calculations after laying out was done: "QTimer::singleShot(1, this, SLOT(onResizeTimer()));", where onResizeTimer does a table resizing. */ class SimpleQTableViewWidthInterface : public TableWidthInterface { std::vector<bool> m_vbBold; // bold is defined on a "per-column" basis; another class is needed to handle the "per-cell" case QTableView& m_tbl; QAbstractItemModel* m_pModel; /*override*/ int getTableWidth() const; // space available for data columns /*override*/ int getRowCount() const; /*override*/ int getColumnCount() const; /*override*/ int getRequestedWidth(int nRow, int nCol) const; /*override*/ bool isHidden(int nCol) const; /*override*/ void setWidth(int nCol, int nWidth); public: SimpleQTableViewWidthInterface(QTableView& tbl); void setBold(int nCol, bool bVal = true) { m_vbBold.at(nCol) = bVal; } }; /* !!! Note that this class should be used after the table got displayed. There seems to be an issue in Qt 4.3 (and perhaps others), causing "resizeEvent()" to not get called after all the layouts are applied. As a result, incorrect sizes and scrollbars get used. The workaround is to use QTimer to do the calculations after laying out was done: "QTimer::singleShot(1, this, SLOT(onResizeTimer()));", where onResizeTimer does a table resizing. */ class SimpleQTreeWidgetWidthInterface : public TableWidthInterface { std::vector<bool> m_vbBold; // bold is defined on a "per-column" basis; another class is needed to handle the "per-cell" case //ttt2 see if "bold" can actually be done QTreeWidget& m_tbl; /*override*/ int getTableWidth() const; // space available for data columns /*override*/ int getRowCount() const; /*override*/ int getColumnCount() const; /*override*/ int getRequestedWidth(int nRow, int nCol) const; /*override*/ bool isHidden(int nCol) const; /*override*/ void setWidth(int nCol, int nWidth); public: SimpleQTreeWidgetWidthInterface(QTreeWidget& tbl); void setBold(int nCol, bool bVal = true) { m_vbBold.at(nCol) = bVal; } }; /* nMaxRows sets a limit to how many values are considered for a column; useful because going through all of them may be too costly with big tables; if bFill is set, the columns get widened more than needed, so the whole area of the table gets covered (fixed-width columns don't get touched, though) */ class ColumnResizer { TableWidthInterface& m_intf; std::vector<std::vector<int> > m_vvAllWidths; int getFitCount(int nCol, int nWidth) const; // how many rows from a column can be shown completely for a given size struct ColInfo { int m_nLargeAvg; double m_dLargeDev; int m_nMinWidth; int m_nWidth; int m_nAskSmall; double m_dPrioSmall; // usually between 0 and 1, but may be higher for narrow columns int m_nAskLarge; double m_dPrioLarge; // between 0 and 1 }; void autoSize(bool bFill); int m_nMaxRows; bool m_bConsistentResults; int m_nTotalRows; int m_nUsedRows; int m_nCols; int m_nFixedWidthCount; std::vector<ColInfo> m_vColInfo; int m_nTotalWidth; int m_nTotalMax; int m_nTableWidth; void readAllWidths(); void computeColInfo(); void setUpMaxWidths(); void setUpAvgWidths(); void setUpMinWidths(); void distributeAskSmall(); void distributeAskLarge(); void distributeRemaining(); // several pixels might remain undistributed after distributeAskSmall() and distributeAskLarge() because of rounding errors; they are dealt with here; void setWidths(); void printWidths(const char* szLabel/*, std::ostream& out*/); void printCellInfo(const char* szLabel/*, std::ostream& out*/); class SequenceGen { std::vector<int> m_vn; int m_nCrt; double rnd() const; public: SequenceGen(int nTotalRows, int nTargetRows); int getNext() { return m_vn.at(m_nCrt++); } }; public: enum { DONT_FILL, FILL }; enum { INCONSISTENT_RESULTS, CONSISTENT_RESULTS }; ColumnResizer(TableWidthInterface& intf, int nMaxRows = 80, bool bFill = false, bool bConsistentResults = false); // resizing is achieved by just instantiating ColumnResizer }; #endif // #ifndef ColumnResizerH ����������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Config.ui�������������������������������������������������������������������0000644�0001750�0000144�00000326637�11271371714�015044� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>ConfigDlg</class> <widget class="QDialog" name="ConfigDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>991</width> <height>673</height> </rect> </property> <property name="minimumSize" > <size> <width>630</width> <height>440</height> </size> </property> <property name="windowTitle" > <string>Configuration</string> </property> <property name="sizeGripEnabled" > <bool>true</bool> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>-1</number> </property> <item> <widget class="QTabWidget" name="m_pMainTabWidget" > <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="currentIndex" > <number>0</number> </property> <widget class="QWidget" name="m_pFilesW" > <attribute name="title" > <string>Files</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_28" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QToolButton" name="m_pSimpleViewB" > <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>Simple view</string> </property> <property name="checkable" > <bool>true</bool> </property> <property name="checked" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pFullViewB" > <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>Full view</string> </property> <property name="checkable" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="m_pFileSettingsW" > <property name="sizePolicy" > <sizepolicy vsizetype="Expanding" hsizetype="Preferred" > <horstretch>0</horstretch> <verstretch>10</verstretch> </sizepolicy> </property> <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="m_pRemovableL" > <property name="text" > <string>Removable TextLabel</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QTabWidget" name="m_pDetailsTabWidget" > <property name="currentIndex" > <number>0</number> </property> <widget class="QWidget" name="m_pSimpleViewTab" > <attribute name="title" > <string>Tab 1</string> </attribute> <layout class="QVBoxLayout" > <property name="spacing" > <number>1</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>14</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pDontCreateBackupRB" > <property name="text" > <string>Don't create backup for modified files</string> </property> </widget> </item> <item> <layout class="QHBoxLayout" > <property name="spacing" > <number>9</number> </property> <item> <widget class="QRadioButton" name="m_pCreateBackupRB" > <property name="text" > <string>Create backup for modified files in</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pPODest2E" /> </item> <item> <widget class="QToolButton" name="m_pSelectOrigTransfDestDir2B" > <property name="text" > <string>...</string> </property> </widget> </item> </layout> </item> <item> <widget class="QRadioButton" name="m_pBackupCustomRB" > <property name="enabled" > <bool>false</bool> </property> <property name="text" > <string>Custom settings (go to full view to make changes)</string> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>241</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="m_pFullViewTab" > <attribute name="title" > <string>Tab 2</string> </attribute> <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QTabWidget" name="tabWidget" > <property name="tabPosition" > <enum>QTabWidget::North</enum> </property> <property name="tabShape" > <enum>QTabWidget::Rounded</enum> </property> <property name="currentIndex" > <number>0</number> </property> <widget class="QWidget" name="tab_3" > <attribute name="title" > <string>Original file that would be changed</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_15" > <layout class="QVBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pPODontChangeRB" > <property name="text" > <string>Don't touch</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pPOEraseRB" > <property name="text" > <string>Erase</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pPOMoveAlwaysChangeRB" > <property name="text" > <string>Move and change the name</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pPOMoveChangeIfNeededRB" > <property name="text" > <string>Move but change the name only if a name collision would occur</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pPOChangeNameRB" > <property name="text" > <string>Change name</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pPOMoveOrEraseRB" > <property name="text" > <string>Move if the destination doesn't already exist; erase if it does</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_3" > <property name="title" > <string>Name change params</string> </property> <layout class="QVBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QGroupBox" name="groupBox_2" > <property name="title" > <string>Identifying label</string> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pPODontUseLabelRB" > <property name="text" > <string>Don't use an identifying label</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pPOUseLabelRB" > <property name="text" > <string>Use "orig" as an identifying label</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_4" > <property name="title" > <string>Counter</string> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pPOAlwaysUseCounterRB" > <property name="text" > <string>Always use a counter</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pPOUseCounterIfNeededRB" > <property name="text" > <string>Only use a counter when a name collision would occur</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_15" > <property name="title" > <string>Destination</string> </property> <layout class="QHBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QLineEdit" name="m_pPODestE" /> </item> <item> <widget class="QToolButton" name="m_pSelectOrigTransfDestDirB" > <property name="text" > <string>...</string> </property> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>421</width> <height>37</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="tab_2" > <attribute name="title" > <string>Original file that would not be changed</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_16" > <layout class="QVBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pUODontChangeRB" > <property name="text" > <string>Don't touch</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pUOEraseRB" > <property name="text" > <string>Erase</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pUOMoveAlwaysChangeRB" > <property name="text" > <string>Move and change the name</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pUOMoveChangeIfNeededRB" > <property name="text" > <string>Move but change the name only if a name collision would occur</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pUOChangeNameRB" > <property name="text" > <string>Change name</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_6" > <property name="title" > <string>Name change params</string> </property> <layout class="QVBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QGroupBox" name="groupBox_7" > <property name="title" > <string>Identifying label</string> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pUODontUseLabelRB" > <property name="text" > <string>Don't use an identifying label</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pUOUseLabelRB" > <property name="text" > <string>Use "orig" as an identifying label</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_8" > <property name="title" > <string>Counter</string> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pUOAlwaysUseCounterRB" > <property name="text" > <string>Always use a counter</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pUOUseCounterIfNeededRB" > <property name="text" > <string>Only use a counter when a name collision would occur</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_14" > <property name="title" > <string>Destination</string> </property> <layout class="QHBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QLineEdit" name="m_pUODestE" /> </item> <item> <widget class="QToolButton" name="m_pSelectOrigNotTransfDestDirB" > <property name="text" > <string>...</string> </property> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>421</width> <height>37</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="tab_4" > <attribute name="title" > <string>Changed file</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_17" > <layout class="QVBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pProcDontCreateRB" > <property name="text" > <string>Don't create</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pProcCreateAlwaysChangeRB" > <property name="text" > <string>Create and change the name</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pProcCreateChangeIfNeededRB" > <property name="text" > <string>Create but change the name only if a name collision would occur</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_10" > <property name="title" > <string>Name change params</string> </property> <layout class="QVBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QGroupBox" name="groupBox_11" > <property name="title" > <string>Identifying label</string> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pProcDontUseLabelRB" > <property name="text" > <string>Don't use an identifying label</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pProcUseLabelRB" > <property name="text" > <string>Use "proc" as an identifying label</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_12" > <property name="title" > <string>Counter</string> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pProcAlwaysUseCounterRB" > <property name="text" > <string>Always use a counter</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pProcUseCounterIfNeededRB" > <property name="text" > <string>Only use a counter when a name collision would occur</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_13" > <property name="title" > <string>Destination</string> </property> <layout class="QGridLayout" > <property name="topMargin" > <number>0</number> </property> <property name="verticalSpacing" > <number>0</number> </property> <item row="0" column="0" > <widget class="QRadioButton" name="m_pProcUseSrcRB" > <property name="text" > <string>Use the source dir</string> </property> </widget> </item> <item row="1" column="0" > <widget class="QRadioButton" name="m_pProcUseSeparateDirRB" > <property name="text" > <string>Use</string> </property> </widget> </item> <item row="1" column="1" > <widget class="QWidget" native="1" name="widget_11" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLineEdit" name="m_pProcDestE" /> </item> <item> <widget class="QToolButton" name="m_pSelectTransfDestDirB" > <property name="text" > <string>...</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>591</width> <height>53</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="tab" > <attribute name="title" > <string>Temporary files</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QFrame" name="m_pSourceDirF" > <property name="frameShape" > <enum>QFrame::NoFrame</enum> </property> <property name="frameShadow" > <enum>QFrame::Raised</enum> </property> <layout class="QHBoxLayout" > <item> <widget class="QLabel" name="label" > <property name="text" > <string>Source directory</string> </property> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_9" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLineEdit" name="m_pSrcDirE" /> </item> <item> <widget class="QToolButton" name="m_pSelectSrcDirB" > <property name="text" > <string>...</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_16" > <property name="title" > <string>Temporary files</string> </property> <layout class="QGridLayout" > <property name="topMargin" > <number>0</number> </property> <property name="verticalSpacing" > <number>0</number> </property> <item row="0" column="0" > <widget class="QRadioButton" name="m_pTempDontCreateRB" > <property name="text" > <string>Don't create</string> </property> </widget> </item> <item row="1" column="0" > <widget class="QRadioButton" name="m_pTempCreateRB" > <property name="text" > <string>Create in</string> </property> </widget> </item> <item row="1" column="1" > <widget class="QWidget" native="1" name="widget_2" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLineEdit" name="m_pTempDestE" /> </item> <item> <widget class="QToolButton" name="m_pSelectTempDirB" > <property name="text" > <string>...</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_17" > <property name="title" > <string>Compare files</string> </property> <layout class="QGridLayout" > <property name="topMargin" > <number>0</number> </property> <property name="verticalSpacing" > <number>0</number> </property> <item row="0" column="0" > <widget class="QRadioButton" name="m_pCompDontCreateRB" > <property name="text" > <string>Don't create</string> </property> </widget> </item> <item row="1" column="0" > <widget class="QRadioButton" name="m_pCompCreateRB" > <property name="text" > <string>Create in</string> </property> </widget> </item> <item row="1" column="1" > <widget class="QWidget" native="1" name="widget_10" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLineEdit" name="m_pCompDestE" /> </item> <item> <widget class="QToolButton" name="m_pSelectCompDirB" > <property name="text" > <string>...</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>81</height> </size> </property> </spacer> </item> </layout> </widget> </widget> </item> </layout> </widget> </widget> </item> </layout> </widget> <widget class="QWidget" name="m_pIgnoredNotesW" > <attribute name="title" > <string>Ignored notes</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QWidget" native="1" name="m_pIgnoredNotesListHldr" /> </item> </layout> </widget> <widget class="QWidget" name="m_pCustomTransfW" > <attribute name="title" > <string>Custom transformation lists</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="widget" > <property name="maximumSize" > <size> <width>16777215</width> <height>150</height> </size> </property> <layout class="QHBoxLayout" > <property name="spacing" > <number>20</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_4" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_3" > <property name="minimumSize" > <size> <width>40</width> <height>0</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>16777215</height> </size> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QToolButton" name="m_pCustomTransform1B" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/transform1.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="checkable" > <bool>true</bool> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <widget class="QTextEdit" name="m_pCustomTransform1T" > <property name="tabChangesFocus" > <bool>true</bool> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_5" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_6" > <property name="minimumSize" > <size> <width>40</width> <height>0</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>16777215</height> </size> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QToolButton" name="m_pCustomTransform2B" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/transform2.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="checkable" > <bool>true</bool> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <widget class="QTextEdit" name="m_pCustomTransform2T" > <property name="tabChangesFocus" > <bool>true</bool> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_7" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_8" > <property name="minimumSize" > <size> <width>40</width> <height>0</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>16777215</height> </size> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QToolButton" name="m_pCustomTransform3B" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/transform3.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="checkable" > <bool>true</bool> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <widget class="QTextEdit" name="m_pCustomTransform3T" > <property name="tabChangesFocus" > <bool>true</bool> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_19" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_21" > <property name="minimumSize" > <size> <width>40</width> <height>0</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>16777215</height> </size> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QToolButton" name="m_pCustomTransform4B" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/transform4.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="checkable" > <bool>true</bool> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <widget class="QTextEdit" name="m_pCustomTransform4T" > <property name="tabChangesFocus" > <bool>true</bool> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="m_pTransfListHldr" > <property name="sizePolicy" > <sizepolicy vsizetype="Expanding" hsizetype="Preferred" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize" > <size> <width>0</width> <height>100</height> </size> </property> </widget> </item> </layout> </widget> <widget class="QWidget" name="m_pTransfParamW" > <attribute name="title" > <string>Transformation params</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QGroupBox" name="m_pLocaleGrp" > <property name="title" > <string>Locale for ID3V2 conversion</string> </property> <layout class="QGridLayout" > <property name="topMargin" > <number>0</number> </property> <item row="0" column="0" > <widget class="QComboBox" name="m_pLocaleCbB" > <property name="minimumSize" > <size> <width>200</width> <height>0</height> </size> </property> <property name="maxVisibleItems" > <number>30</number> </property> </widget> </item> <item row="0" column="1" > <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>181</width> <height>23</height> </size> </property> </spacer> </item> <item row="1" column="0" colspan="2" > <widget class="QTextBrowser" name="m_pCodepageTestM" /> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="m_pCaseGrp" > <property name="title" > <string>Case transformation</string> </property> <layout class="QHBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="label_12" > <property name="text" > <string>Artists</string> </property> </widget> </item> <item> <widget class="QComboBox" name="m_pArtistsCaseCbB" > <property name="minimumSize" > <size> <width>150</width> <height>0</height> </size> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeType" > <enum>QSizePolicy::Fixed</enum> </property> <property name="sizeHint" > <size> <width>31</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QLabel" name="label_13" > <property name="text" > <string>Others</string> </property> </widget> </item> <item> <widget class="QComboBox" name="m_pOthersCaseCbB" > <property name="minimumSize" > <size> <width>150</width> <height>0</height> </size> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <widget class="QCheckBox" name="m_pKeepOrigTimeCkB" > <property name="text" > <string>Keep original modification time when changing a file</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pKeepOneValidImgCkB" > <property name="text" > <string>Keep a single image for a file</string> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>787</width> <height>31</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="tab_6" > <attribute name="title" > <string>Visible Transformations</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="m_pVisibleTransformsHndlr" /> </item> </layout> </widget> <widget class="QWidget" name="m_pQualThreshW" > <attribute name="title" > <string>Quality thresholds</string> </attribute> <layout class="QGridLayout" > <item row="0" column="0" colspan="2" > <widget class="QLabel" name="label_8" > <property name="text" > <string>If the audio bitrate falls below these limits, warnings are generated. For VBR a low bitrate is less of an indicatior of poor quality, because if the signal is simple there's no need for higher bitrates. </string> </property> <property name="alignment" > <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> <property name="wordWrap" > <bool>true</bool> </property> </widget> </item> <item row="1" column="0" colspan="2" > <widget class="QLabel" name="label_9" > <property name="text" > <string>The bitrate is not the best quality indicator. Values from a "Lame header" (if present) are generally better, but these headers are not processed in the current version.</string> </property> <property name="alignment" > <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> <property name="wordWrap" > <bool>true</bool> </property> </widget> </item> <item row="2" column="0" colspan="2" > <widget class="QLabel" name="label_10" > <property name="text" > <string>Note that for mono streams, half of the value for "Dual Channel" is used.</string> </property> <property name="alignment" > <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> <property name="wordWrap" > <bool>true</bool> </property> </widget> </item> <item row="3" column="0" colspan="2" > <widget class="QLabel" name="label_11" > <property name="text" > <string/> </property> <property name="alignment" > <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> <property name="wordWrap" > <bool>true</bool> </property> </widget> </item> <item row="4" column="0" > <widget class="QWidget" native="1" name="widget_12" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Minimum" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <layout class="QGridLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item row="0" column="0" > <widget class="QLabel" name="label_2" > <property name="text" > <string>Stereo CBR</string> </property> </widget> </item> <item row="0" column="1" > <widget class="QComboBox" name="m_pQualStCbrCbB" > <property name="maxVisibleItems" > <number>15</number> </property> </widget> </item> <item row="1" column="0" > <widget class="QLabel" name="label_3" > <property name="text" > <string>Joint Stereo CBR</string> </property> </widget> </item> <item row="1" column="1" > <widget class="QComboBox" name="m_pQualJtStCbrCbB" > <property name="maxVisibleItems" > <number>15</number> </property> </widget> </item> <item row="2" column="0" > <widget class="QLabel" name="label_4" > <property name="text" > <string>Dual Channel CBR</string> </property> </widget> </item> <item row="2" column="1" > <widget class="QComboBox" name="m_pQualDlChCbrCbB" > <property name="maxVisibleItems" > <number>15</number> </property> </widget> </item> <item row="3" column="0" > <widget class="QLabel" name="label_5" > <property name="text" > <string>Stereo VBR</string> </property> </widget> </item> <item row="3" column="1" > <widget class="QSpinBox" name="m_pQualStVbrSB" > <property name="minimumSize" > <size> <width>70</width> <height>0</height> </size> </property> <property name="alignment" > <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> <property name="minimum" > <number>8</number> </property> <property name="maximum" > <number>448</number> </property> </widget> </item> <item row="4" column="0" > <widget class="QLabel" name="label_6" > <property name="text" > <string>Joint Stereo VBR</string> </property> </widget> </item> <item row="4" column="1" > <widget class="QSpinBox" name="m_pQualJtStVbrSB" > <property name="minimumSize" > <size> <width>70</width> <height>0</height> </size> </property> <property name="alignment" > <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> <property name="minimum" > <number>8</number> </property> <property name="maximum" > <number>448</number> </property> </widget> </item> <item row="5" column="0" > <widget class="QLabel" name="label_7" > <property name="text" > <string>Dual Channel VBR</string> </property> </widget> </item> <item row="5" column="1" > <widget class="QSpinBox" name="m_pQualDlChVbrSB" > <property name="minimumSize" > <size> <width>70</width> <height>0</height> </size> </property> <property name="alignment" > <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> <property name="minimum" > <number>8</number> </property> <property name="maximum" > <number>448</number> </property> </widget> </item> <item row="6" column="0" > <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>108</width> <height>41</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item row="4" column="1" > <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>381</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="tab_5" > <attribute name="title" > <string>Colors</string> </attribute> <layout class="QVBoxLayout" > <item> <layout class="QHBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_18" > <layout class="QGridLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item row="0" column="0" > <widget class="QToolButton" name="m_pCol0B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="0" column="1" > <widget class="QLabel" name="label_26" > <property name="text" > <string>Audio</string> </property> </widget> </item> <item row="1" column="0" > <widget class="QToolButton" name="m_pCol1B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="1" column="1" > <widget class="QLabel" name="label_27" > <property name="text" > <string>Xing and LAME</string> </property> </widget> </item> <item row="2" column="0" > <widget class="QToolButton" name="m_pCol2B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="2" column="1" > <widget class="QLabel" name="label_28" > <property name="text" > <string>VBRI</string> </property> </widget> </item> <item row="3" column="0" > <widget class="QToolButton" name="m_pCol3B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="3" column="1" > <widget class="QLabel" name="label_29" > <property name="text" > <string>ID3V2</string> </property> </widget> </item> <item row="4" column="0" > <widget class="QToolButton" name="m_pCol4B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="4" column="1" > <widget class="QLabel" name="label_30" > <property name="text" > <string>APIC</string> </property> </widget> </item> <item row="5" column="0" > <widget class="QToolButton" name="m_pCol5B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="5" column="1" > <widget class="QLabel" name="label_31" > <property name="text" > <string>ID3V2.3.0</string> </property> </widget> </item> <item row="6" column="0" > <widget class="QToolButton" name="m_pCol6B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="6" column="1" > <widget class="QLabel" name="label_32" > <property name="text" > <string>ID3V2.4.0</string> </property> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeType" > <enum>QSizePolicy::Fixed</enum> </property> <property name="sizeHint" > <size> <width>100</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QWidget" native="1" name="widget_24" > <layout class="QGridLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item row="0" column="0" > <widget class="QToolButton" name="m_pCol7B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="0" column="1" > <widget class="QLabel" name="label_20" > <property name="text" > <string>ID3V1</string> </property> </widget> </item> <item row="1" column="0" > <widget class="QToolButton" name="m_pCol8B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="1" column="1" > <widget class="QLabel" name="label_21" > <property name="text" > <string>Broken streams</string> </property> </widget> </item> <item row="2" column="0" > <widget class="QToolButton" name="m_pCol9B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="2" column="1" > <widget class="QLabel" name="label_22" > <property name="text" > <string>Truncated streams</string> </property> </widget> </item> <item row="3" column="0" > <widget class="QToolButton" name="m_pCol10B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="3" column="1" > <widget class="QLabel" name="label_23" > <property name="text" > <string>Unknown streams</string> </property> </widget> </item> <item row="4" column="0" > <widget class="QToolButton" name="m_pCol11B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="4" column="1" > <widget class="QLabel" name="label_24" > <property name="text" > <string>Lyrics</string> </property> </widget> </item> <item row="5" column="0" > <widget class="QToolButton" name="m_pCol12B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="5" column="1" > <widget class="QLabel" name="label_25" > <property name="text" > <string>Ape</string> </property> </widget> </item> <item row="6" column="0" > <widget class="QToolButton" name="m_pCol13B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="6" column="1" > <widget class="QLabel" name="label_19" > <property name="text" > <string>Others</string> </property> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>171</width> <height>20</height> </size> </property> </spacer> </item> </layout> </item> <item> <widget class="QWidget" native="1" name="widget_25" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QPushButton" name="m_pResetColorsB" > <property name="text" > <string>Reset to default colors</string> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>131</height> </size> </property> </spacer> </item> </layout> </widget> <widget class="QWidget" name="m_pOthersW" > <attribute name="title" > <string>Others</string> </attribute> <layout class="QVBoxLayout" > <item> <widget class="QGroupBox" name="groupBox_9" > <property name="title" > <string>Tag editor</string> </property> <layout class="QVBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_27" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_26" > <layout class="QVBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QCheckBox" name="m_pWarnOnNonSeqTracksCkB" > <property name="text" > <string>Warn when the tag editor enters albums with non-sequential track numbers</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pWarnOnPasteToNonSeqTracksCkB" > <property name="text" > <string>Warn when pasting track information in the tag editor for albums with non-sequential track numbers</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pFastSaveCkB" > <property name="text" > <string>Use "fast save" in the tag editor</string> </property> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_14" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="label_77" > <property name="text" > <string>Maximum image size, in kB</string> </property> </widget> </item> <item> <widget class="QSpinBox" name="m_pMaxImgSizeSB" > <property name="toolTip" > <string>If an image size is above this value, it will be recompressed before storing it inside MP3 files</string> </property> <property name="minimum" > <number>5</number> </property> <property name="maximum" > <number>1000</number> </property> <property name="value" > <number>100</number> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <item> <widget class="QGroupBox" name="m_pVarArtistsGrp" > <property name="minimumSize" > <size> <width>200</width> <height>70</height> </size> </property> <property name="title" > <string>Handle "various artists" for</string> </property> <layout class="QHBoxLayout" > <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <item> <layout class="QVBoxLayout" > <item> <widget class="QCheckBox" name="m_pItunesCkB" > <property name="text" > <string>iTunes</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pWmpCkB" > <property name="text" > <string>Windows Media Player</string> </property> </widget> </item> </layout> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeType" > <enum>QSizePolicy::Minimum</enum> </property> <property name="sizeHint" > <size> <width>30</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>2</height> </size> </property> </spacer> </item> </layout> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_22" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QGroupBox" name="groupBox_21" > <property name="title" > <string>If a field is marked as "assigned" when exiting an album</string> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pAssgnSaveRB" > <property name="text" > <string>Save automatically</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pAssgnDiscardRB" > <property name="text" > <string>Discard</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pAssgnAskRB" > <property name="text" > <string>Ask</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_22" > <property name="title" > <string>If a field's value is different from that in the ID3V2 tag when exiting an album</string> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <item> <widget class="QRadioButton" name="m_pNonId3v2SaveRB" > <property name="text" > <string>Save automatically</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pNonId3v2DiscardRB" > <property name="text" > <string>Discard</string> </property> </widget> </item> <item> <widget class="QRadioButton" name="m_pNonId3v2AskRB" > <property name="text" > <string>Ask</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="m_pOthersMiscGrp" > <property name="title" > <string>Misc</string> </property> <layout class="QVBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <layout class="QHBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_13" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Expanding" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <layout class="QVBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>10</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QCheckBox" name="m_pScanAtStartupCkB" > <property name="text" > <string>Scan for new, modified, and deleted files at startup</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pShowExportCkB" > <property name="text" > <string>Show "Export" button</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pShowDebugCkB" > <property name="text" > <string>Show "Debug" button</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pShowSessCkB" > <property name="text" > <string>Show "Sessions" button</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pTraceToFileCkB" > <property name="text" > <string>Log program state to "_trace" and "_step" files</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pCheckForUpdatesCkB" > <property name="text" > <string>Check for new version at startup</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="m_pFontsW" > <layout class="QGridLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item row="0" column="0" > <widget class="QLabel" name="label_14" > <property name="text" > <string>General font:</string> </property> </widget> </item> <item row="0" column="1" > <widget class="QLabel" name="m_pGeneralFontL" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Minimum" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text" > <string>TextLabel</string> </property> </widget> </item> <item row="0" column="2" > <widget class="QPushButton" name="m_pChangeGenFontB" > <property name="text" > <string>Change ...</string> </property> </widget> </item> <item row="0" column="3" > <widget class="QLabel" name="label_18" > <property name="text" > <string>Label font smaller by:</string> </property> </widget> </item> <item row="0" column="4" > <widget class="QSpinBox" name="m_pDecrLabelFontSB" > <property name="maximum" > <number>5</number> </property> </widget> </item> <item row="1" column="0" > <widget class="QLabel" name="label_15" > <property name="text" > <string>Fixed font:</string> </property> </widget> </item> <item row="1" column="1" > <widget class="QLabel" name="m_pFixedFontL" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Minimum" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text" > <string>TextLabel</string> </property> </widget> </item> <item row="1" column="2" > <widget class="QPushButton" name="m_pChangeFixedFontB" > <property name="text" > <string>Change ...</string> </property> </widget> </item> </layout> </widget> </item> </layout> </item> <item> <widget class="QWidget" native="1" name="m_pIconConfW" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="label_17" > <property name="text" > <string>Icon size</string> </property> </widget> </item> <item> <widget class="QSpinBox" name="m_pIconSizeSB" > <property name="minimum" > <number>20</number> </property> <property name="maximum" > <number>64</number> </property> <property name="value" > <number>40</number> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pAutoSizeIconsCkB" > <property name="text" > <string>Auto-size icons based on the width of the main window</string> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_23" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QGroupBox" name="m_pNormalizeGrp" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > <horstretch>7</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="title" > <string>Normalizer</string> </property> <layout class="QVBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_20" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="label_16" > <property name="text" > <string>Command (file names will get added at the end)</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pNormalizerE" /> </item> </layout> </widget> </item> <item> <widget class="QCheckBox" name="m_pKeepNormOpenCkB" > <property name="text" > <string>Keep the window open after completion</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="m_pRenamerGrp" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > <horstretch>4</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="title" > <string>File renamer</string> </property> <layout class="QGridLayout" > <property name="topMargin" > <number>0</number> </property> <item row="0" column="0" > <widget class="QLabel" name="label_33" > <property name="text" > <string>Invalid characters</string> </property> </widget> </item> <item row="0" column="1" > <widget class="QLineEdit" name="m_pInvalidCharsE" /> </item> <item row="1" column="0" > <widget class="QLabel" name="label_34" > <property name="text" > <string>Replace with</string> </property> </widget> </item> <item row="1" column="1" > <widget class="QLineEdit" name="m_pInvalidReplacementE" /> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>161</width> <height>66</height> </size> </property> </spacer> </item> </layout> </widget> </widget> </item> <item> <widget class="QFrame" name="frame" > <property name="minimumSize" > <size> <width>0</width> <height>0</height> </size> </property> <property name="frameShape" > <enum>QFrame::NoFrame</enum> </property> <property name="frameShadow" > <enum>QFrame::Raised</enum> </property> <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QPushButton" name="m_pOkB" > <property name="text" > <string>O&K</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pCancelB" > <property name="text" > <string>Cancel</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> <tabstops> <tabstop>m_pOkB</tabstop> <tabstop>m_pCancelB</tabstop> <tabstop>m_pCustomTransform1T</tabstop> <tabstop>m_pCustomTransform2T</tabstop> <tabstop>m_pCustomTransform3T</tabstop> <tabstop>m_pCustomTransform4T</tabstop> <tabstop>m_pQualStCbrCbB</tabstop> <tabstop>m_pQualJtStCbrCbB</tabstop> <tabstop>m_pQualDlChCbrCbB</tabstop> <tabstop>m_pQualStVbrSB</tabstop> <tabstop>m_pQualJtStVbrSB</tabstop> <tabstop>m_pQualDlChVbrSB</tabstop> <tabstop>m_pLocaleCbB</tabstop> <tabstop>m_pCodepageTestM</tabstop> <tabstop>m_pArtistsCaseCbB</tabstop> <tabstop>m_pOthersCaseCbB</tabstop> <tabstop>m_pKeepOrigTimeCkB</tabstop> <tabstop>m_pAssgnSaveRB</tabstop> <tabstop>m_pAssgnDiscardRB</tabstop> <tabstop>m_pAssgnAskRB</tabstop> <tabstop>m_pNonId3v2SaveRB</tabstop> <tabstop>m_pNonId3v2DiscardRB</tabstop> <tabstop>m_pNonId3v2AskRB</tabstop> <tabstop>m_pIconSizeSB</tabstop> </tabstops> <resources> <include location="Mp3Diags.qrc" /> </resources> <connections/> </ui> �������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/���������������������������������������������������������������������0000755�0001750�0000144�00000000000�12036514073�014521� 5����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/document-save.svg����������������������������������������������������0000644�0001750�0000144�00000030662�11102267310�020013� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="88" height="88" id="svg1307" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/david/Documents/Projects/KDE/Oxygen/kdelibs/scalable/actions/small/22x22" sodipodi:docname="document-save.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" inkscape:export-filename="/home/david/Documents/Projects/KDE/Oxygen/kdelibs/scalable/actions/small/22x22/document-save.png" inkscape:export-xdpi="22.5" inkscape:export-ydpi="22.5"> <defs id="defs1309"> <linearGradient id="linearGradient3291"> <stop style="stop-color:black;stop-opacity:1" offset="0" id="stop3293" /> <stop style="stop-color:black;stop-opacity:0" offset="1" id="stop3295" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient12049"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop12051" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop12053" /> </linearGradient> <linearGradient id="linearGradient2497"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop2499" /> <stop id="stop11148" offset="0.5" style="stop-color:#ececec;stop-opacity:1;" /> <stop style="stop-color:#c1c1c1;stop-opacity:1;" offset="1" id="stop2501" /> </linearGradient> <linearGradient id="linearGradient3251"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3253" /> <stop id="stop14161" offset="0.7087912" style="stop-color:#090909;stop-opacity:0.67870039;" /> <stop style="stop-color:#131313;stop-opacity:0;" offset="1" id="stop3255" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3235"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3237" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3239" /> </linearGradient> <linearGradient id="linearGradient3149"> <stop id="stop3151" offset="0" style="stop-color:#8e8e8e;stop-opacity:1;" /> <stop id="stop3153" offset="1" style="stop-color:#f8f8f8;stop-opacity:1;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient12049" id="linearGradient22415" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.964922,0,0,0.941137,2.09495,7.906447)" x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient12049" id="linearGradient22417" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.494916e-2,95.46583,-43.1294)" x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3235" id="linearGradient22419" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.263178e-2,0,0,5.494916e-2,95.425679,-42.65827)" x1="-2165.3125" y1="2087.9343" x2="-643.06091" y2="1121.7122" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3149" id="linearGradient22421" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.266449e-2,95.46583,-35.606353)" x1="605.17242" y1="3835.6428" x2="-1062.9232" y2="1799.6183" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3235" id="linearGradient22423" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.263178e-2,0,0,5.494916e-2,95.425679,-43.1294)" x1="88.705498" y1="1010.6574" x2="-356.67282" y2="1234.8125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2497" id="radialGradient22425" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.2631778e-2,0,0,9.760431e-2,95.425676,-122.0552)" cx="-519.35938" cy="1724.4219" fx="-519.35938" fy="1724.4219" r="499.35941" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3235" id="linearGradient6203" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.263178e-2,0,0,5.494916e-2,92.625681,-43.1294)" x1="88.705498" y1="1010.6574" x2="-356.67282" y2="1234.8125" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="44" inkscape:cy="44" inkscape:current-layer="g18320" showgrid="false" inkscape:document-units="px" inkscape:grid-bbox="true" guidetolerance="0.1px" showguides="false" inkscape:guide-bbox="true" inkscape:window-width="794" inkscape:window-height="738" inkscape:window-x="0" inkscape:window-y="0" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" inkscape:grid-points="true" width="88px" height="88px" showborder="false" gridtolerance="10000"> <sodipodi:guide orientation="vertical" position="-1365.2977" id="guide2288" /> </sodipodi:namedview> <metadata id="metadata1312"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:contributor> <cc:Agent> <dc:title>Oxygen team</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/LGPL/2.1/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer"> <path sodipodi:nodetypes="ccc" id="path2276" d="M 35.066204,7.307497 L 35.066204,5.464691 L 35.066204,7.307497 z " style="fill:white;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <g id="g18320" transform="matrix(0.714286,0,0,0.714286,-1.714287,-5.714247)"> <path style="opacity:0.08196722;fill:url(#linearGradient22415);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 10.628479,8.4652472 C 8.8673095,8.5903719 8.0050972,9.6618224 8.0050972,11.406299 L 8.0050972,82.02096 C 32.521811,46.530692 55.281152,23.649512 75.73056,8.788763 L 19.282623,8.788763 L 19.282623,8.4652472 L 10.990325,8.4652472 C 10.864909,8.4652472 10.74589,8.4569056 10.628479,8.4652472 z M 119.72497,14.81792 C 83.579397,52.816092 54.569378,102.04945 43.891728,125.76385 L 116.07995,125.76385 C 118.25389,125.76385 119.99994,124.06084 119.99995,121.94048 L 119.93605,15.023794 L 119.72497,14.81792 z " id="path12057" sodipodi:nodetypes="cccccccccccccc" /> <path sodipodi:nodetypes="ccccccccccccccccc" id="path1410" d="M 11.003129,8.0400556 C 8.9964822,8.0400556 8.0157887,9.1208673 8.0157887,10.988425 L 7.9999986,121.93277 C 7.9999986,124.06085 9.750128,125.77405 11.924069,125.77406 L 116.07588,125.77406 C 118.24982,125.77406 119.99994,124.06085 119.99995,121.93277 L 119.92103,14.623657 L 113.09906,8.0400556 L 107.9769,8.0400556 L 107.9769,8.354299 L 98.69035,8.354299 L 97.499269,10.773777 L 94.527713,10.861354 L 94.527713,8.354299 L 19.279281,8.354299 L 19.279281,8.0400556 L 11.003129,8.0400556 z " style="fill:#1c1c1c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="opacity:0.2213115;fill:url(#linearGradient22417);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 11.003129,8.0400556 C 8.9964822,8.0400556 8.0157887,9.1208673 8.0157887,10.988425 L 7.9999986,121.93277 C 7.9999986,124.06085 9.750128,125.77405 11.924069,125.77406 L 116.07588,125.77406 C 118.24982,125.77406 119.99994,124.06085 119.99995,121.93277 L 119.92103,14.623657 L 113.09906,8.0400556 L 107.9769,8.0400556 L 107.9769,8.354299 L 98.69035,8.354299 L 97.499269,10.773777 L 94.527713,10.861354 L 94.527713,8.354299 L 19.279281,8.354299 L 19.279281,8.0400556 L 11.003129,8.0400556 z " id="path11174" sodipodi:nodetypes="ccccccccccccccccc" /> <path id="rect2296" d="M 107.99408,122.78378 L 107.99408,62.851569 C 107.99408,60.811972 106.24395,59.169994 104.07001,59.169994 L 22.997753,59.169994 C 22.963786,59.169994 22.92977,59.169197 22.896011,59.169994 C 20.769396,59.220203 19.073688,60.843841 19.073688,62.851569 L 19.073688,122.78378" style="fill:url(#linearGradient22421);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.88860911;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" sodipodi:nodetypes="ccccccc" /> <path sodipodi:nodetypes="cccccccccccc" id="rect2478" d="M 41.808705,11.471733 L 41.599985,43.969469 C 41.599997,45.833574 42.95943,47.335102 44.647697,47.335102 L 89.05451,47.199925 C 90.742788,47.199925 92.10222,45.69841 92.10222,43.834292 L 91.999965,11.43162 L 41.808705,11.471733 z M 75.199972,19.199936 L 86.399967,19.199936 L 86.399967,41.599927 L 75.199972,41.599927 L 75.199972,19.199936 z " style="fill:url(#radialGradient22425);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4174" width="67.199974" height="2.799999" x="30.399988" y="72.399918" /> <rect y="89.199936" x="30.399988" height="2.799999" width="67.199974" id="rect4176" style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> <rect style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4178" width="67.199974" height="2.799999" x="30.399988" y="105.99995" /> </g> </g> </svg> ������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/zoom-in.png����������������������������������������������������������0000644�0001750�0000144�00000002167�10704447121�016624� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���������Ĵl;���sBIT|d��� pHYs��v��v}Ղ���tEXtSoftware�www.inkscape.org<��IDAT8mL[Uǟ�IeIYP]Hbld@(.Nqq.!Fct A%Ę6`:ˆN8Xp\(=Bɓs<?W3?jOB"?=ee'ߑ-˿.-Ex덫;Mg>8;TTT'NduY6')%,V1=lmi%"XzD~pd%Q M<� ,��O8vj]n �KG~.%@NTU,[msLkk߂wEťSR' ~KסFxS>\Z>a)ђ#<L߲dUbv�ȶHV3""܅yٶt,K"Ji{nEǫ?|Af@g?  P1xS%�no8_DQ �J͂hЄ�HE8cgfffMhWc^_�HžPq" Tv+ie�D9_M$i{LDc+jԖb)d\gF X58uflsfV%k,bi��cc8sCA]-⌔Yӹ\ 9I5;s]xtP2<<aYYyVV@j)؞�H2 q{nY#Y[��"'Oyt|o'Ǭf2Y)5~crrӑ!Ԝ}+/!ڧ|P{vodȹ?2>6}L"o$>I*$I* 溺MMM<S__G`]K C4;;KCҶpS  < HuuuӠBD! s~WG ހwtt .,,WՊ/|sss�x3� 2����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/remove_file.png������������������������������������������������������0000644�0001750�0000144�00000002212�10704447121�017517� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���������Ĵl;���sBIT|d��� pHYs��a��a0U���tEXtSoftware�www.inkscape.org<��IDAT8moUޙ-K](v6R hh ~>ZF}٨$Aj ^@Lx.vvs}X M=79c?d= JZ""y9Y㑐3UUլkkjcp~29Dmp{1&LlDۧhӪXmC'!6ޅaÇ|6\)v#[ǟll)8;9 s~fK-B,OV 6֘_pS)us%5twb a;֩V~o&ͷQ/Bk&bxڦx/w2Ia]5:oy}ƶ?iʶ iGoܺE&T#Z֭]Xp:'j%iB&w"-<Ukֱ/AbP(c-;[`-'_Ɵbu"|�;;3(~: hT Z 4Q$  Q=BO{+B>Ln YL6fA9Hc,@rn?x�B)bB &)-e(Ed@bv:~s7 {K.V~<EyM5(ADŪ0v�lmҩ4־wi=C=|wBf&8w4gӳ;|V$ڏ=www/ut+80 |XcwaH0H |ϛ~'ٟQQ"%;pᣝ�w} "Z#JxK{Ń=jʦf֮l6.^<?3z{!.p%`Ǔ\_hۻHaHW�2QE`uk˽^ut-kmmGDe'O-N-]|rߵ^s# ;W�at|w6W,hzQ~#&(F?)pi a_����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/edit-copy.svg��������������������������������������������������������0000644�0001750�0000144�00000067412�11151311360�017140� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> <svg xmlns:ns="http://ns.adobe.com/SaveForWeb/1.0/" xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" id="Layer_1" width="88" height="88" viewBox="0 0 128 128" overflow="visible" enable-background="new 0 0 128 128" xml:space="preserve" sodipodi:version="0.32" inkscape:version="0.44" sodipodi:docname="editcopy.svg" sodipodi:docbase="/home/david/Progetti/oxygen-svn/Oxygen/theme/svg/actions/small/22x22"><defs id="defs105"><radialGradient inkscape:collect="always" xlink:href="#linearGradient3291" id="radialGradient1880" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.001373,0,0,8.253045e-2,4.25e-5,113.1757)" cx="63.912209" cy="115.70919" fx="63.912209" fy="115.7093" r="63.912209" /><linearGradient id="linearGradient3291"><stop style="stop-color:black;stop-opacity:1" offset="0" id="stop3293" /><stop style="stop-color:black;stop-opacity:0" offset="1" id="stop3295" /></linearGradient><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient18668"> <stop id="stop18670" style="stop-color:#fff8a8;stop-opacity:1;" offset="0" /> <stop id="stop18672" style="stop-color:white;stop-opacity:0;" offset="1" /> </linearGradient><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient15967"> <stop id="stop15969" style="stop-color:white;stop-opacity:1;" offset="0" /> <stop id="stop15971" style="stop-color:white;stop-opacity:0;" offset="1" /> </linearGradient><linearGradient id="XMLID_2_" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop12" /> <stop offset="1" style="stop-color:#FFCC00" id="stop14" /> </linearGradient><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient2391" gradientUnits="userSpaceOnUse" x1="94.343803" y1="102.3447" x2="86.535599" y2="94.536598" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient2393" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="86.586502" y2="94.586502" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient2395" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="87.292999" y2="95.292999" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient2397" gradientUnits="userSpaceOnUse" x1="96" y1="104" x2="88.000198" y2="96.000198" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient2465" gradientUnits="userSpaceOnUse" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient2467" gradientUnits="userSpaceOnUse" cx="102" cy="112.3047" r="139.55859" /> <foreignObject requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/" x="0" y="0" width="1" height="1" id="foreignObject7"> <i:pgfRef xlink:href="#adobe_illustrator_pgf"> </i:pgfRef> </foreignObject> <linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient12378" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient14180" gradientUnits="userSpaceOnUse" x1="-74.820709" y1="100.82378" x2="-18.121965" y2="100.82378" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient14189" gradientUnits="userSpaceOnUse" x1="-74.820709" y1="100.82378" x2="-18.121965" y2="100.82378" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient15967" id="linearGradient15973" gradientUnits="userSpaceOnUse" x1="27.719746" y1="7.881104" x2="27.719746" y2="30.441185" gradientTransform="translate(1.470416e-5,0)" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient15977" gradientUnits="userSpaceOnUse" x1="-74.820709" y1="100.82378" x2="-18.121965" y2="100.82378" /><radialGradient inkscape:collect="always" xlink:href="#linearGradient15967" id="radialGradient15986" cx="26.954102" cy="31.045055" fx="26.954102" fy="31.045055" r="8.968153" gradientTransform="matrix(0.754978,-2.959381e-2,0,0.905772,7.650275,10.87807)" gradientUnits="userSpaceOnUse" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient18657" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /> <linearGradient id="linearGradient18649" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop18651" /> <stop offset="1" style="stop-color:#FFCC00" id="stop18653" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient18674" gradientUnits="userSpaceOnUse" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient18746" gradientUnits="userSpaceOnUse" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient1992" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.829788,0,0,0.854545,10.89361,13.3091)" cx="102" cy="112.3047" r="139.55859" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient1995" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" cx="102" cy="112.3047" r="139.5585" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient2932" gradientUnits="userSpaceOnUse" x1="96" y1="104" x2="88.000198" y2="96.000198" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient2935" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="87.292999" y2="95.292999" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient2938" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="86.586502" y2="94.586502" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient2941" gradientUnits="userSpaceOnUse" x1="94.343803" y1="102.3447" x2="86.535599" y2="94.536598" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient3851" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient3853" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.829788,0,0,0.854545,10.89361,13.3091)" cx="102" cy="112.3047" r="139.55859" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient3855" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" x1="94.343803" y1="102.3447" x2="86.535599" y2="94.536598" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient3857" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" x1="95" y1="103" x2="86.586502" y2="94.586502" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient3859" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" x1="95" y1="103" x2="87.292999" y2="95.292999" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient3861" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" x1="96" y1="104" x2="88.000198" y2="96.000198" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient3885" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient3887" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.829788,0,0,0.854545,10.89361,13.3091)" cx="102" cy="112.3047" r="139.55859" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient3889" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" x1="94.343803" y1="102.3447" x2="86.535599" y2="94.536598" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient3891" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" x1="95" y1="103" x2="86.586502" y2="94.586502" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient3893" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" x1="95" y1="103" x2="87.292999" y2="95.292999" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient3895" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.833334,0,0,0.857143,10.66666,13.14286)" x1="96" y1="104" x2="88.000198" y2="96.000198" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient5587" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" x1="96" y1="104" x2="88.000198" y2="96.000198" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient5590" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" x1="95" y1="103" x2="87.292999" y2="95.292999" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient5593" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" x1="95" y1="103" x2="86.586502" y2="94.586502" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient5596" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" x1="94.343803" y1="102.3447" x2="86.535599" y2="94.536598" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient5599" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.835591,0,0,0.819834,22.1586,17.34877)" cx="102" cy="112.3047" r="139.55859" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient5602" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient8312" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient8314" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.835591,0,0,0.819834,22.1586,17.34877)" cx="102" cy="112.3047" r="139.55859" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient8316" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" x1="94.343803" y1="102.3447" x2="86.535599" y2="94.536598" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient8318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" x1="95" y1="103" x2="86.586502" y2="94.586502" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient8320" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" x1="95" y1="103" x2="87.292999" y2="95.292999" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient8322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.848486,0,0,0.831169,21.33332,16.62339)" x1="96" y1="104" x2="88.000198" y2="96.000198" /></defs><sodipodi:namedview inkscape:window-height="694" inkscape:window-width="1018" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" inkscape:zoom="5.6022727" inkscape:cx="44" inkscape:cy="57.436552" inkscape:window-x="0" inkscape:window-y="0" inkscape:current-layer="Layer_1" showgrid="true" gridspacingx="4px" gridspacingy="4px" gridempspacing="0" width="88px" height="88px" showguides="true" inkscape:guide-bbox="true" /> <metadata id="metadata3"> <ns:sfw> <ns:slices> <ns:slice y="0" x="0" height="128" width="128" sliceID="1316743234" /> </ns:slices> <ns:sliceSourceBounds y="0" x="0" height="128" width="128" bottomLeftOrigin="true" /> <ns:optimizationSettings> <ns:targetSettings targetSettingsID="0" fileFormat="PNG24Format"> <ns:PNG24Format transparency="true" filtered="false" matteColor="#FFFFFF" noMatteColor="false" interlaced="false"> </ns:PNG24Format> </ns:targetSettings> <ns:targetSettings targetSettingsID="1696735251" fileFormat="PNG24Format"> <ns:PNG24Format transparency="true" filtered="false" matteColor="#FFFFFF" noMatteColor="false" interlaced="false"> </ns:PNG24Format> </ns:targetSettings> </ns:optimizationSettings> </ns:sfw> <rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata> <radialGradient id="XMLID_7_" cx="102" cy="112.3047" r="139.5585" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#00537D" id="stop16" /> <stop offset="0.0151" style="stop-color:#186389" id="stop18" /> <stop offset="0.0558" style="stop-color:#558CA8" id="stop20" /> <stop offset="0.0964" style="stop-color:#89AFC3" id="stop22" /> <stop offset="0.1357" style="stop-color:#B3CCD8" id="stop24" /> <stop offset="0.1737" style="stop-color:#D4E2E9" id="stop26" /> <stop offset="0.2099" style="stop-color:#ECF2F5" id="stop28" /> <stop offset="0.2435" style="stop-color:#FAFCFD" id="stop30" /> <stop offset="0.2722" style="stop-color:#FFFFFF" id="stop32" /> </radialGradient> <radialGradient id="XMLID_8_" cx="102" cy="112.3047" r="139.55859" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#535557" id="stop37" /> <stop offset="0.11366145" style="stop-color:#898A8C" id="stop41" /> <stop offset="0.20296688" style="stop-color:#ECECEC" id="stop47" /> <stop offset="0.2363" style="stop-color:#FAFAFA" id="stop49" /> <stop offset="0.2722" style="stop-color:#FFFFFF" id="stop51" /> <stop offset="0.5313" style="stop-color:#FAFAFA" id="stop53" /> <stop offset="0.8449" style="stop-color:#EBECEC" id="stop55" /> <stop offset="1" style="stop-color:#E1E2E3" id="stop57" /> </radialGradient> <linearGradient id="XMLID_9_" gradientUnits="userSpaceOnUse" x1="94.343803" y1="102.3447" x2="86.535599" y2="94.536598"> <stop offset="0" style="stop-color:#FFFFFF" id="stop62" /> <stop offset="1" style="stop-color:#555753" id="stop64" /> </linearGradient> <linearGradient id="XMLID_10_" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="86.586502" y2="94.586502"> <stop offset="0" style="stop-color:#FFFFFF" id="stop69" /> <stop offset="1" style="stop-color:#555753" id="stop71" /> </linearGradient> <linearGradient id="XMLID_11_" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="87.292999" y2="95.292999"> <stop offset="0" style="stop-color:#FFFFFF" id="stop76" /> <stop offset="1" style="stop-color:#393B38" id="stop78" /> </linearGradient> <linearGradient id="XMLID_12_" gradientUnits="userSpaceOnUse" x1="96" y1="104" x2="88.000198" y2="96.000198"> <stop offset="0" style="stop-color:#888A85" id="stop83" /> <stop offset="0.0072" style="stop-color:#8C8E89" id="stop85" /> <stop offset="0.0673" style="stop-color:#ABACA9" id="stop87" /> <stop offset="0.1347" style="stop-color:#C5C6C4" id="stop89" /> <stop offset="0.2115" style="stop-color:#DBDBDA" id="stop91" /> <stop offset="0.3012" style="stop-color:#EBEBEB" id="stop93" /> <stop offset="0.4122" style="stop-color:#F7F7F6" id="stop95" /> <stop offset="0.5679" style="stop-color:#FDFDFD" id="stop97" /> <stop offset="1" style="stop-color:#FFFFFF" id="stop99" /> </linearGradient> <path id="path4416" style="opacity:0.38139535;fill:url(#radialGradient1880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 127.99994,122.72528 C 127.99994,125.63843 99.346193,128 64.000012,128 C 28.653812,128 5.75e-05,125.63843 5.75e-05,122.72528 C 5.75e-05,119.81215 28.653812,117.45058 64.000012,117.45058 C 99.346193,117.45058 127.99994,119.81215 127.99994,122.72528 L 127.99994,122.72528 z " /><g id="g8290" transform="translate(-23.27272,-17.45454)"><path id="path8292" transform="scale(1.454545,1.454545)" d="M 24,16 L 24,78.84375 C 24,79.47461 24.51225,80 25.15625,80 L 59.6875,80 C 59.996669,80.000003 60.28125,79.87053 60.5,79.65625 C 60.499998,79.656252 67.447919,73.986608 70.65625,70.84375 C 73.864585,67.700892 79.65625,60.90625 79.65625,60.90625 C 79.874997,60.691963 80,60.396606 80,60.09375 L 80,16 L 24,16 z " style="opacity:0.1;fill:none;stroke:black;stroke-width:8.00000286;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path style="opacity:0.25;fill:none;stroke:black;stroke-width:2.00000072;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 24,16 L 24,78.84375 C 24,79.47461 24.51225,80 25.15625,80 L 59.6875,80 C 59.996669,80.000003 60.28125,79.87053 60.5,79.65625 C 60.499998,79.656252 67.447919,73.986608 70.65625,70.84375 C 73.864585,67.700892 79.65625,60.90625 79.65625,60.90625 C 79.874997,60.691963 80,60.396606 80,60.09375 L 80,16 L 24,16 z " transform="scale(1.454545,1.454545)" id="path8294" /><path style="opacity:0.15;fill:none;stroke:black;stroke-width:6.00000191;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 24,16 L 24,78.84375 C 24,79.47461 24.51225,80 25.15625,80 L 59.6875,80 C 59.996669,80.000003 60.28125,79.87053 60.5,79.65625 C 60.499998,79.656252 67.447919,73.986608 70.65625,70.84375 C 73.864585,67.700892 79.65625,60.90625 79.65625,60.90625 C 79.874997,60.691963 80,60.396606 80,60.09375 L 80,16 L 24,16 z " transform="scale(1.454545,1.454545)" id="path8296" /><path id="path8298" transform="scale(1.454545,1.454545)" d="M 24,16 L 24,78.84375 C 24,79.47461 24.51225,80 25.15625,80 L 59.6875,80 C 59.996669,80.000003 60.28125,79.87053 60.5,79.65625 C 60.499998,79.656252 67.447919,73.986608 70.65625,70.84375 C 73.864585,67.700892 79.65625,60.90625 79.65625,60.90625 C 79.874997,60.691963 80,60.396606 80,60.09375 L 80,16 L 24,16 z " style="opacity:0.2;fill:none;stroke:black;stroke-width:4.00000143;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path style="fill:url(#radialGradient8312)" d="M 34.909091,23.272731 L 34.909091,114.70131 C 34.909091,115.61892 35.669334,116.36364 36.606061,116.36364 L 86.812608,116.36364 C 87.262306,116.36364 87.694184,116.18825 88.012366,115.87657 L 115.86643,88.590962 C 116.18461,88.279274 116.36364,87.856208 116.36364,87.41569 L 116.36364,23.272731 L 34.909091,23.272731 z " id="path8300" /><path style="fill:url(#radialGradient8314);fill-opacity:1" d="M 37.199227,24.727273 C 36.738816,24.727273 36.363636,25.095378 36.363636,25.547107 L 36.363636,114.08927 C 36.363636,114.54181 36.738816,114.90909 37.199227,114.90909 L 86.642757,114.90909 C 86.862518,114.90909 87.0781,114.82219 87.233519,114.66888 L 114.66428,87.755345 C 114.82051,87.602034 114.90909,87.391336 114.90909,87.17572 L 114.90909,25.547107 C 114.90909,25.095378 114.53475,24.727273 114.07351,24.727273 L 37.199227,24.727273 z " id="path8302" /><path d="M 115.86649,88.590976 C 116.07861,88.383184 100.27218,93.922095 96.000053,93.922095 C 94.596658,93.922095 93.454596,95.040847 93.454596,96.415601 C 93.454596,100.60054 87.800288,116.08438 88.01241,115.87659 L 115.86649,88.590976 z " id="path8304" style="opacity:0.1;fill:url(#linearGradient8316)" /><path d="M 115.86649,88.590976 C 116.18467,88.279289 104.01315,94.753262 96.000053,94.753262 C 95.064174,94.753262 94.303082,95.498822 94.303082,96.415601 C 94.303082,104.26516 87.694228,116.18827 88.01241,115.87659 L 115.86649,88.590976 z " id="path8306" style="opacity:0.1;fill:url(#linearGradient8318)" /><path d="M 115.86649,88.590976 C 116.06928,88.392328 104.32116,95.584432 96.000053,95.584432 C 95.53084,95.584432 95.151568,95.955965 95.151568,96.415601 C 95.151568,104.56688 87.809622,116.07524 88.01241,115.87659 L 115.86649,88.590976 z " id="path8308" style="opacity:0.1;fill:url(#linearGradient8320)" /><path d="M 88.01241,115.87659 C 88.01241,115.87659 98.121267,107.63638 102.78793,103.06495 C 107.4546,98.493523 115.86649,88.590976 115.86649,88.590976 C 115.86649,88.590976 104.69702,96.415601 96.000053,96.415601 C 96.000053,104.93508 88.01241,115.87659 88.01241,115.87659 z " id="path8310" style="fill:url(#linearGradient8322)" /></g><g id="g8278" transform="translate(0,-5.818182)"><path style="opacity:0.1;fill:none;stroke:black;stroke-width:8.00000286;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 24,16 L 24,78.84375 C 24,79.47461 24.51225,80 25.15625,80 L 59.6875,80 C 59.996669,80.000003 60.28125,79.87053 60.5,79.65625 C 60.499998,79.656252 67.447919,73.986608 70.65625,70.84375 C 73.864585,67.700892 79.65625,60.90625 79.65625,60.90625 C 79.874997,60.691963 80,60.396606 80,60.09375 L 80,16 L 24,16 z " transform="scale(1.454545,1.454545)" id="path8276" /><path id="path6495" transform="scale(1.454545,1.454545)" d="M 24,16 L 24,78.84375 C 24,79.47461 24.51225,80 25.15625,80 L 59.6875,80 C 59.996669,80.000003 60.28125,79.87053 60.5,79.65625 C 60.499998,79.656252 67.447919,73.986608 70.65625,70.84375 C 73.864585,67.700892 79.65625,60.90625 79.65625,60.90625 C 79.874997,60.691963 80,60.396606 80,60.09375 L 80,16 L 24,16 z " style="opacity:0.25;fill:none;stroke:black;stroke-width:2.00000072;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path id="path8274" transform="scale(1.454545,1.454545)" d="M 24,16 L 24,78.84375 C 24,79.47461 24.51225,80 25.15625,80 L 59.6875,80 C 59.996669,80.000003 60.28125,79.87053 60.5,79.65625 C 60.499998,79.656252 67.447919,73.986608 70.65625,70.84375 C 73.864585,67.700892 79.65625,60.90625 79.65625,60.90625 C 79.874997,60.691963 80,60.396606 80,60.09375 L 80,16 L 24,16 z " style="opacity:0.15;fill:none;stroke:black;stroke-width:6.00000191;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path style="opacity:0.2;fill:none;stroke:black;stroke-width:4.00000143;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 24,16 L 24,78.84375 C 24,79.47461 24.51225,80 25.15625,80 L 59.6875,80 C 59.996669,80.000003 60.28125,79.87053 60.5,79.65625 C 60.499998,79.656252 67.447919,73.986608 70.65625,70.84375 C 73.864585,67.700892 79.65625,60.90625 79.65625,60.90625 C 79.874997,60.691963 80,60.396606 80,60.09375 L 80,16 L 24,16 z " transform="scale(1.454545,1.454545)" id="path7387" /><path id="path34" d="M 34.909091,23.272731 L 34.909091,114.70131 C 34.909091,115.61892 35.669334,116.36364 36.606061,116.36364 L 86.812608,116.36364 C 87.262306,116.36364 87.694184,116.18825 88.012366,115.87657 L 115.86643,88.590962 C 116.18461,88.279274 116.36364,87.856208 116.36364,87.41569 L 116.36364,23.272731 L 34.909091,23.272731 z " style="fill:url(#radialGradient5602)" /><path id="path59" d="M 37.199227,24.727273 C 36.738816,24.727273 36.363636,25.095378 36.363636,25.547107 L 36.363636,114.08927 C 36.363636,114.54181 36.738816,114.90909 37.199227,114.90909 L 86.642757,114.90909 C 86.862518,114.90909 87.0781,114.82219 87.233519,114.66888 L 114.66428,87.755345 C 114.82051,87.602034 114.90909,87.391336 114.90909,87.17572 L 114.90909,25.547107 C 114.90909,25.095378 114.53475,24.727273 114.07351,24.727273 L 37.199227,24.727273 z " style="fill:url(#radialGradient5599);fill-opacity:1" /><path style="opacity:0.1;fill:url(#linearGradient5596)" id="path66" d="M 115.86649,88.590976 C 116.07861,88.383184 100.27218,93.922095 96.000053,93.922095 C 94.596658,93.922095 93.454596,95.040847 93.454596,96.415601 C 93.454596,100.60054 87.800288,116.08438 88.01241,115.87659 L 115.86649,88.590976 z " /><path style="opacity:0.1;fill:url(#linearGradient5593)" id="path73" d="M 115.86649,88.590976 C 116.18467,88.279289 104.01315,94.753262 96.000053,94.753262 C 95.064174,94.753262 94.303082,95.498822 94.303082,96.415601 C 94.303082,104.26516 87.694228,116.18827 88.01241,115.87659 L 115.86649,88.590976 z " /><path style="opacity:0.1;fill:url(#linearGradient5590)" id="path80" d="M 115.86649,88.590976 C 116.06928,88.392328 104.32116,95.584432 96.000053,95.584432 C 95.53084,95.584432 95.151568,95.955965 95.151568,96.415601 C 95.151568,104.56688 87.809622,116.07524 88.01241,115.87659 L 115.86649,88.590976 z " /><path style="fill:url(#linearGradient5587)" id="path101" d="M 88.01241,115.87659 C 88.01241,115.87659 98.121267,107.63638 102.78793,103.06495 C 107.4546,98.493523 115.86649,88.590976 115.86649,88.590976 C 115.86649,88.590976 104.69702,96.415601 96.000053,96.415601 C 96.000053,104.93508 88.01241,115.87659 88.01241,115.87659 z " /></g></svg>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/arrow-left.svg�������������������������������������������������������0000644�0001750�0000144�00000105055�10737543470�017343� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/david/oxygen" sodipodi:docname="arrow-left.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" inkscape:export-filename="arrow-left.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> <defs id="defs4"> <linearGradient inkscape:collect="always" id="linearGradient3327"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3329" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3331" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient4150"> <stop style="stop-color:#bfffbf;stop-opacity:1;" offset="0" id="stop4152" /> <stop style="stop-color:#bfffbf;stop-opacity:0;" offset="1" id="stop4154" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3409"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3411" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3413" /> </linearGradient> <linearGradient id="linearGradient3362" inkscape:collect="always"> <stop id="stop3364" offset="0" style="stop-color:#bfffbf;stop-opacity:1" /> <stop id="stop3366" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient id="linearGradient3355" inkscape:collect="always"> <stop id="stop3357" offset="0" style="stop-color:#e0ffe0;stop-opacity:1" /> <stop id="stop3359" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient id="linearGradient3349" inkscape:collect="always"> <stop id="stop3351" offset="0" style="stop-color:#00dd00;stop-opacity:1" /> <stop id="stop3353" offset="1" style="stop-color:#000e00;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3342"> <stop style="stop-color:#00ff00;stop-opacity:1" offset="0" id="stop3344" /> <stop style="stop-color:#004d00;stop-opacity:1" offset="1" id="stop3346" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3710"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3712" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3714" /> </linearGradient> <linearGradient id="linearGradient3689" inkscape:collect="always"> <stop id="stop3691" offset="0" style="stop-color:#f0ff80;stop-opacity:1" /> <stop id="stop3693" offset="1" style="stop-color:#f0ff80;stop-opacity:0" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3669"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3671" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3673" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3511"> <stop style="stop-color:#002a0d;stop-opacity:1;" offset="0" id="stop3513" /> <stop style="stop-color:#002a0d;stop-opacity:0;" offset="1" id="stop3515" /> </linearGradient> <radialGradient id="radialGradient2854" cx="538.77338" cy="651.10352" r="126.0234" gradientTransform="translate(-484,-674)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#cbcbcb;stop-opacity:1;" id="stop2856" /> <stop offset="0.53930002" style="stop-color:#282828;stop-opacity:1;" id="stop2858" /> <stop offset="1" style="stop-color:#9d9d9d;stop-opacity:1;" id="stop2860" /> </radialGradient> <linearGradient id="linearGradient2862" gradientUnits="userSpaceOnUse" x1="538.77338" y1="677.87701" x2="538.77338" y2="789.12207" gradientTransform="translate(-484,-674)"> <stop offset="0.0056" style="stop-color:#4d4d4d;stop-opacity:1;" id="stop2864" /> <stop offset="0.1348" style="stop-color:#676767;stop-opacity:1;" id="stop2866" /> <stop offset="0.4831" style="stop-color:#b2b2b2;stop-opacity:1;" id="stop2868" /> <stop offset="0.62989998" style="stop-color:#aaa;stop-opacity:1;" id="stop2870" /> <stop offset="0.85280001" style="stop-color:#a1a1a1;stop-opacity:1;" id="stop2872" /> <stop offset="1" style="stop-color:#9d9d9d;stop-opacity:1;" id="stop2874" /> </linearGradient> <radialGradient id="radialGradient2876" cx="538.77252" cy="792.99609" r="121.5466" gradientTransform="translate(-484,-674)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#d9d9d9;stop-opacity:1;" id="stop2878" /> <stop offset="0.0494" style="stop-color:#c7c7c7;stop-opacity:1;" id="stop2880" /> <stop offset="0.1049" style="stop-color:#b9b9b9;stop-opacity:1;" id="stop2882" /> <stop offset="0.14321923" style="stop-color:#aeaeae;stop-opacity:1;" id="stop2884" /> <stop offset="0.2156" style="stop-color:#a9a9a9;stop-opacity:1;" id="stop2886" /> <stop offset="0.26969999" style="stop-color:#a6a6a6;stop-opacity:1;" id="stop2888" /> <stop offset="0.3989" style="stop-color:#676767;stop-opacity:1;" id="stop2890" /> <stop offset="0.39950001" style="stop-color:#676767;stop-opacity:1;" id="stop2892" /> <stop offset="0.44839999" style="stop-color:#545454;stop-opacity:1;" id="stop2894" /> <stop offset="0.49559999" style="stop-color:#414141;stop-opacity:1;" id="stop2896" /> <stop offset="0.53988957" style="stop-color:#353535;stop-opacity:1;" id="stop2898" /> <stop offset="0.57096523" style="stop-color:#313131;stop-opacity:1;" id="stop2900" /> <stop offset="0.5948" style="stop-color:#3e3e3e;stop-opacity:1;" id="stop2902" /> <stop offset="0.64560002" style="stop-color:#5f5f5f;stop-opacity:1;" id="stop2904" /> <stop offset="0.69319999" style="stop-color:#707070;stop-opacity:1;" id="stop2906" /> <stop offset="0.73589998" style="stop-color:#7b7b7b;stop-opacity:1;" id="stop2908" /> <stop offset="0.76969999" style="stop-color:#7f7f7f;stop-opacity:1;" id="stop2910" /> <stop offset="1" style="stop-color:#313131;stop-opacity:1;" id="stop2912" /> </radialGradient> <linearGradient id="linearGradient2914" gradientUnits="userSpaceOnUse" x1="538.77338" y1="793" x2="538.77338" y2="674" gradientTransform="translate(-484,-674)"> <stop offset="0" style="stop-color:#262626;stop-opacity:1;" id="stop2916" /> <stop offset="0.1124" style="stop-color:#313131;stop-opacity:1;" id="stop2918" /> <stop offset="0.37450001" style="stop-color:#4d4d4d;stop-opacity:1;" id="stop2920" /> <stop offset="0.42309999" style="stop-color:#505050;stop-opacity:1;" id="stop2922" /> <stop offset="0.43689999" style="stop-color:#575757;stop-opacity:1;" id="stop2924" /> <stop offset="0.44909999" style="stop-color:#646464;stop-opacity:1;" id="stop2926" /> <stop offset="0.4605" style="stop-color:#757575;stop-opacity:1;" id="stop2928" /> <stop offset="0.47119999" style="stop-color:#8a8a8a;stop-opacity:1;" id="stop2930" /> <stop offset="0.48140001" style="stop-color:#a3a3a3;stop-opacity:1;" id="stop2932" /> <stop offset="0.49110001" style="stop-color:silver;stop-opacity:1;" id="stop2934" /> <stop offset="0.49439999" style="stop-color:#dfdfdf;stop-opacity:1;" id="stop2936" /> <stop offset="0.51748788" style="stop-color:#afafaf;stop-opacity:1;" id="stop2938" /> <stop offset="0.53259999" style="stop-color:#949494;stop-opacity:1;" id="stop2940" /> <stop offset="0.55519998" style="stop-color:#7c7c7c;stop-opacity:1;" id="stop2942" /> <stop offset="0.58454067" style="stop-color:#656565;stop-opacity:1;" id="stop2944" /> <stop offset="0.60860002" style="stop-color:#525252;stop-opacity:1;" id="stop2946" /> <stop offset="0.64160001" style="stop-color:#434343;stop-opacity:1;" id="stop2948" /> <stop offset="0.69285822" style="stop-color:#393939;stop-opacity:1;" id="stop2951" /> <stop offset="0.73979998" style="stop-color:#333;stop-opacity:1;" id="stop2953" /> <stop offset="0.89889997" style="stop-color:#313131;stop-opacity:1;" id="stop2955" /> <stop offset="1" style="stop-color:#a6a8a4;stop-opacity:1;" id="stop2957" /> </linearGradient> <radialGradient cx="265.3931" cy="-6078.353" r="253.01871" fx="369.5242" fy="-6078.353" id="path2295_1_" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.183616,0,0,-1.462967e-2,-0.962917,-7.25873)"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop8" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop10" /> <a:midPointStop style="stop-color:#000000" offset="0" /> <a:midPointStop style="stop-color:#000000" offset="0.5" /> <a:midPointStop style="stop-color:#FFFFFF" offset="1" /> </radialGradient> <filter inkscape:collect="always" x="-0.12239107" width="1.2447821" y="-0.078971461" height="1.1579429" id="filter3681"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.321914" id="feGaussianBlur3683" /> </filter> <filter inkscape:collect="always" x="-0.45196507" width="1.9039301" y="-0.29913295" height="1.5982659" id="filter3722"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.3476562" id="feGaussianBlur3724" /> </filter> <filter inkscape:collect="always" id="filter3435"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.395" id="feGaussianBlur3437" /> </filter> <filter inkscape:collect="always" id="filter3467"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.4349886" id="feGaussianBlur3469" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4009" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4011" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,-6.690938,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4013" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4017" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-54.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4021" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4023" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4025" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4027" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4029" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4031" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,-6.690938,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4033" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient4035" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4037" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4039" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-54.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4041" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4043" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4045" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4047" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4068" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4071" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4074" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4077" gradientUnits="userSpaceOnUse" gradientTransform="translate(-16,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4080" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-46.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4085" gradientUnits="userSpaceOnUse" gradientTransform="translate(-16,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4088" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,9.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4091" gradientUnits="userSpaceOnUse" gradientTransform="translate(-20,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4095" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4098" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4101" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4104" gradientUnits="userSpaceOnUse" gradientTransform="translate(36,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4107" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,5.634754,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4112" gradientUnits="userSpaceOnUse" gradientTransform="translate(36,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4118" gradientUnits="userSpaceOnUse" gradientTransform="translate(12,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4129" gradientUnits="userSpaceOnUse" gradientTransform="translate(32,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4145" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,5.634754,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4162" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="matrix(0.988811,0,0,0.9872502,-4.2657949e-2,0.2039966)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4164" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="translate(20,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4179" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="matrix(0.9955244,0,0,0.9872502,0.3938517,0.8203689)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4181" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="translate(20,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient3296" gradientUnits="userSpaceOnUse" gradientTransform="translate(24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3310" gradientUnits="userSpaceOnUse" gradientTransform="translate(20,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient3312" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-6.365246,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient3314" gradientUnits="userSpaceOnUse" gradientTransform="translate(24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient3316" gradientUnits="userSpaceOnUse" gradientTransform="translate(8,0)" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3327" id="linearGradient3344" gradientUnits="userSpaceOnUse" gradientTransform="translate(28,0)" x1="56" y1="67.238144" x2="34.345421" y2="40.171875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3327" id="linearGradient3356" gradientUnits="userSpaceOnUse" gradientTransform="translate(28,0)" x1="42.548481" y1="13.921767" x2="46.758774" y2="70.827744" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="4.9140625" inkscape:cx="64" inkscape:cy="64" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" showgrid="true" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" inkscape:window-width="794" inkscape:window-height="740" inkscape:window-x="0" inkscape:window-y="0" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g3936" transform="translate(28,0)"> <path style="opacity:0.53694584;fill:#004d00;fill-opacity:1;fill-rule:evenodd;stroke:#004d00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3467)" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z " id="path3987" /> <path style="fill:url(#linearGradient3310);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,84.46875 L 68,83.875 L 68,78.0625 L 68,49.9375 L 68,45 L 68,43.53125 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z M 60,24.3125 L 60,39.6875 L 54.59375,44 L 45,44 C 44.446,44 44,44.446 44,45 L 44,52.46875 L 33.5,60.875 C 32.550144,61.63413 32,62.78406 32,64 C 32,65.21594 32.550144,66.36587 33.5,67.125 L 44,75.53125 L 44,83.875 C 44,84.429 44.446,84.875 45,84.875 L 55.6875,84.875 L 60,88.3125 L 60,103.6875 L 10.40625,64 L 60,24.3125 z M 44,62.71875 L 44,65.28125 L 42.40625,64 L 44,62.71875 z " id="path3989" /> <path style="opacity:0.53694584;fill:url(#linearGradient3296);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,84.46875 L 68,83.875 L 68,83.1875 L 68,78.0625 L 68,49.9375 L 68,45 L 68,44.8125 L 68,43.53125 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z M 60,24.3125 L 60,39.6875 L 54.59375,44 L 45,44 C 44.446,44 44,44.446 44,45 L 44,52.46875 L 33.5,60.875 C 32.550144,61.63413 32,62.78406 32,64 C 32,65.21594 32.550144,66.36587 33.5,67.125 L 44,75.53125 L 44,83.875 C 44,84.429 44.446,84.875 45,84.875 L 55.6875,84.875 L 60,88.3125 L 60,103.6875 L 10.40625,64 L 60,24.3125 z M 44,62.71875 L 44,65.28125 L 42.40625,64 L 44,62.71875 z " id="path3993" /> <path style="fill:url(#radialGradient3312);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 64,16 L 4,64 L 64,112 L 64,86.40625 L 64,41.59375 L 64,16 z " id="path3999" /> <path style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3314);stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3435)" d="M 64,16 L 4,64 L 64,112 L 64,86.40625 L 64,41.59375 L 64,16 z " id="path4001" /> <path id="path3651" d="M 63.875,12 C 63.075959,12.024867 62.302054,12.283948 61.65625,12.75 L 62.625,21.78125 L 67.96875,15.625 C 67.880958,14.678789 67.469257,13.792159 66.78125,13.125 C 66.003873,12.37118 64.957323,11.966273 63.875,12 z " style="opacity:0.85;fill:url(#radialGradient4088);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> <path transform="matrix(1,0,0,-1,-8,127.7793)" style="opacity:0.35;fill:url(#radialGradient4035);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " id="path3685" /> <path transform="matrix(1,0,0,-1,-8,128.5625)" id="path3705" d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " style="opacity:0.5;fill:url(#radialGradient4037);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> <path style="fill:url(#linearGradient3316);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 64,16 L 4.1875,63.84375 C 12.238841,64.168797 20.513445,64.34375 28.90625,64.34375 C 40.962046,64.34375 52.698537,63.975426 64,63.3125 L 64,41.59375 L 64,16 z " id="path4143" /> <path style="fill:url(#linearGradient3344);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 84,16 L 83.65625,16.28125 L 83.65625,41.375 L 83.65625,62.90625 C 72.417269,63.563595 60.770394,63.937499 48.78125,63.9375 C 40.607993,63.9375 32.537203,63.778318 24.6875,63.46875 L 24.1875,63.84375 C 32.238841,64.168797 40.513445,64.34375 48.90625,64.34375 C 60.962046,64.34375 72.698537,63.975426 84,63.3125 L 84,41.59375 L 84,16 z " transform="translate(-20,0)" id="path3335" /> <path style="fill:url(#linearGradient3356);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 84,16 L 24.1875,63.84375 L 83.75,16.90625 L 83.75,42.03125 L 83.75,63.3125 C 83.832324,63.307705 83.917722,63.317326 84,63.3125 L 84,41.59375 L 84,16 z " transform="translate(-20,0)" id="path3347" /> </g> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/transform1.svg�������������������������������������������������������0000644�0001750�0000144�00000206027�11207732453�017350� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:ns="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="156" height="156" id="svg2365" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docname="transform1.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/MP3Diags/src/images"> <metadata id="metadata198"> <rdf:RDF> <ns:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </ns:Work> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <sodipodi:namedview inkscape:window-height="956" inkscape:window-width="891" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" showgrid="true" inkscape:zoom="1.463932" inkscape:cx="-43.819174" inkscape:cy="64" inkscape:window-x="251" inkscape:window-y="72" inkscape:current-layer="svg2365" /> <defs id="defs2367"> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective200" /> <filter x="-0.085532367" width="1.1710647" y="-0.10938701" height="1.218774" id="filter6906"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.5212367" id="feGaussianBlur6908" /> </filter> <clipPath id="clipPath6130"> <path d="M 125.16669,12.099598 C 122.19641,9.254864 111.282,2.992388 109.84175,5.187905 C 108.10513,7.835221 117.93885,14.870955 121.74406,16.587139 C 123.04716,17.174853 126.16385,13.054607 125.16669,12.099598 z" id="path6132" style="fill:#e20071;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient3168"> <stop id="stop3170" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop3172" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="29.344007" y1="35.892609" x2="5.8861146" y2="54.610104" id="linearGradient6134" xlink:href="#linearGradient3168" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.8205678,0.1491734,0.1491734,0.8205678,119.95493,-30.558073)" /> <linearGradient id="linearGradient2878"> <stop id="stop2880" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2882" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="47.794022" cy="43.680889" r="0.046902865" fx="47.817745" fy="43.681263" id="radialGradient2257" xlink:href="#linearGradient2878" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,140,0,-6071.644)" /> <linearGradient id="linearGradient2926"> <stop id="stop2928" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2934" style="stop-color:#ffffff;stop-opacity:0" offset="0.31868133" /> <stop id="stop2930" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="59.887943" cy="-16.594898" r="15.014902" fx="59.887943" fy="-16.594898" id="radialGradient4868" xlink:href="#linearGradient2926" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2908472,-1.2912538,-0.4877278,0.8613771,257.00005,93.121214)" spreadMethod="reflect" /> <linearGradient id="linearGradient2916"> <stop id="stop2918" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2920" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="58.079144" cy="51.897194" r="15.014902" fx="60.050133" fy="51.985794" id="radialGradient4871" xlink:href="#linearGradient2916" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.9412787,-1.1615663,-0.2846191,0.7136661,292.2596,68.533501)" /> <linearGradient id="linearGradient2948"> <stop id="stop2950" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2956" style="stop-color:#000000;stop-opacity:0" offset="0.14835165" /> <stop id="stop2960" style="stop-color:#000000;stop-opacity:0.39607844" offset="0.42443547" /> <stop id="stop2958" style="stop-color:#000000;stop-opacity:0.79061371" offset="0.57417583" /> <stop id="stop2962" style="stop-color:#000000;stop-opacity:0.09386282" offset="0.78708792" /> <stop id="stop2952" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.277409" y1="41.758987" x2="75.465431" y2="41.511894" id="linearGradient4874" xlink:href="#linearGradient2948" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <filter x="-0.081383675" width="1.1627673" y="-0.11701577" height="1.2340316" id="filter7303"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5574454" id="feGaussianBlur7305" /> </filter> <clipPath id="clipPath6914"> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 81.839741,-15.69481 90.48863,-25.23053 103.93871,-26.883344 C 107.28591,-26.458991 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.52863,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z" id="path6916" style="opacity:1;fill:#34176e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2938"> <stop id="stop2940" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2942" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="61.870293" y1="33.318996" x2="61.870293" y2="40.550549" id="linearGradient4880" xlink:href="#linearGradient2938" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <linearGradient id="linearGradient2854"> <stop id="stop2856" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2858" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="106.03028" y1="59.273457" x2="108.78728" y2="55.574818" id="linearGradient4888" xlink:href="#linearGradient2854" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="94.435982" cy="42.709927" r="16.633095" fx="94.435982" fy="42.709927" id="radialGradient4891" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2134389,-1.5580054,-0.9195638,1.2855562,320.80105,101.437)" /> <radialGradient cx="94.932045" cy="43.032188" r="16.633095" fx="94.932045" fy="43.032188" id="radialGradient4894" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="93.747849" cy="43.102612" r="16.633095" fx="93.747849" fy="43.102612" id="radialGradient4897" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="92.990265" cy="42.850105" r="16.633095" fx="92.990265" fy="42.850105" id="radialGradient4900" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <linearGradient id="linearGradient2830"> <stop id="stop2832" style="stop-color:#111111;stop-opacity:1" offset="0" /> <stop id="stop2838" style="stop-color:#6e6e70;stop-opacity:1" offset="0.14285715" /> <stop id="stop2864" style="stop-color:#101010;stop-opacity:1" offset="0.5714286" /> <stop id="stop2834" style="stop-color:#0d0d0d;stop-opacity:1" offset="1" /> </linearGradient> <radialGradient cx="92.496124" cy="43.249184" r="16.633095" fx="92.496124" fy="43.249184" id="radialGradient4903" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <filter x="-0.059171364" width="1.1183428" y="-0.25424162" height="1.5084833" id="filter5739"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5280665" id="feGaussianBlur5741" /> </filter> <clipPath id="clipPath5354"> <path d="M 103.98397,-1.574449 C 105.35028,-1.792233 108.98473,-2.914664 106.17093,-5.692155 C 76.173344,-27.291403 51.99515,-18.323699 42.936426,-12.159439 C 53.098952,-17.891025 78.771948,-21.925123 103.98397,-1.574449 z" id="path5356" style="opacity:1;fill:#00583f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2803"> <stop id="stop2809" style="stop-color:#e2dcdc;stop-opacity:1" offset="0" /> <stop id="stop2811" style="stop-color:#ffffff;stop-opacity:1" offset="0.39074388" /> <stop id="stop2813" style="stop-color:#dfd9df;stop-opacity:1" offset="0.82692307" /> <stop id="stop2815" style="stop-color:#c3c3c3;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="62.987843" y1="46.469597" x2="118.02947" y2="62.350033" id="linearGradient4910" xlink:href="#linearGradient2803" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2231" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2229" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2227" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2225" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2223" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2221" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2219" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2217" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2215" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2213" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2211" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2209" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2207" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2205" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2203" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2201" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2199" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2197" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2195" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2193" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2191" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2189" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2187" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2185" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2183" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2181" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2179" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2177" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2175" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2173" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2171" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2169" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient id="linearGradient2370"> <stop id="stop2378" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2374" style="stop-color:#2a2a2a;stop-opacity:0.29537368" offset="1" /> </linearGradient> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2167" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient x1="-66.905724" y1="78.000954" x2="-66.905724" y2="77.232819" id="linearGradient4946" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-75.354716)" /> <linearGradient x1="-74.01326" y1="49.46249" x2="-58.206917" y2="65.268829" id="linearGradient4952" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833612,-4.797835,-79.665584)" /> <linearGradient x1="36.909187" y1="75.415688" x2="38.451817" y2="75.479614" id="linearGradient4955" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.983361,0.6663259,-0.6582589,0.9697357,55.439719,-32.927491)" /> <linearGradient id="linearGradient2322"> <stop id="stop2324" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2326" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="37.235054" y1="75.415688" x2="38.61475" y2="75.479614" id="linearGradient4958" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.44832,27.448631)" /> <linearGradient x1="45.615768" y1="128.00496" x2="45.615768" y2="125.89983" id="linearGradient4961" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2310"> <stop id="stop2312" style="stop-color:#020202;stop-opacity:1" offset="0" /> <stop id="stop2314" style="stop-color:#020202;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.24057" y1="61.083416" x2="45.24057" y2="62.415165" id="linearGradient4964" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.36527,27.463989)" /> <linearGradient id="linearGradient3058"> <stop id="stop3060" style="stop-color:#9a7600;stop-opacity:1" offset="0" /> <stop id="stop3066" style="stop-color:#e3ad00;stop-opacity:1" offset="0.32522252" /> <stop id="stop3070" style="stop-color:#ffcd2c;stop-opacity:1" offset="0.6670348" /> <stop id="stop3068" style="stop-color:#e3ad00;stop-opacity:1" offset="0.91571385" /> <stop id="stop3062" style="stop-color:#b98d00;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="34.91254" y1="94.734375" x2="55.089256" y2="94.734375" id="linearGradient4967" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2352"> <stop id="stop2354" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2356" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="-66.905724" y1="77.09996" x2="-66.905724" y2="75.717079" id="linearGradient4949" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764965,0,0,1.1833623,-4.7827195,-79.650397)" /> <linearGradient id="linearGradient2334"> <stop id="stop2336" style="stop-color:#8d8d8d;stop-opacity:1" offset="0" /> <stop id="stop2342" style="stop-color:#e2dcdc;stop-opacity:1" offset="0.2767916" /> <stop id="stop2348" style="stop-color:#ffffff;stop-opacity:1" offset="0.71460712" /> <stop id="stop2344" style="stop-color:#dfd9df;stop-opacity:1" offset="0.80711305" /> <stop id="stop2338" style="stop-color:#888888;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="-70.588905" y1="67.754272" x2="-59.581383" y2="67.754272" id="linearGradient4970" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-79.665581)" /> <linearGradient id="linearGradient6959"> <stop id="stop6961" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop6963" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="0.16120911" y1="117.27959" x2="128.16121" y2="117.27959" id="linearGradient8078" xlink:href="#linearGradient6959" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.785268,-7.3677219e-2,3.9462543e-2,0.4492806,22.778321,70.710911)" /> </defs> <g id="layer1" transform="translate(11.95197,16)"> <path d="M 128.04736,113.95979 C 128.28089,116.61848 67.411471,124.50507 39.669521,127.10794 C 11.927571,129.71081 27.766581,126.04917 27.533061,123.39048 C 27.299531,120.73178 11.081461,120.07787 38.823411,117.475 C 66.565361,114.87213 127.81383,111.3011 128.04736,113.95979 z " id="path6957" style="opacity:0.32093027;fill:url(#linearGradient8078);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31099999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.274934,34.905639 C 85.204914,25.922787 89.34177,14.198553 102.63801,12.53741 C 105.94693,12.9639 108.13372,18.737744 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2874" style="fill:#bfbfc0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <rect width="12.941447" height="29.58403" ry="0" x="-87.844696" y="-16.94743" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2266" style="fill:url(#linearGradient4970);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="13.038667" height="2.5542164" ry="0" x="-87.829575" y="9.101737" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2360" style="opacity:0.36065578;fill:url(#linearGradient4949);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.429289,63.172679 C 65.635414,64.820033 54.923018,83.195864 49.729102,91.344581 C 39.34128,107.642 26.239281,125.86158 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 19.376879,93.833728 30.860819,78.294436 C 36.602784,70.52478 49.810698,53.88547 51.006314,52.505467 C 52.212736,51.113002 53.417042,50.730504 54.693928,51.613654 C 58.435834,54.201727 62.17774,56.7898 65.919646,59.377862 C 66.995538,60.122005 67.369194,61.222275 66.429289,63.172679 z " id="rect1388" style="fill:url(#linearGradient4967);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.247591,63.206257 C 65.453717,64.853621 49.629,53.919059 50.824616,52.539056 C 52.031038,51.146581 53.235344,50.764082 54.51223,51.647242 C 58.254136,54.235305 61.996042,56.823378 65.737948,59.411451 C 66.81384,60.155584 67.187497,61.255863 66.247591,63.206257 z " id="path2290" style="opacity:0.09157511;fill:url(#linearGradient4964);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 26.239281,125.86158 26.239281,125.86158 z " id="path2308" style="opacity:0.3699634;fill:url(#linearGradient4961);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.33068,63.19091 C 65.536805,64.838264 54.824409,83.214095 49.630493,91.362803 C 39.242661,107.66022 26.140672,125.8798 26.140672,125.8798 C 24.569135,128.14762 62.079131,56.808021 65.821037,59.396094 C 66.896928,60.140227 67.270585,61.240506 66.33068,63.19091 z " id="path2320" style="opacity:0.3699634;fill:url(#linearGradient4958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 51.020737,52.411747 C 49.776998,53.730231 36.591653,70.167669 30.909012,77.870037 C 19.543739,93.274764 7.3898106,111.88362 7.3898106,111.88362 C 5.8550281,114.14465 58.555163,54.129906 54.752313,51.55311 C 53.658913,50.812203 52.49326,50.850706 51.020737,52.411747 z " id="path2330" style="opacity:0.23809521;fill:url(#linearGradient4955);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="22.48386" ry="0" x="-87.844696" y="-16.947432" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2350" style="opacity:0.25;fill:url(#linearGradient4952);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="4.1249256" ry="0" x="-87.844696" y="12.822533" transform="matrix(-0.8224474,-0.5688412,0.5695776,-0.8219376,0,0)" id="rect2364" style="opacity:0.29098361;fill:url(#linearGradient4946);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.339764,-119.62564)" id="path2368" style="opacity:0.21245422;fill:url(#radialGradient2167);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.295704,-113.78978)" id="path2486" style="opacity:0.21245422;fill:url(#radialGradient2169);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.251654,-107.95391)" id="path2490" style="opacity:0.21245422;fill:url(#radialGradient2171);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.207455,-102.11799)" id="path2494" style="opacity:0.21245422;fill:url(#radialGradient2173);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.163405,-96.282126)" id="path2498" style="opacity:0.21245422;fill:url(#radialGradient2175);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.119257,-90.446221)" id="path2502" style="opacity:0.21245422;fill:url(#radialGradient2177);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.401175,-83.637696)" id="path2506" style="opacity:0.21245422;fill:url(#radialGradient2179);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.357125,-77.801811)" id="path2510" style="opacity:0.21245422;fill:url(#radialGradient2181);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.312966,-71.965905)" id="path2514" style="opacity:0.21245422;fill:url(#radialGradient2183);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2518" style="opacity:0.21245422;fill:url(#radialGradient2185);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2522" style="opacity:0.21245422;fill:url(#radialGradient2187);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.51209,-120.72315)" id="path2524" style="opacity:0.21245422;fill:url(#radialGradient2189);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.468031,-114.88732)" id="path2526" style="opacity:0.21245422;fill:url(#radialGradient2191);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.423951,-109.05138)" id="path2528" style="opacity:0.21245422;fill:url(#radialGradient2193);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.379792,-103.21548)" id="path2530" style="opacity:0.21245422;fill:url(#radialGradient2195);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,58.335742,-97.379601)" id="path2532" style="opacity:0.21245422;fill:url(#radialGradient2197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,54.291593,-91.543696)" id="path2534" style="opacity:0.21245422;fill:url(#radialGradient2199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.573512,-84.735171)" id="path2536" style="opacity:0.21245422;fill:url(#radialGradient2201);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.529462,-78.899296)" id="path2538" style="opacity:0.21245422;fill:url(#radialGradient2203);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,41.485303,-73.063401)" id="path2540" style="opacity:0.21245422;fill:url(#radialGradient2205);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2542" style="opacity:0.21245422;fill:url(#radialGradient2207);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2544" style="opacity:0.21245422;fill:url(#radialGradient2209);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,86.123367,-112.6923)" id="path2568" style="opacity:0.21245422;fill:url(#radialGradient2211);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.079218,-106.85639)" id="path2570" style="opacity:0.21245422;fill:url(#radialGradient2213);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.035168,-101.02052)" id="path2572" style="opacity:0.21245422;fill:url(#radialGradient2215);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,73.991108,-95.18463)" id="path2574" style="opacity:0.21245422;fill:url(#radialGradient2217);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,69.947019,-89.348755)" id="path2576" style="opacity:0.21245422;fill:url(#radialGradient2219);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,65.90286,-83.51285)" id="path2578" style="opacity:0.21245422;fill:url(#radialGradient2221);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,61.184788,-76.704325)" id="path2580" style="opacity:0.21245422;fill:url(#radialGradient2223);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.14063,-70.86842)" id="path2582" style="opacity:0.21245422;fill:url(#radialGradient2225);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.09658,-65.032544)" id="path2584" style="opacity:0.21245422;fill:url(#radialGradient2227);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2586" style="opacity:0.21245422;fill:url(#radialGradient2229);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2588" style="opacity:0.21245422;fill:url(#radialGradient2231);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 101.38809,11.479353 C 102.63809,12.398423 103.84894,13.381344 105.0387,14.408949 C 104.01321,16.577326 100.48534,20.746249 99.007199,22.467323 C 98.01495,23.622639 93.281961,23.36178 91.998392,24.319263 C 87.944052,27.343595 84.815519,31.864815 80.922501,35.138608 L 72.655729,29.510877 C 72.667829,29.490354 72.685732,29.470645 72.697861,29.450092 C 72.67379,29.475982 72.628395,29.495037 72.604432,29.520354 L 71.432076,28.709507 C 71.432067,28.709497 76.539137,19.842938 71.897343,16.081861 C 61.421124,7.5933688 42.104321,12.7028 40.367328,14.0543 L 42.083541,7.259695 C 42.083541,7.259695 42.33779,7.1294014 42.380871,7.1146373 C 59.53124,-3.8488001 84.402814,-1.0092155 101.38809,11.479353 z " id="path2783" style="fill:url(#linearGradient4910);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 103.83475,-5.0595755 C 104.3991,-4.5551745 105.41114,-5.6873565 104.63008,-6.2226895 C 74.632493,-27.821939 51.99515,-17.681556 42.936426,-11.517296 C 52.35952,-18.300887 76.609727,-26.230729 103.83475,-5.0595755 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath5354)" id="path2823" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5739)" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.128521,13.402952 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.101176,-0.96025992 73.950973,7.4166021 C 82.164175,13.221703 76.243429,25.456347 72.232891,29.69503 z " id="path2842" style="opacity:0.23360656;fill:url(#radialGradient4903);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.523172,29.895808 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.022844,13.705088 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.235986,-1.1547857 74.085773,7.2220662 C 82.298976,13.027177 76.53371,25.657124 72.523172,29.895808 z " id="path2827" style="opacity:0.23360656;fill:url(#radialGradient4900);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 73.103735,30.297352 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.89179,13.624865 40.576201,14.168322 L 42.322269,7.4456578 C 42.322269,7.4456578 62.640397,-1.7383733 74.490184,6.6384787 C 82.703386,12.44359 77.114273,26.058669 73.103735,30.297352 z " id="path2844" style="opacity:0.0737705;fill:url(#radialGradient4897);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.984171,13.626222 40.566444,14.182412 L 42.334152,7.4434568 C 42.334152,7.4434568 61.966375,-0.76572405 73.816172,7.6111279 C 82.029375,13.416239 76.243429,25.456347 72.232891,29.69503 z " id="path2840" style="opacity:0.23360656;fill:url(#radialGradient4894);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.13613,29.628115 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.921635,13.665037 40.571002,14.184262 L 42.322269,7.4456578 C 42.322269,7.4456578 61.764175,-0.47393028 73.613962,7.9029217 C 81.827164,13.708033 76.146668,25.389432 72.13613,29.628115 z " id="path2862" style="opacity:0.37000002;fill:url(#radialGradient4891);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 61.41113,8.3780551 C 54.11035,6.6553332 42.963569,9.4974003 40.902427,12.001391 L 41.0016,10.631158 C 43.787546,7.6855914 53.80009,5.6303314 60.912865,6.8618995 C 62.075305,7.0631792 62.003061,8.5177258 61.41113,8.3780551 z " id="path2868" style="opacity:0.31000001;fill:url(#linearGradient4888);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 42.085054,7.2558055 L 40.347458,14.03836 L 40.579642,14.198955 L 42.326056,7.4656582 L 42.085054,7.2558055 z " id="path2872" style="opacity:0.11000001;fill:#b7b7b7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.793503,23.516486 95.950625,22.98307 C 98.195669,22.788575 103.22118,19.851069 102.52483,17.34553 C 101.28955,12.900833 104.51185,12.778691 106.76072,16.351101 C 107.83597,18.05917 108.68046,20.615514 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 121.44894,38.490512 117.56384,42.696451 L 111.17842,38.965656 L 103.77633,29.053301 C 97.649281,27.059128 88.562348,29.712528 81.865056,36.103558 z " id="path2936" style="opacity:0.5286885;fill:url(#linearGradient4880);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 96.447179,-28.288297 105.15658,-12.530013 103.93871,-26.883344 C 105.73798,-25.86955 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.528633,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,39.556289)" clip-path="url(#clipPath6914)" id="path2902" style="opacity:0.3;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7303)" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.936568,23.945458 96.09369,23.412042 C 98.338733,23.217547 99.058515,23.054066 102.62556,17.81605 C 104.97193,14.370546 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2904" style="opacity:0.11065572;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 90.178924,23.81633 96.336045,23.282914 C 98.581099,23.088419 99.46084,22.257119 102.66207,17.556297 C 105.00842,14.110793 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2946" style="opacity:0.78278689;fill:url(#linearGradient4874);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.186467,36.425805 L 80.943143,35.163804 C 90.771765,25.89748 90.156661,24.109531 96.307061,23.50126 C 99.068954,23.228099 101.46217,20.125666 103.03896,17.817699 C 105.39113,14.376285 105.82661,13.986851 107.08213,16.673348 C 108.04323,18.729874 109.11134,20.957278 109.76753,22.854566 L 120.19358,26.450685 L 126,30.829783 C 123.46105,35.966762 120.42231,40.758067 116.53723,44.964006 L 110.15179,41.233211 L 102.74972,31.320856 C 96.622659,29.326673 88.883759,30.034785 82.186467,36.425805 z " id="path2906" style="opacity:0.55;fill:url(#radialGradient4871);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.052576,35.677069 L 80.809252,34.415058 C 90.637874,25.148744 90.316354,23.346463 96.463708,22.707247 C 99.198595,22.422217 99.463846,21.382923 102.80287,17.054108 C 105.34611,13.756144 105.69272,13.238105 106.94825,15.924612 C 107.90935,17.981128 108.97746,20.208542 109.63365,22.10582 L 120.05969,25.701939 L 125.86612,30.081037 C 123.32716,35.218016 120.28843,40.009321 116.40334,44.21526 L 110.0179,40.484465 L 102.61584,30.57211 C 96.488778,28.577937 88.749878,29.286039 82.052576,35.677069 z " id="path2924" style="opacity:0.76000001;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 47.840924,43.680889 C 47.84099,46.032991 47.832065,48.210404 47.817526,49.389142 C 47.802987,50.56788 47.785056,50.56788 47.770517,49.389142 C 47.755978,48.210404 47.747053,46.032991 47.747119,43.680889 C 47.747053,41.328787 47.755978,39.151374 47.770517,37.972636 C 47.785056,36.793898 47.802987,36.793898 47.817526,37.972636 C 47.832065,39.151374 47.84099,41.328787 47.840924,43.680889 z " transform="matrix(-10.643649,-7.3616191,-0.6740154,0.9726479,659.11339,347.51792)" id="path2876" style="fill:url(#radialGradient2257);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 125.16669,12.099598 C 121.62206,9.685606 112.43786,3.516506 110.99761,5.712023 C 109.26099,8.35934 118.0322,14.038156 121.74406,16.587139 C 122.92246,17.396368 126.3079,12.876785 125.16669,12.099598 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath6130)" id="path3178" style="fill:url(#linearGradient6134);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6906)" /> </g> <path style="font-size:72px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" d="M 118.2564,134.63206 L 109.8189,134.63206 L 109.8189,80.86644 C 107.78763,82.803992 105.11575,84.74149 101.80328,86.67894 C 98.52201,88.616486 95.568888,90.069609 92.943901,91.038315 L 92.943901,82.882065 C 97.662636,80.663369 101.78763,77.975871 105.3189,74.819565 C 108.85012,71.663378 111.35012,68.600881 112.8189,65.632065 L 118.2564,65.632065 L 118.2564,134.63206" id="text2573" /> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/export.svg�����������������������������������������������������������0000644�0001750�0000144�00000016215�11260104701�016557� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="123" height="123" id="svg7146" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images/work" sodipodi:docname="export2.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs7148" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="5.6" inkscape:cx="94.023693" inkscape:cy="72.464518" inkscape:document-units="px" inkscape:current-layer="layer1" width="123px" height="123px" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" /> <metadata id="metadata7151"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-306.28314,-93.230533)"> <g id="g7125" transform="matrix(1.1124311,0,0,1.1124311,275.85324,66.530926)"> <rect y="48.485832" x="31.967699" height="80.972542" width="57.843128" id="rect2519" style="fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> <rect y="30.949408" x="31.380243" height="17.067881" width="57.914093" id="rect2521" style="fill:#999999;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> <path id="path4484" d="M 31.380242,30.507192 L 89.810829,30.507192" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.41756105;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4488" d="M 31.380242,48.485834 L 89.810829,48.485834" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.41756105;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4490" d="M 31.380242,61.969815 L 89.810829,61.969815" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.41756105;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4492" d="M 31.380242,75.453797 L 89.810829,75.453797" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.41756105;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4494" d="M 31.380242,88.937778 L 89.810829,88.937778" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.41756105;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4496" d="M 31.380242,102.42176 L 89.810829,102.42176" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.41756105;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4498" d="M 31.383581,115.90574 L 89.839027,115.90574" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.41756105;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4500" d="M 89.810829,129.1419 L 89.810829,30.691929" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.59573293;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4502" d="M 31.380242,30.689921 L 31.380242,128.99803" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.59386206;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path4504" d="M 60.082983,127.41544 L 60.082983,30.667833" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.57319283;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.41756105;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 31.380242,129.26355 L 89.810829,129.26355" id="path2238" /> <g transform="translate(-66.223747,14.853925)" id="g7118"> <path id="path5168" d="M 164.30948,46.082425 L 191.27744,73.050387 L 164.30948,100.01835" style="fill:none;fill-rule:evenodd;stroke:#00ffe6;stroke-width:13.48398113;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path5170" d="M 132.84685,73.050387 L 186.78278,73.050387 L 186.78278,73.050387" style="fill:none;fill-rule:evenodd;stroke:#00ffe6;stroke-width:13.48398113;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <g id="g5162" transform="translate(3.9111435,-38.344621)"> <path id="path2242" d="M 160.51662,84.511768 L 187.48458,111.47973 L 160.51662,138.44769" style="fill:none;fill-rule:evenodd;stroke:#1e32c8;stroke-width:8.98932076;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path2244" d="M 129.05399,111.47973 L 182.98992,111.47973 L 182.98992,111.47973" style="fill:none;fill-rule:evenodd;stroke:#1e32c8;stroke-width:8.98932076;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> </g> </g> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/mode_album.svg�������������������������������������������������������0000644�0001750�0000144�00000271771�11074307216�017365� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> <svg xmlns:ns="http://ns.adobe.com/SaveForWeb/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" id="Livello_1" width="128" height="128" viewBox="100.873 -104.477 263.043 263.042" overflow="visible" enable-background="new 100.873 -104.477 263.043 263.042" xml:space="preserve" sodipodi:version="0.32" inkscape:version="0.46" sodipodi:docname="mode_album.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" style="overflow:visible" sodipodi:docbase="/home/david/sandbox" inkscape:export-filename="media-optical-audio.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"><defs id="defs82"><inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective152" /><radialGradient gradientUnits="userSpaceOnUse" r="120" cy="27.3013" cx="232.5" id="radialGradient2810"> <stop id="stop2812" style="stop-color:#c9bcd5;stop-opacity:1;" offset="0" /><stop offset="0.5" style="stop-color:#ffffff;stop-opacity:1;" id="stop2816" /> <stop id="stop2820" style="stop-color:#baabc5;stop-opacity:1;" offset="1" /> </radialGradient><linearGradient id="linearGradient2797"><stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop2799" /><stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop2801" /></linearGradient><linearGradient inkscape:collect="always" id="linearGradient3180"><stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3182" /><stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3184" /></linearGradient><filter inkscape:collect="always" id="filter3218"><feGaussianBlur inkscape:collect="always" stdDeviation="1.28" id="feGaussianBlur3220" /></filter><filter inkscape:collect="always" id="filter3273"><feGaussianBlur inkscape:collect="always" stdDeviation="4.64" id="feGaussianBlur3275" /></filter><linearGradient inkscape:collect="always" xlink:href="#linearGradient3180" id="linearGradient3357" gradientUnits="userSpaceOnUse" gradientTransform="translate(-20.000001,0)" x1="232.5" y1="10.801" x2="232.5" y2="43.800999" /><defs id="defs19"> <path id="XMLID_5_" d="M 147.753,-57.596 C 100.89,-10.733 100.89,65.247 147.753,112.11 C 194.615,158.972 270.595,158.973 317.459,112.11 C 364.323,65.247 364.321,-10.733 317.459,-57.596 C 270.596,-104.458 194.616,-104.459 147.753,-57.596 z M 260.891,55.542 C 245.27,71.163 219.943,71.162 204.322,55.542 C 188.701,39.921 188.701,14.594 204.322,-1.026 C 219.943,-16.648 245.269,-16.647 260.89,-1.026 C 276.511,14.594 276.512,39.92 260.891,55.542 z" style="opacity:0.3" /> </defs><clipPath id="XMLID_12_"> <use xlink:href="#XMLID_5_" id="use23" x="0" y="0" width="263.043" height="263.04199" /> </clipPath><linearGradient inkscape:collect="always" xlink:href="#XMLID_15_" id="linearGradient2839" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.027057,0,0,1.0273239,-6.4508223,-0.980434)" x1="249.4619" y1="44.263199" x2="215.5367" y2="10.3379" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_16_" id="linearGradient2857" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.027057,0,0,1.0273239,-6.4508226,-0.980434)" x1="263.14261" y1="53.012199" x2="201.8575" y2="1.5880001" /><linearGradient inkscape:collect="always" xlink:href="#radialGradient2810" id="linearGradient2869" gradientUnits="userSpaceOnUse" x1="137.81563" y1="-108.63532" x2="314.59543" y2="68.14447" gradientTransform="translate(0,41.100466)" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2797" id="linearGradient2832" x1="356.38586" y1="27" x2="232" y2="-65.195312" gradientUnits="userSpaceOnUse" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2797" id="linearGradient3231" x1="109.96723" y1="88.015862" x2="232" y2="88.015862" gradientUnits="userSpaceOnUse" /><clipPath clipPathUnits="userSpaceOnUse" id="clipPath4191"><path style="opacity:1;fill:#e20800;stroke:none" d="M 212.5,43.301 C 203.663,43.301 196.5,36.138 196.5,27.301 C 196.5,18.465 203.663,11.301 212.5,11.301 C 221.337,11.301 228.5,18.465 228.5,27.301 C 228.5,36.138 221.337,43.301 212.5,43.301 z " id="path4193" /></clipPath><filter inkscape:collect="always" id="filter4199"><feGaussianBlur inkscape:collect="always" stdDeviation="2.4476426" id="feGaussianBlur4201" /></filter><filter inkscape:collect="always" id="filter5172"><feGaussianBlur inkscape:collect="always" stdDeviation="2.440645" id="feGaussianBlur5174" /></filter><filter id="filter6448" inkscape:collect="always"><feGaussianBlur id="feGaussianBlur6450" stdDeviation="0.37043075" inkscape:collect="always" /></filter><linearGradient y2="49" x2="48.1172" y1="49" x1="40.1172" gradientTransform="matrix(0.4848485,0,0,0.6314195,44.549334,20.000001)" gradientUnits="userSpaceOnUse" id="linearGradient3914" xlink:href="#radialGradient4397" inkscape:collect="always" /><linearGradient y2="19.9497" x2="52.9131" y1="8.6162" x1="62.2461" gradientUnits="userSpaceOnUse" id="XMLID_13_"><stop id="stop88" style="stop-color:#000000;stop-opacity:1;" offset="0" /><stop id="stop104" style="stop-color:#000000;stop-opacity:0;" offset="1" /></linearGradient><linearGradient y2="49" x2="48.1172" y1="49" x1="40.1172" gradientUnits="userSpaceOnUse" id="linearGradient4683"><stop id="stop16" style="stop-color:#008e00;stop-opacity:1;" offset="0" /><stop id="stop18" style="stop-color:#008700" offset="0.2294" /><stop id="stop20" style="stop-color:#007800" offset="0.5127" /><stop id="stop22" style="stop-color:#005F00" offset="0.8231" /><stop id="stop24" style="stop-color:#004D00" offset="1" /></linearGradient><linearGradient id="linearGradient4390"><stop id="stop4392" offset="0" style="stop-color:#00a208;stop-opacity:1;" /><stop style="stop-color:#dfffa8;stop-opacity:1;" offset="0.5" id="stop4398" /><stop id="stop4394" offset="1" style="stop-color:#8aff47;stop-opacity:0.63291138;" /></linearGradient><filter id="filter5551" height="1.0245266" y="-0.012263282" width="2.117884" x="-0.558942" inkscape:collect="always"><feGaussianBlur id="feGaussianBlur5553" stdDeviation="0.465785" inkscape:collect="always" /></filter><radialGradient style="fill-opacity:1.0;fill:url(#linearGradient6728)" gradientUnits="userSpaceOnUse" r="25.1951" cy="100" cx="23.7837" id="XMLID_10_"><stop id="stop35" style="stop-color:#287f00;stop-opacity:1;" offset="0" /><stop offset="0.5" style="stop-color:#3cf000;stop-opacity:1;" id="stop9094" /><stop id="stop43" style="stop-color:#003a00;stop-opacity:1;" offset="1" /></radialGradient><linearGradient id="linearGradient4540"><stop id="stop4542" offset="0" style="stop-color:#008800;stop-opacity:1;" /><stop id="stop4544" offset="1" style="stop-color:#0aa800;stop-opacity:0.60759491;" /></linearGradient><filter id="filter6116" height="1.355011" y="-0.1775055" width="1.2451262" x="-0.12256312" inkscape:collect="always"><feGaussianBlur id="feGaussianBlur6118" stdDeviation="2.0368781" inkscape:collect="always" /></filter><radialGradient id="radialGradient4531" cx="19.7837" cy="94" r="14" fx="17.1172" fy="88.667" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#ffffff;stop-opacity:1;" id="stop4533" /><stop id="stop4537" style="stop-color:#ffffff;stop-opacity:0.70886075;" offset="0.5" /><stop offset="1" style="stop-color:#ffffff;stop-opacity:0;" id="stop4535" /></radialGradient><filter id="filter5558" inkscape:collect="always"><feGaussianBlur id="feGaussianBlur5560" stdDeviation="0.61029092" inkscape:collect="always" /></filter><linearGradient id="linearGradient2848"><stop id="stop2850" offset="0" style="stop-color:#c3ff6a;stop-opacity:1;" /><stop id="stop2852" offset="1" style="stop-color:#a6ff88;stop-opacity:0;" /></linearGradient><filter id="filter2844" height="1.2780566" y="-0.13902832" width="1.1466216" x="-0.073310805" inkscape:collect="always"><feGaussianBlur id="feGaussianBlur2846" stdDeviation="0.73249726" inkscape:collect="always" /></filter><linearGradient id="linearGradient5332" gradientUnits="userSpaceOnUse" x1="62.2461" y1="8.6162" x2="52.9131" y2="19.9497"><stop offset="0" style="stop-color:#000000;stop-opacity:0;" id="stop5334" /><stop offset="1" style="stop-color:#07631a;stop-opacity:1;" id="stop5336" /></linearGradient><filter id="filter3619" inkscape:collect="always"><feGaussianBlur id="feGaussianBlur3621" stdDeviation="0.69944247" inkscape:collect="always" /></filter><radialGradient id="radialGradient4397" cx="23.7837" cy="100" r="25.1951" gradientUnits="userSpaceOnUse" style="fill-opacity:1.0;fill:url(#linearGradient6728)"><stop id="stop4401" style="stop-color:#2eb800;stop-opacity:1;" offset="0" /><stop offset="1" style="stop-color:#003a00;stop-opacity:1;" id="stop4403" /></radialGradient><radialGradient gradientUnits="userSpaceOnUse" id="XMLID_14_" r="26.416201" cy="18.0903" cx="54.212399"><stop id="stop74" offset="0.33140001" style="stop-color:#f0ff80;stop-opacity:1" /><stop id="stop3926" offset="0.67438829" style="stop-color:#00ff00;stop-opacity:0;" /></radialGradient><linearGradient gradientTransform="matrix(0.6736273,0,0,0.6880491,42.39699,15.073568)" y2="31.295557" x2="32.584381" y1="32.580181" x1="54.103237" gradientUnits="userSpaceOnUse" id="linearGradient3894" xlink:href="#linearGradient4683" inkscape:collect="always" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient4390" id="linearGradient4846" gradientUnits="userSpaceOnUse" x1="44.142799" y1="3.4933131" x2="44.142799" y2="94.157005" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="linearGradient4848" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4999999,0,0,0.5990894,43.9415,23.614063)" x1="44.117001" y1="88.249001" x2="44.117001" y2="83.652809" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient4850" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6433337,0,0,0.5432152,37.044465,32.23032)" x1="0.1174117" y1="101.0003" x2="43.927124" y2="92.500053" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient4540" id="linearGradient4852" gradientUnits="userSpaceOnUse" x1="3.9885471" y1="100.01298" x2="43.874181" y2="100.01298" /><radialGradient inkscape:collect="always" xlink:href="#radialGradient4531" id="radialGradient4854" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6862309,-0.2788753,0.2607269,0.6833644,-6.7420546e-2,33.863485)" cx="22.501722" cy="91.356857" fx="19.835222" fy="86.023857" r="14" /><radialGradient inkscape:collect="always" xlink:href="#linearGradient2848" id="radialGradient4856" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-2.6486575e-2,1.3961697e-2,0.5271235,18.16764,52.58348)" cx="27.127048" cy="113.89391" fx="27.127048" fy="113.89391" r="11.990002" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient5332" id="linearGradient4858" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,39.75779,128)" x1="22.025112" y1="29.212114" x2="21.785669" y2="7.9726162" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_14_" id="radialGradient4860" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.624346,0,0,0.624346,45.032334,16.880096)" cx="54.212399" cy="18.0903" r="26.416201" /><filter inkscape:collect="always" id="filter5526"><feGaussianBlur inkscape:collect="always" stdDeviation="1.6283808" id="feGaussianBlur5528" /></filter></defs><sodipodi:namedview inkscape:window-height="729" inkscape:window-width="888" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" inkscape:zoom="3.3919028" inkscape:cx="64" inkscape:cy="64" inkscape:window-x="0" inkscape:window-y="34" inkscape:current-layer="Livello_1" width="128px" height="128px" showgrid="true" showborder="false"><inkscape:grid type="xygrid" id="grid5443" spacingx="4px" spacingy="4px" /><inkscape:grid id="GridFromPre046Settings" type="xygrid" originx="0px" originy="0px" spacingx="4px" spacingy="4px" color="#0000ff" empcolor="#0000ff" opacity="0.2" empopacity="0.4" empspacing="2" /></sodipodi:namedview> <metadata id="metadata3"> <ns:sfw> <ns:slices /> <ns:sliceSourceBounds y="-17.936" x="-17.185" height="291.47" width="291.47" bottomLeftOrigin="true" /> </ns:sfw> <rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata> <filter id="AI_Sfocatura_4"> <feGaussianBlur stdDeviation="4" id="feGaussianBlur6" /> </filter> <path d="M 232.5,-2.7990622 C 168.435,-2.7990622 116.5,49.135937 116.5,113.20094 C 116.5,177.26494 168.435,229.20094 232.5,229.20094 C 296.565,229.20094 348.5,177.26494 348.5,113.20094 C 348.5,49.135937 296.565,-2.7990622 232.5,-2.7990622 z M 232.5,154.48994 C 209.697,154.48994 191.212,136.00394 191.212,113.20194 C 191.212,90.398938 209.697,71.913938 232.5,71.913938 C 255.303,71.913938 273.788,90.398938 273.788,113.20094 C 273.788,136.00294 255.303,154.48994 232.5,154.48994 z " id="SHADOW" style="opacity:0.8;filter:url(#filter3273)" transform="matrix(1.0275117,0,0,1.0275117,-6.5019703,-85.16126)" /> <radialGradient id="XMLID_11_" cx="232.5" cy="27.3013" r="120" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#d0bfff;stop-opacity:1;" id="stop11" /><stop id="stop2806" style="stop-color:#efeeef;stop-opacity:1;" offset="0.39880952" /><stop id="stop2804" style="stop-color:#ffffff;stop-opacity:1;" offset="0.5" /><stop offset="0.75" style="stop-color:#efeeef;stop-opacity:1;" id="stop2808" /> <stop offset="1" style="stop-color:#d0bfff;stop-opacity:1;" id="stop13" /> </radialGradient> <linearGradient id="XMLID_15_" gradientUnits="userSpaceOnUse" x1="249.4619" y1="44.263199" x2="215.5367" y2="10.3379" xlink:href="#XMLID_16_" spreadMethod="pad"> <stop offset="0.30000001" style="stop-color:#ffffff;stop-opacity:0;" id="stop38" /> <stop offset="0.497" style="stop-color:#FFFFFF" id="stop40" /> <stop offset="0.69999999" style="stop-color:#ffffff;stop-opacity:0;" id="stop42" /> </linearGradient> <linearGradient id="XMLID_16_" gradientUnits="userSpaceOnUse" x1="263.14261" y1="53.012199" x2="201.8575" y2="1.5880001"> <stop offset="0.30000001" style="stop-color:#ffffff;stop-opacity:0;" id="stop51" /> <stop offset="0.497" style="stop-color:#FFFFFF" id="stop53" /> <stop offset="0.69999999" style="stop-color:#ffffff;stop-opacity:0;" id="stop55" /> </linearGradient> <path d="M 232.3945,-96.257404 C 164.29718,-96.257404 109.09309,-41.053311 109.09309,27.044 C 109.09309,95.14131 164.29718,150.34541 232.3945,150.34541 C 300.49181,150.34541 355.6959,95.140283 355.6959,27.044 C 355.6959,-41.052283 300.49181,-96.257404 232.3945,-96.257404 z M 232.3945,68.144468 C 209.69573,68.144468 191.29403,49.742761 191.29403,27.044 C 191.29403,4.345238 209.69573,-14.056468 232.3945,-14.056468 C 255.09428,-14.056468 273.49496,4.345238 273.49496,27.044 C 273.49496,49.742761 255.09428,68.144468 232.3945,68.144468 z" id="path15" style="fill:url(#linearGradient2869);fill-opacity:1" /><g transform="matrix(1.027057,0,0,1.0273239,-6.4508226,-0.980434)" id="g25" clip-path="url(#XMLID_12_)" style="opacity:0.35"> <g id="g27"> <image id="image29" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKoAAACqCAYAAAA9dtSCAAAACXBIWXMAAAsSAAALEgHS3X78AAAA BGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAGkrSURB VHja7L1Lr2TXdSa4197nRMR9ZJJUkpJsqctCF+wWDDdcgHpWQIMN1M9QT12TmhRQwwLanvSwa+wa qQH/gB55KnPAoQow0Ea7q6Bq02WSkiiRycy898bj7L16fWutvc8+EfcmkxLJ5OOmdBiPGxE3bsR3 vvX+Vgz3/+7/fQX+DV+GN8F2QXbxUzneXFx9++23w83NDR0/74c//CF///vft4e/FUJ3pb003X/H X4t/L/V7FBzSmz0icTG+HcIRKH/+3nthdzjc+l6///rr/PDiot3+mRzfAYB/LAB+awHce9DeA/W3 ZVBB5k/fXIAToPzu4Q/pIrwS3n/8QXjtvz/Q5sHdr/ULOXb/bwhv0Lf4fL0J/xD+Lnzr9ZWC9zbQ OnT5/qu/B+oLsOgSoBWcTx7vFZhX/CQ8yG/Q9dUUppzpFXnezcPrkMeyeL+XTzZ8fRjCQa4/PL/g Z8Ovw/nlwI//6xgeCnB/tf75c0F7z7L3QH0ui779kzH88fdu6MMK0O/uA+9+Q687OMvFiuK0IyqF aLcK9EoieUAgXgKVxxWHJymUsOOQSijrDV9eHwS8OWwFuK+8uhPQTiegFeeWwz3L3gP1TpD+VJh0 HM3Mv/dGeP+Dx8TfFoBu3qDVgyk8+zjHcrWj7dlAnCc6u7igFHLY7wcaOdJ0EEDzTILjMPIUb0Ia Isfdmjll5s3AZTvx+bDi8fLAH/9aQJueCmg3vPnoOxxufh6CADZUlv0PwrJ//eN7X/abDtRjkP78 5z8n9UGFRcNuTeHJDT1LAtDDiuhsov2qxPU0UhonOuw48j7J/VEYVdyAQ6QhRIp43ThxiBw4Jeap 8BgT05h5Nw0C3onLbsers/NC+8JFQJuFaR+OG14Jy/7iiGX/i4D23i34BgP1NpDSB49o8+2dYOqc 0sUDGq6eRFoL+FYpHm4CMCi3E8VDjFngyMMkLoCYfvFVh9VIYuD1NWOMXPbiJohDEIRI4zAWPIHp wIUFm+tQYhn55mritOESdyv5jwD4/EpAO3Ieb3gvLPtIWPZXN/duwTcWqCfmXkD6/qNHxLsdvX5+ TvuPh1hW4osOArkb4cfDPglDRrH1kWgVBZAp7OV2jJTTFIO4q5TFRx3kNQHng8JVzH0BmuWn6hQA rIWYhGJD4Zy5CDaL3Ddu5P7DyOUslbLfN5bNwrLwZTcfPRS3YCNuwYfiFmzvg69vAlDvBukjWtNv YtoOlGKKUez4VIY0EhA3iTsaUw455RLTgPvkOhhW4BlTEGKNTIJkInnpjB/kAmwyIinh1BIFznhF odQiCM9UBLAArQC1rBCaCWDl3jDJfcOBeXvDZ+eXZdgWDgLYD4dfh6tfDPwofee5wdc9YL8GQL0N pEFAGgSkTwSkQfxRoUw5LuOUxaYLOAVCSTCYhBYHgUASJhxCCgkeaAjyo8xJSJSEbQVleM+CVYEq Z+FOAaI4rYI0RWyJAl+hWPkhODhnYd3M8rQovoOQsDJuAHCdZQOQPq40ACvD7BbU4Osf7t2Crx9Q 2RKlFN4UkL7dg3QnIBU4paQgnbI4oQJSMftih+NAhzDIc4Vm5bLIZbBLeXtCnwJcCgj+EUVJUKXv We4WSJeAhBUDiATYgmhxZHl1uS34FdAKUKci3BvlDJHbAC7YV4AbivmyB/Fl016IW1g2F/m32twa fJ1/7/reLfiqA/UEpJcC0scC0rWA9DcCsWwgjQLSOJaUJx4EVWLhRwnTeRD6HAV+AlgexVyLh0kj Wy+CsKz4qwGGXdwBoVDYfsKvZM1WCckyIqysB4DKJNd5kp/j9iS4FGOf8PNJKDXDLeCDgFagGtdy f4qCTnMLdgLWJMFYvNqZW/CwwHflDydxCy6H++DrqwzU54I0GEjTNifis5i3wyDOqkQ/o7GogDKK 8cWlxEorweAoQFuJ5RawxpEUrAXsGu0IilON/WHsWdMAxqYB8T+BewHSiSSUAlALrkcBrHin8nC5 30CrroGcOuK8FrCteK7qElS3YHfYc2oprlO34D4n+xUC6ouCdEorM/csZj0PgzDYKPAYBWIS5oSV vMoKAJW4Sb55ASrjviKPUeAKUFkDKzX9TOS/XKw4MlZi9oM6B/BNJ8ZBPEUKB2FhAScf5JkKXoAV 4BXEC9PicRFpV/FjkSIIHoQJw652wK+AdlPGafhEt+A+J/slBuqtIH0gIH0iIN06SJP85yAgNds7 0DSIqQ+jHALMsBLPUAAZ1zzRWl5vLa+4FlZcCU8KaIOANqgbII8FUHEQc33fpIwKkHI1+QJGeWcH +e0HedRBgWnJLD0AYgHtQXwIBa6ybxaWxfNjEuAW8WWjeCaTBGMSeoVYBgEwCXxvmltwn5P9ygCV uT5fe/MscCIB6WYnwRPFq60E6s8EpGFKJECV8GUAUMUYy7cszDlFAaoAlAWcTGthzo18hUJXJGAV 0Bbcr0yrbgFXVuUa9fvbcNOv/qj5pAdxYg2QIeyJ+MAVpH5JfijbgmlLNleBkt6ORYAfhGnFHZgA 0t4tkOBrhLd8c3dO9vF98PXlAOoMUvz7iYAUbuMHAtJv05PdZQwC0sQC0q2AlFepHHgQX3AUnoMp X4m5FyAyakcKUInPBaSEZNFG/MkzsCrhMQzQBrCpHXAlivmp/j0jW4VilQDLg6mOPeVnB7ArAKuX TPvlzwNcAgE1GQu7WyAvLLeFZZHWFeAKx2aeJA4jcrfgBXOy98HXywPqJ4P0YwHpuTApoe6Zyg61 JAHpbkBeX0AqTJnTmiYBaBBwTsKihQSc6Ux+thHQyKXcHwKAC7YdAVZhWPiqwqgC1NaYQqxg5QbS 3DOnHkVYVYDKFAywrADeO4BPWbYGXwi8ANoExi3i90rQ5W5BksvfJid7H3x9QUCdfVIDKUr3JCD9 noB0t3sawzDEdJ1SzBdJeDOVPVJLAtIsIJ3KSrwAmHQBJ8z8sFE2BYNmBee5vOiZfP0GWAWqMCoY mMkZNYiLCFY1868xfzAfFWBluxTTr75oBet+BqhckgBXmJXrz4jb4+AylGI+bnBflsC24seSB2g8 5ZaTTQRfFoWzT5+TvQ++Pkeg/lRA+uZzQHooAtISkvBH4imJTwmQ8kgH+KNiysXEi+ncKGNmAaWw JwOgOZ4JIM45h/OgjKqugPxMgysEVmBT+KnwUWPzUzWTGuYcqoKV+uBpL8xYAQrwGmjBqDSD1xjX fFnC/UTOxmyvxcgcZHUJ4MNKXDid5GQHOcVS0uDrNCd7H3x9YUC9DaQbAelaQDp2IE3DRsz9NIwR qafBfFIx4TwBpMnZNBiD5nguZv88lBmsYNfKsuqjWgZgDJ3p16jf0lSd6acKVgVRx6gzGNVnVYDu Z3YNjV0NpKzuwuzjeiBG8F9ZswhkAdckNCpB2IvlZO8bYr4AoFaQvi0gvRSQPuhAuoe5F5COCtKg JdHIglMFVlpRjmsESQSW1MiezsSQCjgjQCksSheBDazKrvBX7dho5K9AJ0T+AzcfFc3+/t61MmVg ZQcsGbgmNh8VvqcyKgDKjUXV/Buzmqnfu/l3IFsQxva8BlgCeCNbrrbLybbgKwvTnuRk7xtiPneg NpC+LSC9FJA+MJDC3A8C0uIgHdFGIiBdxQHVpJEya3QPwIFJSS/jmbFnuNDLkgBWAaqBNsD0w1+F 2Tf/VAIvpKgicqmo/yeL/BG2IJ+qb18wgC6pLkUVZhfATf+hY02P/h2IlglQNmXm2acVIFOYAauu Qxd48QvmZNEsc98Q8zkD9UVAKv5YOncmXcWiIJW4GPlPZdIoLiupb0rncsC8X8DkC7wunFUvFKQG VmNTA+saVSsuVH1UAaowak1PFc9QFQuoWK9RB1YF6uSuwDITALD1Jt+uwzfFrMsMVmpugrMrg1GN nfvXWuRk8TsJYJXby+DrviHm8wCqgPSnb/40jG+PAtKf02MB6VpA+pqAtAhIWUC6FpCuBKSjwFY+ fAkneCWUhzIoQCYgFZPPCSb/PMLk53ihgJWPXAIrZVKqQFVwxgpUS01lgDTWJpVkhxjeogl/0jCK tefUgip2sKqvqkBV/7EClhfAmlm2ugUVoDD/lV3Nt23ArSBGNkDZlrt8bPCSbcT9SG3J7xSXVcB7 3xDz+QC1A+nPBaSPBKSPBKRBQHohmDwb1/Gwk0gpclp3IEXJcxCQCuts5PomglG5BUkXuBTzD7Be 1PsAYjKGPQs1h2r+rAdRpM0pyqbwT3OXnlLvlCz2B6OiURpBVVkEWA2w7lMeKsseHcac3IGy+q3m qy7Y1diW5mLC8esRLYKv+4aYzxqoxyB9LCBdC0hfu5RP9eN4PkrIsKGUDtMQhzSkmIckIB0FpElA KijaJDBpiAJUmPpwDnMfg7Gn/MILMKsC1H1TspSUsikpm0YEUCtN8mdlU+RjowRbyTw70kN9VK5J KrJyqnap0pyyKtQXA3p3YGq1/z47wAumbeD1gGzPd4AVjS80p8G6IsLtwdd9Q8zvDNSf0k/GMXzv j2/ojQ/fCO88fieuViu6SL9KAp2YiNIYJomY0jCQ0Cmj4ySuUgrohlZzH4VRU6CzCJCWICAVMAaq THoRYfLNZ63R/5mCtajLoJE+Ze9JzWRpKTApUlMOUj3kK9BRf/dT5TGsJVW2bn8D7SJ1VYsCmSpg zZzjOgA6dbnVW12D6qNy5yr0Odk++Dpm2fuGmM8KqBWkNzf03htvhEcPHtN6f4hh9Zu4u94ncZnS er1JYtHEwpdxPRKGTVZDzGsxZRIwhc0QwlmKdCaseo4DABXAXpAeUU1+NJaFG6ABljGpJvktUyA+ qQJVQRqTmv2sjdPwS/2Sgpv+oPlUY1QOzV81ZrUgy10B7tiVe5alyZiVp0WApGC1fgE1/15+7Uuy cyDGnZ9LteKlWQa+b4j5fIBK6pc+ot/s15F2v4mvrwNiobQRc79Z7SWS4kEodRzKtEbL/kAC0Fjg jwqT8nkkPhc0nwu7gk0VqMlZNTI5SDWoOkPKSjunCq0FyJYzdTYVoA4WQFl3v5p7gDS76a9sqtE/ GUiLdv1X0BayypUO+TXABio9WLn6se4S1Dzsgg07wNZ+AQ7ccrLV/M/prWXw1aXE7htifiegdiD9 4PEj+vb6EV2+9puY5JPasM6RYGZU8Cgg5bwSx1QcAgFpElNPJEzKQrVFASpMegE2jSRAxcGM2wbS oABVJtVMAEvghTa/HFfEFuUrQJkGyjXSN5AKq1IDq4GUlEntOlQpOmY1v9VZdWbZ0LsEmtZSsFIF Ks++LHfpLW0f9GoVW4Ggb26xqtacCdh3gD0s3YP7hpjfAaisQdRPxrcFqJe0mt6JW4FhKkN8GHZp HACanQROAtKBR3GthEV5vYplnQDQwGLuy7kwK9j0QsB6ATYdqOhlApMCuArUAKY900ArOEjhk+Lg iJIrqubyVA2cjE0zxeaXCrewtaG0XKr294NN62UNrkIFq7Gs9wXYZXHQBmNY5g6wOtISFuktCnO2 gJcthJpbZTf1ff/AbcHXfUPMb/cvGZu+SWF8N/ypsOn0eBIEvUEPLzcx7qc05Jz2eJzYIvm2R4EF KkXWlS8g1TSU+KTyJSgINaoXBtVLHEQQL8VxLnA7C6x+Kx6PVj6kslaBcGh3FGajBoFjIntvNidF Nnla/0c2hWr/41CH/YI/zn4atBfAn0v2HJ+5CuT3kz8G6ixkh3Zo4ff6e7CDUBGDtEBijHSbDIYe RNrQPXTvXQ+dTMBEg96HVkUa7Aj10Pv0tcmncKP8LggX4GB9fTThJOgbyGeaMEKuihyYkYSMQZL3 ieHwUS4R5kbMUWDePNFhLPKFTTTuRzEBe7oJz/Tn24tfE79xHi6f/H7gX79Hr378q7D+V/9E4X// sxD+0/8Rwjt/Q38e3qG/kTf3zpeLUZds+sGDB3S5/6c4PKb0IOzTtOIhDUEi/P24ocNKPllxXHkN n1Ro9kwi/XNxWoVNYd7zZYow9+VyUCYVZlWGlcCKnEnFL/VLBWnEOAqYFKbeDjX3mNa3if04R/lm /kNopt8OZdT5NnNxXigmnxKWrkDNu9Z0VssUOMPW1Nbc59oFXlxzsz7yAnMdbmnWnoMv7ys4Kirc N8R8un8LafQPP/iAvi0R/9PXVvRgfU27nYTcqAThs6GUplJQLB0EnAIsAVhABz7q+PlMWENYskgE H86Fec4EO3LJ5/KBi4mXoIkZnfvyOO01XQka5PlhJZ/AWMTvjWCoYnNRJMjFeDQrFTI1RtWj+DBq 48/gbGql/8q5xTu8C1tHIMAdq/eqGQM2cSCFdXSwsgM1LQBLDaxgz+oiALQrH8uegy8ts3rw1TIB fDCTX4Mta3yxIkLtOZiDMnMpeG6I8SPaSTAVALdEgNcbYuCaiJePSliG1becrAQWclWCL/H8x32R Z4wFv3YoN+qrDR/Ibx13/OHDd8PVP1pDzCNxCx5eCVz//d+H8Fd/VYMv+bpfLmCNUX/yNv1v/+KS Hjx+TJevHuJwI66nsOnFRUrpkAdx2FZi7FdDmDYS6WxSnIRNEdkX8UOzMKcwqDCpMOuluFSXwrpy yZfCsBeDsekZDrnvDD6tfLhr+dDHiL4A+ahgHuUygU2JjUl1fJ+NTcl90441K7Muj+x5VR/5a0FW ZVaTV61+qzOtzgr21a0K1q6HQIFZjlNb1a91Vl30FoRbxmGothk6gDncN8S8OFARcrwtQBWzH6cp XhwOcZ2u5WRMaaMmPw4p79bCbxJAZY3uBbDn46ARvpj1cikMq+DEpdx+MOh9FlRZFkAAiqF+kufC dTA2VaAm99MEHhiljgpUBakfpYEVUb1O8FNv9hWgMbQmlVzv9/KqSanMj+UOpPV2cw5qAOaPCNS7 AyWU2TXgEMppPrYLvqg2XPMxYA99nnUu2d43xLyw6a//DrsVvSIQm3YHQY0EVFF8eMjkknjpKYuZ juNUGEGQ+Jm8Fq9gnUNWN8ACJLaZp4Cfl7V8KTpZioQ+TmgETuiykr9wEEwAoAgohBx8Hqo2RuO8 j8VjHHwkQFYMvSNgUVSxUf/ijyN2zR8PpYoOA7Dz6Sxcre6pftRkwPSJsOgMq08xOVb9JTFUXzZR 9WGppbgGqu2F1sE1KtNannSaI3wBLHfpreoeMC8bYnjZEENz0/eiIUaZNrI1xBBNYo7Up1U3QBgl aQkZxQSJioVt5Vlars0lZQnGSl6XMuah5NVBgq9tGQr8vahNlN/9/Qv+cHqXfrMSt+BX4hbc3O0W fN4sq3TzE4mjPrp5O56Fm/js1VdjGMf0YJoGTOQV3q9RHh2FTYUtNwiKBpokSAKLshx6+UDQ9kCD KMoPwKpg08HyqsKmBYyK5651LJXY2FSi2hj0iH7MTMoQlYzmoqLjlGfTT9WMg0kXLDq7AItgqz5e xX+WLBtaaGUw5uoeBCseVMZlByvNfuxc9fLf2FJcNLcact9jYIw6nZRXu/7Y+4aYT2TUH8jxNOxu HtNr0ySnJlxFjhvhVIlB4lQ0aQJqFfAmTcnIt4RZ/VG+i1G+SqRbhDGjqp5o8QTzToG0qwpSPQKP gWoqR9M/pn4CmlRk1LQSKA5Y9YBIk0Xa0m8Ex6UmgIv7ncaybdg/hCXrZqsFePylWCMDIEBMzRvF SUHs5y9THXgxuFJ9AQ6m2GIw9+CLPeiiWkTAdda/1V0DMKt+BlPXCOOXsw/LddrAG2I0yOKjnKze ZgcrnTbEMIK3OfgKR8EXx6gNMYmFXU+Cr11JqH7tuYwSfKVwwXEoJY1v8LMPDhwl+Fr9/htwCwhu gQZff/az8LN/++/FLfir6hZ85sHX0vS/IWfHzcNwGHZykk0EgUg5LZFAhfAe9BslPpL3LmClCEEJ trxh4BESPXK/HsgbZsxMkQFTwGv6URwsbygAJQeoUaVG6grQaGgxFJnRpeoxmrX2IH1RsigdKqMp qBE3AFv0T06dnlUtjjxjU66o9YCrAz2TPyqEjn9dTri+mcq0qfquNAPXAzBGrjRzDb7YiwhkJVQI cXAPWOblUCIfNcQs5r6qWzAD1goTPI/RkAVf6sM60wLEAKjYNg2+hIrEjx0UtFFAi7Z4Erdg39yC Fd8cbvjq6oqHByM/Hd/h9OolDx99Jzz69efrFnSm/90Yzt9Pw1Z8xsuYDoNE4tO0WvFhDZMvUf1G TIbmRYcg5j5qECUmPjwUb/YhTP+gJh9HfiCPP0eOVdwgZEKQJcDrjDD7fqQEgV4Bqmb1iV0FjSwD H9TEQ77PIFiimvxm9t0lUL/0KPJfugOxmf1FAMbNFag518At9neutJ6BmhyZgzCHdz1aybb9JrJh GXRxudIgzRmCzIFubzskvm+IeR6j/vqd/0zhlSEkTNY/kE8sH2jaw05ZwI2SBhrSI0obAek6sR3G JBLQZ3T+Rb2sFZyQUJKGyLlWtBCIFaM3N/dk+VGYeDZE1gqTfeP6LVOseij4T5zNfAtvQs+mM3ua zL8TbA20urYGcnTVVCxzY11zUDXfaqzbcrLUXjB4wFcBG2jmfFzDCoyaUyj+bGi8zkwbeM4WUD+J gHIpz4OJRzlZsoCr5WS5NsQscrS8d9ehtiK24Gsu//p1AagVGVgzBtacc5DLlMW5m0oeMiCLhpi0 9YaY5+Rkv/stCb4GCb4+h5zsc3ehliw8B4jViiROMPs+5WSzWAdFJPlrlAgFylhfgggnapyEODmi kwSkmcX+y19shjkWC+Yp0yy9UiGnGqiNruaMvnqyICj5FWQX7UdKYi3q90+hmf3Ow68eQqFKjw43 O0GCsbbG8vgrlFP1jAnE7ewwLeHOFai+az2t9Fnc5WPJSg8oQ8+FBHcJGlDRL4tyK/PR+AwvG2L0 qJE/ax6WjhtiFsEXnzbElPl1NZXWGmKgLc/WxcWHCUHXhIaYIWhDTEZrl7cDlb2A9nxdtiTnwkPk ZG/U4z97hdQt+K64BRJ8hX8Qt+BbAtiHv4NboEB9/Q/+iMX069f6ayPVo4dkDWPJ2wMyW3Uo611Z Gdf9xwaRot+2Je2zZujtUsnUQ2Jl0TDX7quYVP3NNWKJHReq96plpagAs8AoHrFrLWbFRWBF1Ada 7EqrXpvy1+aaKTWQqpy1L2JhZ19qlp87wDpIW/DlwHU1l+ivXN2D5su6i5DbB818mpM1kE7hlpws 1XbDBsZbGmK4L9mSuwVzQ0zoGmK4+rIFDTGDprnky9Gc7KHPyUbwUsadmpOd9s84TWeC3QsJtefg 62MJvr4rwdfmo4e3AvZvzCWgT2LYFP78z8P/9d8C/Y/TU/rOq4Gun0xRGF6cZwmf0oB9DgO24cgn Ln6lBkgr+RJQOjQVE0ybIp9Kmj9d221c16aMEfv1iLzBgqzBg5SrlKc8F9UA28IqCktr21+6uT26 TX05tQOnV1orcy8eEJbP6Wq1i9vUXSVqUoKtsaV75aOzZD4R/e/VIIz8xKQaUNpBuqXAXCpvyknm Lun9Am6qGZOX2hCDukGqDTGwmgne3xpblmgjcfKQ8XIQVZQfrhLtPs70VH72+hvrcPHk2wLY9yh+ /Kvwf/+rf6Lymz8LD//Lf5K39PxGmIXp/zmK8Zszvj5EPtd3dwjYN6YJKk0QIVSOFmLEVGwjScAS Er03k5Uj8b9s3xcjj1+KO6ORnJmdfMgeYQhooqehA0ILqfsQO8yUa2ZdfdYyN0yVhQNj2CnU2FQp kihwD9bivFcbsHh2BSxwM1fAfRF3ZgN77sC4mhcIZ//vHIb5Azn0bgHNfmyfk619ssSDTydMLc3l DTFsqadDTXG14MvY1NwCppMp20VDjPw8VhGOzCcNMaH5sWBatrkv+LPiBwbMfI0FyT9stFO34DDY ZC2KCMO5vPu89/RWFoZlYdh3OP2+ZQp+FCTo+rd/T+EvZ3Z9U9j1Nldg6aN+EExKV/5tR2SiJPIR EA6ka0kQD7FmMWHjBX4FDcgRX2G0IRGPrQu3GJstU0n63ZCFKN4PQlos77/T4DApFVA82wOLXXqf tQOru67UABvnjCrFcMx5HGYfo/db1TPxhJR5KZ3BDs0VmA149UTUISA3/AvA1ovmz/LsLhtYGRle 0krQwi3Q1Bb6ZGsTzElOdmV+LC/ysRbpf34NMQT2ykkuaSpo6sbeuqlMRXhUSE0CMIFpFD8Bxvjg gC2ohGNkk/mVywdl3F6E8NqTENQdeN/cgb+S3/Ljv7kTrA2oF29sOU4PxOB/xOkwyjkr4CziACSc 3RLtoWYj7y3YihycRh69miy5IDZbw13EmYWzTDt3UAPNxRSjiieYMkVP/iCsxiBTTbTbNzEHVzzn +7us5knrd62EenWeYy0OgJs64JYZsNxcA8/f936ru7rswA0euBmQ/X3E2asiT/Nx5dmW+utaf5xf PdCq56D/Ag0LzVz5cI2uMaK5iNA3ddecrPu4YzdV65pbsy/rwddpQ4wGX9QaYthLuDUFRrxsiGk5 WbZsRK12Cf0cCAWEMAk4xI3A7k/xZRPnCS3vcGrT+pAhw6gNnILPp6vMO2HXB698WH4Q/jmL70rh ZxWsQcB6OiflQH1bjks5HgvKVZiPaYOdonLO7A+80YoF7LycPYKzbLkn1ViygTnSkV8/013/CeMT Ft2iQzTrGAjIg9U1UMCas6Zfd7bIm2aC4wbC4EWh6DYx1p+FW5g1LNLzJ0FWKwqELtIPxV0DWngM 9EmuwIL+a0thcCeG3QQsOLW60/pDT4K1yKy6Ba23QHdlUQWvtx5yDqedXLcGX3wCWC/XkoHXtbiO GmJ4WbKtgRjVTEHrOxCADmjMGs2FSDrrlUhYdoLYhniNY5wSRmqV6UIZ4pB3WBf6RK5fbsrTj7cx OFhDuA7h78UN0CBL0PrWW71BVadZ9XjDv7A71ufn/DQJ/eUtXxRsahyLoExzvpjZKcBXsAPJYdYK C6M3E1t0QblyO+p9qGsg2MdmMtKxCbTo6PCPJiIRt+dWN2VvJbVOkFZxb9+kJ4c8nK44OIkU3Znl 2AG2Z18FV2lpgMauR0y7cAXcWN/mCmhHazXasbI7u9fdDD1Xz5XDbAEahOdG7hA64NoOTcs70Nxf kELLyerpArAOLSdrwP1MG2JqKbddB5gDWgzZGJeCuxpyQkCyE8vsWMsGONWRyZygCjMdgKKJhmEM 6Rm4cVPoIMB1NwB/988ErN+5+Cv+flj0Djij/sG/DH/xLPC/u3mXn4WnfLaGlvnEW0RN4gkPJkmG lnLxOLBojFD6lw+goAR3kJNF/vCIt4Fk8UEejvzclPVD1A6IXGtFWdtC0A8B90EtP1tK3oMq3yTh oDXCmpM/2thUnF1DdfpoUWqDVsXSb62kV456AZbewyI3xt2ZUvNmtfzfuwLz7zxKsLB3cNXMlk8a UIfxY8+lo3l3C7imkiOTuwTPC75YS9qmX3BL8BWOgq/WctgE43hWPezljJoAh/u3c7VMgzKbTmh6 XsgwSIBWsKg2akYL6QVMfSGHMU0ZMzSaWn/2OFxf7kK4elQe/+ZJuHz8XvjR9y44/KW8myVOjxP+ /6AuwHj2gMenUbu/xZ8U32kPbhTAJjkf8jREy60RMsLyIQxqCuKBvDsom/lB1zkKWNofqaC1Piis 04MQiHWeqgsQ3R1j70xZGOHGTdyy6rNJ5mbv24O1H8BAFR2B7gb2aS5eFgFaoOW+KsnpqB0JZabl Zv7vcAVCl5MNLenak+a8doio82PpyFWh5sN6X5e3JVg0F30J3ElO9jj44t+lIcYEOVr3FnfMK8eu ZhC43jbGHdx9gHpGQn0bVIe/NsOoymkSVwNJqBUGfPeXazmdRnq62xG//lTewQ/0T+lYFUUB/UoG /ZTelLfx9tt08caluMITnx0O/PQyCXdelItwUw5TKGt0uWPHKCWcubpsjLWSWuQPMlYV8y5gzXo7 t5p1njK0PqIFWwXl/aC5jWJlfl4ExxbPmPlfZDyr8+nfd/RvuHj76LGNN5bzKlawoEorTaheJTei IYa5PhVbmupuv5Xcb3X4BHcFgveAAZjVFbiVXXk+m7qQq/XJUk/33Hvp1TFw8HqmAJcz07YybR0D v7UhpvdjP6Ehhpay8ruq1I0BT3cFANgd8q41dxvMNdG2Te2BK7ZkWW0mpAo0kRmNpMQmbPEXbjb8 WnnIq1ev6R8/ei/8Ybjgh0esOjSUiJ/6F3L5bx69xs++v+ezGzH/4oVsJU5aixOMjBhDNEfMO0y8 OtQQyY0AacZIhFwiLYKh1az+SsaZDP8E/qqaomjDIijAwg3QXjqkvApjjg8ZsGKbTTWEIC/bLMrs zV+lZpq5d/x4mcrUOCS6Y+Ht+1bJopaZJbftNZSrM6s8J/tn37VPW9VsRc9vNagK3Sk4l7TmVFug 43OU++VZ9ufQnJSj1qJQmyRqxHZn8OXvrLpd1hCja5B0L9do6S3qG2JWtazKyrChnzpAQWfHltpa KUi1AR6rQNHiCVZV4257FpQ/WD9qpSVy3xH7a8eJfViN14eReSfew2FLHx6ehjemH/BZKM9J+Iuf ikTH5uZdOrvZ8Pp64vUAoY49ZDtgqpVR4XTgV2bsFxUQynVlUHlLagbYbpu5EKdbALrGbnILwBBY xSyfViJPXeF719Iqz7Ulb2E+YdXSO5ReBJhzBZW5jprDKqRvKQ60V61TgWX2Vduv6q/XFFZNU1H3 894VqOyqVZKWiAq1KDCza5/Y7QDL1bhwl7lo3qy5BVyrs7cHX+F5DTE1W/C8hpjAi2UdXkRYuZlv mxbDzKSDOp4wk9wcKv1Mi05VYhIOjdjFiUoud/JJjZCMWpUrHulyesiPhVUnAfJ/VvN/IeZ/AdQT 80/vn1/y5XXUdvxwwOhNKGi0LaipRWiAJmHRfBAQHxKXPUz/QORqIWBW81thNrJ1t6vfiolT8nQX vsaCkoFmAQryrIqz7KjIxN2wKc85/K5jGR9B8Tpk7cbrMUDHYL0lyOpP4IWvegRQ9VvjbI3rQGyf FViwa3i+KxDmDtk+vU2LvYRUEwl9UlZ/5C470XxSc80exNoKbm0X2gfmwRc/pyGmy8nOUwgrasrc yMcqMHfspVy2JXWuwcCtwKi/O9qcWbRdYPi0MsaZkQlC/pIEXIed3JERe+35qXD0K/IOfvnRr+gP BaQPNar6vv7NwyL0/ekc/Z9J9L+S6H+T4Kuqmc5g1Yhov5i54Gi+adSIL+2zmHwCmxqTajUDJqQo aEmDq6KMDAugNWwYBZQQrCCg3afZCq9YzIvMbWz59zYxUhyMkbpCQJ9jPwqwLHHJcxdp6CtZRzaG Q+er9tkCMreh0CKXX31V/X+xehO1rIAHd3cEWv2JdMSu/VnWsrE8w7YzJa1Npk4hzA0xwYMvHQXn 20fBQ98Qs1DqHmtaS/1PNMTbUrqBFTeshxm2ORXnn3LRniUP7FRTi2gorJvCM/oFSPuygibtAV8j cGOMf/b8Wr8iVZncWPV1Hj7+iJ8i0yknzoXCZhBGZZ23gaJMLdeJJRfTn/cAaVb/NApIWa7jLIx7 OZ/XUasXPGXNFuh0QNEUm7ZclahC0uazajXWiwFeZm2do0c5JfbAaoZq8a6ORRJ1YW7rjupuvvQu dtVndAODoesXaLsDneK9G/LUFbgl0Cr93EzPrreCtZ2B1Lm4PGdlG1tzDcea+3oafJlaVytnFG0+ qW6BApUTz8BFsD16vnWw+8Ggte+4plW4tk7UXlubhtUYRdNdw8R5iGh4CdpGJ9fkqoQ+Ym9pv5IX u1nRw2/lMF7IW7j6YdACwFF6fP735pv6l/8Fyv7Pdvy4fLuMdFY2SEu58gR2QyN6nAoyYqqLpCU2 YcpD1khQnFrxZ5DT4hKhVqdBVtafpwn+KlhVDy3NRjuKJv+tIceKq3q7eOG79cjVSTvuAqvW4bHs AGkqlH7U9j67zjZHpUfxy6PbutoC3F9vM0KF9jjyx7Tnkd8X2dvEOXibQ9fNNT+29ntXliTq7qc7 5eyo7zBzb9ZHH8glimpurr4TnCpsHVkOOIvSSYOh4Nu82QRB1t7xsbZJYj8oqHwT6XW2I9jiOtZF y3IU3WGrfqsGWMg24PdpfxWqSIxOpgSzjymtaRo0v4NflF4RfPIN/erxY7qZtvaX/eV80g4nH4aY /yDm/9GryID+Wlh1w88kqLrYP0NFqQzQ2HO1ZESHGukj6g/onlVQIn0hbBoPYryNVTnuMTZNpmuv fq5O50fyfgBNBdgInWpFUs2p2rdQdJC667o6MtWwPzzneYqLSYWugnWcDWg1hOgp9DpBEONJkNUa WI7aAgH4kxTWsSuQ7nIFukArznOuL8Cuc/C1dMuP3YJK7afBF7nLgI/NFQ7xfXidLbqmTAW4rUvy 04gWAV5rAp981MVaEOtsHFL8yARk+RQimYOvnnVR3w7lswI/tWyFDxI9b/XJcHLaelCltf93p/D+ qxJUTREFYFaNPeFr8VgBVnR+T3LKTJpHJfFV1T8t6gLI3+5+qjCpiScgz6pTkMWURTRlkn1GPrMV I+FMZY6hfv3WaV1By4tKaGfb2gq/PjPaavC87A3gY8+wVpl8gqA2tHBZfjSLbquyDNQaNsqcelqM uTzPFTgKtAJ1pdu7AHsUfBG3Z/fF2vrac/ClHizTabagOkLqEsQqUNdOgLlwXfzUrhJHg/XKoiGF VS5U3QMwuIHdxejYpOlKafZiSllbcEM49y/h5k6gxluFKA8Iqv6Un55/l88k3rt4mMp5GtUFyBg8 8egfedEi/mlWZkVgZeO6GaUsjipZw+6nankLuVXxXbL2BMgla30qC0i1ZdBMvpr+YG6Am322yenS 6VLUrHY7GilxSyr2I/s8i6G4+Xc/NhYrDFQjWV0CN+PUuwTp+L4yX0+dK3DsHvSuQLzFFaAjV4B4 thzPcwXo5Lb3Y/et3dUtCCduQahzb1bCU3ApC3qT+3yfN1JrAFzH3OHLcqquhTvzLrRQZzPbX3Y7 S6bkSclrTzB8qpmp06Dql4c9X16mssLI1F7VSi2YQgoXxCr+J0MhhqLWjiOuaypDmJWLNkOQApkn Z1Yt5/WVKm3MpOg91sgTm1yJNyT5WBS3U4u6mKQpRNTuKmdgH91f9AZUGqWFBbUqVisElC6NXlNW ea7CGojqSlbugijWytcyheXVLJ5Z22tKp+XXTxtonbJr7TTzekB9Ff8Q69/Pc4eBzViaLZldKXPr /b4ehM3nbXlSCgupmX6svFGxZcl10ZLWpuoQEjK0QlPjCt2BSYOfVy4ueL3fGHj/tVz89V2Min// iwRVYNW/Owsf/GLHZxJYrbaoVE28gqTRdBDjr8IF+VCi3PI+SLYsgAZSDBY1ITDk4OC72oGOK6Sp SAOqrEFV1MYVBFIWTGmtli0TYF2rde5YRw3YBkSPGbXwbKRKN928CLCoZ1a/3YKsYr5qmlm1BT49 GyYfJkxlwZxqxVKxAKw9tsw/j0umbWwa7wi0uqaETwy06CjHRn1qeBl6tTq0j2PMFY9WkqOOnemo 8aI28XIdMGfL05ZWCnSR0Fp4AN8UBWnRxnsovKMljyGHJS+FOmz++Gm4+E0SkCJN+/dy/ObFp1DD H/wRP7qsQdUvJKgaNZ10kSbNkQGomKQWg6DRvWD3kEwzVEDKWqESI+3bmpVJlXmzN6tEqCjLe0Dr 3xxYkeasSMFae4tde5dLl6fxijx37fOu+mA5Vi+PLxLr3ejASXxy6rfe1ttq3VMeQ/dTAq0A0Atd eEDVcU1N8VZdi7m95JZAq8+5flKgdcKuvBhpmL31WpttUaY3wCzKKt1Lc3+e1+JB0YFi3TJTK13k Upw8b5+Z+wu0AIl+jwycijubxoyuJD1jV3to8UR+Iic4uqJ/KYfE8uHhc33UFlThjb0d/iL8bfjg 2RP+xdMzTmUjfuqgqaoprTKvIFyQdIaGKptqqiooSIP5rsqkyrDqqwKspD5qYU9VBU9RHfmpXnqz 2RdlUGNRzbxWVu0y1/qzqgbR/FY+Ytij1FX9qnq/lWY25Z7lmuHjpW9KnrZKR37rrSmsGqJUn5SX TOrpqvYax5059GnYlY/YlW/5pquTwPZReWth29zdN2lr6KBTHT7KzdMsbMFzc3YT0PAGmKhaWEiJ Q4VFtyserJ7JgyCXxkM5P1/xowcP+eN/HMJr9G1++KMfcbj6cftjhucpp9ZU1ebwLtHFU14LHJ8I mT6En5GyhPze7GCz31PSSlTyuZyu9h+RWy365qO5BgdysHqT9QDRlGxZKvRp29hfMdXJbq7KRKk8 dVXm1pRKSF3/KjdFoNA1B85U108RmFNG3ePpqBE7VJ/SCjF6VrRegNTNYN3ht4aOaRcprI5pQ62G xfn9cew6qn4ndl3SZLNDtWGWOl1u8j1dlS09BaU7BYibJCa3Vj+aBd1aC6DEKHHeTaCpSb0sE8RX mG21ZlyJJ7ha8TN+Imb4Ojx45ff57Hz4NAIUR0HVOxP/8lXiyykhalJCXIl3WpKKpsgZVqZiMt4C xnCA5EbStjDq5GhIMwTWu6pn4kjoUlQdCkJ5NmE2K2poo5lRTVUFnW/x2WM+HgZcfgOpKUDMtiq6 mbWqFS877XgOKph40RnSxvfrVH/hLt9KiwLZHGS5ZFDLt5L5voXa0NQihfVpXAFeBlqfMo3FCyz7 3kMzODwbnuAgpSaCURUCD10TtbX3BdrJ0+Q6y/WwdZCiq8r6U7FvNhrbGgOLMZ6w2UW+b9J1OyXs xlJ2kziNK37lWyteD+iJvpBA6geLxun4XB+1BlVdqmo1HngjMdE5tp+OYx5CmmvEHK39T/8o8mZb O9s8kNprZ5W6CNX8k3rVRRuq64Ggqpr86MQT2c09NxeA54pVbapeBFd9yornnoBeLKqlrhbB1Xx9 Nvlz+ircmbIKp2ktsnzpIoUVuxTWi7gCtHy9RUVrEd/cWdHio+sdSOtS+dDaAclF3FzachYcZt55 QwoAupWXuJHn3cgL38h9KCfpAdCKud8p0xYTcdPxbezNiiUjFWRywhJkoTZ/ecZZzP6vxOw/FbP/ s4uL8E8a8r/1gsFUY9U325TqB4d9WdOzeJ6GAidjnaIDFeoZGWZdO/6jC82iMiWOwj4xEgSkCh1k pv8wm/5g5l8FzyEipKWLaLV/db9JfT9Nz5U2pkKLYgyHcGohaxOTjbBoJwH3jcmnTSJ9T0DfeRXm 1QHNAV6IDZjAH/f7A7p+AApeQIj+OKbFmMHsClDX2hHa6HY/DsDhtKJ1wq68qG/UP4+bTpal/kun PqipazPxtekdHf2kDCnPNyA6MBWkLNdZrpNdl+coYNl6U3fy9nal6l2hqb4wyAmKFrkIm7KwKSub 7oVNA68ffYvD+XX40Q9/IP7p1UKfKn6iOpXW/yWo+ttnnqq64AteF0hOb6Z1gaSLNkXLm+CskoYa TBX1V6MGUTizJKxXPU9N/GuAFbVIwMaq+gcUY9O5/q+smjT3hrM/VzYNXWDFoV3OqatjRu17Afr+ gCNmrVL+t7Bs6xHoAqoTto2WmqrsGeKSQS3h74+jsigczMFXV3xIn8CutwZaXUC47GbloznJJUjn dr/JFQCtp1j7jHlLACNKRwpOvpbT4lp+mVyGayEeXL9hgDgqmLfyuB17H6t8U3tO0xRHnoaVEFka 8grenLLpVth07Wz6obDpNvzTkkxfhFG7oOqfhy5VZfV/ol25gASGpqqyj6roFKqOM+h4ijBoDOYC wPwn0jKrmQKdryJtwJbHY4J1iFpW1eY+FVermivZ2dTDLKa2TKrvI+WTVFJNWcVWEGDvAzgKsLom 0NZt1SZdu4mQvuwaukiusm1xMNb6fmXaWqKtTO29qy2FRdykMSnOEwQ+YX5UfnV2rSXYYzNCXXWj dd8tpDJnkPJSs7VTU9n5qAlAB5a88RKSHSwHsV5nA7CCVV4VLoE/l3bya3dIS8LKHg5B9QEPltIU Nt1z3sE33Qmb/krY9ELYtEb7bzGFF/VR70pVbQRnEv2vhfUwwr0P0PNjFZ6QD33KKk4AX1W7p/aC QHUBEFgV9VdIfVVNVWlX1ZyqAqOyDqkZo7ZuKviolqZyHzW29FTvm/Ii6d+nrLqCAIdu0dQdRYGj bqs+dbXwXemo+6pLRVHPtOk4bXXb45Z+6+z3hrlAEJelVopdspc6NYw5fXUCUh+/ns19D1I6AakC VLBv7BnCFSk4GQDVw+83FwCsSvBRJdgCk4kLiAalAmuboGYa8v5wXab9oUy7UC6/Fcr6Skz+xT8z 3/QWNn0xRr0tVXV4yhdhVZ5AbhIKvgViKJirKpPQ6ZTgq3rdH75OVBYNWqmSgE9dAPioNmqtZVUw q4pWwMIXrPIJNrLgC6B03q+EeDT/X9dQhWWayhtUQif2pPp/Pl9lWlZzd9UscnnUokTdPP9RJ/OC SYt3qURaZATmCYC5LEtde8fCb12ksOYZ1MWIC3WdWLf2uYY5qqpagvrmuevboTILCs/mvtvCsgQp KYPecM+mAla5/0pZFLejMuyNvPI2hyy+adwVLTjBosZDFLOPebsUobgmAfi0L5tHoTwtT8Xkb8Kr r3/IDyTQ/9F/+CGHvz5l0xcH6l31/+tUVlu0UE1lBakUnJ1DcUGvMs1pDVJzD/Am+KwC1toO6P2q FaxwAwZN8OhINVQv2AYarbPKhk7oaP6/H/ynFjw3LIUWd1iSsF6v1UHun7+YBqk1eOq+/66C1U8I 8Gz2+6mRphXQqk3LihV5sMQeOdWJzUb/d7kChU46qzVBsmyfUpC67LA5xmyza6EudXMm9bHonc9E bdUfdQAqMNkBWkHqgKX6GH0cbVNIMP1bZeeI+f6s8j9xkN8zSmSzSiWfyydxOOfp/TVfp/f4lXPs smom/w7ZyRf993/+JIT/9Z/RW/m74X96+pTG/TVtVpk2Z6NYNUzFFhoS6wqeGHS+C0NlCRv5Ik4I hv+pMzpjNAlErPBxqUSyvQB19yjV3aTavxBdo0+/RWs44dAS//Oi076ivRRd7SUsaW7krACipfbk cnCpl6o8fs6xzGWYq+q0eEAneUmLZqcT2czj3zfrwvbPpxPZzaMmJe79Ul8h50xKvdL1ROQCEpoX dSYlZ9IK0nALSOXS/dYbcpBaeoq33ECaBKSY6jhMBxWpHHW673y6LI8v9vwRvce/9+jCqlAm43On EvXwwkC9JVU1j6pMgqZURnFTB5//Zw+qis5RaW51L77BProsTPK8qvbQcF4jTVXI3ADsRIUQm/Yy BGtrsrYUsgFAr/trL24onk+9RRGwG7kvPcv2jdbV9HcaV03YoqV5ZrG+mjrijo37KlavpkJ9sFO7 m7sgKzRV+KM+AZ4V2BdKGVVdrSsQuPvBTV6rkKWUC3euOs3RPRhVpX94DpyWKagbD5ZmkPItILV0 1PVdIDVh4MNUxO5nCbjTMGbsJDmfkoD0mi8/eo+/fXHB4QVA+ukYFf9+Iqz6396mt/6fQH9Skjgc r4X1MNAK/QZ7TNuCILXrGZuYIUiZXJxWx2khVBCr4Kwzqg6I2cZmMGll1qGK25rMunadkwsA9yJq dCJUcXTZKe2eMG5rU6Mluy0YbtF4FI4kLOlU03Xx3J5du/uOb3ekeHx9ZmZesGnHtNz12mielJh4 FjUga9/1JhJN5pMHTlaM0ehcE/XCpAiaLFdqQRNVgH5KkGqrp4I03wrS808B0k/JqHelqiZ+NiQV UbuU6L+ow2x7OeWKls8GNl8VedOInJrXhy3AIi+nmsAaKlyYdLWxauSoTH+1qKpB5LqEojgbZddW qe3CvRBp6f7yqpwbujx5P4/MtCxR9p1XxyISTSOd+iIuLyZFKHZ9rZVdq+/Z7R3mGmT1fqt/bSfs ysc9rnVWvObdPHkRPStXQBVsW1BZM3w2dFf1UYkbSOXFbizVRAZS90m5mvyXCNIXTE/dnap67913 wvvDjaaqNpD8HdYYf85ZPhgITWgPgK7sDrUhZW8TANZRVbusvFdVq1q6e80LAGxDgLUAoKkqJP+z ygtbeqpuo1SJI+67qvqiAC0SiNxNBBQvp5au1FrHWmpa67jcWov0bTEK9XsB+uLAsuRKdFosoBQW g4HUlVefn8LyaNJ+xnbYFJRl8nTVR1NIgVq0K6IYSOGTRq3Lbz2tpNG9fFLKpJVFqWNSgDO+BJB+ ekY9SlU9OH9XjAdSVeKfCjk+IV10iolSqKmo1pTQoqr7Fa5bODTahzyh1f05e3sg1JJrRxXO+qjC sNbiwbZkUneUxKr+p9P/RQf/rKWE5hBloZNSunriwl/t5v9sqshTQEwd297CrGHe8sc8uw5VbHJO N9RfyI3WyRmwNacoO1LghaYA+aZBb5Zp/q3Ls4dZvsAbl/3sUO1Z6CK5up+yKJL6E+vyCN7L70MZ WwAqTFocpBoskUf3dN35o1fyWtcKVqbOd/1iQfpbMGpF6t80lerL1x7wLy+JH8dUBmgMCJuO+HBG 005FpAWTH6xcKgBFekq7/l3esM5WWVmVlVUpa0lVBYLJxqpV5bo2q9iOA3baUHYN1B1dowofXecu 83PMriF0pdWjkuvicl5SHY7GsedZrH4c+7TkumDXozmsRU9rLbVSex53r8neXsB9666C042P+qPQ Ukge3UeAVDueNLonZ1Iz76g0FVxetduxAyl1II0CUvpiQPrpg6lFqirQW//11/QnE4ezckmb1ZYG znHgpHtTs00sJ9VtwxAYkQsbQF2DdPWk7lTywKrqF5EFVUMdIvPtINEGmZnaJhX/fvrlJ93tcEvG qavc9CmssEgdLVNWtBxBnTUHu20pFI5io3Db9EY4TjndEVQdB2Kh3/bSR1vEzesJdS2xjqA3qUkd a9fonrhL5pObe4CP3NyribfAKdAiT4pdfQ2kpQOpK1V/ESD97Uz/naMqtf4f5D3nPIpNh6+qJCgf VmRbvBVRAIAGvDZYZ/VZ0bASQ3UBND1lHVWqqoKca8zeo2oZAB+kzM1DrfX/SLW7Khylq+ZWwHnq rFnkLk6pGSErzfMta6SWEjx1Apk6JfTqctCiP6Cul6AusjutXLVJkRpkcfsLuJswsaycOdMouRXf 4QG9OWNSBKb4HKO3W8IfLfBJWStOCJZYzb4C81p+diV/h7Opm38waayM+/JA+lua/qOg6m//Nnzw C4yqHFg81bIRSz2qmS7iCkRtOAGUIeXDZKMqtqXDD/VVUW6NJsTFrleFIUDNBETtqtJxFVNWsVGV 0FyAOgS4MP/cXIAaVHUuQTP/dWyFFz0Dc1DVBVR8txsQGvhrkBVuH2057r7qg6h0FGTFPsgq3A0I WsUjel15/ihyPVoKCkwKv1SDJjH3UBEN3FJQZAGTB0505akoNJtc1Rq/gbRsFeDDywHp78aoXaoK UpW0nkdVkFd+gOkt9EOrjJTN1hQHIbSMYlt56KJqlPW+EmxMBUosujoAJowAVrgBplUV1VOLVJOE VPeMaQ6LiNp91tXfFKtdG6CNqfA8whK42xHQp676lqlFX8BCfqUxa0tbdSvVw1IGbRlkxU7msib8 vYeAuEm6VkqpajLMlUlZk1oY57Q0VOS6udpP/IBV4RB43MrZbAxZtDyqgZN8kEg5XVmliTy5L49L aOErNwJ9a9tD4JTppYD0dzT9x6Mqr/MvX93rqMqqUJl0DRFyqliCGu0sD9NURWJt7t/AKrZ8H71S FV1hxRZYRB1fKLplDg0qthKoqO6OLRYpLrjQjH5TWYnukhYDZweZeeeq3VO4zwbM/QDHLYHh1vtu AWsz1tTE1cKRO3ACVu6qU1SbaqsIrO9kdSmZYFmO4u0P1lxSPE+qSovKonuCqYf4roDUGpvpmhe1 +wpSM/9gVHUHSnCQkoOUXipIf/tg6rb6Pz2lMVv9/7qMtJFvcxiKZuu1/E8FuwldaQOVKG7rDmOt +ddqla1KTL5GUYIrTm0dY9VDsu/UVzVyFyfpjl3bwdbVx1tDcaDT+IqOr9PRWktqFSc6FlINx80h y76AI3ni02kROtp60RS2FzPdnZDD3MFodXtqgRN5nrQviwJk8rtvPDcKsJp5hy8qAJUvRsDpINWk vzBpRLdUTUEJSKODNL8ckP4OPuptqarv8eVrr/MvxMCXMfMuHjCGWFKyMx6+pqaqCPr+JqgW3E/V xH9Bwt/SVUHvM6EKpLhQAMiWsoJxV1blUMeqoyf/a39qd92P1vXfJf75xF/te1V7V+E2P/Vo7DrM Qha9XutiYqArDHA/GdAXBqhP5nNVf9JkfohzCgqCMkg/1RSUii0ieIrYNM1790d32m0fYe7ZAqco DErFfNCEEilfCZVc45LhuybtO73hGt0nAXkiYWb5Pqa9gPTwUkD6uzPqov7/Ef2JfKuX6bVwsaj/ Qw6TgJxUlFWxH91r+kRW14fAVl1CS+wpKxPfilT1jjRdZcttQabU0lQxVkVoquTJ1Abeuq4quoPR aNmo1KWvqEsvLSdLT9iwL+zT3d1RdFzjP01d9eKAtWbPvoDD08SUfaN8kzXX1Tq2DMK6oMgbTMhT UNFSTmBUApMy2W1SRp0fR9jaRBo8ya/cy4e7z/mATc4CUpXEF5Cuv1CQ/u7pqReo/4uLWjYQARAn f8jRdmkGX56lPQDFgyrbX1QlgFAYEKZbF/S12l5Qjf6jRv/oV/VKFakAsHoFZVYAZFtYEdu6ikLz 3tXeLeRuLDN0GlZ9vX9eZtGPWPdVq9AJ493WG8ALSXc62hs46wfMwuLkdXu2Vi84zprcIHYFkhIs BYW+imj7nnQEhHX6EyCz2r01PyMfem1gZVy/EkOEatSVfHYCTqoBFmr+EtlLlC8+aYxpf2CJK9YC 0gOWjEQB6eYLB+lnYPo/uf5/NqzRsJ+H4gyA/kQcWpnypmqqaSrrBSguqR48rzrX/5FGCK1SVbWp su67bmUZNvF4Wpj/0mtWha5HoKWwukFAvm1c5dj0n7oDy3bQeWCw5ur7StY8cddSV9ylr6qZZ+12 nItx2ddyQXFUU1CUPAWl5t7zpNFr9xFMyq1Wb36pHLEYaIVJxcQJq5YbrVQBpPBN0Us6sIAUKxpe Pkg/I6CGJlUZnv0pP6hSlSXJXz+WK90wiWYotFYVLYvqvLiKYpeDNaOoj6qJ6VJLqj4MWCcA2JZ6 Ya4K8ZnKw+B67rswOt+UXRaIF3lVaqXUcnQsmlbC6WzVDGI+9WWPplv5SO1qUW7twTr7rNz5qFxL o9Vg+OE+qc84UbDavTY+846sNKogJQzduU+KATwFaypX4mBdaXoqeXSfigZY2ocKUz9o4LWPCSDl SVczfQlA+tkB9Y76fxLrfaY7W1Y5i6vKupYy6e4p8oBKTLQukrW0VVSwcnULjHEnG6uOi7HqOk7N 3BUB2tBf7DqoKni77qoGWFqoAzIvA6x+3Pr2IkA/7HlLP8BiUuUWsNZx0jqeHZdlUWHN1gVlO44V rAAopHEkVmWr3SdjUmHXGx0NcSalGjjpde8vpRrdO0g1aGJIPm8xGk1gUrH3I/ozElo1Xz5IP5tg 6oXq/2qLkQiVE6NoDSZiVCXq5DqWELSgStyDIWowVRuskcbS3gA0Y+ultfhbD5KOq7Q0VU1LcVth Sl0v/rKhugvAaNkHQHdcD4vgqktGLRqv6db0VT/u0jVtc9ds3S+H8MIalXl0xAbxOPggnvn1GjhR E4bwFBR7hQmBU+z7SQlJfQUz6QgJGBgN07TFHlSyAsE0jvFwkMDpsIf8ziEjOXA+bcrqYs8XAtLx CwbpZxNM/Rb1fyQC5EATtTZNCyWqVGW03UbmApBvQ7Zm64Ml/7OVVTkDvKoMhxqN9SkR12kqTVHV SeGqrkKdPxpqKyfN3Xge2lQF225eL7R9vDwP+81jSl1Fvw+mTvoEjkQeyabuvHrFYd6MXgVeZhW9 qFWnSTUTSDWdtCzKyJWy1+4lWNLoHamm2I2PFFLzr+Y+lxtL7EMsQnzRFBWkJSOtlfbiRExRzP2+ CEi3FaQHAekjAWnmICANLwGkn6Hpf4H6/w7Lf+VKTNr6pzNVnNCD6isNNYgys1/7ALwnAHIwBfnU YqoqpgBrcuqurNKb/kW/2xxYxTmX2mr/NPubRyorvY9aTjQBjvxUviO3emtfwNxC6nlWPb/MnWbu 2hWaudcSNKpOUbvy1dyz1+4tcOJr+RjMJwVbwtTjSGr2r8lypjcRedJElsxPRRtMrEKIIsFuisNe QHoQsG7zarxxkE4C0mcvFaSfPaN+Qv0/HoayEV8gYbS6kA4Aam2f4j7ph1WlKsmYlUy/il1anYMp wrnfiu3sulTNN6voMg9Ln3KbqypN98TFgL2kWufl2dUYqhZAZJo1b2Zxk6YQGLrG6zaz1629XK6T 7Bh2ZlZumS3tdHaTr3MldVoU5t7HmgHS4jNOUUXHTEkvGpMGZ1LkRzXlVABOshQUpHeSXFrq6VqM j/ukAtSCwClo+ZopTzEJk3JCUj/zSFlsVzl/JCDNAs73PnqpIP0cTP/dUpUrl6rMqEanNCUqqlel e97JVnCTdvnXUQkLsmxTte0BiNZ9hd1I8oEqq0KwIpn7q63KyqRm7tlgSdGnUrktWyfX7q5NebHT PGvivh3WjvOrxzNWbb7qk8HK/VBek5loIEXlTQfwXBzCWvW04lS8n9Ta9bYuVGbmPnknPsy8Npvo bJODtPh8fkS+FKmnLaGGLz6pfCl7jDNDCGSfBaQHB+koIH1dQHr95QDpZxtM3Vr/ZxrzrtX/p9WK 1liHZdM9ts89huT1/EG3wVnN36pVMWhPQLQgqvYDJG2wtm0eyYOpWPede7Mq1X0G1HZGLwY25+bn sKhqLSv2J1OrR0WkW+b973hQpxrcEq1M89JLBSkCJ5UQ7+buw7yOvNXuW+CEwIjmQMmCpnjF9TaS +ajda+UJkX3YagCl8UASV1RAmiW6F5CSgLRUkKYvF0g/Yx/17lTVh+NZ4TXzRj6AvI9Yhpkxba2D AKyLfdUF0GUVfREAKaqiKSu739NVOuJivQA+AGiTquyy6szu7B2nqzRFFUPvCLbhP17mWflIx2qh Cnjsr/JxEWA5KFgp0/KxfPzyNfXr5t40EQJxU3dWBZM2PuKtelrDL5YnJR3I09Ko+aTInxYwrT6O Ta9UO6GQAkTFaSp7FAsOOns/bHM++/KC9PNh1Mqq//Pb9NYvbf4fqarzlGgse+ztUcQUkChp92hU rSnbY9RUU4KpqZiiCvlGOGNVY1Tdh4Q+gGL7NV0ubJGqqqyqiuo2wdy33fW1dmffbkSFunGRI5WT WzJQdAub1nLukZpJ3QrdxCGqYFmt3RNVJqVOsEx9SmdStrKoduJTm7tnnXGiK2vlIzX34nkLSKOa fOasPukkAROl1QGyS6hxZx4ypjEbSB9+BGU9Dn/85QDp55OeammqfwlX9aT+P6eqMFYN8T5vrOa6 oIBrFkA+VFerZu1XRYoKW1X0i+zSVUNRf64oWLW3KHojdS2TB03gztpVmq6yHd3UgifzW6ljxOCp rLlttNsHRUfdI7f4qTzLqngBn7kTRHcFE/btIWQ+qTWZ6CAeu3wjWcudlUXR/AzmLMEG71AWZQuc tEu/NkdrgFW2KqxbtH6/j4n2U5bPL6zFUglIs4A03wJSXP7gywPSz8n0n9b/l1KVQxlVSa2U5MII rDsA0AJYm1VsowrPIyt+PWC3qm0JZJrr/2zN/lqtslyPW9lOYt1LPH0fAPPR5OodLsDtZdVlher0 krm0uazZ2rtgvurkqzaxi+j6hpFJxXOtQcdSUE0LCjKPYsa1Rg/mRA2/XFnrHsqk6Iqylj5h9xuY erFLUD/Zxlj2CSe9gDOOwcw9QHomIF3dAdLvN8Gylw7SzxGoy/r/5rAOm+uD1v+fHa752XbHu0no MKLH1NbAoACgTShkB3c1/wrW4AezBRq+UUtl2XOofapRtVVzp8LAs5/KC5+Ul2XUNme1ACfdDtI7 /dW6vcH/06PURgC9vaCCVC/t7wne9EwAqQmWoSaPHlIO3gVlkb4xadSavTErfNYUvMafxdSXbTRN fXk9+SwFpEkzLHEqGzFpDwSkcu95uQOkb74FnH4pQPr5mv7nSVV6qqqOqqDpQbuBsLIyWhugyv34 DqOoEjS0x47VpPlVa1QRCEKkQidVY9dULV9MHGysSGs/81wVqRNQwqyHb76lq6X6wt5+SrWfJK0J 0NvSVLwQsW7tf1Zp4lB1Sr0sWkuibEs6uujezD2Jude5+RuVHUcqCgxaLJrXEilAWtzcMypO0RSf 68KHDJBP+zAOe/mUprQWGp3iNJWUV2HIwyDvZZSP76MvP0g/v2DqtlSVSlVutP5/LfEPkqLrIWkj WzL9D6hVWqrKR1OwThsnk/zQJSp51GZrG2Px+X9rrI61qdqP4AEUtcWJNqJS+wCi39dEmY8DptAt 1j0WWrtl3H8xPlIFAWkh/2j6pGGeu1eAWhqqjY9Q75MGlxtXOR26bhI7NZBymR2fHL0J6COF2rOC vKhyIk8kTEoO0hsB6SggjSXcCEjPBJyXAtKPv9wg/XxN/0mqCqMqkX9x2LA4qbyK4j/uSzkQ51xT VUXLpJBKP0A2HSaLyMXU2vKKUDdXW4pKq1RBW9Fg8l1SHZfuq3q7H9MiRXWauqKug8r91OoWhF5p hW71SUu3rKl2BZ6Ye+58Ul0fD/eFrWPMVuLsfKtIG1VmHcDTURLtJeWWN+UrbY6u6nsqKhHVJ62B KGYs44YP0yAgDQDpJCAVo3MuH9m33peX/v84fPDlB+nnz6j4dzKqch4uhCNXQh4xHyjpzC+1riob PzG29MT+UGUr51RVTf6zPrYWCZxJuyHAoEmGNiFSu6qIibqBP6NdPhXabfubaCkEfDTTspB+XAzh UdcFNa9pJNfXClUzX5P5rqoXwkILqkk/1jxpbYJmbSyp8/ltvxPrdm8M4glI43CYspBp2ObVuuQh PShhgxWPAtLrJCD93lcCpJ+zj3pa/799VAUbVlkYNVmjSt2nifXpZIl+zP7Ld72vnVUWVGFLIIb+ AlZbQtzCxqrBqmRj1VFtberq/3WE2gaZa3dV8Z1+LmapfmfxPBSFuvVvKbceO5+Uu/H9SsBFR2Xq tKjuHzaQcm3VY/dJyeXIVU7cxkIQ3auqHkEGsqnqyR91HXWsxBpRdLoU803IsercPumMUxFfPw4C 0gNAKoG9WKxhEpCOX02QfgGm/zRVdTqqQlBClbOdXKk66EQlTH22SQBTUgkurkahbQUstVIVbFJV twBC9pKjp6tqmspcgJPGaWuTnTMAzeTHO1yAOY1V6v6yucG6z0FZCspMfu1JyDpRi/cKwQ1tELfF YWyqeOhqui622EGZk1Vex02+5klZ5cjRxid2Q8uirCY/b+UD1c58BWmaxNxvpyl9PUD6xTBqz6pH UpVPdLl9KLTb6gZAlFajSkqRSVSSLVdDUEDGsApWZ1NjVd1PFbXJBWkroa1hwKJNlcULDrEal1vD CvtykZoirBurIs/dVG27FM+NKpb0b8N6XJmVFkwajElNy70xqW8emWwIz8qivjt02wIiMKlE9PLk 6xhq4MQuBWlNz8EmSW90vkl80hgxiCc+aZIT9wCQloOcuZPE++KTAqRbAelKQPr4KwvSLw6ot+j/ W6pqKCuMRo1jLpnziFRTmewLjVb717ypmH1VUaGibGosi02ARVNVyqgB6ymNUTFTFTARYJpV0Tiy NlV7oqpqmtqu1bo2ZAZo1VWtoG3VKE84zbL8c7zl+9fY9zh5B1QDabCG8L135WP94jbyPKrM6pOS iUH4gWg/KsMWE5FA07OY++hMqis8BaS5yMkKkJYOpGcC0vKwhJ2D9PcEpP+DgDR8tUD6BZl+/6cL gEP4i7/LbVXlapSoSIhwB4tPuaBRhWOEDAD2ErWdnLNYRXRBNRdW82lVF1mbmraqrloAq5ItV/PR Te5F1cpSV7VWrKp5P56rKnOlyrV16Ljk1O9l02lZM/nBo3vNkaq5Z4w068SnNoxYxYkLup2u5eS7 0ki/JvcxB1IfRwZSmHs9gi3vmASk8hcZSIW9V8MdIH34H+Vl/ruvHEi/QEbtewD+6CSoQmcJiz8F NZRUYP6LtrllTfgXT/rrKm2VloHImgqAyaXpVAlIKU/s06pF9Vd1uZpL4yqrhrpQrYXlJgpMcy6V /DHB9RzJR+2p7qhqw6WR5mxUsY0YmLRFisGiew7mb/cb8YJpQVVxCLCl9pNyaFKPAGjU+r0n930Z WdRdo95gApmdYMUP7YLidDiUpA0mq5WANAhI97eB9K9h1L5yIP1iGfW5oyqrMu4GuaalelXyC3VZ Vzf/byAl7SpqAVawYEvXVfpItY5T23oynf/3AXlfVTnP/887AEJTr659d3UXYxeAcZc3VV/U71MM +/h/bsGTShGpS+JTC7poDAIRWxcqcyY1Fb2iLMpNVQ/RPjrz2X1SMQFbOQ107t52HoT9wUEavuYg /eIZ9c5Rlb1+/7EMeYV8fYlZTX+y+X+Bg+6q4sAup+6gBcvqvlUNtDyYwlAa1sFrE3LSAoDtANCu Qp2vbmsqo48rxaYvqWkqKq4KWGxCQAN2767SwMkH8XQ+z0R0ayLfVsLPPmm/EU990sBLVT1dfKup qCtNRbEpmMAnhekXIGqrHgInecM2dw+GFpDGQUB6eEGQBq29MH0VUfrFm/7nS1Va/T81oAk+tIE4 k7X+pcqkTbHO9ndaJoCdUdmYmLT9r5hFVj81si/99fR+Sz9VRdW2XaUtqbDRgeI1/qR9eqxsbEJC uv6h1A3NFtDNIIW5l/t2kU0LCtE9V3HcKqJrys4W4StIwag+LUrpRk4qCZxQccoC0qTJfDDpWEGK +bMVTo5PAGn46oL0i6lMPa/+r1KVx/V/ZT2t/wuLYDlfwmGN1G1Z2hhsiZqKqpE3WTepSq//I0KK ocpV9lKV1nhKR/P/rVw/V5+aMDk1zXwT0iVarm0kmpnUVzaip3QhWNYWO5jC8/W81GGu3Yfge5ys QiXPSxrdW8Ejik86TSsx99OUJj05Vmjq2ZZBQJq+piD9gn3UT1//R2BCRcVpNVVFWv9X+fS90BqW wZrMOjfdKov8vQhgG1VqnZ3aqEr2fcsLbaowK6v4zipuyf6maeU+qTK0+qW+tcV80hbd19o9B6vd O5PWZD4G75jZU1BkPil81WJ775HUL/BFGcHTYSue9p54kE8mS3SfDnvxScXE5MlBei4gXX2NQfpy GLWyqo6q3Fb/j5SEFIudRCl4HwBq+uxDfmFe9jszbGhDgW2bigkAN1WVaEyqdf7YFvfWUZVayjeW 5dpBVWv2NHf6Fd+x53V7q90rk3bR/QmT0rxbtOuA0hSUi+ta4BRtsUPECAlSUAXJ/AH7uBSk4hpN 2OKd3Nx/E0D6ctJTLU11+6hKxpIUVKwghyJfflR1EDpkCFWwr1In31HFOlp9CK0IoFWrdVFfNdZk eyGP/oNmjCzqV/vfd0a54FPphqjImZR0w5j6tgUMnchYNHoKim2sec+2JmexABcg1W4onn1SDj7S LIEUkvkFyXyOqONrnlR+zbaQMvE+CUgPAtLhDpA+FpBeCkjPv8YgfUmm/8Xq/+uBtHtf/FQ5xB/L mo90KcrQUlXzVpXQkv+F66SqugCeeFeSbqkqblsA61YV3dPdianNE63Fzb1vZrFFbaaArZsGi7oe Wr/fWbte8Nq9m3tNQalWqfqj9TbZbQuw0MmP6J6zdkIpSFEgyAf5O+4G6UcC0ulrDtKXy6gvWv+X b06T6HVURQCZIsBYJPZqLOpCwEEDDnn6qib/VVtVAyxIXmKnWlE3QJmS9P8e+Yc6DcA+C6DuaDEd c88ecN0kqIGTTxh4XjfqSDMqTuSVJA+MVCNfXspypK70rJUnX4CryXy2BhN0QZG+Ju/3cnKmNIov rjJIeZXlc5gEpGUG6e8JSB9+zUH6Ehn1OKjqpSqHcibktRlHndkfOVkXvPqAEUoqwi5BW/9s7t+C K2qsCg0rDaQOPOuq2uy/MmNs6rh1D0Bd3KQBU9NWDV4giLVwYCBVLYEasEX93cVypArS4l1QaCCB iZcnX5caOAlIiyb6bUuzAhggLewsSltxIqBess8VpPL3E2r3OwHpuC17Aekvv2EgfXnB1CJVdSxV yfSEdyjcxxWUVFD8F/xixDQGn/+3rSkD15GVTp4ydA3XrqZi6yqtGTX6RLSvzaW2UaWf87f0E3kK il3BxLSgIrlmvrI3awrKgyfddx8UpGFWMLFGk6tQm55t6Zg3mLB2QdnoCdkgXtR+gGlwkO73iOzF 5J9tyyQg3QlIr79hIH25pv859f8zn/9f1P/FdJOWSa1KhaqUzb7Py391HwD7GsuuAGBlVRo0RYXU EtlWIQjkl7o+rV+pbpqQNigoTKpuA8QhdNEYTSosZqvbd4LzndxGWVNAKgGRBkZBmRNmH43OBWAt Epe7HLmZfvY8KUnghChfonsBKRrBo4A083aa9mLsw5jPBKTlGwzSl2z6X6z+v57gD8JHM7nK4Ot/ 5Au1xmrLW5pkZdtUbeJqFlTZTBXzvKmavana5pzqysrEPmItAE0uZwlTH93c1/ksLMFAFz20SaMG TvKYG/SMqjmv5p1rjtTzpnIpb+BG3oDW+OWXANxb1P7RRC2/YD/lGaS7e5B+yRj1k+r/YdBUldjw nNACyLpT6YBltKSDcbp/fm/9AFoNMll1lbMMzU/1AsBgmQTSRePwBNDwVJdNENXmFTyEdDeWB2HG zCqMkTEnLyAtnielGznbrwVVN4njlZD/dXSABk098XWydNSNKuxFvhHAbhPGR0relhi1LIplZilM h5x3U5jO5e8d8yQg3QpI+RsO0i+J6f+k+j+YjUtObDNVRdf5mBiFr/8xBlXpn0P0nGpQ8xx19kp+ Pmq+U/OelHyeyor1db8eGlbQvYIFZKpk7eMj1LIHmOoUQAmLCki1SUT1RuN1ETOeGMvFsFs0CUCz zTkBpHAD3CeNEa16QYUhShCQCjvLG1MmpTgdSs5TDFNOQuiTRPfjVkDK9yB9+cHUIqg6WlV5k+k6 jjStdciEVliGqjuYdVuoVp5AtwBebPr/HlyFWqlim1it1SqVt7Q9eUFfyMSi6sIz6mXJybc0+wJc U2XuKk4KPl6koJqing/mWSWKmogEqRqfaeYT0mhoWoG5F5BGAeke48zpMsvfW8bxHqRfIh/17lTV h6+fwQKjAFBWyCKhUgVRNWU5Yco2AWCq1ME7qZC6qjpV7MGWp5K8qdrEH+Z8qMkCtbq9+qWkArq+ OkjXCIlfvBMG3Ik/qj6p/Oxabt8UmHv1T+GbYsGYXl7bddTswzUYFU3PRQXLzCdVSUkH6SQg3QpI NwJSvgfpl5hRK6seS1WeJxrFYm5ppAGBvxAjpH+xCdRm/6ltSjE3BhtV2BjVlwJHl6gkZeMuTVV5 1Gb7q8pejsak2bugbLAwsDJp1BSU+KS6x0kZ0rYyk8/dB1vsQDaPb/ue5DL6AlwseCBs2YuWJx0i fNKMCZIcHKSbe5B+idNTLU11e/0/geTSqFWqJMyadcUiegAi9nOio+owKKta2kjNNLsWgA0Crtjk 1QcLqLA9KJNNo+pkqi0BCKWoDhZrs4muarcdowieguuTFjXj8D0F0RooFd8vis6nGKKnoLAMNwlY i/iy2Uw+5M0hSa5N4dNBUDoFB+kAzfw7QPpmUF09Dt9QkH6JTP9RqqpKVT4VK37jUpU7MYm7DCQJ WCHpGVV0QqN7TU/Z7qW2ScXKqq5SHVxb1cZbPAMwuwMhmpmfVa1h6jH5qntFCypGaubFpDPJZbrK mtgXs+8H6/yTmn51C4TkbzJ0SUtE0LSVX7KXN73fI6hDl95zQPqBgPTJPUi/xIza1f83h3eJLlD/ X5UnB9ZdElEQCqCOcZiEA9VH1eifTAFQGFBNdXD/1CZXuV6O1uGEqD/oomrTzkUbIVsv1ZxrnZKC FKVRMfuEKB1MioUNujJcfFKkoqqQLlyBpIsdkvzMyqi8jdiDoyks3qcIVT0BJ+0POwnqc5zymYB0 cwtIfyAg/f49SL/EQL0zVbWfU1WJ8+STntF1RTWvimlUMmA2kQc/fG5phOmX4GdIAdkpNPUhhWoJ KbbVzRpc6RhJKBblU8TCpRt5LEqe1/JU68QnjDdHpKLkfgFpyDeJolacEHANWnXKWzmx9jSs9tO0 nxIl5H8XIL0ZP1RxCL5+bQnSN1Xsme8h+mULpu5MVfWjKoWyhEYjVtliBFoF0TQ9BYGpAUfUoIn1 OrasWCBlDdUWRGkwRU3QrG0k0ZXitWiw64THtKfUAiOyJmer12ueVF5SlZ5r7b6ubdSRZvFHE3zk IiCNAGma8v4mnw3nGdo7AOkDNMXcg/Srxqg9q76poyoIqt79eMOX48QbmP89RFVSFkSaXCVUUgjr Kkln/7FELQTfXw+QWKJ+57nWhFl/q+sjeVAyRFlV8lc8giIvSbZ8TXtLrfJkbGp1+6xjzViRI4C8 LmLuJVAynzRGJP3FRUhb4rJNuvVZt2VPHFeH/SRRPqTgz1/JV/KwJOb+WiLCQcz99T1Iv4KMin/P kaq8ymI7U6SUCgYAMZ6CPr0UrTMqUdHEvm1XsbSVp6V4lqKkbvED0lGqWu0qgkR1Ca6xqcnoXNvI SN0+gvui7XFy6ccQTAtKALuNBWsgId9DE7Q1SwUpxlYA0g1A+pgf3oP0q8yo4blSleiZTmgaKVY5 gg5oSCZSUaCqojoAVkkiq6GjoXksKp+uHdC6yE9wC8WfKboMNBaRBewEEN80U9wl6zGt63KulUG1 +ZmuxRfV8RHIkQvOb8QP2YrrK8DOWwJIE6HINJXVcMiThFCY/haQjoOA9PwepF8foGqqSnjy7bfp L8Jl+NfvTmF89VKCqqijKlcDlQ1yqRNEFyijVi7cKaBL1qAS8gxSifZZdVPhx2rURC4agQg/+ZZ0 dFAJVwP/KvCgaSlNSWm7nph88mCKdNbpZtDyadS5e9YdUGUrUd0+wW04YNYrHcphO2H5yOYepF9X oIbnjqrEHbL3gqnBFACH4KkqsnxqRIIe6SgcNq1qatZ1dYQKVNCINZdFHQFtlAajWq+p+KfZVzkm LYema0T3aECBiK74GNdZzX1WVT05AwSRvhEvTNMG74Mi2Pp2kH4gIL0QkD68B+lXH6jPk6qECuUA pIaWqkox1OQ/6uijKzkDjMKmrEFU00CHKqOAVXwHlKiwekJcCh3310E9irYpr/gGPJXhYU1LXds6 HRxI5EuEX8YtwJ3QmS8gFeAexHWYxpCynDl5PTwQkL4iIH1/BukPBKTfvwfpVz+YWqSqbhlV2e2g sxjLSLS2PSdo10c0j/xo32FFwYKoponqpGrz+Ah2akNLqCkpiOSq0t6NpaNQFoX51478GzP3uv9p S6oHVXRs+yA+aYrjIcsJM2FJWxhyHtbl4hwiru/zewLSGwHpH9+D9OvGqN2/blTlXQmqLs9TWWOn 5B4uJeUSbVeTsFqV08EWJeRSU1RVHxOdVsVoVYCOo9waVEnKFH7QiZptd1VAr6kwatElucXBGbS5 pGxzsEVj6IKSB+9XYdgXNDuP8SD/pgQB3TRkcUvKdDOVZ+GCP+JHfPHBBf/oBz/iH3//KrwlIA33 IP3U9vXL/Q8tohJUhZ9f0r959ABtzOmVV1ZxlbbDlYTVE+9HzAGOYmVHimuJ6jcSGZ0JmM4S8RlF OZjP5IXkelgJM+IYdekv1rIGVUopGN6TQ4COdYwsUT86poqLkwX4oje4nmLeodFEfAtd7JB4P2kO F5vx8jYPZ5TFCSiT/O/iVYD0ow6kPxaQvnUP0q8lo94yqvJLCZ0exFQ2QqbjZEt/J0qoTuE4CICg DYz6aHRpaNXygZRlsM3NA2P1D1JTVqFSRT4AVaP2oF1Xu6QqeqydU4V5O2KYL6cdWvUmQWjsQHoj IL24B+k32fSf1v9vXt3zapp4ndbleliVgnk/wUeCj8rwT7EPGC2rJUZfiB5tA/VknVQotcZoklKF 2GR/UOefVGOfNQcrkT+r0JmYfAGt3hZklv3AA+pjU6LhUMph2uaYw9mYy/5gIL0WkA4C0ut7kH5z TL/Zf2BV20r+3c27AsCn8WFYxetV0Dq+4HSgYcBcFFQrVmK21xLkrIUl1/LMtTxhJaBcIV2VYPa1 lFpiW4yGTdfBGFWFg0M+wPyjBBtD3g/IAmCNOISDY94L3qcxRTxG+PygIH2wf1ZiuS7vCzjTw4/4 e/cg/QYGU8f1/3d+zb989SlfCqveJAHZEMvA2P6DqVKUnDiOrsKrjdHYtwbGxOScLq8IKWkOwGam VZOKCgTPsspbUrTmFEEhQjahTeRmDyGFw0jpMIw0wdtQkOYxb6/Gskqvl8fX1wLS9+5B+s1lVGfV n0hQRRZUna33jVWHcZWuy2Hg6TAMcRhDzuMq6KJfuUCzlSb+JYAqOuiXgmr3RNs9oSI+JWpAVdTf FQY9RPS2qnaAgDWa3pUEU+IKo8l6O52LTzoCpDSWhyndg/SeUfs01XJU5ZeHp/xqHsrNNZb+Hco6 pbxT3TOx1RgqAW8W2+oMuXUBJdSoMaQftXbKbaMkhCegzKrSPVPBaHaZVipxmSbtxp8yRl8mjMBM w5BLOBOQ0glI/6OA9K+7ZWP3EPvGMeppqgqs+lhY9bWwiftRPIAhp9XuMEj8P+xJxSbQDTgMFJEF GLQwgOXAKPL7mnSX5Qet5oitLJEytjKPQdcITWhcEYRP5zHKz/9/9s5lNYogCsOnqq8z3ZNkImGU RHATDG59APU9fI1sDb6FOx8lK3dxoaAbmYUIgSBOkkkyPd118z/VPSEXFe8g1iGdZIahYeDrv86p OhehazwCheUmLRchXQKkM0B6J0AaFJWuZFWNSb4/czYd2EFsaCaUiOdOqDTWpLibOpeuQEkRKEnB 8218RYBvusZjV303366YP+qGRvicVChvjIiJs7Ma/M2j2Ag1N8fSmh4fi8Lf5fvOOkiHAdIA6re2 quhVScWNoTMrgg5IwwWorZIJT7N1aZZQDtIUT0rl2mTAh4CLuwLKWCM499XTbeExN0XBR13kq7Dx YyKrI/5t/fm/SPw0QdvnzVUxs3nkPKTyGqQb53OcAlb/+9J/ZatqpxyLwZEQB6qRZ71IrMIF0E5L LMayj/iIx9mlCVZsKSUfX/F2v4mkSA182ribfK44vLc8gMWyXnIPIJ50neO1ksryAOCmSmxSNLZP lTvl46wvQvqQD+8DpAHUq6C+IKruiZ21CV2GVUtRl1zXLHME79yMxES5SOEJcG0dp0xxHAVnwM+Q ALl8RAVFNY7LA2oGVkaWN2Tnrvag9hrjpnyGUDSurKce0ueAdA+QUoD0r5j8J5+tR7zbCV+199Y9 fXVKB+mIRsmyLSrjJhRbzgAsqOGw3TQi06nhmWpW6xrRPBfYSWrbjZtYuShWRiGmt1bbxuiS4Bwg WNKU6IFaNkPq2xORWjoBpEeAdB+QfgiQBkX9btsVtAtIWFnHpdjeTMSoyWma5eKsSkSVnolRzQ1/ YqHgdDZxLZSChuac11LTStdM38SJk/OGoKIuRXifxNplOnMfUzioqnb9vIKKllBR57KxoWfpxO3d D5AGUH/UBeAA5sVlN2D6aSrs2lBUGl4lgK0B7LoFs2mFNb4nrseQp5TUiYdzHjtKqgaAFgBUOOgr DVbnWOpvub35O6KtUYA0gPqTqnoBVtqf0PZm3arrObBz4i5ARCtUzxpyK4ZP/1ubQJRlAw/AUVaU Lk6OKT/NAGjmAV0HoE8A6Gs6BKRbjh4D0jahNEAaQP0VWLnC+T7tANjbAPYIwGoV+e85mx4CWN1+ 55u4jsj3M8nLJQCa+bcZzizHEj/ZaBV0Aej59lOANID6K7AyRW3eyiVgiYZE+2OvsneXv3GLNwT/ E3AWS3jx8muAdj5HsADq7wSWLkK7sA7ec+ugXNgCTqLFBv7inwBosD/xAO76ND7add2I6O+4HrS1 Ve31IPTQCxYs2I/ZZwEGAH47c9XlRq9uAAAAAElFTkSuQmCC" height="169" width="169" transform="translate(209.2856,3.9365)"> </image> </g> <g id="g31"> <image id="image33" transform="translate(86.8154,-118.5337)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKoAAACqCAYAAAA9dtSCAAAACXBIWXMAAAsSAAALEgHS3X78AAAA BGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAGGbSURB VHja7L1rj2XpdR621rv3uVRVd8+NQ0rDy5BUPBIthSFBUIJkATSFGIgSyhhQ0Sch0QQGAiOm5R/A DyKJBPkUBcHkgyNABgjZH5IAhqAAEWBAsZgogiCAMATBkSXK1AwlDi8z7OlbXc7Ze78r6/Ze9j77 VPdcurt6pmq4eapOXfuc56x3rWc961kBLt8u6Ntn+KJ7uP71u+LRaC8BcZGA+T8APPt/ILwgH3/4 Hr+Pv+6lXwP46pOM2l/lj3+fr89eAvXy7X6BkwFHPwLw1OcB/q587so9fP8dvm4BvMrf86E1QuAP X+Kf89X/iUH78XcUYC+B+tDePsUAfYEByrfvZ4D+1LcANq/A+19d4s/91W2AZ+RrfgDUX4V4fBPr 78SmpXDlkN97Db53toF/dYOfxp87JHiSgXtzy0H2VxFeeskBK1EWL4F6+fZmAPo5i6Dvf54B+k34 yM3H4Gf/aoP03gBXwxP4o00LMfawXb6KkTHWrTcwBmqPS9oA3r5FH22fgMPVCq4ePQ2vnbwKvzsw YD9fAfY6J7Iv/utHPro2l8B50CD9AsIXOQn9e4fwkauvwy98p8OPr1v88W6B7z1Y4qJh/GEMt4c1 3gxduDMMuBm22FKLPyDAU8bppu3xzmaLJzcjNssGPnhtjc+0PXwwdvgMvRfe/9fX8S/XPcDP/ADg Z59CuMEh9U8e59//tUf2kcNL8DwojDJIP8cg5Sj6gU+8Ap89Dvh4OIOP3Fjj2RGDcXEVzhiQw7LF g7Meuxahp4iEfHqHiMthBceI0IRAzcARlgK0fUNNO9DxqoVwTHQEHV0ZGhoYo//Pe5b0u2enBM/w 97/yHAfUb/A7z11G1Mu3u4D0CwzSF56Hj8SX4PPfJ/yZJ6/BEhZ4s23xrOtwfdiELm4DDBiawGUR dWFNGNoYmgWjExYQVnz/aoCw7CMuAoXYtIgC5b5HiD3epoAxBlw8voAPhw4aauHff+t1hCNOBeKS o2rkP+aPL4F6+XYOSJ9nkHKB8zk+sj/MR/RrB304PWvDco0cL2OAHppIFBhOfODHhhCbdQgN8MVB NTASOZYyahmoEmO7ANjHiLhgoHLkbReM4tjicrmA4yXBamjgA7ABYrC+zD8GPjUwWH/2kU0BLoH6 IEG63eKz0OPpkvHFZ/vA4W/ZMPggNh2nm8Qg5U/xLTWh4Td+fgSwfMo3jLhGyihExitFLqeA81kK /IY9X4G/EDHCcimYP8MzLsgOaQF/6wBh2a7hLzvOBz7AYP3fhbZ68RKol29jkH6MQfpfMEj/AwEp H9FSDK04/DV8ePdNw9GRGookh3sDLUr0FCaGQYptBNKLayi5BKgcR1G/J3KUbRm0nLEGfp8hCjgQ wdAucBF7iAJXBqtE1g93HSx/gPCXq+8DLB9/JKPqZTF1n4p7+MJnGKS/Df+AQfoeBulrDtIFYwtI ALcOWwmIkUI3oOahkcFIUYMHf77Rr2PwoT1PQRum/DVyB3FUjZwNRP62Ycs5AcfKoR1g6NrFsCaO 1djFjr+cNuv4OMP/+MaG/vvH5afzT/m95wi+/Gg99eESVfcDpM8ySH95HqScY4ahDW1PTdNtOXIS x1eOmhgX/P6Cj+8l43DFeOQrrvi+NUN0zTnqWu/ni4t/rqtgyeGUs1GukiItmggt1/7tcuhbAXnD n17DIrQdhWNc4OraEn5+zXkA3wu/LH8oPVIP6yXhf19A+kUG6acVpLcZpAcSERmkC85JT7FtFthy pIwNNHqctwH5iJdIyrfy/sBHO0dTiX2NZJ6cDqBJUIjvCNID4IgpwRX6IYKc+D1/DgeI/FmGPPWS PfR9S7RaDHgbezxieH+Cv/h34UME39aT9JFC6mWO+jaC9FkG6T9hkP70Sz/GIP0eg3SNa0ks5Y1B 2gnwGGtcn3OAiBwAw0JqIobhkhNPrqNAin6Omrjkw52hxbcgdT3w18EC9Gs5uAheBcyWD3ApJcBD DtZcUTHSG0WxpAmcC0iFxt9xdjzA4vQMnniM4M+HI4Ar3wD44xcvgfpuBOkXGaQ/ySDdbL/LIF0x SA9Q09DYMzb7ZsMRlBEmUbLlcLlQdhRoqYBkkPJPWjHwVgzCtXws9zMC5X55n0GKrURged5QnjvG pb0OCNHjY5Rai38ASVI3MGgH/oBfIbf7AQ7CBp5uG/gDZLT+6G2Erz46RdUlUN9GkP4Yg/SbCtJD BulVpMVWqM3QUieHPNc9nDwK2DgqcujjKEmrSCQglei5lijKYOSICmtMtwJeAaoBVkDK6YHcCo2l LAD/GPRyiyOpfhg5dQX7NN/2xPkEZ7uchVDXtfRHt24BHG0APvSLjNMvXxZT7zaQfpdBuu5bvMqw OVqcMEjP+NTdMEQHzj+bpo1cOBFxNB2WEAYtltoAWiw1EA84Lzjkk/sQ5QI6YuAe6S2CXvI+XyKb OrBLiiyQ6KtgJonOHKX5SV00QnMFTgQaCJxXhAWj9YxfG+vDFj9zwIH8ESuqLouptxGkLYM0CDo4 kp62XNlLIR97hkrDeWlsKXBVz5hBiks+ylYR2yUHPK7gcUWSk/Itx8Sl/AT+WHJXzi6FKtBuFNdM mnoOfPUcSbd8J+NRD3mUT0pUbYgklkZscOgjv0D4F/PnwtA38fCA/z5s8dPrgF97lfOB7/wFf9Nz jwRSL4/+twOkwCBdMwg2AeMiMhYkL4WmiS0X6VLNyz2aYy60UJLjXI57wDVJZEQ8QI2QeMDntUVL u83RUr9PUgbQ1CGR/3LwawVPevAj/3LBLJ/9aHyrcQZSefGrhPF/wiF2iZ10F+hlSXHf8/1Hoqi6 BOrbAVI+TgNDJK4iRz/+X4x8ivO1aKzCR4mkXDgRSmW/slyUQVgAeagXcvWFeDgCKkdZBauCnKt/ Lais34/esPGinySw8r0SdUmyVE6EOZqqAEuiLPVRWlodNe0SPrhawx8cvO+RKaougfpGMMog/a8Z pP9ZDdJrUi0xOnoGqXSXGKBxEJCGJnL006JJQBa1cl/xUW1RlC8G2IED1IGKhxJZOQQe2ucdqHqR RVSUdqp3r/gTFlAlohJps18vPe5J2ld8K2oWyRo4IeAkeeg4qgZY3engicduwp+LZPDKxy98VL0E 6hsA6Re+APjC8z8J8aVfZJB+Ew+vHXPRdAXPBsZC9EgK0RRPDaeoEgEBF6jUUwapgG/NkU+Aeih1 F2lEVZDqrURWSQOMASD5ei6UULjU1p4ztLzULjnq5Zg36lSOfQanHv/8sYR2q5gkdyXqG0l+pTvQ w9NtD38gf9aPhgsfVS+B+gZA+vzzH4OXXvol2MAG6dptfGLBBXoXQrfl6l4KF+U3GahKHzlBT86P JoDyJZFUQMroORKgpmjKt0c5oqJ/reaoyqfKz2vsAhVLgeafilftVgk45ZiXi7RzhQZcqaWA02a+ f9W0DNSGjvueum5Ff3QLHwmq6pKeekMg/QewhffwcS8gXWPoYoDtaVjEs6aBs2ZBQxNIKqhhEWBY cPBaNpy5Cv3EyYFeDQyM7sjRMx4FvYajgJQvDo5X+OuP9MIowDVayigrBjNfSF58GUXFH0u+K42C xLlK0NQIHBGTPLBppKbjtPm0efSoqkt66l5A+gKD9AcG0p5BCgpSCv12GwbG5ULG7YhxQAODtNXq vpdKHYVyAj7uo8wyr/kUZpCGQwao5aQQBHgcUeMBY4QjaeBiSiIvLbl2F6BJqzSgdeYlYvKPpa1x +yoA4EiKQ7Ref8eA7LTDhbAVkQp/sg0C1hhbhuggjaozTqA7Dq+HB+uYqarrMkEIFxqpl0f/vYD0 lEF6k0G6qEEaOaAyLhGaVmh1rqX5RNXj3rpIKO1QiXRrsjzzMF9ouWm+UNKA9Hmp+O370Cr+0uPX 3FQv/RvRGqeWm3KY5o8HafnrrTRQpaNKNAiYSfhXGVThFCAwYpfNkouqnsPvFpbNKf3V4skL3f+/ BOq9gPQ1BmnnII0klX2grhVFvsjwOSeVup/BJFwpRC+cFGhryzWryp4vslxUctMjsvu1oMIRfypA V851YSefHN+oIhT7K5WP0tzUKn0FpzYEGJw9JdCKqEpoKg7nQqLpvCA2JCF4Ia+4MMD7F8sL3/+/ BOpdQAoM0jWDdMMgXTBI+RwN1LcizReIWu9e+U2NfEtUkAo4gxVPCCWKkkdSNJBCLqa00j9MeSdh oqSMOwXnTlO1D4jpmPaCSXlSi5rplqMof4WAdAgirELvaunwFfKrbaCWIh1TD5s7HfzxY6f82Ytb VF0WU3cB6WH3Gh/5JwZS0JE6nWVqmshJKeeknEuq4JniMmgxw0UTSNGkt1o4cVF0yB/LrRZI/PVH pa/vXwNcIKFeJpRGu4LmuSL5G98qr1oVUJrXGteqqQdaMSUvIBXBBNB2a8MnP19DkMDbNdISW8Lq oIXPLC52UXUZUe8C0m5xKqJ7abeHCJtGCP2gNhGiJ5XcMSzIQWM8qR71Gkmpykv52C45qR3/KVc9 VM7ULvl+06NCOvZRWrA+noKpGUUqlPJRKYuWUmhJXsq3CD3YrUVVSU6BhmDcKt8XYgdE61b+cP6z m0P4odMG/vAH/G3xexxVn7pwUfUSqPzMfeoXGKQfHoP0Gh/37WKJfYTQwAGfnhsOhEPThFYLJ7Qj ufTuLa9cW5Wfukx2gYJU89AjTQXICijPWdNx7zyrqKBg6Ud+U3OnBtLULtWWaRKpCBg5L9Wjvnfw DgZe1DSA79AiixPrKImCfK/wFGcY6E7HoG2i9f+Fp/jp7wO8+OIlUC8USPnmC88wSD8xBumCc1Jt OHkkReFIGaSql/eOEwclzUlNbueR1Asm6zppEXUkFFQGqeWl3ibV7lPKZddESXyiLwDTnMI0murF mFSi3wsoj572ce85qkZVASfqfcEArTTXIHOvkb8p9iS6w54LqwPr/8P7CG5cvKKqedeDlJ/NF+Bj cMwgvVWBtOOcdMs5afRIyhkqg0YiKR/10fJAUzYZyIxO4iMdE1Cr6h69YDIq6qCOpEpfJYUUoYpP CJKS38XRFk0NqLkbBZSiZRVVh5QCgEoBwUGqKUGiqURZFWXqWnjYppfqf6CTeLH7/+9KoIpEg097 scBVkJ4ySG8ySBczIE2RNApIVZVvKiiX3xlI5aJaXKIR9YjvM5DmSCqkPngvH4TkXxGa8IRSTmoV vvb0yXlT8kofPZo6PZUq/sHapKnaV61qTwW0RlUlFoBkjCqoDiBIGiCqKhHKyt0XuP/fvBtBKm/P 8DP3CQfpawzSzkEaGaTEIO0cpI0e900rRZMf+UsbDyHv2yuh77loPvYL/eQ9fD/m68LJaSxckkv4 BKAkQCU1nAheSOXEtLqKAIXBSX7kSwQl8EJKbp2eSvehFGDCq6opAEdTgSk04g1AbS9RlajjP+uP 5By4YFRVeDeC1J7teZACgzQwSNsJSIPSPeSFE1nhhHLc02EQcCoNJe9LXz5Kb/4ofSzUU7Be/UGw a+XU0xJlAhWi/XwZlzYZaSPDpEF00Iwn/pxOnfLn7bL3OQ3hS+gopIXTUwubZFWayqdaE01F+kLQ 36H/KJm85kJxQXxgUOj4Mwep/38Bqar2EqRjkELYcF44qDqf/LiXJo4YPRCknJRBRrCOKYISKlgp zTfpkU+H0QQlB6gRFxigeuRryqCVPRdPMgoNZFwnkfpOiZVKIMrifEJtR6nANCpQScCKCjp+XxkI tOaA8GgLDpRyu4x+n7wY+G9ckGpZo9oDiYWQCFaEbhv45y5bGZhp44YR++lNwK+9frFGVZp3PUgP GKRiQzZIG5zzQgZq8MKJw0ruOElOSlXhBJDpJTvy626TCaA1J/XOlFFQxpFKNHae1Kp7yoWTCaLt 2Ndb8OrJT3+BrFb7o+O/0FF69FsqQHbcU8lTnWeFYVA9AIdqEVZHnbEiAenZluBUJF+45T/kmF6W f+IFGVVp3s0gPWCQih2+uOqpM0nDhVOzaLgmbgMaSCmgKfPlqCctmjJIMUVULph0WlQiKLrOFOmg iEwwR1LwOX3pIJGPPxeuVAqnEExtonPPSJaiyvuk8RXsUzpeYkVULqqsoFLQajGFKVfVHJYGASuS fp0T/9KCFWsMjAO/XrrNwPnBhvgx8VGVD12Y/n/zbgZpyyCVERLqxaxJZu+DzziBzjiZU0kqnGg3 khpYcyTFVDiZQt/GSTAd9xqNl8YYOAVlhhKNOJ8A5l5+pqMolfgGVgVqiqrJ5ccr+qSgynQVpgaA RlXo0XlVA65FVlWkiGBFfgzXV9JjbQcuqkStfWd1oaiq5hKkrZpDNI3kfhxJYZBIlztOnBcaSD2S oolHKjI/HfeQBCcHDuDEkxaQmvzPyHxMhH457sm4UiNK0VHpbSj/p5SoapHVHScTSDOXOngbdYDM Avjnhboi41U1EkdJAaKOr9ioCifkQj5cMKoqvBtBumSQNnLcQyu2dybVc5BKNA1pWlTFIcDVuUr2 FKDoR35AcPU9cHUPUkwdoSnvpfo/8CJqZeISFaws+f6FmKB5xa5jKyaM1guDSkqj3gb164lgHpVa WOnn5OuDfw8YG5B+3mJ8gf6+zAL4/cYOGBXGFVsTlAIT74BGc44lZzwraPCUU9fT2/xtr4ridgvw a1+6pKceBEiJQfpkBVIutMWcgaNpVGU+B5uFuIwI8S5DmkYf4TpIx4k8kno0dceSIwVrsONfImgB qVb4KwG42kOqv5SNhhg9JPRTFIpJFXcKRjQwBgOj6kwcuBpfDbj2tYgZrAnsI6pKbx2UYAoqZQES SEP6W/jFicICSHQP2DTii9k0oeOy7uCCjaqEdzJIgUE6OEifkON+ySBtYojQqslYK2AJsRWzMjMs Q3lCc+8ezTJHq/rgIM2R1G4PPaoeOJAVpDmSuvQuGHCqSKqXgi1FyyD2Zu4cFdAvo6UEvIA5qurn GKTRwQp1VE2RVcZgDJhI3vGyWSpjMWymihNTobL0sVAXa348zqgLW+zDKruq8I+8vkK3qrzMUe8H SEVggk5BIYO0F5DK+EgEjWgi1cNs6ZimRbO4ZF1RT+nYP6JK7ExYU1CQBu5WNveUqvs0RuLVPaaZ fAwpH61vAUsHStwkrKmfzPo0X7UiymkqL6pU8kcp76xEKZDaql79kzAClNVVA1f8g9gLh8E6VsIC iEE7xYs1qtK8k0EKDFJikA4JpDJ71xeQ2jySRKDobdHEk6ou1OknTCKTosyveveYlPmoffxCQXkE q3v3WVeaRCZYlfNY2qTqxaNUvx56aUAKzLXPq3+hq3xUGlzyR+icqvGrQ8UCGJfq7yNmtVUCbyQF qdJWsjSI+u5ijao072SQ9gzSs6XsY5K40TZUgVTyUWsrxp1ISln9lKp8Gx8hO/IzBeXV/wFh6Tjl 6h7TrFOad8rGEc6TpqreJVGYoiimah/LioUUZSF93sBq9FRSUlHhVDMDYJFUNABYRVhhBHRkhbRB gKoHoKRtjbJjJfQXa1QlvFNBCgxScpAGj6Sak2JUwzJpjYL22puVjjLLhSbVC144BbN4TPloBmkq nJSCsvd1LDpYFBXGQKwfW7RL+/aooVFzynEeanmnWUdLnop24Eteqp8DJ6RyLltyVctzRQ8g7tNS wYtWYMQAWPsUcuWvf5voaKUtDMZCyMc6qmJ5O7+g4sUbVQnvVJACgxRlhxODNEhO2oqg3UDKnzCe lIJMeq7VRBetcMqVPXrHKYPU2qI1SK1wMpBiBVJMIMVdkFaFUqrkHZgJsBEKOGMGrBVU9jFCLICV nwvKHiTBihVWpfLPdBWmAqu8mPwFFReJOSB9jcjPM1/VNS5x2V7DT9/gTwtV9Sd/8VCKquadClKJ pD2DFASkjUVSK2yahRs85Ll7U+dHV+WXuXsvlqrjPpuauTXk7nGv/lCYPKLSKh7LSd3RrFy5cAI7 +gnN7bz+50G6Q+UpdbFVFVPVsU9Y+v8uqLbulRz3VDpVmJsBdvxbM2DQV4psWiV5ec+Mqjwkq8pH DqiK0e+AKJ/PBWnHII29+OWL5CQKZzgBqbVE5bgnL5q0BVrm7FPXaXTcnwdScJBiAimmwgmy6nkM UsVhAWKu9qvKPx3+BFWXKg1NuSSArJnle9FoLKqGovrXXFTHU/qkUVVNAGqLdbCxFVKPKgwhbudG VR6SVWXzyIFU5kd+kZ+pT8yAtDVziA6scBIxaURdj+PHPS19V1OaFF2P+vZWQGVzCHDBiRvt+viI iZ4TSHECUlBOsgIp5rCIFlVNDVUbm6ZKfwekBsZRMQV5DiXZTeZCihy4KaLGBE6ox1R8+M9VVb76 xyOvTgDIYlbLP8h2WV6IUZXmkQPpF/ghfGEPSGVFjljkRysK1PRWq/sy0mxH/RSklMBaCUx0krRE UlXoe3WPM8d9pqCyd2nIRz16OZ9Aiulcrwr7FC11LV8FToSMc0p5QUoTNHoGIpykADmqQqx7/FCm VXuv9mUKQKOpcqpoWyoB1aJSTICt/08P36qyebRA+iyD9J8wSH96F6Q9g7RnkDZeuYpIOFg7UUFK tfWjd5yg8KSQ5+7T+AgaT1r8oExPmsn8NC3qIMUxSKECKeakMoHUPM3Lv68Advb4r4788jkHNObv oQxWzFpVVVYlLyqPrj0aZZV4VVNaGacqwmzOUyXico4KOlUV2wtgVRkeKZA+/0WAP/+PC0gXV/nh PiogDT5iIT1sSnbkfDzHoIUTEnrhVBlD+IxTEpjktiiOQZo6Tl4xWzsSzAHa2ph65Uhq53xFimrp b5AMWOCX7g8Ot0xNuVtPTVV5KxVy21VHVSi1XnP/PyhVBRPBirEASaSiC9icFSBvfAR3tEYXcvMv CBel/98+UiB96cf4g2/yw+ogjYf8sj91kCJHUrFUiKrMB+MHNSdVwbOZlcns/CEW8wcdH7HWKKoH qUVSOrCpUr0tOan20IXWAttYArZFD3QVZNmiF6k67lMmaltLlPGPqRVVUfeY1vKSrZJUqkr8zVVB hXqf/meW/KTJqR758rGC1Xz9CZOWwHlc6+krTZXBibbqxxatyZZAs28XOSoZrYYypiLNEeGBqYsy J94crOPmIVlVNo8cSK9NQAr8Wucnpw2LhmvWlh9iBmhQFZRW5gpSk+sp+CqpXu2ql6t7KKJnz0tL dY9Qu+sVCirN3tc5aa7uUwkEJb8cfQKqY71ioyZFFOWuFKT8NFdkWf1vuWvNAJif/2j+36ZSze2v dKsQisOKTKryTzPN6qCdKu3/dw+x/988kiDtGKSdgFQcapaN+CjrnnsZTxf1vG7Di3bcux25RUg/ 6vMIsxL5R6WQwuq4x0r0jJXo2at7nFBQWAhOrECKFSoLBh2dOC6aRoAtwIPJzBRQ9vUZtVZpIlrJ Tn80YgDqPn/xAXB+NeWwOq4i//nPoO1D7v83jwZIv8vxj0+zodEOZ9wySAcGKa0akT6LVE+Peh3x IDeHoNy7x8oLCryal0lRxKLMtw0lOFJBJS8oSCooBWkVSWESSSuXiApvOMHf+INpnwfnCqeanqq+ 32aqskjFI2maYEnvm0ilqKqqCQAh/iET/xJVkSAzAKLcDug2QA+5/x8eDZByhtQx3oZrwkKHLkok XVkk5ceOH8YFP6QLPqyWXFes+Frzx+ZRypGUxJeUKnOImAwiGLyUjvsi1dtpi+bCych8L56kaApe v1fFk92TduuMQmxtI+HivjwklYR+PhodnBJNrdNSWFlRZS3XCEnHaoJrba2qGBut92/z/7VWFSsd gCv/iyeAXZ7ftzqlIrzwBej/NxcapNvvigBd29lDx5X9UjbiRTUOa1GGSDRX1EKAkh05lMIJsrUj JdOyI8h+UKm6r7ygXGDim0vUVQ9n9aS6NS/kqbtc3NeRFGciaR1E/R3CcZTNdNOYrpprBozShHz8 +63KAHNDIA3+1U2A3m2A+nq+ior8L+rEKnk7VjwFOCK0bXgoVpXhQoO0b7HvAp5sY9hiCP2ZutBw PhpkclMMG9TfniiYwRj5EJ5cUe0dD/nhVYMINYUQu0e91DTCbHbMBVqXkyElkPrqcd/tZGYPXt0L u4S2NW9CP5VmvkfS4JnAXEQNmDaaVdP7/n6JqCnSjhRV4Cp/yMr/osZKYy0hjau4WKXNyqoUUbOT yujUWLqRxSIk1kAq/0D8AtX5KhV8n2AMt7YdPyjbiqr6xjs7op4LUn4qzhYxDKJ54kgaqG+wHRSk 8oCKZxNivcepGJYRJgPdXChV1b2R+SUnTdW92vQs3eI8V/fWu7e5e6xGmUteipNIirsRdCfFHOen uFNU1d0qTNX9KH/d1axCGqUuk6pFoxptP3rlnYrZP9UaAIkFcBdAMB2A5qrW/2+q/v9WidcPrq4+ EKvK5qGDVN6eY5B+aQakIcpuh9AEBqlsxQviJhJtsYPb1UC9bEzlepg7TpgcTMiEzxpZ0efufZ2j H/0rzCPNuMRK9JwEJugqKEwgRaypqASyPcc91p3SCQ2V3p1UVaMUoAj/9hdVUFRVBGnmP4M101VZ LYXFXK1U+31KC9Koina1ortbj/r/PZ3IERQInljd//5/89BB+iyD9B8xSCOD9HsM0nUFUlkvmiY2 E0g1J20WYnqLWJnoigoqr2msrB8nrnq4IzCRjtMYpL7B2bozubrHXRVUFT0RJ737IoqqQitWtzt4 HX8NZMp0xKkWwIacUNSKqrJ5ciRaiWPBSlFSJR1AbVNp7VUz/g3usqKbAUf9f6GqWpENwNPx/vf/ m4cO0i8ySH+MQfpdBumKQXrgIO0ZpDI60qAaRFCUFTkuMCGzfiSCdWWkW7s8O3mPkxknPHBr8lzd FwqqBilWUj2joMa+j4gVcw+T92ej5iyfP/3cOBcYFUwZoFinAOOCCytdAJm21Xr/VJtVmOf/pAmQ hv96qpRWaOKVGH01kLbEQqNtMHlKWoYtR1Xr/99nq8pwYUB6yCB9ogJpJ607Caj8yAwMUi6ccJAt jmHJD/mKouSiQkNJ4WSrcaQ9qkVUNAqKtIByz3xCa4tGtLYoedeKzGZHLXzInJ6RCk+qNUtmmUrN VKDh/NSkHVWz/jvFFO5mmaWggoqmKkVWrQEIWJT/1efQ+/5eUBlVZer/2OQxbVQapQ0VHVVGVqyt Cm5Tae1WkG3WvtGamgU/P8ILhlb6/3I8PRirynBhQHqVQXpmIA2dcHfBI2ls+TWuD5p63ItLc0Sv 7NGrewWg7XGiYDypgDQKeBW0FUj10hEU9YGynyku0mqgqyAl8YPCUpin6TtKnCkW0nQExglAMxDH YA1V5Z8ZgOogLyN+aZaK8vB0Bma6L81ajUUshQVAF6pYCuVGFTYrFVSIkswxkler3q8jKypW0dU/ OtrSSLmgK4C4Xmio11GVFX9KzFXv96hK89BB2jJI+SGUVeKxE2sZPeabsAAVmKgbswkmfEUOpA3N 67INL68QT0f9EWbpnhZMo5zUeVanoOy4r1aMa1sUZ8ZHMFuUV/X8edX8KE9FwJnj/m4pAI30qpM0 IP8S+xitNZWOf9OpkksAUVOAmFKAaf8fR2PV2QdA26mYbNXl+4JoVYM0V+UMimf8O07p/ltVNg8d pPyaP+ujbh8Jsk2UgkrU5FXMwU0laDJnVvSkmdA/xLI+PINUnJ597ukIK3MI5UpxPHcPFQWVQZop znTCE0J13KecFPfxTxOw4rSowvlO6vi+XWEK7bu/5KlINBWzlAYAlep/4gEwXvVjompMtpU6piKG FaR7rUh3VMkOAP6pHFda6oZIi3ZDwhneT6vK5uGB9JBBeoRn8Sz0koKKzU6LDNBFI7pIAlVAqTQN ivuIrfzOjnqZK82RNLdJvXASs7KxPylW5hCQt49ApSct3VCPpEnmnEr7nci3hyzF/ZTUeRF1LFwZ swJkbFQBKo2EKUksQGVxmk+uUAVWTDSViarzoopqCgByVBV+NQh1aqoqDMYACAkgOsCOIwrIqEr0 UZXT+0JVNQ8PpFcZpBsGqUjJFw1y/sMBteEAKw7M4iy/EBc8WV5LeXzEF+Cmo76u7h2kfuyXSJp5 UsgUFKTViyYyGQlMcMIRZTY//a9S1+2AdQJQqjlSnAcwwt5vn9BUO9Op9TQA5lsaMQEGVMq7U7P8 j7Ac/0npT2WBWp8If6AkAbQUINiUaozSPIhQqCq1qtzA05xE3Q+qqnmQIN0ySE8YpE14gkHKL1P+ L0ap7FGtH0Wqh4Gs45TtyJNUj9RVDyoKCp3MRxeYQLbZ0f5+yUlzxympoKh1rrSAFCFMSMwsMKkR ijWBPwUr3rUdtQvcPRiezQ0qwNZ6gCIFHNNVNNepGlkBYWX9UzQAUK/+AfTtKp7Liom87KfCZtB9 VYOMqghQV3Tc430bVQkPEqTHDFJQkAaGqAzjNQrSoOocUcszSCODNEolTis+bNZYKnxXQWGq8o9o CFrdSz+fX91W3dv7fBucglJmYMlfIzTUwn6PVvj8O/VKhXNqm9eXz3hiGr43WHoumGn1UZU/HZaq K/4xExDmaCqsKSuCPLaSev9VtZ/ud7qqdlnJHqtKV9nn3ARDtqzUVpXqvTXyVXXaKtNVbn2kL3B5 7KIaVQyiT3Gryva+j6q0DxKkLYMUFaQSSTcM0l63c4i/YdC+fRQgiWWiVfco/9poXlCpwo9QVokH UpDKLT8XB1yRHsotqB8UucDEx0ciudOzjzSL0CId9zHhjBIxiuklTLmZaakfemEjccqEzTQWQeUI SGUGhdKtR2OirJzKfSXyaEuFspK3SP6+l0WEKbqkPinlrqmZRkuHwjh+G1shZ/ylYEWlq0iFPeLT KoBLW1UcmLpBRfexLkwwTr5OE03+p6CGLupsmotVZNUKdqE5CPdtVKV5qCBVXSeaFxQ/MISlLapL bKkYluXiqfbMLx/n3n2W6mHVcarGRxArB5OJMr+io1IWgOOJ+mqMBGsJ/6RBNRGW7Oamu6U/7tNS z+kAEkU1ba/SiA3AJGSpSIGRVWUt/6Nxh6rsUrVNKzZSnTevmAZAR6vFVA30bKJOO1XhvoyqNA8e pF2DPZnIROzIpeMUTE+KPjNPNQWl7iWVnlS5UZLc1FfkYF6Rg7aJxEeatSWa1zYWnnTaFq1U+QmK M4normD/fLCOpVHj+3a7rri3uNr9meN8dCJYSfEZaaRzdeaq5KjR78ttVXkfs02l0VSJssqr1ckL LlVXKZPq47JEW/6VfUfaLbgfoyrNgwcpNPzv4NdfkNHchRhyWxcEy25RK57SAF4axss2O8VVL61t TCPNaNU9wGjGqS6cMJvo1uljWeM4nr3DOeXI3cEK54AV91FYuPstO6IWyJQVwTyvOtYBVN5W5Elu clXxsRVdMpGNKtANKip7SpMDFqE1JiZALwd3UH429Ep+35dRlfDgQSq5Ifhu0aCRlErfXdui2rMH Fz1bi1Ry0SPv4R/q+5y7Uy6c5JIRFI7GXDRp4RS9cIrYWtEEWjgRoRvm6eSGPmNeSNk/Jr0f/dL3 wT2d/WPywirdeqGFoyx1ZiR1whpMe/9h2gar267ZNMC/FrywwlFB5aMqtUOgF1Xo1uuoxZWwTFpU BaysKr2I0sUYfrkD4CJZvAdSGarSe8HdCnVVuy7vwPs2qtI8HJBiWorAD0I0m53s9FwZltUdJ6i2 NE+lelgp87GOpDAh8zFM6aeRkLTm8+fI+bG+aRxZ5wLxHMc6E2HxLtpVnE1e9+TBJZJaH3VEZ41M f9UOCEY61dytyuMplCiqvPw3DwNGMCNgMRQYYpRRFbpvoyrNQwVpHmn2vDSvEq9795aT5o+VwCcf H4EMUifyvXBCd9VDrUrLojHEqVyv0Jq428K/K1h3R6Tu2hDAc9KBPVnBLtGKmWYgmPKqWIlT/dgv Amvy70nyvzT3H9NsVF6ZjmlNZSmyMC1Y863VkqsOYA6AIhdO+WrPB1fbnRGpVeUxvbzip+unvw/w 4osPFqhvGaRZmU+ej7rNDta9+7E5RG6L5kha56SYI6l2nAgnhmVYUZa4V2CCu2FslH/eDawFpOeD FefUKZPiCndGVXZz5Z2iCnfc/zB/XWEEsq16MlWrdACVWKXsTi3b/8pOVWME0Lb/SY5KRt6KW5VI rEJzRpJgaP8fPvSWR1WahwJSldkxwAIUkNYCE7QZJ6xmnGSuifJI81zvHnPvHiuBSU1B4bS6hwlc YWYsBO8GVpz2nu4JrNMoirP6AJwvqKbdqkm7dVxYFTPgsqTCnYCsvUpO15YUQH1Socz/+7Y/Ba+6 qFikpdTN8nYqqgEwI6APtA1kqyrD6m0ZVWkeGkhzda8eT9V+UawEJlhsdqjOSdH9pKa9e8zbR2xk PuWkk9ZoKe2rYHgPYJ3hN3ey1BlrFNz5GeeBFids1nh8JXP//vOMhpqr9Kv+f4q4VBZUTKNqHgSE kVFFnzUAlCt/Vf5rzopJ/md0lTAIXL/Fs/swqtI8FJACFX/SBFKs/Un32OzAeEsz5lXiaRBvLDCB 4u9Yj5BMVHWzh/jMEb37cdUYmIEfznCscw2AfUXVvOhqphuwU1TR1KqyymfHuezIUSVF1boBUPf/ qwJrtGNVgW0rBlW9TaSrZ8TBAt+2UZVw30Eq1EacgNTNIcSSPLuYkKvyoRofAVPmk46OYOndqzLf e/fkOWlENfC19nbp3cv2JIpOQUWjlKiioCgWKqp+f+djOS+je5JSTV1579/vx9Gt01aVRgCn1FU1 xgIj51/crwFIEwF59r98PN2qkmkrETd4GpnoKnnifM2lW1WmUZXYBh9TsSkA3au6zG3WaomF7XZV 10DVEYPMD+moSvu2jqo09x2kVDmYSGvUSH2LoFT23RtAMU+LQrbZqZye3cFkh8yv5u6hGh/JVQnh qOVUWp2TjhDORNcdVghn04M5E2mEPb9ntoM1DqV4jiZ7N6L7Ao79jYDxnoDUA/BUwGQO4i/laQCN iqqBKgM1yVexSg3I3VU4N5WJVUZ/EAkgNWQOGAtaksgs3ipV1TxokJLvcEog9U6TqaBqPWlls7Pj mZ+Oe7KOk3iCaluU3LCMctk8coPAGR4Ix44Ps2P6c5/bSQVwnAAg7EoAcadIOkceuDMpsO/4L+kH 7RRUUF6zNMlXve+PowkAiONp1ZGoWoqmOgXoJ8yAyv9IjVoZm3HwUZUBTgnLqMqbpKqahw1SMJOy I4KyES8VTskcwtfsGE+KlT8p+iAeQBVJEad+jnl6ZJKR7s1NK/DiXYqqfYwAzEF8hwmYIf5rr8qZ Wat5wOLMc7cbVd1LOOeqqv2iUSNgVFTRzKgK+EwV5Vw1F1xxkAZAtmWn2ARtBXBy1pdRlTdJVTX3 AtJTBul1BmmcU0H1fdNEUeYHGal9wyCFyW7RfNzvzDilwkkVUKMZp3F171RU3skEteQZJmTUhMPE 83lSmAfvbtU/y57uMARz4JxXXOEMGzCnsBqv95nqANIaIJ2xJoDaotKuoEIVSwNsQ4rvqCqgRBgo F1eVHwDaqkqNwlFArpuqYtPJjrW3PqrS3AtIX/vmd7E/PsSjK1cZpFsx2AmylBiHXgQmoiWV3r0I n5dTkOpteCMgrTzzFeB1x6ly1YMpmV+ffziJpPubn3ujK8IennQ3ysHMb9gBMOyJkrjnb8Fpnrub A49E/qOu1fQPKWGbRmDOILWuVWkAxFL5Z1eVoQhURntVnV8F9aXM5sGkgyrxjF8Sb8eoyp6qn0H6 XAFpd/sQ10sG6fYkxNNNCFvZLzpwJBXBs5Bl2FKM8yC1o/zgnkEKZQGuWkkS5EiqF7nAJK+zr6RA cazMd+FJruCpqtaV9c5VPVSVvr8/+PeMPodJfbnDEEAsPxMzUwATJgBGt6NpgR0hy3hnWvEEwB0G YCRagVL950UWFRPQ1B9DTOsuU/WfGABfU1n8VNO8v92Ci1ai3u+TALrXIPmy8v8FWZ4U2gH5CxkU CzxlSJze5qdT5v+bLcCvfenN0VP20voU3PjYF+Gl//QTEK6f4aK7gkeHAQ/aIQxiCrVdBtr0Db/e Go7mrVjtCFVEqgrXZWO127MBcA6kUIFU6agKpNnBpPbMn6xtBFsOUs60XZBSPtSyMsoBBhmgGbw7 gMQKsDNATuCvwFsDFuoXwQ5t5VTVBKywB6yprRbqMRYYg9MtXRykMGNZ6duoKvPfxjerJLMKA6sq qnwBsNNURkMVVxVd+BvTNO/S1FQ+QUG+B5aoFRMRMbINDbzlUZWwe+RfwfCrPw/r545xtX0MHr92 gAv+lU0cVLuNy4UMcYhRhiQf8octdF8WqrPGilz4TKD7681mBzI/egTVprwq0lYUVK0ndZCSbx+x y3LSvHsRccRkp0jqACUqYEm3NAIWjKPtJDpysCngHfbxrTCRBZbvq68UafeBFWciaxjJBDFL/Ebz V1Pf1WolUJIDhmo5cD1b1Tin2hT5X8iuKu5UHWrbH73iMo2vBHeotnmrHGFVQtjQwKefjqoEGVVZ HQwydYSfXvOPvc6Z3bcB31REtSP/l2Hx438F+OotuH2j54Odf+jyKPQHjW5rpsDRtBFdjLxypIAS G+3If7AIRBKpn4/yGpT1drz6cwWkKZJOQZrWNlYyTBhtX0iRtFIOUdGSkpP1QHvAuUP+TyNomG0O jD4mmADTv6/+HTORtWhbqwbBTlOggDVM9KslolbmwAmgo6iqQ0529IdqADDZ/1iUtaM/RVXRqipg Yw1CAyhfje2nSvbqbhCs+xQ0jsrm31b9r5A/JNzSgCe0Zaie4M8d3rZn9B9/400A9dkPA3z+5/XI b4Y1hqt8y4noOqj+VpQHDafLjaQ6CqIQZLRZdxWN89MM1l3A1gA1kK4nFNRi57hPkZSybVN2Uyg8 YSIEq6H6+thP0XU2FcD9qcAwd9zDJLqGKqetu1lzYK1eRHUHC3Aiwi5gDaNOFU5MJ3HsbL2nU+UC a1+1nvcAQFqolnyqAqSrTgFSVJWAFM2jCouxWtD7IZuqJc+EGO34lzXKjajkBwprBmrADn9qvbRX 2eelu/5r91b1p9wUfvK/wtP/vIWbN2/jwdHjeGXNrwMaAm354hcHn2YyISu3etzzH6AgJfCR5l1w Ho0uHEXT9LVrP/JXFUjTmpyck1beYqNTEketnunw8oSiyVOgMLNCZ672n5nLr/KkvSTW3vn8MZuw S0bNNBtmRljwnBkrgHGHqkj85kTWI3UVlf2qSawC4/n/vOy3rP5JHqu2VzWxA6RsgXipCCvQatLD YbyX+r95U6MqJaJybpqjacfRdHGGw80et6cD9ksGrC4c5BdXqyZiJkyOaCscbbw2G5hVUbUGb9qC V39uNclH62jaeDTNkbRyqK21axPNW6rqoTxBdXTNqQCOUgGYsgL7Kvtp3rq3ANstqEb5Ks0UWVBr A1KUnXoG1Pnr2CEwVPnquMgql7bxiiOg9/+pjKuYFqBEVCzz/7nyH0VTStHURlXSOksZVQmoaYTY VQ4xhjP+rW92VKUAlU99+Jwg5wDeE98L6+1SvEqFveWvCeJaKuPbQdu4JHMyOX9UVxNfeWNrxrNP VI6YfmGirVZ7QDqu7Mt2mxFAd+IHzZDBaSUI1UdufezC/lRgwPNZgaHKW4dxkUXDNI8Nu4VWLq7g fCELFbAGmmMDsNhY1gCtj/5RgVXlrNXxX81a1UxAUJFKPVfFuWphAcAXVhQ/AMBkZAFau6TVQVGZ MEktUK0q1wyXZXutWFV+9y/wbqd/k4/95/jY/3gLt2++joumDacbWfIgO3JQHTb4yVF3DFmGy0Ff JHYrDiyrnF8GL4pwxJkejI96XFc86Wqnuh8T+qFujU7m5GY59t0aEsd9oSkjX6UA9bIHl2ns9C3n mwbVPYR7/pS5ZsBEhI3nNBX2CVhmx7Wr2IQzr2OCUc8f8hZAF6r4rXes0tY/X1YBA1Wz/ZVDdbKr HMoCC28WQBiQTP7XyvIl/lU9f1vbdW9oVMUjKh/7Czn2r/OxfwfhyilDpYOwtZd25DxV2XTdHysr 3LwKT/QUekQkWFTgm7loMVssTU0h9GzNAAWYGt+fG0nnWm1VdJ1JBUaFVpEC7lJWM2nAvuO/LrLm GwShmmydTrlWqcFe6mosExyzAeOkPowKLEgpAPiR7y7WVEkAKXhUFc8l2YSs1X8y/7UGgETXqGlA wMICVDSV7Fto1UJUepmNrFTloxl6DoQbbNozLap+5opIPT4E8O3ziyoD6rN8/YKEuEM4jE/A2XDK iQS/EBaNTHSpnQbJ/mb5T4Is5x78nU1ZFGaArcA6B8jWP06gbCdHPE7ACTvH/Lg1SLBTKMx93bj6 v1sqQDXnmo7uYUxr5VSgBuEwk7dKWVEd/SNgZ0YgjOiruU7WLs863hAcJmxArXUcU1a0k7NW2wDR ctYqV9U169GOf6v807WoctQFjj6WrpWtVed/WJsM6UIUg2bdERYCFz1bfveEOv6dJ/j3V39tnap/ /Mt3Aarnp3oqx6cBN5xecg6MbVRtrTwK5C8+koFD0XCn5WBG5zWTyFjAiOPqfec4ny5vmI+RVU86 uzDlBbUZeOeBdVJo7UTXWDcEcJdznWsG7Cme6rx1BN5pdM2RtIB1bwfL70v+AeN8FWFnAdukwArT y7omWVztHGsi/325WuJVlVs1kDqfGjBfy8aJf89VJdIumtx6jWo3H/SKKRUOiwHDmjFMscMf32xQ i6pzqKoRj7rpetic9rCOVwE6SU17STF0hasq5UG1M8leHkeND7ttRjx0pSnD+UIoIYhc+rtz1fEu 30/p83mLfbJUhMm6kLcUXXcKrXtJBYY9acEw/doqUlOlD4jngbXwreOuVfV+WogFmA0tCmB3GIAd LYA5AGaQ6rYPYwBiAWtOAaJ1qbRTZWAN1Y7V4HoBkKaB2Io2Iv4nWWqHi9T/j2s43SzNqvmc/v8I qFsG6sn2jHEZ+f0OhtiLYBvtwXO/gmC2oTTaXjdW7BLtItI5uVpWFncurK5y/yyAR/+VO6jE3Lce XedTAdyfCuwTr+wDL39Nvm8K1nhOZE1gnaGuAkzdVyaagHFakKYgi0AFs02lt1UFrGVUxcAXMwMQ ytLfxAAs0BiBhbdZW/AlF1FqGzT2aCP9f66zDnC4p1GVvbaTMlJIA5f3jRhfy589FG6cdqfKp0Ai 30vkYBtcTJskYm0ihZMxRIKyf3/jt8HvzSt0aC4ppVIoU7FaGBfcNFOOU5nrpLkvjOYFKWDV3x7t L0rATkSuNgnTSyrbVaobkz4ScoOTeXx74Y/PlIyi6I+KPGIhGV7GXEFSNUZtUcF1+v4whmxxWf45 xa6yHEnp9wa1pwS1oZJtH1I3N/qKQeVUST1VsSFd/gG6lE4bPnK8k/f7xT+Mou1XpSAdLLVsimKE p1b3nOtKl8rsf2RdqCSwspspbroOP705wq/d2m9VuReoEjihaXRZu2SmIThKozqDesMSXHvoMQVV dFtRE5A3bYD9CUr+8s/p8mav8jSlg7ah8pSniygtfXAfmrFwk6aAzSb2QFkBUHCIM9E1h2L3LKUa 1eQvS7JIh2QR0cEEpeYpnSty7iL9hbnfUz6H+6i1BNY80Yxuip3+wuTNmjBq94YKznrm+WuB/EFL r+CQ3agNpI25rKrcv3Ei131V9diXRRMKVFnhI4URRa09yD1TSY56Ba50Ka3AkkYQ2fSxnPJq/isR WUpyPrDDimG74adzy3H7pNuKJbj0/+n/am5yUcXf9eI96FHFXXfJobgRgZREav1Xqv8FZVU42hBY FTF7m6kpwOQv3MLuteGHxC9IV/68f0/nV/3zBvc6ql8E0Z+lOJsW5NhvSK8+v5fGGuenewqteC+s wHx+OitsGXa/Z5S7TgoqmMlXcUI2h4qyCnMpQM5LM101caxWimp8/AdbqpbzVD3+Y3KszjuqLG/N nayFL2ATB/WkxpLZP+//c1G1brz/v9pbVI2Auly0sFyu6Uzif7uwWCQT2m4CS3aeeQ5JfpTb7kwz JWBw4RiU6Be/f3aXqwZtDd4JaKeEsgEW53LaMWApl2w1YM8ptGhaaMVJETbLCsBO0bU3bx3m2q0T rnUPWKddrNGIdcUGBNjDqdYiCpyRAeaclQoDYPK9tvHV6qWyJxWrmDglC6mzVtUB2/paJpX9Rckn hz6ETR8W24gnfYfhZo9/f09RNTr6VwzUeNDCbXidfwtnvk1j4zN60kRb+0I6IT8QYYpwMobQkQKU 2hE/Wi87Mm/wOJMWLKuo2c6IpFvP2BpP+pImFevGgJ+CgfYyC6N8MM3VUdYK4CQVwBSG61QgRV3P S6nyLY84skcnrI76UAVt/pNxNm+tPtazOpZYgpZlkWUAo6+ts2tw4MWSCY/kJ2GSs5LTNaar0gdW nmpNs4KOVUU9OoVWIiXQJQ2QrqEuT1aONNjRr7ypHvtEPpFhLdVIYeGrkpRX1eDMP4rP6qaLNMgP Eu8V6f8vDyJ8kk/y39mQFVVfLv/SSY56ypnybViFHobNQoCqJu9R01Bzf0NbMOTOw9Shrb8pcjzf oVAWHeUKf7RyuwJpl5sDmBsGNWB7z21bf1wdwLRTyFYlRMXPEk6ey/MAOym+zi+0NE+MlQDLCpFS KGH1vVSKLZrmrVWZJK9lHVV0CJX8NZSXPE7y37wvIKW0Zd5Uvjikgqua/Q9VGq4njc37yUY6y2Nt L4A83drlUZ2HFFeBwSojSErm67ycAZVIc1LRJovFvRVcogWwoko23jhD0CkLoCcwB+kF/4g+hjX/ gk2zxK30/19nSHznL/jHP5fDQ2MB9sMI7/08bK5+C2/1t7A5fBJWpyvUYpaMkJOin+Tv1OeBNHKh ji+YjVzN2lfBJ5a8PdfFFQswup3knlPGYIeyihOmlPIzWd2PcE7RMmnH44yib2o+hrNNM9xj6nOO bJD2DWzj3j8T5+yv9vx1Y9+BeVvL2fn/sbYwcTtWm9grIpLbqqvsT9ynEXLtQOYH0FO1rTpt/1OD Nf5a/kaxq4xSl/PLIG6IT2uG9XLgAIm3fVXlDYD3bPKkqgH15ns4G3wMu//kg3B2GqGJRxAarskW PWrNJ1QY9dqICiHtZBhtCsPqxZkZrswMFG50DqD9BKDngTZOOFiqfg/toflp9r5zADsjI8W9cKBK L0oTtOMeOwraL1jZeZ/mJ6Nn1lVNMTY7rA17hCtzTlfk/z4HaQYsFTM1E63UU6p+UWWtjpVVJXlB PNhItjFGXKWJAXDbysrKDj64OoQ/OHhyNKnaWgT8OgP1X8DBR/45HFzniuj2Ek4Ob3CQbmm1Wsbe OCnOAOIgY/VBzNrSHhtFSHSGJFBVhRvQSNpb2FVFUedH/mZGuOK5jL9PRhqTtWJthUwSVFPJh3Xz MY3atE0ufG2OOAldqObDqSy63+FkqaImq5FiLFRVrYrxxFCez4i1Frus+AmeUcoDF8YvIappq8n7 MKWxdnjWEUHnf1MBq1FWZZ1QTVulb6Qqp04pACnhKYe/aADAZwNSUYXKhxKYWAWUK5WYaJyqUVTy fNksXXQ7dVn9Q6RClZZzgYbBJLsr9ZSGjgsqGrRTRR0//df4gfuOkEASSr9sCv/6+IcnX8NG0ooo qcMA6wXnDZtO/51BerO2VdDMC00GkFhnIhg54Sd52HnR0pyMy+5NnyPXAq2yi5lc2Y1jHGlxnA7E YmqHJS3AUR0/e5bOevbNSvYn8/1vJBWgObcA2JsAYBW9953g+37b1CKzvpksA0YamwRUqypTSp/c qp1DV8MKdfJLxhSTnarY56kAhDwNEHwTi9CqUvs0+v89Ncu1tAugWb1OLx/z8f/ch1T9X4B6U4il Hwb4Bf7EyU3cnm45Z5Vx0hY33YY/JyZPS+iHQQtXCxapm6rPZHR/EiVWyMj/PMaABbATbhT23d/P pAbDTJowl8vSGLA41RLA5JbGT8/et8psbZzb4b2kArMwxtFfM++vMh4fwRnlI+757rEJS23ahtXy X6jWvo2HJiZu1ZBz1TKyUq2nxExXFp8q16qSBx9Ed1SxgNNgGIIySSEuFg01DR//2wE+2C3s+P8v H+OA+uW66n+Z4C/+Bd76+s/DyYdehSdXPa3690hwjot2CbGXjVdKWUlm0VsyILvbot26sSOl1ijZ K4hfeqmq3+ocOOlR7ntJ/Zgv8/tmcU6TdGD/bTuWExplskNvEY1TAlN62VybpQSFJz9XPDPikXzy lZIvfuWovz8VUIrBUwGCPRRW7h3Vvy5UArJQzmw5iKWtG+31KIezxYhxGpBhl9qtFYmeOlfptdKg EXPp+M+dKp1UBaWq1AsNgsr/QDcARjMiAUrj8/pcyFK/QDIESu5hG5tB+gv6vTEMUk3x89DJT+X/ dZwpdg3//SccJQ/ePx7u+3IVVU85qt75hR+Bp7qAq83KuDfOS89isGcxdvonmrGz9QK0dSVpcTD6 St53wkCdiHVJgXoZpcoQkr1279vgSvTEUWSt9h3VR3/+XJwvvFIU31eI4Y4TwIjrKc4AO6nBjG3P fqd9GntK4ezhjJllvnsqcE6oH+28mgw3zhRYODkAJvlNJXirmFi3U/fjiYo7taYA2UTNGzNdtfi3 8zolLwJmoCoOoqn/o5AA0g7pQkNrCTu4hSdWp/Dnr70M8E//afGesjz1JqyHW/j4c/8I4Educ9lz grBZaXAkKd4Wwi3csdfVQnaaaW1nYgDBqfin+JpsSQXImwP88hs0FYgGWJyCzi7+GuqRcJoG9Oek DP2+1AAB740tSPx4YQ6m7EAlX56c7iMgIO6Ov8DOk437qnHcN+Byj4Cd3TUwQ3vhvCa93rCyqzbK NEEaVUmjKcmmcjSh6jVHZ0c9dPycGlCROiJPB5TmDz6xykGlbUQLKAihxXYgOjilH1ps6Guvvgrw W79Vjv6cm7x8h+C/+22ELz4P8Ilv8F3H2B4f0pVFEzehxzNaw2IbVNJ9to00iAqmJZk3JH6NcMIh OSq/p1tcoplHxNCqLgbRjmo5KlTUYFU97F71ET9lBc5LDfL75DPmM4OD09SgmaQEWVOc0wIY+z/U J/weOaHPIRGNSy5LBer0MoN+0gwYswKonWujimKVScZxlh2q9DinyZIaxBmKi/zLMfOKoXCMmDvF ZFJA6yiLYw55giGqKlIhfaOz0NhI58p6Bqh6AFXfk4zdxSZZhJqwRYZDY5Atwo1GtEFj6qCGtxvs xPQErnhnfaaFmqmql/9nBiuMwArHgdOg29CfXI1HR/wCYCxs+T/ZL6z2E10nckPRWUV+k3/EIK8Y 6e1GUhKWM2UV6nTSpVDKKTKAgi8u046U0k+JklLff5oCNuezuvn4roCdAHWxr02LkCmuoA+qtGsr VxzCesFjtZF8lLVWfE8FmdwEsi3T2ruz1LZsn84t1ZqiqmWAOW8NzrqAd5RjtX46jjZd55araJ9K bmFtVip1fs5XJ3SV7ae2XyeAAu9aNZYDZ0msZNyNd66kxS2aU50GUdbdQa1KLHlcNbcVIa6rmxtt I6G2PXvsGlmVy3A9kW6rzFNdpVmZ3xisLyH8yvvh+IlP0O3nXsUrr57QsGGUHT5Jx6en2B+cQtMf cswf1GogrGW+mrP6jv/I6BRekONd/tCgryTOAHrP0VttwXICTJhHr1twkHq/OEVcLbyKu19exusf U7ZLF0EETTlZ2gfYN1B8wYiPrZaaTwxIAav+aF3Vk+EUtAltfb3EhyatgAO3kvyO3EvHLdfdwst7 uA7c6CDdbbmOGgdkr7g6iAfMSWg1AGGlfvC16k21Zt20n6gjLF6MhSSz9x8vL3QbHtAnXPIDcSxV ThZ1v1Iw35azngHDCWO3kcyBCyp4/349agLr11/+Ov3pV57F5z/2RTj5hz9Fi0/ehNuvXIfHznq4 dXIMVxaHcdP2uOSAedBeUw9oLtooUidBXZxc5VELMs+leYi8mojMJToIvxaTY3RLanQgkZbBRujv i1Lce8mmA6iiaQbgMn+cbdOpfB6dXaCdKNuWqVjbA4BapY5ShCYLYsAFMTAaRAyUghKOGIMJ7UR1 pZbgavLJiEhYuWlgVavjHvks7AI4fxySbjWUzrU3CTLTAPubpaGOqpUC3ZN1SloACbMNFnGa+Dxl DagIQGg8AKaAFj1O1NaBbgaRXyabKYNXan3knxIHsTSzAfuTexBOp3/IZ+BleuHP/hd4/Ne/jTc4 ui6f+inaMGBPXiH4ocUVur26g831pZb2R1cG7IYliWIbjpqoi1x1kDHIEIKOy8ZBCh01tVDVeARd pttbHoOey4I5BaIZGYymXBV0VAPWAWjgpGl+S+O0wNOKSVogURWnaUEVZStBDE6GFMnTgqy6zqdp Ud3R7lCOfo9SV+oB7YAwM+g0IpM6WDSJrODnccpbzSQa89E/eh71lI27DkZYEoqYAFooMQrl1+jX Nlm7Ti6cJ9fMF5kY+d9BrvTKlWnKNWwfm+6z1GXC/PofYrRpLjK4+C8z94d7AWp6Mz9gSQW+Tv/+ K5+CP3322/j8r/CzH5+i5dMfgac+eUDbG6d4ur3JeawkGoeIBwG7yMF9K8MJXNz160hiqUbKvqrC 20k5jvI65qo253oikO8vTWCt8lj0Aowy6HJEnOdkZwoxot08Fn28l+6l+KIkO5ymBcVpkNJQ6Biw 1SYzqoYSMHf51KfZVD/FFILmI2HNp2ow934rpSKrArYPlAgDlPPWyWDMiIQKtXAD0zCaa/4teack 7w0KVpPvNqrTiuQpX3Q6l8gldTrELCPMqbep+5aUQJXK2wmchT7AT/B1Hd4AUMcPztfhMwzY//Ar AH8Kz+JHn+Uf5VF2+Uk+yV+5jnGxkY4thu0BbpbiNsxpQZDxa+lWcaHHaYFszw42HSC+xJIXcJor sseoBY1EXpla5OxW89i0hFfXmpuXwLY6zm2GPB3z+1mDhXtkzRZfdG/FVyU7nAVsGaH3oIjVqZqU d3NKVPK8FSEX93kBZlYX0Fx09ftGTEFwPSuOmYFgDIA1IShrXjEfBiqzTSkK7UgS0ADWGH0hzDof 1iRnvnABvm2aBg/1ep98oQxJ2RZq1MUpMpoqSaEguUVvYcao1ZaQi/JAPjkB6hvehfoyX7/B1w24 CS/c5Hj7tVcA/oxP82tb/s0/ATf+1gZevXUK71s9Qf1BD+1tDnbbhlbLCNu4pGHbUViJdJELr7a1 pYT6QvTWB+qEmc5hNojZ5kH5V7WUIW29oTUQRhwqlUmDupEw4WJrXYHtTKK62ZCaE7XOAHMTIfom uzw1649zPUNWluQVrYfrU2qftxkp1AyrWlkF4XyrYM97tcSPZpq2uNPBIKyFU3l3BVb/Nj0jTK5n 5H7nFj7jUSOEDT+jPrmBZyDvI6Ypjw1/L39N4PNWvo9TU223Bl0A3Alm+XDbdEin3Yr+EK4R/NaX 7y2i7ksJCkPwdfr6OWnBLbiJGwFjf4jbA7F272x7mdRZm0YTmyjDtL2k0VoNCMU2KE8nDK3Jw9Sh hZNcyVs7WW6htFbFye7wsaMCrGrb0rT48hyX9hRelJw/YCeXdUqrxWI23PixL5xhoP2mG2HGEzJL 61SIFi1tte3lrhfxOfXd6OoTr2rA4JFUE0UvpqAqskIsgm8TZFNRSyIFHE2WEaUXYxreRJtfa5I6 TtQkEBhspJe0zRu9Twtm3UjN0VQ3pwgYo1pQBSFgaegtC5Bhkr4foOFnt48DvX4sf8+rLrKDNw/U fWnBC5wWPC6ma89ex5QWIKcF3+e04AOcFtzhtGB55wB7zk4PDwe1fO83jZpYyt8uKavsz47ibs3/ Pu0wxcWgRm0k9jKgeazKzFDlXJmT5afe+smUKK7Mxy680PLVQrC4l+KL5vhYopIalGmEhsqUg32M ycZ9UnwVdoAq5+xQskIPa7Ea5Ak6sp2WvFCZn0m6tbEOkJxvxTyDHSe0gesDDLCuTQm+rcc4BVXF W/6prU3wxWikgiNSLYd0EkWxL+1TPt7lVq9GZucgyBG7TVGXfHMKmQR/IBp0wJ/MJEBX/LTio85x p10OsJDQFLiaOn3t7QHqeVEWviKA/TY2HmU3jz8JJx8wtuCUbuIR/zF9WOPx8hYqocWHwcDFF0jx JcbaQ8dhs41xOyhroP9A5eN2OVnyXBZTEeb01m7Xi/YXX29VEEM0N+9VcliaFF+Yc1qCegWR0uy+ DAq8GYxUFWKYZPfkhRYCzOSuubj3YsujLaVOlTSXJGcNaZJao21l2mlmQ4BFo0EmNJIWaMdA07Yo 33LNgFuSyWKiDf8geZ+fTdoGaZsibBsFdOw0+njqFaUjL3+AuJxwlFUTK2W+elodcrxqrxCcnr79 QJ1GWcpsgRVfz3/sV2D5i5YWnFt8LdbQriAOxzJmo2JFUcRoWjAENE5WcvNB+2LKycKEk7XhM0gR V9MArI9xMn9POr9lu6zSh/rj8zlZNE7WXkAFsO4N4W1aKEOKyQKJsjtASD4GxcyiEmI7cZuDJpG3 kHYNvEZ+AlmBFazWCYk5iGW/DJn4XaJdtBxcawMZ+g4WMXsdaWcANnJLIOehApQ/LyDd8D/sTMfh MYryWfNRPhaluSPLUaSF2UsbiqPwENNqSv1HBFpp9hJhODqCTd+/sar/racFiY/9Cjz+35a0ADgt uP3Jm/DqKwQfXU85Wf5X4SEdb4/nOVlQmmvQBRgQ0hY/GTxLnGzjC31tOgApGw/v5LF6zIvrB+4C lmZTg3NatfJ7LI+tzI6zvabfF/JkgnOxBjvPW4mS7UkRjqIP9ATnWbNZRpIKZP+VBMwkQ3SedVTC axfTUwJvGkWzwYs+F2W6YltyppV8Lkq3OhZP4suAGy+eBJhnJIWTgjT6/eGMUbfhH79h1G+stjDh SqPHPw0L8aMYhjhIqsFhZbVdwLCVdkBHdJsfxve+9/4D9U0XX9ubOBwTHZ7HyQpd0BgnC87JUs3J IiYTkNbzJI2u5xZfb5MgZi8nm0Dr7oY1aHOUzYUWhcpNprwf3fksJhuYysco6fPIJ70zvxB8h7sK ZOtcVVklSyZUAUfmY6KtCFc2SatIj+tODUL4WA8KQgEpMjiBwcggRTjlf+Ap/wI+qwNf/H6IG44p Gw7eHHUlunKVz7fgCirOUmXGb9DwgwsJ4HHDBfYVeemcnsH6hP/6j/9H9ECB+kaKryNOC07qtICL r03PacH6fE52cE4WhmyR2ajBMVl0JfMEuK+CmNnOF1qBZ2lJ9pMdcbI5LUiiGANr9vKx7bppWzaF LAwIk7HGMmGZJ4Kt0xkqg6tIRW0VrAEV9PgXF3OpsAQ8jCMTwKPl/3x0i3S+RFHS6AkKUv55DM4o CeUpR0cDKuh98nkOM+KCE7b8eugYj51F1TAIq7vgQrrrOKpy7NkuN7Q4eoy6PtDvt3fogRz9b7b4 OmDAHjBgf5DSAmnVDndwuTnAA1zzeXSCp8OSa60Ow0Eb1W1Y9rNKeoADPxS0U3yZYFdkaOHBCmIK 61CiLM10vmjHX9Y0BpT8CxR3qkKyZMB3bEXvhMWyLhV2ZIJZaUuluIpUGxxpZzPYcW+cJseIqLP3 /DgJsKQwwmTFVAAKcMJ/7Ck6MPlXnfDfKJvPNcLyP+WM/2oBNUdWAWuUFnmvC8sCH/rQyMEvnXRq lktacfZyY9jQ6ZUt/PYdgAsB1H3F1760AF7pcMunyh08w72cbIDZ4kvlZQi2R/W+CmJ2OVkqS4cX lWZBnJgXUIQwxsla9K2MkTH7zvrMaRbDKDg1IGqHTwUf9fZsgrFpG5RB08QEuHsNmYdP6iypW1ZM Fk1dkO23nmsGJe9JI6dFTO3InzhgT0g/Ryf8+MrnleznH85HP6cADR/7A3AxRf0g+W/PaUUUxzU5 3xi164E6zk8Pz05hfdBZXPnSl+5pwuGhvX2Gr9/X9yTKfi4VX2BR9jp+IDwB1/EGXuG0YBBO9il+ iJWflW1Wmu6Elk/+Aaz4EsgOXTRbpRDU7MvM60RbMIjcsi2LgS2XnaGhpoAdCWL2tW5n89nx3oPW P3YVV2ELEKdj4HpS6AvRyVKzmMruvuRWqeRuvtGShyK8I5M56y2pIFPfjxpFwa6e5FySIz9EyUs3 fCpLRc+RMspU0gmj+4Tvk9tjvQiPOY85ZqTrfT2EE3mf84cTTtDOBmj5gjN+WrbbiNttj10/tD3h iq9+OO3aeNIcxBucDTx7dEh3vjvQCx0H8s9+li5MRL1fnOxDFcS8UU6WMnhzhE3NAyg281VKAC47 tJTA9QXWIgjZagphh7bCpHoia8d7O5iCdJn4ijbvJAL3oAWQRlK06MnRNJwwvlMUPZboyT+SL9KI Kvfz46g5Kv+cUz7JGOD8M2jYCj01oHqZ9y20w9CGYdFs4+2OsRpauso/eHt2C8JBoD+UaPov/yXd 68zYhXmjXIIVTvb6Lz4FH3367wJwlBVOdstR9g5HWdge4FZ0ssLJ9tc0ohDnrj3ntLJDViYRJMoO jfJaQQUxZKlAEsTIuiJlDBB9+ZsVQpmTpR2aazniV3eBendOFncbCYhVHovJX9YFMZjYAmqyE7rB VCKobUwPrsUP7m6KroMN6WUryZBuZOZ0MUok5WBIW7m4wJLbDR/VArgz/tyJXhZJ+TYe88ufL4uq A1ik7SOccqw44cNNo+ggETU2Ww7V245Pd07W+s0G+m2QpyAOd2gdh+XVyFkqNbdfp/7a36ZfeuWV HE0vdER92zjZHmF9NOwvvppBcz8km0QwTRzIvvk+xlyR+60CV7fSTTlZy2nfIidLO6nBSMFlHTfp vlE/khx6pDXdge4FQz0zTCWgKQDG3KSiPNBt2aoWTz5kl5xs3DKU80qu2tEjKQpAY9QIyu9zNMVj /mXHQB5VJZpKUWUsgCzqO+PfovypVPscsLmAGtSXigMJP/DtgN1BPMQlHbaH9JrQMpun6beXy1E0 fVPqqYvw9nIe8f4OwM2vwde/9gr8qz8b8G9f+yZsv7eF9wzPweGHDync4kdxuAPbdc8P0RXYrLam n4v8nIgh4sasMGMbVQ3cSGUSzFtJqRrdCROM/EZZ7OW2mfq+GX4xCHqCkdqqdn/ZP1GL5xpu9PW0 LtWj4Pq34MSTC13ZhGUcnJJaqyigJpO5SQGV/hYfaU5KKFQKCuX45gsdiPw79MhHOfbRjn7+GvmY wcsA5TwWlfiXlCFKyqCRWZx6+bXQY2tEv4zWt82awumSzs748ed0lR80+j8PEf7ZX/+PAP/Nb4ye 8xYe4beLJoh5WzlZz1l3ONkcyTFzssYSpJQgjc1408AapW5pQ2lxhYqbCx2VLZQEoFsxXjaONHDV HiU6MjjDCb/P+SeDMwS+4jHXaSf8cB1LpCVnATh4nyEqM3CmlFbDKQSGLsbBNALLhh/DIfZ8z6Jd x7P2Ndpur9HAicNw7RB+Y/mbHE2/uuOp0MA75G0aZZNOdutRtt38MNy8egrvwycYc2dwdSEc91Xo ViccEjlQbSNDoJctmiTybeIaQCor2iY7oOS0HfwJjslXK7pGtjbZqHSyaoTR+zVkvWyliU1txR2d LO56F2DR3g5QBCO2WZXqCKsRtXycNbUpklL+nTjRkkJxAfeCyAon/nknGkn1Qk8BtMjy4kl1p6ZB BY6iXC0E4WHlRRBjP4jMrxFzXUFpiEMjlOuWNv1j9NS1p+h/ZZD+ya8zSF88P/V7R7296eKLrgGt Ig7HnXaGBim8xpysdvyoFz2BbTFkbDbmpGx57C4nS7ucLFWc7EzL1qIxja2PaskijicRNG9OE7Xo WxXRmgWYCiwrssw5MuhYYRQqiossmRvmC7ZiV8q3Z3zfKb8m+eLbJh7zTziRKCrvS4WfC6sQ5Zbz 0kEaAFxwwVlU9VTk4gk7/iV9xwGUw8DQc9k6kPT1pXob6ORkoPb2M3SNQfoKg/Sze0D6joqo07cv +5WmEf7ha1+DJ/7vV+8+jTA0dHRFKOo1bbYdwcHC6HG1J2h00l/SWK6PowzPkEcti2ioCbBOrpmr XZoQGHbyUBxNHVSRk/q5fBXKET14FKzvTw40brGDtdWRR35MDjL+uzEVTR3mvQm4sZw0RUl0Qj/n oHybclS9PbWv52Ne8lmOpkFSBwEqQRflb4zU9/JKZpDKqp4lg3Qt/r8M0v72FQbpv6Xl8vfhnzFI //jFeyum3/FvJcpK5+tz2vm6HlOUjbD9lglillcJDrdP4nF7S6uLhrOsRmJYv5Zl30G6YUPn5A5H VVljLGJOtE6XKbcSJwv3wslCxcnS3TjZNBu2HDUOUvcr76elFFm9SWA8K1oXykZYzXOh1/67UVIa TfnjM42kEikbrvIDHfO5obdgH3MUBY24HFE5+kaNpBQG/hmcRGHsOOPsGY45kgpIOwapeP6edAPd XjBIT/9fBulvwK//OtA5i6XffUC9l87XqY6CX8erKS3g4mvbc1rw+IXhZJOOtrRpq4ILc9OA7Hdl rtW7WCYKJAfp4LcigN4wGDfSl1fZngH1hEF4akCFkwRSSwsog5Q/Z8c99tsooG+BAdr1nUfSnsRS ookbFBJ1oMXVK3T6NIP0pXsD6bsaqNMou69V+9H+vXD77A6u1gu8ggcwtCd4GhfYb44xHKzU6gsX QslGBuWgdLnW06itWl1oLFY2MXp0RfVqaCNWnGyccLI48uRa7qyXR4++5m8g2/IsOuNEyG16AgOq 5qlUfN5sDZO2S7WnrxEVNijgkwJJc1Mh+jWSnmIrt7GAtJGoKyAVsJJGUq6Zuthw0dRKTtrLS3aQ Cn9bgfQqg/RpBulLbwCkl0B9A2lBEcRwesZpwZbTAuWCRF+04irrVGguLsLqIcVgcxaypynKdmU1 3CBLC2RIUUAagkbYqU52xzxuZ0gRF5V6azwqjrnAKtMFpgUIOaKaK7ge/VpISbWPClY5+k+hvtCA SlJcOUD161q93UI7mJiaf1YMDNRwOsjAsRz38k++OQEpMEi/wSB97sV7f34ugXqfBDGLqOtwQ99w pMVO89cQF7YGhwSsZBqDJqi4mz9mmL+BIUWTGRb7olrhhYkFKFqBJFHJDue68TQBNS2y0xx1oxFU 89R4mqIrWiQ9I4mgQuQLM7BgYDciht5y+imROfS9KK/C8RAPFlw4bWLLIL3BIKUEUilvv8F/6XNv DHyXQH0DacENj7KPPf5JePUDlhaIQ8xjXHz1e4qvYSEjNKcypMilSpt0sr4Io2GgioWT5bTkuaUo uaqUIA8p4g5oR8XXSDOAxRYpSwaxXmlli+2NQVBul7YaVaWgknxViyVS4l4jbCMcadzwT1SgKrCX NmUq+EQ57ttGV/PEdhuXa6nuX+fafyBgkEICafKLeYPIuwTqBedkg04mjIcUoda17pndsu/3iBrK Nkn/FyXJdYRivKEEvYDUwKrdpY0zAAbShnPYVsTTDNCWtqGljmLscRHFKn+gg2Zo5OW1jkpBQfcq g/QZBql0mX/pTYP0Eqj3IS346IKLr9UdbK8Hfk4XcPTUgN3NBR5vZEhxuauThSEMGynERO8UtBWK lU42oA4uponWMqRIo/w1AXM0/gL1eiNIRz8AlcUbJpIO1R5bpE3OV/kWNZIOG9SPcYNii8s5LYOz E+EOQ50j6ZYjaTPAGuKVVYxwxL/uhMHZ8e1PcF700m8C/M5XCX71zYH0EqiPACerLrdafJEXXzAu vqKlAZIukJljtAm0aWIgJJ/ScTFFPunnbV3585xPTUN8QYUp/L4U7grcrXSx+P2OmkEXnYlPZFxF HXleBomkDM7HGaS3+fYag1R6995xeitguwTqBeZkdUhRm56l+OL/GJxGdUWXG1rhpAYYGagxzWGZ 3VC9FT3ZXyXfSNWikplJ9PxHyCy+RVcFLdn7rZlNKH8v2oSWemqEgmKQLhykXOdDwyBt316QXgL1 InOyMqQoNfik+NIGQhx0SJG8A4Vms68Ef3SxNUE1e5WAWhb3pan/SImm0uFH0kXMMlMm+SrZUJ+M Sm/5JdCDukNyJA0LaeNzEspH/pJBenh/QXoJ1IvMyYrLPMTd4kuGFKM4OU6KL+t8mRFHoMYZg9KV SraX0TdslQ0wQ9pTqyt4MPrGEh1HMWleEGMFEgXUwC+kXjQlse8jDYNF0mv8Z9xhkP7Q/QHpJVAf EU5235BiKr6C6VF1T4L6NQcdszYLIcw7YZPPVXrmzRnFvFGibYHmyj2YBFBHU6JaJfUkPuGNCsf5 83zci1Mkf3bJ/62bMwKRnTT8657iP/73GKTX316QXgL1EeNkp8UXI02s5LTzhZbTNgZMwW7U99Es ULS7j9V2wehFlS6sA3Xa1XFp7f0LFyoGvLoPSrwR+oihHWxv6SY2nJPG7TIKOI/6HxSQ/iaD9Ktf pfsBrEugPiqc7EzxxcEz9AxVhqXsf9JxPflPjaVk2rbR/Tky7x/crF+3l2HeIRXVglY5hagmQEOj WyDEW0+5sUG/RSwiRejccXG/jLFtRVV6wK+oH9BjDwCkl0B9lDjZfmFDilXxJT2lYSGlTxeWKojl Qkzm+hW00ogNephrt7QR/27xmjOxnxh2yJo8EQHITBiZc0rkHFT3PogRpGS6fOCL1Q4nogzU01Pq Dze0vcFfe62nDz4gkF4C9RHjZIPsBquKrwUfxosjPquPO5vhl810kg9gpztHpP6XgWcJj7hozIF+ GHyhn5oj2lDqoD6TMnIXqV2Ifaooa/jDnlZhEWnL+F6vKPbH1HOJ1W17wqc28PQDAuklUB/x4ksC 5VM/3IB1vm5xlOWouV0gtgzGVtR/Pcauxb7pUOoukgaYTOCCm/JLzoAicRacijRAiqIlNcI8tXzK nzJQr1yJ/faMNpsVHEl1L9/61JnkpfCgQHoJ1Ee8+EqdryVH2Rvtdc1ll2dHHBY7bB9fQy9WZR1h bHsVDMR2jW3182VuWfROvXBbYgVxQAbWk5bWHEFbB2hY9/Ta67fh6fe9h14LZ/SBf8Mg/daDA6m8 tZeQuJhv9+LaLaPgr0guu460WEVc3hg4lz2C43gb1+0WzriUWoovnIzeCT91GDUQqnxFXEx7gI1M OXFxhMtGrHO58rpJy3CNhtucsq4bun76Ojx2+BjdfKaHJ64e0sn/1sFLv/Gb8DvwVfrVBxjpLiPq I5wW3Bjlss4YeKQNV7ew3FzDtjuA149vY7MAuPoYwIE0WWUr3i2b/Lvdcdp7K9BqzXeuZBn0dRqa DYTb16i50sK3Vj+AD1/9KL3ytZvw3Ld+j6Podfp9eBE++5BeuJdvjzDF9cKzL+hiOog/BfA05Hz2 x+AZ2PLRfvP4GBdrgMP39nDnpOxtbDm8rsMR3PyOvk9PXLnC+D1TcP4Eg/MOvypeQQPoS1996YFH 0UugviOjrL/HN3/zz/8Gvvfv/h1+avK1t46P4W9eey1/vFos4EeeeWb0Na/z9f8dHNDf6f4OWNiU n/5Z///Lt8u3y7dz3/5/AQYAhGhTjmtqqQcAAAAASUVORK5CYII=" height="169" width="169"> </image> </g> </g><path d="M 232.33993,-14.02642 C 209.65121,-14.02642 191.25765,4.371924 191.25765,27.066536 C 191.25765,49.761148 209.65121,68.159492 232.33993,68.159492 C 255.02967,68.159492 273.42221,49.761148 273.42221,27.066536 C 273.42221,4.371924 255.02967,-14.02642 232.33993,-14.02642 z M 232.33993,43.503718 C 223.26383,43.503718 215.90702,36.144997 215.90702,27.066536 C 215.90702,17.989102 223.26383,10.629353 232.33993,10.629353 C 241.41603,10.629353 248.77284,17.989102 248.77284,27.066536 C 248.77284,36.144997 241.41603,43.503718 232.33993,43.503718 z" id="path48" style="opacity:0.5;fill:#ffffff" /><path d="M 232.33993,-14.02642 C 209.65121,-14.02642 191.25765,4.371924 191.25765,27.066536 C 191.25765,49.761148 209.65121,68.159492 232.33993,68.159492 C 255.02967,68.159492 273.42221,49.761148 273.42221,27.066536 C 273.42221,4.371924 255.02967,-14.02642 232.33993,-14.02642 z M 232.33993,51.722309 C 218.74786,51.722309 207.69056,40.661113 207.69056,27.066536 C 207.69056,13.471959 218.74786,2.410763 232.33993,2.410763 C 245.93098,2.410763 256.9893,13.470931 256.9893,27.066536 C 256.9893,40.66214 245.93098,51.722309 232.33993,51.722309 z" id="path57" style="opacity:0.5;fill:url(#linearGradient2857)" /><g id="g61" style="opacity:0.6" transform="matrix(1.027057,0,0,1.0273239,-6.4508226,-0.980434)"> <defs id="defs63"><path id="XMLID_9_" d="M 232.5,-92.699 C 166.226,-92.699 112.5,-38.973 112.5,27.301 C 112.5,93.575 166.226,147.301 232.5,147.301 C 298.774,147.301 352.5,93.574 352.5,27.301 C 352.5,-38.972 298.774,-92.699 232.5,-92.699 z M 232.5,70.741 C 208.509,70.741 189.06,51.292 189.06,27.301 C 189.06,3.311 208.509,-16.138 232.5,-16.138 C 256.492,-16.138 275.939,3.311 275.939,27.301 C 275.939,51.292 256.492,70.741 232.5,70.741 z" style="opacity:0.8" /></defs> <clipPath id="XMLID_17_"> <use xlink:href="#XMLID_9_" id="use67" x="0" y="0" width="263.043" height="263.04199" /> </clipPath> <g clip-path="url(#XMLID_17_)" id="g69"> <g id="g71" style="fill:url(#linearGradient3231);fill-opacity:1.0;opacity:0.9;filter:url(#filter5172)"> <path style="fill:url(#linearGradient3231);fill-opacity:1.0" d="M 109.96723,78.957075 L 232,27 L 200.05594,149.03173 L 109.96723,78.957075 z" id="polygon73" sodipodi:nodetypes="cccc" /> </g> <g id="g75" style="fill:url(#linearGradient2832);fill-opacity:1.0;opacity:0.80000000000000004;filter:url(#filter4199)"> <path style="fill:url(#linearGradient2832);fill-opacity:1.0" d="M 356.38585,-18.607418 L 232,27 L 273.59529,-93.378925 L 356.38585,-18.607418 z" id="polygon77" sodipodi:nodetypes="cccc" /> </g> </g> </g><path d="M 232.33993,2.410762 C 218.74786,2.410762 207.69056,13.470931 207.69056,27.066536 C 207.69056,40.66214 218.74786,51.722309 232.33993,51.722309 C 245.93098,51.722309 256.9893,40.661113 256.9893,27.066536 C 256.9893,13.471959 245.93098,2.410762 232.33993,2.410762 z" id="path59" style="fill:none;stroke:#d0d0d0;stroke-width:1.23301406;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path d="M 232.33993,2.410762 C 218.74786,2.410762 207.69056,13.470931 207.69056,27.066536 C 207.69056,40.66214 218.74786,51.722309 232.33993,51.722309 C 245.93098,51.722309 256.9893,40.661113 256.9893,27.066536 C 256.9893,13.471959 245.93098,2.410762 232.33993,2.410762 z M 232.33993,43.503718 C 223.26383,43.503718 215.90702,36.144997 215.90702,27.066536 C 215.90702,17.989102 223.26383,10.629353 232.33993,10.629353 C 241.41603,10.629353 248.77284,17.989102 248.77284,27.066536 C 248.77284,36.144997 241.41603,43.503718 232.33993,43.503718 z " id="path46" style="opacity:0.2;fill:#ffffff" /><path d="M 232.33993,2.410762 C 218.74786,2.410762 207.69056,13.470931 207.69056,27.066536 C 207.69056,40.66214 218.74786,51.722309 232.33993,51.722309 C 245.93098,51.722309 256.9893,40.661113 256.9893,27.066536 C 256.9893,13.471959 245.93098,2.410762 232.33993,2.410762 z M 232.33993,43.503718 C 223.26383,43.503718 215.90702,36.144997 215.90702,27.066536 C 215.90702,17.989102 223.26383,10.629353 232.33993,10.629353 C 241.41603,10.629353 248.77284,17.989102 248.77284,27.066536 C 248.77284,36.144997 241.41603,43.503718 232.33993,43.503718 z " id="path44" style="opacity:0.5;fill:url(#linearGradient2839);fill-opacity:1" /><path style="opacity:0.5;fill:none;stroke:url(#linearGradient3357);stroke-width:4.00125122;stroke-miterlimit:4;stroke-dasharray:none;filter:url(#filter3218)" d="M 212.5,43.301 C 203.663,43.301 196.5,36.138 196.5,27.301 C 196.5,18.465 203.663,11.301 212.5,11.301 C 221.337,11.301 228.5,18.465 228.5,27.301 C 228.5,36.138 221.337,43.301 212.5,43.301 z " id="path3174" clip-path="url(#clipPath4191)" transform="matrix(1.027057,0,0,1.0273239,14.090318,-0.9804337)" /><path d="M 232.33993,-22.245011 C 205.15681,-22.245011 183.04119,-0.123646 183.04119,27.066536 C 183.04119,54.256717 205.15681,76.378083 232.33993,76.378083 C 259.52305,76.378083 281.63867,54.256717 281.63867,27.066536 C 281.63867,-0.123646 259.52305,-22.245011 232.33993,-22.245011 z M 232.33993,68.159492 C 209.65121,68.159492 191.25765,49.761148 191.25765,27.066536 C 191.25765,4.371924 209.65121,-14.02642 232.33993,-14.02642 C 255.02967,-14.02642 273.42221,4.371924 273.42221,27.066536 C 273.42221,49.761148 255.02967,68.159492 232.33993,68.159492 z" id="path35" style="opacity:0.1;fill:#323232;fill-opacity:1" /><path style="opacity:0.5;fill:#8e79a5;fill-opacity:1" d="M 232.3945,-96.257406 C 164.29718,-96.257406 109.09309,-41.053313 109.09309,27.043998 C 109.09309,95.141304 164.29718,150.34541 232.3945,150.34541 C 300.49181,150.34541 355.6959,95.140279 355.6959,27.043998 C 355.6959,-41.052287 300.49181,-96.257406 232.3945,-96.257406 z M 232.3945,-94.202383 C 299.35729,-94.202383 353.64088,-39.918792 353.64088,27.043998 C 353.64088,94.005727 299.35729,148.29038 232.3945,148.29038 C 165.43171,148.29038 111.14812,94.005731 111.14812,27.043998 C 111.14812,-39.918794 165.43171,-94.202383 232.3945,-94.202383 z " id="path2259" /></svg>�������MP3Diags-1.0.12.079/src/images/test.svg�������������������������������������������������������������0000644�0001750�0000144�00000036005�11074465356�016237� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:ns="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="430" height="430" id="svg2" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docname="test.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images"> <defs id="defs4"> <filter inkscape:collect="always" x="-0.143268" width="1.286536" y="-0.072184406" height="1.1443688" id="filter5125"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.91024" id="feGaussianBlur5127" /> </filter> <filter id="AI_Sfocatura_2"> <feGaussianBlur stdDeviation="2" id="feGaussianBlur3099" /> </filter> <path id="XMLID_10_" d="M 27.6,69.6 C 27.6,92.759 46.441,111.6 69.6,111.6 C 92.759,111.6 111.6,92.759 111.6,69.6 C 111.6,46.441 92.759,27.6 69.6,27.6 C 46.441,27.6 27.6,46.441 27.6,69.6 z" /> <clipPath id="XMLID_6_"> <use height="139" width="139" y="0" x="0" id="use3143" xlink:href="#XMLID_10_" /> </clipPath> <linearGradient id="circle16776_1_" gradientUnits="userSpaceOnUse" x1="135.5601" y1="417.66461" x2="161.87621" y2="417.66461" gradientTransform="matrix(0,1.7280523,1.7280523,0,-650.07477,-218.71693)"> <stop offset="0" style="stop-color:#FFFFFF" id="stop3132" /> <stop offset="1" style="stop-color:#ffffff;stop-opacity:0;" id="stop3134" /> </linearGradient> <filter inkscape:collect="always" x="-0.132641" width="1.265282" y="-0.34752154" height="1.6950431" id="filter3547"> <feGaussianBlur inkscape:collect="always" stdDeviation="2.7512044" id="feGaussianBlur3549" /> </filter> <linearGradient id="XMLID_14_" gradientUnits="userSpaceOnUse" x1="27.6001" y1="69.600098" x2="111.6001" y2="69.600098" gradientTransform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)"> <stop offset="0" style="stop-color:#2A94EC" id="stop3122" /> <stop offset="1" style="stop-color:#0057AE" id="stop3124" /> </linearGradient> <radialGradient id="XMLID_13_" cx="69.600098" cy="69.600098" r="58" gradientUnits="userSpaceOnUse"> <stop offset="0.6154" style="stop-color:#EEEEEE" id="stop3113" /> <stop offset="0.8225" style="stop-color:#DDDDDD" id="stop3115" /> <stop offset="1" style="stop-color:#FFFFFF" id="stop3117" /> </radialGradient> <radialGradient id="XMLID_12_" cx="69.600098" cy="69.576698" r="58" gradientTransform="matrix(1,0,0,-0.1823,0,134.8566)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#000000" id="stop3102" /> <stop offset="1" style="stop-color:#000000;stop-opacity:0;" id="stop3104" /> </radialGradient> <filter inkscape:collect="always" id="filter5097"> <feGaussianBlur inkscape:collect="always" stdDeviation="2.32" id="feGaussianBlur5099" /> </filter> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 526.18109 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="744.09448 : 526.18109 : 1" inkscape:persp3d-origin="372.04724 : 350.78739 : 1" id="perspective10" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="radialGradient3478" gradientUnits="userSpaceOnUse" cx="69.600098" cy="69.600098" r="58" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.959798" inkscape:cx="72.458881" inkscape:cy="93.803679" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33"> <inkscape:grid type="xygrid" id="grid2383" visible="true" enabled="true" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <ns:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </ns:Work> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-250,-427.42468)"> <g id="g2221" transform="matrix(2.375,0,0,2.3749997,-343.75,-755.92306)"> <path transform="translate(0,52.205354)" d="M 290 472.36218 A 20 20 0 1 1 250,472.36218 A 20 20 0 1 1 290 472.36218 z" sodipodi:ry="20" sodipodi:rx="20" sodipodi:cy="472.36218" sodipodi:cx="270" id="path2385" style="fill:#000000" sodipodi:type="arc" /> <path transform="translate(0,12.205354)" d="M 285 512.36218 A 15 15 0 1 1 255,512.36218 A 15 15 0 1 1 285 512.36218 z" sodipodi:ry="15" sodipodi:rx="15" sodipodi:cy="512.36218" sodipodi:cx="270" id="path2387" style="fill:#e6e6e6" sodipodi:type="arc" /> </g> <text xml:space="preserve" style="font-size:144px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" x="371.625" y="542.42468" id="text2389"><tspan sodipodi:role="line" id="tspan2391" x="371.625" y="542.42468">Thin</tspan></text> <text id="text2397" y="660.50281" x="370.6875" style="font-size:144px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" xml:space="preserve"><tspan y="660.50281" x="370.6875" id="tspan2399" sodipodi:role="line">Thllk</tspan></text> <g id="g2225" transform="matrix(2.375,0,0,2.3750005,-343.75,-892.17352)"> <path transform="translate(0,162.20535)" sodipodi:type="arc" style="fill:#000000" id="path2393" sodipodi:cx="270" sodipodi:cy="472.36218" sodipodi:rx="20" sodipodi:ry="20" d="M 290 472.36218 A 20 20 0 1 1 250,472.36218 A 20 20 0 1 1 290 472.36218 z" /> <path sodipodi:type="arc" style="fill:#e6e6e6" id="path2395" sodipodi:cx="270" sodipodi:cy="512.36218" sodipodi:rx="15" sodipodi:ry="15" d="M 285 512.36218 A 15 15 0 1 1 255,512.36218 A 15 15 0 1 1 285 512.36218 z" transform="translate(0,122.20535)" /> <path transform="translate(70,12.205354)" d="M 212.85714 622.36218 A 12.857143 12.857143 0 1 1 187.14286,622.36218 A 12.857143 12.857143 0 1 1 212.85714 622.36218 z" sodipodi:ry="12.857143" sodipodi:rx="12.857143" sodipodi:cy="622.36218" sodipodi:cx="200" id="path2401" style="fill:#4d4d4d" sodipodi:type="arc" /> </g> <rect style="fill:#000000" id="rect2405" width="94.922791" height="94.999962" x="250.07721" y="742.42468" /> <rect style="fill:#e6e6e6;fill-opacity:1" id="rect2407" width="71.192093" height="71.249969" x="261.94257" y="754.29968" /> <path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.85104251px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 272.0696,796.88319 L 291.04984,813.35985 L 323.51265,777.28408 L 315.02516,768.67174 L 291.15518,802.74365 L 277.59862,789.08747 L 272.0696,796.88319 z " id="path2415" sodipodi:nodetypes="ccccccc" /> <text id="text3194" y="840.50281" x="372.91406" style="font-size:144px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" xml:space="preserve"><tspan y="840.50281" x="372.91406" id="tspan3196" sodipodi:role="line">Now</tspan></text> <g transform="matrix(2.1153417,0,0,2.1153417,377.43597,518.85215)" style="overflow:visible" id="g3410"> <circle transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)" cx="69.599998" cy="69.599998" r="58" id="circle5091" style="opacity:0.7;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter5097)" sodipodi:cx="69.599998" sodipodi:cy="69.599998" sodipodi:rx="58" sodipodi:ry="58" /> <ellipse transform="translate(-9.9998474e-2,1.9102535)" sodipodi:ry="10.573" sodipodi:rx="58" sodipodi:cy="122.173" sodipodi:cx="69.599998" style="opacity:0.6;fill:url(#XMLID_12_)" id="ellipse3106" ry="10.573" rx="58" cy="122.173" cx="69.599998" /> <circle transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)" sodipodi:ry="58" sodipodi:rx="58" sodipodi:cy="69.599998" sodipodi:cx="69.599998" style="fill:url(#radialGradient3478)" id="circle3119" r="58" cy="69.599998" cx="69.599998" /> <path style="fill:url(#XMLID_14_)" id="path3126" d="M 26.062502,67.328127 C 26.062502,92.477355 46.522651,112.9375 71.671877,112.9375 C 96.821104,112.9375 117.28125,92.477355 117.28125,67.328127 C 117.28125,42.178901 96.821104,21.718753 71.671877,21.718753 C 46.522651,21.718753 26.062502,42.178901 26.062502,67.328127 z" /> <g transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)" style="opacity:0.3;filter:url(#filter3547)" enable-background="new " cx="343.99899" ry="36" rx="36" cy="92" id="circle22111"> <path style="fill:#a8dde0" id="path3129" d="M 77.041,104.759 C 63.767,106.115 50.122,103.11 46.565,98.042 C 43.007,92.976 50.885,87.768 64.16,86.41 C 77.434,85.054 91.079,88.058 94.637,93.126 C 98.193,98.194 90.315,103.401 77.041,104.759 z" /> </g> <path style="opacity:0.8;fill:url(#circle16776_1_)" d="M 71.671877,24.06655 C 50.288682,24.06655 32.41958,38.77123 28.113838,58.349597 C 36.698174,66.142284 52.986151,54.358777 71.671877,54.358777 C 90.357604,54.358777 106.64666,66.142284 115.22991,58.349597 C 110.92417,38.77123 93.056158,24.06655 71.671877,24.06655 z" enable-background="new " id="circle16776" /> <g transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)" id="g3137"> <defs id="defs3139"> <path d="M 27.6,69.6 C 27.6,92.759 46.441,111.6 69.6,111.6 C 92.759,111.6 111.6,92.759 111.6,69.6 C 111.6,46.441 92.759,27.6 69.6,27.6 C 46.441,27.6 27.6,46.441 27.6,69.6 z" id="path59" /> </defs> <clipPath id="clipPath3466"> <use height="139" width="139" y="0" x="0" id="use3468" xlink:href="#XMLID_10_" /> </clipPath> <g style="filter:url(#AI_Sfocatura_2)" id="g3145" clip-path="url(#XMLID_6_)"> <path style="fill:none;stroke:#00316e;stroke-width:2" id="path3147" d="M 27.6,69.6 C 27.6,92.759 46.441,111.6 69.6,111.6 C 92.759,111.6 111.6,92.759 111.6,69.6 C 111.6,46.441 92.759,27.6 69.6,27.6 C 46.441,27.6 27.6,46.441 27.6,69.6 z" /> </g> </g> <g style="fill:#00316e;filter:url(#filter5125)" id="g5119" transform="matrix(1.0859375,0,0,1.1113796,-3.201342,-9.3177223)"> <path id="path5121" d="M 63.37,80.089 L 63.192,77.746 C 63.012,73.148 64.44,68.462 68.451,63.684 C 71.304,60.26 73.62,57.286 73.62,54.221 C 73.62,51.157 71.571,48.994 67.202,48.903 C 64.173,48.903 60.696,49.895 58.289,51.517 L 55.348,41.784 C 58.556,39.89 63.815,38.088 70.233,38.088 C 81.91,38.088 87.348,44.668 87.348,52.058 C 87.348,58.997 83.069,63.415 79.681,67.289 C 76.472,70.894 75.046,74.41 75.135,78.466 L 75.135,80.088 L 63.37,80.088 L 63.37,80.089 z" style="fill:#00316e" /> <circle id="circle5123" r="8" cy="93.599998" cx="69.599998" sodipodi:cx="69.599998" sodipodi:cy="93.599998" sodipodi:rx="8" sodipodi:ry="8" style="fill:#00316e" /> </g> <g transform="matrix(1.0859375,0,0,1.0859375,-3.201342,-8.2531233)" id="g5101"> <path style="fill:#ffffff" d="M 63.37,80.089 L 63.192,77.746 C 63.012,73.148 64.44,68.462 68.451,63.684 C 71.304,60.26 73.62,57.286 73.62,54.221 C 73.62,51.157 71.571,48.994 67.202,48.903 C 64.173,48.903 60.696,49.895 58.289,51.517 L 55.348,41.784 C 58.556,39.89 63.815,38.088 70.233,38.088 C 81.91,38.088 87.348,44.668 87.348,52.058 C 87.348,58.997 83.069,63.415 79.681,67.289 C 76.472,70.894 75.046,74.41 75.135,78.466 L 75.135,80.088 L 63.37,80.088 L 63.37,80.089 z" id="path3157" /> <circle style="fill:#ffffff" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="93.599998" sodipodi:cx="69.599998" cx="69.599998" cy="93.599998" r="8" id="circle3159" /> </g> </g> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/COPYING-LGPL.V3.txt��������������������������������������������������0000644�0001750�0000144�00000016454�11107243736�017432� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, “this License” refers to version 3 of the GNU Lesser General Public License, and the “GNU GPL” refers to version 3 of the GNU General Public License. “The Library” refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An “Application” is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A “Combined Work” is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the “Linked Version”. The “Minimal Corresponding Source” for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The “Corresponding Application Code” for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: * a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or * b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: * a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. * b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: * a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. * b) Accompany the Combined Work with a copy of the GNU GPL and this license document. * c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. * d) Do one of the following: o 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. o 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. * e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: * a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. * b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/save_notes.svg�������������������������������������������������������0000644�0001750�0000144�00000125476�11102272707�017425� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="162" height="162" id="svg1307" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docname="save_notes.svg" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <metadata id="metadata170"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <sodipodi:namedview inkscape:window-height="950" inkscape:window-width="1179" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" inkscape:zoom="2.6851852" inkscape:cx="81" inkscape:cy="81" inkscape:window-x="413" inkscape:window-y="172" inkscape:current-layer="svg1307" /> <defs id="defs1309"> <linearGradient id="linearGradient2497"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop2499" /> <stop style="stop-color:#ececec;stop-opacity:1" offset="0.5" id="stop11148" /> <stop style="stop-color:#c1c1c1;stop-opacity:1" offset="1" id="stop2501" /> </linearGradient> <radialGradient cx="-519.35938" cy="1724.4219" r="499.35941" fx="-519.35938" fy="1724.4219" id="radialGradient22425" xlink:href="#linearGradient2497" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.2631778e-2,0,0,9.760431e-2,95.425676,-122.0552)" /> <linearGradient x1="605.17242" y1="3835.6428" x2="-1062.9232" y2="1799.6183" id="linearGradient22421" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.266449e-2,95.46583,-35.606353)" /> <linearGradient x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" id="linearGradient22417" xlink:href="#linearGradient12049" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.494916e-2,95.46583,-43.1294)" /> <linearGradient id="linearGradient12049"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop12051" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop12053" /> </linearGradient> <linearGradient x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" id="linearGradient22415" xlink:href="#linearGradient12049" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.964922,0,0,0.941137,2.09495,7.906447)" /> <inkscape:perspective id="perspective177" inkscape:persp3d-origin="64 : 42.666667 : 1" inkscape:vp_z="128 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 64 : 1" sodipodi:type="inkscape:persp3d" /> <linearGradient id="linearGradient3609"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop3611" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop3613" /> </linearGradient> <linearGradient id="linearGradient2019"> <stop style="stop-color:#fff823;stop-opacity:0.84313726" offset="0" id="stop2912" /> <stop style="stop-color:#ffff02;stop-opacity:0" offset="1" id="stop2023" /> </linearGradient> <linearGradient id="linearGradient2891"> <stop style="stop-color:#3a3a3a;stop-opacity:1" offset="0" id="stop2893" /> <stop style="stop-color:#3a3a3a;stop-opacity:0" offset="1" id="stop2895" /> </linearGradient> <linearGradient id="linearGradient2881"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop2883" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop2885" /> </linearGradient> <linearGradient id="linearGradient4318"> <stop style="stop-color:#fffaa8;stop-opacity:1" offset="0" id="stop4320" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop4322" /> </linearGradient> <linearGradient id="linearGradient4309"> <stop style="stop-color:#fff727;stop-opacity:0.73333335" offset="0" id="stop4311" /> <stop style="stop-color:#ffb266;stop-opacity:0" offset="1" id="stop4313" /> </linearGradient> <linearGradient id="linearGradient4301"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop4303" /> <stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop4305" /> </linearGradient> <linearGradient id="linearGradient4246"> <stop style="stop-color:#3a3a3a;stop-opacity:0.46975088" offset="0" id="stop4248" /> <stop style="stop-color:#3a3a3a;stop-opacity:0" offset="1" id="stop4250" /> </linearGradient> <linearGradient id="linearGradient4089"> <stop style="stop-color:#3a3a3a;stop-opacity:1" offset="0" id="stop4091" /> <stop style="stop-color:#3a3a3a;stop-opacity:0" offset="1" id="stop4093" /> </linearGradient> <linearGradient id="linearGradient6250"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop6252" /> <stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop6254" /> </linearGradient> <linearGradient id="linearGradient5914"> <stop style="stop-color:#0060c8;stop-opacity:1" offset="0" id="stop5916" /> <stop style="stop-color:#003772;stop-opacity:0" offset="1" id="stop5918" /> </linearGradient> <linearGradient id="linearGradient5904"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop5906" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop5908" /> </linearGradient> <linearGradient id="linearGradient4124"> <stop style="stop-color:#002145;stop-opacity:1" offset="0" id="stop4126" /> <stop style="stop-color:#001d3d;stop-opacity:0" offset="1" id="stop4128" /> </linearGradient> <linearGradient id="linearGradient4094"> <stop style="stop-color:#4da3ff;stop-opacity:1" offset="0" id="stop4096" /> <stop style="stop-color:#004895;stop-opacity:1" offset="1" id="stop4098" /> </linearGradient> <linearGradient id="linearGradient4086"> <stop style="stop-color:#d7ebff;stop-opacity:1" offset="0" id="stop4088" /> <stop style="stop-color:#b9dbff;stop-opacity:0" offset="1" id="stop4090" /> </linearGradient> <linearGradient id="linearGradient3189"> <stop style="stop-color:#003d7f;stop-opacity:1" offset="0" id="stop3191" /> <stop style="stop-color:#004da0;stop-opacity:1" offset="0.81415927" id="stop3197" /> <stop style="stop-color:#00438a;stop-opacity:0" offset="1" id="stop3193" /> </linearGradient> <linearGradient id="linearGradient2334"> <stop style="stop-color:#a5a5a5;stop-opacity:1" offset="0" id="stop6098" /> <stop style="stop-color:#dfe1e1;stop-opacity:1" offset="0.07692308" id="stop2346" /> <stop style="stop-color:#e2dcdc;stop-opacity:1" offset="0.5" id="stop2342" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0.78201604" id="stop2348" /> <stop style="stop-color:#dfd9df;stop-opacity:1" offset="0.9005897" id="stop2344" /> <stop style="stop-color:#d5d5d5;stop-opacity:1" offset="1" id="stop6104" /> </linearGradient> <linearGradient id="linearGradient3291"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop3293" /> <stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop3295" /> </linearGradient> <linearGradient x1="-77.403809" y1="22.222563" x2="-62.398071" y2="131.117" id="linearGradient3151" xlink:href="#linearGradient6250" gradientUnits="userSpaceOnUse" /> <linearGradient x1="-77.956337" y1="159.10574" x2="-72.261574" y2="157.58188" id="linearGradient3153" xlink:href="#linearGradient6250" gradientUnits="userSpaceOnUse" /> <linearGradient x1="-59.123386" y1="163.06093" x2="-63.657074" y2="161.16936" id="linearGradient3155" xlink:href="#linearGradient6250" gradientUnits="userSpaceOnUse" /> <linearGradient x1="-63.233101" y1="162.73038" x2="-69.858452" y2="162.15964" id="linearGradient3157" xlink:href="#linearGradient6250" gradientUnits="userSpaceOnUse" /> <radialGradient cx="60.109371" cy="72.828125" r="49.681286" fx="60.109371" fy="72.828125" id="radialGradient3159" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.65927,-7.373712e-3,3.949364e-3,0.353107,17.53952,43.06677)" /> <radialGradient cx="46.320789" cy="97.558548" r="47.040867" fx="20.890965" fy="91.120483" id="radialGradient3161" xlink:href="#linearGradient4086" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.435167,0.137407,-0.138893,0.439871,44.87405,27.01182)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="67.175148" fy="62.592621" id="radialGradient3163" xlink:href="#linearGradient3189" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <linearGradient x1="49.324944" y1="32.59375" x2="94.125" y2="37.34375" id="linearGradient3165" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.65927,-7.373712e-3,7.373712e-3,0.65927,17.29013,20.7694)" spreadMethod="reflect" /> <linearGradient x1="61" y1="-8.000001" x2="52.763168" y2="22.740273" id="linearGradient3167" xlink:href="#linearGradient4124" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.567257,-0.336021,0.336021,0.567257,11.91678,43.57707)" /> <radialGradient cx="60.109371" cy="72.828125" r="49.681286" fx="60.109371" fy="72.828125" id="radialGradient3169" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.48006,-5.369582e-3,2.846636e-3,0.254539,27.75761,-6.596686)" /> <radialGradient cx="33.647404" cy="105.95415" r="47.040867" fx="27.016188" fy="85.312073" id="radialGradient3171" xlink:href="#linearGradient4086" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.17061,0.258566,-0.382999,0.247716,82.44465,-16.18971)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="67.175148" fy="62.592621" id="radialGradient3173" xlink:href="#linearGradient3189" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="53.426815" fy="78.751389" id="radialGradient3177" xlink:href="#linearGradient5914" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <linearGradient x1="79.515709" y1="38.188641" x2="59.352558" y2="38.829636" id="linearGradient3185" xlink:href="#linearGradient3291" gradientUnits="userSpaceOnUse" /> <radialGradient cx="26.689753" cy="54.472202" r="35.40966" fx="10.492155" fy="51.843987" id="radialGradient3187" xlink:href="#linearGradient5904" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.277621,4.035798e-3,-1.584782e-2,1.089994,42.19747,11.66854)" /> <linearGradient x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" id="linearGradient4082" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.986412,0,0,0.924353,-0.347729,4.01022)" /> <linearGradient id="linearGradient3058"> <stop style="stop-color:#9a7600;stop-opacity:1" offset="0" id="stop3060" /> <stop style="stop-color:#e3ad00;stop-opacity:1" offset="0.09292036" id="stop3066" /> <stop style="stop-color:#ffcd2c;stop-opacity:1" offset="0.5043171" id="stop3070" /> <stop style="stop-color:#e3ad00;stop-opacity:1" offset="0.91571385" id="stop3068" /> <stop style="stop-color:#b98d00;stop-opacity:1" offset="1" id="stop3062" /> </linearGradient> <linearGradient x1="124.45079" y1="153.10228" x2="40.305077" y2="51.042213" id="linearGradient4252" xlink:href="#linearGradient4246" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.986412,0,0,1.114461,-0.696478,-26.31741)" /> <radialGradient cx="69.647743" cy="114.19905" r="64.071327" fx="50.822227" fy="89.233253" id="radialGradient4258" xlink:href="#linearGradient4309" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.782917,-0.935261,8.371703e-2,1.343107,-56.85403,5.481532)" /> <radialGradient cx="68.972214" cy="74.718201" r="47.781246" fx="68.972214" fy="74.718201" id="radialGradient4283" xlink:href="#linearGradient4318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.301238,-9.329686e-2,1.427156e-2,0.254081,-23.47707,36.87536)" /> <linearGradient x1="79.825981" y1="98.206459" x2="114.61522" y2="65.502769" id="linearGradient4295" xlink:href="#linearGradient4089" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.690325,0,0,0.779938,34.7461,-1.375054)" /> <linearGradient x1="79.825981" y1="98.206459" x2="114.61522" y2="65.502769" id="linearGradient4297" xlink:href="#linearGradient4089" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.690325,0,0,0.779938,34.7461,-1.375054)" /> <radialGradient cx="92.454208" cy="73.55278" r="3.3587573" fx="91.043648" fy="73.809258" id="radialGradient4307" xlink:href="#linearGradient4301" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.736842,0,19.35599)" /> <radialGradient cx="92.159912" cy="132.51294" r="63.022152" fx="92.159912" fy="132.51294" id="radialGradient2887" xlink:href="#linearGradient2881" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.121997,-0.207569,5.159571e-2,0.527467,-110.2403,57.28961)" /> <linearGradient x1="113" y1="140.25" x2="65.43679" y2="64" id="linearGradient2897" xlink:href="#linearGradient2891" gradientUnits="userSpaceOnUse" /> <linearGradient x1="124.45079" y1="153.10228" x2="40.305077" y2="51.042213" id="linearGradient2930" xlink:href="#linearGradient4246" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.986412,0,0,1.114461,-0.696478,-26.31741)" /> <linearGradient x1="113" y1="140.25" x2="65.43679" y2="64" id="linearGradient2932" xlink:href="#linearGradient2891" gradientUnits="userSpaceOnUse" /> <linearGradient x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" id="linearGradient2934" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.986412,0,0,0.924353,-0.347729,4.01022)" /> <radialGradient cx="69.647743" cy="114.19905" r="64.071327" fx="50.822227" fy="89.233253" id="radialGradient2936" xlink:href="#linearGradient4309" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.782917,-0.935261,8.371703e-2,1.343107,-56.85403,5.481532)" /> <radialGradient cx="68.972214" cy="74.718201" r="47.781246" fx="68.972214" fy="74.718201" id="radialGradient2938" xlink:href="#linearGradient4318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.301238,-9.329686e-2,1.427156e-2,0.254081,-23.47707,36.87536)" /> <linearGradient x1="79.825981" y1="98.206459" x2="114.61522" y2="65.502769" id="linearGradient2942" xlink:href="#linearGradient4089" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.690325,0,0,0.779938,34.7461,-1.375054)" /> <radialGradient cx="92.454208" cy="73.55278" r="3.3587573" fx="91.043648" fy="73.809258" id="radialGradient2944" xlink:href="#linearGradient4301" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.736842,0,19.35599)" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2025" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2916" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="translate(-52.50268,-17.50089)" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2920" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="translate(-52.30268,-18.50089)" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2923" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1,180.22,-18.50089)" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2926" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1,180.42,-17.50089)" /> <linearGradient x1="98.177643" y1="113.32587" x2="89.072945" y2="102.22624" id="linearGradient2929" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1.004372,131.9173,14.846852)" /> <radialGradient cx="68.972214" cy="74.718201" r="47.781246" fx="68.972214" fy="74.718201" id="radialGradient2954" xlink:href="#linearGradient4318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.301238,-9.370473e-2,-1.427156e-2,0.255192,155.3944,51.88342)" /> <radialGradient cx="77.520203" cy="116.66548" r="64.071327" fx="58.694687" fy="91.699684" id="radialGradient2957" xlink:href="#linearGradient4309" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.5775266,-1.1711111,0.1996751,1.4444656,211.75095,25.589505)" /> <linearGradient x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" id="linearGradient2960" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.986412,0,0,0.928394,132.265,18.874603)" /> <linearGradient x1="173.96887" y1="100.2915" x2="57.130394" y2="27.459507" id="linearGradient2973" xlink:href="#linearGradient5904" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.004372,-48.50758,32.43503)" /> <radialGradient cx="92.454208" cy="73.55278" r="3.3587573" fx="91.043648" fy="73.809258" id="radialGradient2975" xlink:href="#linearGradient4301" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.736842,0,19.35599)" /> <filter id="filter3305"> <feGaussianBlur id="feGaussianBlur3307" stdDeviation="1.0460516" inkscape:collect="always" /> </filter> <filter id="filter3597" height="1.1002953" y="-0.05014763" width="1.3017726" x="-0.15088631"> <feGaussianBlur id="feGaussianBlur3599" stdDeviation="0.57059479" inkscape:collect="always" /> </filter> <clipPath id="clipPath3603"> <path d="M 59.441817,-44.032495 L 54.595834,-43.248559 L 56.772878,-26.089281 C 56.857443,-23.205582 58.751574,-21.03054 60.185435,-18.681576 C 61.175137,-21.90528 62.020956,-23.703942 61.607219,-26.964977 L 59.441817,-44.032495 z " style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.45699999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1;filter:url(#filter3597)" id="path3605" /> </clipPath> <radialGradient cx="105.60236" cy="61.783173" r="19.974998" fx="106.32523" fy="51.090271" id="radialGradient3615" xlink:href="#linearGradient3609" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8124666,-0.5830077,1.3642054,1.9011265,-62.61429,20.412027)" /> <filter id="filter3637"> <feGaussianBlur id="feGaussianBlur3639" stdDeviation="0.26548265" inkscape:collect="always" /> </filter> <linearGradient x1="-48.32362" y1="102.86192" x2="-81.932449" y2="102.84682" id="linearGradient3656" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.1828673,2.958248e-2,2.3283892e-2,0.1835217,18.438484,-50.14049)" /> <radialGradient cx="60.109371" cy="72.828125" r="49.681286" fx="60.109371" fy="72.828125" id="radialGradient3658" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2825052,3.4284058e-2,1.8362653e-2,0.1513106,46.77243,-59.710362)" /> <radialGradient cx="46.320789" cy="97.558548" r="47.040867" fx="20.890965" fy="91.120483" id="radialGradient3660" xlink:href="#linearGradient4086" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.1783948,8.3505872e-2,8.4408831e-2,0.1803231,34.164873,-65.027613)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="67.175148" fy="62.592621" id="radialGradient3662" xlink:href="#linearGradient3189" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <linearGradient x1="49.324944" y1="32.59375" x2="94.125" y2="37.34375" id="linearGradient3664" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2825052,3.4284058e-2,3.4284058e-2,0.2825052,45.612899,-69.265056)" spreadMethod="reflect" /> <linearGradient x1="79.515709" y1="38.188641" x2="59.352558" y2="38.829636" id="linearGradient3666" xlink:href="#linearGradient3291" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.427877,5.678872e-2,5.678872e-2,0.427877,51.83148,-79.133689)" /> <linearGradient x1="61" y1="-8.000001" x2="52.763168" y2="22.740273" id="linearGradient3668" xlink:href="#linearGradient4124" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2617984,-0.1115619,-0.1115619,0.2617984,49.20725,-59.811324)" /> <radialGradient cx="60.109371" cy="72.828125" r="49.681286" fx="60.109371" fy="72.828125" id="radialGradient3670" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2057116,2.4964472e-2,1.3236934e-2,0.109073,39.58002,-80.37994)" /> <radialGradient cx="33.647404" cy="105.95415" r="47.040867" fx="27.016188" fy="85.312073" id="radialGradient3672" xlink:href="#linearGradient4086" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-5.8316463e-2,0.1203232,0.1779439,8.4241956e-2,15.635918,-81.378967)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="67.175148" fy="62.592621" id="radialGradient3674" xlink:href="#linearGradient3189" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <radialGradient cx="26.689753" cy="54.472202" r="35.40966" fx="10.492155" fy="51.843987" id="radialGradient3676" xlink:href="#linearGradient5904" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.1166721,2.7380935e-2,0.1258115,0.5360856,31.276382,-75.854424)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="53.426815" fy="78.751389" id="radialGradient3678" xlink:href="#linearGradient5914" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3609" id="radialGradient2332" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8124666,-0.5830077,1.3642054,1.9011265,-64.04421,-14.619294)" cx="105.60236" cy="61.783173" fx="106.32523" fy="51.090271" r="19.974998" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5904" id="linearGradient2335" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.004372,-49.9375,-2.596291)" x1="173.96887" y1="100.2915" x2="57.130394" y2="27.459507" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2019" id="linearGradient2338" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1.004372,130.48738,-20.184469)" x1="98.177643" y1="113.32587" x2="89.072945" y2="102.22624" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4318" id="radialGradient2341" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.301238,-9.370473e-2,-1.427156e-2,0.255192,153.96448,16.852099)" cx="68.972214" cy="74.718201" fx="68.972214" fy="74.718201" r="47.781246" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4309" id="radialGradient2344" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.5775266,-1.1711111,0.1996751,1.4444656,210.32103,-9.441816)" cx="77.520203" cy="116.66548" fx="58.694687" fy="91.699684" r="64.071327" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3058" id="linearGradient2347" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.986412,0,0,0.928394,130.83508,-16.156718)" x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient12049" id="linearGradient2366" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.964922,0,0,0.941137,2.09495,7.906447)" x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient12049" id="linearGradient2368" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.494916e-2,95.46583,-43.1294)" x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2334" id="linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.266449e-2,95.46583,-35.606353)" x1="605.17242" y1="3835.6428" x2="-1062.9232" y2="1799.6183" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2497" id="radialGradient2372" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.2631778e-2,0,0,9.760431e-2,95.425676,-122.0552)" cx="-519.35938" cy="1724.4219" fx="-519.35938" fy="1724.4219" r="499.35941" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3058" id="linearGradient2383" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.986412,0,0,0.928394,130.83508,-16.156718)" x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4309" id="radialGradient2385" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.5775266,-1.1711111,0.1996751,1.4444656,210.32103,-9.441816)" cx="77.520203" cy="116.66548" fx="58.694687" fy="91.699684" r="64.071327" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4318" id="radialGradient2387" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.301238,-9.370473e-2,-1.427156e-2,0.255192,153.96448,16.852099)" cx="68.972214" cy="74.718201" fx="68.972214" fy="74.718201" r="47.781246" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2019" id="linearGradient2389" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1.004372,130.48738,-20.184469)" x1="98.177643" y1="113.32587" x2="89.072945" y2="102.22624" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5904" id="linearGradient2391" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.004372,-49.9375,-2.596291)" x1="173.96887" y1="100.2915" x2="57.130394" y2="27.459507" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3609" id="radialGradient2393" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8124666,-0.5830077,1.3642054,1.9011265,-64.04421,-14.619294)" cx="105.60236" cy="61.783173" fx="106.32523" fy="51.090271" r="19.974998" /> </defs> <path id="path2276" style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 49.462879,-31.750025 L 49.462879,-34.544734 L 49.462879,-31.750025 z " /> <path id="path3206" style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M -70.039321,-118.38028 L -70.039321,-121.17498 L -70.039321,-118.38028 z " /> <g id="layer4" style="display:inline" transform="translate(112.91228,26.201359)" /> <g id="layer5" style="display:inline" transform="translate(112.91228,26.201359)" /> <path id="path6137" style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 174.05068,-147.16862 L 174.05068,-149.96333 L 174.05068,-147.16862 z " /> <path id="path1987" style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 101.56614,-371.07382 L 101.56614,-373.86853 L 101.56614,-371.07382 z " /> <path id="path1747" style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 149.36244,-486.39782 L 149.36244,-489.19253 L 149.36244,-486.39782 z " /> <rect id="rect1327" style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" y="-458.65479" x="138.2153" height="0" width="1" /> <g id="g2374" transform="matrix(1.2356821,0,0,1.8482107,-3.5496248,-25.38523)"> <path d="M 4.7083202,30.661456 L 25.57544,84.205159 L 30.95413,96.225749 C 62.322282,93.543489 95.265863,91.434519 126.73647,83.862569 C 93.614561,10.298058 72.324765,33.353142 4.7083202,30.661456 z " style="fill:#222222;fill-opacity:0.31048387;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3305)" id="path4289" /> <path d="M 90.355469,15.595633 C 69.839931,30.883385 31.459275,27.58542 4.0108302,27.099762 L 26.54868,83.060799 L 32.222931,93.570089 C 35.603792,93.913759 38.269354,93.970409 41.938666,93.714899 C 72.916201,91.557889 108.6155,89.523479 130.41226,72.492299 C 114.79554,54.221776 102.47912,34.938286 90.355469,15.595633 z " style="fill:url(#linearGradient2383);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path3189" /> <path d="M 90.059565,17.10802 C 69.544027,32.395772 31.459275,27.58542 4.0108302,27.099762 L 26.74886,83.557839 L 32.208416,93.529519 C 36.083589,94.079159 39.416305,93.889369 43.691869,93.593189 C 74.254482,91.476029 109.02556,89.203079 130.41226,72.492299 C 114.79554,54.221776 102.18321,36.450675 90.059565,17.10802 z " style="opacity:0.61904764;fill:url(#radialGradient2385);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path4254" /> <path d="M 90.521777,15 C 93.141253,19.179229 95.775082,23.358446 98.443898,27.522529 C 76.344147,42.075359 38.098841,39.507779 9.1428002,38.820788 L 4.1799102,26.508134 C 31.628365,26.993791 70.006241,30.28775 90.521777,15 z " style="opacity:0.57875462;fill:url(#radialGradient2387);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path4270" /> <path d="M 15.50758,55.656179 L 26.75758,83.562429 L 32.19508,93.531179 C 36.070253,94.080819 39.419516,93.889859 43.69508,93.593679 C 51.95176,93.021719 60.514727,92.438739 69.03883,91.562429 L 69.03883,59.124929 C 69.03883,57.199554 68.366752,55.656179 67.53883,55.656179 L 15.50758,55.656179 z " style="opacity:0.61904764;fill:url(#linearGradient2389);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path2017" /> <path d="M 4,27.095443 L 26.75,83.559969 L 32.21875,93.540919 C 36.093924,94.090559 39.411936,93.899869 43.6875,93.603689 C 74.25011,91.486519 109.01955,89.222659 130.40625,72.511879 C 130.20165,72.272509 130.01607,72.029189 129.8125,71.789989 C 108.39484,88.226409 74.143245,91.059929 43.765625,93.164279 C 39.490061,93.460459 36.140796,93.651149 32.265625,93.101499 L 26.53125,82.555599 L 4.21875,27.095443 C 4.147613,27.094129 4.070995,27.0967 4,27.095443 z " style="opacity:0.41904811;fill:url(#linearGradient2391);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path2914" /> <path d="M 90.039751,16.352561 C 101.62367,35.608277 114.55221,54.163887 129.37814,72.249009" style="opacity:0.6457565;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#radialGradient2393);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3637)" id="path3607" /> </g> <g id="g4308" transform="matrix(0.714286,0,0,0.714286,72.100616,67.733076)"> <path id="path12057" style="opacity:0.08196722;fill:url(#linearGradient2366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 10.628479,8.4652472 C 8.8673095,8.5903719 8.0050972,9.6618224 8.0050972,11.406299 L 8.0050972,82.02096 C 32.521811,46.530692 55.281152,23.649512 75.73056,8.788763 L 19.282623,8.788763 L 19.282623,8.4652472 L 10.990325,8.4652472 C 10.864909,8.4652472 10.74589,8.4569056 10.628479,8.4652472 z M 119.72497,14.81792 C 83.579397,52.816092 54.569378,102.04945 43.891728,125.76385 L 116.07995,125.76385 C 118.25389,125.76385 119.99994,124.06084 119.99995,121.94048 L 119.93605,15.023794 L 119.72497,14.81792 z " /> <path id="path1410" style="fill:#1c1c1c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 11.003129,8.0400556 C 8.9964822,8.0400556 8.0157887,9.1208673 8.0157887,10.988425 L 7.9999986,121.93277 C 7.9999986,124.06085 9.750128,125.77405 11.924069,125.77406 L 116.07588,125.77406 C 118.24982,125.77406 119.99994,124.06085 119.99995,121.93277 L 119.92103,14.623657 L 113.09906,8.0400556 L 107.9769,8.0400556 L 107.9769,8.354299 L 98.69035,8.354299 L 97.499269,10.773777 L 94.527713,10.861354 L 94.527713,8.354299 L 19.279281,8.354299 L 19.279281,8.0400556 L 11.003129,8.0400556 z " /> <path id="path11174" style="opacity:0.2213115;fill:url(#linearGradient2368);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 11.003129,8.0400556 C 8.9964822,8.0400556 8.0157887,9.1208673 8.0157887,10.988425 L 7.9999986,121.93277 C 7.9999986,124.06085 9.750128,125.77405 11.924069,125.77406 L 116.07588,125.77406 C 118.24982,125.77406 119.99994,124.06085 119.99995,121.93277 L 119.92103,14.623657 L 113.09906,8.0400556 L 107.9769,8.0400556 L 107.9769,8.354299 L 98.69035,8.354299 L 97.499269,10.773777 L 94.527713,10.861354 L 94.527713,8.354299 L 19.279281,8.354299 L 19.279281,8.0400556 L 11.003129,8.0400556 z " /> <path id="rect2296" style="fill:url(#linearGradient2370);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.88860911;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 107.99408,122.78378 L 107.99408,62.851569 C 107.99408,60.811972 106.24395,59.169994 104.07001,59.169994 L 22.997753,59.169994 C 22.963786,59.169994 22.92977,59.169197 22.896011,59.169994 C 20.769396,59.220203 19.073688,60.843841 19.073688,62.851569 L 19.073688,122.78378" /> <path id="rect2478" style="fill:url(#radialGradient2372);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 41.808705,11.471733 L 41.599985,43.969469 C 41.599997,45.833574 42.95943,47.335102 44.647697,47.335102 L 89.05451,47.199925 C 90.742788,47.199925 92.10222,45.69841 92.10222,43.834292 L 91.999965,11.43162 L 41.808705,11.471733 z M 75.199972,19.199936 L 86.399967,19.199936 L 86.399967,41.599927 L 75.199972,41.599927 L 75.199972,19.199936 z " /> <rect id="rect4174" style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" y="72.399918" x="30.399988" height="2.799999" width="67.199974" /> <rect id="rect4176" style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" y="89.199936" x="30.399988" height="2.799999" width="67.199974" /> <rect id="rect4178" style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" y="105.99995" x="30.399988" height="2.799999" width="67.199974" /> </g> </svg> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/filter-folder.svg����������������������������������������������������0000644�0001750�0000144�00000136633�11074311505�020010� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg1307" sodipodi:version="0.32" inkscape:version="0.46" version="1.0" sodipodi:docbase="/home/david/Progetti/sandbox" sodipodi:docname="filter-folder.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:modified="true"> <defs id="defs1309"> <linearGradient id="XMLID_8_" gradientUnits="userSpaceOnUse" x1="72.0005" y1="96" x2="72.0005" y2="20.0005" gradientTransform="matrix(1.0033876,0,0,1,1.7561237,8)"> <stop offset="0" style="stop-color:#cfe7ff;stop-opacity:1;" id="stop35" /> <stop offset="0.5917" style="stop-color:#71A8F5" id="stop37" /> <stop offset="1" style="stop-color:#2C72C7" id="stop39" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="linearGradient2838" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0033876,0,0,1,-8.2438763,8)" x1="72.0005" y1="96" x2="72.0005" y2="20.0005" /> <filter inkscape:collect="always" x="-0.012357198" width="1.0247144" y="-0.41513768" height="1.8302754" id="filter2848"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.65388509" id="feGaussianBlur2850" /> </filter> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2844"> <path style="fill:#ff00bf" d="M 133.86613,100.978 C 133.79288,102.369 132.59585,103.5 131.19913,103.5 L 16.812952,103.5 C 15.415236,103.5 14.2192,102.368 14.145947,100.979 C 14.145947,100.979 10.508666,30.967 10.508666,30.957 C 10.461513,30.301 10.673223,29.685 11.105684,29.22 C 11.539144,28.756 12.140172,28.501 12.799403,28.501 L 135.21268,28.501 C 135.8719,28.501 136.47293,28.756 136.90339,29.219 C 137.33384,29.682 137.54254,30.298 137.49137,30.966 L 133.86613,100.978 z" id="path2846" /> </clipPath> <linearGradient id="linearGradient2822"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop2824" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop2826" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2822" id="linearGradient2828" x1="22.413761" y1="28.5" x2="22.413761" y2="34.472866" gradientUnits="userSpaceOnUse" gradientTransform="translate(10,0)" /> <linearGradient id="XMLID_9_" gradientUnits="userSpaceOnUse" x1="71.9995" y1="14.2578" x2="71.9995" y2="19.9583" gradientTransform="matrix(1.0033404,0,0,1,-8.2374684,8)"> <stop offset="0.25" style="stop-color:#71a8f5;stop-opacity:0;" id="stop46" /> <stop offset="1" style="stop-color:#0057ae;stop-opacity:1" id="stop48" /> </linearGradient> <linearGradient gradientTransform="matrix(1.0033808,0,0,1,-8.2378002,8)" y2="20.043535" x2="122.39215" y1="96.721588" x1="122.74438" gradientUnits="userSpaceOnUse" id="linearGradient3067"> <stop id="stop3069" style="stop-color:#0055f2;stop-opacity:1;" offset="0" /> <stop offset="0.13053299" style="stop-color:#5ca9ff;stop-opacity:1;" id="stop3077" /> <stop id="stop3071" style="stop-color:#106ced;stop-opacity:1;" offset="0.72006166" /> <stop id="stop3073" style="stop-color:#3462d3;stop-opacity:1;" offset="1" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3067" id="linearGradient3109" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0033808,0,0,1,-8.2378,8)" x1="122.74438" y1="96.721588" x2="122.74438" y2="20" /> <filter inkscape:collect="always" x="-0.0256" width="1.0512" y="-0.384" height="1.768" id="filter2807"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.28" id="feGaussianBlur2809" /> </filter> <linearGradient id="XMLID_6_" gradientUnits="userSpaceOnUse" x1="72.0005" y1="96" x2="72.0005" y2="4.882812e-04" gradientTransform="translate(-7.999995,8)"> <stop offset="0" style="stop-color:#001f81;stop-opacity:1" id="stop7" /> <stop offset="0.0769" style="stop-color:#2451a4;stop-opacity:1;" id="stop9" /> <stop offset="0.58579999" style="stop-color:#299ebe;stop-opacity:1;" id="stop11" /> <stop offset="0.96450001" style="stop-color:#8ba7e7;stop-opacity:1" id="stop13" /> </linearGradient> <linearGradient id="linearGradient3058"> <stop id="stop3060" offset="0" style="stop-color:#9a7600;stop-opacity:1;" /> <stop style="stop-color:#e3ad00;stop-opacity:1;" offset="0.09292036" id="stop3066" /> <stop id="stop3070" offset="0.5043171" style="stop-color:#ffcd2c;stop-opacity:1;" /> <stop id="stop3068" offset="0.91571385" style="stop-color:#e3ad00;stop-opacity:1;" /> <stop id="stop3113" offset="1" style="stop-color:#b98d00;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient4309"> <stop style="stop-color:#fff727;stop-opacity:0.73333335;" offset="0" id="stop4311" /> <stop style="stop-color:#ffb266;stop-opacity:0;" offset="1" id="stop4313" /> </linearGradient> <linearGradient id="linearGradient4318"> <stop id="stop4320" offset="0" style="stop-color:#fffaa8;stop-opacity:1;" /> <stop id="stop4322" offset="1" style="stop-color:white;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient2019"> <stop id="stop2912" offset="0" style="stop-color:#fff823;stop-opacity:0.84313726;" /> <stop style="stop-color:#ffff02;stop-opacity:0;" offset="1" id="stop2023" /> </linearGradient> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective2925" /> <linearGradient inkscape:collect="always" id="linearGradient2897"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2899" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2901" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2884"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2886" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2888" /> </linearGradient> <linearGradient id="linearGradient3054"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3056" /> <stop id="stop3062" offset="0.5714286" style="stop-color:black;stop-opacity:1;" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3058" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3040"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3042" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3044" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3027"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3029" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3031" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3012"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3014" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3016" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2999"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3001" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3003" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2981"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2983" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2985" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2947"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2949" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2951" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2929"> <stop style="stop-color:#bdbdbd;stop-opacity:1;" offset="0" id="stop2931" /> <stop style="stop-color:#bdbdbd;stop-opacity:0;" offset="1" id="stop2933" /> </linearGradient> <linearGradient id="linearGradient2903"> <stop style="stop-color:white;stop-opacity:0.53790611;" offset="0" id="stop2905" /> <stop id="stop2911" offset="0.21464799" style="stop-color:white;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:0.41516244;" offset="0.66342056" id="stop2913" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop2907" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3291"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3293" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3295" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3291" id="radialGradient3297" cx="63.912209" cy="115.70919" fx="63.912209" fy="115.7093" r="63.912209" gradientTransform="matrix(1,0,0,0.197802,0,92.82166)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3054" id="radialGradient3060" cx="63.816387" cy="120.57538" fx="63.816387" fy="120.57538" r="14.672465" gradientTransform="matrix(1,0,0,0.289157,0,85.71021)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2897" id="linearGradient2904" x1="67.25" y1="72.375" x2="65.25" y2="17.625" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient2256" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient2258" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871796,19.248866,2.1082206)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2260" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2262" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.1392194,15.358897,56.83334)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2264" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.5047306,-0.9375819,1.2433202,3.3256839,-79.061389,-69.19504)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2266" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.1392194,15.358897,56.83334)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2268" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.5047306,-0.9375819,1.2433202,3.3256839,-79.061389,-69.19504)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2270" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.556928,-2.91845e-8,0,0.138799,37.13478,97.17706)" cx="57.214077" cy="124.00706" fx="49.233025" fy="124.00705" r="11.383312" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2272" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.2437132,15.358897,49.893028)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2274" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.396982,-6.091903e-3,2.173148e-3,-0.138782,90.77277,126.4457)" cx="76.055191" cy="102.52346" fx="70.111389" fy="106.1347" r="11.383312" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2276" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2999" id="linearGradient2278" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="48.326965" y1="241.35539" x2="60.750298" y2="67.1054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient2280" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient2282" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient2284" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8601654,0,0,0.9472313,14.250514,3.8818714)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient2287" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9384891,0,0,0.9797769,5.3602634,-0.1102297)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient2290" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,0.6237166,10.813747,4.9721139)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient2293" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8332988,-4.0741942e-2,4.3563196e-2,0.8910022,10.908193,1.2960712)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2999" id="linearGradient2297" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="48.326965" y1="241.35539" x2="60.750298" y2="67.1054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2300" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2304" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.2520869,6.5695719,47.48181)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2308" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6417463,-0.8079979,1.3565327,2.8660381,-96.448304,-52.309632)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2312" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.1440028,6.5695719,54.660582)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2315" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6417463,-0.8125119,1.3565327,2.88205,-96.448304,-52.949828)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.1440028,6.5695719,54.660582)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2321" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient2325" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210978,10.813748,-1.9448209)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient2328" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,0.8975001,10.813747,5.9409483)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2330" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.396982,-6.091903e-3,2.173148e-3,-0.138782,90.77277,126.4457)" cx="76.055191" cy="102.52346" fx="70.111389" fy="106.1347" r="11.383312" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2332" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.556928,-2.91845e-8,0,0.138799,37.13478,97.17706)" cx="57.214077" cy="124.00706" fx="49.233025" fy="124.00705" r="11.383312" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient4071" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9273531,0,0,0.9032318,165.67959,-7.0869034)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient4074" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.5749887,171.06836,-2.4016179)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient4077" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.823411,-3.7558978e-2,4.3046279e-2,0.8213927,171.16169,-5.7904698)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient4081" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413255,171.06836,-8.7781679)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4084" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.2323926,166.87455,36.787008)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient4088" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6222655,-0.7448731,1.3404362,2.6421289,65.079072,-55.208227)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4092" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.1327526,166.87455,43.404939)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient4095" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6222655,-0.7490344,1.3404362,2.6568898,65.079072,-55.798408)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4098" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.1327526,166.87455,43.404939)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient4101" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413255,171.06836,-8.7781679)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient4105" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413245,171.06836,-8.7781672)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient4108" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.8273829,171.06836,-1.5084737)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient4132" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.8273829,171.06836,-1.5084737)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient4134" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413245,171.06836,-8.7781672)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient4136" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413255,171.06836,-8.7781679)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4138" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.1327526,166.87455,43.404939)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient4140" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6222655,-0.7490344,1.3404362,2.6568898,65.079072,-55.798408)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4142" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.1327526,166.87455,43.404939)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient4144" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6222655,-0.7448731,1.3404362,2.6421289,65.079072,-55.208227)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient4146" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.556928,-2.91845e-8,0,0.138799,37.13478,97.17706)" cx="57.214077" cy="124.00706" fx="49.233025" fy="124.00705" r="11.383312" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4148" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.2323926,166.87455,36.787008)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient4150" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413255,171.06836,-8.7781679)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient4152" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.823411,-3.7558978e-2,4.3046279e-2,0.8213927,171.16169,-5.7904698)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient4154" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.5749887,171.06836,-2.4016179)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient4156" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9273531,0,0,0.9032318,165.67959,-7.0869034)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8284271" inkscape:cx="90.481778" inkscape:cy="71.874365" inkscape:current-layer="layer1" showgrid="false" inkscape:document-units="px" inkscape:grid-bbox="true" guidetolerance="0.1px" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1600" inkscape:window-height="1113" inkscape:window-x="0" inkscape:window-y="34"> <inkscape:grid id="GridFromPre046Settings" type="xygrid" originx="0px" originy="0px" spacingx="8px" spacingy="8px" color="#0000ff" empcolor="#0000ff" opacity="0.2" empopacity="0.4" empspacing="0" visible="true" enabled="true" /> </sodipodi:namedview> <metadata id="metadata1312"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:contributor> <cc:Agent> <dc:title>Oxygen team</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/LGPL/2.1/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer" transform="translate(-2.8572,5.1129792e-5)"> <g id="g3892" transform="matrix(0.875046,0,0,0.6510063,12.136849,55.245709)"> <path style="fill:url(#XMLID_6_)" id="path15" d="M 117.983,19 C 117.992,17.35 116.64999,16 114.99999,16 L 44.961007,16 L 38.375006,9.414 C 37.597005,8.636 36.061006,8 34.961,8 L 13.999998,8 C 11.799996,8 9.999999,9.8 9.999999,12 L 9.999999,19 C 9.999999,19 10.999999,104 7,104 L 121,104 C 116.99999,104 117.983,19 117.983,19 z" /> <g transform="matrix(1.0033404,0,0,1,-8.2374684,8)" style="opacity:0.6;filter:url(#filter2807)" id="g17"> <path id="path19" d="M 132,96 C 132,98.2 128.4,100 124,100 L 20,100 C 15.6,100 12,98.2 12,96 C 12,93.8 15.6,92 20,92 L 124,92 C 128.4,92 132,93.8 132,96 z" /> </g> <path style="opacity:0.9;fill:url(#linearGradient3109);fill-opacity:1" id="path30" d="M 124.36598,101.004 C 124.27969,102.652 122.85389,104 121.19831,104 L 6.812906,104 C 5.157329,104 3.731522,102.652 3.644228,101.004 L 0.007982,30.992 C -0.112423,29.347 1.143808,28 2.799384,28 L 125.21183,28 C 126.86741,28 128.11762,29.346 127.9912,30.991 L 124.36598,101.004 z" /> <path style="fill:#5293ee;fill-opacity:1" id="path32" d="M 10.580094,28 C 10.551086,23.609 10.516087,20.392 10.500078,19 L 10.500078,12 C 10.500078,10.07 12.07033,8.5 14.000627,8.5 L 34.964921,8.5 C 35.937077,8.5 37.339294,9.081 38.026407,9.768 L 44.759457,16.5 L 115.01648,16.5 C 115.68059,16.5 116.30469,16.76 116.77576,17.233 C 117.24683,17.706 117.50487,18.333 117.50087,18.997 C 117.50087,18.997 117.57288,18.925 117.60989,18.888 C 117.48787,19.495 117.47487,21.062 117.44687,25.161 L 117.43687,28 L 117.92894,28 C 117.95994,22.468 117.99995,19 117.99995,19 C 118.00896,17.35 116.66674,16 115.01648,16 L 44.966498,16 L 38.379463,9.414 C 37.60134,8.636 36.065099,8 34.964921,8 L 14.000627,8 C 11.80028,8 10,9.8 10,12 L 10,19 C 10,19 10.041009,22.468 10.073018,28 L 10.580094,28 z" /> <path style="opacity:0.5;fill:url(#XMLID_9_)" id="path50" d="M 9.8848616,22 C 9.8938916,23.75 9.9029216,25.755 9.9109516,28 L 118.09511,28 C 118.10414,25.755 118.11317,23.75 118.1212,22 L 9.8848616,22 z" /> <path transform="translate(-10,0)" clip-path="url(#clipPath2844)" id="path2788" d="M 12.8125,28.5 C 12.153269,28.5 11.52721,28.754751 11.09375,29.21875 C 10.661289,29.68375 10.452847,30.312749 10.5,30.96875 C 10.5,30.968937 10.559992,32.232788 10.5625,32.28125 C 10.647737,31.886257 10.815287,31.518165 11.09375,31.21875 C 11.52721,30.754751 12.153269,30.5 12.8125,30.5 L 135.21875,30.5 C 135.87797,30.500001 136.47579,30.75575 136.90625,31.21875 C 137.18342,31.516877 137.35439,31.883216 137.4375,32.28125 L 137.5,30.96875 C 137.55117,30.30075 137.3367,29.68175 136.90625,29.21875 C 136.47579,28.75575 135.87797,28.500001 135.21875,28.5 L 12.8125,28.5 z" style="fill:url(#linearGradient2828);fill-opacity:1;filter:url(#filter2848)" /> <path d="M 125.21268,28 L 2.799403,28 C 1.143815,28 -0.1124237,29.347 0.007982,30.992 L 3.645263,101.004 C 3.731547,102.652 5.157364,104 6.812952,104 L 121.19913,104 C 122.85472,104 124.28053,102.652 124.36682,101.004 L 127.99106,30.991 C 128.11849,29.346 126.86827,28 125.21268,28 z M 123.86613,100.978 C 123.79288,102.369 122.59585,103.5 121.19913,103.5 L 6.812952,103.5 C 5.415236,103.5 4.2192,102.368 4.145947,100.979 C 4.145947,100.979 0.508666,30.967 0.508666,30.957 C 0.461513,30.301 0.673223,29.685 1.105684,29.22 C 1.539144,28.756 2.140172,28.501 2.799403,28.501 L 125.21268,28.501 C 125.8719,28.501 126.47293,28.756 126.90339,29.219 C 127.33384,29.682 127.54254,30.298 127.49137,30.966 L 123.86613,100.978 z" id="path2836" style="fill:url(#linearGradient2838)" /> </g> <g id="g4113" transform="translate(-155.20994,8.4852814)"> <path style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 213.09946,-3.9492142 L 213.09946,-6.5250782 L 213.09946,-3.9492142 z" id="path2276" sodipodi:nodetypes="ccc" /> <path sodipodi:nodetypes="ccccc" id="path2978" d="M 261.93205,10.281734 C 251.31567,24.252441 238.88824,37.30901 231.64444,51.279718 L 232.80173,51.243152 L 268.06349,8.678679 C 265.80405,9.573709 263.77948,10.075882 261.93205,10.281734 z" style="opacity:0.41999996;fill:url(#linearGradient4132);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" /> <path sodipodi:nodetypes="cccccsscccsc" id="path1969" d="M 223.70102,-6.5500026 C 197.52651,-6.5500026 176.28428,-1.7184074 176.28428,3.8176469 C 176.28428,15.228627 213.14647,50.404098 213.14647,50.404098 C 213.29888,50.607746 213.48034,50.944882 213.46733,51.337901 L 213.46733,101.54672 C 213.46733,102.78476 215.30358,103.55463 222.52616,103.55463 C 229.59435,103.55463 233.9347,102.96126 233.9347,101.54672 C 233.9347,101.53884 233.93541,101.52325 233.9347,101.51538 L 233.88025,51.337909 C 233.88025,51.107431 233.91377,50.845662 234.02869,50.64935 C 234.02869,50.64935 270.96318,14.910005 270.96318,3.387582 C 270.96318,-0.53698439 249.87553,-6.5500025 223.70102,-6.5500026 z" style="fill:url(#linearGradient4134);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.17618437;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path id="path2880" d="M 223.7004,1.6787706 C 204.39848,1.6787706 188.41533,5.3275933 185.86872,10.055544 C 194.18682,13.100083 208.02062,15.139715 223.7004,15.139715 C 239.36306,15.139715 253.18597,13.142889 261.50708,10.103968 C 259.00961,5.3630182 243.03871,1.6787706 223.7004,1.6787706 z" style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" /> <path sodipodi:nodetypes="ccsccc" id="path2900" d="M 217.13139,51.702002 L 217.13139,102.9663 C 218.89529,103.3124 221.08707,103.55463 223.70077,103.55463 C 225.8753,103.55463 227.75728,103.38624 229.36848,103.14279 L 229.36848,51.702002 C 225.28945,52.551887 221.21042,53.046626 217.13139,51.702002 z" style="opacity:0.61475375;fill:url(#linearGradient4136);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" /> <path sodipodi:nodetypes="cssscsc" id="path2945" d="M 213.79517,50.613592 C 213.79195,50.634668 213.77207,50.651195 213.77207,50.672425 C 213.77207,51.797652 218.33315,53.646798 223.95973,53.646798 C 229.58631,53.646798 234.17048,51.797653 234.17049,50.672425 C 234.17049,50.651813 234.15043,50.634059 234.14738,50.613592 C 231.90344,51.08803 228.17733,51.378419 223.95973,51.378419 C 219.74312,51.378418 216.03929,51.087841 213.79517,50.613592 z" style="opacity:0.11000001;fill:url(#radialGradient4138);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path style="opacity:0.75819672;fill:url(#radialGradient4140);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" d="M 217.13139,51.837124 L 204.45256,15.139715 C 213.17398,16.068077 222.07265,15.692386 230.82582,15.287589 L 229.36848,51.837124 C 225.28945,52.549172 221.21042,52.963672 217.13139,51.837124 z" id="path2915" sodipodi:nodetypes="ccccc" /> <path style="opacity:0.11000001;fill:url(#radialGradient4142);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 213.79517,50.613592 C 213.79195,50.634668 213.77207,50.651195 213.77207,50.672425 C 213.77207,51.797652 218.33315,52.897981 223.95973,52.897981 C 229.58631,52.897981 234.17048,51.797653 234.17049,50.672425 C 234.17049,50.651813 234.15043,50.634059 234.14738,50.613592 C 231.90344,51.08803 228.11199,51.877632 223.89439,51.877632 C 219.67778,51.877631 216.03929,51.087841 213.79517,50.613592 z" id="path2962" sodipodi:nodetypes="cssscsc" /> <path transform="matrix(4.1521204,0,0,7.1175095,-58.922801,-799.05588)" d="M 79.338449,112.83906 A 11.285211,1.4818963 0 1 1 56.768027,112.83906 A 11.285211,1.4818963 0 1 1 79.338449,112.83906 z" sodipodi:ry="1.4818963" sodipodi:rx="11.285211" sodipodi:cy="112.83906" sodipodi:cx="68.053238" id="path2871" style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#5b5b5b;stroke-width:0.19620273;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" sodipodi:type="arc" /> <path sodipodi:nodetypes="ccccc" id="path2939" d="M 216.43915,51.725329 L 201.77328,15.139715 C 210.4947,16.062919 224.33974,15.885384 233.0929,15.482836 L 229.91499,51.829312 C 225.83595,52.537404 220.51818,52.845619 216.43915,51.725329 z" style="opacity:0.75819672;fill:url(#radialGradient4144);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" /> <path sodipodi:type="arc" style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient4146);stroke-width:0.13700832;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path3010" sodipodi:cx="68.053238" sodipodi:cy="112.83906" sodipodi:rx="11.285211" sodipodi:ry="1.4818963" d="M 79.338449,112.83906 A 11.285211,1.4818963 0 1 1 56.768027,112.83906 A 11.285211,1.4818963 0 1 1 79.338449,112.83906 z" transform="matrix(4.1544915,0,0,7.2205454,-59.084163,-810.68232)" /> <path sodipodi:nodetypes="cssscsc" id="path2964" d="M 213.79517,50.613592 C 213.79195,50.634668 213.77207,50.651195 213.77207,50.672425 C 213.77207,51.797652 218.36582,54.47882 223.9924,54.47882 C 229.61897,54.47882 234.17048,51.797653 234.17049,50.672425 C 234.17049,50.651813 234.15043,50.634059 234.14738,50.613592 C 231.90344,51.08803 227.91597,52.085637 223.69837,52.085637 C 219.48176,52.085636 216.03929,51.087841 213.79517,50.613592 z" style="opacity:0.11000001;fill:url(#radialGradient4148);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path style="opacity:0.61475375;fill:url(#linearGradient4150);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" d="M 216.46156,51.552828 L 217.13139,102.9663 C 218.89529,103.3124 221.08707,103.55463 223.70077,103.55463 C 225.8753,103.55463 227.75728,103.38624 229.36848,103.14279 L 229.8322,51.702002 C 225.75317,52.551887 220.5406,52.897452 216.46156,51.552828 z" id="path2943" sodipodi:nodetypes="ccsccc" /> <path sodipodi:nodetypes="ccccc" id="rect3007" d="M 231.71574,51.27294 L 232.74623,51.27294 L 232.74623,102.57134 L 231.67931,102.93445 L 231.71574,51.27294 z" style="opacity:0.21311478;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="rect3024" d="M 193.54658,-3.2342938 C 198.63828,-4.1531031 203.70158,-4.8783603 208.72168,-5.3092161 L 208.83841,1.2131339 C 204.67022,1.4830019 201.00176,2.5673594 197.0523,3.3108166 L 193.54658,-3.2342938 z" style="opacity:0.83606561;fill:url(#linearGradient4152);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccsc" id="path3035" d="M 205.12492,3.4213946 C 200.7279,3.5931371 199.91587,3.6575126 196.54729,3.9591952 C 199.72345,5.2166521 203.37005,6.2458693 206.41426,7.337255 C 210.46317,7.4903406 214.7929,7.5666654 219.32118,7.6067817 C 216.41282,6.2546041 212.79905,2.8549199 208.47525,2.3525054 C 205.43896,1.9996968 205.19168,3.4482211 205.12492,3.4213946 z" style="opacity:0.83606561;fill:url(#linearGradient4154);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path style="opacity:0.53278689;fill:url(#linearGradient4156);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" d="M 213.47601,50.987498 L 213.45981,50.973385 L 213.61919,101.97811 C 213.76554,102.53169 214.26177,102.61382 214.68612,102.79282 C 215.41697,81.768336 214.18735,67.236055 213.47601,50.987498 z" id="path2882" sodipodi:nodetypes="ccccc" /> </g> <path sodipodi:nodetypes="ccc" id="path3117" d="M -109.74325,70.909467 L -109.74325,68.114759 L -109.74325,70.909467 z" style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> </g> </svg> �����������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/assgn-some.svg�������������������������������������������������������0000644�0001750�0000144�00000007000�11163113660�017310� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="680" height="680" id="svg2273" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" sodipodi:docname="assgn-some.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2275" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="375" inkscape:cy="405.71429" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" showgrid="false" showguides="true" height="680px" width="680px" /> <metadata id="metadata2278"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-47.400002,-191.39075)"> <rect style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:15;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4135" width="660" height="630" x="59.899994" y="217.46219" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 163.11429,242.81934 L 163.11429,822.81933" id="path3162" /> <path style="fill:#ccccff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 350.25715,655.67647 L 604.54286,652.81933 L 604.54286,421.39076 L 424.54286,421.39076 L 350.25715,655.67647 z " id="path5108" sodipodi:nodetypes="ccccc" /> <path id="path3155" d="M 68.114294,417.81933 L 708.11429,417.81933" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path3160" d="M 68.114294,657.81933 L 708.11429,657.81933" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 608.11429,237.81933 L 608.11429,817.81932" id="path3164" /> </g> </svg> MP3Diags-1.0.12.079/src/images/tag_editor.svg�������������������������������������������������������0000644�0001750�0000144�00000066440�11162224767�017404� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg1307" sodipodi:version="0.32" inkscape:version="0.43" version="1.0" sodipodi:docbase="/home/pinheiro/Documents/pics/new oxygen/svg" sodipodi:docname="rss_tag.svg"> <defs id="defs1309"> <linearGradient inkscape:collect="always" id="linearGradient12560"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop12562" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop12564" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient11615"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop11617" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop11619" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient11584"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop11586" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop11588" /> </linearGradient> <linearGradient y2="3.1118" x2="17.0464" y1="7.6073999" x1="17.0464" gradientUnits="userSpaceOnUse" id="linearGradient2959"> <stop id="stop2961" style="stop-color:#EEEEEE" offset="0" /> <stop id="stop2963" style="stop-color:#CECECE" offset="0.2909" /> <stop id="stop2965" style="stop-color:#888888" offset="0.85" /> <stop id="stop2967" style="stop-color:#555555" offset="1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7033"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop7035" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop7037" /> </linearGradient> <linearGradient id="linearGradient5259"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop5261" /> <stop id="stop5267" offset="0.5" style="stop-color:#7f7f7f;stop-opacity:0.33935019;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop5263" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3291"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3293" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3295" /> </linearGradient> <linearGradient id="linearGradient2316"> <stop id="stop2318" offset="0" style="stop-color:#dd6a0e;stop-opacity:1;" /> <stop id="stop2320" offset="1" style="stop-color:#ffb66d;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient3075"> <stop id="stop3077" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.42597079" id="stop3093" /> <stop style="stop-color:#f1f1f1;stop-opacity:1;" offset="0.5892781" id="stop3085" /> <stop id="stop3087" offset="0.80219781" style="stop-color:#eaeaea;stop-opacity:1;" /> <stop id="stop3079" offset="1" style="stop-color:#dfdfdf;stop-opacity:1;" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3291" id="radialGradient10686" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.197802,0,92.82166)" cx="63.912209" cy="115.70919" fx="42.094791" fy="115.7093" r="63.912209" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3075" id="radialGradient11644" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.844258,1.256048e-15,-4.710318e-16,1.606667,44.38044,-98.18508)" spreadMethod="reflect" cx="-52.250774" cy="128.00081" fx="-52.250774" fy="128.00081" r="36.937431" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2316" id="linearGradient11646" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.835095,0,0,0.835095,6.816147,12.32049)" x1="32.39278" y1="79.018364" x2="83.208656" y2="79.018364" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5259" id="linearGradient11648" gradientUnits="userSpaceOnUse" gradientTransform="translate(0.267368,-6.264141e-2)" x1="24.851341" y1="60.846405" x2="-35.981007" y2="112.08296" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5259" id="linearGradient11650" gradientUnits="userSpaceOnUse" gradientTransform="translate(0.267368,-6.264141e-2)" x1="24.851341" y1="60.846405" x2="-35.981007" y2="112.08296" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5259" id="linearGradient11652" gradientUnits="userSpaceOnUse" gradientTransform="translate(0.267368,-6.264141e-2)" x1="24.851341" y1="60.846405" x2="-35.981007" y2="112.08296" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2316" id="linearGradient11654" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.835095,0,0,0.835095,7.613067,13.11741)" x1="32.39278" y1="79.018364" x2="83.208656" y2="79.018364" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7033" id="linearGradient11656" gradientUnits="userSpaceOnUse" gradientTransform="translate(0.144757,-0.233352)" x1="96.437851" y1="14.713447" x2="96.397697" y2="23.267729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2959" id="linearGradient11658" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.965789,0,0,0.944211,3.248297,-0.448682)" x1="111.30237" y1="-18.911451" x2="108.5625" y2="26.541067" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient11584" id="linearGradient11660" gradientUnits="userSpaceOnUse" x1="65.073738" y1="53.097416" x2="62.605522" y2="102.24165" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2959" id="linearGradient11662" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.989491,0.144757,0.128566)" x1="112.14121" y1="0.22972308" x2="108.5625" y2="41.496986" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient11584" id="linearGradient11664" gradientUnits="userSpaceOnUse" x1="236.57014" y1="-50.274925" x2="2.61567" y2="111.73157" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient11584" id="linearGradient11666" gradientUnits="userSpaceOnUse" x1="95.915977" y1="-33.667568" x2="32.102207" y2="129.69464" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient11615" id="radialGradient11668" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.381766,0.111574,-0.139672,0.47791,70.02209,5.232857)" cx="99.498825" cy="33.076019" fx="92.406448" fy="33.504173" r="17.845808" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient12560" id="linearGradient12566" x1="96.686058" y1="28.999111" x2="109.04183" y2="41.42416" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2316" id="linearGradient15192" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.835095,0,0,0.835095,5.637308,11.14165)" x1="32.39278" y1="79.018364" x2="83.208656" y2="79.018364" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.5652975" inkscape:cx="24.19134" inkscape:cy="66.08179" inkscape:current-layer="layer1" showgrid="false" inkscape:document-units="px" inkscape:grid-bbox="true" guidetolerance="0.1px" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1106" inkscape:window-height="958" inkscape:window-x="722" inkscape:window-y="85"> <sodipodi:guide orientation="horizontal" position="32.487481" id="guide2204" /> </sodipodi:namedview> <metadata id="metadata1312"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:contributor> <cc:Agent> <dc:title>Oxygen team</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/LGPL/2.1/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer"> <path sodipodi:nodetypes="ccc" id="path2276" d="M 50.892799,3.2812959 L 50.892799,0.48658747 L 50.892799,3.2812959 z " style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path sodipodi:type="arc" style="opacity:0.38139535;fill:url(#radialGradient10686);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path3289" sodipodi:cx="63.912209" sodipodi:cy="115.70919" sodipodi:rx="63.912209" sodipodi:ry="12.641975" d="M 127.82442 115.70919 A 63.912209 12.641975 0 1 1 0,115.70919 A 63.912209 12.641975 0 1 1 127.82442 115.70919 z" transform="matrix(1,0,0,0.416667,0.144757,74.63816)" /> <g id="g11627" transform="matrix(0.99373,0,0,0.99373,9.698994e-4,0.76812)"> <path sodipodi:nodetypes="ccccccccccccssss" id="rect1410" d="M 65.957252,16.860398 C 62.907696,16.584597 59.770313,17.609836 57.426002,19.954148 L 3.301002,74.047898 C -0.89408299,78.242983 -0.89408309,85.009061 3.301002,89.204148 L 33.457252,119.3604 C 37.652337,123.55549 44.418418,123.55548 48.613502,119.3604 L 102.70726,65.235398 C 105.19809,62.744566 105.83999,59.365361 105.83226,56.141648 L 105.76976,27.454148 C 105.76976,21.521399 100.98376,16.735398 95.051007,16.735398 C 95.051007,16.735398 66.443365,16.827319 65.957252,16.860398 z M 94.801007,21.985398 C 98.463627,21.823968 100.95726,24.470845 100.95726,27.547898 C 100.95726,30.624951 98.471807,33.110398 95.394757,33.110398 C 92.317697,33.110399 89.801007,30.624951 89.801007,27.547898 C 89.801007,24.663161 91.983037,22.1096 94.801007,21.985398 z " style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.04313725" /> <rect transform="matrix(0.707107,-0.707107,0.707107,0.707107,0,0)" rx="7.8982348" ry="7.8982348" y="64.655273" x="-51.673248" height="44.167801" width="73.874908" id="rect3166" style="opacity:1;fill:url(#radialGradient11644);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.04313725" /> <path id="path3173" d="M 75.885718,57.507812 L 34.284739,99.108794" style="opacity:0.35655739;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient11646);stroke-width:6.68100023;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <rect style="opacity:0.22950822;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient11648);stroke-width:3.00000095;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect5257" width="73.874908" height="44.167801" x="-51.673248" y="64.655273" ry="7.8982348" rx="7.8982348" transform="matrix(0.707107,-0.707107,0.707107,0.707107,0,0)" /> <rect transform="matrix(0.707107,-0.707107,0.707107,0.707107,0,0)" rx="7.8982348" ry="7.8982348" y="64.655273" x="-51.673248" height="44.167801" width="73.874908" id="rect5269" style="opacity:0.22950822;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient11650);stroke-width:4.70000124;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect style="opacity:0.22950822;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient11652);stroke-width:1.50000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect5271" width="73.874908" height="44.167801" x="-51.673248" y="64.655273" ry="7.8982348" rx="7.8982348" transform="matrix(0.707107,-0.707107,0.707107,0.707107,0,0)" /> <path style="opacity:0.35655739;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient11654);stroke-width:4.28100014;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 76.682637,58.304731 L 35.081658,99.905718" id="path6146" /> <path sodipodi:nodetypes="cccccccc" id="path7023" d="M 95.974287,17.823297 C 85.481516,17.823297 75.240344,17.739431 64.747574,17.739431 C 62.985501,17.739431 60.491741,18.681986 58.875807,20.29792 C 57.215559,22.024579 55.471445,23.415775 53.811196,25.142433 C 56.225419,22.728211 61.024042,19.417529 64.90428,19.417529 C 72.325291,19.417529 92.255327,19.319227 95.974287,19.385637 C 99.686057,19.385637 103.02976,21.506741 104.92901,24.79634 C 104.24024,22.852996 100.25567,17.823297 95.974287,17.823297 z " style="fill:url(#linearGradient11656);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="opacity:1;fill:url(#linearGradient11658);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.28100014;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 100.82818,26.326961 C 98.938027,24.599124 97.412757,21.656447 97.412757,18.406034 C 97.412757,14.872675 99.380507,11.582117 101.55558,8.9316543 C 103.73064,6.2811911 106.84326,4.8075247 109.13903,4.2829843 C 111.4348,3.758444 114.9341,4.1607878 117.10916,5.8173273 C 119.28424,7.4738667 120.58279,10.076472 120.58279,13.60983 C 120.58279,17.143189 118.5547,20.594653 116.37963,23.245116 C 114.20456,25.895577 110.39259,27.695387 108.09681,28.219928 C 107.19159,28.426755 106.70156,28.478743 105.74762,28.384108 L 105.74762,32.025222 C 106.6546,31.947861 107.12437,31.847174 108.09681,31.62499 C 113.50868,30.388482 117.9234,27.25568 120.80298,23.746728 C 123.68255,20.237776 125.33012,16.130459 125.33012,12.032608 C 125.33012,7.9347583 123.68255,4.5770463 120.80298,2.3839513 C 118.5758,0.68772922 115.44044,-0.39061945 111.62798,-0.21262935 C 110.5112,-0.16049075 109.32294,0.008836555 108.09681,0.28898284 C 102.68496,1.5254904 98.240037,4.6877993 95.360457,8.196751 C 92.480887,11.705703 90.863507,15.783513 90.863507,19.881364 C 90.863497,23.979214 92.480887,27.36643 95.360457,29.559527 C 95.900377,29.970733 97.848257,30.831489 97.141137,30.651272 C 97.134377,30.649551 99.104327,31.902937 98.996487,31.335711 C 100.80737,30.597386 101.2053,27.858014 100.82818,26.326961 z " id="path9411" sodipodi:nodetypes="csssssssccsssscssssscc" /> <path id="path10706" d="M 90.5625,16.75 C 82.493814,16.777403 66.333335,16.850191 65.96875,16.875 C 62.919193,16.5992 59.781811,17.624438 57.4375,19.96875 L 7.84375,69.53125 C 19.373301,71.513576 35.736073,74.116497 58.96875,77.5 C 67.242732,78.704986 77.262405,79.536346 87.875,80.09375 L 102.71875,65.25 C 105.20958,62.759169 105.85148,59.379963 105.84375,56.15625 L 105.78125,27.46875 C 105.78125,21.536002 100.99525,16.75 95.0625,16.75 C 95.062499,16.75 93.252062,16.740866 90.5625,16.75 z M 94.875,21.96875 C 98.4908,21.851975 100.96875,24.509486 100.96875,27.5625 C 100.96875,30.639554 98.4833,33.125 95.40625,33.125 C 92.329187,33.125002 89.8125,30.639553 89.8125,27.5625 C 89.812497,24.677764 91.99453,22.124202 94.8125,22 C 94.841114,21.998739 94.846529,21.969669 94.875,21.96875 z " style="opacity:0.11065572;fill:url(#linearGradient11660);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.04313725" /> <path sodipodi:nodetypes="ccsssssssccsssscsssss" id="path7046" d="M 97.375359,32.751517 C 99.475509,31.977786 100.76571,30.212919 100.93539,28.016764 C 98.978277,26.206069 97.644757,23.293743 97.644757,19.887456 C 97.644747,16.184655 99.682197,12.7363 101.93432,9.9587343 C 104.18643,7.1811689 107.4093,5.6368332 109.78639,5.0871385 C 112.16349,4.537444 115.78674,4.9590821 118.03885,6.6950607 C 120.29097,8.431039 121.63552,11.158452 121.63552,14.861251 C 121.63552,18.564052 119.53559,22.18103 117.28347,24.958595 C 115.03136,27.73616 111.08436,29.622279 108.70726,30.171974 C 107.76997,30.38872 106.74637,30.487599 105.75864,30.388425 L 105.75864,34.204148 C 106.69775,34.123076 107.70037,33.973164 108.70726,33.740324 C 114.31083,32.44452 118.88193,29.161485 121.86351,25.484262 C 124.84508,21.80704 126.55101,17.502757 126.55101,13.208394 C 126.55101,8.9140326 124.84508,5.3953022 121.86351,3.0970377 C 119.55744,1.3194736 116.31101,0.18941291 112.36351,0.37593852 C 111.20717,0.43057734 109.97682,0.60802477 108.70726,0.90160537 C 103.1037,2.1974095 98.501327,5.5113663 95.519757,9.1885892 C 92.538177,12.865812 90.863507,17.139173 90.863507,21.433535 C 90.863497,25.727897 92.538177,29.277549 95.519757,31.575814 C 96.078797,32.006739 96.705929,32.408418 97.375359,32.751517 z " style="opacity:1;fill:url(#linearGradient11662);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.28100014;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path id="path11592" d="M 87.21875,16.75 C 78.71516,16.782629 66.287762,16.853292 65.96875,16.875 C 62.919193,16.5992 59.781811,17.624438 57.4375,19.96875 L 7.84375,69.53125 C 14.356712,70.651052 22.410305,71.98654 32.375,73.53125 C 43.387521,56.22581 59.726155,36.241802 71.1875,26.65625 C 75.832301,22.771629 83.170429,19.475338 91.53125,16.75 C 91.224346,16.750624 90.898695,16.748858 90.5625,16.75 C 89.553914,16.753425 88.433549,16.745339 87.21875,16.75 z M 105.59375,25.4375 C 104.03905,26.123892 102.48669,26.807023 100.96875,27.5 C 100.96905,27.523802 100.96875,27.538648 100.96875,27.5625 C 100.96875,30.639554 98.4833,33.125 95.40625,33.125 C 94.072055,33.125001 92.839017,32.655165 91.875,31.875 C 85.192675,35.231446 79.793639,38.393861 77.28125,40.90625 C 69.040453,49.147048 61.755175,64.657329 56.59375,77.15625 C 57.378226,77.271014 58.168037,77.383388 58.96875,77.5 C 67.242732,78.704986 77.262405,79.536346 87.875,80.09375 L 102.71875,65.25 C 105.20958,62.759169 105.85148,59.379963 105.84375,56.15625 L 105.78125,27.46875 C 105.78125,26.773506 105.71934,26.095391 105.59375,25.4375 z " style="opacity:0.20081967;fill:url(#linearGradient11664);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.04313725" /> <path style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.28100014;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 100.93539,27.951048 C 98.978277,26.121121 97.644757,23.177863 97.644757,19.735398 C 97.644747,15.99327 99.142637,12.292464 101.39476,9.4853983 C 103.64687,6.6783321 106.33017,5.0096813 108.70726,4.4541483 C 111.08436,3.8986155 113.7364,4.3247318 115.98851,6.0791483 C 118.24063,7.8335645 119.80101,10.805771 119.80101,14.547898 C 119.80101,18.290026 118.24063,22.053332 115.98851,24.860398 C 113.7364,27.667463 111.08436,29.273615 108.70726,29.829148 C 107.76997,30.048196 106.78874,30.148125 105.80101,30.047898 L 105.80101,34.204148 C 106.74012,34.122215 107.70037,33.970711 108.70726,33.735398 C 114.31083,32.425831 118.88193,29.107927 121.86351,25.391648 C 124.84508,21.67537 126.55101,17.325371 126.55101,12.985398 C 126.55101,8.6454257 124.84508,5.0893227 121.86351,2.7666483 C 119.55744,0.97020468 116.31101,-0.17185845 112.36351,0.016648255 C 111.20717,0.071867415 109.97682,0.25119951 108.70726,0.54789827 C 103.1037,1.8574651 98.501327,5.2066196 95.519757,8.9228983 C 92.538177,12.639177 90.863507,16.957925 90.863507,21.297898 C 90.863497,25.637871 92.538177,29.225223 95.519757,31.547898 C 96.078797,31.9834 96.694077,32.357405 97.363507,32.704148 C 97.369937,32.707482 97.388307,32.700823 97.394757,32.704148 C 99.463657,31.922199 100.76571,30.170528 100.93539,27.951048 z " id="path8516" sodipodi:nodetypes="csssssssccsssscssssscc" /> <path sodipodi:nodetypes="ccccscscccsscsccccc" style="opacity:0.14344261;fill:url(#linearGradient11666);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.04313725" d="M 87.21875,16.75 C 78.71516,16.782629 66.287762,16.853292 65.96875,16.875 C 62.919193,16.5992 59.781811,17.624438 57.4375,19.96875 L 7.84375,69.53125 C 14.356712,70.651052 59.726155,36.241802 71.1875,26.65625 C 75.832301,22.771629 83.170429,19.475338 91.53125,16.75 C 91.224346,16.750624 90.898695,16.748858 90.5625,16.75 C 89.553914,16.753425 88.433549,16.745339 87.21875,16.75 z M 105.59375,25.4375 C 104.03905,26.123892 102.48669,26.807023 100.96875,27.5 C 100.96905,27.523802 100.96875,27.538648 100.96875,27.5625 C 100.96875,30.639554 98.4833,33.125 95.40625,33.125 C 94.072055,33.125001 92.839017,32.655165 91.875,31.875 C 85.192675,35.231446 79.793639,38.393861 77.28125,40.90625 C 69.040453,49.147048 77.262405,79.536346 87.875,80.09375 L 102.71875,65.25 C 105.20958,62.759169 105.85148,59.379963 105.84375,56.15625 L 105.78125,27.46875 C 105.78125,26.773506 105.71934,26.095391 105.59375,25.4375 z " id="path11602" /> <path style="opacity:0.60655738;fill:url(#radialGradient11668);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.28100014;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 90.96875 26.46875 C 91.712717 28.766017 93.069493 30.685101 94.9375 32.125 C 95.493036 32.553222 96.084767 32.971552 96.75 33.3125 C 99.406083 32.361987 100.76114 29.807363 100.21875 26.90625 C 100.06618 26.766783 99.897677 26.623256 99.75 26.46875 L 90.96875 26.46875 z M 112.6875 26.46875 C 110.84997 27.679808 108.83212 28.486717 107.40625 28.8125 C 106.50671 29.018029 106.04171 29.062792 105.09375 28.96875 L 105.09375 30.9375 L 105.09375 32.59375 L 105.09375 34.78125 C 106.02697 34.700686 107.03067 34.54388 108.03125 34.3125 C 113.39667 33.07177 117.81612 29.961838 120.78125 26.46875 L 112.6875 26.46875 z " transform="matrix(1.00631,0,0,1.00631,-9.76019e-4,-0.772966)" id="path11610" /> <path id="path14317" d="M 74.706878,56.328972 L 33.105899,97.929959" style="opacity:0.35655739;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient15192);stroke-width:10.01680565;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> <path style="opacity:0.53688528;fill:#c5c5c5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 89.656712,30.354292 C 90.147952,32.680027 92.244725,34.411058 94.787893,34.411059 C 97.331055,34.411059 99.4673,32.680028 99.958536,30.354292 C 99.103765,32.286307 97.092249,33.645631 94.787893,33.645631 C 92.483533,33.645631 90.511491,32.286307 89.656712,30.354292 z " id="path11672" /> <path style="fill:url(#linearGradient12566);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;opacity:0.30327869" d="M 100.18163,26.901091 C 101.33249,30.951757 103.83808,29.993287 105.1151,33.72654 L 105.1151,36.081713 C 100.54929,34.644208 98.892965,34.944024 96.686058,33.322037 C 98.825095,32.488947 100.73865,30.734861 100.18163,26.901091 z " id="path12550" sodipodi:nodetypes="ccccc" /> </g> </svg> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/palette.svg����������������������������������������������������������0000644�0001750�0000144�00000056274�11206455433�016720� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="122" height="122" viewBox="-0.122 0.464 116 122" id="svg2" xml:space="preserve" style="overflow:visible" sodipodi:version="0.32" inkscape:version="0.46" sodipodi:docname="palette.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata id="metadata48"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview inkscape:window-height="1136" inkscape:window-width="1600" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" showgrid="false" inkscape:zoom="4.3442623" inkscape:cx="61" inkscape:cy="105.20601" inkscape:window-x="-4" inkscape:window-y="-5" inkscape:current-layer="svg2" /><defs id="defs81"><inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 61 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="122 : 61 : 1" inkscape:persp3d-origin="61 : 40.666667 : 1" id="perspective50" /> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_1_" y2="121.414" x2="34.822201" y1="25.107901" x1="39.293499"> <stop offset="0.0056" style="stop-color:#ffae21;stop-opacity:1" id="stop8" /> <stop offset="0.98879999" style="stop-color:#ffffbd;stop-opacity:1" id="stop10" /> <a:midPointStop offset="0.0056" style="stop-color:#FFAE21" /> <a:midPointStop offset="0.5" style="stop-color:#FFAE21" /> <a:midPointStop offset="0.9888" style="stop-color:#FFFFBD" /> </linearGradient> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_2_" y2="122.347" x2="55.1408" y1="26.045401" x1="59.611801"> <stop offset="0.0056" style="stop-color:#ffae21;stop-opacity:1" id="stop15" /> <stop offset="0.98879999" style="stop-color:#ffffbd;stop-opacity:1" id="stop17" /> <a:midPointStop offset="0.0056" style="stop-color:#FFAE21" /> <a:midPointStop offset="0.5" style="stop-color:#FFAE21" /> <a:midPointStop offset="0.9888" style="stop-color:#FFFFBD" /> </linearGradient> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_3_" y2="40.991299" x2="109.016" y1="70.556198" x1="5.9110999"> <stop offset="0.0056" style="stop-color:#ffae21;stop-opacity:1" id="stop22" /> <stop offset="0.98879999" style="stop-color:#ffffbd;stop-opacity:1" id="stop24" /> <a:midPointStop offset="0.0056" style="stop-color:#FFAE21" /> <a:midPointStop offset="0.5" style="stop-color:#FFAE21" /> <a:midPointStop offset="0.9888" style="stop-color:#FFFFBD" /> </linearGradient> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_4_" y2="42.115398" x2="107.473" y1="69.8853" x1="10.6279"> <stop offset="0.0056" style="stop-color:#ffae21;stop-opacity:1" id="stop29" /> <stop offset="0.98879999" style="stop-color:#ffffbd;stop-opacity:1" id="stop31" /> <a:midPointStop offset="0.0056" style="stop-color:#FFAE21" /> <a:midPointStop offset="0.5" style="stop-color:#FFAE21" /> <a:midPointStop offset="0.9888" style="stop-color:#FFFFBD" /> </linearGradient> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_5_" y2="114.324" x2="58.077099" y1="22.0371" x1="58.077099"> <stop offset="0" style="stop-color:#744426;stop-opacity:1" id="stop36" /> <stop offset="1" style="stop-color:#de972b;stop-opacity:1" id="stop38" /> <a:midPointStop offset="0" style="stop-color:#744426" /> <a:midPointStop offset="0.5" style="stop-color:#744426" /> <a:midPointStop offset="1" style="stop-color:#DE972B" /> </linearGradient> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_6_" y2="114.32" x2="34.992699" y1="22.040001" x1="34.992699"> <stop offset="0" style="stop-color:#744426;stop-opacity:1" id="stop43" /> <stop offset="1" style="stop-color:#de972b;stop-opacity:1" id="stop45" /> <a:midPointStop offset="0" style="stop-color:#744426" /> <a:midPointStop offset="0.5" style="stop-color:#744426" /> <a:midPointStop offset="1" style="stop-color:#DE972B" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#XMLID_6_" id="linearGradient2459" gradientUnits="userSpaceOnUse" x1="34.992699" y1="22.040001" x2="34.992699" y2="114.32" gradientTransform="translate(6.3441463e-2,0.4859544)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_5_" id="linearGradient2462" gradientUnits="userSpaceOnUse" x1="58.077099" y1="22.0371" x2="58.077099" y2="114.324" gradientTransform="translate(58.761555,15.448219)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="linearGradient2465" gradientUnits="userSpaceOnUse" x1="10.6279" y1="69.8853" x2="107.473" y2="42.115398" gradientTransform="translate(6.3441463e-2,0.4859544)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_3_" id="linearGradient2468" gradientUnits="userSpaceOnUse" x1="5.9110999" y1="70.556198" x2="109.016" y2="40.991299" gradientTransform="translate(6.3441463e-2,0.4859544)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient2471" gradientUnits="userSpaceOnUse" x1="59.611801" y1="26.045401" x2="55.1408" y2="122.347" gradientTransform="translate(6.3441463e-2,0.4859544)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_1_" id="linearGradient2474" gradientUnits="userSpaceOnUse" x1="39.293499" y1="25.107901" x2="34.822201" y2="121.414" gradientTransform="translate(6.3441463e-2,0.4859544)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_5_" id="linearGradient2502" gradientUnits="userSpaceOnUse" gradientTransform="translate(-2.9434638,1.0650497)" x1="58.077099" y1="22.0371" x2="58.077099" y2="114.324" /></defs> <path style="fill:none" id="path5" d="M 33.198441,100.00895 C 37.311441,100.58995 42.003441,97.139954 44.246441,92.133954 C 43.993441,88.264954 41.865441,85.320954 38.465441,84.843954 C 34.671441,84.312954 30.415441,87.005954 27.797441,91.199954 C 27.336441,95.771954 29.447441,99.482954 33.198441,100.00895 z" /><path style="fill:url(#linearGradient2474)" id="path12" d="M 38.466441,84.843954 C 41.866441,85.321954 43.994441,88.264954 44.247441,92.133954 C 44.472441,91.631954 44.681441,91.119954 44.853441,90.588954 C 46.743441,84.759954 44.596441,79.485954 40.068441,78.850954 C 35.540441,78.216954 30.304441,82.452954 28.414441,88.276954 C 28.090441,89.275954 27.893441,90.255954 27.797441,91.200954 C 30.416441,87.005954 34.671441,84.312954 38.466441,84.843954 z" /><path style="fill:url(#linearGradient2471)" id="path19" d="M 103.15144,9.8099544 C 101.97244,8.8379544 100.74144,7.9579544 99.473441,7.1409544 C 99.962441,7.5049544 100.45144,7.8689544 100.92444,8.2589544 C 128.19444,30.745954 102.92344,78.753954 96.873441,84.133954 C 90.824441,89.520954 88.473441,90.856954 81.874441,91.870954 C 75.272441,92.883954 66.127441,85.220954 58.963441,91.555954 C 51.796441,97.888954 52.534441,104.23595 49.166441,109.15095 C 47.022441,112.27695 42.818441,113.52795 38.949441,114.28795 C 30.678441,113.63395 23.068441,110.74995 16.928441,105.43995 C -2.8035585,88.384954 -0.032558537,52.645954 23.099441,25.884954 C 24.244441,24.560954 25.424441,23.296954 26.621441,22.067954 C 24.490441,24.095954 22.416441,26.245954 20.429441,28.545954 C -4.1575585,56.990954 -7.1035585,94.977954 13.870441,113.10495 C 20.396441,118.74895 28.485441,121.81395 37.276441,122.50895 C 41.389441,121.70095 45.857441,120.37095 48.136441,117.04895 C 51.716441,111.82395 50.932441,105.07795 58.549441,98.346954 C 66.164441,91.613954 75.885441,99.758954 82.902441,98.682954 C 89.917441,97.604954 92.416441,96.183954 98.845441,90.457954 C 105.27544,84.739954 132.13644,33.711954 103.15144,9.8099544 z" /><path style="fill:url(#linearGradient2468)" id="path26" d="M 16.928441,105.43895 C 23.068441,110.74895 30.678441,113.63195 38.949441,114.28695 C 42.819441,113.52695 47.022441,112.27595 49.166441,109.14995 C 52.534441,104.23495 51.796441,97.887954 58.963441,91.554954 C 66.127441,85.219954 75.273441,92.882954 81.874441,91.869954 C 88.473441,90.854954 90.824441,89.518954 96.873441,84.132954 C 102.92344,78.752954 128.19344,30.744954 100.92444,8.2579544 C 100.45044,7.8679544 99.962441,7.5039544 99.473441,7.1399544 C 79.602441,-5.6790456 49.410441,0.3819544 26.621441,22.067954 C 25.423441,23.296954 24.243441,24.560954 23.099441,25.884954 C -0.032558537,52.645954 -2.8035585,88.384954 16.928441,105.43895 z M 26.078441,94.861954 C 26.503441,93.551954 27.095441,92.325954 27.797441,91.199954 C 27.892441,90.254954 28.089441,89.274954 28.414441,88.275954 C 30.304441,82.451954 35.540441,78.215954 40.068441,78.849954 C 44.596441,79.485954 46.743441,84.759954 44.853441,90.588954 C 44.681441,91.119954 44.472441,91.631954 44.247441,92.133954 C 44.352441,93.739954 44.142441,95.502954 43.552441,97.320954 C 41.540441,103.51295 35.974441,108.01295 31.164441,107.33395 C 26.352441,106.65795 24.066441,101.05795 26.078441,94.861954 z" /><path style="fill:url(#linearGradient2465)" id="path33" d="M 16.928441,105.54595 C 23.068441,110.79095 30.678441,113.63995 38.949441,114.28595 C 42.819441,113.53495 47.022441,112.29995 49.166441,109.21195 C 52.534441,104.35595 51.796441,98.085954 58.963441,91.829954 C 66.127441,85.570954 75.273441,93.141954 81.874441,92.141954 C 88.473441,91.138954 90.824441,89.819954 96.873441,84.496954 C 102.92344,79.182954 128.19344,31.754954 100.92444,9.5399544 C 100.45044,9.1549544 99.962441,8.7949544 99.473441,8.4359544 C 79.602441,-4.2280456 49.410441,1.7589544 26.621441,23.182954 C 25.423441,24.396954 24.243441,25.644954 23.099441,26.953954 C -0.032558537,53.390954 -2.8035585,88.697954 16.928441,105.54595 z M 26.078441,95.097954 C 26.503441,93.803954 27.095441,92.591954 27.797441,91.479954 C 27.892441,90.545954 28.089441,89.578954 28.414441,88.590954 C 30.304441,82.836954 35.540441,78.652954 40.068441,79.278954 C 44.595441,79.906954 46.743441,85.116954 44.853441,90.874954 C 44.681441,91.399954 44.472441,91.905954 44.247441,92.400954 C 44.352441,93.987954 44.142441,95.729954 43.552441,97.524954 C 41.540441,103.64195 35.974441,108.08795 31.164441,107.41695 C 26.352441,106.74995 24.066441,101.21795 26.078441,95.097954 z" /><path style="fill:url(#linearGradient2459);fill-rule:evenodd" d="M 40.0625 82.1875 C 35.04633 82.05424 29.897251 86.421874 27.96875 92.875 C 25.76875 100.257 28.571498 107.66775 34.1875 109.34375 C 39.8015 111.01975 46.169998 106.34675 48.375 98.96875 C 50.577 91.58875 47.798499 84.205249 42.1875 82.53125 C 41.484875 82.3215 40.779096 82.206537 40.0625 82.1875 z M 41.28125 84.96875 C 41.831824 84.984986 42.36075 85.049875 42.875 85.21875 C 46.984002 86.569748 48.15675 92.50425 45.46875 98.40625 C 42.780748 104.31125 37.237 108.00725 33.125 106.65625 C 29.013 105.30625 27.84725 99.404 30.53125 93.5 C 32.88675 88.333999 37.427231 84.855096 41.28125 84.96875 z " transform="translate(-3.122,0.464)" id="path47" /><path style="opacity:0.2;fill-rule:evenodd" id="path49" d="M 11.212441,55.506954 L 12.293441,56.650954 L 13.505441,57.702954 L 14.742441,58.721954 L 15.877441,59.757954 L 16.794441,60.792954 L 17.395441,61.844954 L 17.654441,63.056954 L 17.621441,64.563954 L 17.391441,66.278954 L 17.100441,68.077954 L 16.901441,69.859954 L 16.982441,71.582954 L 17.635441,73.169954 L 19.163441,74.245954 L 21.044441,74.291954 L 22.469441,73.245954 L 23.439441,71.750954 L 24.203441,70.068954 L 24.893441,68.357954 L 25.574441,66.840954 L 26.254441,65.784954 L 26.817441,65.352954 L 27.188441,65.344954 L 27.689441,65.671954 L 28.348441,66.471954 L 29.022441,67.539954 L 29.701441,68.643954 L 30.513441,69.653954 L 31.940441,70.214954 L 33.176441,69.047954 L 33.614441,67.483954 L 33.473441,65.888954 L 33.032441,64.301954 L 32.448441,62.738954 L 31.865441,61.221954 L 31.407441,59.853954 L 31.198441,58.743954 L 31.276441,58.031954 L 31.351441,57.924954 L 31.825441,58.073954 L 32.625441,58.462954 L 33.603441,58.927954 L 34.764441,59.250954 L 36.097441,59.019954 L 37.056441,57.950954 L 37.663441,56.558954 L 38.185441,55.000954 L 38.623441,53.251954 L 38.923441,51.386954 L 39.041441,49.487954 L 38.913441,47.614954 L 38.464441,45.857954 L 37.575441,44.278954 L 36.214441,43.196954 L 34.609441,42.810954 L 32.991441,42.898954 L 31.412441,43.226954 L 29.904441,43.623954 L 28.523441,43.938954 L 27.375441,44.050954 L 26.559441,43.896954 L 25.969441,43.466954 L 25.428441,42.625954 L 24.954441,41.469954 L 24.518441,40.180954 L 24.052441,38.929954 L 23.354441,37.769954 L 22.026441,37.110954 L 20.489441,37.756954 L 19.424441,39.094954 L 18.898441,40.718954 L 18.689441,42.475954 L 18.633441,44.285954 L 18.619441,46.063954 L 18.535441,47.683954 L 18.300441,49.009954 L 17.898441,49.891954 L 17.376441,50.341954 L 16.620441,50.531954 L 15.572441,50.531954 L 14.363441,50.393954 L 13.104441,50.271954 L 11.800441,50.352954 L 10.574441,51.073954 L 10.102441,52.597954 L 10.402441,54.179954 L 11.212441,55.506954 M 74.463441,16.011954 L 74.207441,17.660954 L 74.658441,19.181954 L 75.507441,20.445954 L 76.523441,21.534954 L 77.525441,22.529954 L 78.370441,23.465954 L 78.910441,24.306954 L 79.089441,25.048954 L 78.929441,25.728954 L 78.412441,26.457954 L 77.555441,27.265954 L 76.524441,28.131954 L 75.488441,29.109954 L 74.634441,30.318954 L 74.307441,31.856954 L 74.834441,33.509954 L 75.977441,35.071954 L 77.481441,36.525954 L 79.263441,37.901954 L 81.231441,39.144954 L 83.286441,40.221954 L 85.347441,41.066954 L 87.319441,41.638954 L 89.183441,41.853954 L 90.820441,41.501954 L 91.752441,40.315954 L 91.898441,38.928954 L 91.736441,37.601954 L 91.507441,36.321954 L 91.384441,35.182954 L 91.471441,34.353954 L 91.789441,33.818954 L 92.455441,33.387954 L 93.508441,33.064954 L 94.830441,32.849954 L 96.301441,32.680954 L 97.805441,32.468954 L 99.274441,32.104954 L 100.62744,31.424954 L 101.65144,30.244954 L 102.02344,28.781954 L 101.69144,27.451954 L 100.96344,26.378954 L 100.08044,25.466954 L 99.165441,24.638954 L 98.338441,23.850954 L 97.734441,23.101954 L 97.406441,22.400954 L 97.319441,21.663954 L 97.418441,20.793954 L 97.664441,19.807954 L 97.963441,18.717954 L 98.223441,17.553954 L 98.320441,16.294954 L 98.087441,14.968954 L 97.417441,13.717954 L 96.442441,12.603954 L 95.315441,11.571954 L 94.036441,10.627954 L 92.618441,9.7789544 L 91.089441,9.0869544 L 89.483441,8.5859544 L 87.814441,8.3129544 L 86.124441,8.3169544 L 84.407441,8.6099544 L 82.663441,9.1339544 L 80.940441,9.8709544 L 79.278441,10.790954 L 77.745441,11.872954 L 76.391441,13.102954 L 75.277441,14.470954 L 74.463441,16.011954 M 49.362441,18.074954 L 48.103441,18.770954 L 46.562441,19.391954 L 44.846441,19.996954 L 43.062441,20.617954 L 41.316441,21.325954 L 39.696441,22.187954 L 38.303441,23.314954 L 37.296441,24.814954 L 36.975441,26.512954 L 37.419441,28.029954 L 38.320441,29.263954 L 39.403441,30.295954 L 40.522441,31.243954 L 41.519441,32.150954 L 42.254441,33.025954 L 42.636441,33.870954 L 42.702441,34.827954 L 42.487441,35.985954 L 42.070441,37.290954 L 41.567441,38.665954 L 41.122441,40.082954 L 40.886441,41.540954 L 41.106441,43.027954 L 42.054441,44.336954 L 43.488441,45.057954 L 44.959441,45.045954 L 46.312441,44.585954 L 47.584441,43.910954 L 48.827441,43.185954 L 50.036441,42.526954 L 51.199441,42.063954 L 52.290441,41.872954 L 53.483441,42.017954 L 54.900441,42.481954 L 56.466441,43.148954 L 58.106441,43.865954 L 59.782441,44.487954 L 61.487441,44.835954 L 63.211441,44.669954 L 64.768441,43.679954 L 65.625441,42.063954 L 65.489441,40.368954 L 64.801441,38.835954 L 63.872441,37.377954 L 62.910441,35.965954 L 62.115441,34.606954 L 61.651441,33.376954 L 61.622441,32.278954 L 62.039441,31.188954 L 62.885441,30.040954 L 64.045441,28.864954 L 65.371441,27.678954 L 66.700441,26.456954 L 67.886441,25.155954 L 68.748441,23.672954 L 68.992441,21.928954 L 68.342441,20.341954 L 66.924441,19.745954 L 65.483441,19.852954 L 64.079441,20.196954 L 62.720441,20.572954 L 61.514441,20.804954 L 60.663441,20.783954 L 60.205441,20.535954 L 59.928441,20.000954 L 59.853441,19.030954 L 60.003441,17.713954 L 60.264441,16.234954 L 60.486441,14.709954 L 60.479441,13.188954 L 59.900441,11.734954 L 58.463441,10.861954 L 56.801441,10.832954 L 55.413441,11.454954 L 54.274441,12.440954 L 53.274441,13.621954 L 52.334441,14.880954 L 51.385441,16.115954 L 50.407441,17.209954 L 49.362441,18.074954" /><g id="g51" transform="translate(6.3441463e-2,0.4859544)"> <path style="fill:#ff0000;fill-rule:evenodd" id="path53" d="M 10.339,51.565 C 10.447,48.356 15.988,52.161 17.919,49.437 C 19.854,46.716 17.643,39.556 20.314,37.509 C 22.986,35.463 22.454,42.602 25.335,43.77 C 28.219,44.942 33.565,40.861 35.975,43.865 C 38.38,46.865 36.764,53.579 35.376,56.304 C 33.984,59.023 30.415,53.918 29.48,56.579 C 28.543,59.229 32.968,64.781 31.466,67.412 C 29.96,70.039 28.537,62.186 25.657,63.257 C 22.776,64.319 22.322,73.432 18.69,72.144 C 15.059,70.86 19,63.966 17.548,60.39 C 16.094,56.802 10.231,54.772 10.339,51.565 z" /> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_7_" y2="33.8354" x2="23.812" y1="63.070801" x1="23.812"> <stop offset="0.30000001" style="stop-color:#ff0000;stop-opacity:1" id="stop56" /> <stop offset="0.69999999" style="stop-color:#ffffff;stop-opacity:1" id="stop58" /> <a:midPointStop offset="0.3" style="stop-color:#FF0000" /> <a:midPointStop offset="0.5" style="stop-color:#FF0000" /> <a:midPointStop offset="0.7" style="stop-color:#FFFFFF" /> </linearGradient> <path style="fill:url(#XMLID_7_);fill-rule:evenodd" id="path60" d="M 12.745,52.038 C 12.834,49.385 17.418,52.527 19.015,50.273 C 20.615,48.025 18.787,42.101 20.996,40.41 C 23.206,38.72 22.767,44.624 25.149,45.59 C 27.534,46.559 31.957,43.182 33.95,45.668 C 35.941,48.15 34.605,53.705 33.455,55.958 C 32.305,58.203 29.351,53.977 28.578,56.182 C 27.803,58.378 31.464,62.976 30.224,65.143 C 28.976,67.318 27.8,60.822 25.417,61.709 C 23.033,62.587 22.658,70.122 19.654,69.059 C 16.65,67.997 19.911,62.296 18.709,59.33 C 17.505,56.372 12.655,54.689 12.745,52.038 z" /> <path style="fill:#009700;fill-rule:evenodd" id="path62" d="M 49.131,17.833 C 45.796,20.067 38.981,20.568 37.454,24.123 C 35.927,27.686 42.049,29.302 42.836,32.534 C 43.623,35.762 39.387,40.323 41.925,42.448 C 44.463,44.573 47.824,39.851 51.458,39.751 C 55.093,39.655 60.508,44.685 63.189,41.872 C 65.866,39.063 59.05,34.912 59.79,31.009 C 60.527,27.111 67.51,24.45 67.142,20.97 C 66.774,17.494 60.723,22.358 58.641,20.191 C 56.559,18.024 60.65,11.602 57.363,10.786 C 54.072,9.975 52.466,15.601 49.131,17.833 z" /> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_8_" y2="4.6629" x2="54.515202" y1="43.037102" x1="50.078098"> <stop offset="0.24160001" style="stop-color:#009f00;stop-opacity:1" id="stop65" /> <stop offset="0.77999997" style="stop-color:#ffffff;stop-opacity:1" id="stop67" /> <a:midPointStop offset="0.2416" style="stop-color:#009F00" /> <a:midPointStop offset="0.5" style="stop-color:#009F00" /> <a:midPointStop offset="0.78" style="stop-color:#FFFFFF" /> </linearGradient> <path style="fill:url(#XMLID_8_);fill-rule:evenodd" id="path69" d="M 49.711,19.42 C 46.929,21.285 41.246,21.7 39.975,24.666 C 38.703,27.637 43.808,28.983 44.462,31.676 C 45.119,34.369 41.587,38.173 43.702,39.946 C 45.819,41.72 48.622,37.779 51.653,37.701 C 54.683,37.618 59.199,41.815 61.432,39.466 C 63.665,37.125 57.983,33.666 58.598,30.409 C 59.214,27.157 65.036,24.94 64.73,22.04 C 64.419,19.139 59.375,23.196 57.641,21.389 C 55.906,19.583 59.315,14.226 56.574,13.546 C 53.832,12.867 52.494,17.561 49.711,19.42 z" /> <path style="fill:#3d60ff;fill-rule:evenodd" id="path71" d="M 74.637,15.245 C 73.27,18.779 79.269,20.788 79.325,23.953 C 79.384,27.119 72.913,28.391 74.943,31.949 C 76.973,35.512 84.419,39.721 88.325,39.735 C 92.227,39.752 88.03,34.096 90.221,32 C 92.415,29.907 98.492,31.416 99.909,28.673 C 101.329,25.93 96.325,24.277 95.603,21.596 C 94.882,18.911 97.77,15.841 95.756,13.211 C 93.747,10.584 89.434,7.858 85.399,8.243 C 81.365,8.632 76,11.715 74.637,15.245 z" /> <linearGradient gradientUnits="userSpaceOnUse" id="XMLID_9_" y2="3.5658" x2="87.218803" y1="30.395" x1="87.218803"> <stop offset="0.25" style="stop-color:#3f72ff;stop-opacity:1" id="stop74" /> <stop offset="0.75" style="stop-color:#ffffff;stop-opacity:1" id="stop76" /> <a:midPointStop offset="0.25" style="stop-color:#3F72FF" /> <a:midPointStop offset="0.5" style="stop-color:#3F72FF" /> <a:midPointStop offset="0.75" style="stop-color:#FFFFFF" /> </linearGradient> <path style="fill:url(#XMLID_9_);fill-rule:evenodd" id="path78" d="M 76.058,16.268 C 74.852,19.388 80.148,21.161 80.201,23.961 C 80.256,26.754 74.537,27.877 76.331,31.022 C 78.126,34.166 84.697,37.883 88.147,37.895 C 91.594,37.907 87.887,32.915 89.826,31.067 C 91.762,29.215 97.132,30.549 98.381,28.126 C 99.633,25.707 95.212,24.248 94.579,21.878 C 93.94,19.508 96.489,16.799 94.714,14.475 C 92.937,12.15 89.13,9.747 85.564,10.088 C 81.999,10.431 77.264,13.148 76.058,16.268 z" /> </g> <path style="fill:url(#linearGradient2502);fill-rule:evenodd" d="M 74.169984,0.5855807 C 56.021401,1.1009417 35.910608,10.865583 20.544981,28.648081 C -4.0420208,57.092081 -6.9925158,95.080592 13.982481,113.21059 C 20.507483,118.85359 28.596731,121.92183 37.388731,122.61684 C 41.500731,121.80884 45.984731,120.47409 48.263731,117.14809 C 51.844731,111.92809 51.054981,105.19658 58.669981,98.460582 C 66.286984,91.724582 75.996734,99.880332 83.013734,98.804332 C 90.027734,97.723332 92.521234,96.311582 98.951234,90.585582 C 105.38124,84.863582 132.24374,33.83133 103.26374,9.9293307 C 95.241734,3.3154557 85.059134,0.2763637 74.169984,0.5855807 z M 73.544984,4.5543307 C 83.741824,4.2362077 93.180734,7.0232067 100.54499,13.148081 C 127.15999,35.294082 100.96124,82.780832 94.826234,88.116832 C 88.681234,93.453832 86.320484,94.780332 79.732484,95.804332 C 73.145484,96.826332 64.223234,89.272332 56.951231,95.554332 C 49.682231,101.83933 50.253981,108.12684 46.794981,112.99184 C 44.590981,116.08584 40.379731,117.32059 36.513731,118.08559 C 28.299729,117.46059 20.813233,114.61909 14.826231,109.39809 C -4.4167708,92.602092 -0.84827085,57.283081 22.763731,30.773081 C 37.519357,14.203083 56.550241,5.0845357 73.544984,4.5543307 z" id="path40" /></svg>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/session.svg����������������������������������������������������������0000644�0001750�0000144�00000065225�11170306677�016746� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="79" height="79" id="svg2273"> <defs id="defs2275"> <filter id="filter3763"> <feGaussianBlur id="feGaussianBlur3765" stdDeviation="1.389375" inkscape:collect="always" /> </filter> <linearGradient x1="341.5318" y1="528.58008" x2="341.5318" y2="700.07751" id="linearGradient2758" xlink:href="#linearGradient3184" gradientUnits="userSpaceOnUse" spreadMethod="reflect" /> <radialGradient cx="902.44019" cy="573.33636" r="252.67184" fx="902.44019" fy="777.67505" id="radialGradient3552" xlink:href="#linearGradient3152" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.1266434,0,0,0.1104619,244.86927,337.74843)" /> <radialGradient cx="949.625" cy="517.85107" r="119.39729" fx="942.22406" fy="440.14154" id="radialGradient2762" xlink:href="#linearGradient3220" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.7097296,6.4528328e-2,-5.2167868e-2,0.9870304,-1209.4918,-86.255073)" /> <radialGradient cx="1302.5156" cy="396.677" r="252.67184" fx="1302.5156" fy="396.677" id="radialGradient2786" xlink:href="#linearGradient3452" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4615497,0,0,0.7922186,-1517.0981,316.29645)" /> <linearGradient x1="1228.4824" y1="349.26135" x2="1228.4824" y2="687.31006" id="linearGradient2766" xlink:href="#linearGradient3285" gradientUnits="userSpaceOnUse" /> <linearGradient x1="341.5318" y1="528.58008" x2="341.5318" y2="700.07751" id="linearGradient2740" xlink:href="#linearGradient3184" gradientUnits="userSpaceOnUse" spreadMethod="reflect" /> <radialGradient cx="902.44019" cy="573.33636" r="252.67184" fx="902.44019" fy="777.67505" id="radialGradient3544" xlink:href="#linearGradient3152" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.1266434,0,0,0.1104619,244.86927,327.31435)" /> <filter id="filter3275"> <feGaussianBlur inkscape:collect="always" stdDeviation="5.6853481" id="feGaussianBlur3277" /> </filter> <radialGradient cx="949.625" cy="517.85107" r="119.39729" fx="942.22406" fy="440.14154" id="radialGradient2744" xlink:href="#linearGradient3220" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.7097296,6.4528328e-2,-5.2167868e-2,0.9870304,-1209.4918,-86.255073)" /> <radialGradient cx="1302.5156" cy="396.677" r="252.67184" fx="1302.5156" fy="396.677" id="radialGradient2746" xlink:href="#linearGradient3452" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4615497,0,0,0.7922186,-1517.0981,316.29645)" /> <linearGradient x1="1228.4824" y1="349.26135" x2="1228.4824" y2="687.31006" id="linearGradient2748" xlink:href="#linearGradient3285" gradientUnits="userSpaceOnUse" /> <linearGradient x1="341.5318" y1="528.58008" x2="341.5318" y2="700.07751" id="linearGradient2720" xlink:href="#linearGradient3184" gradientUnits="userSpaceOnUse" spreadMethod="reflect" /> <radialGradient cx="902.44019" cy="573.33636" r="252.67184" fx="902.44019" fy="777.67505" id="radialGradient3536" xlink:href="#linearGradient3152" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.1266434,0,0,0.1104619,244.86927,316.33112)" /> <radialGradient cx="949.33209" cy="517.87024" r="119.39729" fx="941.93115" fy="440.16125" id="radialGradient3533" xlink:href="#linearGradient3220" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.216526,9.0242221e-3,-6.6067162e-3,0.1380352,157.02375,289.42458)" /> <radialGradient cx="1302.5156" cy="396.677" r="252.67184" fx="1302.5156" fy="396.677" id="radialGradient2726" xlink:href="#linearGradient3452" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4615497,0,0,0.7922186,-1517.0981,316.29645)" /> <linearGradient x1="1228.4824" y1="349.26135" x2="1228.4824" y2="687.31006" id="linearGradient2728" xlink:href="#linearGradient3285" gradientUnits="userSpaceOnUse" /> <filter id="filter3514"> <feGaussianBlur inkscape:collect="always" stdDeviation="4.19576" id="feGaussianBlur3516" /> </filter> <linearGradient id="linearGradient3184"> <stop style="stop-color:#d3d3d3;stop-opacity:1" offset="0" id="stop3186" /> <stop style="stop-color:#e4e4e4;stop-opacity:1" offset="0.26213592" id="stop4736" /> <stop style="stop-color:#dfdfdf;stop-opacity:1" offset="0.63106799" id="stop6676" /> <stop style="stop-color:#c0c0c0;stop-opacity:1" offset="1" id="stop3188" /> </linearGradient> <linearGradient x1="341.5318" y1="452.76285" x2="341.5318" y2="668.31335" id="linearGradient2700" xlink:href="#linearGradient3184" gradientUnits="userSpaceOnUse" spreadMethod="reflect" /> <linearGradient id="linearGradient3152"> <stop style="stop-color:#a7a7a7;stop-opacity:1" offset="0" id="stop3154" /> <stop style="stop-color:#b7b7b7;stop-opacity:1" offset="0.28746885" id="stop3166" /> <stop style="stop-color:#f2f2f2;stop-opacity:1" offset="0.35849056" id="stop3160" /> <stop style="stop-color:#858585;stop-opacity:1" offset="0.69134921" id="stop3162" /> <stop style="stop-color:#8f8f8f;stop-opacity:1" offset="0.76705599" id="stop3164" /> <stop style="stop-color:#a4a4a4;stop-opacity:1" offset="0.84946543" id="stop3182" /> <stop style="stop-color:#757575;stop-opacity:1" offset="0.88352799" id="stop3178" /> <stop style="stop-color:#989898;stop-opacity:1" offset="0.912646" id="stop3180" /> <stop style="stop-color:#acacac;stop-opacity:1" offset="1" id="stop3156" /> </linearGradient> <radialGradient cx="902.44019" cy="573.33636" r="252.67184" fx="902.44019" fy="777.67505" id="radialGradient3526" xlink:href="#linearGradient3152" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.1266434,0,0,0.1104619,244.86927,305.34788)" /> <linearGradient id="linearGradient3452"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop3454" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop3456" /> </linearGradient> <radialGradient cx="1302.5156" cy="396.677" r="252.67184" fx="1302.5156" fy="396.677" id="radialGradient2706" xlink:href="#linearGradient3452" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4615497,0,0,0.7922186,-1517.0981,316.29645)" /> <filter id="filter3480"> <feGaussianBlur inkscape:collect="always" stdDeviation="4.7167893" id="feGaussianBlur3482" /> </filter> <linearGradient id="linearGradient3285"> <stop style="stop-color:#474747;stop-opacity:1" offset="0" id="stop3287" /> <stop style="stop-color:#474747;stop-opacity:0" offset="1" id="stop3289" /> </linearGradient> <linearGradient x1="1228.4824" y1="349.26135" x2="1228.4824" y2="687.31006" id="linearGradient2708" xlink:href="#linearGradient3285" gradientUnits="userSpaceOnUse" /> <filter id="filter3691"> <feGaussianBlur id="feGaussianBlur3693" stdDeviation="0.53842579" inkscape:collect="always" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3184" id="linearGradient3629" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="341.5318" y1="452.76285" x2="341.5318" y2="637.24835" /> <clipPath id="clipPath3625"> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,119.28636,-49.149663)" style="fill:url(#linearGradient3629);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path3627" /> </clipPath> <linearGradient id="linearGradient3695"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop3697" /> <stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop3699" /> </linearGradient> <linearGradient x1="154.53911" y1="13.390625" x2="154.03125" y2="47.890625" id="linearGradient3701" xlink:href="#linearGradient3695" gradientUnits="userSpaceOnUse" /> <filter id="filter5405"> <feGaussianBlur id="feGaussianBlur5407" stdDeviation="0.18142299" inkscape:collect="always" /> </filter> <linearGradient id="linearGradient3220"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop3222" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop3224" /> </linearGradient> <radialGradient cx="949.33209" cy="517.87024" r="119.39729" fx="941.93115" fy="440.16125" id="radialGradient5382" xlink:href="#linearGradient3220" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.2422167,9.0611786e-3,-7.3905988e-3,0.1386005,133.21096,277.40424)" /> </defs> <g transform="translate(-319.68276,-344.82312)" id="layer1"> <path d="M 359.15738,346.06295 C 341.49338,346.06295 327.15738,353.99751 327.15738,363.75045 C 327.15738,364.53843 327.25728,365.30217 327.43863,366.06295 L 327.15738,366.06295 L 327.15738,396.2817 L 327.15738,402.06295 L 327.25113,402.2192 L 327.28238,403.31295 C 327.28238,413.0659 341.49293,421.00045 359.15738,421.00045 C 376.8218,421.00045 391.03238,413.0659 391.03238,403.31295 L 391.06363,402.18795 L 391.15738,402.06295 L 391.15738,366.06295 L 390.87613,366.06295 C 391.05748,365.30217 391.15738,364.53843 391.15738,363.75045 C 391.15738,353.99751 376.82138,346.06295 359.15738,346.06295 z " style="opacity:0.4;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3763)" id="path2776" /> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,315.90463,315.26842)" style="fill:#7a7a7a;fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3514)" id="path3490" /> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,315.90463,307.02094)" style="fill:url(#linearGradient2758);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path2161" /> <path d="M 391.1566,396.1378 C 391.1566,405.89075 376.8194,413.80685 359.15541,413.80685 C 341.5834,413.80685 327.30642,405.97371 327.15816,396.29076 L 327.2848,403.31818 C 327.2848,413.07112 341.49536,420.98723 359.15937,420.98722 C 376.82337,420.98722 391.02996,413.07112 391.02996,403.31818 L 391.1566,396.1378 z " style="fill:url(#radialGradient3552);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path2168" /> <path d="M 566.27727,486.15744 C 579.07697,526.52416 502.66377,561.86523 387.09487,561.86523 C 265.94097,561.86523 190.88237,525.39212 207.91257,486.15744 C 230.12597,434.98116 310.39967,410.44965 387.09487,410.44965 C 461.01347,410.44965 551.85327,440.66801 566.27727,486.15744 z " transform="matrix(0.1266434,0,0,0.139849,310.1979,322.90458)" style="fill:url(#radialGradient2762);fill-opacity:1;stroke:none;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3275)" id="path3210" /> <path d="M 134.39008,519.23381 C 134.10378,521.69514 133.92128,524.1743 133.92138,526.67131 C 133.92138,596.41044 247.13058,653.01505 386.60878,653.01506 C 526.08708,653.01506 639.26508,596.41043 639.26508,526.67131 C 639.26508,524.1743 639.11388,521.69514 638.82758,519.23381 C 631.11908,585.51499 521.09308,638.14006 386.60878,638.14006 C 252.12458,638.14006 142.09858,585.51499 134.39008,519.23381 z " transform="matrix(0.1266434,0,0,0.139849,310.1979,322.90458)" style="fill:url(#radialGradient2786);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3480)" id="path3443" /> <path d="M 1050.3125,441.16063 C 1050.0262,443.62196 1049.8437,446.10112 1049.8438,448.59813 C 1049.8438,518.33726 1163.053,574.94187 1302.5312,574.94188 C 1442.0095,574.94188 1555.1875,518.33725 1555.1875,448.59813 C 1555.1875,446.10112 1555.0363,443.62196 1554.75,441.16063 C 1547.0415,507.44181 1437.0155,566.06688 1302.5312,566.06688 C 1168.047,566.06688 1058.021,507.44181 1050.3125,441.16063 z " transform="matrix(0.1240149,0,0,0.1369464,197.62608,334.12047)" style="opacity:0.50553505;fill:url(#linearGradient2766);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3480)" id="path3484" /> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,315.90463,304.83434)" style="fill:#7a7a7a;fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3514)" id="path3528" /> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,315.90463,296.58687)" style="fill:url(#linearGradient2740);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path3530" /> <path d="M 391.1566,385.70373 C 391.1566,395.45667 376.8194,403.37278 359.15541,403.37278 C 341.5834,403.37277 327.30642,395.53963 327.15816,385.85669 L 327.2848,392.8841 C 327.2848,402.63705 341.49536,410.55315 359.15937,410.55315 C 376.82337,410.55315 391.02996,402.63705 391.02996,392.8841 L 391.1566,385.70373 z " style="fill:url(#radialGradient3544);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path3532" /> <path d="M 566.27727,486.15744 C 579.07697,526.52416 502.66377,561.86523 387.09487,561.86523 C 265.94097,561.86523 190.88237,525.39212 207.91257,486.15744 C 230.12597,434.98116 310.39967,410.44965 387.09487,410.44965 C 461.01347,410.44965 551.85327,440.66801 566.27727,486.15744 z " transform="matrix(0.1266434,0,0,0.139849,310.1979,312.4705)" style="fill:url(#radialGradient2744);fill-opacity:1;stroke:none;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3275)" id="path3534" /> <path d="M 134.39008,519.23381 C 134.10378,521.69514 133.92128,524.1743 133.92138,526.67131 C 133.92138,596.41044 247.13058,653.01505 386.60878,653.01506 C 526.08708,653.01506 639.26508,596.41043 639.26508,526.67131 C 639.26508,524.1743 639.11388,521.69514 638.82758,519.23381 C 631.11908,585.51499 521.09308,638.14006 386.60878,638.14006 C 252.12458,638.14006 142.09858,585.51499 134.39008,519.23381 z " transform="matrix(0.1266434,0,0,0.139849,310.1979,312.4705)" style="fill:url(#radialGradient2746);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3480)" id="path3536" /> <path d="M 1050.3125,441.16063 C 1050.0262,443.62196 1049.8437,446.10112 1049.8438,448.59813 C 1049.8438,518.33726 1163.053,574.94187 1302.5312,574.94188 C 1442.0095,574.94188 1555.1875,518.33725 1555.1875,448.59813 C 1555.1875,446.10112 1555.0363,443.62196 1554.75,441.16063 C 1547.0415,507.44181 1437.0155,566.06688 1302.5312,566.06688 C 1168.047,566.06688 1058.021,507.44181 1050.3125,441.16063 z " transform="matrix(0.1240149,0,0,0.1369464,197.62608,323.6864)" style="opacity:0.50553505;fill:url(#linearGradient2748);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3480)" id="path3538" /> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,315.90463,293.8511)" style="fill:#7a7a7a;fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3514)" id="path3552" /> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,315.90463,285.60363)" style="fill:url(#linearGradient2720);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path3554" /> <path d="M 391.1566,374.72049 C 391.1566,384.47343 376.8194,392.38954 359.15541,392.38954 C 341.5834,392.38954 327.30642,384.5564 327.15816,374.87345 L 327.2848,381.90086 C 327.2848,391.65381 341.49536,399.56991 359.15937,399.56991 C 376.82337,399.56991 391.02996,391.65381 391.02996,381.90086 L 391.1566,374.72049 z " style="fill:url(#radialGradient3536);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path3556" /> <path d="M 381.91318,369.4759 C 383.53417,375.12114 373.85695,380.06356 359.22091,380.06356 C 343.87757,380.06356 334.37189,374.96283 336.52865,369.4759 C 339.34183,362.31895 349.50797,358.88824 359.22091,358.88824 C 368.58221,358.88824 380.08647,363.11425 381.91318,369.4759 z " style="fill:url(#radialGradient3533);fill-opacity:1;stroke:none;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path3558" /> <path d="M 134.39008,519.23381 C 134.10378,521.69514 133.92128,524.1743 133.92138,526.67131 C 133.92138,596.41044 247.13058,653.01505 386.60878,653.01506 C 526.08708,653.01506 639.26508,596.41043 639.26508,526.67131 C 639.26508,524.1743 639.11388,521.69514 638.82758,519.23381 C 631.11908,585.51499 521.09308,638.14006 386.60878,638.14006 C 252.12458,638.14006 142.09858,585.51499 134.39008,519.23381 z " transform="matrix(0.1266434,0,0,0.139849,310.1979,301.48726)" style="fill:url(#radialGradient2726);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3480)" id="path3560" /> <path d="M 1050.3125,441.16063 C 1050.0262,443.62196 1049.8437,446.10112 1049.8438,448.59813 C 1049.8438,518.33726 1163.053,574.94187 1302.5312,574.94188 C 1442.0095,574.94188 1555.1875,518.33725 1555.1875,448.59813 C 1555.1875,446.10112 1555.0363,443.62196 1554.75,441.16063 C 1547.0415,507.44181 1437.0155,566.06688 1302.5312,566.06688 C 1168.047,566.06688 1058.021,507.44181 1050.3125,441.16063 z " transform="matrix(0.1240149,0,0,0.1369464,197.62608,312.70316)" style="opacity:0.50553505;fill:url(#linearGradient2728);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3480)" id="path3562" /> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,315.90463,282.86787)" style="fill:#7a7a7a;fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3514)" id="path3590" /> <path d="M 594.20979 637.24835 A 252.67799 126.339 0 1 1 88.853806,637.24835 A 252.67799 126.339 0 1 1 594.20979 637.24835 z" transform="matrix(0.1266434,0,0,0.139849,315.90463,274.62039)" style="fill:url(#linearGradient2700);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path3592" /> <path d="M 391.1566,363.73725 C 391.1566,373.4902 376.8194,381.4063 359.15541,381.4063 C 341.5834,381.4063 327.30642,373.57316 327.15816,363.89021 L 327.2848,370.91763 C 327.2848,380.67057 341.49536,388.58667 359.15937,388.58667 C 376.82337,388.58667 391.02996,380.67057 391.02996,370.91763 L 391.1566,363.73725 z " style="fill:url(#radialGradient3526);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path3594" /> <path d="M 134.39008,519.23381 C 134.10378,521.69514 133.92128,524.1743 133.92138,526.67131 C 133.92138,596.41044 247.13058,653.01505 386.60878,653.01506 C 526.08708,653.01506 639.26508,596.41043 639.26508,526.67131 C 639.26508,524.1743 639.11388,521.69514 638.82758,519.23381 C 631.11908,585.51499 521.09308,638.14006 386.60878,638.14006 C 252.12458,638.14006 142.09858,585.51499 134.39008,519.23381 z " transform="matrix(0.1266434,0,0,0.139849,310.1979,290.50403)" style="fill:url(#radialGradient2706);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3480)" id="path3598" /> <path d="M 1050.3125,441.16063 C 1050.0262,443.62196 1049.8437,446.10112 1049.8438,448.59813 C 1049.8438,518.33726 1163.053,574.94187 1302.5312,574.94188 C 1442.0095,574.94188 1555.1875,518.33725 1555.1875,448.59813 C 1555.1875,446.10112 1555.0363,443.62196 1554.75,441.16063 C 1547.0415,507.44181 1437.0155,566.06688 1302.5312,566.06688 C 1168.047,566.06688 1058.021,507.44181 1050.3125,441.16063 z " transform="matrix(0.1240149,0,0,0.1369464,197.62608,301.71992)" style="opacity:0.50553505;fill:url(#linearGradient2708);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3480)" id="path3600" /> <path d="M 162.53125,22.3125 C 144.86725,22.3125 130.53125,30.215801 130.53125,39.96875 C 130.53125,40.13683 130.55404,40.301793 130.5625,40.46875 C 131.0449,30.947898 145.17167,23.3125 162.53125,23.3125 C 179.8904,23.3125 194.01694,30.948228 194.5,40.46875 C 194.50848,40.301559 194.53125,40.137066 194.53125,39.96875 C 194.53125,30.215803 180.19525,22.3125 162.53125,22.3125 z " transform="translate(196.62022,323.76193)" style="fill:url(#linearGradient3701);fill-opacity:1;stroke:none;stroke-width:1.125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3691)" clip-path="url(#clipPath3625)" id="path3572" /> <path d="M 384.78337,357.78339 C 386.5967,363.45175 375.77128,368.41441 359.39869,368.41441 C 342.23487,368.41441 331.60135,363.29279 334.01401,357.78339 C 337.16097,350.59713 348.53331,347.15237 359.39869,347.15237 C 369.8707,347.15237 382.73993,351.39568 384.78337,357.78339 z " style="fill:url(#radialGradient5382);fill-opacity:1;stroke:none;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5405)" id="path3596" /> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/normalize.svg��������������������������������������������������������0000644�0001750�0000144�00000007025�11162374370�017251� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="693.05713" height="646.52856" id="svg2273" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" sodipodi:docname="normalize.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2275" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="375" inkscape:cy="405.71429" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" showgrid="false" showguides="true" /> <metadata id="metadata2278"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-34.900002,-192.36219)"> <rect style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:20.487;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect5078" width="682.56995" height="636.04138" x="40.1436" y="197.60579" /> <path style="fill:#003c82;fill-opacity:1;fill-rule:evenodd;stroke:#003c82;stroke-width:29.27646446;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 359.99546,331.8875 L 403.57142,388.081 L 447.14738,331.8875 L 403.57142,331.8875 L 403.57142,219.50052 L 403.57142,331.8875 L 359.99546,331.8875 z " id="path10907" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:18.32107735;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 41.089283,532.51007 C 70.813239,655.02814 75.271831,672.71118 94.592406,682.81576 C 113.91299,692.92034 122.18914,541.67094 152.49735,536.81199 C 193.373,530.2589 193.48349,793.92625 237.26739,792.70311 C 277.00803,791.55544 271.44994,516.09011 308.60489,495.88096 C 345.75982,475.67178 353.19082,607.03138 388.85956,594.40066 C 424.52831,581.76991 408.18012,428.93809 448.30746,466.83028 C 488.43482,504.72248 510.72778,793.96619 558.28609,781.33545 C 605.84445,768.70473 585.03767,588.0853 626.65119,575.45456 C 668.26473,562.82382 721.76787,691.65727 721.76787,691.65727" id="path12847" sodipodi:nodetypes="cssssssssc" /> <path style="fill:none;fill-rule:evenodd;stroke:#00aa7f;stroke-width:14;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 63.5,428.86218 L 703.5,428.86218 L 703.5,428.86218" id="path13818" /> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/transform2.svg�������������������������������������������������������0000644�0001750�0000144�00000207455�11207732512�017353� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:ns="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="156" height="156" id="svg2365" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docname="transform2.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/MP3Diags/src/images"> <metadata id="metadata198"> <rdf:RDF> <ns:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </ns:Work> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <sodipodi:namedview inkscape:window-height="956" inkscape:window-width="891" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" showgrid="true" inkscape:zoom="1.463932" inkscape:cx="-43.819174" inkscape:cy="64" inkscape:window-x="251" inkscape:window-y="72" inkscape:current-layer="svg2365" /> <defs id="defs2367"> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective200" /> <filter x="-0.085532367" width="1.1710647" y="-0.10938701" height="1.218774" id="filter6906"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.5212367" id="feGaussianBlur6908" /> </filter> <clipPath id="clipPath6130"> <path d="M 125.16669,12.099598 C 122.19641,9.254864 111.282,2.992388 109.84175,5.187905 C 108.10513,7.835221 117.93885,14.870955 121.74406,16.587139 C 123.04716,17.174853 126.16385,13.054607 125.16669,12.099598 z" id="path6132" style="fill:#e20071;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient3168"> <stop id="stop3170" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop3172" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="29.344007" y1="35.892609" x2="5.8861146" y2="54.610104" id="linearGradient6134" xlink:href="#linearGradient3168" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.8205678,0.1491734,0.1491734,0.8205678,119.95493,-30.558073)" /> <linearGradient id="linearGradient2878"> <stop id="stop2880" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2882" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="47.794022" cy="43.680889" r="0.046902865" fx="47.817745" fy="43.681263" id="radialGradient2257" xlink:href="#linearGradient2878" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,140,0,-6071.644)" /> <linearGradient id="linearGradient2926"> <stop id="stop2928" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2934" style="stop-color:#ffffff;stop-opacity:0" offset="0.31868133" /> <stop id="stop2930" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="59.887943" cy="-16.594898" r="15.014902" fx="59.887943" fy="-16.594898" id="radialGradient4868" xlink:href="#linearGradient2926" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2908472,-1.2912538,-0.4877278,0.8613771,257.00005,93.121214)" spreadMethod="reflect" /> <linearGradient id="linearGradient2916"> <stop id="stop2918" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2920" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="58.079144" cy="51.897194" r="15.014902" fx="60.050133" fy="51.985794" id="radialGradient4871" xlink:href="#linearGradient2916" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.9412787,-1.1615663,-0.2846191,0.7136661,292.2596,68.533501)" /> <linearGradient id="linearGradient2948"> <stop id="stop2950" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2956" style="stop-color:#000000;stop-opacity:0" offset="0.14835165" /> <stop id="stop2960" style="stop-color:#000000;stop-opacity:0.39607844" offset="0.42443547" /> <stop id="stop2958" style="stop-color:#000000;stop-opacity:0.79061371" offset="0.57417583" /> <stop id="stop2962" style="stop-color:#000000;stop-opacity:0.09386282" offset="0.78708792" /> <stop id="stop2952" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.277409" y1="41.758987" x2="75.465431" y2="41.511894" id="linearGradient4874" xlink:href="#linearGradient2948" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <filter x="-0.081383675" width="1.1627673" y="-0.11701577" height="1.2340316" id="filter7303"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5574454" id="feGaussianBlur7305" /> </filter> <clipPath id="clipPath6914"> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 81.839741,-15.69481 90.48863,-25.23053 103.93871,-26.883344 C 107.28591,-26.458991 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.52863,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z" id="path6916" style="opacity:1;fill:#34176e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2938"> <stop id="stop2940" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2942" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="61.870293" y1="33.318996" x2="61.870293" y2="40.550549" id="linearGradient4880" xlink:href="#linearGradient2938" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <linearGradient id="linearGradient2854"> <stop id="stop2856" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2858" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="106.03028" y1="59.273457" x2="108.78728" y2="55.574818" id="linearGradient4888" xlink:href="#linearGradient2854" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="94.435982" cy="42.709927" r="16.633095" fx="94.435982" fy="42.709927" id="radialGradient4891" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2134389,-1.5580054,-0.9195638,1.2855562,320.80105,101.437)" /> <radialGradient cx="94.932045" cy="43.032188" r="16.633095" fx="94.932045" fy="43.032188" id="radialGradient4894" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="93.747849" cy="43.102612" r="16.633095" fx="93.747849" fy="43.102612" id="radialGradient4897" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="92.990265" cy="42.850105" r="16.633095" fx="92.990265" fy="42.850105" id="radialGradient4900" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <linearGradient id="linearGradient2830"> <stop id="stop2832" style="stop-color:#111111;stop-opacity:1" offset="0" /> <stop id="stop2838" style="stop-color:#6e6e70;stop-opacity:1" offset="0.14285715" /> <stop id="stop2864" style="stop-color:#101010;stop-opacity:1" offset="0.5714286" /> <stop id="stop2834" style="stop-color:#0d0d0d;stop-opacity:1" offset="1" /> </linearGradient> <radialGradient cx="92.496124" cy="43.249184" r="16.633095" fx="92.496124" fy="43.249184" id="radialGradient4903" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <filter x="-0.059171364" width="1.1183428" y="-0.25424162" height="1.5084833" id="filter5739"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5280665" id="feGaussianBlur5741" /> </filter> <clipPath id="clipPath5354"> <path d="M 103.98397,-1.574449 C 105.35028,-1.792233 108.98473,-2.914664 106.17093,-5.692155 C 76.173344,-27.291403 51.99515,-18.323699 42.936426,-12.159439 C 53.098952,-17.891025 78.771948,-21.925123 103.98397,-1.574449 z" id="path5356" style="opacity:1;fill:#00583f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2803"> <stop id="stop2809" style="stop-color:#e2dcdc;stop-opacity:1" offset="0" /> <stop id="stop2811" style="stop-color:#ffffff;stop-opacity:1" offset="0.39074388" /> <stop id="stop2813" style="stop-color:#dfd9df;stop-opacity:1" offset="0.82692307" /> <stop id="stop2815" style="stop-color:#c3c3c3;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="62.987843" y1="46.469597" x2="118.02947" y2="62.350033" id="linearGradient4910" xlink:href="#linearGradient2803" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2231" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2229" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2227" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2225" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2223" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2221" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2219" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2217" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2215" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2213" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2211" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2209" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2207" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2205" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2203" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2201" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2199" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2197" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2195" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2193" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2191" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2189" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2187" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2185" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2183" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2181" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2179" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2177" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2175" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2173" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2171" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2169" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient id="linearGradient2370"> <stop id="stop2378" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2374" style="stop-color:#2a2a2a;stop-opacity:0.29537368" offset="1" /> </linearGradient> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2167" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient x1="-66.905724" y1="78.000954" x2="-66.905724" y2="77.232819" id="linearGradient4946" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-75.354716)" /> <linearGradient x1="-74.01326" y1="49.46249" x2="-58.206917" y2="65.268829" id="linearGradient4952" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833612,-4.797835,-79.665584)" /> <linearGradient x1="36.909187" y1="75.415688" x2="38.451817" y2="75.479614" id="linearGradient4955" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.983361,0.6663259,-0.6582589,0.9697357,55.439719,-32.927491)" /> <linearGradient id="linearGradient2322"> <stop id="stop2324" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2326" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="37.235054" y1="75.415688" x2="38.61475" y2="75.479614" id="linearGradient4958" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.44832,27.448631)" /> <linearGradient x1="45.615768" y1="128.00496" x2="45.615768" y2="125.89983" id="linearGradient4961" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2310"> <stop id="stop2312" style="stop-color:#020202;stop-opacity:1" offset="0" /> <stop id="stop2314" style="stop-color:#020202;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.24057" y1="61.083416" x2="45.24057" y2="62.415165" id="linearGradient4964" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.36527,27.463989)" /> <linearGradient id="linearGradient3058"> <stop id="stop3060" style="stop-color:#9a7600;stop-opacity:1" offset="0" /> <stop id="stop3066" style="stop-color:#e3ad00;stop-opacity:1" offset="0.32522252" /> <stop id="stop3070" style="stop-color:#ffcd2c;stop-opacity:1" offset="0.6670348" /> <stop id="stop3068" style="stop-color:#e3ad00;stop-opacity:1" offset="0.91571385" /> <stop id="stop3062" style="stop-color:#b98d00;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="34.91254" y1="94.734375" x2="55.089256" y2="94.734375" id="linearGradient4967" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2352"> <stop id="stop2354" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2356" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="-66.905724" y1="77.09996" x2="-66.905724" y2="75.717079" id="linearGradient4949" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764965,0,0,1.1833623,-4.7827195,-79.650397)" /> <linearGradient id="linearGradient2334"> <stop id="stop2336" style="stop-color:#8d8d8d;stop-opacity:1" offset="0" /> <stop id="stop2342" style="stop-color:#e2dcdc;stop-opacity:1" offset="0.2767916" /> <stop id="stop2348" style="stop-color:#ffffff;stop-opacity:1" offset="0.71460712" /> <stop id="stop2344" style="stop-color:#dfd9df;stop-opacity:1" offset="0.80711305" /> <stop id="stop2338" style="stop-color:#888888;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="-70.588905" y1="67.754272" x2="-59.581383" y2="67.754272" id="linearGradient4970" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-79.665581)" /> <linearGradient id="linearGradient6959"> <stop id="stop6961" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop6963" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="0.16120911" y1="117.27959" x2="128.16121" y2="117.27959" id="linearGradient8078" xlink:href="#linearGradient6959" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.785268,-7.3677219e-2,3.9462543e-2,0.4492806,22.778321,70.710911)" /> </defs> <g id="layer1" transform="translate(11.95197,16)"> <path d="M 128.04736,113.95979 C 128.28089,116.61848 67.411471,124.50507 39.669521,127.10794 C 11.927571,129.71081 27.766581,126.04917 27.533061,123.39048 C 27.299531,120.73178 11.081461,120.07787 38.823411,117.475 C 66.565361,114.87213 127.81383,111.3011 128.04736,113.95979 z " id="path6957" style="opacity:0.32093027;fill:url(#linearGradient8078);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31099999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.274934,34.905639 C 85.204914,25.922787 89.34177,14.198553 102.63801,12.53741 C 105.94693,12.9639 108.13372,18.737744 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2874" style="fill:#bfbfc0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <rect width="12.941447" height="29.58403" ry="0" x="-87.844696" y="-16.94743" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2266" style="fill:url(#linearGradient4970);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="13.038667" height="2.5542164" ry="0" x="-87.829575" y="9.101737" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2360" style="opacity:0.36065578;fill:url(#linearGradient4949);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.429289,63.172679 C 65.635414,64.820033 54.923018,83.195864 49.729102,91.344581 C 39.34128,107.642 26.239281,125.86158 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 19.376879,93.833728 30.860819,78.294436 C 36.602784,70.52478 49.810698,53.88547 51.006314,52.505467 C 52.212736,51.113002 53.417042,50.730504 54.693928,51.613654 C 58.435834,54.201727 62.17774,56.7898 65.919646,59.377862 C 66.995538,60.122005 67.369194,61.222275 66.429289,63.172679 z " id="rect1388" style="fill:url(#linearGradient4967);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.247591,63.206257 C 65.453717,64.853621 49.629,53.919059 50.824616,52.539056 C 52.031038,51.146581 53.235344,50.764082 54.51223,51.647242 C 58.254136,54.235305 61.996042,56.823378 65.737948,59.411451 C 66.81384,60.155584 67.187497,61.255863 66.247591,63.206257 z " id="path2290" style="opacity:0.09157511;fill:url(#linearGradient4964);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 26.239281,125.86158 26.239281,125.86158 z " id="path2308" style="opacity:0.3699634;fill:url(#linearGradient4961);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.33068,63.19091 C 65.536805,64.838264 54.824409,83.214095 49.630493,91.362803 C 39.242661,107.66022 26.140672,125.8798 26.140672,125.8798 C 24.569135,128.14762 62.079131,56.808021 65.821037,59.396094 C 66.896928,60.140227 67.270585,61.240506 66.33068,63.19091 z " id="path2320" style="opacity:0.3699634;fill:url(#linearGradient4958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 51.020737,52.411747 C 49.776998,53.730231 36.591653,70.167669 30.909012,77.870037 C 19.543739,93.274764 7.3898106,111.88362 7.3898106,111.88362 C 5.8550281,114.14465 58.555163,54.129906 54.752313,51.55311 C 53.658913,50.812203 52.49326,50.850706 51.020737,52.411747 z " id="path2330" style="opacity:0.23809521;fill:url(#linearGradient4955);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="22.48386" ry="0" x="-87.844696" y="-16.947432" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2350" style="opacity:0.25;fill:url(#linearGradient4952);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="4.1249256" ry="0" x="-87.844696" y="12.822533" transform="matrix(-0.8224474,-0.5688412,0.5695776,-0.8219376,0,0)" id="rect2364" style="opacity:0.29098361;fill:url(#linearGradient4946);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.339764,-119.62564)" id="path2368" style="opacity:0.21245422;fill:url(#radialGradient2167);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.295704,-113.78978)" id="path2486" style="opacity:0.21245422;fill:url(#radialGradient2169);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.251654,-107.95391)" id="path2490" style="opacity:0.21245422;fill:url(#radialGradient2171);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.207455,-102.11799)" id="path2494" style="opacity:0.21245422;fill:url(#radialGradient2173);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.163405,-96.282126)" id="path2498" style="opacity:0.21245422;fill:url(#radialGradient2175);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.119257,-90.446221)" id="path2502" style="opacity:0.21245422;fill:url(#radialGradient2177);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.401175,-83.637696)" id="path2506" style="opacity:0.21245422;fill:url(#radialGradient2179);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.357125,-77.801811)" id="path2510" style="opacity:0.21245422;fill:url(#radialGradient2181);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.312966,-71.965905)" id="path2514" style="opacity:0.21245422;fill:url(#radialGradient2183);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2518" style="opacity:0.21245422;fill:url(#radialGradient2185);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2522" style="opacity:0.21245422;fill:url(#radialGradient2187);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.51209,-120.72315)" id="path2524" style="opacity:0.21245422;fill:url(#radialGradient2189);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.468031,-114.88732)" id="path2526" style="opacity:0.21245422;fill:url(#radialGradient2191);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.423951,-109.05138)" id="path2528" style="opacity:0.21245422;fill:url(#radialGradient2193);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.379792,-103.21548)" id="path2530" style="opacity:0.21245422;fill:url(#radialGradient2195);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,58.335742,-97.379601)" id="path2532" style="opacity:0.21245422;fill:url(#radialGradient2197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,54.291593,-91.543696)" id="path2534" style="opacity:0.21245422;fill:url(#radialGradient2199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.573512,-84.735171)" id="path2536" style="opacity:0.21245422;fill:url(#radialGradient2201);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.529462,-78.899296)" id="path2538" style="opacity:0.21245422;fill:url(#radialGradient2203);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,41.485303,-73.063401)" id="path2540" style="opacity:0.21245422;fill:url(#radialGradient2205);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2542" style="opacity:0.21245422;fill:url(#radialGradient2207);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2544" style="opacity:0.21245422;fill:url(#radialGradient2209);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,86.123367,-112.6923)" id="path2568" style="opacity:0.21245422;fill:url(#radialGradient2211);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.079218,-106.85639)" id="path2570" style="opacity:0.21245422;fill:url(#radialGradient2213);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.035168,-101.02052)" id="path2572" style="opacity:0.21245422;fill:url(#radialGradient2215);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,73.991108,-95.18463)" id="path2574" style="opacity:0.21245422;fill:url(#radialGradient2217);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,69.947019,-89.348755)" id="path2576" style="opacity:0.21245422;fill:url(#radialGradient2219);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,65.90286,-83.51285)" id="path2578" style="opacity:0.21245422;fill:url(#radialGradient2221);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,61.184788,-76.704325)" id="path2580" style="opacity:0.21245422;fill:url(#radialGradient2223);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.14063,-70.86842)" id="path2582" style="opacity:0.21245422;fill:url(#radialGradient2225);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.09658,-65.032544)" id="path2584" style="opacity:0.21245422;fill:url(#radialGradient2227);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2586" style="opacity:0.21245422;fill:url(#radialGradient2229);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2588" style="opacity:0.21245422;fill:url(#radialGradient2231);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 101.38809,11.479353 C 102.63809,12.398423 103.84894,13.381344 105.0387,14.408949 C 104.01321,16.577326 100.48534,20.746249 99.007199,22.467323 C 98.01495,23.622639 93.281961,23.36178 91.998392,24.319263 C 87.944052,27.343595 84.815519,31.864815 80.922501,35.138608 L 72.655729,29.510877 C 72.667829,29.490354 72.685732,29.470645 72.697861,29.450092 C 72.67379,29.475982 72.628395,29.495037 72.604432,29.520354 L 71.432076,28.709507 C 71.432067,28.709497 76.539137,19.842938 71.897343,16.081861 C 61.421124,7.5933688 42.104321,12.7028 40.367328,14.0543 L 42.083541,7.259695 C 42.083541,7.259695 42.33779,7.1294014 42.380871,7.1146373 C 59.53124,-3.8488001 84.402814,-1.0092155 101.38809,11.479353 z " id="path2783" style="fill:url(#linearGradient4910);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 103.83475,-5.0595755 C 104.3991,-4.5551745 105.41114,-5.6873565 104.63008,-6.2226895 C 74.632493,-27.821939 51.99515,-17.681556 42.936426,-11.517296 C 52.35952,-18.300887 76.609727,-26.230729 103.83475,-5.0595755 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath5354)" id="path2823" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5739)" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.128521,13.402952 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.101176,-0.96025992 73.950973,7.4166021 C 82.164175,13.221703 76.243429,25.456347 72.232891,29.69503 z " id="path2842" style="opacity:0.23360656;fill:url(#radialGradient4903);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.523172,29.895808 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.022844,13.705088 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.235986,-1.1547857 74.085773,7.2220662 C 82.298976,13.027177 76.53371,25.657124 72.523172,29.895808 z " id="path2827" style="opacity:0.23360656;fill:url(#radialGradient4900);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 73.103735,30.297352 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.89179,13.624865 40.576201,14.168322 L 42.322269,7.4456578 C 42.322269,7.4456578 62.640397,-1.7383733 74.490184,6.6384787 C 82.703386,12.44359 77.114273,26.058669 73.103735,30.297352 z " id="path2844" style="opacity:0.0737705;fill:url(#radialGradient4897);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.984171,13.626222 40.566444,14.182412 L 42.334152,7.4434568 C 42.334152,7.4434568 61.966375,-0.76572405 73.816172,7.6111279 C 82.029375,13.416239 76.243429,25.456347 72.232891,29.69503 z " id="path2840" style="opacity:0.23360656;fill:url(#radialGradient4894);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.13613,29.628115 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.921635,13.665037 40.571002,14.184262 L 42.322269,7.4456578 C 42.322269,7.4456578 61.764175,-0.47393028 73.613962,7.9029217 C 81.827164,13.708033 76.146668,25.389432 72.13613,29.628115 z " id="path2862" style="opacity:0.37000002;fill:url(#radialGradient4891);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 61.41113,8.3780551 C 54.11035,6.6553332 42.963569,9.4974003 40.902427,12.001391 L 41.0016,10.631158 C 43.787546,7.6855914 53.80009,5.6303314 60.912865,6.8618995 C 62.075305,7.0631792 62.003061,8.5177258 61.41113,8.3780551 z " id="path2868" style="opacity:0.31000001;fill:url(#linearGradient4888);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 42.085054,7.2558055 L 40.347458,14.03836 L 40.579642,14.198955 L 42.326056,7.4656582 L 42.085054,7.2558055 z " id="path2872" style="opacity:0.11000001;fill:#b7b7b7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.793503,23.516486 95.950625,22.98307 C 98.195669,22.788575 103.22118,19.851069 102.52483,17.34553 C 101.28955,12.900833 104.51185,12.778691 106.76072,16.351101 C 107.83597,18.05917 108.68046,20.615514 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 121.44894,38.490512 117.56384,42.696451 L 111.17842,38.965656 L 103.77633,29.053301 C 97.649281,27.059128 88.562348,29.712528 81.865056,36.103558 z " id="path2936" style="opacity:0.5286885;fill:url(#linearGradient4880);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 96.447179,-28.288297 105.15658,-12.530013 103.93871,-26.883344 C 105.73798,-25.86955 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.528633,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,39.556289)" clip-path="url(#clipPath6914)" id="path2902" style="opacity:0.3;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7303)" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.936568,23.945458 96.09369,23.412042 C 98.338733,23.217547 99.058515,23.054066 102.62556,17.81605 C 104.97193,14.370546 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2904" style="opacity:0.11065572;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 90.178924,23.81633 96.336045,23.282914 C 98.581099,23.088419 99.46084,22.257119 102.66207,17.556297 C 105.00842,14.110793 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2946" style="opacity:0.78278689;fill:url(#linearGradient4874);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.186467,36.425805 L 80.943143,35.163804 C 90.771765,25.89748 90.156661,24.109531 96.307061,23.50126 C 99.068954,23.228099 101.46217,20.125666 103.03896,17.817699 C 105.39113,14.376285 105.82661,13.986851 107.08213,16.673348 C 108.04323,18.729874 109.11134,20.957278 109.76753,22.854566 L 120.19358,26.450685 L 126,30.829783 C 123.46105,35.966762 120.42231,40.758067 116.53723,44.964006 L 110.15179,41.233211 L 102.74972,31.320856 C 96.622659,29.326673 88.883759,30.034785 82.186467,36.425805 z " id="path2906" style="opacity:0.55;fill:url(#radialGradient4871);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.052576,35.677069 L 80.809252,34.415058 C 90.637874,25.148744 90.316354,23.346463 96.463708,22.707247 C 99.198595,22.422217 99.463846,21.382923 102.80287,17.054108 C 105.34611,13.756144 105.69272,13.238105 106.94825,15.924612 C 107.90935,17.981128 108.97746,20.208542 109.63365,22.10582 L 120.05969,25.701939 L 125.86612,30.081037 C 123.32716,35.218016 120.28843,40.009321 116.40334,44.21526 L 110.0179,40.484465 L 102.61584,30.57211 C 96.488778,28.577937 88.749878,29.286039 82.052576,35.677069 z " id="path2924" style="opacity:0.76000001;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 47.840924,43.680889 C 47.84099,46.032991 47.832065,48.210404 47.817526,49.389142 C 47.802987,50.56788 47.785056,50.56788 47.770517,49.389142 C 47.755978,48.210404 47.747053,46.032991 47.747119,43.680889 C 47.747053,41.328787 47.755978,39.151374 47.770517,37.972636 C 47.785056,36.793898 47.802987,36.793898 47.817526,37.972636 C 47.832065,39.151374 47.84099,41.328787 47.840924,43.680889 z " transform="matrix(-10.643649,-7.3616191,-0.6740154,0.9726479,659.11339,347.51792)" id="path2876" style="fill:url(#radialGradient2257);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 125.16669,12.099598 C 121.62206,9.685606 112.43786,3.516506 110.99761,5.712023 C 109.26099,8.35934 118.0322,14.038156 121.74406,16.587139 C 122.92246,17.396368 126.3079,12.876785 125.16669,12.099598 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath6130)" id="path3178" style="fill:url(#linearGradient6134);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6906)" /> </g> <path style="font-size:72px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" d="M 130,126.89062 L 130,135 L 84.578125,135 C 84.515622,132.96875 84.843747,131.01563 85.5625,129.14062 C 86.718745,126.04688 88.562493,123.00001 91.09375,120 C 93.656238,117.00002 97.343734,113.53127 102.15625,109.59375 C 109.62497,103.46878 114.67184,98.625036 117.29688,95.0625 C 119.92184,91.468794 121.23434,88.078172 121.23438,84.890625 C 121.23434,81.546928 120.03121,78.734431 117.625,76.453125 C 115.24997,74.140686 112.14059,72.984437 108.29688,72.984375 C 104.23435,72.984437 100.98436,74.203186 98.546875,76.640625 C 96.109361,79.078181 94.874987,82.453178 94.84375,86.765625 L 86.171875,85.875 C 86.76562,79.406306 88.999993,74.484436 92.875,71.109375 C 96.749985,67.703192 101.9531,66.000069 108.48438,66 C 115.07809,66.000069 120.29684,67.828192 124.14062,71.484375 C 127.98433,75.140685 129.9062,79.67193 129.90625,85.078125 C 129.9062,87.828172 129.3437,90.531294 128.21875,93.1875 C 127.0937,95.843789 125.21871,98.640661 122.59375,101.57812 C 119.99996,104.51566 115.67184,108.5469 109.60938,113.67188 C 104.54685,117.92189 101.29686,120.81251 99.859375,122.34375 C 98.421858,123.84376 97.234359,125.35938 96.296875,126.89062 L 130,126.89062" id="text2573" /> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/assign.png�����������������������������������������������������������0000644�0001750�0000144�00000001125�10704447121�016511� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���������Ĵl;���sBIT|d��� pHYs��a��a0U���tEXtSoftware�www.inkscape.org<��IDAT8͕=kTAwY7)(A, D)V,TAQX B(K"La�R"w׻w?1.80xs #tcBBҬvSaujF{fnk|d}7Xwtq �R p]m:LT'kN;׭y]!\:'N6kk> t 1U#<uk4gXWy'divr,ER<L$\Т.W Zb)rY3Q9nZT@#̡6'I 3ЗYsٰesB,�cǠ/ƨ.7[RwA^=|)pINsU7OE<Ì$>&`  ҬIo(3Qom В2dx yNm~Bz_;vѵ$i�[tdb(fXRWͮC7����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/transform3.svg�������������������������������������������������������0000644�0001750�0000144�00000210443�11207732764�017354� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:ns="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="156" height="156" id="svg2365" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docname="transform3.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/MP3Diags/src/images"> <metadata id="metadata198"> <rdf:RDF> <ns:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </ns:Work> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <sodipodi:namedview inkscape:window-height="956" inkscape:window-width="891" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" showgrid="true" inkscape:zoom="1.463932" inkscape:cx="-43.819174" inkscape:cy="64" inkscape:window-x="251" inkscape:window-y="72" inkscape:current-layer="svg2365" /> <defs id="defs2367"> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective200" /> <filter x="-0.085532367" width="1.1710647" y="-0.10938701" height="1.218774" id="filter6906"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.5212367" id="feGaussianBlur6908" /> </filter> <clipPath id="clipPath6130"> <path d="M 125.16669,12.099598 C 122.19641,9.254864 111.282,2.992388 109.84175,5.187905 C 108.10513,7.835221 117.93885,14.870955 121.74406,16.587139 C 123.04716,17.174853 126.16385,13.054607 125.16669,12.099598 z" id="path6132" style="fill:#e20071;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient3168"> <stop id="stop3170" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop3172" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="29.344007" y1="35.892609" x2="5.8861146" y2="54.610104" id="linearGradient6134" xlink:href="#linearGradient3168" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.8205678,0.1491734,0.1491734,0.8205678,119.95493,-30.558073)" /> <linearGradient id="linearGradient2878"> <stop id="stop2880" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2882" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="47.794022" cy="43.680889" r="0.046902865" fx="47.817745" fy="43.681263" id="radialGradient2257" xlink:href="#linearGradient2878" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,140,0,-6071.644)" /> <linearGradient id="linearGradient2926"> <stop id="stop2928" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2934" style="stop-color:#ffffff;stop-opacity:0" offset="0.31868133" /> <stop id="stop2930" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="59.887943" cy="-16.594898" r="15.014902" fx="59.887943" fy="-16.594898" id="radialGradient4868" xlink:href="#linearGradient2926" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2908472,-1.2912538,-0.4877278,0.8613771,257.00005,93.121214)" spreadMethod="reflect" /> <linearGradient id="linearGradient2916"> <stop id="stop2918" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2920" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="58.079144" cy="51.897194" r="15.014902" fx="60.050133" fy="51.985794" id="radialGradient4871" xlink:href="#linearGradient2916" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.9412787,-1.1615663,-0.2846191,0.7136661,292.2596,68.533501)" /> <linearGradient id="linearGradient2948"> <stop id="stop2950" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2956" style="stop-color:#000000;stop-opacity:0" offset="0.14835165" /> <stop id="stop2960" style="stop-color:#000000;stop-opacity:0.39607844" offset="0.42443547" /> <stop id="stop2958" style="stop-color:#000000;stop-opacity:0.79061371" offset="0.57417583" /> <stop id="stop2962" style="stop-color:#000000;stop-opacity:0.09386282" offset="0.78708792" /> <stop id="stop2952" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.277409" y1="41.758987" x2="75.465431" y2="41.511894" id="linearGradient4874" xlink:href="#linearGradient2948" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <filter x="-0.081383675" width="1.1627673" y="-0.11701577" height="1.2340316" id="filter7303"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5574454" id="feGaussianBlur7305" /> </filter> <clipPath id="clipPath6914"> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 81.839741,-15.69481 90.48863,-25.23053 103.93871,-26.883344 C 107.28591,-26.458991 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.52863,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z" id="path6916" style="opacity:1;fill:#34176e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2938"> <stop id="stop2940" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2942" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="61.870293" y1="33.318996" x2="61.870293" y2="40.550549" id="linearGradient4880" xlink:href="#linearGradient2938" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <linearGradient id="linearGradient2854"> <stop id="stop2856" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2858" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="106.03028" y1="59.273457" x2="108.78728" y2="55.574818" id="linearGradient4888" xlink:href="#linearGradient2854" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="94.435982" cy="42.709927" r="16.633095" fx="94.435982" fy="42.709927" id="radialGradient4891" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2134389,-1.5580054,-0.9195638,1.2855562,320.80105,101.437)" /> <radialGradient cx="94.932045" cy="43.032188" r="16.633095" fx="94.932045" fy="43.032188" id="radialGradient4894" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="93.747849" cy="43.102612" r="16.633095" fx="93.747849" fy="43.102612" id="radialGradient4897" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="92.990265" cy="42.850105" r="16.633095" fx="92.990265" fy="42.850105" id="radialGradient4900" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <linearGradient id="linearGradient2830"> <stop id="stop2832" style="stop-color:#111111;stop-opacity:1" offset="0" /> <stop id="stop2838" style="stop-color:#6e6e70;stop-opacity:1" offset="0.14285715" /> <stop id="stop2864" style="stop-color:#101010;stop-opacity:1" offset="0.5714286" /> <stop id="stop2834" style="stop-color:#0d0d0d;stop-opacity:1" offset="1" /> </linearGradient> <radialGradient cx="92.496124" cy="43.249184" r="16.633095" fx="92.496124" fy="43.249184" id="radialGradient4903" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <filter x="-0.059171364" width="1.1183428" y="-0.25424162" height="1.5084833" id="filter5739"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5280665" id="feGaussianBlur5741" /> </filter> <clipPath id="clipPath5354"> <path d="M 103.98397,-1.574449 C 105.35028,-1.792233 108.98473,-2.914664 106.17093,-5.692155 C 76.173344,-27.291403 51.99515,-18.323699 42.936426,-12.159439 C 53.098952,-17.891025 78.771948,-21.925123 103.98397,-1.574449 z" id="path5356" style="opacity:1;fill:#00583f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2803"> <stop id="stop2809" style="stop-color:#e2dcdc;stop-opacity:1" offset="0" /> <stop id="stop2811" style="stop-color:#ffffff;stop-opacity:1" offset="0.39074388" /> <stop id="stop2813" style="stop-color:#dfd9df;stop-opacity:1" offset="0.82692307" /> <stop id="stop2815" style="stop-color:#c3c3c3;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="62.987843" y1="46.469597" x2="118.02947" y2="62.350033" id="linearGradient4910" xlink:href="#linearGradient2803" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2231" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2229" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2227" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2225" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2223" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2221" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2219" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2217" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2215" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2213" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2211" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2209" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2207" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2205" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2203" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2201" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2199" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2197" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2195" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2193" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2191" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2189" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2187" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2185" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2183" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2181" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2179" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2177" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2175" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2173" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2171" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2169" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient id="linearGradient2370"> <stop id="stop2378" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2374" style="stop-color:#2a2a2a;stop-opacity:0.29537368" offset="1" /> </linearGradient> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2167" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient x1="-66.905724" y1="78.000954" x2="-66.905724" y2="77.232819" id="linearGradient4946" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-75.354716)" /> <linearGradient x1="-74.01326" y1="49.46249" x2="-58.206917" y2="65.268829" id="linearGradient4952" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833612,-4.797835,-79.665584)" /> <linearGradient x1="36.909187" y1="75.415688" x2="38.451817" y2="75.479614" id="linearGradient4955" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.983361,0.6663259,-0.6582589,0.9697357,55.439719,-32.927491)" /> <linearGradient id="linearGradient2322"> <stop id="stop2324" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2326" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="37.235054" y1="75.415688" x2="38.61475" y2="75.479614" id="linearGradient4958" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.44832,27.448631)" /> <linearGradient x1="45.615768" y1="128.00496" x2="45.615768" y2="125.89983" id="linearGradient4961" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2310"> <stop id="stop2312" style="stop-color:#020202;stop-opacity:1" offset="0" /> <stop id="stop2314" style="stop-color:#020202;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.24057" y1="61.083416" x2="45.24057" y2="62.415165" id="linearGradient4964" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.36527,27.463989)" /> <linearGradient id="linearGradient3058"> <stop id="stop3060" style="stop-color:#9a7600;stop-opacity:1" offset="0" /> <stop id="stop3066" style="stop-color:#e3ad00;stop-opacity:1" offset="0.32522252" /> <stop id="stop3070" style="stop-color:#ffcd2c;stop-opacity:1" offset="0.6670348" /> <stop id="stop3068" style="stop-color:#e3ad00;stop-opacity:1" offset="0.91571385" /> <stop id="stop3062" style="stop-color:#b98d00;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="34.91254" y1="94.734375" x2="55.089256" y2="94.734375" id="linearGradient4967" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2352"> <stop id="stop2354" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2356" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="-66.905724" y1="77.09996" x2="-66.905724" y2="75.717079" id="linearGradient4949" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764965,0,0,1.1833623,-4.7827195,-79.650397)" /> <linearGradient id="linearGradient2334"> <stop id="stop2336" style="stop-color:#8d8d8d;stop-opacity:1" offset="0" /> <stop id="stop2342" style="stop-color:#e2dcdc;stop-opacity:1" offset="0.2767916" /> <stop id="stop2348" style="stop-color:#ffffff;stop-opacity:1" offset="0.71460712" /> <stop id="stop2344" style="stop-color:#dfd9df;stop-opacity:1" offset="0.80711305" /> <stop id="stop2338" style="stop-color:#888888;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="-70.588905" y1="67.754272" x2="-59.581383" y2="67.754272" id="linearGradient4970" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-79.665581)" /> <linearGradient id="linearGradient6959"> <stop id="stop6961" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop6963" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="0.16120911" y1="117.27959" x2="128.16121" y2="117.27959" id="linearGradient8078" xlink:href="#linearGradient6959" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.785268,-7.3677219e-2,3.9462543e-2,0.4492806,22.778321,70.710911)" /> </defs> <g id="layer1" transform="translate(11.95197,16)"> <path d="M 128.04736,113.95979 C 128.28089,116.61848 67.411471,124.50507 39.669521,127.10794 C 11.927571,129.71081 27.766581,126.04917 27.533061,123.39048 C 27.299531,120.73178 11.081461,120.07787 38.823411,117.475 C 66.565361,114.87213 127.81383,111.3011 128.04736,113.95979 z " id="path6957" style="opacity:0.32093027;fill:url(#linearGradient8078);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31099999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.274934,34.905639 C 85.204914,25.922787 89.34177,14.198553 102.63801,12.53741 C 105.94693,12.9639 108.13372,18.737744 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2874" style="fill:#bfbfc0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <rect width="12.941447" height="29.58403" ry="0" x="-87.844696" y="-16.94743" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2266" style="fill:url(#linearGradient4970);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="13.038667" height="2.5542164" ry="0" x="-87.829575" y="9.101737" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2360" style="opacity:0.36065578;fill:url(#linearGradient4949);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.429289,63.172679 C 65.635414,64.820033 54.923018,83.195864 49.729102,91.344581 C 39.34128,107.642 26.239281,125.86158 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 19.376879,93.833728 30.860819,78.294436 C 36.602784,70.52478 49.810698,53.88547 51.006314,52.505467 C 52.212736,51.113002 53.417042,50.730504 54.693928,51.613654 C 58.435834,54.201727 62.17774,56.7898 65.919646,59.377862 C 66.995538,60.122005 67.369194,61.222275 66.429289,63.172679 z " id="rect1388" style="fill:url(#linearGradient4967);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.247591,63.206257 C 65.453717,64.853621 49.629,53.919059 50.824616,52.539056 C 52.031038,51.146581 53.235344,50.764082 54.51223,51.647242 C 58.254136,54.235305 61.996042,56.823378 65.737948,59.411451 C 66.81384,60.155584 67.187497,61.255863 66.247591,63.206257 z " id="path2290" style="opacity:0.09157511;fill:url(#linearGradient4964);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 26.239281,125.86158 26.239281,125.86158 z " id="path2308" style="opacity:0.3699634;fill:url(#linearGradient4961);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.33068,63.19091 C 65.536805,64.838264 54.824409,83.214095 49.630493,91.362803 C 39.242661,107.66022 26.140672,125.8798 26.140672,125.8798 C 24.569135,128.14762 62.079131,56.808021 65.821037,59.396094 C 66.896928,60.140227 67.270585,61.240506 66.33068,63.19091 z " id="path2320" style="opacity:0.3699634;fill:url(#linearGradient4958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 51.020737,52.411747 C 49.776998,53.730231 36.591653,70.167669 30.909012,77.870037 C 19.543739,93.274764 7.3898106,111.88362 7.3898106,111.88362 C 5.8550281,114.14465 58.555163,54.129906 54.752313,51.55311 C 53.658913,50.812203 52.49326,50.850706 51.020737,52.411747 z " id="path2330" style="opacity:0.23809521;fill:url(#linearGradient4955);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="22.48386" ry="0" x="-87.844696" y="-16.947432" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2350" style="opacity:0.25;fill:url(#linearGradient4952);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="4.1249256" ry="0" x="-87.844696" y="12.822533" transform="matrix(-0.8224474,-0.5688412,0.5695776,-0.8219376,0,0)" id="rect2364" style="opacity:0.29098361;fill:url(#linearGradient4946);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.339764,-119.62564)" id="path2368" style="opacity:0.21245422;fill:url(#radialGradient2167);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.295704,-113.78978)" id="path2486" style="opacity:0.21245422;fill:url(#radialGradient2169);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.251654,-107.95391)" id="path2490" style="opacity:0.21245422;fill:url(#radialGradient2171);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.207455,-102.11799)" id="path2494" style="opacity:0.21245422;fill:url(#radialGradient2173);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.163405,-96.282126)" id="path2498" style="opacity:0.21245422;fill:url(#radialGradient2175);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.119257,-90.446221)" id="path2502" style="opacity:0.21245422;fill:url(#radialGradient2177);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.401175,-83.637696)" id="path2506" style="opacity:0.21245422;fill:url(#radialGradient2179);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.357125,-77.801811)" id="path2510" style="opacity:0.21245422;fill:url(#radialGradient2181);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.312966,-71.965905)" id="path2514" style="opacity:0.21245422;fill:url(#radialGradient2183);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2518" style="opacity:0.21245422;fill:url(#radialGradient2185);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2522" style="opacity:0.21245422;fill:url(#radialGradient2187);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.51209,-120.72315)" id="path2524" style="opacity:0.21245422;fill:url(#radialGradient2189);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.468031,-114.88732)" id="path2526" style="opacity:0.21245422;fill:url(#radialGradient2191);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.423951,-109.05138)" id="path2528" style="opacity:0.21245422;fill:url(#radialGradient2193);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.379792,-103.21548)" id="path2530" style="opacity:0.21245422;fill:url(#radialGradient2195);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,58.335742,-97.379601)" id="path2532" style="opacity:0.21245422;fill:url(#radialGradient2197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,54.291593,-91.543696)" id="path2534" style="opacity:0.21245422;fill:url(#radialGradient2199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.573512,-84.735171)" id="path2536" style="opacity:0.21245422;fill:url(#radialGradient2201);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.529462,-78.899296)" id="path2538" style="opacity:0.21245422;fill:url(#radialGradient2203);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,41.485303,-73.063401)" id="path2540" style="opacity:0.21245422;fill:url(#radialGradient2205);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2542" style="opacity:0.21245422;fill:url(#radialGradient2207);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2544" style="opacity:0.21245422;fill:url(#radialGradient2209);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,86.123367,-112.6923)" id="path2568" style="opacity:0.21245422;fill:url(#radialGradient2211);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.079218,-106.85639)" id="path2570" style="opacity:0.21245422;fill:url(#radialGradient2213);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.035168,-101.02052)" id="path2572" style="opacity:0.21245422;fill:url(#radialGradient2215);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,73.991108,-95.18463)" id="path2574" style="opacity:0.21245422;fill:url(#radialGradient2217);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,69.947019,-89.348755)" id="path2576" style="opacity:0.21245422;fill:url(#radialGradient2219);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,65.90286,-83.51285)" id="path2578" style="opacity:0.21245422;fill:url(#radialGradient2221);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,61.184788,-76.704325)" id="path2580" style="opacity:0.21245422;fill:url(#radialGradient2223);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.14063,-70.86842)" id="path2582" style="opacity:0.21245422;fill:url(#radialGradient2225);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.09658,-65.032544)" id="path2584" style="opacity:0.21245422;fill:url(#radialGradient2227);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2586" style="opacity:0.21245422;fill:url(#radialGradient2229);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2588" style="opacity:0.21245422;fill:url(#radialGradient2231);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 101.38809,11.479353 C 102.63809,12.398423 103.84894,13.381344 105.0387,14.408949 C 104.01321,16.577326 100.48534,20.746249 99.007199,22.467323 C 98.01495,23.622639 93.281961,23.36178 91.998392,24.319263 C 87.944052,27.343595 84.815519,31.864815 80.922501,35.138608 L 72.655729,29.510877 C 72.667829,29.490354 72.685732,29.470645 72.697861,29.450092 C 72.67379,29.475982 72.628395,29.495037 72.604432,29.520354 L 71.432076,28.709507 C 71.432067,28.709497 76.539137,19.842938 71.897343,16.081861 C 61.421124,7.5933688 42.104321,12.7028 40.367328,14.0543 L 42.083541,7.259695 C 42.083541,7.259695 42.33779,7.1294014 42.380871,7.1146373 C 59.53124,-3.8488001 84.402814,-1.0092155 101.38809,11.479353 z " id="path2783" style="fill:url(#linearGradient4910);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 103.83475,-5.0595755 C 104.3991,-4.5551745 105.41114,-5.6873565 104.63008,-6.2226895 C 74.632493,-27.821939 51.99515,-17.681556 42.936426,-11.517296 C 52.35952,-18.300887 76.609727,-26.230729 103.83475,-5.0595755 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath5354)" id="path2823" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5739)" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.128521,13.402952 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.101176,-0.96025992 73.950973,7.4166021 C 82.164175,13.221703 76.243429,25.456347 72.232891,29.69503 z " id="path2842" style="opacity:0.23360656;fill:url(#radialGradient4903);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.523172,29.895808 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.022844,13.705088 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.235986,-1.1547857 74.085773,7.2220662 C 82.298976,13.027177 76.53371,25.657124 72.523172,29.895808 z " id="path2827" style="opacity:0.23360656;fill:url(#radialGradient4900);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 73.103735,30.297352 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.89179,13.624865 40.576201,14.168322 L 42.322269,7.4456578 C 42.322269,7.4456578 62.640397,-1.7383733 74.490184,6.6384787 C 82.703386,12.44359 77.114273,26.058669 73.103735,30.297352 z " id="path2844" style="opacity:0.0737705;fill:url(#radialGradient4897);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.984171,13.626222 40.566444,14.182412 L 42.334152,7.4434568 C 42.334152,7.4434568 61.966375,-0.76572405 73.816172,7.6111279 C 82.029375,13.416239 76.243429,25.456347 72.232891,29.69503 z " id="path2840" style="opacity:0.23360656;fill:url(#radialGradient4894);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.13613,29.628115 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.921635,13.665037 40.571002,14.184262 L 42.322269,7.4456578 C 42.322269,7.4456578 61.764175,-0.47393028 73.613962,7.9029217 C 81.827164,13.708033 76.146668,25.389432 72.13613,29.628115 z " id="path2862" style="opacity:0.37000002;fill:url(#radialGradient4891);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 61.41113,8.3780551 C 54.11035,6.6553332 42.963569,9.4974003 40.902427,12.001391 L 41.0016,10.631158 C 43.787546,7.6855914 53.80009,5.6303314 60.912865,6.8618995 C 62.075305,7.0631792 62.003061,8.5177258 61.41113,8.3780551 z " id="path2868" style="opacity:0.31000001;fill:url(#linearGradient4888);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 42.085054,7.2558055 L 40.347458,14.03836 L 40.579642,14.198955 L 42.326056,7.4656582 L 42.085054,7.2558055 z " id="path2872" style="opacity:0.11000001;fill:#b7b7b7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.793503,23.516486 95.950625,22.98307 C 98.195669,22.788575 103.22118,19.851069 102.52483,17.34553 C 101.28955,12.900833 104.51185,12.778691 106.76072,16.351101 C 107.83597,18.05917 108.68046,20.615514 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 121.44894,38.490512 117.56384,42.696451 L 111.17842,38.965656 L 103.77633,29.053301 C 97.649281,27.059128 88.562348,29.712528 81.865056,36.103558 z " id="path2936" style="opacity:0.5286885;fill:url(#linearGradient4880);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 96.447179,-28.288297 105.15658,-12.530013 103.93871,-26.883344 C 105.73798,-25.86955 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.528633,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,39.556289)" clip-path="url(#clipPath6914)" id="path2902" style="opacity:0.3;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7303)" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.936568,23.945458 96.09369,23.412042 C 98.338733,23.217547 99.058515,23.054066 102.62556,17.81605 C 104.97193,14.370546 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2904" style="opacity:0.11065572;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 90.178924,23.81633 96.336045,23.282914 C 98.581099,23.088419 99.46084,22.257119 102.66207,17.556297 C 105.00842,14.110793 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2946" style="opacity:0.78278689;fill:url(#linearGradient4874);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.186467,36.425805 L 80.943143,35.163804 C 90.771765,25.89748 90.156661,24.109531 96.307061,23.50126 C 99.068954,23.228099 101.46217,20.125666 103.03896,17.817699 C 105.39113,14.376285 105.82661,13.986851 107.08213,16.673348 C 108.04323,18.729874 109.11134,20.957278 109.76753,22.854566 L 120.19358,26.450685 L 126,30.829783 C 123.46105,35.966762 120.42231,40.758067 116.53723,44.964006 L 110.15179,41.233211 L 102.74972,31.320856 C 96.622659,29.326673 88.883759,30.034785 82.186467,36.425805 z " id="path2906" style="opacity:0.55;fill:url(#radialGradient4871);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.052576,35.677069 L 80.809252,34.415058 C 90.637874,25.148744 90.316354,23.346463 96.463708,22.707247 C 99.198595,22.422217 99.463846,21.382923 102.80287,17.054108 C 105.34611,13.756144 105.69272,13.238105 106.94825,15.924612 C 107.90935,17.981128 108.97746,20.208542 109.63365,22.10582 L 120.05969,25.701939 L 125.86612,30.081037 C 123.32716,35.218016 120.28843,40.009321 116.40334,44.21526 L 110.0179,40.484465 L 102.61584,30.57211 C 96.488778,28.577937 88.749878,29.286039 82.052576,35.677069 z " id="path2924" style="opacity:0.76000001;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 47.840924,43.680889 C 47.84099,46.032991 47.832065,48.210404 47.817526,49.389142 C 47.802987,50.56788 47.785056,50.56788 47.770517,49.389142 C 47.755978,48.210404 47.747053,46.032991 47.747119,43.680889 C 47.747053,41.328787 47.755978,39.151374 47.770517,37.972636 C 47.785056,36.793898 47.802987,36.793898 47.817526,37.972636 C 47.832065,39.151374 47.84099,41.328787 47.840924,43.680889 z " transform="matrix(-10.643649,-7.3616191,-0.6740154,0.9726479,659.11339,347.51792)" id="path2876" style="fill:url(#radialGradient2257);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 125.16669,12.099598 C 121.62206,9.685606 112.43786,3.516506 110.99761,5.712023 C 109.26099,8.35934 118.0322,14.038156 121.74406,16.587139 C 122.92246,17.396368 126.3079,12.876785 125.16669,12.099598 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath6130)" id="path3178" style="fill:url(#linearGradient6134);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6906)" /> </g> <path style="font-size:72px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" d="M 90,116.64062 L 98.4375,115.51562 C 99.406237,120.29689 101.04686,123.75001 103.35938,125.875 C 105.70311,127.96876 108.54685,129.01563 111.89062,129.01562 C 115.85935,129.01563 119.20309,127.64063 121.92188,124.89062 C 124.67184,122.14064 126.04683,118.73439 126.04688,114.67188 C 126.04683,110.7969 124.78121,107.6094 122.25,105.10938 C 119.71872,102.57816 116.49997,101.31253 112.59375,101.3125 C 110.99997,101.31253 109.0156,101.62503 106.64062,102.25 L 107.57812,94.84375 C 108.1406,94.90629 108.59373,94.93754 108.9375,94.9375 C 112.53122,94.93754 115.7656,94.000041 118.64062,92.125 C 121.51559,90.250045 122.95309,87.359422 122.95312,83.453125 C 122.95309,80.359429 121.90621,77.796932 119.8125,75.765625 C 117.71872,73.734436 115.0156,72.718812 111.70312,72.71875 C 108.42185,72.718812 105.68748,73.750061 103.5,75.8125 C 101.31248,77.875057 99.906236,80.968804 99.28125,85.09375 L 90.84375,83.59375 C 91.874994,77.937557 94.218742,73.562561 97.875,70.46875 C 101.53123,67.343817 106.0781,65.781319 111.51562,65.78125 C 115.2656,65.781319 118.71872,66.593818 121.875,68.21875 C 125.03121,69.812565 127.43746,72.000063 129.09375,74.78125 C 130.78121,77.562557 131.62495,80.515679 131.625,83.640625 C 131.62495,86.609423 130.82808,89.312545 129.23438,91.75 C 127.64058,94.187541 125.28121,96.125039 122.15625,97.5625 C 126.21871,98.500036 129.37496,100.45316 131.625,103.42188 C 133.87495,106.3594 134.99995,110.0469 135,114.48438 C 134.99995,120.48439 132.81245,125.57813 128.4375,129.76562 C 124.06246,133.92188 118.53122,136 111.84375,136 C 105.81248,136 100.79686,134.20313 96.796875,130.60938 C 92.828118,127.01563 90.562495,122.35939 90,116.64062" id="text2573" /> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/scan.svg�������������������������������������������������������������0000644�0001750�0000144�00000246031�11074212755�016177� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg2" sodipodi:version="0.32" inkscape:version="0.45+devel" width="128" height="128" version="1.0" inkscape:export-filename="/home/pinheiro/pics/oxygen/scalable/actions/system-run.png" inkscape:export-xdpi="180" inkscape:export-ydpi="180" sodipodi:docbase="/home/pinheiro/pics/oxygen/scalable/actions" sodipodi:docname="system-run.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" enable-background="new"> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <defs id="defs5"> <linearGradient id="linearGradient3292"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3294" /> <stop id="stop3304" offset="0.5" style="stop-color:#ffffff;stop-opacity:1;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop3296" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient5880"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop5882" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop5884" /> </linearGradient> <linearGradient id="linearGradient5515"> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="0" id="stop5517" /> <stop id="stop5523" offset="0.32512316" style="stop-color:#ffffff;stop-opacity:1;" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop5519" /> </linearGradient> <linearGradient id="linearGradient5267"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop5269" /> <stop id="stop5275" offset="0.5" style="stop-color:#ffffff;stop-opacity:0.50359714;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop5271" /> </linearGradient> <linearGradient id="linearGradient5247"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop5249" /> <stop id="stop5255" offset="0.5" style="stop-color:#ffffff;stop-opacity:0.79136693;" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop5251" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient5213"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop5215" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop5217" /> </linearGradient> <linearGradient id="linearGradient5131"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop5133" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop5135" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient4993"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop4995" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop4997" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient4913"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop4915" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop4917" /> </linearGradient> <linearGradient id="linearGradient4893"> <stop style="stop-color:#000000;stop-opacity:0;" offset="0" id="stop4895" /> <stop id="stop4909" offset="0.61052197" style="stop-color:#000000;stop-opacity:0;" /> <stop id="stop4905" offset="0.68472904" style="stop-color:#000000;stop-opacity:0.37769786;" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="0.7499575" id="stop4907" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop4897" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3285"> <stop style="stop-color:#474747;stop-opacity:1;" offset="0" id="stop3287" /> <stop style="stop-color:#474747;stop-opacity:0;" offset="1" id="stop3289" /> </linearGradient> <linearGradient id="linearGradient3184"> <stop style="stop-color:#fcfcfc;stop-opacity:1;" offset="0" id="stop3186" /> <stop style="stop-color:#c0c0c0;stop-opacity:1;" offset="1" id="stop3188" /> </linearGradient> <linearGradient id="linearGradient10207"> <stop id="stop10209" offset="0" style="stop-color:#b4b4b4;stop-opacity:1;" /> <stop style="stop-color:#d1d1d1;stop-opacity:1;" offset="0.5" id="stop4937" /> <stop id="stop10211" offset="1" style="stop-color:#fafafa;stop-opacity:1;" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4913" id="radialGradient4925" gradientUnits="userSpaceOnUse" cx="-84" cy="64" fx="-84" fy="64" r="60" /> <mask maskUnits="userSpaceOnUse" id="mask4921"> <path style="opacity:1;fill:url(#radialGradient4925);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M -83.999999,4 C -87.273852,4.0172764 -89.375767,4.1739184 -92.624999,4.625 C -93.586949,4.778184 -94.374999,5.4055494 -94.374999,6.375 L -94.968749,15.8125 C -95.057257,16.767694 -95.725392,17.39683 -96.437499,17.625 C -96.45933,17.631995 -96.478095,17.650033 -96.499999,17.65625 C -100.61684,18.761419 -104.52293,20.378352 -108.125,22.46875 C -108.77655,22.750681 -109.61713,22.733687 -110.3125,22.15625 L -117.40625,15.90625 C -118.09175,15.220752 -119.08648,15.33437 -119.875,15.90625 C -122.49151,17.884842 -124.11032,19.259755 -126.4375,21.5625 C -128.74024,23.889683 -130.11516,25.508484 -132.09375,28.125 C -132.66563,28.913521 -132.77925,29.908252 -132.09375,30.59375 L -125.84375,37.6875 C -125.37003,38.257979 -125.10755,38.996346 -125.375,39.53125 L -125.4375,39.65625 C -127.68302,43.45585 -129.43236,47.592563 -130.5625,51.96875 C -130.57434,51.989388 -130.58117,52.010911 -130.59375,52.03125 C -130.91096,52.544091 -131.44914,52.962834 -132.1875,53.03125 L -141.625,53.625 C -142.59444,53.625 -143.22181,54.41305 -143.375,55.375 C -143.82608,58.624232 -143.98272,60.726147 -144,64 C -143.98272,67.273853 -143.82608,69.375768 -143.375,72.625 C -143.22181,73.586946 -142.59444,74.375 -141.625,74.375 L -132.1875,74.96875 C -131.32015,75.04912 -130.74406,75.615317 -130.46875,76.25 C -129.36552,80.393354 -127.7025,84.314208 -125.59375,87.9375 C -125.22083,88.606007 -125.21212,89.551864 -125.84375,90.3125 L -132.09375,97.40625 C -132.77925,98.091746 -132.66563,99.086477 -132.09375,99.875 C -130.11516,102.49151 -128.74024,104.11031 -126.4375,106.4375 C -124.11032,108.74024 -122.49152,110.11516 -119.875,112.09375 C -119.08648,112.66563 -118.09175,112.77925 -117.40625,112.09375 L -110.3125,105.84375 C -109.55186,105.21212 -108.60601,105.22083 -107.9375,105.59375 L -107.84375,105.5 C -104.31609,107.51717 -100.51556,109.10952 -96.499999,110.1875 L -96.499999,110.34375 C -95.763598,110.55276 -95.05997,111.20302 -94.968749,112.1875 L -94.374999,121.625 C -94.374999,122.59444 -93.586949,123.22181 -92.624999,123.375 C -89.375767,123.82608 -87.273852,123.98272 -83.999999,124 C -80.726146,123.98272 -78.624231,123.82608 -75.374999,123.375 C -74.413053,123.22181 -73.624999,122.59444 -73.624999,121.625 L -73.031249,112.1875 C -72.940025,111.20302 -72.2364,110.55276 -71.499999,110.34375 L -71.499999,110.1875 C -67.484442,109.10952 -63.683904,107.51717 -60.156249,105.5 L -60.062499,105.59375 C -59.393992,105.22083 -58.448137,105.21212 -57.687499,105.84375 L -50.593749,112.09375 C -49.908246,112.77926 -48.913512,112.66564 -48.124999,112.09375 C -45.508489,110.11516 -43.889689,108.74024 -41.562499,106.4375 C -39.259759,104.11031 -37.884839,102.49151 -35.906249,99.875 C -35.334359,99.086487 -35.220739,98.091755 -35.906249,97.40625 L -42.156249,90.3125 C -42.787879,89.55186 -42.779169,88.606007 -42.406249,87.9375 C -40.297499,84.314208 -38.634479,80.393354 -37.531249,76.25 C -37.255939,75.615317 -36.679849,75.04912 -35.812499,74.96875 L -26.374999,74.375 C -25.405549,74.375 -24.778179,73.586946 -24.624999,72.625 C -24.173919,69.375768 -24.017279,67.273853 -23.999999,64 C -24.017279,60.726147 -24.173919,58.624232 -24.624999,55.375 C -24.778179,54.41305 -25.405549,53.625 -26.374999,53.625 L -35.812499,53.03125 C -36.550859,52.962834 -37.089039,52.544091 -37.406249,52.03125 C -37.411879,52.009328 -37.431839,51.99066 -37.437499,51.96875 C -38.567639,47.592563 -40.588709,43.603839 -42.562499,39.65625 L -42.624999,39.53125 C -42.892449,38.996346 -42.629969,38.257977 -42.156249,37.6875 L -35.906249,30.59375 C -35.220739,29.908244 -35.334369,28.913516 -35.906249,28.125 C -37.884839,25.508484 -39.259759,23.88968 -41.562499,21.5625 C -43.889679,19.259753 -45.508479,17.884841 -48.124999,15.90625 C -48.913515,15.334366 -49.908243,15.220745 -50.593749,15.90625 L -57.687499,22.15625 C -58.382875,22.733685 -59.223454,22.750682 -59.874999,22.46875 C -63.477074,20.378352 -67.383162,18.761419 -71.499999,17.65625 C -71.521903,17.650033 -71.540668,17.631995 -71.562499,17.625 C -72.274606,17.39683 -72.942738,16.767694 -73.031249,15.8125 L -73.624999,6.375 C -73.624999,5.4055494 -74.413053,4.778184 -75.374999,4.625 C -78.624231,4.1739184 -80.726146,4.0172764 -83.999999,4 z M -83.999999,48 C -75.168,47.999999 -67.999999,55.168 -67.999999,64 C -68,72.832 -75.168,80 -83.999999,80 C -92.831999,80 -99.999999,72.832 -99.999999,64 C -99.999998,55.167999 -92.831998,48 -83.999999,48 z " id="path4923" sodipodi:nodetypes="ccccssccccccccsccscccccccccccccccccccccccccccccccccccccccccccccccssssccccccccsscccccsssc" /> </mask> <filter inkscape:collect="always" id="filter5054"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.2828183" id="feGaussianBlur5056" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4993" id="radialGradient5077" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.5780636,0,-101.84696)" cx="94.818924" cy="67.895119" fx="94.818924" fy="67.895119" r="43.734375" /> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath5073"> <path id="path5075" d="M 76.90625,-70.062499 C 73.993994,-66.090403 69.299199,-63.499999 64,-63.499999 C 59.104212,-63.499999 54.716932,-65.68865 51.78125,-69.156249 C 28.641624,-73.441819 25.163605,-55.116541 20.28125,-38.406249 C 20.690082,-37.972249 21.088367,-37.541669 21.5625,-37.062499 C 23.88968,-34.759759 25.50848,-33.384839 28.125,-31.406249 C 28.91352,-30.834369 29.90825,-30.720749 30.59375,-31.406249 L 37.6875,-37.656249 C 38.44814,-38.287879 39.39399,-38.279169 40.0625,-37.906249 L 40.15625,-37.999999 C 43.68391,-35.982829 47.484439,-34.390479 51.5,-33.312499 L 51.5,-33.156249 C 52.236402,-32.947239 52.940029,-32.296979 53.03125,-31.312499 L 53.625,-21.874999 C 53.625001,-20.905559 54.41305,-20.278189 55.375,-20.124999 C 58.624233,-19.673919 60.726147,-19.517279 64,-19.499999 C 67.273854,-19.517279 69.375768,-19.673919 72.625,-20.124999 C 73.586947,-20.278189 74.375,-20.905559 74.375,-21.874999 L 74.96875,-31.312499 C 75.059975,-32.296979 75.763599,-32.947239 76.5,-33.156249 L 76.5,-33.312499 C 80.515558,-34.390479 84.316095,-35.982829 87.84375,-37.999999 L 87.9375,-37.906249 C 88.606008,-38.279169 89.551862,-38.287879 90.3125,-37.656249 L 97.40625,-31.406249 C 98.091754,-30.720739 99.086487,-30.834359 99.875,-31.406249 C 102.49151,-33.384839 104.11031,-34.759759 106.4375,-37.062499 C 106.92292,-37.553069 107.3327,-37.993909 107.75,-38.437499 C 111.67353,-45.524173 82.140773,-81.872038 76.90625,-70.062499 z " clip-path="none" mask="none" style="opacity:0.43122678;fill:url(#radialGradient5077);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" sodipodi:nodetypes="csccccccccccccccccccccccccccc" /> </clipPath> <filter inkscape:collect="always" id="filter5162"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.60500001" id="feGaussianBlur5164" /> </filter> <filter inkscape:collect="always" id="filter5257"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.022901589" id="feGaussianBlur5259" /> </filter> <filter inkscape:collect="always" id="filter5309"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.093056358" id="feGaussianBlur5311" /> </filter> <filter inkscape:collect="always" x="-0.11277929" width="1.2255586" y="-0.06669141" height="1.1333828" id="filter5505"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.13268874" id="feGaussianBlur5507" /> </filter> <filter inkscape:collect="always" id="filter5581"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.20386597" id="feGaussianBlur5583" /> </filter> <filter inkscape:collect="always" id="filter5718"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.48701799" id="feGaussianBlur5720" /> </filter> <filter inkscape:collect="always" id="filter5836"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.12356379" id="feGaussianBlur5838" /> </filter> <filter inkscape:collect="always" id="filter5876"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.11909804" id="feGaussianBlur5878" /> </filter> <filter inkscape:collect="always" id="filter5960"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.069666275" id="feGaussianBlur5962" /> </filter> <filter inkscape:collect="always" id="filter3310"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.11377897" id="feGaussianBlur3312" /> </filter> <linearGradient id="linearGradient6446"> <stop id="stop6448" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop6450" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6666"> <stop style="stop-color:#9fc1f2;stop-opacity:1;" offset="0" id="stop6668" /> <stop id="stop3183" offset="0.5" style="stop-color:#587eb5;stop-opacity:1;" /> <stop style="stop-color:#0c2a58;stop-opacity:1;" offset="1" id="stop6670" /> </linearGradient> <linearGradient id="linearGradient2990"> <stop id="stop2992" offset="0" style="stop-color:#d7d7d7;stop-opacity:1;" /> <stop id="stop2994" offset="1" style="stop-color:#ffffff;stop-opacity:1;" /> </linearGradient> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath5947"> <path sodipodi:type="arc" style="opacity:1;fill:#7a4c00;fill-opacity:1;stroke:none;stroke-width:0.48188975;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15;stroke-opacity:1" id="path5949" sodipodi:cx="203.82938" sodipodi:cy="45.093208" sodipodi:rx="56.61927" sodipodi:ry="28.309635" d="M 260.44865,45.093208 A 56.61927,28.309635 0 1 1 147.21011,45.093208 A 56.61927,28.309635 0 1 1 260.44865,45.093208 z" transform="matrix(0.7070054,0,0,0.7070054,-84.728337,7.4759644)" /> </clipPath> <filter inkscape:collect="always" id="filter6019" x="-0.063963689" width="1.1279274" y="-0.12176881" height="1.2435376"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.196414" id="feGaussianBlur6021" /> </filter> <filter inkscape:collect="always" id="filter6085"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.26087548" id="feGaussianBlur6087" /> </filter> <filter inkscape:collect="always" id="filter6093"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.17382035" id="feGaussianBlur6095" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3184" id="radialGradient6101" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9739412,0,0,0.9750591,-92.994702,1.6957237)" cx="255" cy="63.005722" fx="262.43524" fy="71.574997" r="23.279442" /> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath6097"> <path style="fill:url(#radialGradient6101);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.99997759;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 151.42888,45.294924 C 146.00664,45.507398 141.72149,49.966737 141.72512,55.39314 L 141.72512,80.638679 C 141.74221,84.125914 143.55719,87.357596 146.52604,89.187059 C 149.49492,91.016522 153.19755,91.184883 156.3202,89.632403 L 181.56574,77.009633 C 184.9444,75.283737 187.07073,71.809857 187.07073,68.01591 C 187.07073,64.221962 184.9444,60.748083 181.56574,59.022186 L 156.3202,46.399416 C 154.80855,45.625896 153.12623,45.246021 151.42888,45.294924 z" id="path6099" /> </clipPath> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3184" id="radialGradient6107" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9739412,0,0,0.9750591,-44.261685,1.6957237)" cx="255" cy="63.005722" fx="262.43524" fy="71.574997" r="23.279442" /> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath6103"> <path id="path6105" d="M 200.1619,45.294924 C 194.73966,45.507398 190.45451,49.966737 190.45814,55.39314 L 190.45814,80.638679 C 190.47523,84.125914 192.29021,87.357596 195.25906,89.187059 C 198.22794,91.016522 201.93057,91.184883 205.05322,89.632403 L 230.29876,77.009633 C 233.67742,75.283737 235.80375,71.809857 235.80375,68.01591 C 235.80375,64.221962 233.67742,60.748083 230.29876,59.022186 L 205.05322,46.399416 C 203.54157,45.625896 201.85925,45.246021 200.1619,45.294924 z" style="fill:url(#radialGradient6107);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.99997759;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4893" id="radialGradient6323" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.3581356,1.5026073,-1.6333333,1.4762927,-61.051702,-44.648234)" cx="-1.2494017" cy="23.725372" fx="-1.2494017" fy="61.40414" r="60" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4993" id="radialGradient6325" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.5780636,0,-101.84696)" cx="94.818924" cy="67.895119" fx="94.818924" fy="67.895119" r="43.734375" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4993" id="radialGradient6327" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.5780636,0,-101.84696)" cx="89.561417" cy="80.488235" fx="89.561417" fy="80.488235" r="43.734375" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5247" id="radialGradient6335" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.9019608,0,-6.1783597)" cx="54.672985" cy="6.8499207" fx="54.045624" fy="6.341433" r="1.2890996" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5247" id="radialGradient6337" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.9019608,0,-6.1783597)" cx="54.672985" cy="6.8499207" fx="54.045624" fy="6.341433" r="1.2890996" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5267" id="linearGradient6339" gradientUnits="userSpaceOnUse" x1="43.713863" y1="11.36219" x2="18.252157" y2="21.728621" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5247" id="radialGradient6341" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.9019608,0,-6.1783597)" cx="54.672985" cy="6.8499207" fx="54.045624" fy="6.341433" r="1.2890996" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5267" id="linearGradient6343" gradientUnits="userSpaceOnUse" x1="52.721935" y1="17.796528" x2="38.62756" y2="22.658024" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5247" id="radialGradient6345" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.9019608,0,-6.1783597)" cx="54.672985" cy="6.8499207" fx="54.045624" fy="6.341433" r="1.2890996" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3285" id="radialGradient6347" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.9019608,0,-6.1783597)" cx="54.672985" cy="6.8499207" fx="54.672985" fy="6.8499207" r="1.2890996" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3285" id="radialGradient6349" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.9019608,0,-6.1783597)" cx="54.672985" cy="6.8499207" fx="54.672985" fy="6.8499207" r="1.2890996" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5515" id="linearGradient6353" gradientUnits="userSpaceOnUse" x1="114.2963" y1="49.937351" x2="114.2963" y2="61.877388" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3292" id="linearGradient6359" gradientUnits="userSpaceOnUse" x1="310.84995" y1="-27.656115" x2="310.84995" y2="270.16995" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient6361" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7860801,1.3435491e-7,-1.2826114e-7,0.7504268,13.712508,14.534377)" cx="64.101105" cy="61.470516" fx="63.292271" fy="74.81649" r="22.686441" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient6363" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7860801,1.3435491e-7,-1.2826114e-7,0.7504268,13.712508,14.534377)" cx="64.101105" cy="61.470516" fx="63.292271" fy="74.81649" r="22.686441" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6446" id="linearGradient6365" gradientUnits="userSpaceOnUse" x1="71.964134" y1="26.784721" x2="79.398361" y2="63.955555" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2990" id="radialGradient6367" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9679843,-0.1075536,0.2763828,2.487449,-15.584867,-92.434168)" cx="267.42477" cy="81.257088" fx="267.42477" fy="81.257088" r="23.279442" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6446" id="linearGradient6372" gradientUnits="userSpaceOnUse" x1="63.556946" y1="67.196243" x2="62.234333" y2="51.360622" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5880" id="linearGradient6386" gradientUnits="userSpaceOnUse" x1="63.993221" y1="80.369598" x2="63.993221" y2="66.131996" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5880" id="linearGradient6391" gradientUnits="userSpaceOnUse" x1="63.993221" y1="80.369598" x2="63.993221" y2="66.131996" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5515" id="linearGradient6395" gradientUnits="userSpaceOnUse" x1="114.2963" y1="49.937351" x2="114.2963" y2="61.877388" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5213" id="linearGradient6408" gradientUnits="userSpaceOnUse" gradientTransform="translate(-2.9613216e-2,-0.4585689)" x1="62.936993" y1="3.8495977" x2="63.020756" y2="9.8520975" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5131" id="linearGradient6412" gradientUnits="userSpaceOnUse" gradientTransform="translate(-230.03067,39.46691)" x1="283.5" y1="-52.5" x2="282.5" y2="128.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4913" id="radialGradient6415" gradientUnits="userSpaceOnUse" gradientTransform="translate(148,0)" cx="-84" cy="64" fx="-84" fy="64" r="60" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient10207" id="linearGradient6421" gradientUnits="userSpaceOnUse" gradientTransform="translate(1.5e-6,0)" spreadMethod="reflect" x1="64" y1="81.5" x2="64" y2="12.678303" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5131" id="linearGradient6430" gradientUnits="userSpaceOnUse" gradientTransform="translate(-230.03067,40.26691)" x1="320.03067" y1="88.533089" x2="310.03067" y2="-16.466909" /> <filter inkscape:collect="always" id="filter6444"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.84700004" id="feGaussianBlur6446" /> </filter> </defs> <sodipodi:namedview inkscape:window-height="837" inkscape:window-width="1270" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" width="128px" height="128px" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" showgrid="false" inkscape:zoom="2.4335938" inkscape:cx="72.013815" inkscape:cy="56.831349" inkscape:window-x="121" inkscape:window-y="147" inkscape:current-layer="svg2" showguides="true" inkscape:guide-bbox="true"> <inkscape:grid type="xygrid" id="grid6039" /> </sodipodi:namedview> <path sodipodi:nodetypes="ccccssccccccccsccscccccccccccccccccccccccccccccccccccccccccccccccssssccccccccsscccccsssc" id="path5091" d="M 64.000003,4 C 60.726153,4.01728 58.624233,4.17392 55.375003,4.625 C 54.413053,4.77818 53.625003,5.40555 53.625003,6.375 L 53.031253,15.8125 C 52.942743,16.76769 52.274613,17.39683 51.562503,17.625 C 51.540673,17.632 51.521903,17.65003 51.500003,17.65625 C 47.383163,18.76142 43.477073,20.37835 39.875003,22.46875 C 39.223453,22.75068 38.382873,22.73369 37.687503,22.15625 L 30.593753,15.90625 C 29.908253,15.22075 28.913523,15.33437 28.125003,15.90625 C 25.508493,17.88484 23.889683,19.25975 21.562503,21.5625 C 19.259763,23.88968 17.884843,25.50848 15.906253,28.125 C 15.334373,28.91352 15.220753,29.90825 15.906253,30.59375 L 22.156253,37.6875 C 22.629973,38.25798 22.892453,38.99635 22.625003,39.53125 L 22.562503,39.65625 C 20.316983,43.45585 18.567643,47.59256 17.437503,51.96875 C 17.425663,51.98939 17.418833,52.01091 17.406253,52.03125 C 17.089043,52.54409 16.550863,52.96283 15.812503,53.03125 L 6.3750027,53.625 C 5.4055623,53.625 4.7781923,54.41305 4.6250023,55.375 C 4.1739223,58.62423 4.0172823,60.72615 4.0000023,64 C 4.0172823,67.27385 4.1739223,69.37577 4.6250023,72.625 C 4.7781923,73.58695 5.4055623,74.375 6.3750027,74.375 L 15.812503,74.96875 C 16.679853,75.04912 17.255943,75.61532 17.531253,76.25 C 18.634483,80.39335 20.297503,84.31421 22.406253,87.9375 C 22.779173,88.60601 22.787883,89.55186 22.156253,90.3125 L 15.906253,97.40625 C 15.220753,98.09175 15.334373,99.08648 15.906253,99.875 C 17.884843,102.49151 19.259763,104.11031 21.562503,106.4375 C 23.889683,108.74024 25.508483,110.11516 28.125003,112.09375 C 28.913523,112.66563 29.908253,112.77925 30.593753,112.09375 L 37.687503,105.84375 C 38.448143,105.21212 39.393993,105.22083 40.062503,105.59375 L 40.156253,105.5 C 43.683913,107.51717 47.484443,109.10952 51.500003,110.1875 L 51.500003,110.34375 C 52.236403,110.55276 52.940033,111.20302 53.031253,112.1875 L 53.625003,121.625 C 53.625003,122.59444 54.413053,123.22181 55.375003,123.375 C 58.624233,123.82608 60.726153,123.98272 64.000003,124 C 67.273853,123.98272 69.375773,123.82608 72.625003,123.375 C 73.586953,123.22181 74.375003,122.59444 74.375003,121.625 L 74.968753,112.1875 C 75.059973,111.20302 75.763603,110.55276 76.500003,110.34375 L 76.500003,110.1875 C 80.515563,109.10952 84.316103,107.51717 87.843753,105.5 L 87.937503,105.59375 C 88.606013,105.22083 89.551863,105.21212 90.312503,105.84375 L 97.406248,112.09375 C 98.091748,112.77926 99.086488,112.66564 99.874998,112.09375 C 102.49151,110.11516 104.11031,108.74024 106.4375,106.4375 C 108.74024,104.11031 110.11516,102.49151 112.09375,99.875 C 112.66564,99.08649 112.77926,98.09176 112.09375,97.40625 L 105.84375,90.3125 C 105.21212,89.55186 105.22083,88.60601 105.59375,87.9375 C 107.7025,84.31421 109.36552,80.39335 110.46875,76.25 C 110.74406,75.61532 111.32015,75.04912 112.1875,74.96875 L 121.625,74.375 C 122.59445,74.375 123.22182,73.58695 123.375,72.625 C 123.82608,69.37577 123.98272,67.27385 124,64 C 123.98272,60.72615 123.82608,58.62423 123.375,55.375 C 123.22182,54.41305 122.59445,53.625 121.625,53.625 L 112.1875,53.03125 C 111.44914,52.96283 110.91096,52.54409 110.59375,52.03125 C 110.58812,52.00933 110.56816,51.99066 110.5625,51.96875 C 109.43236,47.59256 107.41129,43.60384 105.4375,39.65625 L 105.375,39.53125 C 105.10755,38.99635 105.37003,38.25798 105.84375,37.6875 L 112.09375,30.59375 C 112.77926,29.90824 112.66563,28.91352 112.09375,28.125 C 110.11516,25.50848 108.74024,23.88968 106.4375,21.5625 C 104.11032,19.25975 102.49152,17.88484 99.874998,15.90625 C 99.086478,15.33437 98.091758,15.22074 97.406248,15.90625 L 90.312503,22.15625 C 89.617123,22.73369 88.776553,22.75068 88.125003,22.46875 C 84.522933,20.37835 80.616843,18.76142 76.500003,17.65625 C 76.478103,17.65003 76.459333,17.632 76.437503,17.625 C 75.725393,17.39683 75.057263,16.76769 74.968753,15.8125 L 74.375003,6.375 C 74.375003,5.40555 73.586953,4.77818 72.625003,4.625 C 69.375773,4.17392 67.273853,4.01728 64.000003,4 z M 64.000003,48 C 72.832003,48 80.000003,55.168 80.000003,64 C 80.000003,72.832 72.832003,80 64.000003,80 C 55.168003,80 48.000003,72.832 48.000003,64 C 48.000003,55.168 55.168003,48 64.000003,48 z" style="fill:#363636;fill-opacity:1;stroke:#767676;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" mask="none" /> <path sodipodi:nodetypes="ccccssccccccccsccscccccccccccccccccccccccccccccccccccccccccccccccssssccccccccsscccc" id="path6428" d="M 63.969328,4.76691 C 60.695478,4.78419 58.593558,4.94083 55.344328,5.39191 C 54.382378,5.54509 53.594328,6.17246 53.594328,7.14191 L 53.000578,16.57941 C 52.912068,17.5346 52.243938,18.16374 51.531828,18.39191 C 51.509998,18.39891 51.491228,18.41694 51.469328,18.42316 C 47.352488,19.52833 43.446398,21.14526 39.844328,23.23566 C 39.192778,23.51759 38.352198,23.5006 37.656828,22.92316 L 30.563078,16.67316 C 29.877578,15.98766 28.882848,16.10128 28.094328,16.67316 C 25.477818,18.65175 23.859008,20.02666 21.531828,22.32941 C 19.229088,24.65659 17.854168,26.27539 15.875578,28.89191 C 15.303698,29.68043 15.190078,30.67516 15.875578,31.36066 L 22.125578,38.45441 C 22.599298,39.02489 22.861778,39.76326 22.594328,40.29816 L 22.531828,40.42316 C 20.286308,44.22276 18.536968,48.359475 17.406828,52.735665 C 17.394988,52.756303 17.388158,52.777826 17.375578,52.798165 C 17.058368,53.311006 16.520188,53.729749 15.781828,53.798165 L 6.3443277,54.391915 C 5.3748876,54.391915 4.7475176,55.179965 4.5943276,56.141915 C 4.1432476,59.391147 3.9866076,61.493062 3.9693276,64.766915 C 3.9866076,68.040768 4.1432476,70.142683 4.5943276,73.391915 C 4.7475176,74.353861 5.3748876,75.141915 6.3443277,75.141915 L 15.781828,75.735665 C 16.649178,75.816035 17.225268,76.382232 17.500578,77.016915 C 18.603808,81.160269 20.266828,85.081123 22.375578,88.704415 C 22.748498,89.372922 22.757208,90.318779 22.125578,91.079415 L 15.875578,98.173165 C 15.190078,98.858661 15.303698,99.85339 15.875578,100.64192 C 17.854168,103.25843 19.229088,104.87723 21.531828,107.20442 C 23.859008,109.50716 25.477808,110.88208 28.094328,112.86067 C 28.882848,113.43255 29.877578,113.54617 30.563078,112.86067 L 37.656828,106.61067 C 38.417468,105.97904 39.363318,105.98775 40.031828,106.36067 L 40.125578,106.26692 C 43.653238,108.28409 47.453768,109.87644 51.469328,110.95442 L 51.469328,111.11067 C 52.205728,111.31968 52.909358,111.96994 53.000578,112.95442 L 53.594328,122.39192 C 53.594328,123.36136 54.382378,123.98873 55.344328,124.14192 C 58.593558,124.593 60.695478,124.74964 63.969328,124.76692 C 67.243178,124.74964 69.345098,124.593 72.594328,124.14192 C 73.556278,123.98873 74.344328,123.36136 74.344328,122.39192 L 74.938078,112.95442 C 75.029298,111.96994 75.732928,111.31968 76.469328,111.11067 L 76.469328,110.95442 C 80.484888,109.87644 84.285428,108.28409 87.813078,106.26692 L 87.906828,106.36067 C 88.575338,105.98775 89.521188,105.97904 90.281828,106.61067 L 97.375578,112.86067 C 98.061078,113.54618 99.055818,113.43256 99.844328,112.86067 C 102.46084,110.88208 104.07964,109.50716 106.40683,107.20442 C 108.70957,104.87723 110.08449,103.25843 112.06308,100.64192 C 112.63497,99.8534 112.74859,98.85867 112.06308,98.173165 L 105.81308,91.079415 C 105.18145,90.318775 105.19016,89.372922 105.56308,88.704415 C 107.67183,85.081123 109.33485,81.160269 110.43808,77.016915 C 110.71339,76.382232 111.28948,75.816035 112.15683,75.735665 L 121.59433,75.141915 C 122.56378,75.141915 123.19115,74.353861 123.34433,73.391915 C 123.79541,70.142683 123.95205,68.040768 123.96933,64.766915 C 123.95205,61.493062 123.79541,59.391147 123.34433,56.141915 C 123.19115,55.179965 122.56378,54.391915 121.59433,54.391915 L 112.15683,53.798165 C 111.41847,53.729749 110.88029,53.311006 110.56308,52.798165 C 110.55745,52.776243 110.53749,52.757575 110.53183,52.735665 C 109.40169,48.359475 107.38062,44.370755 105.40683,40.42316 L 105.34433,40.29816 C 105.07688,39.76326 105.33936,39.02489 105.81308,38.45441 L 112.06308,31.36066 C 112.74859,30.67515 112.63496,29.68043 112.06308,28.89191 C 110.08449,26.27539 108.70957,24.65659 106.40683,22.32941 C 104.07965,20.02666 102.46085,18.65175 99.844328,16.67316 C 99.055808,16.10128 98.061088,15.98765 97.375578,16.67316 L 90.281828,22.92316 C 89.586448,23.5006 88.745878,23.51759 88.094328,23.23566 C 84.492258,21.14526 80.586168,19.52833 76.469328,18.42316 C 76.447428,18.41694 76.428658,18.39891 76.406828,18.39191 C 75.694718,18.16374 75.026588,17.5346 74.938078,16.57941 L 74.344328,7.14191 C 74.344328,6.17246 73.556278,5.54509 72.594328,5.39191 C 69.345098,4.94083 67.243178,4.78419 63.969328,4.76691 z" style="fill:none;fill-opacity:1;stroke:url(#linearGradient6430);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter6444)" mask="none" /> <path style="fill:url(#linearGradient6421);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.000002,4 C 60.726149,4.01728 58.624234,4.17392 55.375002,4.625 C 54.413052,4.77818 53.625002,5.40555 53.625002,6.375 L 53.031252,15.8125 C 52.942744,16.76769 52.274609,17.39683 51.562502,17.625 C 51.540671,17.632 51.521906,17.65003 51.500002,17.65625 C 47.383165,18.76142 43.477076,20.37835 39.875002,22.46875 C 39.223456,22.75068 38.382876,22.73369 37.687502,22.15625 L 30.593752,15.90625 C 29.908254,15.22075 28.913525,15.33437 28.125002,15.90625 C 25.508487,17.88484 23.889685,19.25976 21.562502,21.5625 C 19.259757,23.88968 17.884844,25.50848 15.906252,28.125 C 15.334375,28.91352 15.220754,29.90825 15.906252,30.59375 L 22.156252,37.6875 C 22.629973,38.25798 22.892454,38.99635 22.625002,39.53125 L 22.562502,39.65625 C 20.316984,43.45585 18.567642,47.592564 17.437502,51.968751 C 17.425658,51.989389 17.418833,52.010912 17.406252,52.031251 C 17.089043,52.544092 16.550862,52.962835 15.812502,53.031251 L 6.3750017,53.625001 C 5.4055615,53.625001 4.7781915,54.413051 4.6250015,55.375001 C 4.1739215,58.624233 4.0172815,60.726148 4.0000015,64.000001 C 4.0172815,67.273854 4.1739215,69.375769 4.6250015,72.625001 C 4.7781915,73.586947 5.4055615,74.375001 6.3750017,74.375001 L 15.812502,74.968751 C 16.679848,75.049121 17.255938,75.615318 17.531252,76.250001 C 18.634482,80.393355 20.297505,84.314209 22.406252,87.937501 C 22.779173,88.606008 22.787882,89.551865 22.156252,90.312501 L 15.906252,97.406251 C 15.220754,98.091747 15.334372,99.08648 15.906252,99.875 C 17.884844,102.49151 19.259757,104.11031 21.562502,106.4375 C 23.889685,108.74024 25.508486,110.11516 28.125002,112.09375 C 28.913523,112.66563 29.908254,112.77925 30.593752,112.09375 L 37.687502,105.84375 C 38.44814,105.21212 39.393995,105.22083 40.062502,105.59375 L 40.156252,105.5 C 43.683907,107.51717 47.484445,109.10952 51.500002,110.1875 L 51.500002,110.34375 C 52.236403,110.55276 52.940031,111.20302 53.031252,112.1875 L 53.625002,121.625 C 53.625002,122.59444 54.413052,123.22181 55.375002,123.375 C 58.624234,123.82608 60.726149,123.98272 64.000002,124 C 67.273855,123.98272 69.37577,123.82608 72.625002,123.375 C 73.586948,123.22181 74.375002,122.59444 74.375002,121.625 L 74.968752,112.1875 C 75.059976,111.20302 75.763601,110.55276 76.500002,110.34375 L 76.500002,110.1875 C 80.515559,109.10952 84.316097,107.51717 87.843752,105.5 L 87.937502,105.59375 C 88.606009,105.22083 89.551864,105.21212 90.312502,105.84375 L 97.406248,112.09375 C 98.091758,112.77926 99.086488,112.66564 99.874998,112.09375 C 102.49151,110.11516 104.11031,108.74024 106.4375,106.4375 C 108.74024,104.11031 110.11516,102.49151 112.09375,99.875 C 112.66564,99.08649 112.77926,98.091756 112.09375,97.406251 L 105.84375,90.312501 C 105.21212,89.551861 105.22083,88.606008 105.59375,87.937501 C 107.7025,84.314209 109.36552,80.393355 110.46875,76.250001 C 110.74406,75.615318 111.32015,75.049121 112.1875,74.968751 L 121.625,74.375001 C 122.59445,74.375001 123.22182,73.586947 123.375,72.625001 C 123.82608,69.375769 123.98272,67.273854 124,64.000001 C 123.98272,60.726148 123.82608,58.624233 123.375,55.375001 C 123.22182,54.413051 122.59445,53.625001 121.625,53.625001 L 112.1875,53.031251 C 111.44914,52.962835 110.91096,52.544092 110.59375,52.031251 C 110.58812,52.009329 110.56816,51.990661 110.5625,51.968751 C 109.43236,47.592564 107.41129,43.60384 105.4375,39.65625 L 105.375,39.53125 C 105.10755,38.99635 105.37003,38.25798 105.84375,37.6875 L 112.09375,30.59375 C 112.77926,29.90824 112.66563,28.91352 112.09375,28.125 C 110.11516,25.50848 108.74024,23.88968 106.4375,21.5625 C 104.11032,19.25975 102.49152,17.88484 99.874998,15.90625 C 99.086488,15.33437 98.091758,15.22075 97.406248,15.90625 L 90.312502,22.15625 C 89.617126,22.73369 88.776547,22.75068 88.125002,22.46875 C 84.522927,20.37835 80.616839,18.76142 76.500002,17.65625 C 76.478098,17.65003 76.459333,17.632 76.437502,17.625 C 75.725395,17.39683 75.057263,16.76769 74.968752,15.8125 L 74.375002,6.375 C 74.375002,5.40555 73.586948,4.77818 72.625002,4.625 C 69.37577,4.17392 67.273855,4.01728 64.000002,4 z M 64.000002,48.000001 C 72.832001,48 80.000002,55.168001 80.000002,64.000001 C 80.000001,72.832001 72.832001,80.000001 64.000002,80.000001 C 55.168002,80.000001 48.000002,72.832001 48.000002,64.000001 C 48.000003,55.168 55.168003,48.000001 64.000002,48.000001 z" id="path3139" sodipodi:nodetypes="ccccssccccccccsccscccccccccccccccccccccccccccccccccccccccccccccccssssccccccccsscccccsssc" /> <path sodipodi:nodetypes="ccccssccccccccsccscccccccccccccccccccccccccccccccccccccccccccccccssssccccccccsscccccsssc" id="path4891" d="M -83.999999,4 C -87.273852,4.0172764 -89.375767,4.1739184 -92.624999,4.625 C -93.586949,4.778184 -94.374999,5.4055494 -94.374999,6.375 L -94.968749,15.8125 C -95.057257,16.767694 -95.725392,17.39683 -96.437499,17.625 C -96.45933,17.631995 -96.478095,17.650033 -96.499999,17.65625 C -100.61684,18.761419 -104.52293,20.378352 -108.125,22.46875 C -108.77655,22.750681 -109.61713,22.733687 -110.3125,22.15625 L -117.40625,15.90625 C -118.09175,15.220752 -119.08648,15.33437 -119.875,15.90625 C -122.49151,17.884842 -124.11032,19.259755 -126.4375,21.5625 C -128.74024,23.889683 -130.11516,25.508484 -132.09375,28.125 C -132.66563,28.913521 -132.77925,29.908252 -132.09375,30.59375 L -125.84375,37.6875 C -125.37003,38.257979 -125.10755,38.996346 -125.375,39.53125 L -125.4375,39.65625 C -127.68302,43.45585 -129.43236,47.592563 -130.5625,51.96875 C -130.57434,51.989388 -130.58117,52.010911 -130.59375,52.03125 C -130.91096,52.544091 -131.44914,52.962834 -132.1875,53.03125 L -141.625,53.625 C -142.59444,53.625 -143.22181,54.41305 -143.375,55.375 C -143.82608,58.624232 -143.98272,60.726147 -144,64 C -143.98272,67.273853 -143.82608,69.375768 -143.375,72.625 C -143.22181,73.586946 -142.59444,74.375 -141.625,74.375 L -132.1875,74.96875 C -131.32015,75.04912 -130.74406,75.615317 -130.46875,76.25 C -129.36552,80.393354 -127.7025,84.314208 -125.59375,87.9375 C -125.22083,88.606007 -125.21212,89.551864 -125.84375,90.3125 L -132.09375,97.40625 C -132.77925,98.091746 -132.66563,99.086477 -132.09375,99.875 C -130.11516,102.49151 -128.74024,104.11031 -126.4375,106.4375 C -124.11032,108.74024 -122.49152,110.11516 -119.875,112.09375 C -119.08648,112.66563 -118.09175,112.77925 -117.40625,112.09375 L -110.3125,105.84375 C -109.55186,105.21212 -108.60601,105.22083 -107.9375,105.59375 L -107.84375,105.5 C -104.31609,107.51717 -100.51556,109.10952 -96.499999,110.1875 L -96.499999,110.34375 C -95.763598,110.55276 -95.05997,111.20302 -94.968749,112.1875 L -94.374999,121.625 C -94.374999,122.59444 -93.586949,123.22181 -92.624999,123.375 C -89.375767,123.82608 -87.273852,123.98272 -83.999999,124 C -80.726146,123.98272 -78.624231,123.82608 -75.374999,123.375 C -74.413053,123.22181 -73.624999,122.59444 -73.624999,121.625 L -73.031249,112.1875 C -72.940025,111.20302 -72.2364,110.55276 -71.499999,110.34375 L -71.499999,110.1875 C -67.484442,109.10952 -63.683904,107.51717 -60.156249,105.5 L -60.062499,105.59375 C -59.393992,105.22083 -58.448137,105.21212 -57.687499,105.84375 L -50.593749,112.09375 C -49.908246,112.77926 -48.913512,112.66564 -48.124999,112.09375 C -45.508489,110.11516 -43.889689,108.74024 -41.562499,106.4375 C -39.259759,104.11031 -37.884839,102.49151 -35.906249,99.875 C -35.334359,99.086487 -35.220739,98.091755 -35.906249,97.40625 L -42.156249,90.3125 C -42.787879,89.55186 -42.779169,88.606007 -42.406249,87.9375 C -40.297499,84.314208 -38.634479,80.393354 -37.531249,76.25 C -37.255939,75.615317 -36.679849,75.04912 -35.812499,74.96875 L -26.374999,74.375 C -25.405549,74.375 -24.778179,73.586946 -24.624999,72.625 C -24.173919,69.375768 -24.017279,67.273853 -23.999999,64 C -24.017279,60.726147 -24.173919,58.624232 -24.624999,55.375 C -24.778179,54.41305 -25.405549,53.625 -26.374999,53.625 L -35.812499,53.03125 C -36.550859,52.962834 -37.089039,52.544091 -37.406249,52.03125 C -37.411879,52.009328 -37.431839,51.99066 -37.437499,51.96875 C -38.567639,47.592563 -40.588709,43.603839 -42.562499,39.65625 L -42.624999,39.53125 C -42.892449,38.996346 -42.629969,38.257977 -42.156249,37.6875 L -35.906249,30.59375 C -35.220739,29.908244 -35.334369,28.913516 -35.906249,28.125 C -37.884839,25.508484 -39.259759,23.88968 -41.562499,21.5625 C -43.889679,19.259753 -45.508479,17.884841 -48.124999,15.90625 C -48.913515,15.334366 -49.908243,15.220745 -50.593749,15.90625 L -57.687499,22.15625 C -58.382875,22.733685 -59.223454,22.750682 -59.874999,22.46875 C -63.477074,20.378352 -67.383162,18.761419 -71.499999,17.65625 C -71.521903,17.650033 -71.540668,17.631995 -71.562499,17.625 C -72.274606,17.39683 -72.942738,16.767694 -73.031249,15.8125 L -73.624999,6.375 C -73.624999,5.4055494 -74.413053,4.778184 -75.374999,4.625 C -78.624231,4.1739184 -80.726146,4.0172764 -83.999999,4 z M -83.999999,48 C -75.168,47.999999 -67.999999,55.168 -67.999999,64 C -68,72.832 -75.168,80 -83.999999,80 C -92.831999,80 -99.999999,72.832 -99.999999,64 C -99.999998,55.167999 -92.831998,48 -83.999999,48 z" style="fill:url(#radialGradient6323);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" mask="url(#mask4921)" transform="translate(148,0)" /> <path style="opacity:0.95923911;fill:url(#radialGradient6325);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5054)" mask="none" clip-path="url(#clipPath5073)" d="M 76.90625,-70.062499 C 73.993994,-66.090403 69.299199,-63.499999 64,-63.499999 C 59.104212,-63.499999 54.716932,-65.68865 51.78125,-69.156249 L 20.28125,-38.406249 C 20.690082,-37.972249 21.088367,-37.541669 21.5625,-37.062499 C 23.88968,-34.759759 25.50848,-33.384839 28.125,-31.406249 C 28.91352,-30.834369 29.90825,-30.720749 30.59375,-31.406249 L 37.6875,-37.656249 C 38.44814,-38.287879 39.39399,-38.279169 40.0625,-37.906249 L 40.15625,-37.999999 C 43.68391,-35.982829 47.484439,-34.390479 51.5,-33.312499 L 51.5,-33.156249 C 52.236402,-32.947239 52.940029,-32.296979 53.03125,-31.312499 L 53.625,-21.874999 C 53.625001,-20.905559 54.41305,-20.278189 55.375,-20.124999 C 58.624233,-19.673919 60.726147,-19.517279 64,-19.499999 C 67.273854,-19.517279 69.375768,-19.673919 72.625,-20.124999 C 73.586947,-20.278189 74.375,-20.905559 74.375,-21.874999 L 74.96875,-31.312499 C 75.059975,-32.296979 75.763599,-32.947239 76.5,-33.156249 L 76.5,-33.312499 C 80.515558,-34.390479 84.316095,-35.982829 87.84375,-37.999999 L 87.9375,-37.906249 C 88.606008,-38.279169 89.551862,-38.287879 90.3125,-37.656249 L 97.40625,-31.406249 C 98.091754,-30.720739 99.086487,-30.834359 99.875,-31.406249 C 102.49151,-33.384839 104.11031,-34.759759 106.4375,-37.062499 C 106.92292,-37.553069 107.3327,-37.993909 107.75,-38.437499 L 76.90625,-70.062499 z" id="path4953" transform="translate(1.5e-6,143.5)" /> <path id="path5079" d="M 76.90625,-70.062499 C 73.993994,-66.090403 69.299199,-63.499999 64,-63.499999 C 59.104212,-63.499999 54.716932,-65.68865 51.78125,-69.156249 L 20.28125,-38.406249 C 20.690082,-37.972249 21.088367,-37.541669 21.5625,-37.062499 C 23.88968,-34.759759 25.50848,-33.384839 28.125,-31.406249 C 28.91352,-30.834369 29.90825,-30.720749 30.59375,-31.406249 L 37.6875,-37.656249 C 38.44814,-38.287879 39.39399,-38.279169 40.0625,-37.906249 L 40.15625,-37.999999 C 43.68391,-35.982829 47.484439,-34.390479 51.5,-33.312499 L 51.5,-33.156249 C 52.236402,-32.947239 52.940029,-32.296979 53.03125,-31.312499 L 53.625,-21.874999 C 53.625001,-20.905559 54.41305,-20.278189 55.375,-20.124999 C 58.624233,-19.673919 60.726147,-19.517279 64,-19.499999 C 67.273854,-19.517279 69.375768,-19.673919 72.625,-20.124999 C 73.586947,-20.278189 74.375,-20.905559 74.375,-21.874999 L 74.96875,-31.312499 C 75.059975,-32.296979 75.763599,-32.947239 76.5,-33.156249 L 76.5,-33.312499 C 80.515558,-34.390479 84.316095,-35.982829 87.84375,-37.999999 L 87.9375,-37.906249 C 88.606008,-38.279169 89.551862,-38.287879 90.3125,-37.656249 L 97.40625,-31.406249 C 98.091754,-30.720739 99.086487,-30.834359 99.875,-31.406249 C 102.49151,-33.384839 104.11031,-34.759759 106.4375,-37.062499 C 106.92292,-37.553069 107.3327,-37.993909 107.75,-38.437499 L 76.90625,-70.062499 z" clip-path="url(#clipPath5073)" mask="none" style="opacity:0.9918478;fill:url(#radialGradient6327);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5054)" transform="matrix(-1,0,0,-1,127.98705,-15.49155)" /> <path sodipodi:nodetypes="ccccssccccccccsccscccccccccccccccccccccccccccccccccccccccccccccccssssccccccccsscccccsssc" id="path5085" d="M 64.000002,4 C 60.726152,4.01728 58.624232,4.17392 55.375002,4.625 C 54.413052,4.77818 53.625002,5.40555 53.625002,6.375 L 53.031252,15.8125 C 52.942742,16.76769 52.274612,17.39683 51.562502,17.625 C 51.540672,17.632 51.521902,17.65003 51.500002,17.65625 C 47.383162,18.76142 43.477072,20.37835 39.875002,22.46875 C 39.223452,22.75068 38.382872,22.73369 37.687502,22.15625 L 30.593752,15.90625 C 29.908252,15.22075 28.913522,15.33437 28.125002,15.90625 C 25.508492,17.88484 23.889682,19.25975 21.562502,21.5625 C 19.259762,23.88968 17.884842,25.50848 15.906252,28.125 C 15.334372,28.91352 15.220752,29.90825 15.906252,30.59375 L 22.156252,37.6875 C 22.629972,38.25798 22.892452,38.99635 22.625002,39.53125 L 22.562502,39.65625 C 20.316982,43.45585 18.567642,47.592563 17.437502,51.96875 C 17.425662,51.989388 17.418832,52.010911 17.406252,52.03125 C 17.089042,52.544091 16.550862,52.962834 15.812502,53.03125 L 6.3750017,53.625 C 5.405562,53.625 4.778192,54.41305 4.625002,55.375 C 4.173922,58.624232 4.017282,60.726147 4.000002,64 C 4.017282,67.273853 4.173922,69.375768 4.625002,72.625 C 4.778192,73.586946 5.405562,74.375 6.3750017,74.375 L 15.812502,74.96875 C 16.679852,75.04912 17.255942,75.615317 17.531252,76.25 C 18.634482,80.393354 20.297502,84.314208 22.406252,87.9375 C 22.779172,88.606007 22.787882,89.551864 22.156252,90.3125 L 15.906252,97.40625 C 15.220752,98.091746 15.334372,99.08648 15.906252,99.875 C 17.884842,102.49151 19.259762,104.11031 21.562502,106.4375 C 23.889682,108.74024 25.508482,110.11516 28.125002,112.09375 C 28.913522,112.66563 29.908252,112.77925 30.593752,112.09375 L 37.687502,105.84375 C 38.448142,105.21212 39.393992,105.22083 40.062502,105.59375 L 40.156252,105.5 C 43.683912,107.51717 47.484442,109.10952 51.500002,110.1875 L 51.500002,110.34375 C 52.236402,110.55276 52.940032,111.20302 53.031252,112.1875 L 53.625002,121.625 C 53.625002,122.59444 54.413052,123.22181 55.375002,123.375 C 58.624232,123.82608 60.726152,123.98272 64.000002,124 C 67.273852,123.98272 69.375772,123.82608 72.625002,123.375 C 73.586952,123.22181 74.375002,122.59444 74.375002,121.625 L 74.968752,112.1875 C 75.059972,111.20302 75.763602,110.55276 76.500002,110.34375 L 76.500002,110.1875 C 80.515562,109.10952 84.316102,107.51717 87.843752,105.5 L 87.937502,105.59375 C 88.606012,105.22083 89.551862,105.21212 90.312502,105.84375 L 97.406248,112.09375 C 98.091748,112.77926 99.086488,112.66564 99.874998,112.09375 C 102.49151,110.11516 104.11031,108.74024 106.4375,106.4375 C 108.74024,104.11031 110.11516,102.49151 112.09375,99.875 C 112.66564,99.08649 112.77926,98.091755 112.09375,97.40625 L 105.84375,90.3125 C 105.21212,89.55186 105.22083,88.606007 105.59375,87.9375 C 107.7025,84.314208 109.36552,80.393354 110.46875,76.25 C 110.74406,75.615317 111.32015,75.04912 112.1875,74.96875 L 121.625,74.375 C 122.59445,74.375 123.22182,73.586946 123.375,72.625 C 123.82608,69.375768 123.98272,67.273853 124,64 C 123.98272,60.726147 123.82608,58.624232 123.375,55.375 C 123.22182,54.41305 122.59445,53.625 121.625,53.625 L 112.1875,53.03125 C 111.44914,52.962834 110.91096,52.544091 110.59375,52.03125 C 110.58812,52.009328 110.56816,51.99066 110.5625,51.96875 C 109.43236,47.592563 107.41129,43.603839 105.4375,39.65625 L 105.375,39.53125 C 105.10755,38.99635 105.37003,38.25798 105.84375,37.6875 L 112.09375,30.59375 C 112.77926,29.90824 112.66563,28.91352 112.09375,28.125 C 110.11516,25.50848 108.74024,23.88968 106.4375,21.5625 C 104.11032,19.25975 102.49152,17.88484 99.874998,15.90625 C 99.086478,15.33437 98.091758,15.22074 97.406248,15.90625 L 90.312502,22.15625 C 89.617122,22.73369 88.776552,22.75068 88.125002,22.46875 C 84.522932,20.37835 80.616842,18.76142 76.500002,17.65625 C 76.478102,17.65003 76.459332,17.632 76.437502,17.625 C 75.725392,17.39683 75.057262,16.76769 74.968752,15.8125 L 74.375002,6.375 C 74.375002,5.40555 73.586952,4.77818 72.625002,4.625 C 69.375772,4.17392 67.273852,4.01728 64.000002,4 z M 64.000002,48 C 72.832002,47.999999 80.000002,55.168 80.000002,64 C 80.000002,72.832 72.832002,80 64.000002,80 C 55.168002,80 48.000002,72.832 48.000002,64 C 48.000002,55.167999 55.168002,48 64.000002,48 z" style="opacity:0.73234199;fill:url(#radialGradient6415);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path mask="none" style="fill:none;fill-opacity:1;stroke:url(#linearGradient6412);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5162)" d="M 63.969328,3.96691 C 60.695478,3.98419 58.593558,4.14083 55.344328,4.59191 C 54.382378,4.74509 53.594328,5.37246 53.594328,6.34191 L 53.000578,15.77941 C 52.912068,16.7346 52.243938,17.36374 51.531828,17.59191 C 51.509998,17.59891 51.491228,17.61694 51.469328,17.62316 C 47.352488,18.72833 43.446398,20.34526 39.844328,22.43566 C 39.192778,22.71759 38.352198,22.7006 37.656828,22.12316 L 30.563078,15.87316 C 29.877578,15.18766 28.882848,15.30128 28.094328,15.87316 C 25.477818,17.85175 23.859008,19.22666 21.531828,21.52941 C 19.229088,23.85659 17.854168,25.47539 15.875578,28.09191 C 15.303698,28.88043 15.190078,29.87516 15.875578,30.56066 L 22.125578,37.65441 C 22.599298,38.22489 22.861778,38.96326 22.594328,39.49816 L 22.531828,39.62316 C 20.286308,43.42276 18.536968,47.559475 17.406828,51.935665 C 17.394988,51.956303 17.388158,51.977826 17.375578,51.998165 C 17.058368,52.511006 16.520188,52.929749 15.781828,52.998165 L 6.3443277,53.591915 C 5.3748876,53.591915 4.7475176,54.379965 4.5943276,55.341915 C 4.1432476,58.591147 3.9866076,60.693062 3.9693276,63.966915 C 3.9866076,67.240768 4.1432476,69.342683 4.5943276,72.591915 C 4.7475176,73.553861 5.3748876,74.341915 6.3443277,74.341915 L 15.781828,74.935665 C 16.649178,75.016035 17.225268,75.582232 17.500578,76.216915 C 18.603808,80.360269 20.266828,84.281123 22.375578,87.904415 C 22.748498,88.572922 22.757208,89.518779 22.125578,90.279415 L 15.875578,97.373165 C 15.190078,98.058661 15.303698,99.05339 15.875578,99.84192 C 17.854168,102.45843 19.229088,104.07723 21.531828,106.40442 C 23.859008,108.70716 25.477808,110.08208 28.094328,112.06067 C 28.882848,112.63255 29.877578,112.74617 30.563078,112.06067 L 37.656828,105.81067 C 38.417468,105.17904 39.363318,105.18775 40.031828,105.56067 L 40.125578,105.46692 C 43.653238,107.48409 47.453768,109.07644 51.469328,110.15442 L 51.469328,110.31067 C 52.205728,110.51968 52.909358,111.16994 53.000578,112.15442 L 53.594328,121.59192 C 53.594328,122.56136 54.382378,123.18873 55.344328,123.34192 C 58.593558,123.793 60.695478,123.94964 63.969328,123.96692 C 67.243178,123.94964 69.345098,123.793 72.594328,123.34192 C 73.556278,123.18873 74.344328,122.56136 74.344328,121.59192 L 74.938078,112.15442 C 75.029298,111.16994 75.732928,110.51968 76.469328,110.31067 L 76.469328,110.15442 C 80.484888,109.07644 84.285428,107.48409 87.813078,105.46692 L 87.906828,105.56067 C 88.575338,105.18775 89.521188,105.17904 90.281828,105.81067 L 97.375578,112.06067 C 98.061078,112.74618 99.055818,112.63256 99.844328,112.06067 C 102.46084,110.08208 104.07964,108.70716 106.40683,106.40442 C 108.70957,104.07723 110.08449,102.45843 112.06308,99.84192 C 112.63497,99.0534 112.74859,98.05867 112.06308,97.373165 L 105.81308,90.279415 C 105.18145,89.518775 105.19016,88.572922 105.56308,87.904415 C 107.67183,84.281123 109.33485,80.360269 110.43808,76.216915 C 110.71339,75.582232 111.28948,75.016035 112.15683,74.935665 L 121.59433,74.341915 C 122.56378,74.341915 123.19115,73.553861 123.34433,72.591915 C 123.79541,69.342683 123.95205,67.240768 123.96933,63.966915 C 123.95205,60.693062 123.79541,58.591147 123.34433,55.341915 C 123.19115,54.379965 122.56378,53.591915 121.59433,53.591915 L 112.15683,52.998165 C 111.41847,52.929749 110.88029,52.511006 110.56308,51.998165 C 110.55745,51.976243 110.53749,51.957575 110.53183,51.935665 C 109.40169,47.559475 107.38062,43.570755 105.40683,39.62316 L 105.34433,39.49816 C 105.07688,38.96326 105.33936,38.22489 105.81308,37.65441 L 112.06308,30.56066 C 112.74859,29.87515 112.63496,28.88043 112.06308,28.09191 C 110.08449,25.47539 108.70957,23.85659 106.40683,21.52941 C 104.07965,19.22666 102.46085,17.85175 99.844328,15.87316 C 99.055808,15.30128 98.061088,15.18765 97.375578,15.87316 L 90.281828,22.12316 C 89.586448,22.7006 88.745878,22.71759 88.094328,22.43566 C 84.492258,20.34526 80.586168,18.72833 76.469328,17.62316 C 76.447428,17.61694 76.428658,17.59891 76.406828,17.59191 C 75.694718,17.36374 75.026588,16.7346 74.938078,15.77941 L 74.344328,6.34191 C 74.344328,5.37246 73.556278,4.74509 72.594328,4.59191 C 69.345098,4.14083 67.243178,3.98419 63.969328,3.96691 z M 63.969328,47.966915 C 72.801328,47.966915 79.969328,55.134915 79.969328,63.966915 C 79.969328,72.798915 72.801328,79.966915 63.969328,79.966915 C 55.137328,79.966915 47.969328,72.798915 47.969328,63.966915 C 47.969328,55.134914 55.137328,47.966915 63.969328,47.966915 z" id="path5139" sodipodi:nodetypes="ccccssccccccccsccscccccccccccccccccccccccccccccccccccccccccccccccssssccccccccsscccccsssc" /> <path style="opacity:0.73234199;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 15.486342,28.9375 C 15.326382,29.522915 15.430352,30.131509 15.892592,30.59375 L 22.142592,37.6875 C 22.356312,37.944872 22.512882,38.239635 22.611342,38.53125 C 22.878792,37.99635 22.616312,37.25798 22.142592,36.6875 L 15.892592,29.59375 C 15.695272,29.396433 15.559372,29.173766 15.486342,28.9375 z M 112.45509,28.9375 C 112.38207,29.173767 112.27741,29.39643 112.08009,29.59375 L 105.83009,36.6875 C 105.36419,37.248562 105.11543,37.967423 105.36134,38.5 C 105.46142,38.220513 105.62522,37.934222 105.83009,37.6875 L 112.08009,30.59375 C 112.54234,30.131502 112.61506,29.522913 112.45509,28.9375 z M 63.986342,47 C 55.154342,47 47.98634,54.167999 47.986342,63 C 47.986342,63.170003 48.01232,63.331269 48.017592,63.5 C 48.286226,54.902828 55.324345,48 63.986342,48 C 72.648447,47.999999 79.686626,54.902677 79.955092,63.5 C 79.960358,63.331378 79.986342,63.169893 79.986342,63 C 79.986342,54.168 72.81834,46.999999 63.986342,47 z M 123.98634,63.5 C 123.95514,66.479862 123.78772,68.553675 123.36134,71.625 C 123.20816,72.586946 122.58079,73.375 121.61134,73.375 L 112.17384,73.96875 C 111.30649,74.04912 110.7304,74.615317 110.45509,75.25 C 109.35186,79.393354 107.68884,83.314208 105.58009,86.9375 C 105.34274,87.362983 105.23242,87.906576 105.36134,88.4375 C 105.40513,88.253701 105.49155,88.096221 105.58009,87.9375 C 107.68884,84.314208 109.35186,80.393354 110.45509,76.25 C 110.7304,75.615317 111.30649,75.04912 112.17384,74.96875 L 121.61134,74.375 C 122.58079,74.375 123.20816,73.586946 123.36134,72.625 C 123.81242,69.375768 123.96906,67.273853 123.98634,64 C 123.9854,63.820745 123.98815,63.672609 123.98634,63.5 z M 4.0175921,65.28125 C 4.0687221,67.851735 4.2236121,69.832063 4.6113421,72.625 C 4.7645321,73.586946 5.3919021,74.375 6.3613421,74.375 L 15.798842,74.96875 C 16.666192,75.04912 17.242282,75.615317 17.517592,76.25 C 18.620822,80.393354 20.283842,84.314208 22.392592,87.9375 C 22.480942,88.095885 22.536302,88.25413 22.580092,88.4375 C 22.709012,87.906576 22.629942,87.362983 22.392592,86.9375 C 20.283842,83.314208 18.620822,79.393354 17.517592,75.25 C 17.242282,74.615317 16.666192,74.04912 15.798842,73.96875 L 6.3613421,73.375 C 5.3919021,73.375 4.7645321,72.586946 4.6113421,71.625 C 4.2730321,69.188076 4.0900821,67.405878 4.0175921,65.28125 z M 15.486342,98.0625 C 15.305672,98.647047 15.485322,99.313451 15.892592,99.875 C 17.871182,102.49151 19.246102,104.11031 21.548842,106.4375 C 23.876022,108.74024 25.494822,110.11516 28.111342,112.09375 C 28.89986,112.66563 29.894592,112.77925 30.580092,112.09375 L 37.673842,105.84375 C 38.43448,105.21212 39.380332,105.22083 40.048842,105.59375 L 40.142592,105.5 C 43.67025,107.51717 47.470782,109.10952 51.486342,110.1875 L 51.486342,110.34375 C 52.22274,110.55276 52.926372,111.20302 53.017592,112.1875 L 53.611342,121.625 C 53.61134,122.59444 54.399392,123.22181 55.361342,123.375 C 58.61057,123.82608 60.712492,123.98272 63.986342,124 C 67.26019,123.98272 69.362112,123.82608 72.611342,123.375 C 73.57329,123.22181 74.361342,122.59444 74.361342,121.625 L 74.955092,112.1875 C 75.04631,111.20302 75.749942,110.55276 76.486342,110.34375 L 76.486342,110.1875 C 80.5019,109.10952 84.302442,107.51717 87.830092,105.5 L 87.923842,105.59375 C 88.59235,105.22083 89.538202,105.21212 90.298842,105.84375 L 97.392592,112.09375 C 98.078092,112.77926 99.072832,112.66564 99.86134,112.09375 C 102.47785,110.11516 104.09665,108.74024 106.42384,106.4375 C 108.72658,104.11031 110.1015,102.49151 112.08009,99.875 C 112.48737,99.313458 112.63577,98.64705 112.45509,98.0625 C 112.37783,98.345251 112.26635,98.618192 112.08009,98.875 C 110.1015,101.49151 108.72658,103.11031 106.42384,105.4375 C 104.09665,107.74024 102.47785,109.11516 99.86134,111.09375 C 99.072832,111.66564 98.078092,111.77926 97.392592,111.09375 L 90.298842,104.84375 C 89.538202,104.21212 88.59235,104.22083 87.923842,104.59375 L 87.830092,104.5 C 84.302442,106.51717 80.5019,108.10952 76.486342,109.1875 L 76.486342,109.34375 C 75.749942,109.55276 75.04631,110.20302 74.955092,111.1875 L 74.361342,120.625 C 74.361342,121.59444 73.57329,122.22181 72.611342,122.375 C 69.362112,122.82608 67.26019,122.98272 63.986342,123 C 60.712492,122.98272 58.61057,122.82608 55.361342,122.375 C 54.399392,122.22181 53.61134,121.59444 53.611342,120.625 L 53.017592,111.1875 C 52.926372,110.20302 52.22274,109.55276 51.486342,109.34375 L 51.486342,109.1875 C 47.470782,108.10952 43.67025,106.51717 40.142592,104.5 L 40.048842,104.59375 C 39.380332,104.22083 38.43448,104.21212 37.673842,104.84375 L 30.580092,111.09375 C 29.894592,111.77925 28.89986,111.66563 28.111342,111.09375 C 25.494822,109.11516 23.876022,107.74024 21.548842,105.4375 C 19.246102,103.11031 17.871182,101.49151 15.892592,98.875 C 15.706342,98.618188 15.563602,98.345252 15.486342,98.0625 z" id="path2293" /> <path style="fill:url(#linearGradient6408);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5257)" d="M 55.234189,4.1094074 C 59.793055,3.6731616 67.427002,3.5064632 72.177942,4.0736611 C 74.083693,4.301182 74.71593,6.9512394 74.322721,11.437402 C 74.295467,11.748351 73.75078,5.4767039 71.820479,5.3962747 C 67.149676,5.2016579 60.140185,4.9297585 55.591652,5.3962747 C 54.546072,5.5035137 53.630117,7.5889507 53.625605,7.2550831 C 53.607732,5.8609768 53.379455,4.2868901 55.234189,4.1094074 z" id="path5211" sodipodi:nodetypes="cssssss" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6335);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path5245" sodipodi:cx="54.672985" sodipodi:cy="6.8499207" sodipodi:rx="1.2890996" sodipodi:ry="2.4518168" d="M 55.962085,6.8499207 A 1.2890996,2.4518168 0 1 1 53.383886,6.8499207 A 1.2890996,2.4518168 0 1 1 55.962085,6.8499207 z" transform="matrix(0.899969,0.4359538,-0.4359538,0.899969,8.6574518,-23.80688)" /> <path transform="matrix(-0.899969,0.4359538,0.4359538,0.899969,119.08978,-23.80688)" d="M 55.962085,6.8499207 A 1.2890996,2.4518168 0 1 1 53.383886,6.8499207 A 1.2890996,2.4518168 0 1 1 55.962085,6.8499207 z" sodipodi:ry="2.4518168" sodipodi:rx="1.2890996" sodipodi:cy="6.8499207" sodipodi:cx="54.672985" id="path5261" style="fill:url(#radialGradient6337);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" sodipodi:type="arc" /> <g id="g5317"> <path sodipodi:nodetypes="cccccccccccccc" id="path5265" d="M 51.361769,18.300158 C 47.31399,19.538268 43.502707,21.010153 39.835703,23.200199 C 38.838725,23.56376 38.239385,23.203633 37.409163,22.69467 L 30.533965,16.581359 C 30.100651,16.223138 29.032451,15.656721 28.208531,16.379147 C 23.636725,20.338825 19.992825,24.584012 15.974724,28.71406 L 17.464573,27.925114 C 21.036923,24.466658 24.476222,20.963851 28.309637,17.592417 C 28.879576,17.120343 29.732198,17.301563 30.230648,17.794629 L 36.814794,23.598489 C 37.820831,24.58216 39.105219,24.977955 40.442338,24.514575 C 44.087158,22.164406 47.913748,20.535239 51.939844,18.94762 C 52.785283,18.599047 53.455728,17.247499 53.342533,16.140136 C 53.225179,16.85456 52.34317,17.987134 51.361769,18.300158 z" style="fill:url(#linearGradient6339);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5309)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient6341);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="path5313" sodipodi:cx="54.672985" sodipodi:cy="6.8499207" sodipodi:rx="1.2890996" sodipodi:ry="2.4518168" d="M 55.962085,6.8499207 A 1.2890996,2.4518168 0 1 1 53.383886,6.8499207 A 1.2890996,2.4518168 0 1 1 55.962085,6.8499207 z" transform="matrix(0.2034271,1.2369315,-0.9790901,0.2569992,24.508092,-52.470535)" /> </g> <g id="g5331" transform="matrix(-1,0,0,1,128.37557,0)"> <path style="fill:url(#linearGradient6343);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5309)" d="M 51.361769,18.300158 C 47.31399,19.538268 43.502707,21.010153 39.835703,23.200199 C 38.838725,23.56376 38.668341,22.703185 37.838119,22.194222 L 30.962921,16.080911 C 30.529607,15.72269 29.032451,15.656721 28.208531,16.379147 C 22.994884,19.696984 19.49462,24.085807 15.974724,28.71406 L 17.464573,27.925114 C 19.948131,25.060545 23.468546,21.513493 28.309637,17.592417 C 28.879576,17.120343 30.161154,16.801115 30.659604,17.294181 L 37.24375,23.098041 C 38.249787,24.081712 39.105219,24.977955 40.442338,24.514575 C 44.087158,22.164406 47.913748,20.535239 51.939844,18.94762 C 52.785283,18.599047 53.455728,17.247499 53.342533,16.140136 C 53.225179,16.85456 52.34317,17.987134 51.361769,18.300158 z" id="path5333" sodipodi:nodetypes="cccccccccccccc" /> <path transform="matrix(0.2034271,1.2369315,-0.9790901,0.2569992,24.508092,-52.470535)" d="M 55.962085,6.8499207 A 1.2890996,2.4518168 0 1 1 53.383886,6.8499207 A 1.2890996,2.4518168 0 1 1 55.962085,6.8499207 z" sodipodi:ry="2.4518168" sodipodi:rx="1.2890996" sodipodi:cy="6.8499207" sodipodi:cx="54.672985" id="path5335" style="opacity:1;fill:url(#radialGradient6345);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" sodipodi:type="arc" /> </g> <path sodipodi:type="arc" style="opacity:0.31970257;fill:url(#radialGradient6347);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5505)" id="path5341" sodipodi:cx="54.672985" sodipodi:cy="6.8499207" sodipodi:rx="1.2890996" sodipodi:ry="2.4518168" d="M 55.962085,6.8499207 A 1.2890996,2.4518168 0 1 1 53.383886,6.8499207 A 1.2890996,2.4518168 0 1 1 55.962085,6.8499207 z" transform="matrix(-0.9946903,-0.4812292,-0.3574506,0.9612934,168.32567,49.779168)" inkscape:transform-center-x="0.70774092" inkscape:transform-center-y="0.60663507" /> <path inkscape:transform-center-y="0.60663507" inkscape:transform-center-x="-0.70774134" transform="matrix(0.9946903,-0.4812292,0.3574506,0.9612934,-39.943898,50.082486)" d="M 55.962085,6.8499207 A 1.2890996,2.4518168 0 1 1 53.383886,6.8499207 A 1.2890996,2.4518168 0 1 1 55.962085,6.8499207 z" sodipodi:ry="2.4518168" sodipodi:rx="1.2890996" sodipodi:cy="6.8499207" sodipodi:cx="54.672985" id="path5509" style="opacity:0.31970257;fill:url(#radialGradient6349);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5505)" sodipodi:type="arc" /> <path style="fill:url(#linearGradient6395);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5581)" d="M 109.72078,50.196512 C 109.90912,50.933157 109.69575,52.311579 110.19226,53.441451 C 110.48274,54.102469 110.88736,54.526819 111.41864,54.546603 C 116.20582,54.724865 118.36563,54.681116 121.52923,54.900474 C 122.00058,54.933156 122.58757,55.226399 122.81784,56.141217 C 123.23273,57.789461 123.16843,61.128778 123.60189,62.710901 C 124.3426,65.546272 123.89819,57.905429 123.55134,55.608215 C 123.26906,54.022185 122.5811,53.327607 121.73144,53.28278 C 118.36035,53.104927 114.984,53.218169 111.31754,53.080569 C 111.06358,53.114284 110.78853,52.816722 110.53609,52.38652 C 110.086,51.619466 110.11888,50.537973 109.72078,50.196512 z" id="path5513" sodipodi:nodetypes="cssssccscsc" /> <path sodipodi:nodetypes="cssssccscsc" id="path5585" d="M 109.72078,49.696512 C 109.90912,50.433157 109.69575,51.811579 110.19226,52.941451 C 110.48274,53.602469 110.88736,54.026819 111.41864,54.046603 C 116.20582,54.224865 118.36563,54.681116 121.52923,54.900474 C 122.00058,54.933156 122.58757,55.226399 122.81784,56.141217 C 123.23273,57.789461 123.16843,61.128778 123.60189,62.710901 C 124.3426,65.546272 123.89819,57.905429 123.55134,55.608215 C 123.26906,54.022185 122.5811,53.327607 121.73144,53.28278 C 118.36035,53.104927 114.984,52.718169 111.31754,52.580569 C 111.06358,52.614284 110.78853,52.316722 110.53609,51.88652 C 110.086,51.119466 110.11888,50.037973 109.72078,49.696512 z" style="fill:url(#linearGradient6353);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5581)" transform="matrix(-1,0,0,1,128.27026,0.7)" /> <path style="opacity:0.87360595;fill:url(#linearGradient6391);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5876)" d="M 48.310016,64.191133 C 48.305267,64.34987 48.262848,64.502928 48.262848,64.662809 C 48.262848,73.339333 55.340282,80.369599 64.016806,80.369599 C 72.69333,80.369599 79.723601,73.339336 79.723596,64.662809 C 79.723596,64.502928 79.681177,64.34987 79.676428,64.191133 C 79.448061,72.668853 72.549344,79.473416 64.016806,79.473416 C 55.484266,79.473416 48.538388,72.668853 48.310016,64.191133 z" id="path5589" /> <path style="opacity:0.87360595;fill:#565656;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5718)" d="M 79.676428,63.990452 C 79.681177,63.831715 79.723596,63.678657 79.723596,63.518776 C 79.723596,54.842252 72.646162,47.811986 63.969638,47.811986 C 55.293114,47.811986 48.262843,54.842249 48.262848,63.518776 C 48.262848,63.678657 48.305267,63.831715 48.310016,63.990452 C 48.538383,55.512732 55.4371,48.708169 63.969638,48.708169 C 72.502178,48.708169 79.448056,55.512732 79.676428,63.990452 z" id="path5596" /> <path id="path5722" d="M 80.264493,64.297087 C 80.26942,64.132398 80.313429,63.973601 80.313429,63.807725 C 80.313429,54.805862 72.970617,47.511986 63.968754,47.511986 C 54.966891,47.511986 47.67301,54.805859 47.673015,63.807725 C 47.673015,63.973601 47.717024,64.132398 47.721951,64.297087 C 47.958881,55.501483 55.116276,48.026774 63.968754,48.026774 C 72.821234,48.026774 80.027557,55.501483 80.264493,64.297087 z" style="opacity:0.87360595;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5836)" sodipodi:nodetypes="cssscsc" /> <path id="path5888" d="M 48.310016,64.191133 C 48.305267,64.34987 48.262848,64.502928 48.262848,64.662809 C 48.262848,73.339333 55.340282,81.369599 64.016806,81.369599 C 72.69333,81.369599 79.723601,73.339336 79.723596,64.662809 C 79.723596,64.502928 79.681177,64.34987 79.676428,64.191133 C 79.448061,72.668853 72.549344,79.473416 64.016806,79.473416 C 55.484266,79.473416 48.538388,72.668853 48.310016,64.191133 z" style="opacity:0.34572491;fill:url(#linearGradient6386);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter5876)" sodipodi:nodetypes="cssscsc" /> <path style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5960)" d="M 112.31492,97.901603 C 112.36723,98.459206 112.1884,98.939761 111.95746,99.402948 L 108.5973,103.764 L 111.67149,99.402948 C 111.53652,98.886575 111.48142,98.330267 111.17104,97.901603 C 109.38533,95.700951 107.11057,93.581807 106.09506,91.252789 L 112.31492,97.901603 z" id="path5890" sodipodi:nodetypes="ccccccc" /> <path sodipodi:nodetypes="ccccccc" id="path5964" d="M 112.31492,97.901603 C 112.36723,98.459206 112.1884,98.939761 111.95746,99.402948 L 108.5973,103.764 L 111.67149,99.402948 C 111.53652,98.886575 111.48142,98.330267 111.17104,97.901603 C 109.38533,95.700951 107.11057,93.581807 106.09506,91.252789 L 112.31492,97.901603 z" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5960)" transform="matrix(-1,0,0,1,128.41914,0)" /> <path transform="matrix(0.5892134,0,0,0.5892134,-119.15695,-0.1299716)" d="M 366.04225,108.83997 A 55.192307,55.192307 0 1 1 255.65764,108.83997 A 55.192307,55.192307 0 1 1 366.04225,108.83997 z" sodipodi:ry="55.192307" sodipodi:rx="55.192307" sodipodi:cy="108.83997" sodipodi:cx="310.84995" id="path3300" style="fill:none;fill-opacity:0.07755103;stroke:url(#linearGradient6359);stroke-width:1.69717801;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3310)" sodipodi:type="arc" /> <path style="fill:#343434;fill-opacity:0.07755103;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3310)" d="M 64,31.46875 C 46.048934,31.46875 31.468751,46.048934 31.46875,64 C 31.46875,81.951066 46.048937,96.531253 64,96.53125 C 81.951066,96.53125 96.53125,81.951065 96.53125,64 C 96.53125,46.048934 81.951069,31.468751 64,31.46875 z M 64,49.40625 C 72.050642,49.40625 78.59375,55.949358 78.59375,64 C 78.59375,72.050642 72.050642,78.59375 64,78.59375 C 55.949358,78.59375 49.40625,72.050642 49.40625,64 C 49.40625,55.949358 55.949358,49.40625 64,49.40625 z" id="path3326" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6361);fill-opacity:1;stroke:none;stroke-width:0.48188975;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15;stroke-opacity:1" id="path5737" sodipodi:cx="64.101105" sodipodi:cy="58.236969" sodipodi:rx="22.445498" sodipodi:ry="22.445498" d="M 86.546602,58.236969 A 22.445498,22.445498 0 1 1 41.655607,58.236969 A 22.445498,22.445498 0 1 1 86.546602,58.236969 z" transform="matrix(1.4144163,0,0,1.4144163,-26.682236,-18.493557)" /> <path transform="matrix(1.4144163,0,0,1.4144163,-26.682236,-18.493557)" d="M 86.546602,58.236969 A 22.445498,22.445498 0 1 1 41.655607,58.236969 A 22.445498,22.445498 0 1 1 86.546602,58.236969 z" sodipodi:ry="22.445498" sodipodi:rx="22.445498" sodipodi:cy="58.236969" sodipodi:cx="64.101105" id="path6023" style="fill:url(#radialGradient6363);fill-opacity:1;stroke:none;stroke-width:0.48188975;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15;stroke-opacity:1" sodipodi:type="arc" /> <path transform="matrix(1.4144163,0,0,1.4144163,-26.682236,-18.493557)" d="M 86.546602,58.236969 A 22.445498,22.445498 0 1 1 41.655607,58.236969 A 22.445498,22.445498 0 1 1 86.546602,58.236969 z" sodipodi:ry="22.445498" sodipodi:rx="22.445498" sodipodi:cy="58.236969" sodipodi:cx="64.101105" id="path5941" style="fill:url(#linearGradient6365);fill-opacity:1;stroke:none;stroke-width:0.48188975;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15;stroke-opacity:1;filter:url(#filter6019)" sodipodi:type="arc" clip-path="url(#clipPath5947)" /> <g id="g6109" transform="matrix(0.6879621,0,0,0.6879621,-114.95451,16.172498)"> <path id="path6041" d="M 249.70376,45.294924 C 244.28152,45.507398 239.99637,49.966737 240,55.39314 L 240,80.638679 C 240.01709,84.125914 241.83207,87.357596 244.80092,89.187059 C 247.7698,91.016522 251.47243,91.184883 254.59508,89.632403 L 279.84062,77.009633 C 283.21928,75.283737 285.34561,71.809857 285.34561,68.01591 C 285.34561,64.221962 283.21928,60.748083 279.84062,59.022186 L 254.59508,46.399416 C 253.08343,45.625896 251.40111,45.246021 249.70376,45.294924 z" style="fill:url(#radialGradient6367);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.99997759;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path transform="translate(49.539651,0)" clip-path="url(#clipPath6103)" id="path6067" d="M 200.15625,43.880333 C 194.73401,44.092803 190.46512,48.547673 190.46875,53.974083 L 190.46875,56.974083 C 190.46512,51.547673 194.73401,47.092803 200.15625,46.880333 C 201.8536,46.831433 203.55085,47.200563 205.0625,47.974083 L 230.3125,60.599083 C 233.23871,62.093863 235.20784,64.909623 235.6875,68.099083 C 235.76166,67.605923 235.8125,67.107143 235.8125,66.599083 C 235.81249,62.805143 233.69116,59.324983 230.3125,57.599083 L 205.0625,44.974083 C 203.55085,44.200563 201.8536,43.831433 200.15625,43.880333 z" style="fill:#121212;fill-opacity:0.77810651;fill-rule:evenodd;stroke:none;stroke-width:7.99997759;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter6085)" /> <path transform="translate(98.3,0)" clip-path="url(#clipPath6097)" id="path6069" d="M 186.9375,67.53447 C 186.45778,70.72382 184.48863,73.53973 181.5625,75.03447 L 156.3125,87.65947 C 153.18985,89.21195 149.50012,89.05144 146.53125,87.22197 C 143.5624,85.39251 141.73585,82.14671 141.71875,78.65947 L 141.71875,81.65947 C 141.73585,85.14671 143.5624,88.39251 146.53125,90.22197 C 149.50012,92.05144 153.18985,92.21195 156.3125,90.65947 L 181.5625,78.03447 C 184.94117,76.30857 187.0625,72.82841 187.0625,69.03447 C 187.0625,68.52632 187.01169,68.02771 186.9375,67.53447 z" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.99997759;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter6093)" /> </g> <path style="fill:url(#linearGradient6372);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 32.663743,62.558842 C 47.790896,67.271222 79.465243,66.662474 95.111981,58.071282 L 95.083473,57.156355 C 78.858817,65.657736 47.897487,67.244919 32.663743,62.558842 z" id="path6029" sodipodi:nodetypes="cccc" /> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/about.svg������������������������������������������������������������0000644�0001750�0000144�00000037316�10737543470�016377� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2" sodipodi:version="0.32" inkscape:version="0.44.1" version="1.0" sodipodi:docbase="/Users/david/Progetti/oxygen-svn/theme/svg/actions" sodipodi:docname="info.svg"> <defs id="defs4"> <linearGradient id="linearGradient8332" gradientUnits="userSpaceOnUse" x1="-84.002403" y1="-383.9971" x2="-12.0029" y2="-383.9971" gradientTransform="matrix(0,1,-1,0,-39.9985,140.0029)"> <stop offset="0" style="stop-color:white;stop-opacity:0;" id="stop8334" /> <stop id="stop8340" style="stop-color:#005ab5;stop-opacity:0;" offset="0.8125" /> <stop offset="1" style="stop-color:#005ab5;stop-opacity:1;" id="stop8336" /> </linearGradient> <linearGradient gradientTransform="matrix(0,1,-1,0,-39.9985,140.0029)" y2="-383.9971" x2="-12.0029" y1="-383.9971" x1="-84.002403" gradientUnits="userSpaceOnUse" id="linearGradient6537"> <stop id="stop6539" style="stop-color:#0081ec;stop-opacity:1;" offset="0" /> <stop id="stop6541" style="stop-color:#0057ae;stop-opacity:1;" offset="1" /> </linearGradient> <linearGradient id="linearGradient3954"> <stop style="stop-color:#b3b3b3;stop-opacity:1;" offset="0" id="stop3956" /> <stop id="stop3962" offset="0.52879584" style="stop-color:#ffffff;stop-opacity:1;" /> <stop style="stop-color:#c5c5c5;stop-opacity:1;" offset="1" id="stop3958" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3954" id="linearGradient3112" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.947013,0,0,0.947013,-91.07835,-17.66858)" x1="129.2838" y1="126.57678" x2="188.37695" y2="50.386463" /> <linearGradient id="linearGradient26907" gradientUnits="userSpaceOnUse" x1="-84.002403" y1="-383.9971" x2="-12.0029" y2="-383.9971" gradientTransform="matrix(0,1,-1,0,-39.9985,140.0029)"> <stop offset="0" style="stop-color:#888a85;stop-opacity:1;" id="stop26909" /> <stop offset="1" style="stop-color:#2e3436;stop-opacity:1;" id="stop26911" /> </linearGradient> <linearGradient gradientTransform="matrix(0,1,-1,0,-39.9985,140.0029)" y2="-383.9975" x2="-23.516129" y1="-383.9971" x1="-84.002403" gradientUnits="userSpaceOnUse" id="linearGradient3711"> <stop id="stop3713" style="stop-color:white;stop-opacity:1;" offset="0" /> <stop id="stop3715" style="stop-color:white;stop-opacity:0;" offset="1" /> </linearGradient> <linearGradient id="linearGradient3081"> <stop id="stop3083" offset="0" style="stop-color:#28691f;stop-opacity:1;" /> <stop id="stop3085" offset="1" style="stop-color:#00bf00;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient3290"> <stop style="stop-color:yellow;stop-opacity:1;" offset="0" id="stop3292" /> <stop style="stop-color:#ffb66d;stop-opacity:1;" offset="1" id="stop3294" /> </linearGradient> <linearGradient id="linearGradient3638"> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="0" id="stop3640" /> <stop id="stop3661" offset="0.06868132" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop3659" offset="0.5" style="stop-color:#ffffff;stop-opacity:1;" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3642" /> </linearGradient> <linearGradient id="linearGradient1563"> <stop id="stop1565" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop1567" offset="1" style="stop-color:white;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3273"> <stop id="stop3275" offset="0" style="stop-color:#ffffff;stop-opacity:0.55035973;" /> <stop id="stop3277" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3291" inkscape:collect="always"> <stop id="stop3293" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop3295" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient12948"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop12950" /> <stop style="stop-color:#c0c0c0;stop-opacity:0;" offset="1" id="stop12952" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3291" id="radialGradient3743" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.197802,0,92.82166)" cx="63.912209" cy="115.70919" fx="63.975182" fy="116.88514" r="63.912209" /> <radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.111111,0,138.1081)" r="64.796692" fy="177.29686" fx="80.738739" cy="155.37218" cx="80.738739" id="radialGradient5079" xlink:href="#linearGradient5073" inkscape:collect="always" /> <linearGradient id="linearGradient5073" inkscape:collect="always"> <stop id="stop5075" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop5077" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <foreignObject id="foreignObject7221" height="1" width="1" y="0" x="0" requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/"> <i:pgfRef xlink:href="#adobe_illustrator_pgf" /> </foreignObject> <linearGradient id="XMLID_1_" gradientUnits="userSpaceOnUse" x1="95.693398" y1="141.1738" x2="32.308601" y2="77.789001"> <stop offset="0" style="stop-color:#75511A" id="stop7227" /> <stop offset="0.3988" style="stop-color:#563A11" id="stop7229" /> <stop offset="0.7642" style="stop-color:#402B0B" id="stop7231" /> <stop offset="1" style="stop-color:#382509" id="stop7233" /> </linearGradient> <linearGradient id="XMLID_3_" gradientUnits="userSpaceOnUse" x1="63.9995" y1="92.865196" x2="63.9995" y2="120.8652" gradientTransform="translate(175.0067,11.74752)"> <stop offset="0" style="stop-color:#888A85" id="stop7261" /> <stop offset="0.3226" style="stop-color:#A6A7A3" id="stop7263" /> <stop offset="1" style="stop-color:#EEEEEC" id="stop7265" /> </linearGradient> <linearGradient id="XMLID_4_" gradientUnits="userSpaceOnUse" x1="64.000504" y1="108.8652" x2="64.000504" y2="92.865196"> <stop offset="0" style="stop-color:#EEEEEC" id="stop7270" /> <stop offset="1" style="stop-color:#FFFFFF" id="stop7272" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3081" id="linearGradient2149" gradientUnits="userSpaceOnUse" x1="62.112335" y1="90.513916" x2="67.887672" y2="39.095695" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3711" id="radialGradient1978" gradientUnits="userSpaceOnUse" cx="343.99899" cy="92" fx="343.99899" fy="92" r="36" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3711" id="linearGradient6552" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0,1.591298,-1.591298,0,-146.0489,141.4862)" x1="-88.058083" y1="-131.93112" x2="-45.096584" y2="-131.93112" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6537" id="linearGradient6556" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0,1,-1,0,-39.9985,140.0029)" x1="-70.002899" y1="-383.9971" x2="-11.91648" y2="-383.9971" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient8332" id="radialGradient8330" cx="343.99899" cy="92" fx="343.99899" fy="92" r="36" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient8332" id="radialGradient8345" gradientUnits="userSpaceOnUse" cx="343.99899" cy="92" fx="343.99899" fy="92" r="36" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="64" inkscape:cy="48.421907" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1018" inkscape:window-height="694" inkscape:window-x="0" inkscape:window-y="22" showgrid="true" gridspacingx="4px" gridspacingy="4px" gridempspacing="0" inkscape:grid-points="true" inkscape:object-paths="false" showguides="true" inkscape:guide-bbox="true" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <path sodipodi:type="arc" style="opacity:0.38139535;fill:url(#radialGradient3743);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path3289" sodipodi:cx="63.912209" sodipodi:cy="115.70919" sodipodi:rx="63.912209" sodipodi:ry="12.641975" d="M 127.82442 115.70919 A 63.912209 12.641975 0 1 1 0,115.70919 A 63.912209 12.641975 0 1 1 127.82442 115.70919 z" transform="matrix(-1.001374,0,0,0.410379,128,75.32738)" /> <circle sodipodi:ry="36" sodipodi:rx="36" sodipodi:cy="92" sodipodi:cx="343.99899" style="fill:url(#linearGradient6556);fill-opacity:1" r="36" rx="8.0010004" cx="343.99899" cy="92" ry="8.0010004" id="circle3581_2_" transform="matrix(-1.502244,0.402525,-0.402525,-1.502244,617.8027,63.73825)" /> <circle transform="matrix(-0.667663,6.708758e-2,-0.1789,-0.250375,310.1343,104.4008)" id="circle22111" ry="8.0010004" cy="92" cx="343.99899" rx="8.0010004" r="36" style="opacity:0.4;fill:url(#radialGradient1978);fill-opacity:1" sodipodi:cx="343.99899" sodipodi:cy="92" sodipodi:rx="36" sodipodi:ry="36" /> <path style="opacity:0.8;fill:url(#linearGradient6552);fill-opacity:1" d="M 64.000032,14.177736 C 39.563103,14.177736 19.143817,31.433503 14.22224,54.407743 C 24.032276,63.552748 42.646324,69.723981 64.000032,69.723981 C 85.353756,69.723981 103.96779,63.552748 113.77782,54.407743 C 108.85626,31.433503 88.436946,14.177736 64.000032,14.177736 z " id="circle16776" /> <path sodipodi:nodetypes="ccccccccccc" id="path5288" d="M 72,56 L 48,56 L 48,64 L 56,64 L 56,96 L 48,96 L 48,104 L 80,104 L 80,96 L 72,96 C 72,96 72,56 72,56 z " style="font-size:132.5063324px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:none;fill-opacity:1;stroke:#0057ae;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;font-family:Bitstream Vera Serif;stroke-miterlimit:4;stroke-dasharray:none;opacity:0.5" /> <path sodipodi:nodetypes="ccc" id="path2276" d="M -106.3852,44.124126 L -106.3852,41.329417 L -106.3852,44.124126 z " style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path id="path5291" d="M 64.125792,22.602966 C 57.503028,22.602966 52.125799,27.98018 52.125799,34.60297 C 52.125799,41.22576 57.503028,46.602969 64.125792,46.602969 C 70.748584,46.602969 76.125799,41.225759 76.125799,34.60297 C 76.125799,27.98018 70.748598,22.602966 64.125792,22.602966 z " style="font-size:132.5063324px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:none;fill-opacity:1;stroke:#0057ae;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;font-family:Bitstream Vera Serif;stroke-miterlimit:4;stroke-dasharray:none;opacity:0.5" /> <path style="font-size:132.5063324px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:white;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;font-family:Bitstream Vera Serif;stroke-miterlimit:4;stroke-dasharray:none" d="M 64.125792,22.602966 C 57.503028,22.602966 52.125799,27.98018 52.125799,34.60297 C 52.125799,41.22576 57.503028,46.602969 64.125792,46.602969 C 70.748584,46.602969 76.125799,41.225759 76.125799,34.60297 C 76.125799,27.98018 70.748598,22.602966 64.125792,22.602966 z " id="path4399" /> <path style="font-size:132.5063324px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:white;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;font-family:Bitstream Vera Serif;stroke-miterlimit:4;stroke-dasharray:none;opacity:1" d="M 72,56 L 48,56 L 48,64 L 56,64 L 56,96 L 48,96 L 48,104 L 80,104 L 80,96 L 72,96 C 72,96 72,56 72,56 z " id="path2876" sodipodi:nodetypes="ccccccccccc" /> </g> </svg> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/file-rename.svg������������������������������������������������������0000644�0001750�0000144�00000210471�11165071421�017430� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:ns="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg1307" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" sodipodi:docname="file-rename.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs1309"> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2783" id="linearGradient2853" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6396061,0,0,0.2975711,-219.32795,-16.635765)" x1="190.03462" y1="90.22673" x2="207.94772" y2="90.22673" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2783" id="linearGradient2850" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.5845965,0,0,0.2719788,-208.29628,-82.092949)" x1="190.03462" y1="90.22673" x2="207.94772" y2="90.22673" /> <linearGradient inkscape:collect="always" id="linearGradient2584"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop2586" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop2588" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2584" id="linearGradient2847" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7007659,0,0,0.7007659,-214.84064,-138.4309)" x1="254.01285" y1="282.73343" x2="183.3956" y2="212.11615" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2783" id="linearGradient2844" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7007659,0,0,0.7007659,-231.41295,-79.905807)" x1="190.03462" y1="90.22673" x2="208.7153" y2="90.22673" /> <linearGradient inkscape:collect="always" id="linearGradient2816"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop2818" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop2820" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2816" id="linearGradient2841" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7007659,0,0,0.7007659,-60.584337,-174.06617)" x1="-40.931931" y1="154.80533" x2="-44.212151" y2="142.56337" /> <linearGradient inkscape:collect="always" id="linearGradient3737"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3739" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3741" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3737" id="linearGradient2835" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7007659,0,0,0.7007659,-60.584337,-174.06617)" x1="-53.739216" y1="145.54308" x2="-53.739216" y2="146.01439" /> <linearGradient inkscape:collect="always" id="linearGradient3969"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3971" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3973" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3969" id="linearGradient2832" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7007659,0,0,0.7007659,-214.84064,-121.32351)" x1="98.411324" y1="185.68851" x2="166.32983" y2="155.59846" /> <linearGradient inkscape:collect="always" id="linearGradient2837"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop2839" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop2841" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2837" id="linearGradient2826" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0394891,0,0,0.8127018,139.27881,-202.85961)" x1="-71.804848" y1="128.92874" x2="-56.400097" y2="224.42052" /> <linearGradient id="linearGradient2803"> <stop id="stop2809" offset="0" style="stop-color:#e2dcdc;stop-opacity:1;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.39074388" id="stop2811" /> <stop style="stop-color:#dfd9df;stop-opacity:1;" offset="0.82692307" id="stop2813" /> <stop style="stop-color:#c3c3c3;stop-opacity:1;" offset="1" id="stop2815" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2803" id="linearGradient2823" gradientUnits="userSpaceOnUse" x1="22.22868" y1="-5.3515735" x2="27.94627" y2="-5.3515735" gradientTransform="matrix(0.8113368,0,0,0.8113368,-84.183374,91.988474)" /> <linearGradient inkscape:collect="always" id="linearGradient3794"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3796" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3798" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3794" id="linearGradient2768" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.603475,1.045249,-1.045249,0.603475,205.9786,145.2615)" x1="-52.533428" y1="212.26097" x2="-52.218658" y2="210.21022" /> <linearGradient id="linearGradient2334"> <stop id="stop2336" offset="0" style="stop-color:#323232;stop-opacity:1;" /> <stop style="stop-color:#dfe1e1;stop-opacity:1;" offset="0.07692308" id="stop2346" /> <stop style="stop-color:#e2dcdc;stop-opacity:1;" offset="0.5" id="stop2342" /> <stop id="stop2348" offset="0.78201604" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop2344" offset="0.9005897" style="stop-color:#dfd9df;stop-opacity:1;" /> <stop id="stop2338" offset="1" style="stop-color:#3a3a3a;stop-opacity:1;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2334" id="linearGradient2766" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.577491,1.44816,-1.045249,0.603475,204.2967,164.9777)" x1="-52.71875" y1="182.0625" x2="-49.3125" y2="182.0625" /> <linearGradient id="linearGradient3916"> <stop id="stop3926" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop style="stop-color:#b9abb9;stop-opacity:1;" offset="0.3598901" id="stop3935" /> <stop id="stop3928" offset="0.71978021" style="stop-color:#dfd9df;stop-opacity:1;" /> <stop id="stop3930" offset="1" style="stop-color:#3a3a3a;stop-opacity:1;" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3916" id="radialGradient2770" gradientUnits="userSpaceOnUse" cx="-151.73438" cy="289.98047" fx="-151.62585" fy="290.38544" r="0.6328125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2897" id="linearGradient2772" gradientUnits="userSpaceOnUse" x1="-151.52597" y1="289.93997" x2="-151.82185" y2="290.10934" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3877" id="linearGradient2780" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.5,-0.866025,-0.866025,-0.5,175.1251,303.2683)" x1="-128.98389" y1="289.60529" x2="-129.63054" y2="280.78455" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3877" id="linearGradient2778" gradientUnits="userSpaceOnUse" x1="-135.90878" y1="273.1312" x2="-134.63533" y2="274.5062" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2783" id="linearGradient2776" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.192457,0.327601,0.333345,-0.189141,-161.4249,355.0328)" x1="-161.94588" y1="164.39458" x2="-115.94351" y2="160.49312" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2783" id="linearGradient2774" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.912724,0,0,0.424636,-6.403316,173.8027)" x1="190.03462" y1="90.22673" x2="208.77219" y2="90.22673" /> <linearGradient id="linearGradient2783"> <stop style="stop-color:#323232;stop-opacity:1;" offset="0" id="stop2785" /> <stop id="stop2787" offset="0.07692308" style="stop-color:#dfe1e1;stop-opacity:1;" /> <stop style="stop-color:#b6b1b1;stop-opacity:1;" offset="0.26289096" id="stop2799" /> <stop id="stop2789" offset="0.5" style="stop-color:#8d8282;stop-opacity:1;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.78201604" id="stop2791" /> <stop style="stop-color:#dfd9df;stop-opacity:1;" offset="0.9005897" id="stop2793" /> <stop style="stop-color:#3a3a3a;stop-opacity:1;" offset="1" id="stop2795" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2783" id="linearGradient2810" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.1823264,-0.1941654,0.18393,-0.1958484,-19.316228,101.23797)" x1="-162.56029" y1="167.36592" x2="-118.89805" y2="161.92447" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3877" id="linearGradient2807" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6605258,-0.1856532,0.1769887,0.692862,74.475044,-122.2594)" x1="-203.8418" y1="321.43585" x2="-120.47014" y2="273.30142" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3877" id="linearGradient2804" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.1769871,-0.6928637,-0.6605274,-0.1856515,243.78267,55.292842)" x1="-135.90878" y1="273.1312" x2="-134.63533" y2="274.5062" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3877" id="linearGradient2801" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6605258,-0.1856532,0.1769887,0.692862,74.372209,-122.35113)" x1="-119.93997" y1="274.45004" x2="-123.91203" y2="276.74332" /> <linearGradient id="linearGradient3877"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3879" /> <stop id="stop3943" offset="0.25824177" style="stop-color:#000000;stop-opacity:0.49458483;" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3881" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3877" id="linearGradient2798" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6605258,-0.1856532,0.1769887,0.692862,74.37566,-122.33087)" x1="-119.88942" y1="290.39322" x2="-133.02272" y2="277.25986" /> <linearGradient inkscape:collect="always" id="linearGradient2594"> <stop style="stop-color:#fafafa;stop-opacity:1;" offset="0" id="stop2596" /> <stop style="stop-color:#fafafa;stop-opacity:0;" offset="1" id="stop2598" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2594" id="linearGradient2795" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4835379,0.5072113,-0.4835395,0.5072096,224.75809,2.3325271)" x1="-113.99815" y1="261.99951" x2="-102.01393" y2="265.21066" /> <linearGradient id="XMLID_8_" gradientUnits="userSpaceOnUse" x1="72.0005" y1="96" x2="72.0005" y2="20.0005" gradientTransform="matrix(1.0033876,0,0,1,1.7561237,8)"> <stop offset="0" style="stop-color:#cfe7ff;stop-opacity:1;" id="stop35" /> <stop offset="0.5917" style="stop-color:#71A8F5" id="stop37" /> <stop offset="1" style="stop-color:#2C72C7" id="stop39" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="linearGradient2838" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0033876,0,0,1,-8.2438763,8)" x1="72.0005" y1="96" x2="72.0005" y2="20.0005" /> <filter inkscape:collect="always" x="-0.012357198" width="1.0247144" y="-0.41513768" height="1.8302754" id="filter2848"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.65388509" id="feGaussianBlur2850" /> </filter> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2844"> <path style="fill:#ff00bf" d="M 133.86613,100.978 C 133.79288,102.369 132.59585,103.5 131.19913,103.5 L 16.812952,103.5 C 15.415236,103.5 14.2192,102.368 14.145947,100.979 C 14.145947,100.979 10.508666,30.967 10.508666,30.957 C 10.461513,30.301 10.673223,29.685 11.105684,29.22 C 11.539144,28.756 12.140172,28.501 12.799403,28.501 L 135.21268,28.501 C 135.8719,28.501 136.47293,28.756 136.90339,29.219 C 137.33384,29.682 137.54254,30.298 137.49137,30.966 L 133.86613,100.978 z" id="path2846" /> </clipPath> <linearGradient id="linearGradient2822"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop2824" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop2826" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2822" id="linearGradient2828" x1="22.413761" y1="28.5" x2="22.413761" y2="34.472866" gradientUnits="userSpaceOnUse" gradientTransform="translate(10,0)" /> <linearGradient id="XMLID_9_" gradientUnits="userSpaceOnUse" x1="71.9995" y1="14.2578" x2="71.9995" y2="19.9583" gradientTransform="matrix(1.0033404,0,0,1,-8.2374684,8)"> <stop offset="0.25" style="stop-color:#71a8f5;stop-opacity:0;" id="stop46" /> <stop offset="1" style="stop-color:#0057ae;stop-opacity:1" id="stop48" /> </linearGradient> <linearGradient gradientTransform="matrix(1.0033808,0,0,1,-8.2378002,8)" y2="20.043535" x2="122.39215" y1="96.721588" x1="122.74438" gradientUnits="userSpaceOnUse" id="linearGradient3067"> <stop id="stop3069" style="stop-color:#0055f2;stop-opacity:1;" offset="0" /> <stop offset="0.13053299" style="stop-color:#5ca9ff;stop-opacity:1;" id="stop3077" /> <stop id="stop3071" style="stop-color:#106ced;stop-opacity:1;" offset="0.72006166" /> <stop id="stop3073" style="stop-color:#3462d3;stop-opacity:1;" offset="1" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3067" id="linearGradient3109" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0033808,0,0,1,-8.2378,8)" x1="122.74438" y1="96.721588" x2="122.74438" y2="20" /> <filter inkscape:collect="always" x="-0.0256" width="1.0512" y="-0.384" height="1.768" id="filter2807"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.28" id="feGaussianBlur2809" /> </filter> <linearGradient id="XMLID_6_" gradientUnits="userSpaceOnUse" x1="72.0005" y1="96" x2="72.0005" y2="4.882812e-04" gradientTransform="translate(-7.999995,8)"> <stop offset="0" style="stop-color:#001f81;stop-opacity:1" id="stop7" /> <stop offset="0.0769" style="stop-color:#2451a4;stop-opacity:1;" id="stop9" /> <stop offset="0.58579999" style="stop-color:#299ebe;stop-opacity:1;" id="stop11" /> <stop offset="0.96450001" style="stop-color:#8ba7e7;stop-opacity:1" id="stop13" /> </linearGradient> <linearGradient id="linearGradient3058"> <stop id="stop3060" offset="0" style="stop-color:#9a7600;stop-opacity:1;" /> <stop style="stop-color:#e3ad00;stop-opacity:1;" offset="0.09292036" id="stop3066" /> <stop id="stop3070" offset="0.5043171" style="stop-color:#ffcd2c;stop-opacity:1;" /> <stop id="stop3068" offset="0.91571385" style="stop-color:#e3ad00;stop-opacity:1;" /> <stop id="stop3113" offset="1" style="stop-color:#b98d00;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient4309"> <stop style="stop-color:#fff727;stop-opacity:0.73333335;" offset="0" id="stop4311" /> <stop style="stop-color:#ffb266;stop-opacity:0;" offset="1" id="stop4313" /> </linearGradient> <linearGradient id="linearGradient4318"> <stop id="stop4320" offset="0" style="stop-color:#fffaa8;stop-opacity:1;" /> <stop id="stop4322" offset="1" style="stop-color:white;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient2019"> <stop id="stop2912" offset="0" style="stop-color:#fff823;stop-opacity:0.84313726;" /> <stop style="stop-color:#ffff02;stop-opacity:0;" offset="1" id="stop2023" /> </linearGradient> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective2925" /> <linearGradient inkscape:collect="always" id="linearGradient2897"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2899" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2901" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2884"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2886" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2888" /> </linearGradient> <linearGradient id="linearGradient3054"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3056" /> <stop id="stop3062" offset="0.5714286" style="stop-color:black;stop-opacity:1;" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3058" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3040"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3042" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3044" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3027"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3029" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3031" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3012"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3014" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3016" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2999"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3001" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3003" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2981"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2983" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2985" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2947"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2949" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2951" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2929"> <stop style="stop-color:#bdbdbd;stop-opacity:1;" offset="0" id="stop2931" /> <stop style="stop-color:#bdbdbd;stop-opacity:0;" offset="1" id="stop2933" /> </linearGradient> <linearGradient id="linearGradient2903"> <stop style="stop-color:white;stop-opacity:0.53790611;" offset="0" id="stop2905" /> <stop id="stop2911" offset="0.21464799" style="stop-color:white;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:0.41516244;" offset="0.66342056" id="stop2913" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop2907" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3291"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3293" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3295" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3291" id="radialGradient3297" cx="63.912209" cy="115.70919" fx="63.912209" fy="115.7093" r="63.912209" gradientTransform="matrix(1,0,0,0.197802,0,92.82166)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3054" id="radialGradient3060" cx="63.816387" cy="120.57538" fx="63.816387" fy="120.57538" r="14.672465" gradientTransform="matrix(1,0,0,0.289157,0,85.71021)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient2256" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient2258" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871796,19.248866,2.1082206)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2260" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2262" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.1392194,15.358897,56.83334)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2264" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.5047306,-0.9375819,1.2433202,3.3256839,-79.061389,-69.19504)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2266" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.1392194,15.358897,56.83334)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2268" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.5047306,-0.9375819,1.2433202,3.3256839,-79.061389,-69.19504)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2270" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.556928,-2.91845e-8,0,0.138799,37.13478,97.17706)" cx="57.214077" cy="124.00706" fx="49.233025" fy="124.00705" r="11.383312" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2272" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.2437132,15.358897,49.893028)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2274" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.396982,-6.091903e-3,2.173148e-3,-0.138782,90.77277,126.4457)" cx="76.055191" cy="102.52346" fx="70.111389" fy="106.1347" r="11.383312" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2276" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2999" id="linearGradient2278" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="48.326965" y1="241.35539" x2="60.750298" y2="67.1054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient2280" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient2282" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient2284" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8601654,0,0,0.9472313,14.250514,3.8818714)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient2287" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9384891,0,0,0.9797769,5.3602634,-0.1102297)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient2290" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,0.6237166,10.813747,4.9721139)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient2293" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8332988,-4.0741942e-2,4.3563196e-2,0.8910022,10.908193,1.2960712)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2999" id="linearGradient2297" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="48.326965" y1="241.35539" x2="60.750298" y2="67.1054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2300" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2304" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.2520869,6.5695719,47.48181)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2308" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6417463,-0.8079979,1.3565327,2.8660381,-96.448304,-52.309632)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2312" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.1440028,6.5695719,54.660582)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2315" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6417463,-0.8125119,1.3565327,2.88205,-96.448304,-52.949828)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.1440028,6.5695719,54.660582)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2321" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient2325" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210978,10.813748,-1.9448209)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient2328" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,0.8975001,10.813747,5.9409483)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2330" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.396982,-6.091903e-3,2.173148e-3,-0.138782,90.77277,126.4457)" cx="76.055191" cy="102.52346" fx="70.111389" fy="106.1347" r="11.383312" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2332" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.556928,-2.91845e-8,0,0.138799,37.13478,97.17706)" cx="57.214077" cy="124.00706" fx="49.233025" fy="124.00705" r="11.383312" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient4071" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9273531,0,0,0.9032318,165.67959,-7.0869034)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient4074" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.5749887,171.06836,-2.4016179)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient4077" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.823411,-3.7558978e-2,4.3046279e-2,0.8213927,171.16169,-5.7904698)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient4081" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413255,171.06836,-8.7781679)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4084" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.2323926,166.87455,36.787008)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient4088" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6222655,-0.7448731,1.3404362,2.6421289,65.079072,-55.208227)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4092" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.1327526,166.87455,43.404939)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient4095" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6222655,-0.7490344,1.3404362,2.6568898,65.079072,-55.798408)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4098" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.1327526,166.87455,43.404939)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient4101" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413255,171.06836,-8.7781679)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient4105" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413245,171.06836,-8.7781672)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient4108" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.8273829,171.06836,-1.5084737)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient4132" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.8273829,171.06836,-1.5084737)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient4134" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413245,171.06836,-8.7781672)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient4136" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413255,171.06836,-8.7781679)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4138" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.1327526,166.87455,43.404939)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient4140" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6222655,-0.7490344,1.3404362,2.6568898,65.079072,-55.798408)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4142" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.1327526,166.87455,43.404939)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient4144" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6222655,-0.7448731,1.3404362,2.6421289,65.079072,-55.208227)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient4146" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.556928,-2.91845e-8,0,0.138799,37.13478,97.17706)" cx="57.214077" cy="124.00706" fx="49.233025" fy="124.00705" r="11.383312" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient4148" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8914271,0,0,0.2323926,166.87455,36.787008)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient4150" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.9413255,171.06836,-8.7781679)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient4152" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.823411,-3.7558978e-2,4.3046279e-2,0.8213927,171.16169,-5.7904698)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient4154" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8243945,0,0,0.5749887,171.06836,-2.4016179)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient4156" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9273531,0,0,0.9032318,165.67959,-7.0869034)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="linearGradient2814" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8310903,0,0,0.8282844,-25.699307,-5.5875846)" x1="72.0005" y1="96" x2="72.0005" y2="20.0005" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8284271" inkscape:cx="90.481778" inkscape:cy="71.874365" inkscape:current-layer="layer1" showgrid="true" inkscape:document-units="px" inkscape:grid-bbox="true" guidetolerance="0.1px" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33"> <inkscape:grid id="GridFromPre046Settings" type="xygrid" originx="0px" originy="0px" spacingx="8px" spacingy="8px" color="#0000ff" empcolor="#0000ff" opacity="0.2" empopacity="0.4" empspacing="0" visible="true" enabled="true" /> </sodipodi:namedview> <metadata id="metadata1312"> <rdf:RDF> <ns:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <ns:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:contributor> <ns:Agent> <dc:title>Oxygen team</dc:title> </ns:Agent> </dc:contributor> </ns:Work> <ns:License rdf:about="http://creativecommons.org/licenses/LGPL/2.1/"> <ns:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <ns:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <ns:requires rdf:resource="http://web.resource.org/cc/Notice" /> <ns:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <ns:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <ns:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </ns:License> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer" transform="translate(-2.8572,5.1129792e-5)"> <g id="g3892" transform="matrix(0.875046,0,0,0.6510063,12.136849,55.245709)"> <path style="fill:url(#XMLID_6_)" id="path15" d="M 117.983,19 C 117.992,17.35 116.64999,16 114.99999,16 L 44.961007,16 L 38.375006,9.414 C 37.597005,8.636 36.061006,8 34.961,8 L 13.999998,8 C 11.799996,8 9.999999,9.8 9.999999,12 L 9.999999,19 C 9.999999,19 10.999999,104 7,104 L 121,104 C 116.99999,104 117.983,19 117.983,19 z" /> <g transform="matrix(1.0033404,0,0,1,-8.2374684,8)" style="opacity:0.6;filter:url(#filter2807)" id="g17"> <path id="path19" d="M 132,96 C 132,98.2 128.4,100 124,100 L 20,100 C 15.6,100 12,98.2 12,96 C 12,93.8 15.6,92 20,92 L 124,92 C 128.4,92 132,93.8 132,96 z" /> </g> <path style="opacity:0.9;fill:url(#linearGradient3109);fill-opacity:1" id="path30" d="M 124.36598,101.004 C 124.27969,102.652 122.85389,104 121.19831,104 L 6.812906,104 C 5.157329,104 3.731522,102.652 3.644228,101.004 L 0.007982,30.992 C -0.112423,29.347 1.143808,28 2.799384,28 L 125.21183,28 C 126.86741,28 128.11762,29.346 127.9912,30.991 L 124.36598,101.004 z" /> <path style="fill:#5293ee;fill-opacity:1" id="path32" d="M 10.580094,28 C 10.551086,23.609 10.516087,20.392 10.500078,19 L 10.500078,12 C 10.500078,10.07 12.07033,8.5 14.000627,8.5 L 34.964921,8.5 C 35.937077,8.5 37.339294,9.081 38.026407,9.768 L 44.759457,16.5 L 115.01648,16.5 C 115.68059,16.5 116.30469,16.76 116.77576,17.233 C 117.24683,17.706 117.50487,18.333 117.50087,18.997 C 117.50087,18.997 117.57288,18.925 117.60989,18.888 C 117.48787,19.495 117.47487,21.062 117.44687,25.161 L 117.43687,28 L 117.92894,28 C 117.95994,22.468 117.99995,19 117.99995,19 C 118.00896,17.35 116.66674,16 115.01648,16 L 44.966498,16 L 38.379463,9.414 C 37.60134,8.636 36.065099,8 34.964921,8 L 14.000627,8 C 11.80028,8 10,9.8 10,12 L 10,19 C 10,19 10.041009,22.468 10.073018,28 L 10.580094,28 z" /> <path style="opacity:0.5;fill:url(#XMLID_9_)" id="path50" d="M 9.8848616,22 C 9.8938916,23.75 9.9029216,25.755 9.9109516,28 L 118.09511,28 C 118.10414,25.755 118.11317,23.75 118.1212,22 L 9.8848616,22 z" /> <path transform="translate(-10,0)" clip-path="url(#clipPath2844)" id="path2788" d="M 12.8125,28.5 C 12.153269,28.5 11.52721,28.754751 11.09375,29.21875 C 10.661289,29.68375 10.452847,30.312749 10.5,30.96875 C 10.5,30.968937 10.559992,32.232788 10.5625,32.28125 C 10.647737,31.886257 10.815287,31.518165 11.09375,31.21875 C 11.52721,30.754751 12.153269,30.5 12.8125,30.5 L 135.21875,30.5 C 135.87797,30.500001 136.47579,30.75575 136.90625,31.21875 C 137.18342,31.516877 137.35439,31.883216 137.4375,32.28125 L 137.5,30.96875 C 137.55117,30.30075 137.3367,29.68175 136.90625,29.21875 C 136.47579,28.75575 135.87797,28.500001 135.21875,28.5 L 12.8125,28.5 z" style="fill:url(#linearGradient2828);fill-opacity:1;filter:url(#filter2848)" /> <path d="M 125.21268,28 L 2.799403,28 C 1.143815,28 -0.1124237,29.347 0.007982,30.992 L 3.645263,101.004 C 3.731547,102.652 5.157364,104 6.812952,104 L 121.19913,104 C 122.85472,104 124.28053,102.652 124.36682,101.004 L 127.99106,30.991 C 128.11849,29.346 126.86827,28 125.21268,28 z M 123.86613,100.978 C 123.79288,102.369 122.59585,103.5 121.19913,103.5 L 6.812952,103.5 C 5.415236,103.5 4.2192,102.368 4.145947,100.979 C 4.145947,100.979 0.508666,30.967 0.508666,30.957 C 0.461513,30.301 0.673223,29.685 1.105684,29.22 C 1.539144,28.756 2.140172,28.501 2.799403,28.501 L 125.21268,28.501 C 125.8719,28.501 126.47293,28.756 126.90339,29.219 C 127.33384,29.682 127.54254,30.298 127.49137,30.966 L 123.86613,100.978 z" id="path2836" style="fill:url(#linearGradient2838)" /> </g> <path sodipodi:nodetypes="ccc" id="path3117" d="M -109.74325,70.909467 L -109.74325,68.114759 L -109.74325,70.909467 z" style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect ry="1.3016655" y="-13.310369" x="-97.78054" height="47.046753" width="11.457333" id="rect3812" style="fill:url(#linearGradient2853);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" rx="1.3016655" transform="matrix(-0.6900151,-0.723795,-0.6900151,0.723795,0,0)" /> <rect style="fill:url(#linearGradient2850);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect2810" width="10.47196" height="43.000557" x="-97.202515" y="-79.053535" ry="1.3016655" rx="1.3016655" transform="matrix(-0.6900151,-0.723795,-0.6900151,0.723795,0,0)" /> <rect rx="1.3016655" style="fill:url(#linearGradient2847);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect1709" width="11.457333" height="47.046753" x="-97.78054" y="-13.310369" ry="1.3016655" transform="matrix(-0.6900151,-0.723795,-0.6900151,0.723795,0,0)" /> <rect y="-72.074402" x="-98.242996" height="94.343567" width="12.552909" id="rect2803" style="fill:url(#linearGradient2844);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" transform="matrix(-0.6900151,-0.723795,-0.6900151,0.723795,0,0)" /> <rect style="fill:url(#linearGradient2841);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect2814" width="10.095819" height="5.7921371" x="-96.922829" y="-77.863937" transform="matrix(-0.6900151,-0.723795,-0.6900151,0.723795,0,0)" /> <rect ry="1.3016655" y="-79.053535" x="-97.202515" height="2.3453741" width="10.47196" id="rect2848" style="fill:url(#linearGradient2814);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" rx="1.3016655" transform="matrix(-0.6900151,-0.723795,-0.6900151,0.723795,0,0)" /> <rect style="opacity:0.25819672;fill:url(#linearGradient2835);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect3733" width="12.552909" height="1.3034983" x="-98.242996" y="-72.074402" transform="matrix(-0.6900151,-0.723795,-0.6900151,0.723795,0,0)" /> <rect style="fill:url(#linearGradient2832);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect3967" width="12.157243" height="76.821854" x="-97.920517" y="-54.553318" transform="matrix(-0.6900151,-0.723795,-0.6900151,0.723795,0,0)" /> <rect style="fill:url(#linearGradient2826);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect2824" width="3.4818461" height="46.486431" x="85.516884" y="-78.455139" transform="matrix(0.5873912,0.8093032,-0.6984414,0.7156673,0,0)" /> <rect style="opacity:0.7786885;fill:url(#linearGradient2823);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect2892" width="4.6388941" height="1.1884769" x="-66.148415" y="87.052299" transform="matrix(-0.6900151,0.723795,0.6900151,0.723795,0,0)" /> <g id="g3828" transform="matrix(0.6605274,-0.1856515,0.1769871,0.6928637,64.329455,-111.7311)"> <path sodipodi:nodetypes="ccccsssssssssssssccssssssssssssssssssssscccccccssssssssssssssc" id="rect2826" d="M 13.86477,181.00757 L -45.518463,215.2925 L -45.499604,215.32517 L -45.728253,215.45717 C -45.74088,215.46446 -45.775242,215.48461 -45.793581,215.49489 C -45.801915,215.49981 -45.820246,215.50969 -45.826245,215.51375 C -45.83742,215.52044 -45.877496,215.54416 -45.891574,215.55147 C -45.895763,215.5539 -45.920635,215.56795 -45.924237,215.57032 C -45.946175,215.59282 -45.985519,215.64187 -46.003371,215.65957 C -46.010014,215.66646 -46.029521,215.67136 -46.036035,215.67843 C -46.182957,215.84486 -46.313983,216.09024 -46.370074,216.3068 C -46.383426,216.36341 -46.387395,216.43757 -46.392632,216.49404 C -46.391728,216.50864 -46.388684,216.56361 -46.387578,216.57822 C -46.386352,216.60014 -46.383087,216.64827 -46.382526,216.66241 C -46.381339,216.68121 -46.379519,216.72786 -46.377472,216.74659 C -46.376813,216.76123 -46.373296,216.81617 -46.372419,216.83078 C -46.366715,216.8585 -46.356234,216.92032 -46.348507,216.94763 C -46.341928,216.95879 -46.3176,217.00186 -46.31079,217.01297 L -45.175212,219.88505 C -45.169793,219.90337 -45.174474,219.94909 -45.170159,219.96923 C -45.168722,219.97596 -45.152871,219.99534 -45.1513,220.00191 C -45.149459,220.00811 -45.134678,220.02888 -45.132442,220.03457 C -45.129004,220.0404 -45.118096,220.06111 -45.113583,220.06723 C -45.092389,220.09245 -45.046964,220.12283 -45.024344,220.14637 C -45.019304,220.15186 -45.009636,220.17404 -45.005485,220.17903 C -44.999214,220.19059 -44.974179,220.23299 -44.967768,220.24436 C -44.955412,220.25246 -44.909867,220.28292 -44.897387,220.29083 C -44.895831,220.29373 -44.880066,220.32006 -44.878528,220.32349 C -44.865096,220.33329 -44.82203,220.36097 -44.808146,220.36995 C -44.798942,220.37231 -44.765855,220.38147 -44.756624,220.38376 C -44.73849,220.39345 -44.707381,220.41935 -44.686243,220.43023 C -44.68104,220.43263 -44.639764,220.44191 -44.634721,220.44404 C -44.626942,220.44666 -44.591047,220.45545 -44.583197,220.45784 C -44.575277,220.46003 -44.539665,220.46968 -44.531675,220.47165 C -44.523618,220.47339 -44.488266,220.48393 -44.480153,220.48546 C -44.471007,220.48799 -44.437785,220.49678 -44.428629,220.49927 C -44.414454,220.49847 -44.358716,220.49551 -44.344443,220.49421 C -44.327552,220.49411 -44.277271,220.49018 -44.260256,220.48915 C -44.247461,220.48804 -44.198153,220.48552 -44.17607,220.48411 C -44.134554,220.4748 -44.064223,220.45287 -44.026554,220.44133 C -44.019197,220.44112 -43.98341,220.45498 -43.975032,220.45514 L -43.844376,220.37971 C -43.835918,220.3751 -43.820137,220.36571 -43.811713,220.36084 L -42.897118,219.8328 L 16.260393,185.92505 L 13.86477,181.00757 z M -37.285044,213.10851 C -37.28253,213.1134 -37.301264,213.15428 -37.298851,213.16003 C -37.291882,213.17891 -37.267389,213.20738 -37.261133,213.22535 C -37.247256,213.26016 -37.226337,213.33748 -37.218363,213.37487 C -37.20701,213.4465 -37.194819,213.54772 -37.203203,213.62744 C -37.313083,214.39618 -38.286454,215.51585 -39.628733,216.29082 C -40.971019,217.0658 -42.286954,217.26785 -42.854083,216.88997 C -42.911006,216.84795 -42.993229,216.78718 -43.032562,216.7317 C -43.04967,216.69712 -43.063187,216.61263 -43.075333,216.58218 C -43.097444,216.50024 -43.112337,216.38113 -43.109351,216.29697 C -43.048828,215.52837 -42.084207,214.39853 -40.70268,213.60091 C -39.407502,212.85314 -38.108986,212.61476 -37.515047,212.93643 C -37.486469,212.95346 -37.450942,212.99569 -37.425807,213.01557 C -37.410572,213.02728 -37.371746,213.05041 -37.355426,213.06204 C -37.350216,213.06606 -37.341388,213.09045 -37.336568,213.0947 C -37.334617,213.09707 -37.28679,213.10605 -37.285044,213.10851 z " style="opacity:1;fill:url(#linearGradient2766);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccsssssssssssssccssssssssssssssssssssscccccc" style="opacity:1;fill:url(#linearGradient2768);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M -45.714448,215.40565 L -45.518463,215.2925 L -45.499604,215.32517 L -45.728253,215.45717 C -45.74088,215.46446 -45.775242,215.48461 -45.793581,215.49489 C -45.801915,215.49981 -45.820246,215.50969 -45.826245,215.51375 C -45.83742,215.52044 -45.877496,215.54416 -45.891574,215.55147 C -45.895763,215.5539 -45.920635,215.56795 -45.924237,215.57032 C -45.946175,215.59282 -45.985519,215.64187 -46.003371,215.65957 C -46.010014,215.66646 -46.029521,215.67136 -46.036035,215.67843 C -46.182957,215.84486 -46.313983,216.09024 -46.370074,216.3068 C -46.383426,216.36341 -46.387395,216.43757 -46.392632,216.49404 C -46.391728,216.50864 -46.388684,216.56361 -46.387578,216.57822 C -46.386352,216.60014 -46.383087,216.64827 -46.382526,216.66241 C -46.381339,216.68121 -46.379519,216.72786 -46.377472,216.74659 C -46.376813,216.76123 -46.373296,216.81617 -46.372419,216.83078 C -46.366715,216.8585 -46.356234,216.92032 -46.348507,216.94763 C -46.341928,216.95879 -46.3176,217.00186 -46.31079,217.01297 L -45.175212,219.88505 C -45.169793,219.90337 -45.174474,219.94909 -45.170159,219.96923 C -45.168722,219.97596 -45.152871,219.99534 -45.1513,220.00191 C -45.149459,220.00811 -45.134678,220.02888 -45.132442,220.03457 C -45.129004,220.0404 -45.118096,220.06111 -45.113583,220.06723 C -45.092389,220.09245 -45.046964,220.12283 -45.024344,220.14637 C -45.019304,220.15186 -45.009636,220.17404 -45.005485,220.17903 C -44.999214,220.19059 -44.974179,220.23299 -44.967768,220.24436 C -44.955412,220.25246 -44.909867,220.28292 -44.897387,220.29083 C -44.895831,220.29373 -44.880066,220.32006 -44.878528,220.32349 C -44.865096,220.33329 -44.82203,220.36097 -44.808146,220.36995 C -44.798942,220.37231 -44.765855,220.38147 -44.756624,220.38376 C -44.73849,220.39345 -44.707381,220.41935 -44.686243,220.43023 C -44.68104,220.43263 -44.639764,220.44191 -44.634721,220.44404 C -44.626942,220.44666 -44.591047,220.45545 -44.583197,220.45784 C -44.575277,220.46003 -44.539665,220.46968 -44.531675,220.47165 C -44.523618,220.47339 -44.488266,220.48393 -44.480153,220.48546 C -44.471007,220.48799 -44.437785,220.49678 -44.428629,220.49927 C -44.414454,220.49847 -44.358716,220.49551 -44.344443,220.49421 C -44.327552,220.49411 -44.277271,220.49018 -44.260256,220.48915 C -44.247461,220.48804 -44.198153,220.48552 -44.17607,220.48411 C -44.134554,220.4748 -44.064223,220.45287 -44.026554,220.44133 C -44.019197,220.44112 -43.98341,220.45498 -43.975032,220.45514 L -43.844376,220.37971 C -43.835918,220.3751 -43.820137,220.36571 -43.811713,220.36084 L -42.897118,219.8328 L -43.746384,220.32312 L -45.714448,215.40565 z " id="path3792" /> </g> <path sodipodi:type="arc" style="fill:url(#radialGradient2770);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path3897" sodipodi:cx="-151.73438" sodipodi:cy="289.98047" sodipodi:rx="0.6328125" sodipodi:ry="0.6328125" d="M -151.10156 289.98047 A 0.6328125 0.6328125 0 1 1 -152.36719,289.98047 A 0.6328125 0.6328125 0 1 1 -151.10156 289.98047 z" transform="matrix(0.1899314,-0.7435378,-0.7088365,-0.1992295,259.07832,52.465152)" /> <path transform="matrix(0.1899314,-0.7435378,-0.7088365,-0.1992295,259.07832,52.465152)" d="M -151.10156 289.98047 A 0.6328125 0.6328125 0 1 1 -152.36719,289.98047 A 0.6328125 0.6328125 0 1 1 -151.10156 289.98047 z" sodipodi:ry="0.6328125" sodipodi:rx="0.6328125" sodipodi:cy="289.98047" sodipodi:cx="-151.73438" id="path2902" style="fill:url(#linearGradient2772);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" sodipodi:type="arc" /> <g id="g3953" transform="matrix(5.1487099e-2,-0.2015594,-0.1921525,-5.4007661e-2,87.017231,93.815456)"> <rect ry="1.8574883" y="178.54808" x="167.04588" height="67.136131" width="16.349716" id="rect3945" style="opacity:1;fill:url(#linearGradient2774);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" rx="1.8574883" transform="matrix(0.5,0.866025,-0.866025,0.5,0,0)" /> <path style="opacity:1;fill:url(#linearGradient2776);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M -145.78378,283.42273 C -138.59591,276.69175 -128.85355,267.63505 -127.93118,266.7728 C -127.93073,266.77307 -119.8818,280.91965 -119.88534,280.92067 C -121.09278,281.27218 -133.74319,284.97064 -143.24776,287.73956 L -145.78378,283.42273 z " id="path3947" sodipodi:nodetypes="csscc" /> <path sodipodi:nodetypes="csscc" id="path3949" d="M -145.78378,283.42273 C -138.59591,276.69175 -128.85355,267.63505 -127.93118,266.7728 C -127.93073,266.77307 -123.81603,278.06285 -123.81957,278.06387 C -125.02701,278.41538 -133.74319,284.97064 -143.24776,287.73956 L -145.78378,283.42273 z " style="opacity:1;fill:url(#linearGradient2778);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path style="opacity:1;fill:url(#linearGradient2780);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M -143.23729,287.75259 C -133.81415,284.8932 -122.67207,279.75187 -123.15491,278.5852 L -128.10201,266.63168 L -145.7849,283.42888 L -143.23729,287.75259 z " id="path3951" sodipodi:nodetypes="csccc" /> </g> <path style="fill:url(#linearGradient2810);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 30.752337,103.69534 C 36.470495,99.964746 44.176951,94.896016 44.909738,94.417016 C 44.909641,94.416646 36.990001,86.213513 36.988695,86.215775 C 36.542811,86.987105 31.860927,95.065486 28.349792,101.1368 L 30.752337,103.69534 z " id="path3836" sodipodi:nodetypes="csscc" /> <path sodipodi:nodetypes="ccccc" id="path1701" d="M 28.343562,101.17882 L 37.009216,86.313881 L 44.997613,94.467226 L 30.782691,103.69897 L 28.343562,101.17882 z " style="opacity:0.72540989;fill:url(#linearGradient2807);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path sodipodi:nodetypes="csscc" id="path3875" d="M 30.772573,103.68323 C 36.490732,99.952626 44.197185,94.883896 44.929972,94.404906 C 44.929875,94.404536 37.010238,86.201397 37.008932,86.203655 C 36.563048,86.974993 31.881163,95.053376 28.370032,101.12469 L 30.772573,103.68323 z " style="fill:url(#linearGradient2804);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path style="opacity:0.72540989;fill:url(#linearGradient2801);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 28.240712,101.08706 L 36.906371,86.222126 L 44.894768,94.375466 L 30.679846,103.60721 L 28.240712,101.08706 z " id="path1705" sodipodi:nodetypes="ccccc" /> <path style="opacity:0.72540989;fill:url(#linearGradient2798);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 28.317522,100.90222 L 37.007626,86.293719 L 44.881501,94.388646 L 30.732211,103.65317 L 28.317522,100.90222 z " id="path3937" sodipodi:nodetypes="ccccc" /> <path style="opacity:0.7786885;fill:url(#linearGradient2795);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" d="M 44.220828,78.836582 L 48.947097,87.871088 L 45.008627,94.356136 L 37.2171,86.18316 L 44.220828,78.836582 z " id="rect2592" sodipodi:nodetypes="ccccc" /> <rect style="opacity:0.52459011;fill:#e0e0e0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.80000019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect1851" width="21.856394" height="12.58142" x="-6.602591" y="85.630295" transform="matrix(-0.6900151,0.723795,0.6900151,0.723795,0,0)" /> </g> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/arrow-right-double.svg�����������������������������������������������0000644�0001750�0000144�00000123466�10737543467�021012� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/david" sodipodi:docname="arrow-right-double.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" inkscape:export-filename="arrow-left-double.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> <defs id="defs4"> <linearGradient inkscape:collect="always" id="linearGradient4167"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop4169" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop4171" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient4150"> <stop style="stop-color:#bfffbf;stop-opacity:1;" offset="0" id="stop4152" /> <stop style="stop-color:#bfffbf;stop-opacity:0;" offset="1" id="stop4154" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3409"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3411" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3413" /> </linearGradient> <linearGradient id="linearGradient3362" inkscape:collect="always"> <stop id="stop3364" offset="0" style="stop-color:#bfffbf;stop-opacity:1" /> <stop id="stop3366" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient id="linearGradient3355" inkscape:collect="always"> <stop id="stop3357" offset="0" style="stop-color:#e0ffe0;stop-opacity:1" /> <stop id="stop3359" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient id="linearGradient3349" inkscape:collect="always"> <stop id="stop3351" offset="0" style="stop-color:#00dd00;stop-opacity:1" /> <stop id="stop3353" offset="1" style="stop-color:#000e00;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3342"> <stop style="stop-color:#00ff00;stop-opacity:1" offset="0" id="stop3344" /> <stop style="stop-color:#004d00;stop-opacity:1" offset="1" id="stop3346" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3710"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3712" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3714" /> </linearGradient> <linearGradient id="linearGradient3689" inkscape:collect="always"> <stop id="stop3691" offset="0" style="stop-color:#f0ff80;stop-opacity:1" /> <stop id="stop3693" offset="1" style="stop-color:#f0ff80;stop-opacity:0" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3669"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3671" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3673" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3511"> <stop style="stop-color:#002a0d;stop-opacity:1;" offset="0" id="stop3513" /> <stop style="stop-color:#002a0d;stop-opacity:0;" offset="1" id="stop3515" /> </linearGradient> <radialGradient id="radialGradient2854" cx="538.77338" cy="651.10352" r="126.0234" gradientTransform="translate(-484,-674)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#cbcbcb;stop-opacity:1;" id="stop2856" /> <stop offset="0.53930002" style="stop-color:#282828;stop-opacity:1;" id="stop2858" /> <stop offset="1" style="stop-color:#9d9d9d;stop-opacity:1;" id="stop2860" /> </radialGradient> <linearGradient id="linearGradient2862" gradientUnits="userSpaceOnUse" x1="538.77338" y1="677.87701" x2="538.77338" y2="789.12207" gradientTransform="translate(-484,-674)"> <stop offset="0.0056" style="stop-color:#4d4d4d;stop-opacity:1;" id="stop2864" /> <stop offset="0.1348" style="stop-color:#676767;stop-opacity:1;" id="stop2866" /> <stop offset="0.4831" style="stop-color:#b2b2b2;stop-opacity:1;" id="stop2868" /> <stop offset="0.62989998" style="stop-color:#aaa;stop-opacity:1;" id="stop2870" /> <stop offset="0.85280001" style="stop-color:#a1a1a1;stop-opacity:1;" id="stop2872" /> <stop offset="1" style="stop-color:#9d9d9d;stop-opacity:1;" id="stop2874" /> </linearGradient> <radialGradient id="radialGradient2876" cx="538.77252" cy="792.99609" r="121.5466" gradientTransform="translate(-484,-674)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#d9d9d9;stop-opacity:1;" id="stop2878" /> <stop offset="0.0494" style="stop-color:#c7c7c7;stop-opacity:1;" id="stop2880" /> <stop offset="0.1049" style="stop-color:#b9b9b9;stop-opacity:1;" id="stop2882" /> <stop offset="0.14321923" style="stop-color:#aeaeae;stop-opacity:1;" id="stop2884" /> <stop offset="0.2156" style="stop-color:#a9a9a9;stop-opacity:1;" id="stop2886" /> <stop offset="0.26969999" style="stop-color:#a6a6a6;stop-opacity:1;" id="stop2888" /> <stop offset="0.3989" style="stop-color:#676767;stop-opacity:1;" id="stop2890" /> <stop offset="0.39950001" style="stop-color:#676767;stop-opacity:1;" id="stop2892" /> <stop offset="0.44839999" style="stop-color:#545454;stop-opacity:1;" id="stop2894" /> <stop offset="0.49559999" style="stop-color:#414141;stop-opacity:1;" id="stop2896" /> <stop offset="0.53988957" style="stop-color:#353535;stop-opacity:1;" id="stop2898" /> <stop offset="0.57096523" style="stop-color:#313131;stop-opacity:1;" id="stop2900" /> <stop offset="0.5948" style="stop-color:#3e3e3e;stop-opacity:1;" id="stop2902" /> <stop offset="0.64560002" style="stop-color:#5f5f5f;stop-opacity:1;" id="stop2904" /> <stop offset="0.69319999" style="stop-color:#707070;stop-opacity:1;" id="stop2906" /> <stop offset="0.73589998" style="stop-color:#7b7b7b;stop-opacity:1;" id="stop2908" /> <stop offset="0.76969999" style="stop-color:#7f7f7f;stop-opacity:1;" id="stop2910" /> <stop offset="1" style="stop-color:#313131;stop-opacity:1;" id="stop2912" /> </radialGradient> <linearGradient id="linearGradient2914" gradientUnits="userSpaceOnUse" x1="538.77338" y1="793" x2="538.77338" y2="674" gradientTransform="translate(-484,-674)"> <stop offset="0" style="stop-color:#262626;stop-opacity:1;" id="stop2916" /> <stop offset="0.1124" style="stop-color:#313131;stop-opacity:1;" id="stop2918" /> <stop offset="0.37450001" style="stop-color:#4d4d4d;stop-opacity:1;" id="stop2920" /> <stop offset="0.42309999" style="stop-color:#505050;stop-opacity:1;" id="stop2922" /> <stop offset="0.43689999" style="stop-color:#575757;stop-opacity:1;" id="stop2924" /> <stop offset="0.44909999" style="stop-color:#646464;stop-opacity:1;" id="stop2926" /> <stop offset="0.4605" style="stop-color:#757575;stop-opacity:1;" id="stop2928" /> <stop offset="0.47119999" style="stop-color:#8a8a8a;stop-opacity:1;" id="stop2930" /> <stop offset="0.48140001" style="stop-color:#a3a3a3;stop-opacity:1;" id="stop2932" /> <stop offset="0.49110001" style="stop-color:silver;stop-opacity:1;" id="stop2934" /> <stop offset="0.49439999" style="stop-color:#dfdfdf;stop-opacity:1;" id="stop2936" /> <stop offset="0.51748788" style="stop-color:#afafaf;stop-opacity:1;" id="stop2938" /> <stop offset="0.53259999" style="stop-color:#949494;stop-opacity:1;" id="stop2940" /> <stop offset="0.55519998" style="stop-color:#7c7c7c;stop-opacity:1;" id="stop2942" /> <stop offset="0.58454067" style="stop-color:#656565;stop-opacity:1;" id="stop2944" /> <stop offset="0.60860002" style="stop-color:#525252;stop-opacity:1;" id="stop2946" /> <stop offset="0.64160001" style="stop-color:#434343;stop-opacity:1;" id="stop2948" /> <stop offset="0.69285822" style="stop-color:#393939;stop-opacity:1;" id="stop2951" /> <stop offset="0.73979998" style="stop-color:#333;stop-opacity:1;" id="stop2953" /> <stop offset="0.89889997" style="stop-color:#313131;stop-opacity:1;" id="stop2955" /> <stop offset="1" style="stop-color:#a6a8a4;stop-opacity:1;" id="stop2957" /> </linearGradient> <radialGradient cx="265.3931" cy="-6078.353" r="253.01871" fx="369.5242" fy="-6078.353" id="path2295_1_" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.183616,0,0,-1.462967e-2,-0.962917,-7.25873)"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop8" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop10" /> <a:midPointStop style="stop-color:#000000" offset="0" /> <a:midPointStop style="stop-color:#000000" offset="0.5" /> <a:midPointStop style="stop-color:#FFFFFF" offset="1" /> </radialGradient> <filter inkscape:collect="always" x="-0.12239107" width="1.2447821" y="-0.078971461" height="1.1579429" id="filter3681"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.321914" id="feGaussianBlur3683" /> </filter> <filter inkscape:collect="always" x="-0.45196507" width="1.9039301" y="-0.29913295" height="1.5982659" id="filter3722"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.3476562" id="feGaussianBlur3724" /> </filter> <filter inkscape:collect="always" id="filter3435"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.395" id="feGaussianBlur3437" /> </filter> <filter inkscape:collect="always" id="filter3467"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.4349886" id="feGaussianBlur3469" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4009" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4011" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,-6.690938,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4013" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient4015" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4017" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-54.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4021" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4023" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4025" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4027" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4029" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4031" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,-6.690938,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4033" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient4035" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4037" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4039" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-54.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4041" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4043" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4045" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4047" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4068" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4071" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4074" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4077" gradientUnits="userSpaceOnUse" gradientTransform="translate(-16,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4080" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-46.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4085" gradientUnits="userSpaceOnUse" gradientTransform="translate(-16,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4088" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,1.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4091" gradientUnits="userSpaceOnUse" gradientTransform="translate(-20,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4095" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4098" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4101" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4104" gradientUnits="userSpaceOnUse" gradientTransform="translate(36,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4107" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,5.634754,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4112" gradientUnits="userSpaceOnUse" gradientTransform="translate(36,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4115" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4118" gradientUnits="userSpaceOnUse" gradientTransform="translate(12,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4122" gradientUnits="userSpaceOnUse" gradientTransform="translate(16,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4129" gradientUnits="userSpaceOnUse" gradientTransform="translate(32,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4132" gradientUnits="userSpaceOnUse" gradientTransform="translate(12,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4136" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-14.365246,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4139" gradientUnits="userSpaceOnUse" gradientTransform="translate(16,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4145" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,5.634754,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4156" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4162" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="matrix(0.988811,0,0,0.9872502,-4.2657949e-2,0.2039966)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4164" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="translate(20,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4167" id="linearGradient4173" x1="117.15954" y1="85.009705" x2="88.276085" y2="25.99531" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4179" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="matrix(0.9955244,0,0,0.9872502,0.3938517,0.8203689)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4181" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="translate(20,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4167" id="linearGradient4184" gradientUnits="userSpaceOnUse" gradientTransform="translate(20,0)" x1="25.151232" y1="36.751064" x2="23.062586" y2="56.203735" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient2331" gradientUnits="userSpaceOnUse" gradientTransform="translate(12,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient2333" gradientUnits="userSpaceOnUse" gradientTransform="translate(16,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient2335" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-14.365246,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient2337" gradientUnits="userSpaceOnUse" gradientTransform="translate(16,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient2339" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient2341" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient2343" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,1.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient2345" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient2347" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient2349" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4167" id="linearGradient2351" gradientUnits="userSpaceOnUse" x1="117.15954" y1="85.009705" x2="88.276085" y2="25.99531" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4167" id="linearGradient2353" gradientUnits="userSpaceOnUse" gradientTransform="translate(20,0)" x1="25.151232" y1="36.751064" x2="23.062586" y2="56.203735" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="4.9609375" inkscape:cx="64" inkscape:cy="64" inkscape:document-units="px" inkscape:current-layer="g3936" width="128px" height="128px" showgrid="true" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" inkscape:window-width="748" inkscape:window-height="732" inkscape:window-x="0" inkscape:window-y="0" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g3936" transform="translate(20,0)"> <g id="g2316" transform="matrix(-1,0,0,1,88,0)"> <path id="path3987" d="M 55.875,12 C 55.009497,12.02693 54.176101,12.33398 53.5,12.875 L -6.5,60.875 C -7.449856,61.63413 -8,62.78406 -8,64 C -8,65.21594 -7.449856,66.36587 -6.5,67.125 L 53.5,115.125 C 54.700963,116.08613 56.332437,116.26025 57.71875,115.59375 C 59.105067,114.92725 60.000642,113.53821 60,112 L 60,94.71875 L 85.5,115.125 C 86.70096,116.08613 88.33244,116.26025 89.71875,115.59375 C 91.10507,114.92725 92.00064,113.53821 92,112 L 92,88.3125 L 92,83.875 L 92,83.1875 L 92,78.0625 L 92,49.9375 L 92,45 L 92,44.8125 L 92,39.6875 L 92,16 C 92.00042,14.91715 91.55863,13.87882 90.78125,13.125 C 90.00387,12.37118 88.95732,11.96627 87.875,12 C 87.0095,12.02693 86.1761,12.33398 85.5,12.875 L 60,33.28125 L 60,16 C 60.000417,14.91715 59.558627,13.87882 58.78125,13.125 C 58.003873,12.37118 56.957323,11.96627 55.875,12 z " style="opacity:0.53694584;fill:#004d00;fill-opacity:1;fill-rule:evenodd;stroke:#004d00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3467)" /> <path id="path3989" d="M 55.875,12 C 55.009497,12.02693 54.176101,12.33398 53.5,12.875 L -6.5,60.875 C -7.449856,61.63413 -8,62.78406 -8,64 C -8,65.21594 -7.449856,66.36587 -6.5,67.125 L 53.5,115.125 C 54.700963,116.08613 56.332437,116.26025 57.71875,115.59375 C 59.105067,114.92725 60.000642,113.53821 60,112 L 60,94.71875 L 85.5,115.125 C 86.70096,116.08613 88.33244,116.26025 89.71875,115.59375 C 91.10507,114.92725 92.00064,113.53821 92,112 L 92,88.3125 L 92,83.875 L 92,78.0625 L 92,49.9375 L 92,45 L 92,39.6875 L 92,16 C 92.00042,14.91715 91.55863,13.87882 90.78125,13.125 C 90.00387,12.37118 88.95732,11.96627 87.875,12 C 87.0095,12.02693 86.1761,12.33398 85.5,12.875 L 60,33.28125 L 60,16 C 60.000417,14.91715 59.558627,13.87882 58.78125,13.125 C 58.003873,12.37118 56.957323,11.96627 55.875,12 z M 52,24.3125 L 52,39.6875 L 46.59375,44 L 37,44 C 36.446,44 36,44.446 36,45 L 36,52.46875 L 25.5,60.875 C 24.550144,61.63413 24,62.78406 24,64 C 24,65.21594 24.550144,66.36587 25.5,67.125 L 36,75.53125 L 36,83.875 C 36,84.429 36.446,84.875 37,84.875 L 47.6875,84.875 L 52,88.3125 L 52,103.6875 L 2.40625,64 L 52,24.3125 z M 84,24.3125 L 84,44 L 69,44 C 68.446,44 68,44.446 68,45 L 68,83.875 C 68,84.429 68.446,84.875 69,84.875 L 84,84.875 L 84,103.6875 L 60,84.46875 L 60,83.875 L 60,78.0625 L 60,49.9375 L 60,45 L 60,43.53125 L 84,24.3125 z M 36,62.71875 L 36,65.28125 L 34.40625,64 L 36,62.71875 z " style="fill:url(#linearGradient2331);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path3993" d="M 55.875,12 C 55.009497,12.02693 54.176101,12.33398 53.5,12.875 L -6.5,60.875 C -7.449856,61.63413 -8,62.78406 -8,64 C -8,65.21594 -7.449856,66.36587 -6.5,67.125 L 53.5,115.125 C 54.700963,116.08613 56.332437,116.26025 57.71875,115.59375 C 59.105067,114.92725 60.000642,113.53821 60,112 L 60,94.71875 L 85.5,115.125 C 86.70096,116.08613 88.33244,116.26025 89.71875,115.59375 C 91.10507,114.92725 92.00064,113.53821 92,112 L 92,88.3125 L 92,83.875 L 92,83.1875 L 92,78.0625 L 92,49.9375 L 92,45 L 92,44.8125 L 92,39.6875 L 92,16 C 92.00042,14.91715 91.55863,13.87882 90.78125,13.125 C 90.00387,12.37118 88.95732,11.96627 87.875,12 C 87.0095,12.02693 86.1761,12.33398 85.5,12.875 L 60,33.28125 L 60,16 C 60.000417,14.91715 59.558627,13.87882 58.78125,13.125 C 58.003873,12.37118 56.957323,11.96627 55.875,12 z M 52,24.3125 L 52,39.6875 L 46.59375,44 L 37,44 C 36.446,44 36,44.446 36,45 L 36,52.46875 L 25.5,60.875 C 24.550144,61.63413 24,62.78406 24,64 C 24,65.21594 24.550144,66.36587 25.5,67.125 L 36,75.53125 L 36,83.875 C 36,84.429 36.446,84.875 37,84.875 L 47.6875,84.875 L 52,88.3125 L 52,103.6875 L 2.40625,64 L 52,24.3125 z M 84,24.3125 L 84,44 L 69,44 C 68.446,44 68,44.446 68,45 L 68,83.875 C 68,84.429 68.446,84.875 69,84.875 L 84,84.875 L 84,103.6875 L 60,84.46875 L 60,83.875 L 60,83.1875 L 60,78.0625 L 60,49.9375 L 60,45 L 60,44.8125 L 60,43.53125 L 84,24.3125 z M 36,62.71875 L 36,65.28125 L 34.40625,64 L 36,62.71875 z " style="opacity:0.53694584;fill:url(#linearGradient2333);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path3999" d="M 56,16 L -4,64 L 56,112 L 56,86.40625 L 88,112 L 88,80 L 88,48 L 88,16 L 56,41.59375 L 56,16 z " style="fill:url(#radialGradient2335);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path id="path4001" d="M 56,16 L -4,64 L 56,112 L 56,86.40625 L 88,112 L 88,80 L 88,48 L 88,16 L 56,41.59375 L 56,16 z " style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2337);stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3435)" /> <path id="path3991" d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " style="opacity:0.85;fill:url(#radialGradient2339);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> <path transform="matrix(1,0,0,-1,16,127.7793)" style="opacity:0.35;fill:url(#radialGradient2341);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " id="path3995" /> <path style="opacity:0.85;fill:url(#radialGradient2343);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" d="M 55.875,12 C 55.075959,12.024867 54.302054,12.283948 53.65625,12.75 L 54.625,21.78125 L 59.96875,15.625 C 59.880958,14.678789 59.469257,13.792159 58.78125,13.125 C 58.003873,12.37118 56.957323,11.966273 55.875,12 z " id="path3651" /> <path id="path3685" d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " style="opacity:0.35;fill:url(#radialGradient2345);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" transform="matrix(1,0,0,-1,-16,127.7793)" /> <path style="opacity:0.5;fill:url(#radialGradient2347);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " id="path3705" transform="matrix(1,0,0,-1,-16,128.5625)" /> <path id="path4143" d="M 56,16 L -3.8125,63.84375 C 4.238841,64.168797 12.513445,64.34375 20.90625,64.34375 C 44.837882,64.34375 67.533203,62.960664 88,60.5 L 88,48 L 88,16 L 56,41.59375 L 56,16 z " style="fill:url(#linearGradient2349);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cccccccccsccsccc" id="path4158" transform="translate(-20,0)" d="M 76,16 L 75.34375,16.53125 L 75.34375,41.28125 L 76,40.75 L 76,16 z M 108,16 L 107.46875,16.8125 L 107.46875,47.59375 L 107.46875,59.9375 C 87.230955,62.366791 64.288861,63.718749 40.625,63.71875 C 32.585491,63.71875 24.663189,63.551875 16.9375,63.25 L 16.1875,63.84375 C 24.238841,64.168797 32.513445,64.34375 40.90625,64.34375 C 64.837882,64.34375 87.533203,62.960664 108,60.5 L 108,48 L 108,16 z " style="fill:url(#linearGradient2351);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path id="path4175" transform="translate(-20,0)" d="M 76,16 L 16.1875,63.84375 C 16.321516,63.84916 16.45961,63.838423 16.59375,63.84375 L 76,16.75 L 76,16 z M 108,16 L 76.15625,41.46875 L 76.15625,41.875 L 108,16.625 L 108,16 z " style="fill:url(#linearGradient2353);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </g> </g> </g> </svg> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/va_sa.svg������������������������������������������������������������0000644�0001750�0000144�00000010147�11257112602�016332� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="145" height="145" id="svg2382" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images/work" sodipodi:docname="va_sa1.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs2384"> <linearGradient inkscape:collect="always" id="linearGradient9691"> <stop style="stop-color:#323232;stop-opacity:1;" offset="0" id="stop9693" /> <stop style="stop-color:#000000;stop-opacity:1" offset="1" id="stop9695" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient9691" id="linearGradient2424" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.988046,0,0,0.9880485,606.48161,51.057849)" x1="66.397873" y1="5.9613037" x2="66.603661" y2="129.03691" /> <linearGradient inkscape:collect="always" id="linearGradient9739"> <stop style="stop-color:#494949;stop-opacity:1" offset="0" id="stop9741" /> <stop style="stop-color:#000000;stop-opacity:1" offset="1" id="stop9743" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient9739" id="linearGradient9745" x1="56.941498" y1="5.3460956" x2="57.352737" y2="125.73909" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0075326,0,0,1,598.85574,45.557498)" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="5.6" inkscape:cx="76.435434" inkscape:cy="73.428571" inkscape:document-units="px" inkscape:current-layer="layer1" width="145px" height="145px" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" /> <metadata id="metadata2387"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-597.87867,-39.605735)"> <path style="fill:url(#linearGradient2424);fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 669.84296,51.143189 C 663.34307,51.226229 655.81027,55.908729 653.90546,65.299439 C 638.87242,64.839719 632.15504,85.471269 630.90546,99.518189 C 629.3179,117.36468 641.91583,129.7871 654.34296,134.61194 C 654.16189,136.63746 653.90719,138.51568 653.09296,139.42444 C 647.91135,145.20763 643.82363,145.57154 634.65546,148.17444 C 624.42704,151.07835 616.31095,153.91637 610.43671,159.08069 C 605.98906,162.99084 602.89813,167.39418 602.09296,172.83069 L 737.74921,172.83069 C 736.94404,167.39418 733.85312,162.99083 729.40546,159.08069 C 723.59646,153.97373 715.48089,150.97202 705.18671,148.04944 C 695.95064,145.42728 688.90517,142.44923 687.31171,138.20569 C 686.13506,135.07212 685.66636,129.29894 685.59296,126.61194 C 699.74633,124.58359 708.59296,116.12203 708.59296,101.39319 C 708.59296,77.435779 689.34264,50.894069 669.84296,51.143189 z " id="path2375" /> </g> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/patterns.svg���������������������������������������������������������0000644�0001750�0000144�00000020465�11207732740�017113� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="680" height="680" id="svg2273" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/MP3Diags/src/images" sodipodi:docname="patterns.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2275" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="375" inkscape:cy="405.71429" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" showgrid="false" showguides="true" height="680px" width="680px" /> <metadata id="metadata2278"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-47.400002,-191.39075)"> <rect style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:11.6702919;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4135" width="659.04401" height="381.90115" x="58.235142" y="350.08307" /> <path transform="scale(0.8939565,1.1186227)" style="font-size:246.03437805px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" d="M 90.557479,435.89597 C 90.557464,423.3221 93.720989,412.63018 100.04806,403.8202 C 106.37509,395.01055 115.54531,390.60564 127.55874,390.60547 C 138.61101,390.60564 147.74118,394.57006 154.94929,402.49873 C 162.23733,410.34764 165.88139,421.92054 165.88148,437.21745 C 165.88139,452.11418 162.19729,463.60698 154.82915,471.6959 C 147.54096,479.70492 138.53092,483.70938 127.79901,483.70929 C 117.14709,483.70938 108.25719,479.74496 101.12927,471.81603 C 94.081391,463.88729 90.557464,451.91395 90.557479,435.89597 M 128.15941,405.50208 C 122.79338,405.50224 118.30838,407.82483 114.70441,412.46985 C 111.18044,417.11518 109.41848,425.64468 109.41851,438.05838 C 109.41848,449.3511 111.22049,457.31998 114.82454,461.96505 C 118.42852,466.53024 122.87347,468.81278 128.15941,468.81268 C 133.60543,468.81278 138.09043,466.49019 141.61442,461.84491 C 145.21837,457.19984 147.02038,448.71038 147.02045,436.37651 C 147.02038,425.00397 145.21837,417.03509 141.61442,412.46985 C 138.01034,407.82483 133.52534,405.50224 128.15941,405.50208 M 128.27955,576.21245 L 224.62699,390.60547 L 242.16655,390.60547 L 146.17951,576.21245 L 128.27955,576.21245 M 204.44449,528.39913 C 204.44436,515.74507 207.60788,505.05316 213.93507,496.32336 C 220.26198,487.51362 229.47224,483.10871 241.56588,483.10862 C 252.61803,483.10871 261.74821,487.07313 268.95643,495.00189 C 276.24436,502.85071 279.88842,514.4236 279.88862,529.72061 C 279.88842,544.61724 276.20431,556.11005 268.8363,564.19906 C 261.54798,572.20799 252.4979,576.21245 241.68602,576.21245 C 231.03398,576.21245 222.14408,572.24803 215.01628,564.31919 C 207.96828,556.31027 204.44436,544.33693 204.44449,528.39913 M 242.16655,498.00524 C 236.72032,498.00531 232.19528,500.3279 228.59141,504.97301 C 225.06734,509.61825 223.30537,518.14775 223.30552,530.56154 C 223.30537,541.77408 225.10738,549.70291 228.71155,554.34807 C 232.31541,558.99326 236.76036,561.31585 242.04642,561.31584 C 247.57241,561.31585 252.09745,558.99326 255.62156,554.34807 C 259.22539,549.70291 261.0274,541.21345 261.02759,528.87967 C 261.0274,517.50704 259.22539,509.53816 255.62156,504.97301 C 252.01736,500.3279 247.53237,498.00531 242.16655,498.00524 M 311.12345,569.72522 L 311.12345,442.14294 L 330.58516,442.14294 L 330.58516,460.28317 C 339.95556,446.26766 353.49064,439.25985 371.19044,439.25972 C 378.87893,439.25985 385.92678,440.66142 392.33402,443.46441 C 398.82115,446.18757 403.66655,449.79159 406.87023,454.27647 C 410.07369,458.76158 412.31618,464.08752 413.59773,470.25429 C 414.3985,474.25885 414.79895,481.26666 414.79907,491.27773 L 414.79907,569.72522 L 393.17496,569.72522 L 393.17496,492.11867 C 393.17486,483.30893 392.33392,476.74162 390.65214,472.4167 C 388.97017,468.01189 385.96683,464.52801 381.64209,461.96505 C 377.39728,459.32221 372.3917,458.00074 366.62535,458.00062 C 357.41501,458.00074 349.44613,460.92399 342.71869,466.7704 C 336.07123,472.61702 332.74753,483.70938 332.74757,500.04752 L 332.74757,569.72522 L 311.12345,569.72522 M 454.20301,569.72522 L 454.20301,545.09776 L 478.83048,545.09776 L 478.83048,569.72522 L 454.20301,569.72522 M 514.39012,435.89597 C 514.39011,423.3221 517.55363,412.63018 523.8807,403.8202 C 530.20773,395.01055 539.37795,390.60564 551.39138,390.60547 C 562.44365,390.60564 571.57382,394.57006 578.78193,402.49873 C 586.06997,410.34764 589.71403,421.92054 589.71412,437.21745 C 589.71403,452.11418 586.02993,463.60698 578.6618,471.6959 C 571.3736,479.70492 562.36356,483.70938 551.63165,483.70929 C 540.97973,483.70938 532.08983,479.74496 524.96191,471.81603 C 517.91403,463.88729 514.39011,451.91395 514.39012,435.89597 M 551.99205,405.50208 C 546.62602,405.50224 542.14103,407.82483 538.53705,412.46985 C 535.01308,417.11518 533.25112,425.64468 533.25115,438.05838 C 533.25112,449.3511 535.05313,457.31998 538.65718,461.96505 C 542.26116,466.53024 546.70611,468.81278 551.99205,468.81268 C 557.43807,468.81278 561.92307,466.49019 565.44706,461.84491 C 569.05101,457.19984 570.85302,448.71038 570.85309,436.37651 C 570.85302,425.00397 569.05101,417.03509 565.44706,412.46985 C 561.84298,407.82483 557.35798,405.50224 551.99205,405.50208 M 552.11219,576.21245 L 648.45963,390.60547 L 665.99919,390.60547 L 570.01215,576.21245 L 552.11219,576.21245 M 628.27713,528.39913 C 628.277,515.74507 631.44052,505.05316 637.76771,496.32336 C 644.09462,487.51362 653.30489,483.10871 665.39852,483.10862 C 676.45067,483.10871 685.58085,487.07313 692.78907,495.00189 C 700.077,502.85071 703.72106,514.4236 703.72126,529.72061 C 703.72106,544.61724 700.03695,556.11005 692.66894,564.19906 C 685.38062,572.20799 676.33054,576.21245 665.51866,576.21245 C 654.86663,576.21245 645.97672,572.24803 638.84892,564.31919 C 631.80093,556.31027 628.277,544.33693 628.27713,528.39913 M 665.99919,498.00524 C 660.55296,498.00531 656.02792,500.3279 652.42406,504.97301 C 648.89998,509.61825 647.13801,518.14775 647.13816,530.56154 C 647.13801,541.77408 648.94002,549.70291 652.54419,554.34807 C 656.14805,558.99326 660.59301,561.31585 665.87906,561.31584 C 671.40505,561.31585 675.93009,558.99326 679.4542,554.34807 C 683.05804,549.70291 684.86004,541.21345 684.86023,528.87967 C 684.86004,517.50704 683.05804,509.53816 679.4542,504.97301 C 675.85,500.3279 671.36501,498.00531 665.99919,498.00524 M 782.16878,550.38365 L 785.29226,569.48495 C 779.20541,570.76638 773.75934,571.40709 768.95404,571.4071 C 761.10524,571.40709 755.01846,570.16571 750.69367,567.68294 C 746.36882,565.20018 743.32543,561.95656 741.56349,557.95209 C 739.80151,553.86755 738.92052,545.33805 738.92054,532.36355 L 738.92054,458.9617 L 723.06286,458.9617 L 723.06286,442.14294 L 738.92054,442.14294 L 738.92054,410.5477 L 760.42453,397.57324 L 760.42453,442.14294 L 782.16878,442.14294 L 782.16878,458.9617 L 760.42453,458.9617 L 760.42453,533.56489 C 760.42448,539.7318 760.78489,543.69622 761.50573,545.45816 C 762.30658,547.22014 763.54796,548.62171 765.22988,549.66285 C 766.9918,550.70403 769.47457,551.22461 772.67819,551.22459 C 775.08081,551.22461 778.24434,550.94429 782.16878,550.38365" id="text3191" /> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/transform.svg��������������������������������������������������������0000644�0001750�0000144�00000240030�11106025171�017245� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:ns="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="128" height="128" id="svg2365" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docname="transform.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images"> <metadata id="metadata198"> <rdf:RDF> <ns:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </ns:Work> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <sodipodi:namedview inkscape:window-height="1098" inkscape:window-width="1600" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" showgrid="false" inkscape:zoom="4.140625" inkscape:cx="64" inkscape:cy="64" inkscape:window-x="0" inkscape:window-y="33" inkscape:current-layer="svg2365"> <inkscape:grid type="xygrid" id="grid2575" visible="true" enabled="true" /> </sodipodi:namedview> <defs id="defs2367"> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3327" id="linearGradient3356" gradientUnits="userSpaceOnUse" gradientTransform="translate(28,0)" x1="42.548481" y1="13.921767" x2="46.758774" y2="70.827744" /> <linearGradient inkscape:collect="always" id="linearGradient3327"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3329" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3331" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3327" id="linearGradient3344" gradientUnits="userSpaceOnUse" gradientTransform="translate(28,0)" x1="56" y1="67.238144" x2="34.345421" y2="40.171875" /> <linearGradient inkscape:collect="always" id="linearGradient4150"> <stop style="stop-color:#bfffbf;stop-opacity:1;" offset="0" id="stop4152" /> <stop style="stop-color:#bfffbf;stop-opacity:0;" offset="1" id="stop4154" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient3316" gradientUnits="userSpaceOnUse" gradientTransform="translate(8,0)" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" /> <filter inkscape:collect="always" x="-0.45196507" width="1.9039301" y="-0.29913295" height="1.5982659" id="filter3722"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.3476562" id="feGaussianBlur3724" /> </filter> <linearGradient inkscape:collect="always" id="linearGradient3710"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3712" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3714" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4037" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <linearGradient id="linearGradient3689" inkscape:collect="always"> <stop id="stop3691" offset="0" style="stop-color:#f0ff80;stop-opacity:1" /> <stop id="stop3693" offset="1" style="stop-color:#f0ff80;stop-opacity:0" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient4035" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <filter inkscape:collect="always" x="-0.12239107" width="1.2447821" y="-0.078971461" height="1.1579429" id="filter3681"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.321914" id="feGaussianBlur3683" /> </filter> <linearGradient inkscape:collect="always" id="linearGradient3669"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3671" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3673" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4088" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,9.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <filter inkscape:collect="always" id="filter3435"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.395" id="feGaussianBlur3437" /> </filter> <linearGradient id="linearGradient3355" inkscape:collect="always"> <stop id="stop3357" offset="0" style="stop-color:#e0ffe0;stop-opacity:1" /> <stop id="stop3359" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient3314" gradientUnits="userSpaceOnUse" gradientTransform="translate(24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient id="linearGradient3349" inkscape:collect="always"> <stop id="stop3351" offset="0" style="stop-color:#00dd00;stop-opacity:1" /> <stop id="stop3353" offset="1" style="stop-color:#000e00;stop-opacity:1" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient3312" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-6.365246,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" id="linearGradient3511"> <stop style="stop-color:#002a0d;stop-opacity:1;" offset="0" id="stop3513" /> <stop style="stop-color:#002a0d;stop-opacity:0;" offset="1" id="stop3515" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient3296" gradientUnits="userSpaceOnUse" gradientTransform="translate(24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <linearGradient inkscape:collect="always" id="linearGradient3342"> <stop style="stop-color:#00ff00;stop-opacity:1" offset="0" id="stop3344" /> <stop style="stop-color:#004d00;stop-opacity:1" offset="1" id="stop3346" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3310" gradientUnits="userSpaceOnUse" gradientTransform="translate(20,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <filter inkscape:collect="always" id="filter3467"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.4349886" id="feGaussianBlur3469" /> </filter> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective200" /> <filter x="-0.085532367" width="1.1710647" y="-0.10938701" height="1.218774" id="filter6906"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.5212367" id="feGaussianBlur6908" /> </filter> <clipPath id="clipPath6130"> <path d="M 125.16669,12.099598 C 122.19641,9.254864 111.282,2.992388 109.84175,5.187905 C 108.10513,7.835221 117.93885,14.870955 121.74406,16.587139 C 123.04716,17.174853 126.16385,13.054607 125.16669,12.099598 z" id="path6132" style="fill:#e20071;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient3168"> <stop id="stop3170" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop3172" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="29.344007" y1="35.892609" x2="5.8861146" y2="54.610104" id="linearGradient6134" xlink:href="#linearGradient3168" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.8205678,0.1491734,0.1491734,0.8205678,119.95493,-30.558073)" /> <linearGradient id="linearGradient2878"> <stop id="stop2880" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2882" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="47.794022" cy="43.680889" r="0.046902865" fx="47.817745" fy="43.681263" id="radialGradient2257" xlink:href="#linearGradient2878" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,140,0,-6071.644)" /> <linearGradient id="linearGradient2926"> <stop id="stop2928" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2934" style="stop-color:#ffffff;stop-opacity:0" offset="0.31868133" /> <stop id="stop2930" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="59.887943" cy="-16.594898" r="15.014902" fx="59.887943" fy="-16.594898" id="radialGradient4868" xlink:href="#linearGradient2926" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2908472,-1.2912538,-0.4877278,0.8613771,257.00005,93.121214)" spreadMethod="reflect" /> <linearGradient id="linearGradient2916"> <stop id="stop2918" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2920" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="58.079144" cy="51.897194" r="15.014902" fx="60.050133" fy="51.985794" id="radialGradient4871" xlink:href="#linearGradient2916" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.9412787,-1.1615663,-0.2846191,0.7136661,292.2596,68.533501)" /> <linearGradient id="linearGradient2948"> <stop id="stop2950" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2956" style="stop-color:#000000;stop-opacity:0" offset="0.14835165" /> <stop id="stop2960" style="stop-color:#000000;stop-opacity:0.39607844" offset="0.42443547" /> <stop id="stop2958" style="stop-color:#000000;stop-opacity:0.79061371" offset="0.57417583" /> <stop id="stop2962" style="stop-color:#000000;stop-opacity:0.09386282" offset="0.78708792" /> <stop id="stop2952" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.277409" y1="41.758987" x2="75.465431" y2="41.511894" id="linearGradient4874" xlink:href="#linearGradient2948" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <filter x="-0.081383675" width="1.1627673" y="-0.11701577" height="1.2340316" id="filter7303"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5574454" id="feGaussianBlur7305" /> </filter> <clipPath id="clipPath6914"> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 81.839741,-15.69481 90.48863,-25.23053 103.93871,-26.883344 C 107.28591,-26.458991 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.52863,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z" id="path6916" style="opacity:1;fill:#34176e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2938"> <stop id="stop2940" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2942" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="61.870293" y1="33.318996" x2="61.870293" y2="40.550549" id="linearGradient4880" xlink:href="#linearGradient2938" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <linearGradient id="linearGradient2854"> <stop id="stop2856" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2858" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="106.03028" y1="59.273457" x2="108.78728" y2="55.574818" id="linearGradient4888" xlink:href="#linearGradient2854" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="94.435982" cy="42.709927" r="16.633095" fx="94.435982" fy="42.709927" id="radialGradient4891" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2134389,-1.5580054,-0.9195638,1.2855562,320.80105,101.437)" /> <radialGradient cx="94.932045" cy="43.032188" r="16.633095" fx="94.932045" fy="43.032188" id="radialGradient4894" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="93.747849" cy="43.102612" r="16.633095" fx="93.747849" fy="43.102612" id="radialGradient4897" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="92.990265" cy="42.850105" r="16.633095" fx="92.990265" fy="42.850105" id="radialGradient4900" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <linearGradient id="linearGradient2830"> <stop id="stop2832" style="stop-color:#111111;stop-opacity:1" offset="0" /> <stop id="stop2838" style="stop-color:#6e6e70;stop-opacity:1" offset="0.14285715" /> <stop id="stop2864" style="stop-color:#101010;stop-opacity:1" offset="0.5714286" /> <stop id="stop2834" style="stop-color:#0d0d0d;stop-opacity:1" offset="1" /> </linearGradient> <radialGradient cx="92.496124" cy="43.249184" r="16.633095" fx="92.496124" fy="43.249184" id="radialGradient4903" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <filter x="-0.059171364" width="1.1183428" y="-0.25424162" height="1.5084833" id="filter5739"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5280665" id="feGaussianBlur5741" /> </filter> <clipPath id="clipPath5354"> <path d="M 103.98397,-1.574449 C 105.35028,-1.792233 108.98473,-2.914664 106.17093,-5.692155 C 76.173344,-27.291403 51.99515,-18.323699 42.936426,-12.159439 C 53.098952,-17.891025 78.771948,-21.925123 103.98397,-1.574449 z" id="path5356" style="opacity:1;fill:#00583f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2803"> <stop id="stop2809" style="stop-color:#e2dcdc;stop-opacity:1" offset="0" /> <stop id="stop2811" style="stop-color:#ffffff;stop-opacity:1" offset="0.39074388" /> <stop id="stop2813" style="stop-color:#dfd9df;stop-opacity:1" offset="0.82692307" /> <stop id="stop2815" style="stop-color:#c3c3c3;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="62.987843" y1="46.469597" x2="118.02947" y2="62.350033" id="linearGradient4910" xlink:href="#linearGradient2803" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2231" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2229" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2227" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2225" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2223" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2221" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2219" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2217" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2215" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2213" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2211" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2209" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2207" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2205" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2203" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2201" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2199" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2197" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2195" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2193" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2191" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2189" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2187" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2185" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2183" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2181" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2179" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2177" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2175" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2173" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2171" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2169" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient id="linearGradient2370"> <stop id="stop2378" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2374" style="stop-color:#2a2a2a;stop-opacity:0.29537368" offset="1" /> </linearGradient> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2167" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient x1="-66.905724" y1="78.000954" x2="-66.905724" y2="77.232819" id="linearGradient4946" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-75.354716)" /> <linearGradient x1="-74.01326" y1="49.46249" x2="-58.206917" y2="65.268829" id="linearGradient4952" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833612,-4.797835,-79.665584)" /> <linearGradient x1="36.909187" y1="75.415688" x2="38.451817" y2="75.479614" id="linearGradient4955" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.983361,0.6663259,-0.6582589,0.9697357,55.439719,-32.927491)" /> <linearGradient id="linearGradient2322"> <stop id="stop2324" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2326" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="37.235054" y1="75.415688" x2="38.61475" y2="75.479614" id="linearGradient4958" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.44832,27.448631)" /> <linearGradient x1="45.615768" y1="128.00496" x2="45.615768" y2="125.89983" id="linearGradient4961" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2310"> <stop id="stop2312" style="stop-color:#020202;stop-opacity:1" offset="0" /> <stop id="stop2314" style="stop-color:#020202;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.24057" y1="61.083416" x2="45.24057" y2="62.415165" id="linearGradient4964" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.36527,27.463989)" /> <linearGradient id="linearGradient3058"> <stop id="stop3060" style="stop-color:#9a7600;stop-opacity:1" offset="0" /> <stop id="stop3066" style="stop-color:#e3ad00;stop-opacity:1" offset="0.32522252" /> <stop id="stop3070" style="stop-color:#ffcd2c;stop-opacity:1" offset="0.6670348" /> <stop id="stop3068" style="stop-color:#e3ad00;stop-opacity:1" offset="0.91571385" /> <stop id="stop3062" style="stop-color:#b98d00;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="34.91254" y1="94.734375" x2="55.089256" y2="94.734375" id="linearGradient4967" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2352"> <stop id="stop2354" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2356" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="-66.905724" y1="77.09996" x2="-66.905724" y2="75.717079" id="linearGradient4949" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764965,0,0,1.1833623,-4.7827195,-79.650397)" /> <linearGradient id="linearGradient2334"> <stop id="stop2336" style="stop-color:#8d8d8d;stop-opacity:1" offset="0" /> <stop id="stop2342" style="stop-color:#e2dcdc;stop-opacity:1" offset="0.2767916" /> <stop id="stop2348" style="stop-color:#ffffff;stop-opacity:1" offset="0.71460712" /> <stop id="stop2344" style="stop-color:#dfd9df;stop-opacity:1" offset="0.80711305" /> <stop id="stop2338" style="stop-color:#888888;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="-70.588905" y1="67.754272" x2="-59.581383" y2="67.754272" id="linearGradient4970" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-79.665581)" /> <linearGradient id="linearGradient6959"> <stop id="stop6961" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop6963" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="0.16120911" y1="117.27959" x2="128.16121" y2="117.27959" id="linearGradient8078" xlink:href="#linearGradient6959" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.785268,-7.3677219e-2,3.9462543e-2,0.4492806,22.778321,70.710911)" /> </defs> <g id="layer1" transform="translate(-6,8.2439641e-8)"> <path d="M 128.04736,113.95979 C 128.28089,116.61848 67.411471,124.50507 39.669521,127.10794 C 11.927571,129.71081 27.766581,126.04917 27.533061,123.39048 C 27.299531,120.73178 11.081461,120.07787 38.823411,117.475 C 66.565361,114.87213 127.81383,111.3011 128.04736,113.95979 z" id="path6957" style="opacity:0.32093027;fill:url(#linearGradient8078);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31099999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.274934,34.905639 C 85.204914,25.922787 89.34177,14.198553 102.63801,12.53741 C 105.94693,12.9639 108.13372,18.737744 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z" id="path2874" style="fill:#bfbfc0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <rect width="12.941447" height="29.58403" ry="0" x="-87.844696" y="-16.94743" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2266" style="fill:url(#linearGradient4970);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="13.038667" height="2.5542164" ry="0" x="-87.829575" y="9.101737" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2360" style="opacity:0.36065578;fill:url(#linearGradient4949);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.429289,63.172679 C 65.635414,64.820033 54.923018,83.195864 49.729102,91.344581 C 39.34128,107.642 26.239281,125.86158 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 19.376879,93.833728 30.860819,78.294436 C 36.602784,70.52478 49.810698,53.88547 51.006314,52.505467 C 52.212736,51.113002 53.417042,50.730504 54.693928,51.613654 C 58.435834,54.201727 62.17774,56.7898 65.919646,59.377862 C 66.995538,60.122005 67.369194,61.222275 66.429289,63.172679 z" id="rect1388" style="fill:url(#linearGradient4967);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.247591,63.206257 C 65.453717,64.853621 49.629,53.919059 50.824616,52.539056 C 52.031038,51.146581 53.235344,50.764082 54.51223,51.647242 C 58.254136,54.235305 61.996042,56.823378 65.737948,59.411451 C 66.81384,60.155584 67.187497,61.255863 66.247591,63.206257 z" id="path2290" style="opacity:0.09157511;fill:url(#linearGradient4964);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 26.239281,125.86158 26.239281,125.86158 z" id="path2308" style="opacity:0.3699634;fill:url(#linearGradient4961);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.33068,63.19091 C 65.536805,64.838264 54.824409,83.214095 49.630493,91.362803 C 39.242661,107.66022 26.140672,125.8798 26.140672,125.8798 C 24.569135,128.14762 62.079131,56.808021 65.821037,59.396094 C 66.896928,60.140227 67.270585,61.240506 66.33068,63.19091 z" id="path2320" style="opacity:0.3699634;fill:url(#linearGradient4958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 51.020737,52.411747 C 49.776998,53.730231 36.591653,70.167669 30.909012,77.870037 C 19.543739,93.274764 7.3898106,111.88362 7.3898106,111.88362 C 5.8550281,114.14465 58.555163,54.129906 54.752313,51.55311 C 53.658913,50.812203 52.49326,50.850706 51.020737,52.411747 z" id="path2330" style="opacity:0.23809521;fill:url(#linearGradient4955);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="22.48386" ry="0" x="-87.844696" y="-16.947432" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2350" style="opacity:0.25;fill:url(#linearGradient4952);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="4.1249256" ry="0" x="-87.844696" y="12.822533" transform="matrix(-0.8224474,-0.5688412,0.5695776,-0.8219376,0,0)" id="rect2364" style="opacity:0.29098361;fill:url(#linearGradient4946);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.339764,-119.62564)" id="path2368" style="opacity:0.21245422;fill:url(#radialGradient2167);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.295704,-113.78978)" id="path2486" style="opacity:0.21245422;fill:url(#radialGradient2169);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.251654,-107.95391)" id="path2490" style="opacity:0.21245422;fill:url(#radialGradient2171);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.207455,-102.11799)" id="path2494" style="opacity:0.21245422;fill:url(#radialGradient2173);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.163405,-96.282126)" id="path2498" style="opacity:0.21245422;fill:url(#radialGradient2175);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.119257,-90.446221)" id="path2502" style="opacity:0.21245422;fill:url(#radialGradient2177);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.401175,-83.637696)" id="path2506" style="opacity:0.21245422;fill:url(#radialGradient2179);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.357125,-77.801811)" id="path2510" style="opacity:0.21245422;fill:url(#radialGradient2181);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.312966,-71.965905)" id="path2514" style="opacity:0.21245422;fill:url(#radialGradient2183);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2518" style="opacity:0.21245422;fill:url(#radialGradient2185);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2522" style="opacity:0.21245422;fill:url(#radialGradient2187);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.51209,-120.72315)" id="path2524" style="opacity:0.21245422;fill:url(#radialGradient2189);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.468031,-114.88732)" id="path2526" style="opacity:0.21245422;fill:url(#radialGradient2191);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.423951,-109.05138)" id="path2528" style="opacity:0.21245422;fill:url(#radialGradient2193);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.379792,-103.21548)" id="path2530" style="opacity:0.21245422;fill:url(#radialGradient2195);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,58.335742,-97.379601)" id="path2532" style="opacity:0.21245422;fill:url(#radialGradient2197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,54.291593,-91.543696)" id="path2534" style="opacity:0.21245422;fill:url(#radialGradient2199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.573512,-84.735171)" id="path2536" style="opacity:0.21245422;fill:url(#radialGradient2201);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.529462,-78.899296)" id="path2538" style="opacity:0.21245422;fill:url(#radialGradient2203);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,41.485303,-73.063401)" id="path2540" style="opacity:0.21245422;fill:url(#radialGradient2205);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2542" style="opacity:0.21245422;fill:url(#radialGradient2207);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2544" style="opacity:0.21245422;fill:url(#radialGradient2209);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,86.123367,-112.6923)" id="path2568" style="opacity:0.21245422;fill:url(#radialGradient2211);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.079218,-106.85639)" id="path2570" style="opacity:0.21245422;fill:url(#radialGradient2213);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.035168,-101.02052)" id="path2572" style="opacity:0.21245422;fill:url(#radialGradient2215);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,73.991108,-95.18463)" id="path2574" style="opacity:0.21245422;fill:url(#radialGradient2217);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,69.947019,-89.348755)" id="path2576" style="opacity:0.21245422;fill:url(#radialGradient2219);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,65.90286,-83.51285)" id="path2578" style="opacity:0.21245422;fill:url(#radialGradient2221);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,61.184788,-76.704325)" id="path2580" style="opacity:0.21245422;fill:url(#radialGradient2223);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.14063,-70.86842)" id="path2582" style="opacity:0.21245422;fill:url(#radialGradient2225);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.09658,-65.032544)" id="path2584" style="opacity:0.21245422;fill:url(#radialGradient2227);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2586" style="opacity:0.21245422;fill:url(#radialGradient2229);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2588" style="opacity:0.21245422;fill:url(#radialGradient2231);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 101.38809,11.479353 C 102.63809,12.398423 103.84894,13.381344 105.0387,14.408949 C 104.01321,16.577326 100.48534,20.746249 99.007199,22.467323 C 98.01495,23.622639 93.281961,23.36178 91.998392,24.319263 C 87.944052,27.343595 84.815519,31.864815 80.922501,35.138608 L 72.655729,29.510877 C 72.667829,29.490354 72.685732,29.470645 72.697861,29.450092 C 72.67379,29.475982 72.628395,29.495037 72.604432,29.520354 L 71.432076,28.709507 C 71.432067,28.709497 76.539137,19.842938 71.897343,16.081861 C 61.421124,7.5933688 42.104321,12.7028 40.367328,14.0543 L 42.083541,7.259695 C 42.083541,7.259695 42.33779,7.1294014 42.380871,7.1146373 C 59.53124,-3.8488001 84.402814,-1.0092155 101.38809,11.479353 z" id="path2783" style="fill:url(#linearGradient4910);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 103.83475,-5.0595755 C 104.3991,-4.5551745 105.41114,-5.6873565 104.63008,-6.2226895 C 74.632493,-27.821939 51.99515,-17.681556 42.936426,-11.517296 C 52.35952,-18.300887 76.609727,-26.230729 103.83475,-5.0595755 z" transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath5354)" id="path2823" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5739)" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.128521,13.402952 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.101176,-0.96025992 73.950973,7.4166021 C 82.164175,13.221703 76.243429,25.456347 72.232891,29.69503 z" id="path2842" style="opacity:0.23360656;fill:url(#radialGradient4903);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.523172,29.895808 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.022844,13.705088 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.235986,-1.1547857 74.085773,7.2220662 C 82.298976,13.027177 76.53371,25.657124 72.523172,29.895808 z" id="path2827" style="opacity:0.23360656;fill:url(#radialGradient4900);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 73.103735,30.297352 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.89179,13.624865 40.576201,14.168322 L 42.322269,7.4456578 C 42.322269,7.4456578 62.640397,-1.7383733 74.490184,6.6384787 C 82.703386,12.44359 77.114273,26.058669 73.103735,30.297352 z" id="path2844" style="opacity:0.0737705;fill:url(#radialGradient4897);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.984171,13.626222 40.566444,14.182412 L 42.334152,7.4434568 C 42.334152,7.4434568 61.966375,-0.76572405 73.816172,7.6111279 C 82.029375,13.416239 76.243429,25.456347 72.232891,29.69503 z" id="path2840" style="opacity:0.23360656;fill:url(#radialGradient4894);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.13613,29.628115 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.921635,13.665037 40.571002,14.184262 L 42.322269,7.4456578 C 42.322269,7.4456578 61.764175,-0.47393028 73.613962,7.9029217 C 81.827164,13.708033 76.146668,25.389432 72.13613,29.628115 z" id="path2862" style="opacity:0.37000002;fill:url(#radialGradient4891);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 61.41113,8.3780551 C 54.11035,6.6553332 42.963569,9.4974003 40.902427,12.001391 L 41.0016,10.631158 C 43.787546,7.6855914 53.80009,5.6303314 60.912865,6.8618995 C 62.075305,7.0631792 62.003061,8.5177258 61.41113,8.3780551 z" id="path2868" style="opacity:0.31000001;fill:url(#linearGradient4888);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 42.085054,7.2558055 L 40.347458,14.03836 L 40.579642,14.198955 L 42.326056,7.4656582 L 42.085054,7.2558055 z" id="path2872" style="opacity:0.11000001;fill:#b7b7b7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.793503,23.516486 95.950625,22.98307 C 98.195669,22.788575 103.22118,19.851069 102.52483,17.34553 C 101.28955,12.900833 104.51185,12.778691 106.76072,16.351101 C 107.83597,18.05917 108.68046,20.615514 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 121.44894,38.490512 117.56384,42.696451 L 111.17842,38.965656 L 103.77633,29.053301 C 97.649281,27.059128 88.562348,29.712528 81.865056,36.103558 z" id="path2936" style="opacity:0.5286885;fill:url(#linearGradient4880);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 96.447179,-28.288297 105.15658,-12.530013 103.93871,-26.883344 C 105.73798,-25.86955 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.528633,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z" transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,39.556289)" clip-path="url(#clipPath6914)" id="path2902" style="opacity:0.3;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7303)" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.936568,23.945458 96.09369,23.412042 C 98.338733,23.217547 99.058515,23.054066 102.62556,17.81605 C 104.97193,14.370546 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z" id="path2904" style="opacity:0.11065572;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 90.178924,23.81633 96.336045,23.282914 C 98.581099,23.088419 99.46084,22.257119 102.66207,17.556297 C 105.00842,14.110793 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z" id="path2946" style="opacity:0.78278689;fill:url(#linearGradient4874);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.186467,36.425805 L 80.943143,35.163804 C 90.771765,25.89748 90.156661,24.109531 96.307061,23.50126 C 99.068954,23.228099 101.46217,20.125666 103.03896,17.817699 C 105.39113,14.376285 105.82661,13.986851 107.08213,16.673348 C 108.04323,18.729874 109.11134,20.957278 109.76753,22.854566 L 120.19358,26.450685 L 126,30.829783 C 123.46105,35.966762 120.42231,40.758067 116.53723,44.964006 L 110.15179,41.233211 L 102.74972,31.320856 C 96.622659,29.326673 88.883759,30.034785 82.186467,36.425805 z" id="path2906" style="opacity:0.55;fill:url(#radialGradient4871);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.052576,35.677069 L 80.809252,34.415058 C 90.637874,25.148744 90.316354,23.346463 96.463708,22.707247 C 99.198595,22.422217 99.463846,21.382923 102.80287,17.054108 C 105.34611,13.756144 105.69272,13.238105 106.94825,15.924612 C 107.90935,17.981128 108.97746,20.208542 109.63365,22.10582 L 120.05969,25.701939 L 125.86612,30.081037 C 123.32716,35.218016 120.28843,40.009321 116.40334,44.21526 L 110.0179,40.484465 L 102.61584,30.57211 C 96.488778,28.577937 88.749878,29.286039 82.052576,35.677069 z" id="path2924" style="opacity:0.76000001;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 47.840924,43.680889 C 47.84099,46.032991 47.832065,48.210404 47.817526,49.389142 C 47.802987,50.56788 47.785056,50.56788 47.770517,49.389142 C 47.755978,48.210404 47.747053,46.032991 47.747119,43.680889 C 47.747053,41.328787 47.755978,39.151374 47.770517,37.972636 C 47.785056,36.793898 47.802987,36.793898 47.817526,37.972636 C 47.832065,39.151374 47.84099,41.328787 47.840924,43.680889 z" transform="matrix(-10.643649,-7.3616191,-0.6740154,0.9726479,659.11339,347.51792)" id="path2876" style="fill:url(#radialGradient2257);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 125.16669,12.099598 C 121.62206,9.685606 112.43786,3.516506 110.99761,5.712023 C 109.26099,8.35934 118.0322,14.038156 121.74406,16.587139 C 122.92246,17.396368 126.3079,12.876785 125.16669,12.099598 z" transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath6130)" id="path3178" style="fill:url(#linearGradient6134);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6906)" /> </g> <g id="g3936" transform="matrix(-4.7623428e-8,-0.3840804,0.5556156,-3.2920652e-8,55.61277,123.18704)"> <path style="opacity:0.53694584;fill:#004d00;fill-opacity:1;fill-rule:evenodd;stroke:#004d00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3467)" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z " id="path3987" /> <path style="fill:url(#linearGradient3310);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,84.46875 L 68,83.875 L 68,78.0625 L 68,49.9375 L 68,45 L 68,43.53125 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z M 60,24.3125 L 60,39.6875 L 54.59375,44 L 45,44 C 44.446,44 44,44.446 44,45 L 44,52.46875 L 33.5,60.875 C 32.550144,61.63413 32,62.78406 32,64 C 32,65.21594 32.550144,66.36587 33.5,67.125 L 44,75.53125 L 44,83.875 C 44,84.429 44.446,84.875 45,84.875 L 55.6875,84.875 L 60,88.3125 L 60,103.6875 L 10.40625,64 L 60,24.3125 z M 44,62.71875 L 44,65.28125 L 42.40625,64 L 44,62.71875 z " id="path3989" /> <path style="opacity:0.53694584;fill:url(#linearGradient3296);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,84.46875 L 68,83.875 L 68,83.1875 L 68,78.0625 L 68,49.9375 L 68,45 L 68,44.8125 L 68,43.53125 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z M 60,24.3125 L 60,39.6875 L 54.59375,44 L 45,44 C 44.446,44 44,44.446 44,45 L 44,52.46875 L 33.5,60.875 C 32.550144,61.63413 32,62.78406 32,64 C 32,65.21594 32.550144,66.36587 33.5,67.125 L 44,75.53125 L 44,83.875 C 44,84.429 44.446,84.875 45,84.875 L 55.6875,84.875 L 60,88.3125 L 60,103.6875 L 10.40625,64 L 60,24.3125 z M 44,62.71875 L 44,65.28125 L 42.40625,64 L 44,62.71875 z " id="path3993" /> <path style="fill:url(#radialGradient3312);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 64,16 L 4,64 L 64,112 L 64,86.40625 L 64,41.59375 L 64,16 z " id="path3999" /> <path style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3314);stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3435)" d="M 64,16 L 4,64 L 64,112 L 64,86.40625 L 64,41.59375 L 64,16 z " id="path4001" /> <path id="path3651" d="M 63.875,12 C 63.075959,12.024867 62.302054,12.283948 61.65625,12.75 L 62.625,21.78125 L 67.96875,15.625 C 67.880958,14.678789 67.469257,13.792159 66.78125,13.125 C 66.003873,12.37118 64.957323,11.966273 63.875,12 z " style="opacity:0.85;fill:url(#radialGradient4088);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> <path transform="matrix(1,0,0,-1,-8,127.7793)" style="opacity:0.35;fill:url(#radialGradient4035);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " id="path3685" /> <path transform="matrix(1,0,0,-1,-8,128.5625)" id="path3705" d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " style="opacity:0.5;fill:url(#radialGradient4037);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> <path style="fill:url(#linearGradient3316);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 64,16 L 4.1875,63.84375 C 12.238841,64.168797 20.513445,64.34375 28.90625,64.34375 C 40.962046,64.34375 52.698537,63.975426 64,63.3125 L 64,41.59375 L 64,16 z " id="path4143" /> <path style="fill:url(#linearGradient3344);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 84,16 L 83.65625,16.28125 L 83.65625,41.375 L 83.65625,62.90625 C 72.417269,63.563595 60.770394,63.937499 48.78125,63.9375 C 40.607993,63.9375 32.537203,63.778318 24.6875,63.46875 L 24.1875,63.84375 C 32.238841,64.168797 40.513445,64.34375 48.90625,64.34375 C 60.962046,64.34375 72.698537,63.975426 84,63.3125 L 84,41.59375 L 84,16 z " transform="translate(-20,0)" id="path3335" /> <path style="fill:url(#linearGradient3356);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 84,16 L 24.1875,63.84375 L 83.75,16.90625 L 83.75,42.03125 L 83.75,63.3125 C 83.832324,63.307705 83.917722,63.317326 84,63.3125 L 84,41.59375 L 84,16 z " transform="translate(-20,0)" id="path3347" /> </g> </svg> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/decode.svg�����������������������������������������������������������0000644�0001750�0000144�00000013670�11074457531�016502� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:ns="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="430" height="430" id="svg2" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docname="decode.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images"> <defs id="defs4"> <filter id="AI_Sfocatura_2"> <feGaussianBlur stdDeviation="2" id="feGaussianBlur3099" /> </filter> <clipPath id="XMLID_6_"> <path id="use3143" d="M 27.6,69.6 C 27.6,92.759 46.441,111.6 69.6,111.6 C 92.759,111.6 111.6,92.759 111.6,69.6 C 111.6,46.441 92.759,27.6 69.6,27.6 C 46.441,27.6 27.6,46.441 27.6,69.6 z" /> </clipPath> <linearGradient id="circle16776_1_" gradientUnits="userSpaceOnUse" x1="135.5601" y1="417.66461" x2="161.87621" y2="417.66461" gradientTransform="matrix(0,1.7280523,1.7280523,0,-650.07477,-218.71693)"> <stop offset="0" style="stop-color:#FFFFFF" id="stop3132" /> <stop offset="1" style="stop-color:#ffffff;stop-opacity:0;" id="stop3134" /> </linearGradient> <linearGradient id="XMLID_14_" gradientUnits="userSpaceOnUse" x1="27.6001" y1="69.600098" x2="111.6001" y2="69.600098" gradientTransform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)"> <stop offset="0" style="stop-color:#2A94EC" id="stop3122" /> <stop offset="1" style="stop-color:#0057AE" id="stop3124" /> </linearGradient> <radialGradient id="XMLID_13_" cx="69.600098" cy="69.600098" r="58" gradientUnits="userSpaceOnUse"> <stop offset="0.6154" style="stop-color:#EEEEEE" id="stop3113" /> <stop offset="0.8225" style="stop-color:#DDDDDD" id="stop3115" /> <stop offset="1" style="stop-color:#FFFFFF" id="stop3117" /> </radialGradient> <radialGradient id="XMLID_12_" cx="69.600098" cy="69.576698" r="58" gradientTransform="matrix(1,0,0,-0.1823,0,134.8566)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#000000" id="stop3102" /> <stop offset="1" style="stop-color:#000000;stop-opacity:0;" id="stop3104" /> </radialGradient> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 526.18109 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="744.09448 : 526.18109 : 1" inkscape:persp3d-origin="372.04724 : 350.78739 : 1" id="perspective10" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="radialGradient3478" gradientUnits="userSpaceOnUse" cx="69.600098" cy="69.600098" r="58" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.49497475" inkscape:cx="349.5625" inkscape:cy="255.71429" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33"> <inkscape:grid type="xygrid" id="grid2383" visible="true" enabled="true" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <ns:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </ns:Work> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-250,-427.42468)"> <text xml:space="preserve" style="font-size:144px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" x="276.26395" y="637.21143" id="text3484"><tspan sodipodi:role="line" id="tspan3486" x="276.26395" y="637.21143">00011</tspan></text> <text xml:space="preserve" style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" x="133.34013" y="268.37558" id="text3488" transform="translate(250,427.42468)"><tspan sodipodi:role="line" id="tspan3490" x="133.34013" y="268.37558" /></text> <text xml:space="preserve" style="font-size:144px" x="272.22336" y="776.61249" id="text3492"><tspan sodipodi:role="line" id="tspan3494" x="272.22336" y="776.61249">10101</tspan></text> </g> </svg> ������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/duplicate_first.svg��������������������������������������������������0000644�0001750�0000144�00000013153�11170303244�020420� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="640.71423" height="637.85712" id="svg2273" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" sodipodi:docname="duplicate_first.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2275" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="375" inkscape:cy="405.71429" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" showgrid="true" showguides="true" height="680px" width="680px" /> <metadata id="metadata2278"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-67.757143,-213.17646)"> <rect style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:22.264;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect2166" width="618.45062" height="615.59351" x="78.888954" y="224.30827" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" d="M 40,40 L 640,40" id="path2158" transform="translate(47.400002,191.39075)" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" d="M 40,200 L 640,200" id="path2160" transform="translate(47.400002,191.39075)" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" d="M 40,380 L 640,380" id="path2162" transform="translate(47.400002,191.39075)" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" d="M 87.900002,750.89075 L 687.9,750.89075" id="path2164" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" d="M 120,40 L 120,640" id="path4110" transform="translate(47.400002,191.39075)" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" d="M 520,40 L 520,640" id="path4112" transform="translate(47.400002,191.39075)" /> <g id="g3175" transform="matrix(0.5782789,0.8158392,-0.8158392,0.5782789,554.70924,732.43972)" style="fill:#3232b4;fill-opacity:1;stroke:#3232b4;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> <path id="path3160" d="M -142.64361,10.84735 L -142.64361,51.93415 L -72.056598,31.39075 L -142.64361,10.84735 z " style="fill:#3232b4;fill-opacity:1;fill-rule:evenodd;stroke:#3232b4;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path3162" d="M -515.91145,29.95981 L -141.07826,31.39075" style="fill:#3232b4;fill-opacity:1;fill-rule:evenodd;stroke:#3232b4;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" sodipodi:nodetypes="cc" /> </g> <g id="g3179" transform="matrix(0.6964802,0.7175761,-0.7175761,0.6964802,570.46839,548.13954)" style="fill:#3232b4;fill-opacity:1;stroke:#3232b4;stroke-width:19.99999809;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> <path style="fill:#3232b4;fill-opacity:1;fill-rule:evenodd;stroke:#3232b4;stroke-width:19.99999809;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M -142.64361,10.84735 L -142.64361,51.93415 L -72.056598,31.39075 L -142.64361,10.84735 z " id="path3181" /> <path style="fill:#3232b4;fill-opacity:1;fill-rule:evenodd;stroke:#3232b4;stroke-width:19.99999809;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M -390.86625,31.503754 L -141.07826,31.39075" id="path3183" sodipodi:nodetypes="cc" /> </g> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/edit-undo.svg��������������������������������������������������������0000644�0001750�0000144�00000106073�10737543470�017152� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2606" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docname="edit-undo.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" sodipodi:docbase="/home/david/oxygen/trunk/scalable/actions" inkscape:export-filename="edit-undo.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> <defs id="defs2608"> <linearGradient inkscape:collect="always" id="linearGradient3342"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3344" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3347" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3326"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3328" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3330" /> </linearGradient> <linearGradient id="linearGradient3825"> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="0" id="stop3827" /> <stop id="stop3833" offset="0.5" style="stop-color:#ffffff;stop-opacity:0.18705036;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop3829" /> </linearGradient> <linearGradient id="linearGradient3751"> <stop style="stop-color:#beba2c;stop-opacity:1;" offset="0" id="stop3753" /> <stop style="stop-color:#b6be2c;stop-opacity:0;" offset="1" id="stop3755" /> </linearGradient> <linearGradient id="linearGradient3528"> <stop style="stop-color:#eaf209;stop-opacity:1;" offset="0" id="stop3530" /> <stop style="stop-color:#c7c634;stop-opacity:0;" offset="1" id="stop3532" /> </linearGradient> <linearGradient id="linearGradient3295"> <stop style="stop-color:#fffe63;stop-opacity:1;" offset="0" id="stop3297" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3299" /> </linearGradient> <linearGradient id="linearGradient3202"> <stop style="stop-color:#fcff9c;stop-opacity:1;" offset="0" id="stop3204" /> <stop style="stop-color:#c1a965;stop-opacity:0;" offset="1" id="stop3206" /> </linearGradient> <radialGradient id="XMLID_4_" cx="48" cy="-0.2148" r="55.148" gradientTransform="matrix(0.9792,0,0,0.9725,133.0002,20.8762)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#cfd13d;stop-opacity:1;" id="stop3082" /> <stop offset="1" style="stop-color:#db8900;stop-opacity:1;" id="stop3090" /> </radialGradient> <linearGradient id="linearGradient3260" inkscape:collect="always"> <stop id="stop3262" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop3264" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3344"> <stop id="stop3346" offset="0" style="stop-color:#fdff63;stop-opacity:1;" /> <stop id="stop3348" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3449"> <stop id="stop3451" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop3453" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="linearGradient3516" x1="147.09375" y1="33.40625" x2="8.083992" y2="123.90625" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="radialGradient3524" cx="67.09375" cy="116.90625" fx="67.09375" fy="116.90625" r="56" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3528" id="radialGradient3535" cx="99.726295" cy="27.418272" fx="64.689766" fy="68.231934" r="56" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.693735,5.8671246e-2,-3.6242796e-2,0.4285387,33.939389,26.8809)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3548" x1="75.09375" y1="4.5317035" x2="75.09375" y2="80.172485" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3581" gradientUnits="userSpaceOnUse" gradientTransform="translate(4.2161108e-3,1.9705695e-3)" x1="75.09375" y1="4.5317035" x2="75.09375" y2="80.172485" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3613" x1="208.59375" y1="130.40625" x2="208.59375" y2="63.426777" gradientUnits="userSpaceOnUse" gradientTransform="translate(-137,0)" /> <filter inkscape:collect="always" id="filter3639"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.0580524" id="feGaussianBlur3641" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3654" cx="-10.165252" cy="66.906013" fx="-10.165252" fy="66.906013" r="59.995121" gradientTransform="matrix(0.4582893,-2.1035589e-8,4.5903973e-8,1.0000813,20.447953,-5.1974351e-3)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3658" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.2676699,0.521376,-0.7037472,0.3612977,108.99386,-36.062981)" cx="167.67001" cy="80.404922" fx="167.67001" fy="80.404922" r="59.995121" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3676" x1="120.0625" y1="12.569496" x2="125.30366" y2="14.444496" gradientUnits="userSpaceOnUse" spreadMethod="reflect" /> <filter inkscape:collect="always" x="-0.15096202" width="1.301924" y="-0.13732364" height="1.2746473" id="filter3738"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.39257441" id="feGaussianBlur3740" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3744" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.982366,1.671718e-2,-3.5801148e-3,0.2103843,-18.56344,30.477792)" cx="72.684891" cy="48.228905" fx="74.871155" fy="26.862719" r="59.995121" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3751" id="radialGradient3757" cx="66.01458" cy="126.69183" fx="66.01458" fy="126.69183" r="59.99512" gradientTransform="matrix(0.675025,0,0,0.3583625,19.527377,41.004647)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="radialGradient3767" cx="64.088867" cy="7.4108429" fx="64.088867" fy="7.4108429" r="59.995121" gradientTransform="matrix(0.3093869,0,0,0.4779247,44.260611,3.8644223)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3344" id="linearGradient3771" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="120.0625" y1="12.569496" x2="125.30366" y2="14.444496" /> <filter inkscape:collect="always" id="filter3438"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.3342697" id="feGaussianBlur3440" /> </filter> <filter inkscape:collect="always" id="filter3630"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.89883985" id="feGaussianBlur3632" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient2361" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2363" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2365" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2367" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3349" x1="-73" y1="105.625" x2="-163" y2="86.125" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" x="-0.087741371" width="1.1754827" y="-0.10211017" height="1.2042203" id="filter3363"> <feGaussianBlur inkscape:collect="always" stdDeviation="3.0526685" id="feGaussianBlur3365" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3372" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3376" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient3388" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3390" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3392" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3394" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3396" gradientUnits="userSpaceOnUse" x1="-73" y1="105.625" x2="-163" y2="86.125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3398" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3400" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient3422" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3424" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3426" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3428" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3430" gradientUnits="userSpaceOnUse" x1="-73" y1="105.625" x2="-163" y2="86.125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3432" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3434" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <mask maskUnits="userSpaceOnUse" id="mask3402"> <g id="g3404" transform="translate(167.50257,-3.755156e-3)"> <g id="g3406" transform="translate(80.51637,30.885255)"> <path style="opacity:1;fill:url(#radialGradient3422);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M -184.42232,-32.47243 C -217.54751,-32.47243 -248.42232,-0.097625 -248.42232,33.02757 C -248.42232,66.15276 -217.04751,97.02757 -183.92232,97.02757 C -153.6332,97.02757 -128.58571,70.81131 -124.51607,41.68382 L -159.54732,36.65257 C -161.172,48.6137 -171.47739,57.62132 -183.92232,57.62132 C -197.49395,57.62132 -206.01607,46.0992 -206.01607,32.52757 C -206.01607,18.955936 -199.99395,12.43382 -186.42232,12.43382 C -179.6365,12.433819 -176.50103,10.198864 -172.04732,14.65257 L -176.8745,25.979749 C -178.93037,28.035619 -179.11822,29.285529 -178.55411,30.595278 C -178.04554,31.776057 -177.03338,33.12132 -174.34438,33.12132 L -130.39107,33.12132 C -126.54518,33.12132 -123.93208,30.466941 -123.93208,26.871189 L -124.00095,-17.206829 C -124.00095,-19.687584 -124.90346,-21.050058 -126.18242,-21.556444 C -127.49674,-22.076829 -129.21563,-21.679122 -131.28951,-19.605244 L -141.48482,-19.40993 C -152.34417,-30.269281 -167.85972,-32.47243 -184.42232,-32.47243 z " id="path3408" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="ccccc" style="fill:url(#linearGradient3424);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" d="M -161.5,34.5 C -162,37 -180,54 -180,54 L -132.5,80 L -112,38.5 L -161.5,34.5 z " id="path3410" /> <path sodipodi:nodetypes="ccccc" id="path3412" d="M -161.5,34.5 C -162,37 -181.27817,54.389087 -181.27817,54.389087 L -151.62742,97.591883 L -112,38.5 L -161.5,34.5 z " style="fill:url(#linearGradient3426);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" /> <path style="fill:url(#linearGradient3428);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" d="M -161.5,34.5 C -162,37 -181.27817,54.389087 -181.27817,54.389087 L -151.62742,97.591883 L -112,38.5 L -161.5,34.5 z " id="path3414" sodipodi:nodetypes="ccccc" /> </g> <rect y="69.75" x="-119" height="71.75" width="83.5" id="rect3416" style="opacity:1;fill:url(#linearGradient3430);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" /> <path sodipodi:nodetypes="ccccc" id="path3418" d="M -159.5,68.25 L -39.138259,55.983708 L -93.453327,162.55286 L -197.79465,128.96507 L -159.5,68.25 z " style="fill:url(#linearGradient3432);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" transform="matrix(0.6393762,0.7688941,-0.7688941,0.6393762,37.597642,128.08723)" /> <path transform="matrix(0.6393762,0.7688941,-0.7688941,0.6393762,37.597642,128.08723)" style="fill:url(#linearGradient3434);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" d="M -159.5,68.25 L -39.138259,55.983708 L -93.453327,162.55286 L -197.79465,128.96507 L -159.5,68.25 z " id="path3420" sodipodi:nodetypes="ccccc" /> </g> </mask> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3751" id="linearGradient3565" x1="-267.47665" y1="18.103027" x2="-33.476654" y2="18.103027" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3567" gradientUnits="userSpaceOnUse" gradientTransform="translate(-137,0)" x1="208.59375" y1="130.40625" x2="208.59375" y2="63.426777" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="4.6484375" inkscape:cx="64" inkscape:cy="64" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" showgrid="false" inkscape:grid-points="true" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="748" inkscape:window-height="681" inkscape:window-x="526" inkscape:window-y="51" /> <metadata id="metadata2611"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1"> <g id="g3835" mask="url(#mask3402)" transform="matrix(-1,0,0,1,128.17774,0)"> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="rect3204" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:1;fill:url(#linearGradient3516);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:0.79775277;fill:url(#radialGradient3757);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " id="path3749" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="path3656" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:0.68913861;fill:url(#radialGradient3658);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:1;fill:url(#radialGradient3654);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " id="path3643" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="path3742" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:0.79775277;fill:url(#radialGradient3744);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:0.74531836;fill:url(#radialGradient3767);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3630)" d="M 64.09375,4.20625 C 30.968558,4.2062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,4.20625 64.09375,4.20625 z " id="path3759" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cccczc" id="path3660" d="M 117.6875,10.75 L 118.625,15.125 L 119.875,16 L 123.875,13.375 C 124.12188,11.651249 123.52383,10.027571 121.9375,9.3749999 C 120.35116,8.7224285 118.77622,9.5017032 117.6875,10.75 z " style="opacity:0.82022472;fill:url(#linearGradient3676);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3738)" /> <path transform="matrix(0,1,1,0,60.363582,-60.363586)" style="opacity:0.82022472;fill:url(#linearGradient3771);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3738)" d="M 117.6875,10.75 L 119.875,13.875 L 120.375,13.75 L 123.875,13.375 C 124.12188,11.651249 123.52383,10.027571 121.9375,9.3749999 C 120.35116,8.7224285 118.77622,9.5017032 117.6875,10.75 z " id="path3769" sodipodi:nodetypes="cccczc" /> <path id="path3494" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.0937501,94.867948 33.132054,119.90625 64.09375,119.90625 C 91.026646,119.90625 113.21548,101.0995 118.625,75.90625 L 91.5,72.03125 C 88.061436,83.928551 77.059621,92.5 64.09375,92.5 C 48.356404,92.499999 35.5,79.643599 35.5,63.90625 C 35.500001,48.168899 48.356402,35.3125 64.09375,35.3125 C 71.966166,35.312499 79.145304,38.520304 84.3125,43.6875 C 85.071964,44.438909 85.499997,45.462886 85.5,46.53125 C 85.5,47.599614 85.071964,48.623591 84.3125,49.375 L 73.6875,60 L 117.625,60 C 119.63039,60 120.09375,59.407836 120.09375,57.75 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " style="opacity:1;fill:url(#radialGradient3524);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:1;fill:url(#radialGradient3535);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.0937501,94.867948 33.132054,119.90625 64.09375,119.90625 C 91.026646,119.90625 113.21548,101.0995 118.625,75.90625 L 91.5,72.03125 C 88.061436,83.928551 77.059621,92.5 64.09375,92.5 C 48.356404,92.499999 35.5,79.643599 35.5,63.90625 C 35.500001,48.168899 48.356402,35.3125 64.09375,35.3125 C 71.966166,35.312499 79.145304,38.520304 84.3125,43.6875 C 85.071964,44.438909 85.499997,45.462886 85.5,46.53125 C 85.5,47.599614 85.071964,48.623591 84.3125,49.375 L 73.6875,60 L 117.625,60 C 119.63039,60 120.09375,59.407836 120.09375,57.75 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " id="path3526" /> <path sodipodi:nodetypes="csccssccccccscc" id="path3537" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.09375,64.474122 8.1082724,65.029981 8.125,65.59375 C 14.11447,66.271402 20.266218,66.74388 26.53125,67 C 26.260548,56.540958 30.202859,46.025084 38.34375,38.21875 C 53.683067,23.509813 78.072313,24.004431 92.78125,39.34375 C 95.545099,42.226046 97.537852,45.032117 99.34375,48.59375 L 78.84375,59 L 98,59 C 105.9282,56.973373 113.18621,55.563033 120.09375,52.8125 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " style="opacity:1;fill:url(#linearGradient3548);fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path sodipodi:nodetypes="cscscscccccccccccssssssccscscc" id="path3553" d="M 64.099866,7.9087646 C 33.138176,7.9087644 8.0998661,32.947063 8.0998661,63.908764 C 8.0998761,64.087476 8.0973761,64.263059 8.0998661,64.440014 C 8.3531061,33.696509 33.295846,8.9087645 64.099866,8.9087646 C 79.583236,8.9087645 93.555946,15.177347 103.69361,25.315014 C 104.44503,26.074479 105.469,26.502514 106.53736,26.502514 C 107.60573,26.502515 108.6297,26.074478 109.38111,25.315014 L 119.50611,15.158764 L 119.99986,52.708764 C 113.09232,55.459294 105.43431,56.569624 97.506116,58.596264 L 78.849866,59.002514 L 98.006116,59.002514 C 105.93431,56.975884 113.19232,55.565544 120.09986,52.815014 L 120.00611,14.658764 L 120.00611,13.658764 L 119.50611,14.158764 L 109.38111,24.315014 C 108.62971,25.074479 107.60572,25.502514 106.53736,25.502514 C 105.46901,25.502515 104.44502,25.074478 103.69361,24.315014 C 103.68314,24.304548 103.67283,24.294222 103.66236,24.283764 C 103.60999,24.231473 103.55869,24.179598 103.50611,24.127514 C 102.93231,23.559643 102.35524,23.012364 101.75611,22.471264 C 101.67459,22.397145 101.58807,22.326157 101.50611,22.252514 C 91.590066,13.342335 78.496526,7.9087646 64.099866,7.9087646 z M 63.443616,27.127514 C 54.205446,27.378034 45.040176,30.920194 37.849866,37.815014 C 30.217786,45.133448 26.722316,55.187931 26.537366,65.033764 C 26.777246,55.231884 30.717786,45.539698 38.349866,38.221264 C 51.665996,25.452364 71.803196,24.123207 86.506116,34.033764 C 79.627056,29.22869 71.518656,26.908534 63.443616,27.127514 z " style="opacity:1;fill:url(#linearGradient3581);fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path id="path3603" d="M 63.59375,7.90625 C 32.63205,7.9062499 7.59375,32.944549 7.59375,63.90625 C 7.59375,94.867948 32.63205,119.90625 63.59375,119.90625 C 90.52665,119.90625 112.71548,101.0995 118.125,75.90625 L 91,72.03125 C 87.56144,83.928551 76.55962,92.5 63.59375,92.5 C 47.8564,92.499999 35,79.643599 35,63.90625 C 35,48.168899 47.8564,35.3125 63.59375,35.3125 C 71.46617,35.312499 78.6453,38.520304 83.8125,43.6875 C 84.57196,44.438909 85,45.462886 85,46.53125 C 85,47.599614 84.57196,48.623591 83.8125,49.375 L 73.1875,60 L 117.125,60 C 119.13039,60 119.59375,59.407836 119.59375,57.75 L 119.5,13.65625 L 108.875,24.3125 C 108.12359,25.071964 107.09961,25.5 106.03125,25.5 C 104.96289,25.5 103.93891,25.071964 103.1875,24.3125 C 93.04984,14.174833 79.07711,7.90625 63.59375,7.90625 z " style="opacity:1;fill:none;fill-opacity:1;stroke:url(#linearGradient3567);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3639)" /> </g> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/va_va.svg������������������������������������������������������������0000644�0001750�0000144�00000015577�11257112456�016360� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="250" height="250" id="svg2260" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images/work" sodipodi:docname="va_va.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs2262"> <linearGradient inkscape:collect="always" id="linearGradient9739"> <stop style="stop-color:#494949;stop-opacity:1" offset="0" id="stop9741" /> <stop style="stop-color:#000000;stop-opacity:1" offset="1" id="stop9743" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient9739" id="linearGradient9745" x1="56.941498" y1="5.3460956" x2="57.352737" y2="125.73909" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1202075,0,0,1.1783429,4.601e-2,-4.036e-2)" /> <linearGradient inkscape:collect="always" id="linearGradient9691"> <stop style="stop-color:#323232;stop-opacity:1;" offset="0" id="stop9693" /> <stop style="stop-color:#000000;stop-opacity:1" offset="1" id="stop9695" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient9691" id="linearGradient2194" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.988046,0,0,0.9880485,-153.7676,46.44591)" x1="66.397873" y1="5.9613037" x2="66.603661" y2="129.03691" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient9691" id="linearGradient2407" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.988046,0,0,0.9880485,-429.19272,311.33612)" x1="66.397873" y1="5.9613037" x2="66.603661" y2="129.03691" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient9739" id="linearGradient2410" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1202075,0,0,1.1783429,4.601e-2,-4.036e-2)" x1="56.941498" y1="5.3460956" x2="57.352737" y2="125.73909" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient9691" id="linearGradient2416" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.988046,0,0,0.9880485,-429.19272,311.33612)" x1="66.397873" y1="5.9613037" x2="66.603661" y2="129.03691" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient9739" id="linearGradient2418" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1202075,0,0,1.1783429,4.601e-2,-4.036e-2)" x1="56.941498" y1="5.3460956" x2="57.352737" y2="125.73909" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8" inkscape:cx="6.3580641" inkscape:cy="115.42461" inkscape:document-units="px" inkscape:current-layer="layer1" width="250px" height="250px" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" /> <metadata id="metadata2265"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(536.13407,-293.46698)"> <g id="g2412" transform="translate(4.6428572,65.714286)"> <path id="path2375" d="M -365.83137,311.42146 C -372.33126,311.5045 -379.86406,316.187 -381.76887,325.57771 C -396.80191,325.11799 -403.51929,345.74954 -404.76887,359.79646 C -406.35643,377.64295 -393.7585,390.06537 -381.33137,394.89021 C -381.51244,396.91573 -381.76714,398.79395 -382.58137,399.70271 C -387.76298,405.4859 -391.8507,405.84981 -401.01887,408.45271 C -411.24729,411.35662 -419.36338,414.19464 -425.23762,419.35896 C -429.68527,423.26911 -432.7762,427.67245 -433.58137,433.10896 L -297.92512,433.10896 C -298.73029,427.67245 -301.82121,423.2691 -306.26887,419.35896 C -312.07787,414.252 -320.19344,411.25029 -330.48762,408.32771 C -339.72369,405.70555 -346.76916,402.7275 -348.36262,398.48396 C -349.53927,395.35039 -350.00797,389.57721 -350.08137,386.89021 C -335.928,384.86186 -327.08137,376.4003 -327.08137,361.67146 C -327.08137,337.71405 -346.33169,311.17234 -365.83137,311.42146 z " style="fill:url(#linearGradient2416);fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path3295" transform="translate(-536.13941,293.46164)" d="M 69.4375,1.375 C 60.338217,1.98404 53.52651,6.07068 48.78125,14.15625 C 47.714509,15.97391 47.5398,17.22896 47.15625,19.09375 C 46.772731,20.958551 46.47369,23.21195 46.28125,25.65625 C 45.906609,30.414601 45.83105,35.53589 46.125,41.375 C 46.713331,53.062861 45.03414,60.30348 49.25,66.59375 C 57.473921,78.864171 55.30902,87.02001 53.4375,93 C 51.93936,97.787002 43.05044,104.6596 33.9375,107.5625 C 23.77068,110.80111 12.94755,114.19028 9.875,116.3125 C 3.9513998,120.40394 1.375,126.91614 1.375,134.46875 L 1.375,139.28125 L 141.03125,139.28125 L 141.03125,134.46875 C 141.03127,126.91613 137.23169,125.03648 132.0625,119.9375 C 126.28851,114.24191 118.48217,111.13442 108.25,107.875 C 99.069556,104.95059 91.51015,97.35272 89.21875,93 C 87.347223,89.444892 86.07863,79.09314 90.375,71.1875 C 94.004527,64.508887 98.34375,57.43958 98.34375,41.375 C 98.343753,35.527701 98.56212,30.41459 98.1875,25.65625 C 97.995066,23.211951 97.69604,20.95855 97.3125,19.09375 C 96.928978,17.228961 96.78548,15.97391 95.71875,14.15625 C 90.996979,6.1107398 82.0783,1.375 72.6875,1.375 L 69.75,1.375 L 69.59375,1.375 L 69.4375,1.375 z " style="fill:url(#linearGradient2418);fill-opacity:1;stroke:#000000;stroke-width:2.73932219;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/musicbrainz_logo1.svg������������������������������������������������0000644�0001750�0000144�00000113775�11163125541�020705� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="171" height="117.83302" id="svg2456" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" sodipodi:docname="musicbrainz_logo1.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2458" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.959798" inkscape:cx="103.73576" inkscape:cy="96.628015" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" height="173px" width="173px" /> <metadata id="metadata2461"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-252.90555,-356.05028)"> <path d="M 337.64155,383.47228 L 337.64155,450.75928 L 385.40655,450.75928 C 385.40655,450.75928 389.40655,439.83728 389.40655,436.45228 C 389.40655,433.06928 389.40655,426.90528 389.40655,426.90528 C 389.40655,426.90528 391.07255,422.16928 391.07255,416.07728 C 391.07255,409.98728 388.84155,398.48328 383.42655,396.45228 C 383.42655,396.45228 367.86255,375.47328 349.59055,378.18128 C 349.59055,378.18128 338.55155,377.93428 337.64155,383.47228 z " id="path3" style="fill:#ffba58" /> <g transform="translate(209.84255,172.16228)" id="g5"> <path d="M 180.977,254.474 C 180.758,257.619 181.196,264.357 180.539,266.38 C 179.883,268.4 178.131,274.241 177.258,276.263 C 176.951,276.972 176.674,277.82 176.391,278.704 L 174.387,278.587 C 174.514,278.257 174.657,277.931 174.85,277.61 C 175.944,275.815 175.727,273.118 175.727,273.118 C 175.727,273.118 177.915,266.604 178.35,264.583 C 178.789,262.562 177.696,256.944 177.914,255.37 C 178.135,253.8 178.789,252.899 179.883,249.755 C 180.977,246.609 179.444,242.792 179.227,241.442 C 179.008,240.096 178.571,235.153 178.131,233.805 C 177.695,232.455 175.07,228.412 174.904,227.457 C 174.74,226.502 170.494,225.32 170.494,225.32 C 170.273,223.074 168.943,221.447 168.943,221.447 C 168.943,219.201 161.285,212.91 161.285,212.91 C 158.879,211.113 147.939,207.295 145.096,206.619 C 142.249,205.947 140.718,207.744 140.718,207.744 C 136.997,205.947 133.716,207.744 131.529,209.092 C 129.342,210.44 129.123,212.686 129.123,212.686 C 127.809,214.26 128.029,210.665 128.029,210.665 C 128.029,210.665 128.902,206.173 132.185,205.05 C 135.466,203.925 140.937,204.599 140.937,204.599 C 148.377,203.029 160.192,208.869 163.694,211.564 C 167.194,214.261 174.85,223.919 174.85,223.919 C 174.85,223.919 177.258,225.942 179.444,230.659 C 181.633,235.378 182.071,245.487 181.852,247.509 C 181.633,249.531 181.195,251.327 180.977,254.474 z " id="path7" /> <g id="g9"> <path d="M 148.453,210.265 C 147.818,209.177 145.283,211.351 143.382,211.351 C 141.48,211.351 137.993,210.046 135.773,210.482 C 133.554,210.918 130.701,212.658 130.068,214.179 C 129.433,215.7 131.019,221.355 132.922,221.79 C 132.922,221.79 129.75,225.27 131.334,226.575 C 132.922,227.88 133.555,226.575 133.555,225.923 C 133.555,225.271 133.237,223.53 134.506,223.095 C 135.774,222.661 137.36,221.138 137.36,221.138 C 137.36,221.138 134.823,221.138 133.555,219.833 C 132.285,218.528 132.92,216.136 133.555,215.048 C 134.188,213.96 135.772,212.003 137.36,212.003 C 138.944,212.003 142.114,213.308 144.336,213.091 C 146.551,212.874 149.088,211.353 148.453,210.265 z " id="path11" /> <path d="M 153.525,216.571 C 153.525,216.571 157.011,220.485 153.525,225.051 C 150.039,229.619 150.355,227.662 150.355,227.662 L 151.623,229.402 C 151.623,229.402 154.158,225.705 156.379,225.922 C 158.598,226.139 161.451,228.096 162.402,231.36 C 163.353,234.622 161.134,237.233 158.281,237.667 C 155.427,238.103 144.648,237.015 144.648,237.015 C 144.648,237.015 145.601,237.667 145.283,238.755 C 144.967,239.841 144.334,241.148 144.334,241.148 C 144.334,241.148 146.869,238.972 153.209,239.189 C 159.549,239.408 161.77,240.494 164.305,244.627 C 166.84,248.76 165.254,254.848 163.987,256.371 C 162.72,257.894 157.012,258.33 156.38,259.851 C 155.748,261.372 157.648,262.896 157.966,263.982 C 158.282,265.07 157.015,265.941 157.015,265.941 C 157.015,265.941 160.501,264.418 163.036,264.636 C 165.573,264.853 170.329,267.245 170.329,267.245 C 170.329,267.245 169.376,267.681 169.694,268.333 C 170.012,268.985 170.645,269.638 170.329,270.29 C 170.013,270.942 169.061,271.376 169.061,271.376 C 169.061,271.376 170.645,271.595 171.596,270.29 C 172.547,268.985 170.645,268.767 171.28,268.114 C 171.913,267.462 173.182,267.68 173.182,267.68 C 173.182,267.68 172.229,267.461 170.645,265.504 C 169.061,263.547 168.426,262.459 166.207,262.459 C 163.986,262.459 161.451,262.676 161.451,262.676 C 161.451,262.676 159.232,261.807 160.183,260.502 C 161.134,259.197 168.425,258.326 168.425,258.326 C 168.425,258.326 166.206,257.021 166.206,255.935 C 166.206,254.847 167.79,252.671 170.644,251.15 C 173.498,249.627 175.716,247.234 175.716,242.668 C 175.716,238.102 176.925,237.061 178.825,235.32 L 178.159,232.32 C 178.159,232.32 176.35,236.361 174.448,237.666 L 169.692,235.49 C 169.692,235.49 170.643,238.318 173.18,239.406 C 173.18,239.406 175.08,243.103 173.496,245.713 C 171.91,248.322 167.789,250.279 167.789,250.279 C 167.789,250.279 166.521,243.972 165.887,242.668 C 165.254,241.363 163.985,240.059 163.668,239.188 C 163.352,238.319 165.572,232.881 165.254,231.141 C 164.936,229.403 162.4,224.182 157.645,223.746 C 157.646,223.747 157.012,216.136 153.525,216.571 z " id="path13" /> <path d="M 146.551,227.444 C 146.551,227.444 149.088,226.794 151.307,227.88 C 153.526,228.968 155.112,232.23 153.209,233.97 C 153.209,233.97 152.258,234.622 151.307,233.534 C 151.307,233.534 151.623,228.968 149.721,228.532 C 147.819,228.096 146.551,227.444 146.551,227.444 z " id="path15" /> <path d="M 149.088,221.573 C 149.088,221.573 145.602,220.052 142.431,220.921 C 139.261,221.79 137.359,225.704 137.359,225.704 C 137.359,225.704 135.773,222.878 138.627,220.704 C 141.481,218.528 146.235,219.833 148.454,220.052 C 150.672,220.269 150.99,220.485 149.088,221.573 z " id="path17" /> <path d="M 144.967,219.833 C 144.967,219.833 144.016,218.093 145.283,217.659 C 146.551,217.223 148.137,216.788 147.502,216.136 C 146.869,215.484 143.699,216.788 142.747,218.745 C 141.796,220.704 141.796,220.704 141.796,220.704 L 144.967,219.833 z " id="path19" /> <path d="M 142.431,228.751 C 142.431,228.751 136.408,234.187 136.408,239.841 C 136.408,245.497 139.262,250.064 141.48,250.064 C 143.7,250.064 143.702,248.107 145.284,248.541 C 146.87,248.977 149.089,250.936 146.87,251.369 C 144.649,251.805 142.432,252.674 140.529,251.805 C 138.627,250.934 136.408,249.846 135.138,247.889 C 133.872,245.932 134.189,241.801 133.872,239.625 C 133.554,237.449 137.673,229.838 139.261,228.752 C 140.845,227.663 142.431,226.792 142.431,228.751 z " id="path21" /> <path d="M 156.063,246.149 C 156.063,246.149 153.526,245.713 152.575,244.626 C 151.624,243.54 151.309,244.845 151.942,247.019 C 152.575,249.193 152.893,252.673 152.258,254.197 C 151.623,255.718 148.77,259.851 144.967,259.416 C 141.161,258.98 139.894,257.895 138.943,256.59 C 137.992,255.283 136.091,255.067 135.773,256.371 C 135.457,257.676 136.722,259.199 137.359,260.068 C 137.992,260.937 137.675,260.937 139.578,261.589 C 141.48,262.243 145.284,263.112 148.454,262.025 C 151.624,260.938 154.477,256.154 154.477,254.63 C 154.477,253.108 155.111,248.323 156.063,246.149 z " id="path23" /> </g> <path d="M 178.826,265.321 C 178.826,265.321 178.482,257.077 176.148,255.411 C 173.814,253.745 173.14,253.993 173.068,253.274 C 173.013,252.719 172.959,252.526 174.623,252.581 C 175.955,252.626 179.494,254.987 179.494,254.987 L 178.826,265.321 z " id="path25" /> <path d="M 151.16,207.987 C 151.16,207.987 154.16,208.987 153.494,210.653 C 152.826,212.321 152.828,212.987 154.16,212.987 C 155.494,212.987 156.16,210.987 157.826,211.653 C 159.494,212.321 158.16,214.987 159.826,215.321 C 161.494,215.653 162.16,215.319 163.16,215.653 C 164.16,215.987 167.826,218.653 167.494,219.987 C 167.16,221.319 163.826,217.987 162.826,218.653 C 161.826,219.321 160.16,220.319 161.494,220.987 C 162.826,221.653 166.826,221.653 168.494,223.321 C 170.16,224.987 170.586,225.934 171.494,224.987 C 172.443,223.993 169.494,217.987 167.494,216.321 C 165.494,214.653 154.494,207.319 151.16,207.987 z " id="path27" /> <path d="M 172.324,236.685 C 172.324,236.685 174.013,237.39 174.529,237.203 C 175.047,237.014 176.359,235.842 177.017,234.574 C 177.673,233.306 177.392,232.32 177.111,231.664 L 178.519,233.072 L 179.271,238.187 L 178.847,237.812 C 178.847,237.812 178.706,236.544 178.238,236.591 C 177.77,236.638 176.736,237.53 176.736,237.53 L 173.732,237.952 L 172.277,237.106 L 172.324,236.685 z " id="path29" /> <path d="M 176.592,253.274 C 176.592,253.274 177.647,253.829 178.117,253.608 C 178.59,253.385 178.783,252.608 178.783,252.608 L 178.367,254.717 L 177.258,254.717 L 176.592,253.274 z " id="path31" /> <path d="M 137.493,255.821 C 136.624,256.342 135.8,256.751 135.968,257.251 C 136.134,257.751 137.493,270.987 143.494,271.321 C 149.494,271.653 154.66,269.821 157.66,271.821 C 160.66,273.821 157.326,275.653 157.326,275.653 C 157.326,275.653 156.992,277.987 159.66,276.153 C 159.66,276.153 160.492,276.653 160.66,276.153 C 160.826,275.653 160.994,272.155 159.494,271.321 C 157.994,270.487 155.826,269.821 154.826,269.153 C 153.826,268.487 146.99,269.913 145.156,269.585 C 141.313,268.894 141.577,265.556 140.077,263.056 C 138.577,260.556 138.325,255.321 137.493,255.821 z " id="path33" /> <path d="M 176.826,269.653 C 176.826,269.653 175.494,273.321 173.494,273.321 C 173.494,273.321 176.16,274.321 175.826,275.653 C 175.494,276.987 176.826,269.653 176.826,269.653 z " id="path35" /> <path d="M 159.326,274.999 C 159.326,274.999 162.248,274.106 164.58,274.202 C 166.914,274.296 167.918,276.288 167.918,276.288 C 167.918,276.288 165.486,275.302 164.16,275.321 C 162.832,275.341 160.484,276.344 160.484,276.344 L 159.326,274.999 z " id="path37" /> <path d="M 144.059,275.64 C 144.059,275.64 142.511,272.466 139.511,272.279 C 136.511,272.092 136.952,272.072 135.952,271.884 C 134.952,271.696 133.368,268.466 132.306,268.216 C 131.244,267.966 130.868,267.591 130.431,267.778 C 129.994,267.965 130.243,268.466 130.494,268.591 C 130.745,268.716 131.682,268.841 132.119,269.091 C 132.556,269.341 133.369,271.966 135.119,272.779 C 136.869,273.592 138.23,273.674 138.918,273.861 C 139.606,274.048 141.811,275.256 142.873,276.631 C 142.872,276.63 144.455,277.222 144.059,275.64 z " id="path39" /> </g> <path d="M 338.20255,383.47228 L 338.20255,450.75928 L 291.03455,450.75928 C 291.03455,450.75928 286.33655,439.71628 286.33655,436.33128 C 286.33655,432.94828 286.28755,426.90528 286.28755,426.90528 C 286.28755,426.90528 284.93355,422.16928 284.93355,416.07728 C 284.93355,409.98728 288.31755,398.48328 293.73155,396.45228 C 293.73155,396.45228 309.29655,375.47328 327.56755,378.18128 C 327.56855,378.18128 338.60855,377.93428 338.20255,383.47228 z " id="path41" style="fill:#736dab" /> <path d="M 333.89955,421.74328 C 335.38855,420.99528 336.23255,422.74328 338.23255,422.74328 C 340.23255,422.74328 342.56555,420.40928 343.56555,421.74128 C 344.56555,423.07528 343.89855,421.74128 343.56555,423.40928 C 343.23255,425.07528 340.46155,425.72028 338.23255,425.74328 C 336.12455,425.76428 335.23155,425.40928 333.56555,423.40928 C 331.89955,421.40928 333.23355,422.07728 333.89955,421.74328 z " id="path43" /> <path d="M 334.73255,403.74328 C 334.73255,403.74328 335.89955,402.40928 338.23255,402.40928 C 340.56555,402.40928 342.06555,404.24328 342.73255,404.24328 C 343.39955,404.24328 344.06555,403.90928 344.06555,403.90928 C 344.06555,403.90928 344.06655,402.07728 343.39955,401.74328 C 342.73255,401.40928 339.89955,400.74328 338.39955,400.74328 C 336.89955,400.74328 334.39855,401.74128 333.56555,401.90928 C 332.73255,402.07528 331.89855,403.24328 332.56555,403.74328 C 333.23255,404.24328 334.73255,403.74328 334.73255,403.74328 z " id="path45" /> <g transform="translate(209.84255,172.16228)" id="g47"> <path d="M 75.906,254.474 C 76.126,257.619 75.687,264.357 76.344,266.38 C 77,268.4 78.752,274.241 79.626,276.263 C 79.932,276.972 80.21,277.82 80.492,278.704 L 82.497,278.587 C 82.37,278.257 82.227,277.931 82.033,277.61 C 80.939,275.815 81.157,273.118 81.157,273.118 C 81.157,273.118 78.969,266.604 78.533,264.583 C 78.095,262.562 79.188,256.944 78.97,255.37 C 78.749,253.8 78.095,252.899 77,249.755 C 75.906,246.609 77.439,242.792 77.656,241.442 C 77.876,240.096 78.312,235.153 78.752,233.805 C 79.189,232.455 81.814,228.412 81.979,227.457 C 82.144,226.502 86.39,225.32 86.39,225.32 C 86.61,223.074 87.941,221.447 87.941,221.447 C 87.941,219.201 95.598,212.91 95.598,212.91 C 98.005,211.113 108.945,207.295 111.788,206.619 C 114.634,205.947 116.165,207.744 116.165,207.744 C 119.885,205.947 123.166,207.744 125.354,209.092 C 127.542,210.44 127.759,212.686 127.759,212.686 C 129.073,214.26 128.854,210.665 128.854,210.665 C 128.854,210.665 127.98,206.173 124.697,205.05 C 121.416,203.925 115.945,204.599 115.945,204.599 C 108.507,203.029 96.691,208.869 93.19,211.564 C 89.69,214.261 82.033,223.919 82.033,223.919 C 82.033,223.919 79.626,225.942 77.439,230.659 C 75.25,235.378 74.812,245.487 75.031,247.509 C 75.25,249.531 75.688,251.327 75.906,254.474 z " id="path49" /> <g id="g51"> <path d="M 108.43,210.265 C 109.065,209.177 111.6,211.351 113.501,211.351 C 115.403,211.351 118.89,210.046 121.109,210.482 C 123.328,210.918 126.182,212.658 126.815,214.179 C 127.45,215.7 125.864,221.355 123.961,221.79 C 123.961,221.79 127.133,225.27 125.548,226.575 C 123.961,227.88 123.328,226.575 123.328,225.923 C 123.328,225.271 123.645,223.53 122.377,223.095 C 121.108,222.661 119.523,221.138 119.523,221.138 C 119.523,221.138 122.06,221.138 123.328,219.833 C 124.597,218.528 123.963,216.136 123.328,215.048 C 122.695,213.96 121.11,212.003 119.523,212.003 C 117.939,212.003 114.768,213.308 112.548,213.091 C 110.332,212.874 107.795,211.353 108.43,210.265 z " id="path53" /> <path d="M 103.357,216.571 C 103.357,216.571 99.871,220.485 103.357,225.051 C 106.843,229.619 106.527,227.662 106.527,227.662 L 105.259,229.402 C 105.259,229.402 102.724,225.705 100.503,225.922 C 98.284,226.139 95.431,228.096 94.48,231.36 C 93.529,234.622 95.749,237.233 98.602,237.667 C 101.455,238.103 112.234,237.015 112.234,237.015 C 112.234,237.015 111.281,237.667 111.599,238.755 C 111.915,239.841 112.549,241.148 112.549,241.148 C 112.549,241.148 110.014,238.972 103.673,239.189 C 97.333,239.408 95.112,240.494 92.577,244.627 C 90.042,248.76 91.628,254.848 92.895,256.371 C 94.162,257.894 99.87,258.33 100.502,259.851 C 101.136,261.372 99.234,262.896 98.917,263.982 C 98.601,265.07 99.868,265.941 99.868,265.941 C 99.868,265.941 96.381,264.418 93.846,264.636 C 91.309,264.853 86.554,267.245 86.554,267.245 C 86.554,267.245 87.506,267.681 87.188,268.333 C 86.871,268.985 86.237,269.638 86.554,270.29 C 86.87,270.942 87.822,271.376 87.822,271.376 C 87.822,271.376 86.237,271.595 85.286,270.29 C 84.335,268.985 86.237,268.767 85.603,268.114 C 84.969,267.461 83.701,267.68 83.701,267.68 C 83.701,267.68 84.653,267.461 86.237,265.504 C 87.822,263.547 88.456,262.459 90.675,262.459 C 92.896,262.459 95.431,262.676 95.431,262.676 C 95.431,262.676 97.651,261.807 96.7,260.502 C 95.749,259.197 88.457,258.326 88.457,258.326 C 88.457,258.326 90.676,257.021 90.676,255.935 C 90.676,254.847 89.092,252.671 86.238,251.15 C 83.385,249.627 81.166,247.234 81.166,242.668 C 81.166,238.102 79.958,237.061 78.057,235.32 L 78.723,232.32 C 78.723,232.32 80.533,236.361 82.435,237.666 L 87.19,235.49 C 87.19,235.49 86.239,238.318 83.703,239.406 C 83.703,239.406 81.802,243.103 83.387,245.713 C 84.972,248.323 89.093,250.279 89.093,250.279 C 89.093,250.279 90.362,243.972 90.995,242.668 C 91.628,241.363 92.897,240.059 93.214,239.188 C 93.53,238.319 91.311,232.881 91.628,231.141 C 91.946,229.403 94.482,224.182 99.237,223.746 C 99.236,223.747 99.871,216.136 103.357,216.571 z " id="path55" /> <path d="M 110.332,227.444 C 110.332,227.444 107.795,226.794 105.576,227.88 C 103.357,228.968 101.771,232.23 103.674,233.97 C 103.674,233.97 104.625,234.622 105.576,233.534 C 105.576,233.534 105.26,228.968 107.162,228.532 C 109.064,228.096 110.332,227.444 110.332,227.444 z " id="path57" /> <path d="M 107.795,221.573 C 107.795,221.573 111.281,220.052 114.452,220.921 C 117.622,221.79 119.524,225.704 119.524,225.704 C 119.524,225.704 121.109,222.878 118.256,220.704 C 115.402,218.528 110.648,219.833 108.429,220.052 C 106.211,220.269 105.893,220.485 107.795,221.573 z " id="path59" /> <path d="M 111.916,219.833 C 111.916,219.833 112.868,218.093 111.6,217.659 C 110.332,217.223 108.746,216.788 109.381,216.136 C 110.015,215.484 113.185,216.788 114.136,218.745 C 115.087,220.704 115.087,220.704 115.087,220.704 L 111.916,219.833 z " id="path61" /> <path d="M 114.452,228.751 C 114.452,228.751 120.475,234.187 120.475,239.841 C 120.475,245.497 117.621,250.064 115.403,250.064 C 113.185,250.064 113.182,248.107 111.599,248.541 C 110.014,248.977 107.795,250.936 110.014,251.369 C 112.234,251.805 114.452,252.674 116.354,251.805 C 118.256,250.934 120.475,249.846 121.745,247.889 C 123.011,245.932 122.694,241.801 123.011,239.625 C 123.329,237.449 119.209,229.838 117.622,228.752 C 116.038,227.663 114.452,226.792 114.452,228.751 z " id="path63" /> <path d="M 100.821,246.149 C 100.821,246.149 103.357,245.713 104.308,244.626 C 105.259,243.54 105.575,244.845 104.941,247.019 C 104.308,249.193 103.991,252.673 104.625,254.197 C 105.26,255.718 108.113,259.851 111.916,259.416 C 115.721,258.98 116.989,257.895 117.94,256.59 C 118.891,255.283 120.792,255.067 121.109,256.371 C 121.426,257.675 120.16,259.199 119.524,260.068 C 118.891,260.937 119.207,260.937 117.305,261.589 C 115.403,262.243 111.599,263.112 108.429,262.025 C 105.259,260.938 102.406,256.154 102.406,254.63 C 102.406,253.108 101.771,248.323 100.821,246.149 z " id="path65" /> </g> <path d="M 78.057,265.321 C 78.057,265.321 78.402,257.077 80.735,255.411 C 83.069,253.745 83.743,253.993 83.815,253.274 C 83.87,252.719 83.925,252.526 82.261,252.581 C 80.928,252.626 77.39,254.987 77.39,254.987 L 78.057,265.321 z " id="path67" /> <path d="M 105.723,207.987 C 105.723,207.987 102.723,208.987 103.39,210.653 C 104.057,212.321 104.056,212.987 102.723,212.987 C 101.39,212.987 100.723,210.987 99.057,211.653 C 97.39,212.321 98.723,214.987 97.057,215.321 C 95.39,215.653 94.723,215.319 93.723,215.653 C 92.723,215.987 89.057,218.653 89.39,219.987 C 89.723,221.319 93.057,217.987 94.057,218.653 C 95.057,219.321 96.723,220.319 95.39,220.987 C 94.057,221.653 90.057,221.653 88.39,223.321 C 86.723,224.987 86.297,225.934 85.39,224.987 C 84.44,223.993 87.39,217.987 89.39,216.321 C 91.39,214.653 102.389,207.319 105.723,207.987 z " id="path69" /> <path d="M 84.56,236.685 C 84.56,236.685 82.871,237.39 82.354,237.203 C 81.837,237.014 80.524,235.842 79.866,234.574 C 79.21,233.306 79.491,232.32 79.772,231.664 L 78.364,233.072 L 77.613,238.187 L 78.036,237.812 C 78.036,237.812 78.177,236.544 78.645,236.591 C 79.115,236.638 80.147,237.53 80.147,237.53 L 83.152,237.952 L 84.607,237.106 L 84.56,236.685 z " id="path71" /> <path d="M 80.291,253.274 C 80.291,253.274 79.237,253.829 78.766,253.608 C 78.294,253.385 78.1,252.608 78.1,252.608 L 78.516,254.717 L 79.625,254.717 L 80.291,253.274 z " id="path73" /> <path d="M 119.39,255.821 C 120.259,256.342 121.082,256.751 120.915,257.251 C 120.748,257.751 119.39,270.987 113.39,271.321 C 107.39,271.653 102.223,269.821 99.223,271.821 C 96.223,273.821 99.557,275.653 99.557,275.653 C 99.557,275.653 99.891,277.987 97.223,276.153 C 97.223,276.153 96.391,276.653 96.223,276.153 C 96.057,275.653 95.89,272.155 97.39,271.321 C 98.89,270.487 101.057,269.821 102.057,269.153 C 103.057,268.487 109.893,269.913 111.727,269.585 C 115.57,268.894 115.305,265.556 116.805,263.056 C 118.305,260.556 118.557,255.321 119.39,255.821 z " id="path75" /> <path d="M 80.057,269.653 C 80.057,269.653 81.39,273.321 83.39,273.321 C 83.39,273.321 80.723,274.321 81.057,275.653 C 81.39,276.987 80.057,269.653 80.057,269.653 z " id="path77" /> <path d="M 112.824,275.64 C 112.824,275.64 114.372,272.466 117.372,272.279 C 120.372,272.092 119.931,272.072 120.931,271.884 C 121.931,271.696 123.515,268.466 124.577,268.216 C 125.639,267.966 126.015,267.591 126.452,267.778 C 126.889,267.965 126.64,268.466 126.389,268.591 C 126.138,268.716 125.201,268.841 124.764,269.091 C 124.327,269.341 123.514,271.966 121.764,272.779 C 120.014,273.592 118.652,273.674 117.964,273.861 C 117.276,274.048 115.072,275.256 114.01,276.631 C 114.011,276.63 112.429,277.222 112.824,275.64 z " id="path79" /> </g> <path d="M 301.00955,364.05028 L 292.05155,367.06628 L 291.98955,376.36928 C 291.69555,376.33328 291.37355,376.34228 291.03555,376.40328 C 289.66955,376.65428 288.56255,377.66328 288.56255,378.65728 C 288.56255,379.65028 289.66855,380.25328 291.03555,380.00428 C 292.39855,379.75428 293.50455,378.74528 293.50455,377.75228 C 293.50455,377.71628 293.49255,377.68428 293.48955,377.64828 L 293.48955,369.82228 L 299.50755,367.79328 L 299.50755,373.74728 C 299.20855,373.70828 298.88155,373.71628 298.53555,373.77828 C 297.16955,374.02928 296.06255,375.03828 296.06255,376.03228 C 296.06255,377.02528 297.16855,377.62828 298.53555,377.37928 C 299.86955,377.13528 300.94855,376.16328 300.99555,375.19128 L 301.00755,375.19128 L 301.00955,364.05028 z " id="path81" /> <path d="M 268.00955,393.05028 L 259.05155,396.06628 L 258.98955,405.36928 C 258.69555,405.33328 258.37355,405.34228 258.03555,405.40328 C 256.66955,405.65428 255.56255,406.66328 255.56255,407.65728 C 255.56255,408.65028 256.66855,409.25328 258.03555,409.00428 C 259.39855,408.75428 260.50455,407.74528 260.50455,406.75228 C 260.50455,406.71628 260.49255,406.68428 260.48955,406.64828 L 260.48955,398.82228 L 266.50755,396.79328 L 266.50755,402.74728 C 266.20855,402.70828 265.88155,402.71628 265.53555,402.77828 C 264.16955,403.02928 263.06255,404.03828 263.06255,405.03228 C 263.06255,406.02528 264.16855,406.62828 265.53555,406.37928 C 266.86955,406.13528 267.94855,405.16328 267.99555,404.19128 L 268.00755,404.19128 L 268.00955,393.05028 z " id="path83" /> <path d="M 279.00955,415.05028 L 270.05155,418.06628 L 269.98955,427.36928 C 269.69555,427.33328 269.37355,427.34228 269.03555,427.40328 C 267.66955,427.65428 266.56255,428.66328 266.56255,429.65728 C 266.56255,430.65028 267.66855,431.25328 269.03555,431.00428 C 270.39855,430.75428 271.50455,429.74528 271.50455,428.75228 C 271.50455,428.71628 271.49255,428.68428 271.48955,428.64828 L 271.48955,420.82228 L 277.50755,418.79328 L 277.50755,424.74728 C 277.20855,424.70828 276.88155,424.71628 276.53555,424.77828 C 275.16955,425.02928 274.06255,426.03828 274.06255,427.03228 C 274.06255,428.02528 275.16855,428.62828 276.53555,428.37928 C 277.86955,428.13528 278.94855,427.16328 278.99555,426.19128 L 279.00755,426.19128 L 279.00955,415.05028 z " id="path85" /> <path d="M 370.50955,356.05028 L 361.55155,359.06628 L 361.48955,368.36928 C 361.19555,368.33328 360.87355,368.34228 360.53555,368.40328 C 359.16955,368.65428 358.06255,369.66328 358.06255,370.65728 C 358.06255,371.65028 359.16855,372.25328 360.53555,372.00428 C 361.89855,371.75428 363.00455,370.74528 363.00455,369.75228 C 363.00455,369.71628 362.99255,369.68428 362.98955,369.64828 L 362.98955,361.82228 L 369.00755,359.79328 L 369.00755,365.74728 C 368.70855,365.70828 368.38155,365.71628 368.03555,365.77828 C 366.66955,366.02928 365.56255,367.03828 365.56255,368.03228 C 365.56255,369.02528 366.66855,369.62828 368.03555,369.37928 C 369.36955,369.13528 370.44855,368.16328 370.49555,367.19128 L 370.50755,367.19128 L 370.50955,356.05028 z " id="path87" /> <path d="M 412.84255,372.55028 L 403.88455,375.56628 L 403.82255,384.86928 C 403.52855,384.83328 403.20655,384.84228 402.86855,384.90328 C 401.50255,385.15428 400.39555,386.16328 400.39555,387.15728 C 400.39555,388.15028 401.50155,388.75328 402.86855,388.50428 C 404.23155,388.25428 405.33755,387.24528 405.33755,386.25228 C 405.33755,386.21628 405.32555,386.18428 405.32255,386.14828 L 405.32255,378.32228 L 411.34055,376.29328 L 411.34055,382.24728 C 411.04155,382.20828 410.71455,382.21628 410.36855,382.27828 C 409.00255,382.52928 407.89555,383.53828 407.89555,384.53228 C 407.89555,385.52528 409.00155,386.12828 410.36855,385.87928 C 411.70255,385.63528 412.78155,384.66328 412.82855,383.69128 L 412.84055,383.69128 L 412.84255,372.55028 z " id="path89" /> <path d="M 406.50955,400.05028 L 397.55155,403.06628 L 397.48955,412.36928 C 397.19555,412.33328 396.87355,412.34228 396.53555,412.40328 C 395.16955,412.65428 394.06255,413.66328 394.06255,414.65728 C 394.06255,415.65028 395.16855,416.25328 396.53555,416.00428 C 397.89855,415.75428 399.00455,414.74528 399.00455,413.75228 C 399.00455,413.71628 398.99255,413.68428 398.98955,413.64828 L 398.98955,405.82228 L 405.00755,403.79328 L 405.00755,409.74728 C 404.70855,409.70828 404.38155,409.71628 404.03555,409.77828 C 402.66955,410.02928 401.56255,411.03828 401.56255,412.03228 C 401.56255,413.02528 402.66855,413.62828 404.03555,413.37928 C 405.36955,413.13528 406.44855,412.16328 406.49555,411.19128 L 406.50755,411.19128 L 406.50955,400.05028 z " id="path91" /> <polygon transform="translate(209.84255,172.16228)" points="210.805,299.575 47.442,299.575 47.844,278.548 211.207,278.548 210.805,299.575 " id="polygon95" style="fill:#9999ff" /> <path d="M 375.92055,450.65528 L 384.92055,450.65528 C 384.92055,450.65528 384.35055,448.35828 382.34655,448.30328 C 380.34455,448.25128 375.91855,450.65628 375.92055,450.65528 z " id="path97" style="fill:#ff9900" /> <path d="M 307.39955,447.42128 C 307.39955,447.42128 304.47755,446.52828 302.14555,446.62428 C 299.81255,446.71828 298.80755,448.71028 298.80755,448.71028 C 298.80755,448.71028 301.23955,447.72428 302.56555,447.74328 C 303.89355,447.76328 306.24155,448.76628 306.24155,448.76628 L 307.39955,447.42128 z " id="path99" /> <rect x="253.40555" y="448.05029" width="170" height="25.333" id="rect101" style="fill:#bcaeed;stroke:#000000" /> <g transform="translate(209.84255,172.16228)" id="g103"> <g id="g105"> <path d="M 51.35,279.122 L 56.389,279.122 L 60.384,289.644 L 64.613,279.122 L 69.705,279.122 L 72.682,298.81 L 67.564,298.81 L 66.128,287.478 L 66.076,287.478 L 61.35,298.81 L 59.314,298.81 L 54.796,287.478 L 54.744,287.478 L 53.1,298.81 L 48.008,298.81 L 51.35,279.122 z " id="path107" style="fill:#6600cc" /> <path d="M 79.418,285.415 L 79.418,292.569 C 79.418,294.266 79.836,295.466 81.794,295.466 C 83.752,295.466 84.17,294.266 84.17,292.569 L 84.17,285.415 L 88.922,285.415 L 88.922,293.482 C 88.922,297.895 85.815,299.253 81.794,299.253 C 77.773,299.253 74.666,297.896 74.666,293.482 L 74.666,285.415 L 79.418,285.415 z " id="path109" style="fill:#6600cc" /> <path d="M 100.802,288.861 C 100.071,288.469 99.053,288.209 98.243,288.209 C 97.695,288.209 96.755,288.443 96.755,289.122 C 96.755,290.036 98.243,290.167 98.896,290.298 C 101.116,290.741 102.787,291.786 102.787,294.267 C 102.787,297.791 99.575,299.253 96.469,299.253 C 94.563,299.253 92.683,298.705 91.064,297.713 L 92.788,294.397 C 93.754,295.076 95.373,295.755 96.548,295.755 C 97.149,295.755 98.036,295.467 98.036,294.736 C 98.036,293.691 96.548,293.639 95.059,293.248 C 93.57,292.857 92.082,292.125 92.082,289.723 C 92.082,286.434 95.059,284.971 97.983,284.971 C 99.497,284.971 101.011,285.206 102.395,285.833 L 100.802,288.861 z " id="path111" style="fill:#6600cc" /> <path d="M 110.384,280.271 C 110.384,281.733 109.184,282.934 107.721,282.934 C 106.259,282.934 105.058,281.733 105.058,280.271 C 105.058,278.809 106.259,277.608 107.721,277.608 C 109.184,277.608 110.384,278.81 110.384,280.271 z M 110.097,298.81 L 105.345,298.81 L 105.345,285.415 L 110.097,285.415 L 110.097,298.81 z " id="path113" style="fill:#6600cc" /> <path d="M 122.891,289.775 C 122.186,289.253 121.351,288.835 120.437,288.835 C 118.61,288.835 117.173,290.245 117.173,292.099 C 117.173,294.032 118.557,295.389 120.515,295.389 C 121.351,295.389 122.265,295.05 122.891,294.475 L 122.891,298.496 C 121.847,299.018 120.698,299.253 119.549,299.253 C 115.58,299.253 112.265,296.303 112.265,292.256 C 112.265,287.947 115.554,284.971 119.758,284.971 C 120.855,284.971 121.951,285.233 122.891,285.754 L 122.891,289.775 z " id="path115" style="fill:#6600cc" /> <path d="M 125.945,298.81 L 125.945,279.122 L 133.257,279.122 C 136.755,279.122 139.106,280.48 139.106,284.24 C 139.106,286.015 138.531,287.451 136.938,288.261 L 136.938,288.314 C 139.758,288.679 140.959,290.585 140.959,293.327 C 140.959,297.452 137.434,298.81 133.831,298.81 L 125.945,298.81 z M 131.063,286.851 L 131.637,286.851 C 132.994,286.851 134.405,286.617 134.405,284.946 C 134.405,283.144 132.812,283.04 131.428,283.04 L 131.063,283.04 L 131.063,286.851 z M 131.063,294.893 L 131.715,294.893 C 133.23,294.893 135.788,294.971 135.788,292.804 C 135.788,290.428 133.256,290.663 131.585,290.663 L 131.063,290.663 L 131.063,294.893 z " id="path117" style="fill:#6600cc" /> <path d="M 148.27,287.608 L 148.323,287.608 C 149.236,285.962 150.803,285.232 152.657,285.232 L 153.571,285.232 L 153.571,289.801 C 152.918,289.435 152.292,289.357 151.56,289.357 C 148.923,289.357 148.27,291.106 148.27,293.404 L 148.27,298.809 L 143.518,298.809 L 143.518,285.414 L 148.27,285.414 L 148.27,287.608 z " id="path119" style="fill:#6600cc" /> <path d="M 169.993,298.81 L 165.241,298.81 L 165.241,297.322 L 165.188,297.322 C 164.353,298.653 162.709,299.254 161.141,299.254 C 157.172,299.254 154.379,295.939 154.379,292.1 C 154.379,288.262 157.12,284.972 161.089,284.972 C 162.629,284.972 164.248,285.547 165.24,286.722 L 165.24,285.416 L 169.992,285.416 L 169.992,298.81 L 169.993,298.81 z M 159.288,292.125 C 159.288,293.822 160.411,295.128 162.343,295.128 C 164.276,295.128 165.398,293.822 165.398,292.125 C 165.398,290.48 164.276,289.097 162.343,289.097 C 160.411,289.097 159.288,290.48 159.288,292.125 z " id="path121" style="fill:#6600cc" /> <path d="M 178.191,280.271 C 178.191,281.733 176.99,282.934 175.528,282.934 C 174.066,282.934 172.865,281.733 172.865,280.271 C 172.865,278.809 174.066,277.608 175.528,277.608 C 176.99,277.608 178.191,278.81 178.191,280.271 z M 177.904,298.81 L 173.152,298.81 L 173.152,285.415 L 177.904,285.415 L 177.904,298.81 z " id="path123" style="fill:#6600cc" /> <path d="M 185.79,287.139 L 185.842,287.139 C 186.939,285.52 188.271,284.971 190.124,284.971 C 193.727,284.971 195.163,287.242 195.163,290.533 L 195.163,298.81 L 190.411,298.81 L 190.411,292.283 C 190.411,291.003 190.62,288.758 188.27,288.758 C 186.337,288.758 185.79,290.195 185.79,291.865 L 185.79,298.81 L 181.038,298.81 L 181.038,285.415 L 185.79,285.415 L 185.79,287.139 z " id="path125" style="fill:#6600cc" /> <path d="M 210.516,294.866 L 210.516,298.809 L 196.939,298.809 L 203.232,289.357 L 197.775,289.357 L 197.775,285.415 L 211.143,285.415 L 204.876,294.866 L 210.516,294.866 z " id="path127" style="fill:#6600cc" /> </g> <g id="g129"> <path d="M 51.35,279.122 L 56.389,279.122 L 60.384,289.644 L 64.613,279.122 L 69.705,279.122 L 72.682,298.81 L 67.564,298.81 L 66.128,287.478 L 66.076,287.478 L 61.35,298.81 L 59.314,298.81 L 54.796,287.478 L 54.744,287.478 L 53.1,298.81 L 48.008,298.81 L 51.35,279.122 z " id="path131" style="fill:#34176b" /> <path d="M 79.418,285.415 L 79.418,292.569 C 79.418,294.266 79.836,295.466 81.794,295.466 C 83.752,295.466 84.17,294.266 84.17,292.569 L 84.17,285.415 L 88.922,285.415 L 88.922,293.482 C 88.922,297.895 85.815,299.253 81.794,299.253 C 77.773,299.253 74.666,297.896 74.666,293.482 L 74.666,285.415 L 79.418,285.415 z " id="path133" style="fill:#34176b" /> <path d="M 100.802,288.861 C 100.071,288.469 99.053,288.209 98.243,288.209 C 97.695,288.209 96.755,288.443 96.755,289.122 C 96.755,290.036 98.243,290.167 98.896,290.298 C 101.116,290.741 102.787,291.786 102.787,294.267 C 102.787,297.791 99.575,299.253 96.469,299.253 C 94.563,299.253 92.683,298.705 91.064,297.713 L 92.788,294.397 C 93.754,295.076 95.373,295.755 96.548,295.755 C 97.149,295.755 98.036,295.467 98.036,294.736 C 98.036,293.691 96.548,293.639 95.059,293.248 C 93.57,292.857 92.082,292.125 92.082,289.723 C 92.082,286.434 95.059,284.971 97.983,284.971 C 99.497,284.971 101.011,285.206 102.395,285.833 L 100.802,288.861 z " id="path135" style="fill:#34176b" /> <path d="M 110.384,280.271 C 110.384,281.733 109.184,282.934 107.721,282.934 C 106.259,282.934 105.058,281.733 105.058,280.271 C 105.058,278.809 106.259,277.608 107.721,277.608 C 109.184,277.608 110.384,278.81 110.384,280.271 z M 110.097,298.81 L 105.345,298.81 L 105.345,285.415 L 110.097,285.415 L 110.097,298.81 z " id="path137" style="fill:#34176b" /> <path d="M 122.891,289.775 C 122.186,289.253 121.351,288.835 120.437,288.835 C 118.61,288.835 117.173,290.245 117.173,292.099 C 117.173,294.032 118.557,295.389 120.515,295.389 C 121.351,295.389 122.265,295.05 122.891,294.475 L 122.891,298.496 C 121.847,299.018 120.698,299.253 119.549,299.253 C 115.58,299.253 112.265,296.303 112.265,292.256 C 112.265,287.947 115.554,284.971 119.758,284.971 C 120.855,284.971 121.951,285.233 122.891,285.754 L 122.891,289.775 z " id="path139" style="fill:#34176b" /> <path d="M 125.945,298.81 L 125.945,279.122 L 133.257,279.122 C 136.755,279.122 139.106,280.48 139.106,284.24 C 139.106,286.015 138.531,287.451 136.938,288.261 L 136.938,288.314 C 139.758,288.679 140.959,290.585 140.959,293.327 C 140.959,297.452 137.434,298.81 133.831,298.81 L 125.945,298.81 z M 131.063,286.851 L 131.637,286.851 C 132.994,286.851 134.405,286.617 134.405,284.946 C 134.405,283.144 132.812,283.04 131.428,283.04 L 131.063,283.04 L 131.063,286.851 z M 131.063,294.893 L 131.715,294.893 C 133.23,294.893 135.788,294.971 135.788,292.804 C 135.788,290.428 133.256,290.663 131.585,290.663 L 131.063,290.663 L 131.063,294.893 z " id="path141" style="fill:#34176b" /> <path d="M 148.27,287.608 L 148.323,287.608 C 149.236,285.962 150.803,285.232 152.657,285.232 L 153.571,285.232 L 153.571,289.801 C 152.918,289.435 152.292,289.357 151.56,289.357 C 148.923,289.357 148.27,291.106 148.27,293.404 L 148.27,298.809 L 143.518,298.809 L 143.518,285.414 L 148.27,285.414 L 148.27,287.608 z " id="path143" style="fill:#34176b" /> <path d="M 169.993,298.81 L 165.241,298.81 L 165.241,297.322 L 165.188,297.322 C 164.353,298.653 162.709,299.254 161.141,299.254 C 157.172,299.254 154.379,295.939 154.379,292.1 C 154.379,288.262 157.12,284.972 161.089,284.972 C 162.629,284.972 164.248,285.547 165.24,286.722 L 165.24,285.416 L 169.992,285.416 L 169.992,298.81 L 169.993,298.81 z M 159.288,292.125 C 159.288,293.822 160.411,295.128 162.343,295.128 C 164.276,295.128 165.398,293.822 165.398,292.125 C 165.398,290.48 164.276,289.097 162.343,289.097 C 160.411,289.097 159.288,290.48 159.288,292.125 z " id="path145" style="fill:#34176b" /> <path d="M 178.191,280.271 C 178.191,281.733 176.99,282.934 175.528,282.934 C 174.066,282.934 172.865,281.733 172.865,280.271 C 172.865,278.809 174.066,277.608 175.528,277.608 C 176.99,277.608 178.191,278.81 178.191,280.271 z M 177.904,298.81 L 173.152,298.81 L 173.152,285.415 L 177.904,285.415 L 177.904,298.81 z " id="path147" style="fill:#34176b" /> <path d="M 185.79,287.139 L 185.842,287.139 C 186.939,285.52 188.271,284.971 190.124,284.971 C 193.727,284.971 195.163,287.242 195.163,290.533 L 195.163,298.81 L 190.411,298.81 L 190.411,292.283 C 190.411,291.003 190.62,288.758 188.27,288.758 C 186.337,288.758 185.79,290.195 185.79,291.865 L 185.79,298.81 L 181.038,298.81 L 181.038,285.415 L 185.79,285.415 L 185.79,287.139 z " id="path149" style="fill:#34176b" /> <path d="M 210.516,294.866 L 210.516,298.809 L 196.939,298.809 L 203.232,289.357 L 197.775,289.357 L 197.775,285.415 L 211.143,285.415 L 204.876,294.866 L 210.516,294.866 z " id="path151" style="fill:#34176b" /> </g> </g> </g> </svg> ���MP3Diags-1.0.12.079/src/images/undo_settings.svg����������������������������������������������������0000644�0001750�0000144�00000106073�10737543470�020147� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2606" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docname="edit-undo.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" sodipodi:docbase="/home/david/oxygen/trunk/scalable/actions" inkscape:export-filename="edit-undo.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> <defs id="defs2608"> <linearGradient inkscape:collect="always" id="linearGradient3342"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3344" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3347" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3326"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3328" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3330" /> </linearGradient> <linearGradient id="linearGradient3825"> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="0" id="stop3827" /> <stop id="stop3833" offset="0.5" style="stop-color:#ffffff;stop-opacity:0.18705036;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop3829" /> </linearGradient> <linearGradient id="linearGradient3751"> <stop style="stop-color:#beba2c;stop-opacity:1;" offset="0" id="stop3753" /> <stop style="stop-color:#b6be2c;stop-opacity:0;" offset="1" id="stop3755" /> </linearGradient> <linearGradient id="linearGradient3528"> <stop style="stop-color:#eaf209;stop-opacity:1;" offset="0" id="stop3530" /> <stop style="stop-color:#c7c634;stop-opacity:0;" offset="1" id="stop3532" /> </linearGradient> <linearGradient id="linearGradient3295"> <stop style="stop-color:#fffe63;stop-opacity:1;" offset="0" id="stop3297" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3299" /> </linearGradient> <linearGradient id="linearGradient3202"> <stop style="stop-color:#fcff9c;stop-opacity:1;" offset="0" id="stop3204" /> <stop style="stop-color:#c1a965;stop-opacity:0;" offset="1" id="stop3206" /> </linearGradient> <radialGradient id="XMLID_4_" cx="48" cy="-0.2148" r="55.148" gradientTransform="matrix(0.9792,0,0,0.9725,133.0002,20.8762)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#cfd13d;stop-opacity:1;" id="stop3082" /> <stop offset="1" style="stop-color:#db8900;stop-opacity:1;" id="stop3090" /> </radialGradient> <linearGradient id="linearGradient3260" inkscape:collect="always"> <stop id="stop3262" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop3264" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3344"> <stop id="stop3346" offset="0" style="stop-color:#fdff63;stop-opacity:1;" /> <stop id="stop3348" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3449"> <stop id="stop3451" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop3453" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="linearGradient3516" x1="147.09375" y1="33.40625" x2="8.083992" y2="123.90625" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="radialGradient3524" cx="67.09375" cy="116.90625" fx="67.09375" fy="116.90625" r="56" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3528" id="radialGradient3535" cx="99.726295" cy="27.418272" fx="64.689766" fy="68.231934" r="56" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.693735,5.8671246e-2,-3.6242796e-2,0.4285387,33.939389,26.8809)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3548" x1="75.09375" y1="4.5317035" x2="75.09375" y2="80.172485" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3581" gradientUnits="userSpaceOnUse" gradientTransform="translate(4.2161108e-3,1.9705695e-3)" x1="75.09375" y1="4.5317035" x2="75.09375" y2="80.172485" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3613" x1="208.59375" y1="130.40625" x2="208.59375" y2="63.426777" gradientUnits="userSpaceOnUse" gradientTransform="translate(-137,0)" /> <filter inkscape:collect="always" id="filter3639"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.0580524" id="feGaussianBlur3641" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3654" cx="-10.165252" cy="66.906013" fx="-10.165252" fy="66.906013" r="59.995121" gradientTransform="matrix(0.4582893,-2.1035589e-8,4.5903973e-8,1.0000813,20.447953,-5.1974351e-3)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3658" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.2676699,0.521376,-0.7037472,0.3612977,108.99386,-36.062981)" cx="167.67001" cy="80.404922" fx="167.67001" fy="80.404922" r="59.995121" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3676" x1="120.0625" y1="12.569496" x2="125.30366" y2="14.444496" gradientUnits="userSpaceOnUse" spreadMethod="reflect" /> <filter inkscape:collect="always" x="-0.15096202" width="1.301924" y="-0.13732364" height="1.2746473" id="filter3738"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.39257441" id="feGaussianBlur3740" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3744" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.982366,1.671718e-2,-3.5801148e-3,0.2103843,-18.56344,30.477792)" cx="72.684891" cy="48.228905" fx="74.871155" fy="26.862719" r="59.995121" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3751" id="radialGradient3757" cx="66.01458" cy="126.69183" fx="66.01458" fy="126.69183" r="59.99512" gradientTransform="matrix(0.675025,0,0,0.3583625,19.527377,41.004647)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="radialGradient3767" cx="64.088867" cy="7.4108429" fx="64.088867" fy="7.4108429" r="59.995121" gradientTransform="matrix(0.3093869,0,0,0.4779247,44.260611,3.8644223)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3344" id="linearGradient3771" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="120.0625" y1="12.569496" x2="125.30366" y2="14.444496" /> <filter inkscape:collect="always" id="filter3438"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.3342697" id="feGaussianBlur3440" /> </filter> <filter inkscape:collect="always" id="filter3630"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.89883985" id="feGaussianBlur3632" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient2361" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2363" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2365" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2367" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3349" x1="-73" y1="105.625" x2="-163" y2="86.125" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" x="-0.087741371" width="1.1754827" y="-0.10211017" height="1.2042203" id="filter3363"> <feGaussianBlur inkscape:collect="always" stdDeviation="3.0526685" id="feGaussianBlur3365" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3372" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3376" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient3388" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3390" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3392" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3394" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3396" gradientUnits="userSpaceOnUse" x1="-73" y1="105.625" x2="-163" y2="86.125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3398" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3400" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient3422" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3424" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3426" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3428" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3430" gradientUnits="userSpaceOnUse" x1="-73" y1="105.625" x2="-163" y2="86.125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3432" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3434" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <mask maskUnits="userSpaceOnUse" id="mask3402"> <g id="g3404" transform="translate(167.50257,-3.755156e-3)"> <g id="g3406" transform="translate(80.51637,30.885255)"> <path style="opacity:1;fill:url(#radialGradient3422);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M -184.42232,-32.47243 C -217.54751,-32.47243 -248.42232,-0.097625 -248.42232,33.02757 C -248.42232,66.15276 -217.04751,97.02757 -183.92232,97.02757 C -153.6332,97.02757 -128.58571,70.81131 -124.51607,41.68382 L -159.54732,36.65257 C -161.172,48.6137 -171.47739,57.62132 -183.92232,57.62132 C -197.49395,57.62132 -206.01607,46.0992 -206.01607,32.52757 C -206.01607,18.955936 -199.99395,12.43382 -186.42232,12.43382 C -179.6365,12.433819 -176.50103,10.198864 -172.04732,14.65257 L -176.8745,25.979749 C -178.93037,28.035619 -179.11822,29.285529 -178.55411,30.595278 C -178.04554,31.776057 -177.03338,33.12132 -174.34438,33.12132 L -130.39107,33.12132 C -126.54518,33.12132 -123.93208,30.466941 -123.93208,26.871189 L -124.00095,-17.206829 C -124.00095,-19.687584 -124.90346,-21.050058 -126.18242,-21.556444 C -127.49674,-22.076829 -129.21563,-21.679122 -131.28951,-19.605244 L -141.48482,-19.40993 C -152.34417,-30.269281 -167.85972,-32.47243 -184.42232,-32.47243 z " id="path3408" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="ccccc" style="fill:url(#linearGradient3424);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" d="M -161.5,34.5 C -162,37 -180,54 -180,54 L -132.5,80 L -112,38.5 L -161.5,34.5 z " id="path3410" /> <path sodipodi:nodetypes="ccccc" id="path3412" d="M -161.5,34.5 C -162,37 -181.27817,54.389087 -181.27817,54.389087 L -151.62742,97.591883 L -112,38.5 L -161.5,34.5 z " style="fill:url(#linearGradient3426);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" /> <path style="fill:url(#linearGradient3428);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" d="M -161.5,34.5 C -162,37 -181.27817,54.389087 -181.27817,54.389087 L -151.62742,97.591883 L -112,38.5 L -161.5,34.5 z " id="path3414" sodipodi:nodetypes="ccccc" /> </g> <rect y="69.75" x="-119" height="71.75" width="83.5" id="rect3416" style="opacity:1;fill:url(#linearGradient3430);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" /> <path sodipodi:nodetypes="ccccc" id="path3418" d="M -159.5,68.25 L -39.138259,55.983708 L -93.453327,162.55286 L -197.79465,128.96507 L -159.5,68.25 z " style="fill:url(#linearGradient3432);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" transform="matrix(0.6393762,0.7688941,-0.7688941,0.6393762,37.597642,128.08723)" /> <path transform="matrix(0.6393762,0.7688941,-0.7688941,0.6393762,37.597642,128.08723)" style="fill:url(#linearGradient3434);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" d="M -159.5,68.25 L -39.138259,55.983708 L -93.453327,162.55286 L -197.79465,128.96507 L -159.5,68.25 z " id="path3420" sodipodi:nodetypes="ccccc" /> </g> </mask> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3751" id="linearGradient3565" x1="-267.47665" y1="18.103027" x2="-33.476654" y2="18.103027" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3567" gradientUnits="userSpaceOnUse" gradientTransform="translate(-137,0)" x1="208.59375" y1="130.40625" x2="208.59375" y2="63.426777" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="4.6484375" inkscape:cx="64" inkscape:cy="64" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" showgrid="false" inkscape:grid-points="true" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="748" inkscape:window-height="681" inkscape:window-x="526" inkscape:window-y="51" /> <metadata id="metadata2611"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1"> <g id="g3835" mask="url(#mask3402)" transform="matrix(-1,0,0,1,128.17774,0)"> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="rect3204" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:1;fill:url(#linearGradient3516);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:0.79775277;fill:url(#radialGradient3757);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " id="path3749" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="path3656" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:0.68913861;fill:url(#radialGradient3658);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:1;fill:url(#radialGradient3654);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " id="path3643" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="path3742" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:0.79775277;fill:url(#radialGradient3744);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:0.74531836;fill:url(#radialGradient3767);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3630)" d="M 64.09375,4.20625 C 30.968558,4.2062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,4.20625 64.09375,4.20625 z " id="path3759" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cccczc" id="path3660" d="M 117.6875,10.75 L 118.625,15.125 L 119.875,16 L 123.875,13.375 C 124.12188,11.651249 123.52383,10.027571 121.9375,9.3749999 C 120.35116,8.7224285 118.77622,9.5017032 117.6875,10.75 z " style="opacity:0.82022472;fill:url(#linearGradient3676);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3738)" /> <path transform="matrix(0,1,1,0,60.363582,-60.363586)" style="opacity:0.82022472;fill:url(#linearGradient3771);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3738)" d="M 117.6875,10.75 L 119.875,13.875 L 120.375,13.75 L 123.875,13.375 C 124.12188,11.651249 123.52383,10.027571 121.9375,9.3749999 C 120.35116,8.7224285 118.77622,9.5017032 117.6875,10.75 z " id="path3769" sodipodi:nodetypes="cccczc" /> <path id="path3494" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.0937501,94.867948 33.132054,119.90625 64.09375,119.90625 C 91.026646,119.90625 113.21548,101.0995 118.625,75.90625 L 91.5,72.03125 C 88.061436,83.928551 77.059621,92.5 64.09375,92.5 C 48.356404,92.499999 35.5,79.643599 35.5,63.90625 C 35.500001,48.168899 48.356402,35.3125 64.09375,35.3125 C 71.966166,35.312499 79.145304,38.520304 84.3125,43.6875 C 85.071964,44.438909 85.499997,45.462886 85.5,46.53125 C 85.5,47.599614 85.071964,48.623591 84.3125,49.375 L 73.6875,60 L 117.625,60 C 119.63039,60 120.09375,59.407836 120.09375,57.75 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " style="opacity:1;fill:url(#radialGradient3524);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:1;fill:url(#radialGradient3535);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.0937501,94.867948 33.132054,119.90625 64.09375,119.90625 C 91.026646,119.90625 113.21548,101.0995 118.625,75.90625 L 91.5,72.03125 C 88.061436,83.928551 77.059621,92.5 64.09375,92.5 C 48.356404,92.499999 35.5,79.643599 35.5,63.90625 C 35.500001,48.168899 48.356402,35.3125 64.09375,35.3125 C 71.966166,35.312499 79.145304,38.520304 84.3125,43.6875 C 85.071964,44.438909 85.499997,45.462886 85.5,46.53125 C 85.5,47.599614 85.071964,48.623591 84.3125,49.375 L 73.6875,60 L 117.625,60 C 119.63039,60 120.09375,59.407836 120.09375,57.75 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " id="path3526" /> <path sodipodi:nodetypes="csccssccccccscc" id="path3537" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.09375,64.474122 8.1082724,65.029981 8.125,65.59375 C 14.11447,66.271402 20.266218,66.74388 26.53125,67 C 26.260548,56.540958 30.202859,46.025084 38.34375,38.21875 C 53.683067,23.509813 78.072313,24.004431 92.78125,39.34375 C 95.545099,42.226046 97.537852,45.032117 99.34375,48.59375 L 78.84375,59 L 98,59 C 105.9282,56.973373 113.18621,55.563033 120.09375,52.8125 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " style="opacity:1;fill:url(#linearGradient3548);fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path sodipodi:nodetypes="cscscscccccccccccssssssccscscc" id="path3553" d="M 64.099866,7.9087646 C 33.138176,7.9087644 8.0998661,32.947063 8.0998661,63.908764 C 8.0998761,64.087476 8.0973761,64.263059 8.0998661,64.440014 C 8.3531061,33.696509 33.295846,8.9087645 64.099866,8.9087646 C 79.583236,8.9087645 93.555946,15.177347 103.69361,25.315014 C 104.44503,26.074479 105.469,26.502514 106.53736,26.502514 C 107.60573,26.502515 108.6297,26.074478 109.38111,25.315014 L 119.50611,15.158764 L 119.99986,52.708764 C 113.09232,55.459294 105.43431,56.569624 97.506116,58.596264 L 78.849866,59.002514 L 98.006116,59.002514 C 105.93431,56.975884 113.19232,55.565544 120.09986,52.815014 L 120.00611,14.658764 L 120.00611,13.658764 L 119.50611,14.158764 L 109.38111,24.315014 C 108.62971,25.074479 107.60572,25.502514 106.53736,25.502514 C 105.46901,25.502515 104.44502,25.074478 103.69361,24.315014 C 103.68314,24.304548 103.67283,24.294222 103.66236,24.283764 C 103.60999,24.231473 103.55869,24.179598 103.50611,24.127514 C 102.93231,23.559643 102.35524,23.012364 101.75611,22.471264 C 101.67459,22.397145 101.58807,22.326157 101.50611,22.252514 C 91.590066,13.342335 78.496526,7.9087646 64.099866,7.9087646 z M 63.443616,27.127514 C 54.205446,27.378034 45.040176,30.920194 37.849866,37.815014 C 30.217786,45.133448 26.722316,55.187931 26.537366,65.033764 C 26.777246,55.231884 30.717786,45.539698 38.349866,38.221264 C 51.665996,25.452364 71.803196,24.123207 86.506116,34.033764 C 79.627056,29.22869 71.518656,26.908534 63.443616,27.127514 z " style="opacity:1;fill:url(#linearGradient3581);fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path id="path3603" d="M 63.59375,7.90625 C 32.63205,7.9062499 7.59375,32.944549 7.59375,63.90625 C 7.59375,94.867948 32.63205,119.90625 63.59375,119.90625 C 90.52665,119.90625 112.71548,101.0995 118.125,75.90625 L 91,72.03125 C 87.56144,83.928551 76.55962,92.5 63.59375,92.5 C 47.8564,92.499999 35,79.643599 35,63.90625 C 35,48.168899 47.8564,35.3125 63.59375,35.3125 C 71.46617,35.312499 78.6453,38.520304 83.8125,43.6875 C 84.57196,44.438909 85,45.462886 85,46.53125 C 85,47.599614 84.57196,48.623591 83.8125,49.375 L 73.1875,60 L 117.125,60 C 119.13039,60 119.59375,59.407836 119.59375,57.75 L 119.5,13.65625 L 108.875,24.3125 C 108.12359,25.071964 107.09961,25.5 106.03125,25.5 C 104.96289,25.5 103.93891,25.071964 103.1875,24.3125 C 93.04984,14.174833 79.07711,7.90625 63.59375,7.90625 z " style="opacity:1;fill:none;fill-opacity:1;stroke:url(#linearGradient3567);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3639)" /> </g> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/change-case.svg������������������������������������������������������0000644�0001750�0000144�00000010633�11265372005�017403� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="680" height="680" id="svg2273" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/mp3diags/src/images" sodipodi:docname="change_case.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2275" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="375" inkscape:cy="405.71429" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" showgrid="false" showguides="true" height="680px" width="680px" /> <metadata id="metadata2278"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-47.400002,-191.39075)"> <path style="font-size:64px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Luxi Serif" d="M 71.471438,747.66831 L 71.471438,730.15527 L 77.102612,729.8728 C 88.023645,729.11957 94.849294,726.85982 97.579604,723.09356 C 100.13918,720.08058 103.29605,713.77208 107.0502,704.16815 L 118.82446,674.50896 L 252.18091,324.24789 L 270.09827,324.24789 L 402.94267,676.48623 L 415.74079,705.58049 C 422.56609,721.02208 432.12205,729.11957 444.40858,729.8728 L 450.03975,730.15527 L 450.03975,747.66831 L 324.87414,747.66831 L 324.87414,730.15527 L 329.48146,730.15527 C 347.05728,730.15527 355.84535,726.01243 355.84559,717.72665 C 355.84535,707.55778 352.26187,693.15188 345.09517,674.50896 L 323.85029,618.86264 L 161.57022,618.86264 L 139.81342,674.50896 C 136.9124,681.85322 135.03532,686.93766 134.18225,689.76225 L 128.55104,709.53506 C 127.52713,713.11305 127.0152,716.22021 127.01527,718.85652 C 127.0152,726.38898 134.86469,730.15527 150.56383,730.15527 L 154.65924,730.15527 L 154.65924,747.66831 L 71.471438,747.66831 M 170.01698,595.98268 L 314.63565,595.98268 L 242.7103,405.59885 L 170.01698,595.98268 M 611.29603,705.58049 C 591.5015,738.34685 567.18508,754.73003 538.34679,754.73003 C 517.35785,754.73003 500.63494,747.19756 488.17814,732.13255 C 475.72133,716.87924 469.49289,696.35323 469.49289,670.55439 C 469.49289,601.06721 509.42301,566.32366 589.28331,566.32348 L 599.77777,566.32348 L 599.77777,528.19022 C 599.77766,497.49551 597.55926,477.8169 593.12277,469.15428 C 588.68596,460.11555 579.04473,455.59606 564.19896,455.59579 C 549.86505,455.59606 539.79715,459.17397 533.99538,466.3296 C 528.1935,473.48577 525.29266,486.00848 525.29266,503.89792 L 525.29266,508.98235 L 490.4818,508.98235 L 490.4818,459.83282 C 515.73673,442.69668 542.69809,434.12845 571.36592,434.12817 C 599.69237,434.12845 619.91335,441.09607 632.02897,455.03085 C 644.14447,468.96627 650.20223,492.59944 650.20233,525.93047 L 650.20233,662.64527 C 650.20223,689.95063 651.31132,707.93443 653.52983,716.59677 C 655.74802,725.07083 660.27002,729.30785 667.09581,729.30785 C 669.82596,729.30785 674.17726,728.46045 680.14995,726.76565 L 681.68571,747.66831 C 668.71675,752.3761 659.16081,754.73003 653.01788,754.73003 C 631.85828,754.73003 617.95092,738.34685 611.29603,705.58049 M 599.77777,699.36618 L 599.77777,583.83653 L 588.00353,583.83653 C 545.34306,583.83672 524.01277,609.07051 524.01288,659.53812 C 524.01277,700.77853 536.21368,721.39874 560.61548,721.39874 C 572.90158,721.39874 585.95571,714.05455 599.77777,699.36618" id="text2158" /> </g> </svg> �����������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/COPYING-GPL.V3.txt���������������������������������������������������0000644�0001750�0000144�00000103606�11107243727�017312� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> 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. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> 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 <http://www.gnu.org/licenses/>. 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: <program> Copyright (C) <year> <name of author> 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 <http://www.gnu.org/licenses/>. 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 <http://www.gnu.org/philosophy/why-not-lgpl.html>.��������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/go-previous.svg������������������������������������������������������0000644�0001750�0000144�00000106734�10737543467�017553� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2606" sodipodi:version="0.32" inkscape:version="0.45+devel" version="1.0" sodipodi:docname="go-previous.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" sodipodi:docbase="/home/pinheiro/artwork/Oxygen/scribus/scalable" inkscape:export-filename="/home/pinheiro/pics/oxygen/scalable/actions/go-next.png" inkscape:export-xdpi="180" inkscape:export-ydpi="180"> <defs id="defs2608"> <linearGradient inkscape:collect="always" id="linearGradient3449"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3451" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3453" /> </linearGradient> <linearGradient id="linearGradient3295"> <stop style="stop-color:#63e9ff;stop-opacity:1;" offset="0" id="stop3297" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3299" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3260"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3262" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3264" /> </linearGradient> <linearGradient id="linearGradient3202"> <stop style="stop-color:#cdeeff;stop-opacity:1;" offset="0" id="stop3204" /> <stop style="stop-color:#d2e8ed;stop-opacity:0;" offset="1" id="stop3206" /> </linearGradient> <radialGradient id="XMLID_4_" cx="48" cy="-0.2148" r="55.148" gradientTransform="matrix(0.9792,0,0,0.9725,133.0002,20.8762)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#72D13D" id="stop3082" /> <stop offset="0.3553" style="stop-color:#35AC1C" id="stop3084" /> <stop offset="0.6194" style="stop-color:#0F9508" id="stop3086" /> <stop offset="0.7574" style="stop-color:#008C00" id="stop3088" /> <stop offset="1" style="stop-color:#007A00" id="stop3090" /> </radialGradient> <radialGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="radialGradient3629" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="172" cy="76" fx="172" fy="76" r="56" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient3213" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="172" cy="76" fx="188.88173" fy="121.44213" r="56" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3301" x1="73.742638" y1="15.336544" x2="78.939339" y2="16.750759" gradientUnits="userSpaceOnUse" spreadMethod="reflect" gradientTransform="translate(4,0)" /> <filter inkscape:collect="always" x="-0.10207015" width="1.2041403" y="-0.12495601" height="1.249912" id="filter3387"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.44655691" id="feGaussianBlur3389" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3393" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="74.75" y1="14.275884" x2="78.939339" y2="16.750759" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6404" id="linearGradient3409" gradientUnits="userSpaceOnUse" x1="194.5" y1="123.90683" x2="104.25" y2="5.1559582" gradientTransform="matrix(1,0,0,0.8610463,-108,-1.4361867)" /> <filter inkscape:collect="always" x="-0.11573034" width="1.2314607" y="-0.12753956" height="1.2550791" id="filter3443"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.32549158" id="feGaussianBlur3445" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3455" cx="72.020813" cy="66.344505" fx="72.020813" fy="66.344505" r="60" gradientTransform="matrix(0.5816285,1.767767e-2,-2.6986249e-2,0.8878982,31.921846,5.9419094)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3521" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8610463,-108.16138,-1.4361867)" spreadMethod="reflect" x1="223.32712" y1="53.784153" x2="226.659" y2="57.279232" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient2226" gradientUnits="userSpaceOnUse" x1="179.17224" y1="123.75864" x2="180.40749" y2="62.959969" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient2228" gradientUnits="userSpaceOnUse" x1="179.17224" y1="123.75864" x2="173.98071" y2="65.448112" gradientTransform="translate(97,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3253" x1="47.968472" y1="16.138517" x2="49.218472" y2="85.427559" gradientUnits="userSpaceOnUse" gradientTransform="translate(-0.5,-87.681242)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3530" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8610463,-108.16138,-1.4361867)" spreadMethod="reflect" x1="223.32712" y1="53.784153" x2="226.659" y2="57.279232" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3534" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.2586607,-0.5212474,0.8274344,0.4106011,-35.53945,50.055595)" cx="-16.668488" cy="86.826965" fx="-16.668488" fy="86.826965" r="60" /> <radialGradient r="43.474762" fy="51.592991" fx="88.042809" cy="74.979416" cx="77.533371" spreadMethod="reflect" gradientTransform="matrix(-0.4961056,0.4409829,-0.7360594,-0.8280666,-11.726835,87.897058)" gradientUnits="userSpaceOnUse" id="radialGradient3139" xlink:href="#linearGradient2990" inkscape:collect="always" /> <clipPath id="clipPath3135" clipPathUnits="userSpaceOnUse"> <path style="fill:url(#radialGradient3139);fill-opacity:1;stroke:none;stroke-width:16.49500084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15;stroke-opacity:1" d="M -97.32181,27.94375 C -107.56112,27.943751 -117.79103,31.818176 -125.55562,39.582762 C -133.56284,47.589993 -137.44486,58.222613 -137.19463,68.779409 L -137.19463,96.822041 C -137.19463,100.87378 -133.94013,104.12828 -129.88839,104.12828 L -64.755235,104.12828 C -60.703495,104.12828 -57.448995,100.87378 -57.448995,96.822041 L -57.448995,68.779409 C -57.198765,58.222612 -61.080775,47.589993 -69.088001,39.582762 C -76.852581,31.818171 -87.082497,27.943749 -97.32181,27.94375 z M -97.32181,43.481014 C -90.982458,43.481015 -84.633535,45.9179 -79.764176,50.787256 C -74.95275,55.59868 -72.515179,61.833382 -72.457934,68.090021 L -122.15737,68.090021 C -122.10012,61.833381 -119.69086,55.598679 -114.87944,50.787256 C -110.01008,45.917895 -103.66116,43.481013 -97.32181,43.481014 z" id="path3137" sodipodi:nodetypes="csccccccsccsccsc" /> </clipPath> <radialGradient r="43.474762" fy="51.592991" fx="88.042809" cy="74.979416" cx="77.533371" spreadMethod="reflect" gradientTransform="matrix(-0.4961056,0.4409829,-0.7360594,-0.8280666,-99.14147,87.897058)" gradientUnits="userSpaceOnUse" id="radialGradient3133" xlink:href="#linearGradient2990" inkscape:collect="always" /> <clipPath id="clipPath3129" clipPathUnits="userSpaceOnUse"> <path sodipodi:nodetypes="csccccccsccsccsc" id="path3131" d="M -184.73645,27.94375 C -194.97576,27.943751 -205.20567,31.818176 -212.97026,39.582762 C -220.97748,47.589993 -224.8595,58.222613 -224.60927,68.779409 L -224.60927,96.822041 C -224.60927,100.87378 -221.35477,104.12828 -217.30303,104.12828 L -152.16987,104.12828 C -148.11813,104.12828 -144.86363,100.87378 -144.86363,96.822041 L -144.86363,68.779409 C -144.6134,58.222612 -148.49541,47.589993 -156.50264,39.582762 C -164.26722,31.818171 -174.49713,27.943749 -184.73645,27.94375 z M -184.73645,43.481014 C -178.39709,43.481015 -172.04817,45.9179 -167.17881,50.787256 C -162.36739,55.59868 -159.92981,61.833382 -159.87257,68.090021 L -209.57201,68.090021 C -209.51476,61.833381 -207.1055,55.598679 -202.29408,50.787256 C -197.42472,45.917895 -191.0758,43.481013 -184.73645,43.481014 z" style="fill:url(#radialGradient3133);fill-opacity:1;stroke:none;stroke-width:16.49500084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15;stroke-opacity:1" /> </clipPath> <radialGradient r="43.474762" fy="51.592991" fx="73.551216" cy="74.979408" cx="63.041775" spreadMethod="reflect" gradientTransform="matrix(-1.1040885,0.8280667,-0.6647496,-0.8863327,191.44623,62.253906)" gradientUnits="userSpaceOnUse" id="radialGradient2409" xlink:href="#linearGradient2990" inkscape:collect="always" /> <linearGradient y2="-20.962214" x2="60.402065" y1="64.076149" x1="60.402065" gradientUnits="userSpaceOnUse" id="linearGradient3289" xlink:href="#linearGradient6674" inkscape:collect="always" /> <linearGradient gradientUnits="userSpaceOnUse" y2="8" x2="-60" y1="105.83054" x1="-60.945251" id="linearGradient3243" xlink:href="#linearGradient3237" inkscape:collect="always" /> <linearGradient y2="21.03125" x2="31.376678" y1="71.084908" x1="115.76678" gradientTransform="translate(0.2332229,1.9150941)" gradientUnits="userSpaceOnUse" id="linearGradient3233" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient y2="46.228859" x2="59.225807" y1="7.8973217" x1="59.225807" gradientTransform="translate(0.2623629,1)" gradientUnits="userSpaceOnUse" id="linearGradient3231" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient y2="82.029854" x2="74.447762" y1="-26.936626" x1="64" gradientUnits="userSpaceOnUse" id="linearGradient2816" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient gradientUnits="userSpaceOnUse" y2="88.633484" x2="19.934336" y1="50.580647" x1="19.096775" id="linearGradient6680" xlink:href="#linearGradient6674" inkscape:collect="always" /> <linearGradient gradientTransform="translate(0,3)" gradientUnits="userSpaceOnUse" y2="50.728985" x2="62.038712" y1="15.91371" x1="62.038712" id="linearGradient6649" xlink:href="#linearGradient6643" inkscape:collect="always" /> <linearGradient gradientUnits="userSpaceOnUse" y2="74.913147" x2="55.329033" y1="112" x1="55.329033" id="linearGradient6637" xlink:href="#linearGradient6631" inkscape:collect="always" /> <linearGradient y2="28.235947" x2="13.96104" y1="21.101994" x1="21.094994" spreadMethod="reflect" gradientTransform="translate(0.4129032,0.6193548)" gradientUnits="userSpaceOnUse" id="linearGradient6472" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient y2="28.235947" x2="13.96104" y1="21.101994" x1="21.094994" spreadMethod="reflect" gradientTransform="translate(0.4129032,0.6193548)" gradientUnits="userSpaceOnUse" id="linearGradient6470" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient y2="27.070099" x2="15.126888" y1="21.101994" x1="21.094994" spreadMethod="reflect" gradientTransform="translate(0.4129032,0.6193548)" gradientUnits="userSpaceOnUse" id="linearGradient6464" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient gradientTransform="translate(-7.5870968,-7.3806452)" spreadMethod="reflect" gradientUnits="userSpaceOnUse" y2="27.007854" x2="15.189133" y1="21.101994" x1="21.094994" id="linearGradient6452" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient gradientUnits="userSpaceOnUse" y2="-24" x2="24" y1="88" x1="32" id="linearGradient6410" xlink:href="#linearGradient6404" inkscape:collect="always" /> <radialGradient r="42.559486" fy="103.5803" fx="42.700352" cy="103.5803" cx="42.700352" spreadMethod="pad" gradientTransform="matrix(1.3965253,6.9831451e-3,-7.781496e-3,1.5561835,-122.82611,-69.698616)" gradientUnits="userSpaceOnUse" id="radialGradient9692" xlink:href="#linearGradient6666" inkscape:collect="always" /> <linearGradient id="linearGradient6404"> <stop id="stop6406" offset="0" style="stop-color:#081e3e;stop-opacity:1;" /> <stop id="stop6408" offset="1" style="stop-color:#387de4;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient6446"> <stop id="stop6448" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop6450" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6631"> <stop id="stop6633" offset="0" style="stop-color:#703700;stop-opacity:1;" /> <stop id="stop6635" offset="1" style="stop-color:#bf5e00;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6643"> <stop id="stop6645" offset="0" style="stop-color:#fffddc;stop-opacity:1;" /> <stop id="stop6647" offset="1" style="stop-color:#ffdfbf;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6666"> <stop style="stop-color:#9fc1f2;stop-opacity:1;" offset="0" id="stop6668" /> <stop id="stop3183" offset="0.5" style="stop-color:#587eb5;stop-opacity:1;" /> <stop style="stop-color:#0c2a58;stop-opacity:1;" offset="1" id="stop6670" /> </linearGradient> <linearGradient id="linearGradient6674"> <stop id="stop6676" offset="0" style="stop-color:#001648;stop-opacity:1;" /> <stop id="stop6678" offset="1" style="stop-color:#11a9ff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3237"> <stop id="stop3239" offset="0" style="stop-color:#d5e6ff;stop-opacity:1;" /> <stop id="stop3241" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient2990"> <stop id="stop2992" offset="0" style="stop-color:#d7d7d7;stop-opacity:1;" /> <stop id="stop2994" offset="1" style="stop-color:#ffffff;stop-opacity:1;" /> </linearGradient> <filter inkscape:collect="always" id="filter3187"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.56525828" id="feGaussianBlur3189" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6404" id="linearGradient3219" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,0.8610463,375,-1.4361867)" x1="194.5" y1="123.90683" x2="104.25" y2="5.1559582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3221" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2586607,-0.5212474,-0.8274344,0.4106011,302.53945,50.055595)" cx="-16.668488" cy="86.826965" fx="-16.668488" fy="86.826965" r="60" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3223" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="73.742638" y1="15.336544" x2="78.939339" y2="16.750759" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3225" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8610463,-108.16138,-1.4361867)" spreadMethod="reflect" x1="223.32712" y1="53.784153" x2="226.659" y2="57.279232" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3227" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.5816285,1.767767e-2,2.6986249e-2,0.8878982,235.07816,5.9419094)" cx="72.020813" cy="66.344505" fx="72.020813" fy="66.344505" r="60" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3229" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="74.75" y1="14.275884" x2="78.939339" y2="16.750759" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3232" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8610463,-108.16138,-1.4361867)" spreadMethod="reflect" x1="223.32712" y1="53.784153" x2="226.659" y2="57.279232" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient3234" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="172" cy="76" fx="188.88173" fy="121.44213" r="56" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="radialGradient3236" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="172" cy="76" fx="172" fy="76" r="56" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3238" gradientUnits="userSpaceOnUse" gradientTransform="translate(97,0)" x1="179.17224" y1="123.75864" x2="173.98071" y2="65.448112" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3240" gradientUnits="userSpaceOnUse" x1="179.17224" y1="123.75864" x2="173.98071" y2="65.448112" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3242" gradientUnits="userSpaceOnUse" gradientTransform="translate(138.5,0)" x1="47.968472" y1="16.138517" x2="49.218472" y2="85.427559" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3244" gradientUnits="userSpaceOnUse" gradientTransform="translate(138.78748,-0.1385179)" x1="87.468468" y1="-0.36148256" x2="116.71847" y2="106.42756" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3246" gradientUnits="userSpaceOnUse" gradientTransform="translate(138.78748,-0.1385179)" x1="196.46846" y1="63.138515" x2="52.218468" y2="66.224457" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient3011" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="180.33144" cy="95.705101" fx="180.33144" fy="95.705101" r="56" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient3017" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="180.33144" cy="95.705101" fx="180.33144" fy="95.705101" r="56" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient3019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="180.33144" cy="95.705101" fx="180.33144" fy="95.705101" r="56" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient3022" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.9801409,-108,-10.49071)" cx="180.33144" cy="95.705101" fx="180.33144" fy="95.705101" r="56" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3040" x1="86.54718" y1="16.154284" x2="84.946472" y2="77.340378" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3044" gradientUnits="userSpaceOnUse" x1="86.54718" y1="16.154284" x2="88.73349" y2="85.671814" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3048" gradientUnits="userSpaceOnUse" x1="86.54718" y1="16.154284" x2="88.73349" y2="85.671814" gradientTransform="translate(0,-71.953293)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3052" gradientUnits="userSpaceOnUse" gradientTransform="translate(0,-70.953293)" x1="86.54718" y1="16.154284" x2="88.73349" y2="85.671814" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3056" gradientUnits="userSpaceOnUse" gradientTransform="translate(-110.95955,-70.953293)" x1="86.54718" y1="16.154284" x2="88.73349" y2="85.671814" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3060" gradientUnits="userSpaceOnUse" gradientTransform="translate(-111.95955,-71.953293)" x1="86.54718" y1="16.154284" x2="88.73349" y2="85.671814" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3066" gradientUnits="userSpaceOnUse" gradientTransform="translate(-112.95955,-71.753293)" x1="86.54718" y1="16.154284" x2="88.73349" y2="85.671814" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3068" gradientUnits="userSpaceOnUse" gradientTransform="translate(-110.95955,-70.953293)" x1="86.54718" y1="16.154284" x2="88.73349" y2="85.671814" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3071" gradientUnits="userSpaceOnUse" gradientTransform="translate(-110.95955,-70.953293)" x1="238.95955" y1="154.86557" x2="194.50755" y2="87.140793" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3073" gradientUnits="userSpaceOnUse" gradientTransform="translate(0,-71.953293)" x1="86.54718" y1="16.154284" x2="88.73349" y2="85.671814" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3076" gradientUnits="userSpaceOnUse" gradientTransform="translate(1.8266169,3.3486328)" x1="86.54718" y1="16.154284" x2="82.259415" y2="61.186066" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.8671875" inkscape:cx="157.79223" inkscape:cy="8.6239481" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" showgrid="false" inkscape:grid-points="true" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1016" inkscape:window-height="692" inkscape:window-x="360" inkscape:window-y="67"> <inkscape:grid type="xygrid" id="grid2576" spacingx="4px" spacingy="4px" empspacing="2" /> </sodipodi:namedview> <metadata id="metadata2611"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1"> <path sodipodi:nodetypes="ccsccccccccccc" id="path2488" d="M 73.21875,12.165446 L 5.55194,61.147784 C 4.5686,61.853052 4,62.898046 4,64 C 4,65.101954 4.5686,66.146948 5.55194,66.852216 L 73.90625,115.82531 C 78.04937,118.4557 84,118.82842 84,113 L 84,88.000004 L 116,88.000004 C 118.38204,88.000658 120.00076,86.051051 120,84 L 120,44 C 120.00076,41.94895 118.38204,39.999344 116,40 L 84,40 L 84,15.999999 C 84,12.108863 76.97948,9.4467058 73.21875,12.165446 z" style="fill:url(#linearGradient3409);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path sodipodi:nodetypes="ccsccccccccccc" id="path3532" d="M 73.21875,12.165446 L 5.55194,61.147784 C 4.5686,61.853052 4,62.898046 4,64 C 4,65.101954 4.5686,66.146948 5.55194,66.852216 L 73.90625,115.82531 C 78.04937,118.4557 84,118.82842 84,113 L 84,88.000004 L 116,88.000004 C 118.38204,88.000658 120.00076,86.051051 120,84 L 120,44 C 120.00076,41.94895 118.38204,39.999344 116,40 L 84,40 L 84,15.999999 C 84,12.108863 76.97948,9.4467058 73.21875,12.165446 z" style="opacity:0.25468164;fill:url(#radialGradient3534);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path style="fill:url(#linearGradient3301);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" d="M 76.5,11.0625 C 75.422912,11.127783 74.386099,11.439286 73.5,12 L 75.875,19.625 L 84,16.46875 L 84,16 C 84,13.081648 80.061079,10.84666 76.5,11.0625 z" id="path3272" /> <path id="path3519" d="M 115.65112,40 C 115.31168,41.154561 113.08862,46.125 113.08862,46.125 L 119.83862,46.09375 L 119.83862,44 C 119.83938,41.94895 118.22066,39.999344 115.83862,40 L 115.65112,40 z" style="opacity:0.6142322;fill:url(#linearGradient3521);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3443)" transform="matrix(1,0,0,-1,0,128.125)" /> <path style="fill:url(#radialGradient3455);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 73.21875,12.165446 L 5.55194,61.147784 C 4.5686,61.853052 4,62.898046 4,64 C 4,65.101954 4.5686,66.146948 5.55194,66.852216 L 73.90625,115.82531 C 78.04937,118.4557 84,118.82842 84,113 L 84,88.000004 L 116,88.000004 C 118.38204,88.000658 120.00076,86.051051 120,84 L 120,44 C 120.00076,41.94895 118.38204,39.999344 116,40 L 84,40 L 84,15.999999 C 84,12.108863 76.97948,9.4467058 73.21875,12.165446 z" id="path3447" sodipodi:nodetypes="ccsccccccccccc" /> <path id="path3391" d="M 72.5,11.0625 C 71.422912,11.127783 70.386099,11.439286 69.5,12 L 71.875,19.625 L 80,16.46875 L 80,16 C 80,13.081648 76.061079,10.84666 72.5,11.0625 z" style="opacity:0.70411987;fill:url(#linearGradient3393);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" transform="matrix(0.8316412,0,0,-1,17.4687,128.78415)" sodipodi:nodetypes="cccccc" /> <path transform="matrix(-2.8382138e-2,-0.9995972,-0.9995972,2.8382138e-2,163.11805,158.48653)" style="opacity:0.74906365;fill:url(#linearGradient3530);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3443)" d="M 115.65112,40 C 115.31168,41.154561 113.08862,46.125 113.08862,46.125 L 119.83862,46.09375 L 119.83862,44 C 119.83938,41.94895 118.22066,39.999344 115.83862,40 L 115.65112,40 z" id="path3528" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> <g style="fill:url(#radialGradient3011);fill-opacity:1;stroke:none;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" transform="matrix(1,0,0,0.8609865,-108,-1.4349776)" id="g3472"> <path sodipodi:nodetypes="ccccccccccc" id="path3474" d="M 181.55044,21.46494 L 117.50547,73.806959 C 116.11967,75.416501 116.3415,76.828137 117.40303,78.061061 L 180,129.07866 C 184,132.6608 188,132.85189 188,129.07866 L 188,99.229172 L 224,99.229172 L 224,52.770836 L 188,52.770836 L 188,23.929232 C 188,20.738359 184.84713,19.254283 181.55044,21.46494 z" style="fill:url(#radialGradient3011);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> <g style="fill:none;fill-opacity:1;stroke:url(#linearGradient2226);stroke-width:1.07770979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3187)" transform="matrix(1,0,0,0.8609865,-205.20303,-1.6349776)" id="g3469"> <path sodipodi:nodetypes="ccccccccccc" id="path3471" d="M 278.55044,21.46494 L 214.10547,73.806959 C 212.71967,75.416501 212.9415,76.828137 214.00303,78.061061 L 277,129.07866 C 281,132.6608 285,132.85189 285,129.07866 L 285,99.229172 L 321,99.229172 L 321,52.770836 L 285,52.770836 L 285,23.929232 C 285,20.738359 281.84713,19.254283 278.55044,21.46494 z" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2228);stroke-width:1.07770979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> <path style="opacity:1;fill:url(#linearGradient3044);fill-opacity:1;stroke:none;stroke-width:0.10030345000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15000000000000036;stroke-opacity:1" d="M 76.5 16.15625 C 75.589703 16.181967 74.592716 16.436454 73.5625 17.03125 L 9.5 62.125 C 8.1141997 63.510796 8.34472 64.719719 9.40625 65.78125 L 10.8125 66.78125 C 24.774233 70.043458 40.330414 71.875 56.75 71.875 C 78.607935 71.875 98.947017 68.650116 116 63.09375 L 116 44 L 80 44 L 80 19.15625 C 80 17.267482 78.502653 16.099672 76.5 16.15625 z " id="path2420" /> <path style="opacity:1;fill:url(#linearGradient3076);fill-opacity:1;stroke:none;stroke-width:0.10030345000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15000000000000036;stroke-opacity:1" d="M 76.5,16.12845 C 75.589703,16.154167 74.592716,16.408654 73.5625,17.00345 L 9.499997,62.0972 C 8.618937,62.978256 8.401207,63.789056 8.624997,64.5347 C 8.743157,64.083141 9.004577,63.592622 9.499997,63.0972 L 73.5625,18.00345 C 74.592716,17.408654 75.589703,17.154167 76.5,17.12845 C 78.502653,17.071872 80,18.239682 80,20.12845 L 80,19.12845 C 80,17.239682 78.502653,16.071872 76.5,16.12845 z M 80,43.972199 L 80,44.972199 L 116,44.972199 L 116,43.972199 L 80,43.972199 z" id="path3046" sodipodi:nodetypes="ccccccscccccccc" /> <path style="opacity:1;fill:url(#linearGradient3071);fill-opacity:1;stroke:none;stroke-width:0.10030345000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15000000000000036;stroke-opacity:1" d="M 78.060277,16.1875 C 78.653643,16.707072 78.997778,17.457136 78.997777,18.375 L 78.997777,43.21875 L 79.997777,19.15625 C 79.997777,17.444147 79.78206,16.339843 78.060277,16.1875 z M 116,44 L 114.99778,62.3125 C 97.944794,67.868866 77.605714,71.09375 55.747777,71.09375 C 39.834912,71.09375 24.748338,69.356836 11.122777,66.28125 L 11.810277,66.78125 C 25.772008,70.043458 41.328191,71.875 57.747777,71.875 C 79.605714,71.875 98.944794,68.650116 115.99778,63.09375 L 116,44 z" id="path3054" sodipodi:nodetypes="cccccccsccscc" /> </g> </svg> ������������������������������������MP3Diags-1.0.12.079/src/images/mode_file.svg��������������������������������������������������������0000644�0001750�0000144�00000114145�10737543502�017200� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2606" sodipodi:version="0.32" inkscape:version="0.45+devel" version="1.0" sodipodi:docname="sound1.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:docbase="/home/david/Progetti/sandbox"> <defs id="defs2608"> <linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient3894" gradientUnits="userSpaceOnUse" x1="54.103237" y1="32.580181" x2="32.584381" y2="31.295557" gradientTransform="matrix(0.6736273,0,0,0.6880491,42.39699,15.073568)" /> <radialGradient cx="54.212399" cy="18.0903" r="26.416201" id="XMLID_14_" gradientUnits="userSpaceOnUse"> <stop style="stop-color:#f0ff80;stop-opacity:1" offset="0.33140001" id="stop74" /> <stop style="stop-color:#00ff00;stop-opacity:0;" offset="0.67438829" id="stop3926" /> </radialGradient> <radialGradient inkscape:collect="always" xlink:href="#XMLID_14_" id="radialGradient3885" gradientUnits="userSpaceOnUse" cx="54.212399" cy="18.0903" r="26.416201" gradientTransform="matrix(0.624346,0,0,0.624346,45.032334,16.880096)" /> <linearGradient id="linearGradient8528"> <stop style="stop-color:#888888;stop-opacity:0.39215687;" offset="0" id="stop8530" /> <stop id="stop8540" offset="0.5" style="stop-color:#888888;stop-opacity:1;" /> <stop style="stop-color:#888888;stop-opacity:0.39215687;" offset="1" id="stop8532" /> </linearGradient> <radialGradient gradientUnits="userSpaceOnUse" r="65.999802" cy="25" cx="60" id="XMLID_11_"> <stop id="stop7985" style="stop-color:#77DE6C" offset="0" /> <stop id="stop7987" style="stop-color:#0A8000" offset="1" /> </radialGradient> <radialGradient style="fill-opacity:1.0;fill:url(#linearGradient6728)" gradientUnits="userSpaceOnUse" r="25.1951" cy="100" cx="23.7837" id="radialGradient4397"> <stop offset="0" style="stop-color:#2eb800;stop-opacity:1;" id="stop4401" /> <stop id="stop4403" style="stop-color:#003a00;stop-opacity:1;" offset="1" /> </radialGradient> <filter inkscape:collect="always" id="filter3619"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.69944247" id="feGaussianBlur3621" /> </filter> <linearGradient y2="19.9497" x2="52.9131" y1="8.6162" x1="62.2461" gradientUnits="userSpaceOnUse" id="linearGradient5332"> <stop id="stop5334" style="stop-color:#000000;stop-opacity:0;" offset="0" /> <stop id="stop5336" style="stop-color:#07631a;stop-opacity:1;" offset="1" /> </linearGradient> <filter inkscape:collect="always" x="-0.073310805" width="1.1466216" y="-0.13902832" height="1.2780566" id="filter2844"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.73249726" id="feGaussianBlur2846" /> </filter> <linearGradient id="linearGradient2848"> <stop style="stop-color:#c3ff6a;stop-opacity:1;" offset="0" id="stop2850" /> <stop style="stop-color:#a6ff88;stop-opacity:0;" offset="1" id="stop2852" /> </linearGradient> <filter inkscape:collect="always" id="filter5558"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.61029092" id="feGaussianBlur5560" /> </filter> <radialGradient gradientUnits="userSpaceOnUse" fy="88.667" fx="17.1172" r="14" cy="94" cx="19.7837" id="radialGradient4531"> <stop id="stop4533" style="stop-color:#ffffff;stop-opacity:1;" offset="0" /> <stop offset="0.5" style="stop-color:#ffffff;stop-opacity:0.70886075;" id="stop4537" /> <stop id="stop4535" style="stop-color:#ffffff;stop-opacity:0;" offset="1" /> </radialGradient> <filter inkscape:collect="always" x="-0.12256312" width="1.2451262" y="-0.1775055" height="1.355011" id="filter6116"> <feGaussianBlur inkscape:collect="always" stdDeviation="2.0368781" id="feGaussianBlur6118" /> </filter> <linearGradient id="linearGradient4540"> <stop style="stop-color:#008800;stop-opacity:1;" offset="0" id="stop4542" /> <stop style="stop-color:#0aa800;stop-opacity:0.60759491;" offset="1" id="stop4544" /> </linearGradient> <radialGradient id="XMLID_10_" cx="23.7837" cy="100" r="25.1951" gradientUnits="userSpaceOnUse" style="fill-opacity:1.0;fill:url(#linearGradient6728)"> <stop offset="0" style="stop-color:#287f00;stop-opacity:1;" id="stop35" /> <stop id="stop9094" style="stop-color:#3cf000;stop-opacity:1;" offset="0.5" /> <stop offset="1" style="stop-color:#003a00;stop-opacity:1;" id="stop43" /> </radialGradient> <filter inkscape:collect="always" x="-0.558942" width="2.117884" y="-0.012263282" height="1.0245266" id="filter5551"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.465785" id="feGaussianBlur5553" /> </filter> <linearGradient id="linearGradient4390"> <stop style="stop-color:#00a208;stop-opacity:1;" offset="0" id="stop4392" /> <stop id="stop4398" offset="0.5" style="stop-color:#dfffa8;stop-opacity:1;" /> <stop style="stop-color:#8aff47;stop-opacity:0.63291138;" offset="1" id="stop4394" /> </linearGradient> <linearGradient id="XMLID_9_" gradientUnits="userSpaceOnUse" x1="40.1172" y1="49" x2="48.1172" y2="49"> <stop offset="0" style="stop-color:#008e00;stop-opacity:1;" id="stop16" /> <stop offset="0.2294" style="stop-color:#008700" id="stop18" /> <stop offset="0.5127" style="stop-color:#007800" id="stop20" /> <stop offset="0.8231" style="stop-color:#005F00" id="stop22" /> <stop offset="1" style="stop-color:#004D00" id="stop24" /> </linearGradient> <linearGradient id="XMLID_13_" gradientUnits="userSpaceOnUse" x1="62.2461" y1="8.6162" x2="52.9131" y2="19.9497"> <stop offset="0" style="stop-color:#000000;stop-opacity:1;" id="stop88" /> <stop offset="1" style="stop-color:#000000;stop-opacity:0;" id="stop104" /> </linearGradient> <linearGradient id="linearGradient10207"> <stop style="stop-color:#a2a2a2;stop-opacity:1;" offset="0" id="stop10209" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop10211" /> </linearGradient> <linearGradient id="XMLID_12_" gradientUnits="userSpaceOnUse" x1="96" y1="104" x2="88.000198" y2="96.000198"> <stop offset="0" style="stop-color:#888A85" id="stop83" /> <stop offset="0.0072" style="stop-color:#8C8E89" id="stop85" /> <stop offset="0.0673" style="stop-color:#ABACA9" id="stop87" /> <stop offset="0.1347" style="stop-color:#C5C6C4" id="stop89" /> <stop offset="0.2652576" style="stop-color:#DBDBDA" id="stop91" /> <stop offset="0.37646064" style="stop-color:#EBEBEB" id="stop93" /> <stop offset="0.48740286" style="stop-color:#F7F7F6" id="stop95" /> <stop offset="0.6324091" style="stop-color:#FDFDFD" id="stop97" /> <stop offset="1" style="stop-color:#FFFFFF" id="stop99" /> </linearGradient> <radialGradient id="XMLID_8_" cx="102" cy="112.3047" r="139.55859" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#b7b8b9;stop-opacity:1;" id="stop41" /> <stop offset="0.18851049" style="stop-color:#ECECEC" id="stop47" /> <stop offset="0.25718147" style="stop-color:#FAFAFA" id="stop49" /> <stop offset="0.30111277" style="stop-color:#FFFFFF" id="stop51" /> <stop offset="0.5313" style="stop-color:#FAFAFA" id="stop53" /> <stop offset="0.8449" style="stop-color:#EBECEC" id="stop55" /> <stop offset="1" style="stop-color:#E1E2E3" id="stop57" /> </radialGradient> <filter inkscape:collect="always" x="-0.19200002" width="1.3839999" y="-0.19199999" height="1.3839999" id="filter6697"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.9447689" id="feGaussianBlur6699" /> </filter> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath7084"> <path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 72,88 L 40,120 L 32,120 L 32,80 L 72,80 L 72,88 z" id="path7086" /> </clipPath> <radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient9437" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.9996653,2e-6,3.0160848e-3)" cx="102" cy="112.3047" r="139.55859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient10207" id="linearGradient10213" x1="98.617439" y1="106.41443" x2="91.228737" y2="99.254974" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" id="filter2770"> <feGaussianBlur inkscape:collect="always" stdDeviation="2.0786429" id="feGaussianBlur2772" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="radialGradient7858" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.2670157,0,81.512404)" cx="45.43161" cy="111.20621" fx="45.43161" fy="111.20621" r="33.764351" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient7860" gradientUnits="userSpaceOnUse" x1="40.1172" y1="49" x2="48.1172" y2="49" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4390" id="linearGradient7862" gradientUnits="userSpaceOnUse" x1="44.142799" y1="3.4933131" x2="44.142799" y2="94.157005" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="linearGradient7864" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.9999508,19.75779,0)" x1="44.117001" y1="88.249001" x2="44.117001" y2="83.652809" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient7866" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8419836,19.882588,18.956994)" x1="0.1174117" y1="101.0003" x2="43.927124" y2="92.500053" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4540" id="linearGradient7868" gradientUnits="userSpaceOnUse" x1="3.9885471" y1="100.01298" x2="43.874181" y2="100.01298" /> <radialGradient inkscape:collect="always" xlink:href="#radialGradient4531" id="radialGradient7870" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6862309,-0.2788753,0.2607269,0.6833644,-6.7420546e-2,33.863485)" cx="22.501722" cy="91.356857" fx="19.835222" fy="86.023857" r="14" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2848" id="radialGradient7872" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-2.6486575e-2,1.3961697e-2,0.5271235,18.16764,52.58348)" cx="27.127048" cy="113.89391" fx="27.127048" fy="113.89391" r="11.990002" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5332" id="linearGradient7874" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,39.75779,128)" x1="22.025112" y1="29.212114" x2="21.785669" y2="7.9726162" /> <linearGradient inkscape:collect="always" xlink:href="#radialGradient4397" id="linearGradient7876" gradientUnits="userSpaceOnUse" gradientTransform="scale(1,0.9999508)" x1="92.25" y1="8.4984522" x2="68" y2="15.500762" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2848" id="linearGradient7878" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.962555,0,0,0.95911,3.8148459,-0.5857864)" x1="80.965881" y1="4.8331532" x2="76.376823" y2="14.051684" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8534" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8536" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8538" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8559" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8561" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8563" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8565" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8567" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8569" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8603" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8605" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8607" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8609" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8611" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8528" id="linearGradient8613" gradientUnits="userSpaceOnUse" x1="83.806137" y1="33.289322" x2="83.806137" y2="92.312012" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient9414" gradientUnits="userSpaceOnUse" x1="40.1172" y1="49" x2="48.1172" y2="49" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4390" id="linearGradient9416" gradientUnits="userSpaceOnUse" x1="44.142799" y1="3.4933131" x2="44.142799" y2="94.157005" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="linearGradient9418" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.9999508,19.75779,0)" x1="44.117001" y1="88.249001" x2="44.117001" y2="83.652809" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient9420" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8419836,19.882588,18.956994)" x1="0.1174117" y1="101.0003" x2="43.927124" y2="92.500053" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4540" id="linearGradient9422" gradientUnits="userSpaceOnUse" x1="3.9885471" y1="100.01298" x2="43.874181" y2="100.01298" /> <radialGradient inkscape:collect="always" xlink:href="#radialGradient4531" id="radialGradient9424" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6862309,-0.2788753,0.2607269,0.6833644,-6.7420546e-2,33.863485)" cx="22.501722" cy="91.356857" fx="19.835222" fy="86.023857" r="14" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2848" id="radialGradient9426" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-2.6486575e-2,1.3961697e-2,0.5271235,18.16764,52.58348)" cx="27.127048" cy="113.89391" fx="27.127048" fy="113.89391" r="11.990002" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5332" id="linearGradient9428" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,39.75779,128)" x1="22.025112" y1="29.212114" x2="21.785669" y2="7.9726162" /> <linearGradient inkscape:collect="always" xlink:href="#radialGradient4397" id="linearGradient9430" gradientUnits="userSpaceOnUse" gradientTransform="scale(1,0.9999508)" x1="92.25" y1="8.4984522" x2="68" y2="15.500762" /> <linearGradient inkscape:collect="always" xlink:href="#radialGradient4397" id="linearGradient9433" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.64,0,0,0.6451296,24.32,20.000001)" x1="92.25" y1="8.4984522" x2="68" y2="15.500762" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient9440" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6433337,0,0,0.5432152,37.044465,32.23032)" x1="0.1174117" y1="101.0003" x2="43.927124" y2="92.500053" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="linearGradient9443" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.64,0,0,0.6451296,36.964986,20.000001)" x1="44.117001" y1="88.249001" x2="44.117001" y2="83.652809" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient9447" gradientUnits="userSpaceOnUse" x1="40.1172" y1="49" x2="48.1172" y2="49" gradientTransform="matrix(0.64,0,0,0.6451296,37.04512,20.000001)" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="radialGradient10249" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.2670157,0,81.512404)" cx="45.43161" cy="111.20621" fx="45.43161" fy="111.20621" r="33.764351" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4390" id="linearGradient10253" gradientUnits="userSpaceOnUse" x1="44.142799" y1="3.4933131" x2="44.142799" y2="94.157005" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_13_" id="linearGradient3910" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4999999,0,0,0.5990894,43.9415,23.614063)" x1="44.117001" y1="88.249001" x2="44.117001" y2="83.652809" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient3914" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4848485,0,0,0.6314195,44.549334,20.000001)" x1="40.1172" y1="49" x2="48.1172" y2="49" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient4914" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6433337,0,0,0.5432152,37.044465,32.23032)" x1="0.1174117" y1="101.0003" x2="43.927124" y2="92.500053" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4540" id="linearGradient4916" gradientUnits="userSpaceOnUse" x1="3.9885471" y1="100.01298" x2="43.874181" y2="100.01298" /> <radialGradient inkscape:collect="always" xlink:href="#radialGradient4531" id="radialGradient4918" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6862309,-0.2788753,0.2607269,0.6833644,-6.7420546e-2,33.863485)" cx="22.501722" cy="91.356857" fx="19.835222" fy="86.023857" r="14" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2848" id="radialGradient4920" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-2.6486575e-2,1.3961697e-2,0.5271235,18.16764,52.58348)" cx="27.127048" cy="113.89391" fx="27.127048" fy="113.89391" r="11.990002" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5332" id="linearGradient4922" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,39.75779,128)" x1="22.025112" y1="29.212114" x2="21.785669" y2="7.9726162" /> <filter inkscape:collect="always" id="filter6448"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.37043075" id="feGaussianBlur6450" /> </filter> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8284271" inkscape:cx="64" inkscape:cy="60.344296" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" showgrid="true" inkscape:grid-points="true" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1016" inkscape:window-height="692" inkscape:window-x="0" inkscape:window-y="0" /> <metadata id="metadata2611"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1"> <path style="opacity:0.5;fill:#000000;fill-opacity:1;filter:url(#filter2770)" d="M 16,8 L 16,120 C 16,120 79.15625,120 79.15625,120 L 79.1875,120 C 79.187503,120 91.09375,110.09375 96.59375,104.59375 C 102.09375,99.09375 112,87.1875 112,87.1875 L 112,87.15625 L 112,8 L 16,8 z" id="path7865" sodipodi:nodetypes="csccscccc" transform="matrix(1.0416667,0,0,1.0267857,-2.6666667,-1.2142891)" /> <path style="fill:#ffffff;fill-opacity:1" d="M 16.000001,8 L 16,120 C 16,120 79.146418,120 79.146418,120 L 112,87.14642 L 112,8 L 16.000001,8 z" id="path34" sodipodi:nodetypes="cccccc" /> <path style="fill:url(#radialGradient9437);fill-opacity:1" d="M 18.000002,9.0000034 C 17.449002,9.0000034 17.000002,9.4488534 17.000002,9.9996684 L 17.000002,117.96352 C 17.000002,118.51533 17.449002,118.96318 18.000002,118.96318 L 77.171999,118.96318 C 77.434999,118.96318 79.934679,119.08131 80.12068,118.89438 L 110.707,88.094202 C 110.894,87.907264 111,85.40942 111,85.146508 L 111,9.9996684 C 111,9.4488534 110.552,9.0000034 110,9.0000034 L 18.000002,9.0000034 z" id="path59" sodipodi:nodetypes="ccccccccccc" /> <path d="M 41.879531,115.98249 C 41.879531,115.98249 66.18914,91.672876 66.18914,91.672876 C 66.18914,91.672876 56.836,94.586 46.586,94.586 C 46.586,104.836 41.879531,115.98249 41.879531,115.98249 z" id="path5540" style="opacity:0.4;fill:#000000;fill-opacity:1;filter:url(#filter6697)" sodipodi:nodetypes="cccc" clip-path="url(#clipPath7084)" transform="translate(40,0)" /> <path style="fill:url(#linearGradient10213);fill-opacity:1" id="path14523" d="M 79.172,120 C 79.172,120 91.086,110.086 96.586,104.586 C 102.086,99.086 112,87.172 112,87.172 C 112,87.172 98.25,96 88,96 C 88,106.25 79.172,120 79.172,120 z" sodipodi:nodetypes="csccc" /> <g id="g8542" transform="matrix(0.7796007,0,0,0.8187773,-28.43011,-15.233625)"> <g style="opacity:0.8;fill:url(#linearGradient8563);fill-opacity:1" transform="translate(76,24)" id="g7973"> <radialGradient style="fill-opacity:1.0;fill:url(#linearGradient8536)" id="radialGradient8130" cx="60" cy="25" r="66" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#77DE6C;fill-opacity:1.0;fill:url(#linearGradient8536)" id="stop7976" /> <stop offset="1" style="stop-color:#0A8000;fill-opacity:1.0;fill:url(#linearGradient8536)" id="stop7978" /> </radialGradient> <path d="M 76.306,44.035 C 81.057,49.225 83.67,55.96 83.67,63 C 83.67,70.041 81.057,76.775 76.308,81.965 L 80.077,85.414 C 85.69,79.281 88.779,71.32 88.779,63 C 88.779,54.68 85.69,46.719 80.076,40.585 L 76.306,44.035 z" id="path7980" style="fill:url(#linearGradient8565);fill-opacity:1" /> </g> <g style="opacity:0.6;fill:url(#linearGradient8567);fill-opacity:1" transform="translate(76,24)" id="g7982"> <radialGradient style="fill-opacity:1.0;fill:url(#linearGradient8538)" id="radialGradient8136" cx="60" cy="25" r="65.999802" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#77DE6C;fill-opacity:1.0;fill:url(#linearGradient8538)" id="stop8138" /> <stop offset="1" style="stop-color:#0A8000;fill-opacity:1.0;fill:url(#linearGradient8538)" id="stop8140" /> </radialGradient> <path d="M 83.849,37.137 C 90.323,44.215 93.89,53.399 93.89,63 C 93.89,72.602 90.324,81.785 83.847,88.861 L 87.618,92.312 C 94.958,84.291 99,73.881 99,63 C 99,52.119 94.958,41.709 87.619,33.688 L 83.849,37.137 z" id="path7989" style="fill:url(#linearGradient8569);fill-opacity:1" /> </g> </g> <g transform="matrix(-0.7796007,0,0,0.8187773,156.43013,-15.233625)" id="g8571"> <g id="g8573" transform="translate(76,24)" style="fill:url(#linearGradient8603);fill-opacity:1"> <radialGradient gradientUnits="userSpaceOnUse" r="66.000099" cy="25" cx="60" id="radialGradient8575" style="fill-opacity:1.0;fill:url(#linearGradient8534)"> <stop id="stop8577" style="stop-color:#77DE6C;fill-opacity:1.0;fill:url(#linearGradient8534)" offset="0" /> <stop id="stop8579" style="stop-color:#0A8000;fill-opacity:1.0;fill:url(#linearGradient8534)" offset="1" /> </radialGradient> </g> <g id="g8583" transform="translate(76,24)" style="opacity:0.8;fill:url(#linearGradient8607);fill-opacity:1"> <radialGradient gradientUnits="userSpaceOnUse" r="66" cy="25" cx="60" id="radialGradient8585" style="fill-opacity:1.0;fill:url(#linearGradient8536)"> <stop id="stop8587" style="stop-color:#77DE6C;fill-opacity:1.0;fill:url(#linearGradient8536)" offset="0" /> <stop id="stop8589" style="stop-color:#0A8000;fill-opacity:1.0;fill:url(#linearGradient8536)" offset="1" /> </radialGradient> <path style="fill:url(#linearGradient8609);fill-opacity:1" id="path8591" d="M 76.306,44.035 C 81.057,49.225 83.67,55.96 83.67,63 C 83.67,70.041 81.057,76.775 76.308,81.965 L 80.077,85.414 C 85.69,79.281 88.779,71.32 88.779,63 C 88.779,54.68 85.69,46.719 80.076,40.585 L 76.306,44.035 z" /> </g> <g id="g8593" transform="translate(76,24)" style="opacity:0.6;fill:url(#linearGradient8611);fill-opacity:1"> <radialGradient gradientUnits="userSpaceOnUse" r="65.999802" cy="25" cx="60" id="radialGradient8595" style="fill-opacity:1.0;fill:url(#linearGradient8538)"> <stop id="stop8597" style="stop-color:#77DE6C;fill-opacity:1.0;fill:url(#linearGradient8538)" offset="0" /> <stop id="stop8599" style="stop-color:#0A8000;fill-opacity:1.0;fill:url(#linearGradient8538)" offset="1" /> </radialGradient> <path style="fill:url(#linearGradient8613);fill-opacity:1" id="path8601" d="M 83.849,37.137 C 90.323,44.215 93.89,53.399 93.89,63 C 93.89,72.602 90.324,81.785 83.847,88.861 L 87.618,92.312 C 94.958,84.291 99,73.881 99,63 C 99,52.119 94.958,41.709 87.619,33.688 L 83.849,37.137 z" /> </g> </g> <g id="g6452"> <path transform="matrix(0.6065569,0,0,-0.5060088,24.923143,151.70934)" d="M 79.195961,111.20621 A 33.764351,9.0156116 0 1 1 11.667259,111.20621 A 33.764351,9.0156116 0 1 1 79.195961,111.20621 z" sodipodi:ry="9.0156116" sodipodi:rx="33.764351" sodipodi:cy="111.20621" sodipodi:cx="45.43161" id="path2268" style="opacity:0.6;fill:url(#radialGradient10249);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" sodipodi:type="arc" /> <path sodipodi:nodetypes="ccccc" id="polygon26" d="M 64,20.000001 L 68,20 L 68,84 L 64,80.616273 L 64,20.000001 z" style="fill:url(#linearGradient3914)" /> <path transform="matrix(1,0,0,-0.6586861,20.883,82.719523)" style="opacity:0.7;fill:url(#linearGradient10253);fill-opacity:1;filter:url(#filter5551)" id="path28" d="M 43.117,3 C 43.117,8.489 43.117,89.342 43.117,93.657 C 43.93,93.861 44.122,93.909 45.117,94.157 C 45.117,87.29 45.117,8.41 45.117,3 C 44.18,3 44.055,3 43.117,3 z" /> <path sodipodi:nodetypes="cscccc" style="opacity:0.3;fill:url(#linearGradient3910);fill-opacity:1" id="path30" d="M 68,73.392341 C 67.143,72.181581 66.1255,72.280489 64.9565,71.342915 C 64.642499,71.091297 64.3225,70.860048 64,70.641381 L 64,81.126644 L 68,84.443026 L 68,73.392341 z" /> <g transform="matrix(1.0439542,-0.1256516,0.123061,0.9926215,-13.588253,5.4747774)" id="g4907"> <path style="fill:url(#linearGradient4914);fill-opacity:1" id="path45" d="M 37.422745,90.448873 C 39.094769,95.838112 47.227793,98.705202 55.587915,96.853383 C 63.948679,95.001015 69.368766,89.130492 67.697385,83.741249 C 66.02536,78.352554 57.892979,75.48492 49.532858,77.337284 C 41.172737,79.189648 35.750721,85.060176 37.422745,90.448873 z" /> <path style="opacity:0.9;fill:url(#linearGradient4916);fill-opacity:1;filter:url(#filter6116)" id="path49" d="M 43.576,95.141 C 41.685,87.924 31.358,84.38 20.508,87.226 C 9.659,90.072 2.397,98.231 4.288,105.45 C 5.392,109.668 9.388,112.616 14.675,113.783 C 11.444,112.132 9.023,109.457 8.13,106.047 C 6.226,98.778 11.933,90.983 20.878,88.635 C 29.823,86.288 38.619,90.279 40.523,97.547 C 41.417,100.957 40.618,104.478 38.612,107.503 C 42.646,103.891 44.681,99.358 43.576,95.141 z" transform="matrix(0.686105,0,0,0.5432152,36.321363,32.23032)" /> <path d="M 34.447549,87.550082 C 26.821174,91.714578 22.351297,97.864018 24.881162,100.7108 C 25.981924,101.94913 28.11253,102.24758 29.704981,102.27971 C 33.829576,102.36316 39.151934,100.85171 43.939512,98.237452 C 51.565138,94.073903 56.035552,87.922908 53.504726,85.076463 C 52.403963,83.838127 50.27336,83.539682 48.680904,83.507544 C 44.55556,83.425047 39.235126,84.935827 34.447549,87.550082 z" id="path70" style="opacity:0.8;fill:url(#radialGradient4918);fill-opacity:1;filter:url(#filter5558)" transform="matrix(0.7077814,0,0,0.6148065,20.645198,26.252134)" /> <path d="M 46.87479,109 C 39.70279,110.882 34.28679,109.601 34.94979,112.134 C 35.22279,113.179 36.25179,113.966 37.06579,114.442 C 39.30679,115.753 43.49679,116.681 48.53679,115.359 C 55.70779,113.477 59.46279,108.399 58.79979,105.867 C 58.52679,104.821 57.49779,104.035 56.68379,103.558 C 54.44279,102.248 51.91379,107.678 46.87479,109 z" id="path72" style="opacity:0.6;fill:url(#radialGradient4920);fill-opacity:1;filter:url(#filter2844)" transform="matrix(0.7114081,0.1240747,-0.1849201,0.7638422,40.01216,0.650991)" /> <path style="opacity:0.8;fill:url(#linearGradient4922);fill-opacity:1;filter:url(#filter3619)" d="M 87.84375,97.625 C 87.195821,106.01465 79.50551,114.10563 68.59375,116.96875 C 55.59875,120.37775 42.942749,115.1085 40.34375,105.1875 C 40.110816,104.29842 39.966685,103.39736 39.90625,102.5 C 39.798559,104.06171 39.937656,105.6375 40.34375,107.1875 C 42.942749,117.1085 55.59875,122.37775 68.59375,118.96875 C 80.371374,115.87844 88.376529,106.70048 87.84375,97.625 z" id="path2338" clip-path="none" transform="matrix(0.6181529,0,0,0.5432152,13.113494,32.23032)" /> </g> <path sodipodi:nodetypes="ccccc" d="M 74.474445,31.506933 C 71.055118,27.422674 69.328611,22.448767 68.058151,20 L 68,36.38856 C 91.135055,46.126519 76.191526,72 76.191526,72 C 93.282123,54.396264 77.621635,35.265746 74.474445,31.506933 z" style="fill:url(#linearGradient3894);fill-opacity:1" id="path29" /> <path d="M 73.283992,31.834433 C 70.159765,28.004069 69.501081,25.426769 68.767471,24.347899 C 68.767471,36.307872 72.659648,36.165521 69.085889,35.47874 C 75.426749,38.7397 80.299771,43.233118 82.158445,48 C 80.073753,40.152595 75.917481,35.062926 73.283992,31.834433 z" style="fill:url(#radialGradient3885);filter:url(#filter6448)" id="path90" /> </g> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/sort_asc.svg���������������������������������������������������������0000644�0001750�0000144�00000004313�11163115364�017060� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="680" height="680" id="svg2273" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" sodipodi:docname="sort_asc.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2275" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="375" inkscape:cy="405.71429" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" showgrid="true" showguides="true" height="680px" width="680px" /> <metadata id="metadata2278"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-47.400002,-191.39075)"> <path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:24.38571167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 326.81224,243.58361 L 326.81224,699.28499 L 226.59286,699.28499 L 366.9,832.19789 L 507.20714,699.28499 L 406.98776,699.28499 L 406.98776,243.58361 L 326.81224,243.58361 z " id="path5137" /> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/save_log.svg���������������������������������������������������������0000644�0001750�0000144�00000750015�11102347372�017050� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="162" height="162" id="svg1307"> <defs id="defs1309"> <linearGradient id="linearGradient2497"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop2499" /> <stop style="stop-color:#ececec;stop-opacity:1" offset="0.5" id="stop11148" /> <stop style="stop-color:#c1c1c1;stop-opacity:1" offset="1" id="stop2501" /> </linearGradient> <radialGradient cx="-519.35938" cy="1724.4219" r="499.35941" fx="-519.35938" fy="1724.4219" id="radialGradient22425" xlink:href="#linearGradient2497" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.2631778e-2,0,0,9.760431e-2,95.425676,-122.0552)" /> <linearGradient x1="605.17242" y1="3835.6428" x2="-1062.9232" y2="1799.6183" id="linearGradient22421" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.266449e-2,95.46583,-35.606353)" /> <linearGradient x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" id="linearGradient22417" xlink:href="#linearGradient12049" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.494916e-2,95.46583,-43.1294)" /> <linearGradient id="linearGradient12049"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop12051" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop12053" /> </linearGradient> <linearGradient x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" id="linearGradient22415" xlink:href="#linearGradient12049" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.964922,0,0,0.941137,2.09495,7.906447)" /> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective177" /> <linearGradient id="linearGradient3609"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop3611" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop3613" /> </linearGradient> <linearGradient id="linearGradient2019"> <stop style="stop-color:#fff823;stop-opacity:0.84313726" offset="0" id="stop2912" /> <stop style="stop-color:#ffff02;stop-opacity:0" offset="1" id="stop2023" /> </linearGradient> <linearGradient id="linearGradient2891"> <stop style="stop-color:#3a3a3a;stop-opacity:1" offset="0" id="stop2893" /> <stop style="stop-color:#3a3a3a;stop-opacity:0" offset="1" id="stop2895" /> </linearGradient> <linearGradient id="linearGradient2881"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop2883" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop2885" /> </linearGradient> <linearGradient id="linearGradient4318"> <stop style="stop-color:#fffaa8;stop-opacity:1" offset="0" id="stop4320" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop4322" /> </linearGradient> <linearGradient id="linearGradient4309"> <stop style="stop-color:#fff727;stop-opacity:0.73333335" offset="0" id="stop4311" /> <stop style="stop-color:#ffb266;stop-opacity:0" offset="1" id="stop4313" /> </linearGradient> <linearGradient id="linearGradient4301"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop4303" /> <stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop4305" /> </linearGradient> <linearGradient id="linearGradient4246"> <stop style="stop-color:#3a3a3a;stop-opacity:0.46975088" offset="0" id="stop4248" /> <stop style="stop-color:#3a3a3a;stop-opacity:0" offset="1" id="stop4250" /> </linearGradient> <linearGradient id="linearGradient4089"> <stop style="stop-color:#3a3a3a;stop-opacity:1" offset="0" id="stop4091" /> <stop style="stop-color:#3a3a3a;stop-opacity:0" offset="1" id="stop4093" /> </linearGradient> <linearGradient id="linearGradient6250"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop6252" /> <stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop6254" /> </linearGradient> <linearGradient id="linearGradient5914"> <stop style="stop-color:#0060c8;stop-opacity:1" offset="0" id="stop5916" /> <stop style="stop-color:#003772;stop-opacity:0" offset="1" id="stop5918" /> </linearGradient> <linearGradient id="linearGradient5904"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop5906" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop5908" /> </linearGradient> <linearGradient id="linearGradient4124"> <stop style="stop-color:#002145;stop-opacity:1" offset="0" id="stop4126" /> <stop style="stop-color:#001d3d;stop-opacity:0" offset="1" id="stop4128" /> </linearGradient> <linearGradient id="linearGradient4094"> <stop style="stop-color:#4da3ff;stop-opacity:1" offset="0" id="stop4096" /> <stop style="stop-color:#004895;stop-opacity:1" offset="1" id="stop4098" /> </linearGradient> <linearGradient id="linearGradient4086"> <stop style="stop-color:#d7ebff;stop-opacity:1" offset="0" id="stop4088" /> <stop style="stop-color:#b9dbff;stop-opacity:0" offset="1" id="stop4090" /> </linearGradient> <linearGradient id="linearGradient3189"> <stop style="stop-color:#003d7f;stop-opacity:1" offset="0" id="stop3191" /> <stop style="stop-color:#004da0;stop-opacity:1" offset="0.81415927" id="stop3197" /> <stop style="stop-color:#00438a;stop-opacity:0" offset="1" id="stop3193" /> </linearGradient> <linearGradient id="linearGradient2334"> <stop style="stop-color:#a5a5a5;stop-opacity:1" offset="0" id="stop6098" /> <stop style="stop-color:#dfe1e1;stop-opacity:1" offset="0.07692308" id="stop2346" /> <stop style="stop-color:#e2dcdc;stop-opacity:1" offset="0.5" id="stop2342" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0.78201604" id="stop2348" /> <stop style="stop-color:#dfd9df;stop-opacity:1" offset="0.9005897" id="stop2344" /> <stop style="stop-color:#d5d5d5;stop-opacity:1" offset="1" id="stop6104" /> </linearGradient> <linearGradient id="linearGradient3291"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop3293" /> <stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop3295" /> </linearGradient> <linearGradient x1="-77.403809" y1="22.222563" x2="-62.398071" y2="131.117" id="linearGradient3151" xlink:href="#linearGradient6250" gradientUnits="userSpaceOnUse" /> <linearGradient x1="-77.956337" y1="159.10574" x2="-72.261574" y2="157.58188" id="linearGradient3153" xlink:href="#linearGradient6250" gradientUnits="userSpaceOnUse" /> <linearGradient x1="-59.123386" y1="163.06093" x2="-63.657074" y2="161.16936" id="linearGradient3155" xlink:href="#linearGradient6250" gradientUnits="userSpaceOnUse" /> <linearGradient x1="-63.233101" y1="162.73038" x2="-69.858452" y2="162.15964" id="linearGradient3157" xlink:href="#linearGradient6250" gradientUnits="userSpaceOnUse" /> <radialGradient cx="60.109371" cy="72.828125" r="49.681286" fx="60.109371" fy="72.828125" id="radialGradient3159" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.65927,-7.373712e-3,3.949364e-3,0.353107,17.53952,43.06677)" /> <radialGradient cx="46.320789" cy="97.558548" r="47.040867" fx="20.890965" fy="91.120483" id="radialGradient3161" xlink:href="#linearGradient4086" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.435167,0.137407,-0.138893,0.439871,44.87405,27.01182)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="67.175148" fy="62.592621" id="radialGradient3163" xlink:href="#linearGradient3189" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <linearGradient x1="49.324944" y1="32.59375" x2="94.125" y2="37.34375" id="linearGradient3165" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.65927,-7.373712e-3,7.373712e-3,0.65927,17.29013,20.7694)" spreadMethod="reflect" /> <linearGradient x1="61" y1="-8.000001" x2="52.763168" y2="22.740273" id="linearGradient3167" xlink:href="#linearGradient4124" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.567257,-0.336021,0.336021,0.567257,11.91678,43.57707)" /> <radialGradient cx="60.109371" cy="72.828125" r="49.681286" fx="60.109371" fy="72.828125" id="radialGradient3169" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.48006,-5.369582e-3,2.846636e-3,0.254539,27.75761,-6.596686)" /> <radialGradient cx="33.647404" cy="105.95415" r="47.040867" fx="27.016188" fy="85.312073" id="radialGradient3171" xlink:href="#linearGradient4086" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.17061,0.258566,-0.382999,0.247716,82.44465,-16.18971)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="67.175148" fy="62.592621" id="radialGradient3173" xlink:href="#linearGradient3189" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="53.426815" fy="78.751389" id="radialGradient3177" xlink:href="#linearGradient5914" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <linearGradient x1="79.515709" y1="38.188641" x2="59.352558" y2="38.829636" id="linearGradient3185" xlink:href="#linearGradient3291" gradientUnits="userSpaceOnUse" /> <radialGradient cx="26.689753" cy="54.472202" r="35.40966" fx="10.492155" fy="51.843987" id="radialGradient3187" xlink:href="#linearGradient5904" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.277621,4.035798e-3,-1.584782e-2,1.089994,42.19747,11.66854)" /> <linearGradient x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" id="linearGradient4082" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.986412,0,0,0.924353,-0.347729,4.01022)" /> <linearGradient id="linearGradient3058"> <stop style="stop-color:#9a7600;stop-opacity:1" offset="0" id="stop3060" /> <stop style="stop-color:#e3ad00;stop-opacity:1" offset="0.09292036" id="stop3066" /> <stop style="stop-color:#ffcd2c;stop-opacity:1" offset="0.5043171" id="stop3070" /> <stop style="stop-color:#e3ad00;stop-opacity:1" offset="0.91571385" id="stop3068" /> <stop style="stop-color:#b98d00;stop-opacity:1" offset="1" id="stop3062" /> </linearGradient> <linearGradient x1="124.45079" y1="153.10228" x2="40.305077" y2="51.042213" id="linearGradient4252" xlink:href="#linearGradient4246" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.986412,0,0,1.114461,-0.696478,-26.31741)" /> <radialGradient cx="69.647743" cy="114.19905" r="64.071327" fx="50.822227" fy="89.233253" id="radialGradient4258" xlink:href="#linearGradient4309" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.782917,-0.935261,8.371703e-2,1.343107,-56.85403,5.481532)" /> <radialGradient cx="68.972214" cy="74.718201" r="47.781246" fx="68.972214" fy="74.718201" id="radialGradient4283" xlink:href="#linearGradient4318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.301238,-9.329686e-2,1.427156e-2,0.254081,-23.47707,36.87536)" /> <linearGradient x1="79.825981" y1="98.206459" x2="114.61522" y2="65.502769" id="linearGradient4295" xlink:href="#linearGradient4089" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.690325,0,0,0.779938,34.7461,-1.375054)" /> <linearGradient x1="79.825981" y1="98.206459" x2="114.61522" y2="65.502769" id="linearGradient4297" xlink:href="#linearGradient4089" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.690325,0,0,0.779938,34.7461,-1.375054)" /> <radialGradient cx="92.454208" cy="73.55278" r="3.3587573" fx="91.043648" fy="73.809258" id="radialGradient4307" xlink:href="#linearGradient4301" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.736842,0,19.35599)" /> <radialGradient cx="92.159912" cy="132.51294" r="63.022152" fx="92.159912" fy="132.51294" id="radialGradient2887" xlink:href="#linearGradient2881" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.121997,-0.207569,5.159571e-2,0.527467,-110.2403,57.28961)" /> <linearGradient x1="113" y1="140.25" x2="65.43679" y2="64" id="linearGradient2897" xlink:href="#linearGradient2891" gradientUnits="userSpaceOnUse" /> <linearGradient x1="124.45079" y1="153.10228" x2="40.305077" y2="51.042213" id="linearGradient2930" xlink:href="#linearGradient4246" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.986412,0,0,1.114461,-0.696478,-26.31741)" /> <linearGradient x1="113" y1="140.25" x2="65.43679" y2="64" id="linearGradient2932" xlink:href="#linearGradient2891" gradientUnits="userSpaceOnUse" /> <linearGradient x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" id="linearGradient2934" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.986412,0,0,0.924353,-0.347729,4.01022)" /> <radialGradient cx="69.647743" cy="114.19905" r="64.071327" fx="50.822227" fy="89.233253" id="radialGradient2936" xlink:href="#linearGradient4309" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.782917,-0.935261,8.371703e-2,1.343107,-56.85403,5.481532)" /> <radialGradient cx="68.972214" cy="74.718201" r="47.781246" fx="68.972214" fy="74.718201" id="radialGradient2938" xlink:href="#linearGradient4318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.301238,-9.329686e-2,1.427156e-2,0.254081,-23.47707,36.87536)" /> <linearGradient x1="79.825981" y1="98.206459" x2="114.61522" y2="65.502769" id="linearGradient2942" xlink:href="#linearGradient4089" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.690325,0,0,0.779938,34.7461,-1.375054)" /> <radialGradient cx="92.454208" cy="73.55278" r="3.3587573" fx="91.043648" fy="73.809258" id="radialGradient2944" xlink:href="#linearGradient4301" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.736842,0,19.35599)" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2025" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2916" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="translate(-52.50268,-17.50089)" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2920" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="translate(-52.30268,-18.50089)" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2923" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1,180.22,-18.50089)" /> <linearGradient x1="98.177643" y1="113.32587" x2="94.729797" y2="108.5625" id="linearGradient2926" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1,180.42,-17.50089)" /> <linearGradient x1="98.177643" y1="113.32587" x2="89.072945" y2="102.22624" id="linearGradient2929" xlink:href="#linearGradient2019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1.004372,131.9173,14.846852)" /> <radialGradient cx="68.972214" cy="74.718201" r="47.781246" fx="68.972214" fy="74.718201" id="radialGradient2954" xlink:href="#linearGradient4318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.301238,-9.370473e-2,-1.427156e-2,0.255192,155.3944,51.88342)" /> <radialGradient cx="77.520203" cy="116.66548" r="64.071327" fx="58.694687" fy="91.699684" id="radialGradient2957" xlink:href="#linearGradient4309" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.5775266,-1.1711111,0.1996751,1.4444656,211.75095,25.589505)" /> <linearGradient x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" id="linearGradient2960" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.986412,0,0,0.928394,132.265,18.874603)" /> <linearGradient x1="173.96887" y1="100.2915" x2="57.130394" y2="27.459507" id="linearGradient2973" xlink:href="#linearGradient5904" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.004372,-48.50758,32.43503)" /> <radialGradient cx="92.454208" cy="73.55278" r="3.3587573" fx="91.043648" fy="73.809258" id="radialGradient2975" xlink:href="#linearGradient4301" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.736842,0,19.35599)" /> <filter id="filter3305"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.0460516" id="feGaussianBlur3307" /> </filter> <filter x="-0.15088631" width="1.3017726" y="-0.05014763" height="1.1002953" id="filter3597"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.57059479" id="feGaussianBlur3599" /> </filter> <clipPath id="clipPath3603"> <path d="M 59.441817,-44.032495 L 54.595834,-43.248559 L 56.772878,-26.089281 C 56.857443,-23.205582 58.751574,-21.03054 60.185435,-18.681576 C 61.175137,-21.90528 62.020956,-23.703942 61.607219,-26.964977 L 59.441817,-44.032495 z " style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.45699999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1;filter:url(#filter3597)" id="path3605" /> </clipPath> <radialGradient cx="105.60236" cy="61.783173" r="19.974998" fx="106.32523" fy="51.090271" id="radialGradient3615" xlink:href="#linearGradient3609" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8124666,-0.5830077,1.3642054,1.9011265,-62.61429,20.412027)" /> <filter id="filter3637"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.26548265" id="feGaussianBlur3639" /> </filter> <linearGradient x1="-48.32362" y1="102.86192" x2="-81.932449" y2="102.84682" id="linearGradient3656" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.1828673,2.958248e-2,2.3283892e-2,0.1835217,18.438484,-50.14049)" /> <radialGradient cx="60.109371" cy="72.828125" r="49.681286" fx="60.109371" fy="72.828125" id="radialGradient3658" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2825052,3.4284058e-2,1.8362653e-2,0.1513106,46.77243,-59.710362)" /> <radialGradient cx="46.320789" cy="97.558548" r="47.040867" fx="20.890965" fy="91.120483" id="radialGradient3660" xlink:href="#linearGradient4086" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.1783948,8.3505872e-2,8.4408831e-2,0.1803231,34.164873,-65.027613)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="67.175148" fy="62.592621" id="radialGradient3662" xlink:href="#linearGradient3189" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <linearGradient x1="49.324944" y1="32.59375" x2="94.125" y2="37.34375" id="linearGradient3664" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2825052,3.4284058e-2,3.4284058e-2,0.2825052,45.612899,-69.265056)" spreadMethod="reflect" /> <linearGradient x1="79.515709" y1="38.188641" x2="59.352558" y2="38.829636" id="linearGradient3666" xlink:href="#linearGradient3291" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.427877,5.678872e-2,5.678872e-2,0.427877,51.83148,-79.133689)" /> <linearGradient x1="61" y1="-8.000001" x2="52.763168" y2="22.740273" id="linearGradient3668" xlink:href="#linearGradient4124" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2617984,-0.1115619,-0.1115619,0.2617984,49.20725,-59.811324)" /> <radialGradient cx="60.109371" cy="72.828125" r="49.681286" fx="60.109371" fy="72.828125" id="radialGradient3670" xlink:href="#linearGradient4094" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2057116,2.4964472e-2,1.3236934e-2,0.109073,39.58002,-80.37994)" /> <radialGradient cx="33.647404" cy="105.95415" r="47.040867" fx="27.016188" fy="85.312073" id="radialGradient3672" xlink:href="#linearGradient4086" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-5.8316463e-2,0.1203232,0.1779439,8.4241956e-2,15.635918,-81.378967)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="67.175148" fy="62.592621" id="radialGradient3674" xlink:href="#linearGradient3189" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <radialGradient cx="26.689753" cy="54.472202" r="35.40966" fx="10.492155" fy="51.843987" id="radialGradient3676" xlink:href="#linearGradient5904" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.1166721,2.7380935e-2,0.1258115,0.5360856,31.276382,-75.854424)" /> <radialGradient cx="67.175148" cy="62.592621" r="33.941124" fx="53.426815" fy="78.751389" id="radialGradient3678" xlink:href="#linearGradient5914" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.333333,0,41.72841)" /> <linearGradient x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" id="linearGradient2366" xlink:href="#linearGradient12049" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.964922,0,0,0.941137,2.09495,7.906447)" /> <linearGradient x1="1054.6731" y1="-5.5660009" x2="-1250.6598" y2="3149.0283" id="linearGradient2368" xlink:href="#linearGradient12049" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.494916e-2,95.46583,-43.1294)" /> <linearGradient x1="605.17242" y1="3835.6428" x2="-1062.9232" y2="1799.6183" id="linearGradient2370" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.613329e-2,0,0,5.266449e-2,95.46583,-35.606353)" /> <radialGradient cx="-519.35938" cy="1724.4219" r="499.35941" fx="-519.35938" fy="1724.4219" id="radialGradient2372" xlink:href="#linearGradient2497" gradientUnits="userSpaceOnUse" gradientTransform="matrix(5.2631778e-2,0,0,9.760431e-2,95.425676,-122.0552)" /> </defs> <path d="M 49.462879,-31.750025 L 49.462879,-34.544734 L 49.462879,-31.750025 z " style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path2276" /> <path d="M -70.039321,-118.38028 L -70.039321,-121.17498 L -70.039321,-118.38028 z " style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path3206" /> <g transform="translate(112.91228,26.201359)" style="display:inline" id="layer4" /> <g transform="translate(112.91228,26.201359)" style="display:inline" id="layer5" /> <path d="M 174.05068,-147.16862 L 174.05068,-149.96333 L 174.05068,-147.16862 z " style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path6137" /> <path d="M 101.56614,-371.07382 L 101.56614,-373.86853 L 101.56614,-371.07382 z " style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path1987" /> <path d="M 149.36244,-486.39782 L 149.36244,-489.19253 L 149.36244,-486.39782 z " style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path1747" /> <rect width="1" height="0" x="138.2153" y="-458.65479" style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect1327" /> <g transform="matrix(0.8041462,0,0,0.9159764,-72.021928,-316.03016)" id="g3575"> <rect width="165.53104" height="148.89655" x="100" y="348.10345" style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.79999995;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect2604" /> <path d="M 147.4375,357 C 146.97656,357.00001 146.6328,357.07325 146.375,357.25 C 146.12109,357.42276 145.94531,357.65629 145.84375,357.9375 C 145.76953,358.14642 145.71874,358.47638 145.71875,358.90625 L 145.71875,359.59375 L 144.8125,359.59375 L 144.8125,360.4375 L 145.71875,360.4375 L 145.71875,366 L 146.78125,366 L 146.78125,360.4375 L 148,360.4375 L 148,359.59375 L 146.78125,359.59375 L 146.78125,359 C 146.78125,358.61433 146.83593,358.35938 146.96875,358.21875 C 147.10156,358.07815 147.33593,358.00001 147.65625,358 C 147.85156,358.00001 148.06249,358.02232 148.28125,358.0625 L 148.4375,357.09375 C 148.07812,357.02144 147.73437,357 147.4375,357 z M 194.6875,357.125 C 194.0625,357.12501 193.53906,357.2795 193.125,357.625 C 192.71484,357.97051 192.42968,358.45496 192.21875,359.09375 C 192.01172,359.72852 191.90625,360.58046 191.90625,361.625 C 191.90625,363.28423 192.18359,364.48356 192.75,365.21875 C 193.22265,365.82941 193.85937,366.12501 194.6875,366.125 C 195.3164,366.125 195.83984,365.97051 196.25,365.625 C 196.66406,365.27548 196.98046,364.79103 197.1875,364.15625 C 197.39453,363.51747 197.49999,362.66153 197.5,361.625 C 197.49999,360.74919 197.4414,360.04551 197.3125,359.53125 C 197.18359,359.013 197.0078,358.57632 196.78125,358.21875 C 196.55468,357.85718 196.2539,357.59509 195.90625,357.40625 C 195.55859,357.21342 195.14843,357.125 194.6875,357.125 z M 207.28125,357.125 C 206.53515,357.12501 205.94921,357.34334 205.5,357.78125 C 205.05078,358.21917 204.8125,358.76345 204.8125,359.40625 C 204.8125,359.83211 204.91406,360.19467 205.125,360.5 C 205.33594,360.80534 205.65625,361.02277 206.09375,361.1875 C 205.57031,361.32812 205.16015,361.61032 204.875,362 C 204.59375,362.38568 204.46875,362.86301 204.46875,363.4375 C 204.46875,364.20886 204.73046,364.85676 205.25,365.375 C 205.76953,365.88924 206.46484,366.12501 207.3125,366.125 C 208.16015,366.125 208.82421,365.88925 209.34375,365.375 C 209.86328,364.86076 210.12499,364.22403 210.125,363.46875 C 210.12499,362.92237 209.99608,362.45622 209.71875,362.0625 C 209.44531,361.66879 209.02734,361.36426 208.5,361.1875 C 208.92578,361.02279 209.26171,360.80133 209.46875,360.5 C 209.67968,360.19468 209.78124,359.84729 209.78125,359.4375 C 209.78124,358.79471 209.55077,358.2272 209.09375,357.78125 C 208.63671,357.3313 208.03124,357.125 207.28125,357.125 z M 172.8125,357.15625 L 172.8125,360.3125 C 172.6289,360.05137 172.38671,359.84819 172.09375,359.6875 C 171.80078,359.52279 171.46874,359.43752 171.09375,359.4375 C 170.58203,359.43751 170.13281,359.56654 169.71875,359.84375 C 169.30469,360.12096 168.98828,360.54022 168.78125,361.0625 C 168.57422,361.58076 168.46875,362.14246 168.46875,362.78125 C 168.46875,363.4361 168.58593,364.02504 168.8125,364.53125 C 169.04297,365.03344 169.36718,365.43753 169.78125,365.71875 C 170.19922,365.99997 170.6289,366.125 171.125,366.125 C 171.89062,366.125 172.48046,365.82226 172.875,365.1875 L 172.875,366 L 173.875,366 L 173.875,357.15625 L 172.8125,357.15625 z M 215.40625,357.15625 L 215.40625,360.3125 C 215.22265,360.05137 215.01172,359.84819 214.71875,359.6875 C 214.42578,359.52279 214.0625,359.43752 213.6875,359.4375 C 213.17578,359.43751 212.72657,359.56654 212.3125,359.84375 C 211.89844,360.12096 211.58204,360.54022 211.375,361.0625 C 211.16797,361.58076 211.06251,362.14246 211.0625,362.78125 C 211.0625,363.4361 211.17969,364.02504 211.40625,364.53125 C 211.63672,365.03344 211.96094,365.43753 212.375,365.71875 C 212.79297,365.99997 213.25391,366.125 213.75,366.125 C 214.51562,366.125 215.10547,365.82226 215.5,365.1875 L 215.5,366 L 216.46875,366 L 216.46875,357.15625 L 215.40625,357.15625 z M 227.40625,357.15625 L 223.5,362.875 L 223.5,363.875 L 227.21875,363.875 L 227.21875,366 L 228.28125,366 L 228.28125,363.875 L 229.4375,363.875 L 229.4375,362.875 L 228.28125,362.875 L 228.28125,357.15625 L 227.40625,357.15625 z M 234.78125,357.15625 L 234.78125,360.3125 C 234.59765,360.05137 234.35546,359.84819 234.0625,359.6875 C 233.76953,359.52279 233.43749,359.43752 233.0625,359.4375 C 232.55078,359.43751 232.10156,359.56654 231.6875,359.84375 C 231.27344,360.12096 230.95703,360.54022 230.75,361.0625 C 230.54297,361.58076 230.4375,362.14246 230.4375,362.78125 C 230.4375,363.4361 230.55468,364.02504 230.78125,364.53125 C 231.01172,365.03344 231.33593,365.43753 231.75,365.71875 C 232.16797,365.99997 232.59765,366.125 233.09375,366.125 C 233.85937,366.125 234.44921,365.82226 234.84375,365.1875 L 234.84375,366 L 235.8125,366 L 235.8125,357.15625 L 234.78125,357.15625 z M 112.65625,357.34375 L 111.625,358 L 111.625,359.59375 L 110.84375,359.59375 L 110.84375,360.4375 L 111.625,360.4375 L 111.625,364.125 C 111.625,364.77584 111.66406,365.20135 111.75,365.40625 C 111.83594,365.60713 111.97656,365.75045 112.1875,365.875 C 112.39844,365.99954 112.71093,366.06251 113.09375,366.0625 C 113.32812,366.0625 113.57812,366.03302 113.875,365.96875 L 113.71875,365 C 113.52734,365.02812 113.36718,365.06249 113.25,365.0625 C 113.09375,365.0625 112.99218,365.02096 112.90625,364.96875 C 112.82422,364.91652 112.75781,364.86964 112.71875,364.78125 C 112.68359,364.69287 112.65624,364.46559 112.65625,364.15625 L 112.65625,360.4375 L 113.71875,360.4375 L 113.71875,359.59375 L 112.65625,359.59375 L 112.65625,357.34375 z M 186.78125,357.34375 L 185.71875,358 L 185.71875,359.59375 L 184.9375,359.59375 L 184.9375,360.4375 L 185.71875,360.4375 L 185.71875,364.125 C 185.71875,364.77584 185.75782,365.20135 185.84375,365.40625 C 185.92969,365.60713 186.10157,365.75045 186.3125,365.875 C 186.52344,365.99954 186.80469,366.06251 187.1875,366.0625 C 187.42187,366.0625 187.70313,366.03302 188,365.96875 L 187.84375,365 C 187.65234,365.02812 187.49219,365.06249 187.375,365.0625 C 187.21875,365.0625 187.08594,365.02096 187,364.96875 C 186.91797,364.91652 186.85157,364.86964 186.8125,364.78125 C 186.77734,364.69287 186.78125,364.46559 186.78125,364.15625 L 186.78125,360.4375 L 187.84375,360.4375 L 187.84375,359.59375 L 186.78125,359.59375 L 186.78125,357.34375 z M 194.6875,358 C 195.17968,358.00001 195.57812,358.24068 195.90625,358.71875 C 196.23828,359.19684 196.40624,360.17068 196.40625,361.625 C 196.40624,363.0713 196.23827,364.04915 195.90625,364.53125 C 195.57812,365.01335 195.17187,365.25 194.6875,365.25 C 194.20312,365.25 193.80078,365.00935 193.46875,364.53125 C 193.14062,364.04915 192.96875,363.07533 192.96875,361.625 C 192.96875,360.17469 193.16796,359.19459 193.53125,358.65625 C 193.82031,358.23442 194.20312,358.00002 194.6875,358 z M 207.28125,358 C 207.67968,358.00001 208.01562,358.13306 208.28125,358.40625 C 208.55078,358.67543 208.68749,359.00854 208.6875,359.40625 C 208.6875,359.78792 208.57421,360.10985 208.3125,360.375 C 208.05468,360.63614 207.71874,360.78126 207.3125,360.78125 C 206.89453,360.78126 206.54296,360.64017 206.28125,360.375 C 206.01953,360.10985 205.90625,359.76157 205.90625,359.34375 C 205.90625,358.97415 206.01562,358.67141 206.28125,358.40625 C 206.54687,358.1411 206.8789,358.00001 207.28125,358 z M 227.21875,358.90625 L 227.21875,362.875 L 224.53125,362.875 L 227.21875,358.90625 z M 107.46875,359.4375 C 107.14453,359.43751 106.84765,359.47411 106.5625,359.5625 C 106.28125,359.64687 106.03906,359.75046 105.875,359.875 C 105.65625,360.03571 105.5039,360.25495 105.375,360.5 C 105.25,360.74106 105.1875,360.996 105.1875,361.28125 C 105.1875,361.59462 105.2539,361.8951 105.40625,362.15625 C 105.5625,362.41337 105.79687,362.60135 106.09375,362.75 C 106.39453,362.89463 106.91406,363.08038 107.6875,363.28125 C 108.26172,363.4299 108.63671,363.55982 108.78125,363.65625 C 108.98828,363.79686 109.09374,363.97367 109.09375,364.21875 C 109.09375,364.49194 108.95312,364.73262 108.71875,364.9375 C 108.48437,365.13838 108.14062,365.24999 107.65625,365.25 C 107.17578,365.25 106.80078,365.13525 106.53125,364.90625 C 106.26562,364.67725 106.08984,364.33613 106.03125,363.90625 L 105,364.0625 C 105.11719,364.74146 105.39062,365.27949 105.8125,365.625 C 106.23828,365.9705 106.84765,366.125 107.65625,366.125 C 108.14453,366.125 108.58202,366.04775 108.96875,365.875 C 109.35546,365.69823 109.64062,365.44239 109.84375,365.125 C 110.05078,364.8036 110.15624,364.45532 110.15625,364.09375 C 110.15624,363.72414 110.07421,363.43657 109.90625,363.1875 C 109.73828,362.93842 109.51562,362.75355 109.21875,362.625 C 108.92578,362.49243 108.40234,362.29865 107.65625,362.09375 C 107.14062,361.94912 106.82421,361.85267 106.71875,361.8125 C 106.53515,361.73617 106.39843,361.64777 106.3125,361.53125 C 106.22656,361.41876 106.1875,361.29686 106.1875,361.15625 C 106.1875,360.93529 106.29296,360.75847 106.5,360.59375 C 106.70703,360.42904 107.04687,360.34374 107.53125,360.34375 C 107.9414,360.34376 108.27734,360.44021 108.5,360.625 C 108.72656,360.80981 108.85937,361.04557 108.90625,361.375 L 109.9375,361.25 C 109.87109,360.8362 109.73827,360.49508 109.5625,360.25 C 109.38671,360.00092 109.12109,359.80089 108.75,359.65625 C 108.38281,359.51163 107.95703,359.43752 107.46875,359.4375 z M 117.03125,359.4375 C 116.78515,359.43751 116.55078,359.51163 116.34375,359.65625 C 116.14062,359.80089 115.92968,360.10853 115.6875,360.5625 L 115.6875,359.59375 L 114.75,359.59375 L 114.75,366 L 115.78125,366 L 115.78125,362.625 C 115.78125,362.16701 115.85156,361.76069 115.96875,361.375 C 116.04687,361.1219 116.1914,360.92188 116.375,360.78125 C 116.55859,360.63663 116.73828,360.56252 116.96875,360.5625 C 117.22656,360.56251 117.49218,360.62456 117.75,360.78125 L 118.125,359.78125 C 117.75781,359.54824 117.38671,359.43752 117.03125,359.4375 z M 121.3125,359.4375 C 120.45312,359.43751 119.75781,359.74916 119.21875,360.34375 C 118.67969,360.93834 118.40625,361.76708 118.40625,362.84375 C 118.40625,363.88428 118.65625,364.70273 119.1875,365.28125 C 119.72265,365.85575 120.46484,366.125 121.375,366.125 C 122.09765,366.125 122.6914,365.95532 123.15625,365.59375 C 123.62109,365.23218 123.92187,364.71736 124.09375,364.0625 L 123.03125,363.9375 C 122.87109,364.3955 122.64843,364.7286 122.375,364.9375 C 122.10156,365.14641 121.76171,365.24999 121.375,365.25 C 120.85547,365.25 120.41015,365.06113 120.0625,364.6875 C 119.71484,364.31387 119.53906,363.76555 119.5,363.0625 L 124.125,363.0625 C 124.1289,362.93394 124.15624,362.84554 124.15625,362.78125 C 124.15624,361.72465 123.87108,360.89505 123.34375,360.3125 C 122.8164,359.72997 122.14452,359.43752 121.3125,359.4375 z M 128.0625,359.4375 C 127.52734,359.43751 127.0625,359.5036 126.65625,359.65625 C 126.25,359.8049 125.9336,360.03129 125.71875,360.3125 C 125.50391,360.58971 125.34375,360.95229 125.25,361.40625 L 126.28125,361.5625 C 126.39453,361.10853 126.57813,360.80178 126.8125,360.625 C 127.05078,360.44422 127.41016,360.34376 127.90625,360.34375 C 128.4375,360.34376 128.85546,360.47368 129.125,360.71875 C 129.32421,360.89954 129.40624,361.18309 129.40625,361.625 C 129.40625,361.66518 129.41015,361.78886 129.40625,361.9375 C 129.0039,362.08213 128.38281,362.20806 127.53125,362.3125 C 127.11328,362.36473 126.80078,362.4125 126.59375,362.46875 C 126.3125,362.5491 126.07031,362.65584 125.84375,362.8125 C 125.62109,362.96919 125.42188,363.17637 125.28125,363.4375 C 125.14453,363.69462 125.09375,363.99913 125.09375,364.3125 C 125.09375,364.84683 125.25782,365.2795 125.625,365.625 C 125.99219,365.96649 126.53516,366.125 127.21875,366.125 C 127.63281,366.125 128.01562,366.04685 128.375,365.90625 C 128.73828,365.76564 129.10937,365.529 129.5,365.1875 C 129.53125,365.48881 129.60937,365.77501 129.71875,366 L 130.8125,366 C 130.67968,365.75493 130.57811,365.48391 130.53125,365.21875 C 130.48828,364.94958 130.46874,364.32091 130.46875,363.3125 L 130.46875,361.84375 C 130.46874,361.36165 130.47265,361.02857 130.4375,360.84375 C 130.37499,360.54646 130.24999,360.31785 130.09375,360.125 C 129.93749,359.92815 129.70702,359.75358 129.375,359.625 C 129.04296,359.49645 128.59374,359.43752 128.0625,359.4375 z M 134.9375,359.4375 C 134.52343,359.43751 134.16796,359.52591 133.84375,359.71875 C 133.51953,359.90758 133.25781,360.1554 133.0625,360.46875 L 133.0625,359.59375 L 132.125,359.59375 L 132.125,366 L 133.1875,366 L 133.15625,362.65625 C 133.15625,362.07372 133.23046,361.62185 133.34375,361.3125 C 133.45703,361.00316 133.62499,360.78571 133.875,360.625 C 134.1289,360.46431 134.42187,360.37502 134.71875,360.375 C 135.10937,360.37501 135.39062,360.50897 135.5625,360.75 C 135.73437,360.99105 135.81249,361.3304 135.8125,361.8125 L 135.8125,366 L 136.875,366 L 136.875,362.28125 C 136.87499,361.62238 137.02343,361.14106 137.3125,360.84375 C 137.60156,360.54244 137.96874,360.37502 138.40625,360.375 C 138.64843,360.37501 138.85155,360.446 139.03125,360.5625 C 139.21093,360.67901 139.33983,360.83841 139.40625,361.03125 C 139.47655,361.22008 139.49999,361.53485 139.5,361.96875 L 139.5,366 L 140.5625,366 L 140.5625,361.59375 C 140.56249,360.86257 140.39452,360.31826 140.0625,359.96875 C 139.73046,359.61522 139.24218,359.43752 138.625,359.4375 C 137.83593,359.43751 137.21093,359.81526 136.71875,360.5625 C 136.59765,360.20897 136.35937,359.94687 136.0625,359.75 C 135.76953,359.55315 135.39843,359.43752 134.9375,359.4375 z M 151.34375,359.4375 C 150.57422,359.43751 149.91015,359.68218 149.375,360.15625 C 148.73437,360.72674 148.40625,361.5961 148.40625,362.78125 C 148.40625,363.86196 148.68359,364.70675 149.21875,365.28125 C 149.75781,365.85575 150.47265,366.125 151.34375,366.125 C 151.88671,366.125 152.38671,366.01115 152.84375,365.75 C 153.30468,365.48886 153.63671,365.12631 153.875,364.65625 C 154.11718,364.18219 154.24999,363.51109 154.25,362.6875 C 154.24999,361.67108 153.98046,360.887 153.4375,360.3125 C 152.89453,359.73399 152.19921,359.43752 151.34375,359.4375 z M 165.09375,359.4375 C 164.23047,359.43751 163.58202,359.79695 163.125,360.5 L 163.125,359.59375 L 162.15625,359.59375 L 162.15625,366 L 163.21875,366 L 163.21875,362.5 C 163.21875,361.68043 163.39452,361.10577 163.71875,360.8125 C 164.04687,360.51923 164.42577,360.37502 164.875,360.375 C 165.15625,360.37501 165.38671,360.46117 165.59375,360.59375 C 165.80468,360.72232 165.94921,360.87278 166.03125,361.09375 C 166.11328,361.3107 166.15624,361.65184 166.15625,362.09375 L 166.15625,366 L 167.21875,366 L 167.21875,362.0625 C 167.21874,361.56032 167.1953,361.20088 167.15625,361 C 167.09374,360.69066 166.99999,360.41248 166.84375,360.1875 C 166.68749,359.96253 166.44139,359.79284 166.125,359.65625 C 165.8125,359.51564 165.46874,359.43752 165.09375,359.4375 z M 181.46875,359.4375 C 180.93359,359.43751 180.46874,359.5036 180.0625,359.65625 C 179.65625,359.8049 179.33984,360.03129 179.125,360.3125 C 178.91016,360.58971 178.78125,360.95229 178.6875,361.40625 L 179.71875,361.5625 C 179.83203,361.10853 179.98437,360.80178 180.21875,360.625 C 180.45703,360.44422 180.84765,360.34376 181.34375,360.34375 C 181.875,360.34376 182.26171,360.47368 182.53125,360.71875 C 182.73046,360.89954 182.84374,361.18309 182.84375,361.625 C 182.84375,361.66518 182.8164,361.78886 182.8125,361.9375 C 182.41015,362.08213 181.78906,362.20806 180.9375,362.3125 C 180.51953,362.36473 180.20703,362.4125 180,362.46875 C 179.71875,362.5491 179.47656,362.65584 179.25,362.8125 C 179.02734,362.96919 178.82812,363.17637 178.6875,363.4375 C 178.55078,363.69462 178.5,363.99913 178.5,364.3125 C 178.5,364.84683 178.66406,365.2795 179.03125,365.625 C 179.39844,365.96649 179.9414,366.125 180.625,366.125 C 181.03906,366.125 181.42187,366.04685 181.78125,365.90625 C 182.14453,365.76564 182.51562,365.529 182.90625,365.1875 C 182.9375,365.48881 183.01562,365.77501 183.125,366 L 184.21875,366 C 184.08593,365.75493 184.01562,365.48391 183.96875,365.21875 C 183.92578,364.94958 183.87499,364.32091 183.875,363.3125 L 183.875,361.84375 C 183.87499,361.36165 183.8789,361.02857 183.84375,360.84375 C 183.78124,360.54646 183.65624,360.31785 183.5,360.125 C 183.34374,359.92815 183.11327,359.75358 182.78125,359.625 C 182.44921,359.49645 181.99999,359.43752 181.46875,359.4375 z M 220.65625,359.4375 C 220.12109,359.43751 219.61327,359.58261 219.15625,359.84375 C 218.70312,360.10088 218.3789,360.48175 218.15625,361 C 217.93359,361.51826 217.81249,362.12149 217.8125,362.8125 C 217.8125,363.88116 218.07812,364.70676 218.59375,365.28125 C 219.11328,365.85173 219.77343,366.125 220.625,366.125 C 221.30468,366.125 221.8789,365.91379 222.34375,365.5 C 222.81249,365.08218 223.10546,364.51646 223.21875,363.78125 L 222.1875,363.65625 C 222.11328,364.19861 221.93358,364.58262 221.65625,364.84375 C 221.3789,365.10489 221.03905,365.24999 220.625,365.25 C 220.10937,365.25 219.6953,365.04596 219.375,364.65625 C 219.05469,364.26655 218.90624,363.64099 218.90625,362.78125 C 218.90625,361.93356 219.07421,361.32722 219.40625,360.9375 C 219.73828,360.54379 220.15624,360.34374 220.6875,360.34375 C 221.03906,360.34376 221.34765,360.43931 221.59375,360.65625 C 221.84375,360.8732 221.99608,361.19514 222.09375,361.625 L 223.125,361.46875 C 223.0039,360.82194 222.74218,360.31826 222.3125,359.96875 C 221.88281,359.61522 221.33202,359.43752 220.65625,359.4375 z M 155.46875,359.59375 L 155.46875,363.5625 C 155.46875,364.02451 155.48828,364.34958 155.53125,364.5625 C 155.59375,364.87988 155.6914,365.15404 155.84375,365.375 C 156,365.59195 156.24609,365.76162 156.5625,365.90625 C 156.88281,366.05088 157.22656,366.125 157.59375,366.125 C 158.42578,366.125 159.07812,365.75439 159.5625,365.03125 L 159.5625,366 L 160.5,366 L 160.5,359.59375 L 159.4375,359.59375 L 159.4375,363 C 159.4375,363.54638 159.39843,363.992 159.28125,364.28125 C 159.16796,364.56649 158.96483,364.76877 158.6875,364.9375 C 158.41015,365.10222 158.1289,365.18751 157.8125,365.1875 C 157.49609,365.1875 157.21484,365.12944 157,364.96875 C 156.78515,364.80403 156.66015,364.5665 156.59375,364.28125 C 156.55078,364.08439 156.49999,363.69148 156.5,363.125 L 156.5,359.59375 L 155.46875,359.59375 z M 198.34375,359.59375 L 200.4375,362.65625 L 198.15625,366 L 199.4375,366 L 201.0625,363.46875 L 201.40625,364 L 202.6875,366 L 204,366 L 201.6875,362.59375 L 203.8125,359.59375 L 202.5625,359.59375 L 201.5,361.09375 C 201.35547,361.29865 201.20313,361.54734 201.03125,361.8125 C 200.92187,361.61966 200.77344,361.379 200.59375,361.09375 L 199.65625,359.59375 L 198.34375,359.59375 z M 121.3125,360.34375 C 121.84765,360.34376 122.28906,360.55094 122.625,360.96875 C 122.84375,361.23793 122.98437,361.61792 123.03125,362.15625 L 119.5625,362.15625 C 119.59765,361.59782 119.76562,361.17722 120.09375,360.84375 C 120.42578,360.5103 120.82812,360.34374 121.3125,360.34375 z M 151.34375,360.34375 C 151.86328,360.34376 152.27734,360.55897 152.625,360.96875 C 152.97656,361.37452 153.15624,361.95857 153.15625,362.75 C 153.15624,363.58966 152.97265,364.21521 152.625,364.625 C 152.27734,365.03479 151.86718,365.24999 151.34375,365.25 C 150.8164,365.25 150.3789,365.03078 150.03125,364.625 C 149.68359,364.21522 149.5,363.60083 149.5,362.78125 C 149.5,361.96168 149.68359,361.34328 150.03125,360.9375 C 150.3789,360.53174 150.8164,360.34376 151.34375,360.34375 z M 171.1875,360.34375 C 171.66797,360.34376 172.07812,360.55897 172.40625,360.96875 C 172.73437,361.37854 172.90624,361.99918 172.90625,362.875 C 172.90625,363.67047 172.73046,364.26655 172.40625,364.65625 C 172.08593,365.04193 171.71093,365.24999 171.25,365.25 C 170.79297,365.25 170.39843,365.03078 170.0625,364.625 C 169.72656,364.21923 169.56249,363.60081 169.5625,362.78125 L 169.53125,362.78125 C 169.53125,361.93356 169.68749,361.33122 170,360.9375 C 170.3164,360.54379 170.71874,360.34376 171.1875,360.34375 z M 213.8125,360.34375 C 214.29297,360.34376 214.67188,360.55897 215,360.96875 C 215.32812,361.37854 215.5,361.99918 215.5,362.875 C 215.5,363.67047 215.35547,364.26655 215.03125,364.65625 C 214.71093,365.04193 214.30469,365.24999 213.84375,365.25 C 213.38672,365.25 212.99219,365.03078 212.65625,364.625 C 212.32031,364.21923 212.15626,363.60081 212.15625,362.78125 C 212.15625,361.93356 212.31251,361.33122 212.625,360.9375 C 212.9414,360.54379 213.34375,360.34376 213.8125,360.34375 z M 233.15625,360.34375 C 233.63672,360.34376 234.04687,360.55897 234.375,360.96875 C 234.70312,361.37854 234.87499,361.99918 234.875,362.875 C 234.875,363.67047 234.69921,364.26655 234.375,364.65625 C 234.05468,365.04193 233.67968,365.24999 233.21875,365.25 C 232.76172,365.25 232.36718,365.03078 232.03125,364.625 C 231.69531,364.21923 231.49999,363.60081 231.5,362.78125 C 231.5,361.93356 231.65624,361.33122 231.96875,360.9375 C 232.28515,360.54379 232.68749,360.34376 233.15625,360.34375 z M 207.28125,361.65625 C 207.78906,361.65625 208.19531,361.84601 208.53125,362.1875 C 208.87109,362.52899 209.06249,362.94649 209.0625,363.46875 C 209.06249,363.98299 208.89062,364.41656 208.5625,364.75 C 208.23437,365.08345 207.8164,365.25 207.3125,365.25 C 206.98828,365.25 206.68749,365.15668 206.40625,365 C 206.125,364.8393 205.89453,364.63302 205.75,364.34375 C 205.60937,364.05449 205.5625,363.74684 205.5625,363.4375 C 205.5625,362.9313 205.70703,362.49374 206.03125,362.15625 C 206.35937,361.81878 206.78515,361.65626 207.28125,361.65625 z M 129.40625,362.78125 L 129.40625,363.15625 C 129.40625,363.63433 129.36327,364.00494 129.25,364.25 C 129.10156,364.56738 128.84765,364.81519 128.53125,365 C 128.21484,365.18079 127.875,365.28125 127.46875,365.28125 C 127.05859,365.28125 126.74609,365.19285 126.53125,365 C 126.32031,364.80716 126.21875,364.57052 126.21875,364.28125 C 126.21875,364.09243 126.2461,363.90268 126.34375,363.75 C 126.4414,363.59332 126.60156,363.4866 126.78125,363.40625 C 126.96094,363.3259 127.25391,363.25178 127.6875,363.1875 C 128.45312,363.07501 129.02343,362.94196 129.40625,362.78125 z M 182.8125,362.78125 L 182.8125,363.15625 C 182.8125,363.63433 182.76952,364.00494 182.65625,364.25 C 182.50781,364.56738 182.28515,364.81519 181.96875,365 C 181.65234,365.18079 181.28124,365.28125 180.875,365.28125 C 180.46484,365.28125 180.15234,365.19285 179.9375,365 C 179.72656,364.80716 179.625,364.57052 179.625,364.28125 C 179.625,364.09243 179.65234,363.90268 179.75,363.75 C 179.84765,363.59332 180.00781,363.4866 180.1875,363.40625 C 180.36719,363.3259 180.66015,363.25178 181.09375,363.1875 C 181.85937,363.07501 182.42968,362.94196 182.8125,362.78125 z M 259.28125,372.4375 C 258.70312,372.43751 258.16015,372.5179 257.6875,372.71875 C 257.21484,372.91963 256.87108,373.23532 256.625,373.625 C 256.37891,374.01069 256.24999,374.42907 256.25,374.875 C 256.25,375.28077 256.33202,375.63932 256.53125,375.96875 C 256.73437,376.29417 257.05858,376.56031 257.46875,376.78125 C 257.78515,376.95401 258.33593,377.14688 259.125,377.34375 C 259.57589,377.45395 259.73151,377.51635 260,377.59375 L 260,376.34375 C 259.79721,376.29149 259.61783,376.24335 259.375,376.1875 C 258.45312,375.97056 257.90624,375.7674 257.6875,375.5625 C 257.46484,375.35761 257.34374,375.09864 257.34375,374.78125 C 257.34375,374.41566 257.49999,374.10086 257.8125,373.84375 C 258.1289,373.58262 258.62499,373.46876 259.3125,373.46875 C 259.56626,373.46875 259.79415,373.4891 260,373.53125 L 260,372.5 C 259.76396,372.464 259.54304,372.4375 259.28125,372.4375 z M 118,372.5625 L 118,373.8125 L 119.0625,373.8125 L 119.0625,372.5625 L 118,372.5625 z M 133.34375,372.5625 L 133.34375,381.40625 L 134.375,381.40625 L 134.375,377.90625 C 134.375,377.40407 134.44531,377.004 134.5625,376.71875 C 134.67969,376.43351 134.88281,376.22722 135.15625,376.0625 C 135.43359,375.89377 135.71874,375.81251 136.03125,375.8125 C 136.44921,375.81251 136.77343,375.93843 137,376.1875 C 137.23046,376.43257 137.34374,376.80139 137.34375,377.34375 L 137.34375,381.40625 L 138.40625,381.40625 L 138.40625,377.34375 C 138.40624,376.71702 138.33593,376.26693 138.1875,375.9375 C 138.04296,375.60807 137.80858,375.34105 137.46875,375.15625 C 137.1289,374.96743 136.71093,374.87499 136.25,374.875 C 135.5,374.87501 134.86718,375.16345 134.375,375.75 L 134.375,372.5625 L 133.34375,372.5625 z M 152.6875,372.5625 L 152.6875,381.40625 L 153.75,381.40625 L 153.75,378.875 L 154.5,378.125 L 156.5625,381.40625 L 157.84375,381.40625 L 155.25,377.375 L 157.625,375 L 156.25,375 L 153.75,377.625 L 153.75,372.5625 L 152.6875,372.5625 z M 158.78125,372.5625 L 158.78125,381.40625 L 164.15625,381.40625 L 164.15625,380.375 L 159.90625,380.375 L 159.90625,372.5625 L 158.78125,372.5625 z M 181.5625,372.5625 L 181.5625,381.40625 L 182.71875,381.40625 L 182.71875,377.40625 L 186.75,377.40625 L 186.75,376.34375 L 182.71875,376.34375 L 182.71875,373.625 L 187.375,373.625 L 187.375,372.5625 L 181.5625,372.5625 z M 216.4375,372.5625 L 216.4375,381.40625 L 217.59375,381.40625 L 217.59375,372.5625 L 216.4375,372.5625 z M 226.21875,372.5625 L 226.21875,381.40625 L 227.3125,381.40625 L 227.3125,373.90625 L 229.8125,381.40625 L 230.84375,381.40625 L 233.3125,374.03125 L 233.3125,381.40625 L 234.40625,381.40625 L 234.40625,372.5625 L 232.90625,372.5625 L 230.84375,378.71875 C 230.63671,379.34146 230.47266,379.83486 230.375,380.15625 C 230.28906,379.86699 230.15625,379.42628 229.96875,378.84375 L 227.9375,372.5625 L 226.21875,372.5625 z M 121.9375,372.78125 L 120.875,373.4375 L 120.875,375 L 120.09375,375 L 120.09375,375.84375 L 120.875,375.84375 L 120.875,379.53125 C 120.875,380.18209 120.91406,380.60761 121,380.8125 C 121.08594,381.01338 121.22656,381.18796 121.4375,381.3125 C 121.64844,381.43704 121.96093,381.50002 122.34375,381.5 C 122.57812,381.5 122.82813,381.47053 123.125,381.40625 L 122.96875,380.4375 C 122.77734,380.46562 122.64844,380.46875 122.53125,380.46875 C 122.375,380.46875 122.24218,380.45847 122.15625,380.40625 C 122.07422,380.35402 122.00781,380.2759 121.96875,380.1875 C 121.93359,380.09912 121.93749,379.9031 121.9375,379.59375 L 121.9375,375.84375 L 122.96875,375.84375 L 122.96875,375 L 121.9375,375 L 121.9375,372.78125 z M 179.3125,372.78125 L 178.25,373.4375 L 178.25,375 L 177.46875,375 L 177.46875,375.84375 L 178.25,375.84375 L 178.25,379.53125 C 178.25,380.18209 178.28906,380.60761 178.375,380.8125 C 178.46094,381.01338 178.60156,381.18796 178.8125,381.3125 C 179.02344,381.43704 179.33593,381.50002 179.71875,381.5 C 179.95312,381.5 180.20312,381.47053 180.5,381.40625 L 180.34375,380.4375 C 180.15234,380.46562 180.02343,380.46875 179.90625,380.46875 C 179.75,380.46875 179.61718,380.45847 179.53125,380.40625 C 179.44922,380.35402 179.38281,380.2759 179.34375,380.1875 C 179.30859,380.09912 179.31249,379.9031 179.3125,379.59375 L 179.3125,375.84375 L 180.34375,375.84375 L 180.34375,375 L 179.3125,375 L 179.3125,372.78125 z M 107.96875,374.875 C 107.10937,374.87501 106.41406,375.15541 105.875,375.75 C 105.33594,376.34459 105.0625,377.20455 105.0625,378.28125 C 105.0625,379.32178 105.34375,380.10899 105.875,380.6875 C 106.41015,381.262 107.12109,381.56251 108.03125,381.5625 C 108.7539,381.5625 109.34765,381.36158 109.8125,381 C 110.27734,380.63843 110.60937,380.15484 110.78125,379.5 L 109.6875,379.34375 C 109.52734,379.80175 109.30468,380.13483 109.03125,380.34375 C 108.75781,380.55266 108.41796,380.65625 108.03125,380.65625 C 107.51172,380.65625 107.09765,380.46739 106.75,380.09375 C 106.40234,379.72012 106.19531,379.20306 106.15625,378.5 L 110.8125,378.5 C 110.8164,378.37144 110.81249,378.2518 110.8125,378.1875 C 110.81249,377.1309 110.52733,376.33256 110,375.75 C 109.47265,375.16747 108.80077,374.87499 107.96875,374.875 z M 129.84375,374.875 C 129.30859,374.87501 128.83202,374.98887 128.375,375.25 C 127.92187,375.50713 127.56641,375.91926 127.34375,376.4375 C 127.12109,376.95576 127,377.559 127,378.25 C 127,379.31866 127.26563,380.11299 127.78125,380.6875 C 128.30078,381.25798 128.99218,381.56251 129.84375,381.5625 C 130.52343,381.5625 131.09765,381.3513 131.5625,380.9375 C 132.03124,380.51968 132.32421,379.95394 132.4375,379.21875 L 131.40625,379.0625 C 131.33203,379.60486 131.15234,380.02013 130.875,380.28125 C 130.59765,380.54239 130.2578,380.65625 129.84375,380.65625 C 129.32812,380.65625 128.88281,380.48346 128.5625,380.09375 C 128.24219,379.70405 128.09374,379.07849 128.09375,378.21875 C 128.09375,377.37106 128.26171,376.73344 128.59375,376.34375 C 128.92578,375.95004 129.34374,375.75 129.875,375.75 C 130.22656,375.75001 130.53515,375.87682 130.78125,376.09375 C 131.03125,376.3107 131.21483,376.63262 131.3125,377.0625 L 132.34375,376.90625 C 132.22265,376.25944 131.92968,375.75577 131.5,375.40625 C 131.07031,375.05272 130.51952,374.87499 129.84375,374.875 z M 142.5625,374.875 C 141.70312,374.87501 141.00781,375.15541 140.46875,375.75 C 139.92969,376.34459 139.65625,377.20455 139.65625,378.28125 C 139.65625,379.32178 139.9375,380.10899 140.46875,380.6875 C 141.0039,381.262 141.71484,381.56251 142.625,381.5625 C 143.34765,381.5625 143.9414,381.36158 144.40625,381 C 144.87109,380.63843 145.20312,380.15484 145.375,379.5 L 144.28125,379.34375 C 144.12109,379.80175 143.89843,380.13483 143.625,380.34375 C 143.35156,380.55266 143.01171,380.65625 142.625,380.65625 C 142.10547,380.65625 141.6914,380.46739 141.34375,380.09375 C 140.99609,379.72012 140.78906,379.20306 140.75,378.5 L 145.40625,378.5 C 145.41015,378.37144 145.40624,378.2518 145.40625,378.1875 C 145.40624,377.1309 145.12109,376.33256 144.59375,375.75 C 144.0664,375.16747 143.39452,374.87499 142.5625,374.875 z M 149.21875,374.875 C 148.68359,374.87501 148.17578,374.98887 147.71875,375.25 C 147.26562,375.50713 146.9414,375.91926 146.71875,376.4375 C 146.49609,376.95576 146.375,377.559 146.375,378.25 C 146.375,379.31866 146.64062,380.11299 147.15625,380.6875 C 147.67578,381.25798 148.33593,381.56251 149.1875,381.5625 C 149.86718,381.5625 150.4414,381.3513 150.90625,380.9375 C 151.37499,380.51968 151.66796,379.95394 151.78125,379.21875 L 150.75,379.0625 C 150.67578,379.60486 150.49609,380.02013 150.21875,380.28125 C 149.9414,380.54239 149.60155,380.65625 149.1875,380.65625 C 148.67187,380.65625 148.25781,380.48346 147.9375,380.09375 C 147.61719,379.70405 147.46874,379.07849 147.46875,378.21875 C 147.46875,377.37106 147.63671,376.73344 147.96875,376.34375 C 148.30078,375.95004 148.71874,375.75 149.25,375.75 C 149.60156,375.75001 149.91015,375.87682 150.15625,376.09375 C 150.40625,376.3107 150.55859,376.63262 150.65625,377.0625 L 151.6875,376.90625 C 151.5664,376.25944 151.30468,375.75577 150.875,375.40625 C 150.44531,375.05272 149.89452,374.87499 149.21875,374.875 z M 168,374.875 C 167.46484,374.87501 166.99999,374.9411 166.59375,375.09375 C 166.1875,375.2424 165.87109,375.4688 165.65625,375.75 C 165.44141,376.02721 165.28124,376.38977 165.1875,376.84375 L 166.21875,376.96875 C 166.33203,376.51478 166.51562,376.20804 166.75,376.03125 C 166.98828,375.85047 167.34765,375.78127 167.84375,375.78125 C 168.375,375.78126 168.79296,375.87994 169.0625,376.125 C 169.26171,376.30579 169.34374,376.62059 169.34375,377.0625 C 169.34375,377.10268 169.34765,377.19512 169.34375,377.34375 C 168.9414,377.48838 168.3203,377.61431 167.46875,377.71875 C 167.05078,377.77098 166.73827,377.81876 166.53125,377.875 C 166.25,377.95535 166.00781,378.09331 165.78125,378.25 C 165.55859,378.40669 165.35937,378.61388 165.21875,378.875 C 165.08203,379.13212 165.03124,379.40538 165.03125,379.71875 C 165.03125,380.25308 165.19531,380.68576 165.5625,381.03125 C 165.92969,381.37274 166.47265,381.56251 167.15625,381.5625 C 167.57031,381.5625 167.95312,381.48436 168.3125,381.34375 C 168.67578,381.20314 169.04686,380.96648 169.4375,380.625 C 169.46875,380.92631 169.54686,381.18127 169.65625,381.40625 L 170.75,381.40625 C 170.61718,381.16118 170.51561,380.92142 170.46875,380.65625 C 170.42578,380.38708 170.40624,379.72713 170.40625,378.71875 L 170.40625,377.28125 C 170.40624,376.79915 170.41014,376.46605 170.375,376.28125 C 170.31249,375.98396 170.18749,375.75533 170.03125,375.5625 C 169.87499,375.36565 169.64452,375.19105 169.3125,375.0625 C 168.98046,374.93395 168.53124,374.87499 168,374.875 z M 174.09375,374.875 C 173.76953,374.87501 173.47265,374.91162 173.1875,375 C 172.90625,375.08437 172.69531,375.18797 172.53125,375.3125 C 172.3125,375.47321 172.1289,375.69242 172,375.9375 C 171.875,376.17856 171.8125,376.43351 171.8125,376.71875 C 171.8125,377.03212 171.8789,377.30136 172.03125,377.5625 C 172.1875,377.81962 172.42187,378.03886 172.71875,378.1875 C 173.01953,378.33213 173.53906,378.48664 174.3125,378.6875 C 174.88672,378.83615 175.26171,378.96608 175.40625,379.0625 C 175.61328,379.20311 175.71874,379.41118 175.71875,379.65625 C 175.71875,379.92944 175.60937,380.17012 175.375,380.375 C 175.14062,380.57588 174.76562,380.65625 174.28125,380.65625 C 173.80078,380.65625 173.42578,380.54151 173.15625,380.3125 C 172.89062,380.0835 172.74609,379.77364 172.6875,379.34375 L 171.625,379.5 C 171.74219,380.17896 172.01562,380.68574 172.4375,381.03125 C 172.86328,381.37675 173.47265,381.56251 174.28125,381.5625 C 174.76953,381.5625 175.20702,381.48525 175.59375,381.3125 C 175.98046,381.13573 176.29687,380.8799 176.5,380.5625 C 176.70703,380.2411 176.81249,379.89282 176.8125,379.53125 C 176.81249,379.16164 176.73046,378.84283 176.5625,378.59375 C 176.39453,378.34467 176.14062,378.15981 175.84375,378.03125 C 175.55078,377.89868 175.02734,377.73613 174.28125,377.53125 C 173.76562,377.38662 173.48046,377.29018 173.375,377.25 C 173.1914,377.17367 173.05468,377.08525 172.96875,376.96875 C 172.88281,376.85626 172.81249,376.73437 172.8125,376.59375 C 172.8125,376.37279 172.91796,376.16473 173.125,376 C 173.33203,375.83529 173.70312,375.75 174.1875,375.75 C 174.59765,375.75001 174.90234,375.84646 175.125,376.03125 C 175.35156,376.21606 175.48437,376.48308 175.53125,376.8125 L 176.5625,376.65625 C 176.49609,376.24245 176.36327,375.93258 176.1875,375.6875 C 176.01171,375.43842 175.74609,375.2384 175.375,375.09375 C 175.00781,374.94913 174.58202,374.87499 174.09375,374.875 z M 191,374.875 C 190.7539,374.87501 190.51952,374.94914 190.3125,375.09375 C 190.10937,375.23839 189.89843,375.51479 189.65625,375.96875 L 189.65625,375 L 188.71875,375 L 188.71875,381.40625 L 189.75,381.40625 L 189.75,378.0625 C 189.75,377.60451 189.82031,377.16695 189.9375,376.78125 C 190.01562,376.52815 190.16015,376.35935 190.34375,376.21875 C 190.52734,376.07413 190.70702,376 190.9375,376 C 191.19531,376.00001 191.46093,376.06207 191.71875,376.21875 L 192.09375,375.21875 C 191.72656,374.98574 191.35546,374.87499 191,374.875 z M 195.34375,374.875 C 194.80859,374.87501 194.34374,374.9411 193.9375,375.09375 C 193.53125,375.2424 193.21484,375.4688 193,375.75 C 192.78516,376.02721 192.65625,376.38977 192.5625,376.84375 L 193.59375,376.96875 C 193.70703,376.51478 193.85937,376.20804 194.09375,376.03125 C 194.33203,375.85047 194.72265,375.78127 195.21875,375.78125 C 195.75,375.78126 196.13671,375.87994 196.40625,376.125 C 196.60546,376.30579 196.71874,376.62059 196.71875,377.0625 C 196.71875,377.10268 196.6914,377.19512 196.6875,377.34375 C 196.28515,377.48838 195.66406,377.61431 194.8125,377.71875 C 194.39453,377.77098 194.08203,377.81876 193.875,377.875 C 193.59375,377.95535 193.35156,378.09331 193.125,378.25 C 192.90234,378.40669 192.70312,378.61388 192.5625,378.875 C 192.42578,379.13212 192.375,379.40538 192.375,379.71875 C 192.375,380.25308 192.53906,380.68576 192.90625,381.03125 C 193.27344,381.37274 193.8164,381.56251 194.5,381.5625 C 194.91406,381.5625 195.29687,381.48436 195.65625,381.34375 C 196.01953,381.20314 196.39062,380.96648 196.78125,380.625 C 196.8125,380.92631 196.89062,381.18127 197,381.40625 L 198.09375,381.40625 C 197.96093,381.16118 197.89062,380.92142 197.84375,380.65625 C 197.80078,380.38708 197.74999,379.72713 197.75,378.71875 L 197.75,377.28125 C 197.74999,376.79915 197.7539,376.46605 197.71875,376.28125 C 197.65624,375.98396 197.53124,375.75533 197.375,375.5625 C 197.21874,375.36565 196.98827,375.19105 196.65625,375.0625 C 196.32421,374.93395 195.87499,374.87499 195.34375,374.875 z M 202.25,374.875 C 201.83593,374.87501 201.44922,374.96342 201.125,375.15625 C 200.80078,375.34508 200.53907,375.59288 200.34375,375.90625 L 200.34375,375 L 199.40625,375 L 199.40625,381.40625 L 200.46875,381.40625 L 200.46875,378.09375 C 200.46875,377.51122 200.51172,377.05936 200.625,376.75 C 200.73828,376.44066 200.9375,376.22322 201.1875,376.0625 C 201.4414,375.90181 201.70313,375.81249 202,375.8125 C 202.39062,375.81251 202.67188,375.9152 202.84375,376.15625 C 203.01562,376.3973 203.09375,376.7679 203.09375,377.25 L 203.09375,381.40625 L 204.15625,381.40625 L 204.15625,377.6875 C 204.15624,377.02863 204.30469,376.54729 204.59375,376.25 C 204.88281,375.94869 205.25,375.81249 205.6875,375.8125 C 205.92968,375.81251 206.13281,375.85225 206.3125,375.96875 C 206.49218,376.08526 206.62109,376.24467 206.6875,376.4375 C 206.7578,376.62633 206.78125,376.94111 206.78125,377.375 L 206.78125,381.40625 L 207.84375,381.40625 L 207.84375,377.03125 C 207.84374,376.30007 207.67578,375.75577 207.34375,375.40625 C 207.01171,375.05272 206.52344,374.87499 205.90625,374.875 C 205.11718,374.87501 204.49219,375.25274 204,376 C 203.8789,375.64647 203.67188,375.3531 203.375,375.15625 C 203.08203,374.9594 202.71094,374.87499 202.25,374.875 z M 212,374.875 C 211.14062,374.87501 210.44531,375.15541 209.90625,375.75 C 209.36719,376.34459 209.09375,377.20455 209.09375,378.28125 C 209.09375,379.32178 209.34375,380.10899 209.875,380.6875 C 210.41015,381.262 211.15234,381.56251 212.0625,381.5625 C 212.78515,381.5625 213.3789,381.36158 213.84375,381 C 214.30859,380.63843 214.60937,380.15484 214.78125,379.5 L 213.6875,379.34375 C 213.52734,379.80175 213.30468,380.13483 213.03125,380.34375 C 212.75781,380.55266 212.44921,380.65625 212.0625,380.65625 C 211.54297,380.65625 211.09765,380.46739 210.75,380.09375 C 210.40234,379.72012 210.22656,379.20306 210.1875,378.5 L 214.8125,378.5 C 214.8164,378.37144 214.81249,378.2518 214.8125,378.1875 C 214.81249,377.1309 214.55858,376.33256 214.03125,375.75 C 213.5039,375.16747 212.83202,374.87499 212,374.875 z M 222.375,374.875 C 221.51172,374.87501 220.86328,375.23443 220.40625,375.9375 L 220.40625,375 L 219.4375,375 L 219.4375,381.40625 L 220.5,381.40625 L 220.5,377.90625 C 220.5,377.08668 220.67578,376.54328 221,376.25 C 221.32812,375.95673 221.70703,375.81249 222.15625,375.8125 C 222.4375,375.81251 222.66797,375.86743 222.875,376 C 223.08593,376.12857 223.23047,376.31029 223.3125,376.53125 C 223.39453,376.7482 223.4375,377.08932 223.4375,377.53125 L 223.4375,381.40625 L 224.5,381.40625 L 224.5,377.46875 C 224.49999,376.96657 224.47656,376.63839 224.4375,376.4375 C 224.37499,376.12816 224.28125,375.84999 224.125,375.625 C 223.96874,375.40003 223.72266,375.23035 223.40625,375.09375 C 223.09375,374.95314 222.75,374.87499 222.375,374.875 z M 238.90625,374.875 C 238.5,374.87501 238.16015,374.96028 237.875,375.125 C 237.58984,375.28571 237.32031,375.51835 237.09375,375.84375 L 237.09375,375 L 236.125,375 L 236.125,383.875 L 237.1875,383.875 L 237.1875,380.75 C 237.36719,380.98302 237.59765,381.15985 237.875,381.3125 C 238.15625,381.46516 238.46094,381.56251 238.8125,381.5625 C 239.29296,381.5625 239.7539,381.43345 240.1875,381.15625 C 240.62499,380.87503 240.96093,380.45978 241.1875,379.9375 C 241.41796,379.41121 241.53124,378.81109 241.53125,378.15625 C 241.53124,377.54559 241.42578,376.97898 241.21875,376.46875 C 241.01171,375.95452 240.71875,375.56249 240.3125,375.28125 C 239.90625,375.00003 239.4375,374.87499 238.90625,374.875 z M 245.375,374.875 C 244.51562,374.87501 243.82031,375.15541 243.28125,375.75 C 242.74219,376.34459 242.46875,377.20455 242.46875,378.28125 C 242.46875,379.32178 242.71875,380.10899 243.25,380.6875 C 243.78515,381.262 244.52734,381.56251 245.4375,381.5625 C 246.16015,381.5625 246.7539,381.36158 247.21875,381 C 247.68359,380.63843 247.98437,380.15484 248.15625,379.5 L 247.0625,379.34375 C 246.90234,379.80175 246.67969,380.13483 246.40625,380.34375 C 246.13281,380.55266 245.82422,380.65625 245.4375,380.65625 C 244.91797,380.65625 244.47266,380.46739 244.125,380.09375 C 243.77734,379.72012 243.60156,379.20306 243.5625,378.5 L 248.1875,378.5 C 248.1914,378.37144 248.1875,378.2518 248.1875,378.1875 C 248.18749,377.1309 247.93359,376.33256 247.40625,375.75 C 246.8789,375.16747 246.20703,374.87499 245.375,374.875 z M 251.78125,374.875 C 251.23047,374.87501 250.75391,375.00004 250.34375,375.28125 C 249.9375,375.56248 249.6211,375.98173 249.40625,376.5 C 249.19141,377.01424 249.09375,377.57683 249.09375,378.1875 C 249.09375,379.07537 249.3125,379.83399 249.78125,380.46875 C 250.25,381.10352 250.92578,381.40625 251.78125,381.40625 C 252.46875,381.40625 253.03906,381.12093 253.5,380.5625 C 253.5039,381.26958 253.49219,381.74779 253.4375,381.96875 C 253.34375,382.33032 253.14063,382.61161 252.875,382.8125 C 252.60937,383.01337 252.23828,383.125 251.75,383.125 C 251.29687,383.125 250.94922,383.01336 250.6875,382.8125 C 250.49219,382.66385 250.35547,382.41918 250.3125,382.09375 L 249.3125,381.9375 C 249.29687,382.62851 249.51172,383.15852 249.96875,383.5 C 250.42578,383.8455 251.00782,383.99999 251.75,384 C 252.375,384 252.91797,383.89729 253.34375,383.65625 C 253.77343,383.4152 254.08594,383.07406 254.28125,382.65625 C 254.48046,382.24245 254.5625,381.52758 254.5625,380.53125 L 254.5625,375 L 253.59375,375 L 253.59375,375.78125 C 253.11718,375.1706 252.51563,374.87499 251.78125,374.875 z M 111.5625,375 L 113.6875,378.09375 L 111.40625,381.40625 L 112.6875,381.40625 L 114.3125,378.875 L 114.65625,379.4375 L 115.9375,381.40625 L 117.21875,381.40625 L 114.90625,378.03125 L 117.0625,375 L 115.8125,375 L 114.75,376.53125 C 114.60547,376.73615 114.45312,376.9536 114.28125,377.21875 C 114.17187,377.02591 114.02343,376.78526 113.84375,376.5 L 112.875,375 L 111.5625,375 z M 118,375 L 118,381.40625 L 119.0625,381.40625 L 119.0625,375 L 118,375 z M 238.8125,375.71875 C 239.26562,375.71876 239.64453,375.90673 239.96875,376.3125 C 240.29687,376.71827 240.46875,377.34071 240.46875,378.15625 C 240.46874,379.01198 240.27343,379.65271 239.9375,380.0625 C 239.60546,380.46827 239.21875,380.65625 238.75,380.65625 C 238.28906,380.65625 237.88672,380.45622 237.5625,380.0625 C 237.23828,379.66879 237.09375,379.0736 237.09375,378.25 C 237.09375,377.42642 237.25,376.80488 237.59375,376.375 C 237.9414,375.94112 238.36328,375.71874 238.8125,375.71875 z M 108,375.75 C 108.53515,375.75001 108.94531,375.95717 109.28125,376.375 C 109.5,376.64418 109.64062,377.0554 109.6875,377.59375 L 106.21875,377.59375 C 106.2539,377.03532 106.42187,376.58345 106.75,376.25 C 107.08203,375.91655 107.51562,375.75 108,375.75 z M 142.59375,375.75 C 143.1289,375.75001 143.53906,375.95717 143.875,376.375 C 144.09375,376.64418 144.23437,377.0554 144.28125,377.59375 L 140.8125,377.59375 C 140.84765,377.03532 141.01562,376.58345 141.34375,376.25 C 141.67578,375.91655 142.10937,375.75 142.59375,375.75 z M 212,375.75 C 212.53515,375.75001 212.97655,375.95717 213.3125,376.375 C 213.53125,376.64418 213.67187,377.0554 213.71875,377.59375 L 210.25,377.59375 L 210.21875,377.59375 C 210.2539,377.03532 210.45312,376.58345 210.78125,376.25 C 211.11328,375.91655 211.51562,375.75 212,375.75 z M 245.375,375.75 C 245.91015,375.75001 246.35156,375.95717 246.6875,376.375 C 246.90625,376.64418 247.04687,377.0554 247.09375,377.59375 L 243.59375,377.59375 C 243.6289,377.03532 243.82813,376.58345 244.15625,376.25 C 244.48828,375.91655 244.89062,375.75 245.375,375.75 z M 251.84375,375.78125 C 252.32031,375.78126 252.72656,375.97726 253.0625,376.375 C 253.40234,376.77274 253.59375,377.3416 253.59375,378.125 C 253.59375,378.94457 253.42188,379.55181 253.09375,379.9375 C 252.76562,380.31916 252.35938,380.50001 251.875,380.5 C 251.38672,380.5 250.98047,380.32319 250.65625,379.9375 C 250.33203,379.55182 250.15625,378.93339 250.15625,378.09375 C 250.15625,377.32239 250.32813,376.73346 250.65625,376.34375 C 250.98437,375.95004 251.375,375.78127 251.84375,375.78125 z M 169.34375,378.1875 L 169.34375,378.59375 C 169.34375,379.07183 169.30077,379.44242 169.1875,379.6875 C 169.03906,380.00488 168.78515,380.2527 168.46875,380.4375 C 168.15234,380.61829 167.81249,380.71876 167.40625,380.71875 C 166.99609,380.71875 166.68359,380.59908 166.46875,380.40625 C 166.25781,380.21341 166.15624,379.97675 166.15625,379.6875 C 166.15625,379.49868 166.18359,379.34016 166.28125,379.1875 C 166.3789,379.03082 166.53905,378.89286 166.71875,378.8125 C 166.89844,378.73215 167.1914,378.68929 167.625,378.625 C 168.39062,378.51251 168.96093,378.34822 169.34375,378.1875 z M 196.6875,378.1875 L 196.6875,378.59375 C 196.6875,379.07183 196.64452,379.44242 196.53125,379.6875 C 196.38281,380.00488 196.16015,380.2527 195.84375,380.4375 C 195.52734,380.61829 195.15624,380.71876 194.75,380.71875 C 194.33984,380.71875 194.02734,380.59908 193.8125,380.40625 C 193.60156,380.21341 193.49999,379.97675 193.5,379.6875 C 193.5,379.49868 193.52734,379.34016 193.625,379.1875 C 193.72265,379.03082 193.88281,378.89286 194.0625,378.8125 C 194.24219,378.73215 194.53515,378.68929 194.96875,378.625 C 195.73437,378.51251 196.30468,378.34822 196.6875,378.1875 z M 257,378.46875 L 255.90625,378.5625 C 255.92187,379.15307 256.07812,379.68621 256.375,380.15625 C 256.67578,380.62228 257.10155,380.98575 257.625,381.21875 C 258.15234,381.45176 258.81639,381.56249 259.59375,381.5625 C 259.73566,381.5625 259.86478,381.54351 260,381.53125 L 260,380.46875 C 259.85157,380.48742 259.69398,380.5 259.53125,380.5 C 259.04297,380.5 258.60936,380.42276 258.21875,380.25 C 257.82812,380.07323 257.53124,379.84372 257.34375,379.5625 C 257.16015,379.27726 257.05077,378.91068 257,378.46875 z M 107.9375,387.96875 C 107.3125,387.96876 106.78906,388.15452 106.375,388.5 C 105.96484,388.84551 105.64843,389.32998 105.4375,389.96875 C 105.23047,390.60352 105.125,391.4242 105.125,392.46875 C 105.125,394.12798 105.40234,395.32729 105.96875,396.0625 C 106.4414,396.67316 107.10937,397 107.9375,397 C 108.5664,397 109.08984,396.81424 109.5,396.46875 C 109.91406,396.11923 110.19921,395.63477 110.40625,395 C 110.61328,394.36122 110.71874,393.50526 110.71875,392.46875 C 110.71874,391.59294 110.66015,390.92049 110.53125,390.40625 C 110.40234,389.888 110.22655,389.45131 110,389.09375 C 109.77343,388.73218 109.5039,388.43882 109.15625,388.25 C 108.80859,388.05717 108.39843,387.96877 107.9375,387.96875 z M 120.5,387.96875 C 119.7539,387.96876 119.16796,388.18711 118.71875,388.625 C 118.26953,389.06292 118.0625,389.60721 118.0625,390.25 C 118.0625,390.67586 118.16406,391.03844 118.375,391.34375 C 118.58594,391.64909 118.90625,391.89779 119.34375,392.0625 C 118.82031,392.20312 118.41015,392.45405 118.125,392.84375 C 117.84375,393.22943 117.6875,393.70674 117.6875,394.28125 C 117.6875,395.05261 117.94922,395.70049 118.46875,396.21875 C 118.98828,396.73299 119.68359,397 120.53125,397 C 121.3789,397 122.07421,396.73299 122.59375,396.21875 C 123.11328,395.70451 123.37499,395.06779 123.375,394.3125 C 123.37499,393.76612 123.21483,393.29995 122.9375,392.90625 C 122.66406,392.51254 122.27734,392.23928 121.75,392.0625 C 122.17578,391.89779 122.48046,391.64506 122.6875,391.34375 C 122.89843,391.03843 122.99999,390.69106 123,390.28125 C 122.99999,389.63846 122.76952,389.10219 122.3125,388.65625 C 121.85546,388.2063 121.24999,387.96877 120.5,387.96875 z M 140.78125,387.96875 C 139.875,387.96876 139.16015,388.29381 138.625,388.96875 C 138.01172,389.74413 137.71875,391.01132 137.71875,392.71875 C 137.71875,394.2454 137.97656,395.33309 138.53125,396 C 139.08594,396.66289 139.80859,397 140.6875,397 C 141.20312,397 141.65624,396.87812 142.0625,396.625 C 142.46874,396.3719 142.80077,396.00531 143.03125,395.53125 C 143.26562,395.05317 143.37499,394.52318 143.375,393.96875 C 143.37499,393.12508 143.12108,392.43657 142.625,391.90625 C 142.13281,391.37193 141.54687,391.09376 140.84375,391.09375 C 140.4414,391.09376 140.05468,391.2134 139.6875,391.40625 C 139.32031,391.5991 139.0039,391.88353 138.75,392.28125 C 138.75781,391.39741 138.87109,390.72808 139.0625,390.25 C 139.2539,389.77192 139.51171,389.40534 139.84375,389.15625 C 140.09765,388.96342 140.38281,388.87502 140.71875,388.875 C 141.13671,388.87501 141.49609,389.00315 141.78125,389.3125 C 141.95312,389.50535 142.09374,389.82414 142.1875,390.25 L 143.21875,390.15625 C 143.13281,389.46927 142.87108,388.95219 142.4375,388.5625 C 142.00781,388.17281 141.45702,387.96877 140.78125,387.96875 z M 210.53125,387.96875 C 209.85156,387.96876 209.26952,388.16076 208.8125,388.5625 C 208.35547,388.96024 208.0664,389.52284 207.9375,390.25 L 209,390.4375 C 209.07812,389.9072 209.2578,389.51517 209.53125,389.25 C 209.80469,388.98485 210.15233,388.87502 210.5625,388.875 C 210.97656,388.87501 211.30077,388.98887 211.5625,389.25 C 211.82421,389.51114 211.96874,389.85226 211.96875,390.25 C 211.96875,390.75219 211.76561,391.10271 211.40625,391.34375 C 211.04687,391.58481 210.66796,391.71877 210.21875,391.71875 C 210.17578,391.71876 210.10155,391.7268 210.03125,391.71875 L 209.90625,392.65625 C 210.20312,392.5759 210.45702,392.53125 210.65625,392.53125 C 211.14453,392.53125 211.55858,392.70583 211.875,393.03125 C 212.1914,393.35265 212.34374,393.75185 212.34375,394.25 C 212.34374,394.77228 212.15624,395.20898 211.8125,395.5625 C 211.47265,395.91604 211.05858,396.09374 210.5625,396.09375 C 210.14453,396.09375 209.79296,395.95668 209.5,395.6875 C 209.21094,395.41431 209.02733,394.98967 208.90625,394.375 L 207.84375,394.5 C 207.91406,395.2352 208.1914,395.85048 208.6875,396.3125 C 209.1875,396.77451 209.80858,397.00001 210.5625,397 C 211.39843,397 212.10936,396.72183 212.65625,396.1875 C 213.20312,395.64916 213.46874,394.9901 213.46875,394.21875 C 213.46874,393.64827 213.31249,393.19015 213.03125,392.8125 C 212.74999,392.43084 212.35155,392.18302 211.84375,392.0625 C 212.23437,391.8777 212.55077,391.62586 212.75,391.3125 C 212.94921,390.99914 213.03124,390.63165 213.03125,390.25 C 213.03124,389.84826 212.92967,389.48257 212.71875,389.125 C 212.51171,388.76745 212.20702,388.48614 211.8125,388.28125 C 211.41796,388.07235 210.99999,387.96877 210.53125,387.96875 z M 225.375,387.96875 C 224.55859,387.96876 223.92188,388.18711 223.4375,388.625 C 222.95312,389.0589 222.66797,389.69962 222.59375,390.53125 L 223.6875,390.625 C 223.6914,390.07059 223.82032,389.65714 224.125,389.34375 C 224.42969,389.03039 224.83594,388.87501 225.34375,388.875 C 225.82421,388.87501 226.23438,389.0152 226.53125,389.3125 C 226.83203,389.60578 226.96875,389.97638 226.96875,390.40625 C 226.96875,390.81604 226.79688,391.25676 226.46875,391.71875 C 226.14062,392.17675 225.52735,392.77506 224.59375,393.5625 C 223.99219,394.06871 223.53907,394.52059 223.21875,394.90625 C 222.90234,395.29193 222.64454,395.69601 222.5,396.09375 C 222.41016,396.3348 222.39844,396.58262 222.40625,396.84375 L 228.0625,396.84375 L 228.0625,395.8125 L 223.84375,395.8125 C 223.96094,395.61564 224.13282,395.41159 224.3125,395.21875 C 224.49219,395.02189 224.89844,394.64014 225.53125,394.09375 C 226.28906,393.43488 226.83203,392.90891 227.15625,392.53125 C 227.48437,392.15361 227.70312,391.81023 227.84375,391.46875 C 227.98437,391.12727 228.0625,390.75979 228.0625,390.40625 C 228.06249,389.71123 227.82422,389.15755 227.34375,388.6875 C 226.86328,388.21746 226.19922,387.96877 225.375,387.96875 z M 235.21875,387.96875 C 234.53906,387.96876 233.98829,388.16076 233.53125,388.5625 C 233.07422,388.96024 232.78516,389.52284 232.65625,390.25 L 233.6875,390.4375 C 233.76562,389.9072 233.94532,389.51517 234.21875,389.25 C 234.49219,388.98485 234.83985,388.87502 235.25,388.875 C 235.66406,388.87501 236.01953,388.98887 236.28125,389.25 C 236.54296,389.51114 236.65625,389.85226 236.65625,390.25 C 236.65625,390.75219 236.48438,391.10271 236.125,391.34375 C 235.76562,391.58481 235.35547,391.71877 234.90625,391.71875 C 234.86328,391.71876 234.82032,391.7268 234.75,391.71875 L 234.625,392.65625 C 234.92187,392.5759 235.17578,392.53125 235.375,392.53125 C 235.86328,392.53125 236.2461,392.70583 236.5625,393.03125 C 236.8789,393.35265 237.03125,393.75185 237.03125,394.25 C 237.03124,394.77228 236.875,395.20898 236.53125,395.5625 C 236.1914,395.91604 235.77735,396.09374 235.28125,396.09375 C 234.86328,396.09375 234.51172,395.95668 234.21875,395.6875 C 233.92969,395.41431 233.71485,394.98967 233.59375,394.375 L 232.53125,394.5 C 232.60156,395.2352 232.87891,395.85048 233.375,396.3125 C 233.875,396.77451 234.52735,397.00001 235.28125,397 C 236.11718,397 236.79688,396.72183 237.34375,396.1875 C 237.89062,395.64916 238.15625,394.9901 238.15625,394.21875 C 238.15624,393.64827 238.03125,393.19015 237.75,392.8125 C 237.46874,392.43084 237.07031,392.18302 236.5625,392.0625 C 236.95312,391.8777 237.23828,391.62586 237.4375,391.3125 C 237.63671,390.99914 237.75,390.63165 237.75,390.25 C 237.74999,389.84826 237.64844,389.48257 237.4375,389.125 C 237.23046,388.76745 236.92578,388.48614 236.53125,388.28125 C 236.13671,388.07235 235.6875,387.96877 235.21875,387.96875 z M 245.34375,387.96875 C 244.71875,387.96876 244.19532,388.15452 243.78125,388.5 C 243.37109,388.84551 243.05469,389.32998 242.84375,389.96875 C 242.63672,390.60352 242.53126,391.4242 242.53125,392.46875 C 242.53125,394.12798 242.83985,395.32729 243.40625,396.0625 C 243.8789,396.67316 244.51563,397 245.34375,397 C 245.97265,397 246.4961,396.81424 246.90625,396.46875 C 247.32031,396.11923 247.63672,395.63477 247.84375,395 C 248.05078,394.36122 248.15625,393.50526 248.15625,392.46875 C 248.15624,391.59294 248.06641,390.92049 247.9375,390.40625 C 247.80859,389.888 247.63281,389.45131 247.40625,389.09375 C 247.17968,388.73218 246.91016,388.43882 246.5625,388.25 C 246.21484,388.05717 245.80469,387.96877 245.34375,387.96875 z M 128.65625,388 L 128.65625,391.1875 C 128.47265,390.92637 128.23047,390.69196 127.9375,390.53125 C 127.64453,390.36654 127.3125,390.28125 126.9375,390.28125 C 126.42578,390.28126 125.97656,390.44155 125.5625,390.71875 C 125.14844,390.99596 124.83203,391.38399 124.625,391.90625 C 124.41797,392.42451 124.3125,393.01748 124.3125,393.65625 C 124.3125,394.3111 124.42969,394.86881 124.65625,395.375 C 124.88672,395.87719 125.21094,396.28127 125.625,396.5625 C 126.04297,396.84372 126.47266,396.96876 126.96875,396.96875 C 127.73437,396.96875 128.32421,396.66603 128.71875,396.03125 L 128.71875,396.84375 L 129.6875,396.84375 L 129.6875,388 L 128.65625,388 z M 131.375,388 L 131.375,396.84375 L 132.34375,396.84375 L 132.34375,396.03125 C 132.76172,396.662 133.32812,396.96876 134.0625,396.96875 C 134.80078,396.96875 135.4414,396.69235 135.96875,396.09375 C 136.49609,395.49514 136.74999,394.62803 136.75,393.53125 C 136.74999,393.06924 136.68749,392.65577 136.5625,392.25 C 136.43749,391.84424 136.28515,391.50398 136.0625,391.21875 C 135.84374,390.9295 135.56249,390.68793 135.21875,390.53125 C 134.8789,390.37056 134.5078,390.28125 134.125,390.28125 C 133.43359,390.28126 132.85156,390.58175 132.40625,391.15625 L 132.40625,388 L 131.375,388 z M 158.375,388 L 158.375,396.84375 L 159.53125,396.84375 L 159.53125,388 L 158.375,388 z M 180.75,388 L 180.75,396.84375 L 181.8125,396.84375 L 181.8125,388 L 180.75,388 z M 183.4375,388 L 183.4375,389.25 L 184.5,389.25 L 184.5,388 L 183.4375,388 z M 190.09375,388 L 190.09375,391.1875 C 189.91015,390.92637 189.66797,390.69196 189.375,390.53125 C 189.08203,390.36654 188.75,390.28125 188.375,390.28125 C 187.86328,390.28126 187.38282,390.44155 186.96875,390.71875 C 186.55469,390.99596 186.23829,391.38399 186.03125,391.90625 C 185.82422,392.42451 185.75001,393.01748 185.75,393.65625 C 185.75,394.3111 185.83594,394.86881 186.0625,395.375 C 186.29297,395.87719 186.61719,396.28127 187.03125,396.5625 C 187.44922,396.84372 187.91016,396.96876 188.40625,396.96875 C 189.17187,396.96875 189.76172,396.66603 190.15625,396.03125 L 190.15625,396.84375 L 191.125,396.84375 L 191.125,388 L 190.09375,388 z M 196.4375,388 L 196.4375,396.84375 L 197.59375,396.84375 L 197.59375,388 L 196.4375,388 z M 199.59375,388 L 199.59375,396.84375 L 202.6875,396.84375 C 203.20703,396.84375 203.66406,396.78792 204.0625,396.6875 C 204.46484,396.58706 204.8125,396.44285 205.09375,396.25 C 205.3789,396.05314 205.63672,395.77497 205.875,395.4375 C 206.11327,395.09601 206.31641,394.67451 206.46875,394.15625 C 206.62109,393.638 206.6875,393.04594 206.6875,392.375 C 206.68749,391.58758 206.57031,390.89193 206.34375,390.28125 C 206.12109,389.66658 205.79687,389.14372 205.34375,388.75 C 204.99609,388.44468 204.55469,388.24151 204.0625,388.125 C 203.71093,388.04064 203.19922,388.00001 202.53125,388 L 199.59375,388 z M 214.0625,388 L 217.40625,396.84375 L 218.5625,396.84375 L 221.9375,388 L 220.75,388 L 218.4375,394.4375 C 218.26171,394.9196 218.10155,395.3929 217.96875,395.875 C 217.84765,395.42504 217.71093,394.95173 217.53125,394.4375 L 215.3125,388 L 214.0625,388 z M 254.09375,388.21875 L 253.03125,388.84375 L 253.03125,390.4375 L 252.25,390.4375 L 252.25,391.28125 L 253.03125,391.28125 L 253.03125,394.96875 C 253.03125,395.61959 253.0703,396.04512 253.15625,396.25 C 253.24219,396.45088 253.41405,396.62547 253.625,396.75 C 253.83594,396.87454 254.11718,396.93749 254.5,396.9375 C 254.73437,396.9375 255.01561,396.87679 255.3125,396.8125 L 255.15625,395.875 C 254.96484,395.90312 254.80468,395.90625 254.6875,395.90625 C 254.53125,395.90625 254.39843,395.89598 254.3125,395.84375 C 254.23047,395.79152 254.16405,395.71338 254.125,395.625 C 254.08984,395.53662 254.09374,395.34061 254.09375,395.03125 L 254.09375,391.28125 L 255.15625,391.28125 L 255.15625,390.4375 L 254.09375,390.4375 L 254.09375,388.21875 z M 107.90625,388.875 C 108.39843,388.87501 108.82812,389.11566 109.15625,389.59375 C 109.48828,390.07184 109.65624,391.01442 109.65625,392.46875 C 109.65624,393.91505 109.48827,394.89292 109.15625,395.375 C 108.82812,395.8571 108.42187,396.09374 107.9375,396.09375 C 107.45312,396.09375 107.05078,395.85308 106.71875,395.375 C 106.39062,394.8929 106.21875,393.91906 106.21875,392.46875 C 106.21875,391.01844 106.38671,390.03835 106.75,389.5 C 107.03906,389.07817 107.42187,388.87501 107.90625,388.875 z M 120.25,388.875 C 120.34204,388.85843 120.43066,388.87501 120.53125,388.875 C 120.92968,388.87501 121.26562,389.00808 121.53125,389.28125 C 121.80078,389.55043 121.93749,389.88352 121.9375,390.28125 C 121.9375,390.66292 121.79296,390.98486 121.53125,391.25 C 121.27343,391.51114 120.93749,391.625 120.53125,391.625 C 120.11328,391.62501 119.79296,391.51516 119.53125,391.25 C 119.26953,390.98485 119.125,390.63659 119.125,390.21875 C 119.125,389.84915 119.26562,389.51517 119.53125,389.25 C 119.73047,389.05114 119.97388,388.92472 120.25,388.875 z M 245.34375,388.875 C 245.83593,388.87501 246.23438,389.11566 246.5625,389.59375 C 246.89453,390.07184 247.0625,391.01442 247.0625,392.46875 C 247.06249,393.91505 246.89453,394.89292 246.5625,395.375 C 246.23437,395.8571 245.82813,396.09374 245.34375,396.09375 C 244.85937,396.09375 244.45704,395.85308 244.125,395.375 C 243.79687,394.8929 243.62501,393.91906 243.625,392.46875 C 243.625,391.01844 243.79297,390.03835 244.15625,389.5 C 244.44531,389.07817 244.85938,388.87501 245.34375,388.875 z M 200.71875,389.0625 L 202.53125,389.0625 C 203.20703,389.06251 203.69531,389.09823 204,389.21875 C 204.42187,389.38749 204.76953,389.72058 205.0625,390.21875 C 205.35937,390.71291 205.53125,391.41973 205.53125,392.34375 C 205.53124,393.01066 205.43359,393.59247 205.28125,394.0625 C 205.13281,394.52853 204.92578,394.9103 204.65625,395.1875 C 204.46484,395.38436 204.19922,395.51652 203.875,395.625 C 203.55468,395.73347 203.12891,395.81251 202.5625,395.8125 L 200.71875,395.8125 L 200.71875,389.0625 z M 147.34375,390.28125 C 146.80859,390.28126 146.34374,390.37858 145.9375,390.53125 C 145.53125,390.6799 145.21484,390.87502 145,391.15625 C 144.78516,391.43346 144.65624,391.79603 144.5625,392.25 L 145.59375,392.40625 C 145.70703,391.95228 145.85937,391.64552 146.09375,391.46875 C 146.33203,391.28797 146.72265,391.18749 147.21875,391.1875 C 147.75,391.18751 148.13671,391.31744 148.40625,391.5625 C 148.60546,391.74329 148.71874,392.05807 148.71875,392.5 C 148.71875,392.54018 148.6914,392.6326 148.6875,392.78125 C 148.28515,392.92588 147.66405,393.05179 146.8125,393.15625 C 146.39453,393.20848 146.08202,393.25627 145.875,393.3125 C 145.59375,393.39285 145.35156,393.49957 145.125,393.65625 C 144.90234,393.81294 144.70312,394.02011 144.5625,394.28125 C 144.42578,394.53837 144.37499,394.84289 144.375,395.15625 C 144.375,395.69058 144.53906,396.12324 144.90625,396.46875 C 145.27344,396.81024 145.8164,396.96876 146.5,396.96875 C 146.91406,396.96875 147.29687,396.92186 147.65625,396.78125 C 148.01953,396.64064 148.39061,396.40398 148.78125,396.0625 C 148.8125,396.36381 148.89061,396.61878 149,396.84375 L 150.09375,396.84375 C 149.96093,396.59868 149.89061,396.32765 149.84375,396.0625 C 149.80078,395.79333 149.74999,395.16464 149.75,394.15625 L 149.75,392.71875 C 149.74999,392.23665 149.75389,391.90356 149.71875,391.71875 C 149.65624,391.42146 149.53124,391.16159 149.375,390.96875 C 149.21874,390.7719 148.98827,390.62856 148.65625,390.5 C 148.32421,390.37145 147.87499,390.28125 147.34375,390.28125 z M 164.3125,390.28125 C 163.44922,390.28126 162.80078,390.64069 162.34375,391.34375 L 162.34375,390.4375 L 161.375,390.4375 L 161.375,396.84375 L 162.4375,396.84375 L 162.4375,393.34375 C 162.4375,392.52418 162.61328,391.98078 162.9375,391.6875 C 163.26562,391.39423 163.64453,391.25 164.09375,391.25 C 164.375,391.25001 164.63671,391.30494 164.84375,391.4375 C 165.05468,391.56607 165.19921,391.74779 165.28125,391.96875 C 165.36328,392.1857 165.40624,392.49557 165.40625,392.9375 L 165.40625,396.84375 L 166.4375,396.84375 L 166.4375,392.90625 C 166.43749,392.40407 166.41405,392.04462 166.375,391.84375 C 166.31249,391.53441 166.21874,391.2875 166.0625,391.0625 C 165.90624,390.83753 165.66015,390.63661 165.34375,390.5 C 165.03125,390.35939 164.68749,390.28125 164.3125,390.28125 z M 176.71875,390.28125 C 176.18359,390.28126 175.71874,390.37858 175.3125,390.53125 C 174.90625,390.6799 174.58984,390.87502 174.375,391.15625 C 174.16016,391.43346 174,391.79603 173.90625,392.25 L 174.9375,392.40625 C 175.05078,391.95228 175.23437,391.64552 175.46875,391.46875 C 175.70703,391.28797 176.0664,391.18749 176.5625,391.1875 C 177.09375,391.18751 177.51171,391.31744 177.78125,391.5625 C 177.98046,391.74329 178.06249,392.05807 178.0625,392.5 C 178.0625,392.54018 178.0664,392.6326 178.0625,392.78125 C 177.66015,392.92588 177.03905,393.05179 176.1875,393.15625 C 175.76953,393.20848 175.45702,393.25627 175.25,393.3125 C 174.96875,393.39285 174.72656,393.49957 174.5,393.65625 C 174.27734,393.81294 174.07812,394.02011 173.9375,394.28125 C 173.80078,394.53837 173.75,394.84289 173.75,395.15625 C 173.75,395.69058 173.91406,396.12324 174.28125,396.46875 C 174.64844,396.81024 175.1914,396.96876 175.875,396.96875 C 176.28906,396.96875 176.67187,396.92186 177.03125,396.78125 C 177.39453,396.64064 177.76562,396.40398 178.15625,396.0625 C 178.1875,396.36381 178.26562,396.61878 178.375,396.84375 L 179.46875,396.84375 C 179.33593,396.59868 179.23436,396.32765 179.1875,396.0625 C 179.14453,395.79333 179.12499,395.16464 179.125,394.15625 L 179.125,392.71875 C 179.12499,392.23665 179.1289,391.90356 179.09375,391.71875 C 179.03124,391.42146 178.90624,391.16159 178.75,390.96875 C 178.59374,390.7719 178.36327,390.62856 178.03125,390.5 C 177.69921,390.37145 177.24999,390.28125 176.71875,390.28125 z M 258.8125,390.28125 C 258.27734,390.28126 257.78124,390.37858 257.375,390.53125 C 256.96875,390.6799 256.68358,390.87502 256.46875,391.15625 C 256.25391,391.43346 256.09376,391.79603 256,392.25 L 257.03125,392.40625 C 257.14453,391.95228 257.32811,391.64552 257.5625,391.46875 C 257.80078,391.28797 258.16015,391.18749 258.65625,391.1875 C 259.1875,391.18751 259.57421,391.31744 259.84375,391.5625 C 259.90815,391.62095 259.95642,391.69552 260,391.78125 L 260,390.46875 C 259.68061,390.36101 259.29883,390.28125 258.8125,390.28125 z M 111.5625,390.4375 L 113.6875,393.5 L 111.40625,396.84375 L 112.6875,396.84375 L 114.3125,394.3125 L 114.65625,394.84375 L 115.9375,396.84375 L 117.21875,396.84375 L 114.90625,393.4375 L 117.0625,390.4375 L 115.8125,390.4375 L 114.75,391.9375 C 114.60547,392.1424 114.45312,392.39111 114.28125,392.65625 C 114.17187,392.46341 114.02343,392.22274 113.84375,391.9375 L 112.875,390.4375 L 111.5625,390.4375 z M 151.6875,390.4375 L 151.6875,391.6875 L 152.90625,391.6875 L 152.90625,390.4375 L 151.6875,390.4375 z M 167.4375,390.4375 L 169.8125,396.84375 L 170.78125,396.84375 L 173.125,390.4375 L 172.0625,390.4375 L 170.65625,394.34375 C 170.48828,394.81782 170.37499,395.22503 170.28125,395.5625 C 170.16015,395.11656 170.01952,394.69505 169.875,394.28125 L 168.53125,390.4375 L 167.4375,390.4375 z M 183.4375,390.4375 L 183.4375,396.84375 L 184.5,396.84375 L 184.5,390.4375 L 183.4375,390.4375 z M 127.03125,391.1875 C 127.51172,391.18751 127.92187,391.40273 128.25,391.8125 C 128.57812,392.22229 128.74999,392.87419 128.75,393.75 C 128.75,394.54547 128.57421,395.11031 128.25,395.5 C 127.92968,395.88568 127.55469,396.09376 127.09375,396.09375 C 126.63672,396.09375 126.24219,395.87452 125.90625,395.46875 C 125.57031,395.06298 125.375,394.47583 125.375,393.65625 C 125.375,392.80856 125.53125,392.17498 125.84375,391.78125 C 126.16015,391.38754 126.5625,391.18749 127.03125,391.1875 z M 134.03125,391.1875 C 134.48828,391.18751 134.86718,391.38354 135.1875,391.78125 C 135.51171,392.17899 135.68749,392.78937 135.6875,393.625 C 135.68749,394.44055 135.52343,395.05496 135.1875,395.46875 C 134.85156,395.87854 134.42968,396.09376 133.96875,396.09375 C 133.40234,396.09375 132.95702,395.80844 132.625,395.25 C 132.42187,394.90851 132.31249,394.36109 132.3125,393.59375 C 132.3125,392.81436 132.50781,392.2223 132.84375,391.8125 C 133.17968,391.3987 133.57031,391.18751 134.03125,391.1875 z M 188.46875,391.1875 C 188.94922,391.18751 189.35938,391.40273 189.6875,391.8125 C 190.01562,392.22229 190.15625,392.87419 190.15625,393.75 C 190.15625,394.54547 190.01172,395.11031 189.6875,395.5 C 189.36718,395.88568 188.96094,396.09376 188.5,396.09375 C 188.04297,396.09375 187.64844,395.87452 187.3125,395.46875 C 186.97656,395.06298 186.81251,394.47583 186.8125,393.65625 C 186.8125,392.80856 186.96876,392.17498 187.28125,391.78125 C 187.59765,391.38754 188,391.18749 188.46875,391.1875 z M 140.625,392.0625 C 141.10546,392.0625 141.49609,392.24021 141.8125,392.59375 C 142.1289,392.94328 142.31249,393.42058 142.3125,394.03125 C 142.31249,394.66602 142.1328,395.16163 141.8125,395.53125 C 141.49218,395.90086 141.10155,396.09374 140.65625,396.09375 C 140.35156,396.09375 140.08984,396.02052 139.8125,395.84375 C 139.53515,395.66296 139.31249,395.40399 139.15625,395.0625 C 139.0039,394.72101 138.90624,394.34238 138.90625,393.96875 C 138.90625,393.39827 139.07421,392.94327 139.40625,392.59375 C 139.73828,392.24021 140.14843,392.06252 140.625,392.0625 z M 120.5,392.53125 C 121.00781,392.53125 121.44531,392.68978 121.78125,393.03125 C 122.12109,393.37274 122.28124,393.79023 122.28125,394.3125 C 122.28124,394.82674 122.10937,395.26029 121.78125,395.59375 C 121.45312,395.9272 121.03515,396.09374 120.53125,396.09375 C 120.20703,396.09375 119.90624,396.03169 119.625,395.875 C 119.34375,395.7143 119.14453,395.47676 119,395.1875 C 118.85937,394.89824 118.78125,394.59061 118.78125,394.28125 C 118.78125,393.77505 118.95703,393.36872 119.28125,393.03125 C 119.60937,392.69378 120.0039,392.53124 120.5,392.53125 z M 260,392.8125 C 259.59742,392.93921 259.01717,393.06214 258.25,393.15625 C 257.83203,393.20848 257.51952,393.25627 257.3125,393.3125 C 257.03125,393.39285 256.78905,393.49957 256.5625,393.65625 C 256.33984,393.81294 256.17187,394.02011 256.03125,394.28125 C 255.89453,394.53837 255.81251,394.84289 255.8125,395.15625 C 255.8125,395.69058 256.0078,396.12324 256.375,396.46875 C 256.74219,396.81024 257.2539,396.96876 257.9375,396.96875 C 258.35156,396.96875 258.73436,396.92186 259.09375,396.78125 C 259.38856,396.66714 259.68717,396.46516 260,396.21875 L 260,395 C 259.98696,395.03665 259.98379,395.09246 259.96875,395.125 C 259.82031,395.44238 259.59764,395.69021 259.28125,395.875 C 258.96484,396.05579 258.59374,396.12501 258.1875,396.125 C 257.77734,396.125 257.46483,396.03659 257.25,395.84375 C 257.03906,395.65091 256.93749,395.41426 256.9375,395.125 C 256.9375,394.93618 256.99608,394.77767 257.09375,394.625 C 257.1914,394.46832 257.3203,394.33036 257.5,394.25 C 257.67969,394.16965 257.97265,394.09552 258.40625,394.03125 C 259.08643,393.93132 259.62195,393.82548 260,393.6875 L 260,392.8125 z M 148.6875,393.625 L 148.6875,394.03125 C 148.6875,394.50933 148.64452,394.87993 148.53125,395.125 C 148.38281,395.44238 148.16015,395.69021 147.84375,395.875 C 147.52734,396.05579 147.15624,396.12501 146.75,396.125 C 146.33984,396.125 146.02734,396.03659 145.8125,395.84375 C 145.60156,395.65091 145.49999,395.41426 145.5,395.125 C 145.5,394.93618 145.52734,394.77767 145.625,394.625 C 145.72265,394.46832 145.8828,394.33036 146.0625,394.25 C 146.24219,394.16965 146.53515,394.09552 146.96875,394.03125 C 147.73437,393.91876 148.30468,393.78569 148.6875,393.625 z M 178.0625,393.625 L 178.0625,394.03125 C 178.0625,394.50933 178.01952,394.87993 177.90625,395.125 C 177.75781,395.44238 177.5039,395.69021 177.1875,395.875 C 176.87109,396.05579 176.53124,396.12501 176.125,396.125 C 175.71484,396.125 175.40234,396.03659 175.1875,395.84375 C 174.97656,395.65091 174.87499,395.41426 174.875,395.125 C 174.875,394.93618 174.90234,394.77767 175,394.625 C 175.09765,394.46832 175.25781,394.33036 175.4375,394.25 C 175.61719,394.16965 175.91015,394.09552 176.34375,394.03125 C 177.10937,393.91876 177.67968,393.78569 178.0625,393.625 z M 151.6875,395.59375 L 151.6875,396.84375 L 152.90625,396.84375 L 152.90625,395.59375 L 151.6875,395.59375 z M 229.8125,395.59375 L 229.8125,396.84375 L 231,396.84375 L 231,395.59375 L 229.8125,395.59375 z M 239.8125,395.59375 L 239.8125,396.84375 L 241,396.84375 L 241,395.59375 L 239.8125,395.59375 z M 107.9375,403.40625 C 107.3125,403.40626 106.78906,403.56075 106.375,403.90625 C 105.96484,404.25176 105.64843,404.76749 105.4375,405.40625 C 105.23047,406.04102 105.125,406.86171 105.125,407.90625 C 105.125,409.56548 105.40234,410.7648 105.96875,411.5 C 106.4414,412.11066 107.10937,412.40626 107.9375,412.40625 C 108.5664,412.40625 109.08984,412.25175 109.5,411.90625 C 109.91406,411.55673 110.19921,411.07227 110.40625,410.4375 C 110.61328,409.79872 110.71874,408.94277 110.71875,407.90625 C 110.71874,407.03044 110.66015,406.32675 110.53125,405.8125 C 110.40234,405.29425 110.22655,404.85757 110,404.5 C 109.77343,404.13843 109.5039,403.87633 109.15625,403.6875 C 108.80859,403.49467 108.39843,403.40627 107.9375,403.40625 z M 120.5,403.40625 C 119.7539,403.40626 119.16796,403.62462 118.71875,404.0625 C 118.26953,404.50042 118.0625,405.04472 118.0625,405.6875 C 118.0625,406.11336 118.16406,406.47591 118.375,406.78125 C 118.58594,407.08659 118.90625,407.30405 119.34375,407.46875 C 118.82031,407.60937 118.41015,407.89156 118.125,408.28125 C 117.84375,408.66693 117.6875,409.14425 117.6875,409.71875 C 117.6875,410.49011 117.94922,411.138 118.46875,411.65625 C 118.98828,412.17049 119.68359,412.40626 120.53125,412.40625 C 121.3789,412.40625 122.07421,412.1705 122.59375,411.65625 C 123.11328,411.14201 123.37499,410.5053 123.375,409.75 C 123.37499,409.20362 123.21483,408.73746 122.9375,408.34375 C 122.66406,407.95004 122.27734,407.64554 121.75,407.46875 C 122.17578,407.30404 122.48046,407.08257 122.6875,406.78125 C 122.89843,406.47593 122.99999,406.12853 123,405.71875 C 122.99999,405.07596 122.76952,404.50845 122.3125,404.0625 C 121.85546,403.61255 121.24999,403.40627 120.5,403.40625 z M 140.78125,403.40625 C 139.875,403.40626 139.16015,403.73132 138.625,404.40625 C 138.01172,405.18163 137.71875,406.41758 137.71875,408.125 C 137.71875,409.65165 137.97656,410.7706 138.53125,411.4375 C 139.08594,412.10039 139.80859,412.40626 140.6875,412.40625 C 141.20312,412.40625 141.65624,412.28434 142.0625,412.03125 C 142.46874,411.77815 142.80077,411.41156 143.03125,410.9375 C 143.26562,410.45942 143.37499,409.96066 143.375,409.40625 C 143.37499,408.56258 143.12108,407.87405 142.625,407.34375 C 142.13281,406.80943 141.54687,406.53127 140.84375,406.53125 C 140.4414,406.53126 140.05468,406.61966 139.6875,406.8125 C 139.32031,407.00535 139.0039,407.32101 138.75,407.71875 C 138.75781,406.83491 138.87109,406.13434 139.0625,405.65625 C 139.2539,405.17817 139.51171,404.8116 139.84375,404.5625 C 140.09765,404.36967 140.38281,404.28125 140.71875,404.28125 C 141.13671,404.28126 141.49609,404.44065 141.78125,404.75 C 141.95312,404.94285 142.09374,405.26165 142.1875,405.6875 L 143.21875,405.59375 C 143.13281,404.90677 142.87108,404.35845 142.4375,403.96875 C 142.00781,403.57906 141.45702,403.40627 140.78125,403.40625 z M 210.53125,403.40625 C 209.85156,403.40626 209.26952,403.59827 208.8125,404 C 208.35547,404.39774 208.0664,404.96035 207.9375,405.6875 L 209,405.875 C 209.07812,405.3447 209.2578,404.95265 209.53125,404.6875 C 209.80469,404.42235 210.15233,404.28125 210.5625,404.28125 C 210.97656,404.28126 211.30077,404.42638 211.5625,404.6875 C 211.82421,404.94864 211.96874,405.25852 211.96875,405.65625 C 211.96875,406.15844 211.76561,406.54019 211.40625,406.78125 C 211.04687,407.02231 210.66796,407.15624 210.21875,407.15625 C 210.17578,407.15626 210.10155,407.13303 210.03125,407.125 L 209.90625,408.09375 C 210.20312,408.0134 210.45702,407.96876 210.65625,407.96875 C 211.14453,407.96875 211.55858,408.11209 211.875,408.4375 C 212.1914,408.7589 212.34374,409.18932 212.34375,409.6875 C 212.34374,410.20978 212.15624,410.64645 211.8125,411 C 211.47265,411.35354 211.05858,411.53125 210.5625,411.53125 C 210.14453,411.53125 209.79296,411.39416 209.5,411.125 C 209.21094,410.85181 209.02733,410.39593 208.90625,409.78125 L 207.84375,409.9375 C 207.91406,410.6727 208.1914,411.25673 208.6875,411.71875 C 209.1875,412.18076 209.80858,412.43749 210.5625,412.4375 C 211.39843,412.4375 212.10936,412.15934 212.65625,411.625 C 213.20312,411.08666 213.46874,410.42761 213.46875,409.65625 C 213.46874,409.08577 213.31249,408.62766 213.03125,408.25 C 212.74999,407.86834 212.35155,407.58927 211.84375,407.46875 C 212.23437,407.28395 212.55077,407.06336 212.75,406.75 C 212.94921,406.43664 213.03124,406.06916 213.03125,405.6875 C 213.03124,405.28576 212.92967,404.92008 212.71875,404.5625 C 212.51171,404.20495 212.20702,403.92365 211.8125,403.71875 C 211.41796,403.50985 210.99999,403.40627 210.53125,403.40625 z M 225.375,403.40625 C 224.55859,403.40626 223.92188,403.62462 223.4375,404.0625 C 222.95312,404.4964 222.66797,405.10588 222.59375,405.9375 L 223.6875,406.0625 C 223.6914,405.50809 223.82032,405.06336 224.125,404.75 C 224.42969,404.43664 224.83594,404.28126 225.34375,404.28125 C 225.82421,404.28126 226.23438,404.45271 226.53125,404.75 C 226.83203,405.04328 226.96875,405.38264 226.96875,405.8125 C 226.96875,406.22229 226.79688,406.66298 226.46875,407.125 C 226.14062,407.583 225.52735,408.21257 224.59375,409 C 223.99219,409.50621 223.53907,409.95806 223.21875,410.34375 C 222.90234,410.72943 222.64454,411.10227 222.5,411.5 C 222.41016,411.74105 222.39844,412.02013 222.40625,412.28125 L 228.0625,412.28125 L 228.0625,411.21875 L 223.84375,411.21875 C 223.96094,411.02189 224.13282,410.81784 224.3125,410.625 C 224.49219,410.42814 224.89844,410.07762 225.53125,409.53125 C 226.28906,408.87238 226.83203,408.34639 227.15625,407.96875 C 227.48437,407.59111 227.70312,407.24774 227.84375,406.90625 C 227.98437,406.56477 228.0625,406.1973 228.0625,405.84375 C 228.06249,405.14873 227.82422,404.56381 227.34375,404.09375 C 226.86328,403.62371 226.19922,403.40627 225.375,403.40625 z M 245.34375,403.40625 C 244.71875,403.40626 244.19532,403.56075 243.78125,403.90625 C 243.37109,404.25176 243.05469,404.76749 242.84375,405.40625 C 242.63672,406.04102 242.53126,406.86171 242.53125,407.90625 C 242.53125,409.56548 242.83985,410.7648 243.40625,411.5 C 243.8789,412.11066 244.51563,412.40626 245.34375,412.40625 C 245.97265,412.40625 246.4961,412.25175 246.90625,411.90625 C 247.32031,411.55673 247.63672,411.07227 247.84375,410.4375 C 248.05078,409.79872 248.15625,408.94277 248.15625,407.90625 C 248.15624,407.03044 248.06641,406.32675 247.9375,405.8125 C 247.80859,405.29425 247.63281,404.85757 247.40625,404.5 C 247.17968,404.13843 246.91016,403.87633 246.5625,403.6875 C 246.21484,403.49467 245.80469,403.40627 245.34375,403.40625 z M 128.65625,403.4375 L 128.65625,406.59375 C 128.47265,406.33262 128.23047,406.12947 127.9375,405.96875 C 127.64453,405.80404 127.3125,405.71876 126.9375,405.71875 C 126.42578,405.71876 125.97656,405.84781 125.5625,406.125 C 125.14844,406.40221 124.83203,406.82147 124.625,407.34375 C 124.41797,407.86201 124.3125,408.42373 124.3125,409.0625 C 124.3125,409.71735 124.42969,410.30629 124.65625,410.8125 C 124.88672,411.31469 125.21094,411.71877 125.625,412 C 126.04297,412.28122 126.47266,412.40624 126.96875,412.40625 C 127.73437,412.40625 128.32421,412.10351 128.71875,411.46875 L 128.71875,412.28125 L 129.6875,412.28125 L 129.6875,403.4375 L 128.65625,403.4375 z M 131.375,403.4375 L 131.375,412.28125 L 132.34375,412.28125 L 132.34375,411.46875 C 132.76172,412.0995 133.32812,412.40624 134.0625,412.40625 C 134.80078,412.40625 135.4414,412.09861 135.96875,411.5 C 136.49609,410.90139 136.74999,410.06554 136.75,408.96875 C 136.74999,408.50674 136.68749,408.06203 136.5625,407.65625 C 136.43749,407.25049 136.28515,406.91024 136.0625,406.625 C 135.84374,406.33575 135.56249,406.12543 135.21875,405.96875 C 134.8789,405.80806 134.5078,405.71876 134.125,405.71875 C 133.43359,405.71876 132.85156,406.01926 132.40625,406.59375 L 132.40625,403.4375 L 131.375,403.4375 z M 158.375,403.4375 L 158.375,412.28125 L 159.53125,412.28125 L 159.53125,403.4375 L 158.375,403.4375 z M 180.75,403.4375 L 180.75,412.28125 L 181.8125,412.28125 L 181.8125,403.4375 L 180.75,403.4375 z M 183.4375,403.4375 L 183.4375,404.6875 L 184.5,404.6875 L 184.5,403.4375 L 183.4375,403.4375 z M 190.09375,403.4375 L 190.09375,406.59375 C 189.91015,406.33262 189.66797,406.12947 189.375,405.96875 C 189.08203,405.80404 188.75,405.71876 188.375,405.71875 C 187.86328,405.71876 187.38282,405.84781 186.96875,406.125 C 186.55469,406.40221 186.23829,406.82147 186.03125,407.34375 C 185.82422,407.86201 185.75001,408.42373 185.75,409.0625 C 185.75,409.71735 185.83594,410.30629 186.0625,410.8125 C 186.29297,411.31469 186.61719,411.71877 187.03125,412 C 187.44922,412.28122 187.91016,412.40624 188.40625,412.40625 C 189.17187,412.40625 189.76172,412.10351 190.15625,411.46875 L 190.15625,412.28125 L 191.125,412.28125 L 191.125,403.4375 L 190.09375,403.4375 z M 196.4375,403.4375 L 196.4375,412.28125 L 197.59375,412.28125 L 197.59375,403.4375 L 196.4375,403.4375 z M 199.59375,403.4375 L 199.59375,412.28125 L 202.6875,412.28125 C 203.20703,412.28125 203.66406,412.22543 204.0625,412.125 C 204.46484,412.02456 204.8125,411.88033 205.09375,411.6875 C 205.3789,411.49064 205.63672,411.21248 205.875,410.875 C 206.11327,410.53351 206.31641,410.11202 206.46875,409.59375 C 206.62109,409.0755 206.6875,408.48341 206.6875,407.8125 C 206.68749,407.02508 206.57031,406.32941 206.34375,405.71875 C 206.12109,405.10408 205.79687,404.58123 205.34375,404.1875 C 204.99609,403.88218 204.55469,403.67902 204.0625,403.5625 C 203.71093,403.47814 203.19922,403.43752 202.53125,403.4375 L 199.59375,403.4375 z M 214.0625,403.4375 L 217.40625,412.28125 L 218.5625,412.28125 L 221.9375,403.4375 L 220.75,403.4375 L 218.4375,409.84375 C 218.26171,410.32585 218.10155,410.79916 217.96875,411.28125 C 217.84765,410.83129 217.71093,410.35798 217.53125,409.84375 L 215.3125,403.4375 L 214.0625,403.4375 z M 236.09375,403.4375 L 232.1875,409.15625 L 232.1875,410.15625 L 235.90625,410.15625 L 235.90625,412.28125 L 236.96875,412.28125 L 236.96875,410.15625 L 238.125,410.15625 L 238.125,409.15625 L 236.96875,409.15625 L 236.96875,403.4375 L 236.09375,403.4375 z M 254.09375,403.625 L 253.03125,404.28125 L 253.03125,405.875 L 252.25,405.875 L 252.25,406.71875 L 253.03125,406.71875 L 253.03125,410.40625 C 253.03125,411.05709 253.0703,411.4826 253.15625,411.6875 C 253.24219,411.88838 253.41405,412.03169 253.625,412.15625 C 253.83594,412.28079 254.11718,412.34375 254.5,412.34375 C 254.73437,412.34375 255.01561,412.31427 255.3125,412.25 L 255.15625,411.28125 C 254.96484,411.30937 254.80468,411.34376 254.6875,411.34375 C 254.53125,411.34375 254.39843,411.30224 254.3125,411.25 C 254.23047,411.19777 254.16405,411.15088 254.125,411.0625 C 254.08984,410.97412 254.09374,410.74684 254.09375,410.4375 L 254.09375,406.71875 L 255.15625,406.71875 L 255.15625,405.875 L 254.09375,405.875 L 254.09375,403.625 z M 107.90625,404.28125 C 108.39843,404.28126 108.82812,404.52192 109.15625,405 C 109.48828,405.47809 109.65624,406.45192 109.65625,407.90625 C 109.65624,409.35255 109.48827,410.33039 109.15625,410.8125 C 108.82812,411.2946 108.42187,411.53125 107.9375,411.53125 C 107.45312,411.53125 107.05078,411.29059 106.71875,410.8125 C 106.39062,410.3304 106.21875,409.35657 106.21875,407.90625 C 106.21875,406.45594 106.38671,405.47586 106.75,404.9375 C 107.03906,404.51567 107.42187,404.28126 107.90625,404.28125 z M 120.53125,404.28125 C 120.92968,404.28126 121.26562,404.41431 121.53125,404.6875 C 121.80078,404.95668 121.93749,405.28978 121.9375,405.6875 C 121.9375,406.06917 121.79296,406.39109 121.53125,406.65625 C 121.27343,406.91739 120.93749,407.06251 120.53125,407.0625 C 120.11328,407.06251 119.79296,406.92142 119.53125,406.65625 C 119.26953,406.3911 119.125,406.04281 119.125,405.625 C 119.125,405.2554 119.26562,404.95265 119.53125,404.6875 C 119.79687,404.42235 120.1289,404.28125 120.53125,404.28125 z M 245.34375,404.28125 C 245.83593,404.28126 246.23438,404.52192 246.5625,405 C 246.89453,405.47809 247.0625,406.45192 247.0625,407.90625 C 247.06249,409.35255 246.89453,410.33039 246.5625,410.8125 C 246.23437,411.2946 245.82813,411.53125 245.34375,411.53125 C 244.85937,411.53125 244.45704,411.29059 244.125,410.8125 C 243.79687,410.3304 243.62501,409.35657 243.625,407.90625 C 243.625,406.45594 243.79297,405.47586 244.15625,404.9375 C 244.44531,404.51567 244.85938,404.28126 245.34375,404.28125 z M 200.71875,404.46875 L 202.53125,404.46875 C 203.20703,404.46876 203.69531,404.53574 204,404.65625 C 204.42187,404.82499 204.76953,405.15809 205.0625,405.65625 C 205.35937,406.15041 205.53125,406.85724 205.53125,407.78125 C 205.53124,408.44816 205.43359,409.02995 205.28125,409.5 C 205.13281,409.96603 204.92578,410.31655 204.65625,410.59375 C 204.46484,410.79061 204.19922,410.95402 203.875,411.0625 C 203.55468,411.17097 203.12891,411.21877 202.5625,411.21875 L 200.71875,411.21875 L 200.71875,404.46875 z M 235.90625,405.1875 L 235.90625,409.15625 L 233.21875,409.15625 L 235.90625,405.1875 z M 147.34375,405.71875 C 146.80859,405.71876 146.34374,405.78484 145.9375,405.9375 C 145.53125,406.08615 145.21484,406.31253 145,406.59375 C 144.78516,406.87096 144.65624,407.23353 144.5625,407.6875 L 145.59375,407.84375 C 145.70703,407.38978 145.85937,407.08302 146.09375,406.90625 C 146.33203,406.72547 146.72265,406.625 147.21875,406.625 C 147.75,406.62501 148.13671,406.75495 148.40625,407 C 148.60546,407.18079 148.71874,407.46433 148.71875,407.90625 C 148.71875,407.94643 148.6914,408.07011 148.6875,408.21875 C 148.28515,408.36338 147.66405,408.4893 146.8125,408.59375 C 146.39453,408.64598 146.08202,408.69375 145.875,408.75 C 145.59375,408.83035 145.35156,408.93708 145.125,409.09375 C 144.90234,409.25044 144.70312,409.45761 144.5625,409.71875 C 144.42578,409.97587 144.37499,410.2804 144.375,410.59375 C 144.375,411.12808 144.53906,411.56074 144.90625,411.90625 C 145.27344,412.24774 145.8164,412.40624 146.5,412.40625 C 146.91406,412.40625 147.29687,412.32812 147.65625,412.1875 C 148.01953,412.04689 148.39061,411.81024 148.78125,411.46875 C 148.8125,411.77006 148.89061,412.05628 149,412.28125 L 150.09375,412.28125 C 149.96093,412.03618 149.89061,411.76516 149.84375,411.5 C 149.80078,411.23083 149.74999,410.60215 149.75,409.59375 L 149.75,408.125 C 149.74999,407.6429 149.75389,407.30981 149.71875,407.125 C 149.65624,406.82771 149.53124,406.5991 149.375,406.40625 C 149.21874,406.2094 148.98827,406.03482 148.65625,405.90625 C 148.32421,405.7777 147.87499,405.71876 147.34375,405.71875 z M 164.3125,405.71875 C 163.44922,405.71876 162.80078,406.0782 162.34375,406.78125 L 162.34375,405.875 L 161.375,405.875 L 161.375,412.28125 L 162.4375,412.28125 L 162.4375,408.78125 C 162.4375,407.96168 162.61328,407.38704 162.9375,407.09375 C 163.26562,406.80048 163.64453,406.65626 164.09375,406.65625 C 164.375,406.65626 164.63671,406.74242 164.84375,406.875 C 165.05468,407.00357 165.19921,407.15405 165.28125,407.375 C 165.36328,407.59195 165.40624,407.93308 165.40625,408.375 L 165.40625,412.28125 L 166.4375,412.28125 L 166.4375,408.34375 C 166.43749,407.84157 166.41405,407.48213 166.375,407.28125 C 166.31249,406.97191 166.21874,406.69373 166.0625,406.46875 C 165.90624,406.24378 165.66015,406.07409 165.34375,405.9375 C 165.03125,405.79689 164.68749,405.71876 164.3125,405.71875 z M 176.71875,405.71875 C 176.18359,405.71876 175.71874,405.78484 175.3125,405.9375 C 174.90625,406.08615 174.58984,406.31253 174.375,406.59375 C 174.16016,406.87096 174,407.23353 173.90625,407.6875 L 174.9375,407.84375 C 175.05078,407.38978 175.23437,407.08302 175.46875,406.90625 C 175.70703,406.72547 176.0664,406.625 176.5625,406.625 C 177.09375,406.62501 177.51171,406.75495 177.78125,407 C 177.98046,407.18079 178.06249,407.46433 178.0625,407.90625 C 178.0625,407.94643 178.0664,408.07011 178.0625,408.21875 C 177.66015,408.36338 177.03905,408.4893 176.1875,408.59375 C 175.76953,408.64598 175.45702,408.69375 175.25,408.75 C 174.96875,408.83035 174.72656,408.93708 174.5,409.09375 C 174.27734,409.25044 174.07812,409.45761 173.9375,409.71875 C 173.80078,409.97587 173.75,410.2804 173.75,410.59375 C 173.75,411.12808 173.91406,411.56074 174.28125,411.90625 C 174.64844,412.24774 175.1914,412.40624 175.875,412.40625 C 176.28906,412.40625 176.67187,412.32812 177.03125,412.1875 C 177.39453,412.04689 177.76562,411.81024 178.15625,411.46875 C 178.1875,411.77006 178.26562,412.05628 178.375,412.28125 L 179.46875,412.28125 C 179.33593,412.03618 179.23436,411.76516 179.1875,411.5 C 179.14453,411.23083 179.12499,410.60215 179.125,409.59375 L 179.125,408.125 C 179.12499,407.6429 179.1289,407.30981 179.09375,407.125 C 179.03124,406.82771 178.90624,406.5991 178.75,406.40625 C 178.59374,406.2094 178.36327,406.03482 178.03125,405.90625 C 177.69921,405.7777 177.24999,405.71876 176.71875,405.71875 z M 258.8125,405.71875 C 258.27734,405.71876 257.78124,405.78484 257.375,405.9375 C 256.96875,406.08615 256.68358,406.31253 256.46875,406.59375 C 256.25391,406.87096 256.09376,407.23353 256,407.6875 L 257.03125,407.84375 C 257.14453,407.38978 257.32811,407.08302 257.5625,406.90625 C 257.80078,406.72547 258.16015,406.625 258.65625,406.625 C 259.1875,406.62501 259.57421,406.75495 259.84375,407 C 259.91015,407.06026 259.95573,407.12947 260,407.21875 L 260,405.875 C 259.68074,405.76744 259.29843,405.71876 258.8125,405.71875 z M 111.5625,405.875 L 113.6875,408.9375 L 111.40625,412.28125 L 112.6875,412.28125 L 114.3125,409.75 L 114.65625,410.28125 L 115.9375,412.28125 L 117.21875,412.28125 L 114.90625,408.875 L 117.0625,405.875 L 115.8125,405.875 L 114.75,407.375 C 114.60547,407.5799 114.45312,407.82859 114.28125,408.09375 C 114.17187,407.90091 114.02343,407.66024 113.84375,407.375 L 112.875,405.875 L 111.5625,405.875 z M 151.6875,405.875 L 151.6875,407.09375 L 152.90625,407.09375 L 152.90625,405.875 L 151.6875,405.875 z M 167.4375,405.875 L 169.8125,412.28125 L 170.78125,412.28125 L 173.125,405.875 L 172.0625,405.875 L 170.65625,409.78125 C 170.48828,410.25532 170.37499,410.66254 170.28125,411 C 170.16015,410.55406 170.01952,410.10131 169.875,409.6875 L 168.53125,405.875 L 167.4375,405.875 z M 183.4375,405.875 L 183.4375,412.28125 L 184.5,412.28125 L 184.5,405.875 L 183.4375,405.875 z M 127.03125,406.625 C 127.51172,406.62501 127.92187,406.84021 128.25,407.25 C 128.57812,407.65979 128.74999,408.28045 128.75,409.15625 C 128.75,409.95172 128.57421,410.54779 128.25,410.9375 C 127.92968,411.32318 127.55469,411.53126 127.09375,411.53125 C 126.63672,411.53125 126.24219,411.31202 125.90625,410.90625 C 125.57031,410.50048 125.375,409.88208 125.375,409.0625 C 125.375,408.21481 125.53125,407.61246 125.84375,407.21875 C 126.16015,406.82504 126.5625,406.625 127.03125,406.625 z M 134.03125,406.625 C 134.48828,406.62501 134.86718,406.82102 135.1875,407.21875 C 135.51171,407.61649 135.68749,408.22688 135.6875,409.0625 C 135.68749,409.87805 135.52343,410.49244 135.1875,410.90625 C 134.85156,411.31604 134.42968,411.53126 133.96875,411.53125 C 133.40234,411.53125 132.95702,411.24594 132.625,410.6875 C 132.42187,410.34601 132.31249,409.7986 132.3125,409.03125 C 132.3125,408.25186 132.50781,407.65978 132.84375,407.25 C 133.17968,406.8362 133.57031,406.62502 134.03125,406.625 z M 188.46875,406.625 C 188.94922,406.62501 189.35938,406.84021 189.6875,407.25 C 190.01562,407.65979 190.15625,408.28045 190.15625,409.15625 C 190.15625,409.95172 190.01172,410.54779 189.6875,410.9375 C 189.36718,411.32318 188.96094,411.53126 188.5,411.53125 C 188.04297,411.53125 187.64844,411.31202 187.3125,410.90625 C 186.97656,410.50048 186.81251,409.88208 186.8125,409.0625 C 186.8125,408.21481 186.96876,407.61246 187.28125,407.21875 C 187.59765,406.82504 188,406.625 188.46875,406.625 z M 140.625,407.5 C 141.10546,407.5 141.49609,407.67771 141.8125,408.03125 C 142.1289,408.38078 142.31249,408.85809 142.3125,409.46875 C 142.31249,410.10352 142.1328,410.59914 141.8125,410.96875 C 141.49218,411.33836 141.10155,411.53125 140.65625,411.53125 C 140.35156,411.53125 140.08984,411.42678 139.8125,411.25 C 139.53515,411.06921 139.31249,410.81025 139.15625,410.46875 C 139.0039,410.12726 138.90624,409.77988 138.90625,409.40625 C 138.90625,408.83577 139.07421,408.38077 139.40625,408.03125 C 139.73828,407.67771 140.14843,407.5 140.625,407.5 z M 120.5,407.9375 C 121.00781,407.9375 121.44531,408.12726 121.78125,408.46875 C 122.12109,408.81024 122.28124,409.22774 122.28125,409.75 C 122.28124,410.26424 122.10937,410.6978 121.78125,411.03125 C 121.45312,411.3647 121.03515,411.53125 120.53125,411.53125 C 120.20703,411.53125 119.90624,411.43792 119.625,411.28125 C 119.34375,411.12055 119.14453,410.91427 119,410.625 C 118.85937,410.33574 118.78125,410.02811 118.78125,409.71875 C 118.78125,409.21255 118.95703,408.77498 119.28125,408.4375 C 119.60937,408.10003 120.0039,407.9375 120.5,407.9375 z M 260,408.25 C 259.59742,408.37671 259.01717,408.49965 258.25,408.59375 C 257.83203,408.64598 257.51952,408.69375 257.3125,408.75 C 257.03125,408.83035 256.78905,408.93708 256.5625,409.09375 C 256.33984,409.25044 256.17187,409.45761 256.03125,409.71875 C 255.89453,409.97587 255.81251,410.2804 255.8125,410.59375 C 255.8125,411.12808 256.0078,411.56074 256.375,411.90625 C 256.74219,412.24774 257.2539,412.40624 257.9375,412.40625 C 258.35156,412.40625 258.73436,412.32812 259.09375,412.1875 C 259.38856,412.07339 259.68717,411.87141 260,411.625 L 260,410.4375 C 259.98904,410.46683 259.98104,410.50466 259.96875,410.53125 C 259.82031,410.84863 259.59764,411.09644 259.28125,411.28125 C 258.96484,411.46204 258.59374,411.56249 258.1875,411.5625 C 257.77734,411.5625 257.46483,411.4741 257.25,411.28125 C 257.03906,411.08841 256.93749,410.85176 256.9375,410.5625 C 256.9375,410.37368 256.99608,410.18393 257.09375,410.03125 C 257.1914,409.87457 257.3203,409.76784 257.5,409.6875 C 257.67969,409.60715 257.97265,409.53303 258.40625,409.46875 C 259.08643,409.36882 259.62195,409.26299 260,409.125 L 260,408.25 z M 148.6875,409.0625 L 148.6875,409.4375 C 148.6875,409.91558 148.64452,410.28619 148.53125,410.53125 C 148.38281,410.84863 148.16015,411.09644 147.84375,411.28125 C 147.52734,411.46204 147.15624,411.56249 146.75,411.5625 C 146.33984,411.5625 146.02734,411.4741 145.8125,411.28125 C 145.60156,411.08841 145.49999,410.85176 145.5,410.5625 C 145.5,410.37368 145.52734,410.18393 145.625,410.03125 C 145.72265,409.87457 145.8828,409.76784 146.0625,409.6875 C 146.24219,409.60715 146.53515,409.53303 146.96875,409.46875 C 147.73437,409.35626 148.30468,409.2232 148.6875,409.0625 z M 178.0625,409.0625 L 178.0625,409.4375 C 178.0625,409.91558 178.01952,410.28619 177.90625,410.53125 C 177.75781,410.84863 177.5039,411.09644 177.1875,411.28125 C 176.87109,411.46204 176.53124,411.56249 176.125,411.5625 C 175.71484,411.5625 175.40234,411.4741 175.1875,411.28125 C 174.97656,411.08841 174.87499,410.85176 174.875,410.5625 C 174.875,410.37368 174.90234,410.18393 175,410.03125 C 175.09765,409.87457 175.25781,409.76784 175.4375,409.6875 C 175.61719,409.60715 175.91015,409.53303 176.34375,409.46875 C 177.10937,409.35626 177.67968,409.2232 178.0625,409.0625 z M 151.6875,411.03125 L 151.6875,412.28125 L 152.90625,412.28125 L 152.90625,411.03125 L 151.6875,411.03125 z M 229.8125,411.03125 L 229.8125,412.28125 L 231,412.28125 L 231,411.03125 L 229.8125,411.03125 z M 239.8125,411.03125 L 239.8125,412.28125 L 241,412.28125 L 241,411.03125 L 239.8125,411.03125 z M 226.9375,418.71875 C 226.08203,418.71876 225.34374,418.88843 224.6875,419.25 C 224.03125,419.61158 223.5078,420.15901 223.15625,420.90625 C 222.80859,421.64949 222.65624,422.45276 222.65625,423.3125 C 222.65625,424.18028 222.80468,424.98444 223.15625,425.6875 C 223.50781,426.39056 224.03124,426.90764 224.71875,427.28125 C 225.41015,427.65086 226.18749,427.84376 227.03125,427.84375 C 227.65624,427.84375 228.28124,427.72899 228.875,427.5 C 229.46874,427.26699 230.03514,426.92675 230.59375,426.46875 L 230.59375,423.1875 L 226.9375,423.1875 L 226.9375,424.21875 L 229.46875,424.21875 L 229.46875,425.875 C 229.22656,426.09596 228.87499,426.30315 228.40625,426.5 C 227.93749,426.69284 227.46092,426.78124 226.96875,426.78125 C 226.40234,426.78125 225.8789,426.66336 225.375,426.40625 C 224.87109,426.14913 224.48437,425.74906 224.21875,425.21875 C 223.95703,424.68844 223.81249,424.03744 223.8125,423.25 C 223.8125,422.61122 223.93749,422.01514 224.15625,421.46875 C 224.28515,421.15137 224.45702,420.85892 224.6875,420.59375 C 224.92187,420.3286 225.21483,420.12945 225.59375,419.96875 C 225.97265,419.80404 226.41796,419.71874 226.9375,419.71875 C 227.37109,419.71876 227.76952,419.78082 228.125,419.9375 C 228.48046,420.09017 228.77733,420.30537 228.96875,420.5625 C 229.16015,420.81963 229.30858,421.17504 229.4375,421.625 L 230.46875,421.34375 C 230.3203,420.74917 230.09764,420.24462 229.8125,419.875 C 229.52734,419.5054 229.12889,419.23616 228.625,419.03125 C 228.12499,418.82235 227.55858,418.71875 226.9375,418.71875 z M 237.4375,418.71875 C 236.97656,418.71876 236.60156,418.792 236.34375,418.96875 C 236.08984,419.14151 235.91406,419.37504 235.8125,419.65625 C 235.73828,419.86517 235.71875,420.19513 235.71875,420.625 L 235.71875,421.28125 L 234.78125,421.28125 L 234.78125,422.125 L 235.71875,422.125 L 235.71875,427.6875 L 236.75,427.6875 L 236.75,422.125 L 237.96875,422.125 L 237.96875,421.28125 L 236.75,421.28125 L 236.75,420.71875 C 236.75,420.33308 236.80468,420.04688 236.9375,419.90625 C 237.07031,419.76565 237.30468,419.68751 237.625,419.6875 C 237.82031,419.68751 238.03124,419.70983 238.25,419.75 L 238.40625,418.8125 C 238.04687,418.74019 237.73437,418.71875 237.4375,418.71875 z M 107.9375,418.8125 C 107.3125,418.81251 106.78906,418.99825 106.375,419.34375 C 105.96484,419.68926 105.64843,420.17372 105.4375,420.8125 C 105.23047,421.44727 105.125,422.29922 105.125,423.34375 C 105.125,425.00298 105.40234,426.20231 105.96875,426.9375 C 106.4414,427.54816 107.10937,427.84376 107.9375,427.84375 C 108.5664,427.84375 109.08984,427.65801 109.5,427.3125 C 109.91406,426.96298 110.19921,426.4785 110.40625,425.84375 C 110.61328,425.20497 110.71874,424.38028 110.71875,423.34375 C 110.71874,422.46794 110.66015,421.76426 110.53125,421.25 C 110.40234,420.73175 110.22655,420.29507 110,419.9375 C 109.77343,419.57593 109.5039,419.31384 109.15625,419.125 C 108.80859,418.93217 108.39843,418.8125 107.9375,418.8125 z M 120.5,418.8125 C 119.7539,418.81251 119.16796,419.03084 118.71875,419.46875 C 118.26953,419.90667 118.0625,420.45095 118.0625,421.09375 C 118.0625,421.51961 118.16406,421.88217 118.375,422.1875 C 118.58594,422.49284 118.90625,422.74153 119.34375,422.90625 C 118.82031,423.04687 118.41015,423.29782 118.125,423.6875 C 117.84375,424.07318 117.6875,424.55051 117.6875,425.125 C 117.6875,425.89636 117.94922,426.54423 118.46875,427.0625 C 118.98828,427.57674 119.68359,427.84376 120.53125,427.84375 C 121.3789,427.84375 122.07421,427.57673 122.59375,427.0625 C 123.11328,426.54826 123.37499,425.91153 123.375,425.15625 C 123.37499,424.60987 123.21483,424.14372 122.9375,423.75 C 122.66406,423.35629 122.27734,423.08301 121.75,422.90625 C 122.17578,422.74154 122.48046,422.52008 122.6875,422.21875 C 122.89843,421.91343 122.99999,421.53479 123,421.125 C 122.99999,420.48221 122.76952,419.94596 122.3125,419.5 C 121.85546,419.05005 121.24999,418.8125 120.5,418.8125 z M 140.78125,418.8125 C 139.875,418.81251 139.16015,419.16883 138.625,419.84375 C 138.01172,420.61913 137.71875,421.85506 137.71875,423.5625 C 137.71875,425.08915 137.97656,426.17685 138.53125,426.84375 C 139.08594,427.50664 139.80859,427.84376 140.6875,427.84375 C 141.20312,427.84375 141.65624,427.72185 142.0625,427.46875 C 142.46874,427.21565 142.80077,426.84907 143.03125,426.375 C 143.26562,425.89692 143.37499,425.36692 143.375,424.8125 C 143.37499,423.96883 143.12108,423.28031 142.625,422.75 C 142.13281,422.21568 141.54687,421.96874 140.84375,421.96875 C 140.4414,421.96876 140.05468,422.05717 139.6875,422.25 C 139.32031,422.44285 139.0039,422.72727 138.75,423.125 C 138.75781,422.24116 138.87109,421.57184 139.0625,421.09375 C 139.2539,420.61567 139.51171,420.24911 139.84375,420 C 140.09765,419.80717 140.38281,419.71876 140.71875,419.71875 C 141.13671,419.71876 141.49609,419.87816 141.78125,420.1875 C 141.95312,420.38035 142.09374,420.66791 142.1875,421.09375 L 143.21875,421.03125 C 143.13281,420.34427 142.87108,419.79596 142.4375,419.40625 C 142.00781,419.01656 141.45702,418.8125 140.78125,418.8125 z M 128.65625,418.875 L 128.65625,422.03125 C 128.47265,421.77012 128.23047,421.56694 127.9375,421.40625 C 127.64453,421.24154 127.3125,421.15627 126.9375,421.15625 C 126.42578,421.15626 125.97656,421.28529 125.5625,421.5625 C 125.14844,421.83971 124.83203,422.22773 124.625,422.75 C 124.41797,423.26826 124.3125,423.86121 124.3125,424.5 C 124.3125,425.15485 124.42969,425.7438 124.65625,426.25 C 124.88672,426.75219 125.21094,427.12503 125.625,427.40625 C 126.04297,427.68747 126.47266,427.84375 126.96875,427.84375 C 127.73437,427.84375 128.32421,427.50977 128.71875,426.875 L 128.71875,427.6875 L 129.6875,427.6875 L 129.6875,418.875 L 128.65625,418.875 z M 131.375,418.875 L 131.375,427.6875 L 132.34375,427.6875 L 132.34375,426.90625 C 132.76172,427.537 133.32812,427.84375 134.0625,427.84375 C 134.80078,427.84375 135.4414,427.53611 135.96875,426.9375 C 136.49609,426.33889 136.74999,425.50302 136.75,424.40625 C 136.74999,423.94424 136.68749,423.49951 136.5625,423.09375 C 136.43749,422.68799 136.28515,422.34775 136.0625,422.0625 C 135.84374,421.77325 135.56249,421.53169 135.21875,421.375 C 134.8789,421.21431 134.5078,421.15627 134.125,421.15625 C 133.43359,421.15626 132.85156,421.42551 132.40625,422 L 132.40625,418.875 L 131.375,418.875 z M 158.1875,418.875 L 158.1875,427.6875 L 159.28125,427.6875 L 159.28125,420.75 L 163.78125,427.6875 L 164.9375,427.6875 L 164.9375,418.875 L 163.875,418.875 L 163.875,425.78125 L 159.34375,418.875 L 158.1875,418.875 z M 196.84375,418.875 L 196.84375,427.6875 L 197.9375,427.6875 L 197.9375,420.1875 L 200.4375,427.6875 L 201.46875,427.6875 L 203.96875,420.3125 L 203.96875,427.6875 L 205.0625,427.6875 L 205.0625,418.875 L 203.53125,418.875 L 201.46875,425 C 201.26171,425.62271 201.09765,426.1161 201,426.4375 C 200.91406,426.14824 200.78124,425.70755 200.59375,425.125 L 198.5625,418.875 L 196.84375,418.875 z M 206.90625,418.875 L 206.90625,427.6875 L 208.03125,427.6875 L 208.03125,424.09375 L 210.25,424.09375 C 211.46484,424.09375 212.28515,423.83077 212.75,423.3125 C 213.21484,422.79023 213.46874,422.15753 213.46875,421.40625 C 213.46874,420.96835 213.36327,420.58436 213.1875,420.21875 C 213.01562,419.85317 212.78514,419.5759 212.5,419.375 C 212.21484,419.17012 211.85936,419.00983 211.4375,418.9375 C 211.13671,418.88126 210.6953,418.875 210.125,418.875 L 206.90625,418.875 z M 214.9375,418.875 L 214.9375,427.6875 L 221.34375,427.6875 L 221.34375,426.65625 L 216.0625,426.65625 L 216.0625,423.65625 L 220.8125,423.65625 L 220.8125,422.59375 L 216.0625,422.59375 L 216.0625,419.90625 L 221.15625,419.90625 L 221.15625,418.875 L 214.9375,418.875 z M 174.65625,419.0625 L 173.59375,419.71875 L 173.59375,421.28125 L 172.84375,421.28125 L 172.84375,422.125 L 173.59375,422.125 L 173.59375,425.8125 C 173.59375,426.46334 173.66405,426.88885 173.75,427.09375 C 173.83594,427.29463 173.97655,427.4692 174.1875,427.59375 C 174.39844,427.71829 174.67968,427.78126 175.0625,427.78125 C 175.29687,427.78125 175.57812,427.75177 175.875,427.6875 L 175.71875,426.71875 C 175.52734,426.74687 175.36718,426.78124 175.25,426.78125 C 175.09375,426.78125 174.96093,426.73972 174.875,426.6875 C 174.79297,426.63527 174.7578,426.55714 174.71875,426.46875 C 174.68359,426.38037 174.65624,426.18434 174.65625,425.875 L 174.65625,422.125 L 175.71875,422.125 L 175.71875,421.28125 L 174.65625,421.28125 L 174.65625,419.0625 z M 107.90625,419.71875 C 108.39843,419.71876 108.82812,419.95943 109.15625,420.4375 C 109.48828,420.91559 109.65624,421.88943 109.65625,423.34375 C 109.65624,424.79005 109.48827,425.73665 109.15625,426.21875 C 108.82812,426.70085 108.42187,426.93751 107.9375,426.9375 C 107.45312,426.9375 107.05078,426.7281 106.71875,426.25 C 106.39062,425.7679 106.21875,424.79408 106.21875,423.34375 C 106.21875,421.89344 106.38671,420.88209 106.75,420.34375 C 107.03906,419.92192 107.42187,419.71877 107.90625,419.71875 z M 120.53125,419.71875 C 120.92968,419.71876 121.26562,419.85181 121.53125,420.125 C 121.80078,420.39418 121.93749,420.72726 121.9375,421.125 C 121.9375,421.50667 121.79296,421.8286 121.53125,422.09375 C 121.27343,422.35489 120.93749,422.50002 120.53125,422.5 C 120.11328,422.50001 119.79296,422.35892 119.53125,422.09375 C 119.26953,421.8286 119.125,421.48032 119.125,421.0625 C 119.125,420.6929 119.26562,420.39016 119.53125,420.125 C 119.79687,419.85985 120.1289,419.71876 120.53125,419.71875 z M 208.03125,419.90625 L 210.21875,419.90625 C 210.73437,419.90626 211.08983,419.91652 211.28125,419.96875 C 211.57812,420.05313 211.8203,420.23486 212,420.5 C 212.18359,420.76114 212.28124,421.06789 212.28125,421.4375 C 212.28124,421.94773 212.12108,422.34378 211.8125,422.625 C 211.5039,422.90623 210.98437,423.0625 210.25,423.0625 L 208.03125,423.0625 L 208.03125,419.90625 z M 147.34375,421.15625 C 146.80859,421.15626 146.34374,421.22235 145.9375,421.375 C 145.53125,421.52365 145.21484,421.75004 145,422.03125 C 144.78516,422.30846 144.65624,422.67104 144.5625,423.125 L 145.59375,423.25 C 145.70703,422.79603 145.85937,422.48928 146.09375,422.3125 C 146.33203,422.13172 146.72265,422.06251 147.21875,422.0625 C 147.75,422.06251 148.13671,422.16118 148.40625,422.40625 C 148.60546,422.58704 148.71874,422.90184 148.71875,423.34375 C 148.71875,423.38393 148.6914,423.47636 148.6875,423.625 C 148.28515,423.76963 147.66405,423.89556 146.8125,424 C 146.39453,424.05223 146.08202,424.10001 145.875,424.15625 C 145.59375,424.2366 145.35156,424.37456 145.125,424.53125 C 144.90234,424.68794 144.70312,424.89512 144.5625,425.15625 C 144.42578,425.41337 144.37499,425.68663 144.375,426 C 144.375,426.53433 144.53906,426.967 144.90625,427.3125 C 145.27344,427.65399 145.8164,427.84375 146.5,427.84375 C 146.91406,427.84375 147.29687,427.7656 147.65625,427.625 C 148.01953,427.48439 148.39061,427.24775 148.78125,426.90625 C 148.8125,427.20756 148.89061,427.46251 149,427.6875 L 150.09375,427.6875 C 149.96093,427.44243 149.89061,427.20266 149.84375,426.9375 C 149.80078,426.66833 149.74999,426.00841 149.75,425 L 149.75,423.5625 C 149.74999,423.0804 149.75389,422.74732 149.71875,422.5625 C 149.65624,422.26521 149.53124,422.0366 149.375,421.84375 C 149.21874,421.6469 148.98827,421.47233 148.65625,421.34375 C 148.32421,421.2152 147.87499,421.15627 147.34375,421.15625 z M 169.25,421.15625 C 168.48047,421.15626 167.84765,421.40093 167.3125,421.875 C 166.67187,422.44549 166.34374,423.31485 166.34375,424.5 C 166.34375,425.58071 166.62109,426.39425 167.15625,426.96875 C 167.69531,427.54325 168.3789,427.84375 169.25,427.84375 C 169.79296,427.84375 170.29296,427.69862 170.75,427.4375 C 171.21093,427.17636 171.57421,426.81381 171.8125,426.34375 C 172.05468,425.86969 172.15624,425.22984 172.15625,424.40625 C 172.15624,423.38983 171.88671,422.60575 171.34375,422.03125 C 170.80078,421.45274 170.10546,421.15627 169.25,421.15625 z M 182.6875,421.15625 C 182.15234,421.15626 181.6875,421.22235 181.28125,421.375 C 180.875,421.52365 180.5586,421.75004 180.34375,422.03125 C 180.12891,422.30846 180.00001,422.67104 179.90625,423.125 L 180.9375,423.25 C 181.05078,422.79603 181.20313,422.48928 181.4375,422.3125 C 181.67578,422.13172 182.06641,422.06251 182.5625,422.0625 C 183.09375,422.06251 183.48047,422.16118 183.75,422.40625 C 183.94921,422.58704 184.0625,422.90184 184.0625,423.34375 C 184.0625,423.38393 184.03516,423.47636 184.03125,423.625 C 183.6289,423.76963 183.00782,423.89556 182.15625,424 C 181.73828,424.05223 181.42579,424.10001 181.21875,424.15625 C 180.9375,424.2366 180.69532,424.37456 180.46875,424.53125 C 180.24609,424.68794 180.04688,424.89512 179.90625,425.15625 C 179.76953,425.41337 179.71876,425.68663 179.71875,426 C 179.71875,426.53433 179.88282,426.967 180.25,427.3125 C 180.61719,427.65399 181.16016,427.84375 181.84375,427.84375 C 182.25781,427.84375 182.64063,427.7656 183,427.625 C 183.36328,427.48439 183.73438,427.24775 184.125,426.90625 C 184.15625,427.20756 184.23438,427.46251 184.34375,427.6875 L 185.4375,427.6875 C 185.30468,427.44243 185.23438,427.20266 185.1875,426.9375 C 185.14453,426.66833 185.09375,426.00841 185.09375,425 L 185.09375,423.5625 C 185.09374,423.0804 185.09766,422.74732 185.0625,422.5625 C 184.99999,422.26521 184.875,422.0366 184.71875,421.84375 C 184.56249,421.6469 184.33203,421.47233 184,421.34375 C 183.66796,421.2152 183.21875,421.15627 182.6875,421.15625 z M 189.6875,421.15625 C 188.82422,421.15626 188.14452,421.5157 187.6875,422.21875 L 187.6875,421.28125 L 186.75,421.28125 L 186.75,427.6875 L 187.8125,427.6875 L 187.8125,424.1875 C 187.8125,423.36793 187.95702,422.82452 188.28125,422.53125 C 188.60937,422.23798 189.01952,422.09377 189.46875,422.09375 C 189.75,422.09376 189.98046,422.14867 190.1875,422.28125 C 190.39843,422.40982 190.54296,422.59153 190.625,422.8125 C 190.70703,423.02945 190.74999,423.37059 190.75,423.8125 L 190.75,427.6875 L 191.8125,427.6875 L 191.8125,423.75 C 191.81249,423.24782 191.78905,422.91964 191.75,422.71875 C 191.68749,422.40941 191.56249,422.13123 191.40625,421.90625 C 191.24999,421.68128 191.03514,421.51159 190.71875,421.375 C 190.40625,421.23439 190.06249,421.15627 189.6875,421.15625 z M 241.0625,421.15625 C 240.8164,421.15626 240.58203,421.23038 240.375,421.375 C 240.17187,421.51964 239.96093,421.79603 239.71875,422.25 L 239.71875,421.28125 L 238.78125,421.28125 L 238.78125,427.6875 L 239.8125,427.6875 L 239.8125,424.34375 C 239.8125,423.88576 239.88281,423.44819 240,423.0625 C 240.07812,422.8094 240.22265,422.64063 240.40625,422.5 C 240.58984,422.35538 240.76953,422.28127 241,422.28125 C 241.25781,422.28126 241.52343,422.34331 241.78125,422.5 L 242.15625,421.5 C 241.78906,421.26699 241.41796,421.15627 241.0625,421.15625 z M 245.40625,421.15625 C 244.87109,421.15626 244.40625,421.22235 244,421.375 C 243.59375,421.52365 243.27734,421.75004 243.0625,422.03125 C 242.84766,422.30846 242.71875,422.67104 242.625,423.125 L 243.65625,423.25 C 243.76953,422.79603 243.92187,422.48928 244.15625,422.3125 C 244.39453,422.13172 244.78515,422.06251 245.28125,422.0625 C 245.8125,422.06251 246.19921,422.16118 246.46875,422.40625 C 246.66796,422.58704 246.78124,422.90184 246.78125,423.34375 C 246.78125,423.38393 246.7539,423.47636 246.75,423.625 C 246.34765,423.76963 245.72656,423.89556 244.875,424 C 244.45703,424.05223 244.14453,424.10001 243.9375,424.15625 C 243.65625,424.2366 243.41406,424.37456 243.1875,424.53125 C 242.96484,424.68794 242.76562,424.89512 242.625,425.15625 C 242.48828,425.41337 242.4375,425.68663 242.4375,426 C 242.4375,426.53433 242.60156,426.967 242.96875,427.3125 C 243.33594,427.65399 243.8789,427.84375 244.5625,427.84375 C 244.97656,427.84375 245.35937,427.7656 245.71875,427.625 C 246.08203,427.48439 246.45312,427.24775 246.84375,426.90625 C 246.875,427.20756 246.95312,427.46251 247.0625,427.6875 L 248.15625,427.6875 C 248.02343,427.44243 247.95312,427.20266 247.90625,426.9375 C 247.86328,426.66833 247.81249,426.00841 247.8125,425 L 247.8125,423.5625 C 247.81249,423.0804 247.8164,422.74732 247.78125,422.5625 C 247.71874,422.26521 247.59374,422.0366 247.4375,421.84375 C 247.28124,421.6469 247.05077,421.47233 246.71875,421.34375 C 246.38671,421.2152 245.93749,421.15627 245.40625,421.15625 z M 252.3125,421.15625 C 251.89843,421.15626 251.51172,421.24466 251.1875,421.4375 C 250.86328,421.62633 250.60156,421.87415 250.40625,422.1875 L 250.40625,421.28125 L 249.46875,421.28125 L 249.46875,427.6875 L 250.53125,427.6875 L 250.53125,424.375 C 250.53125,423.79247 250.57422,423.3406 250.6875,423.03125 C 250.80078,422.72191 251,422.50446 251.25,422.34375 C 251.5039,422.18306 251.76562,422.09377 252.0625,422.09375 C 252.45312,422.09376 252.73437,422.19644 252.90625,422.4375 C 253.07812,422.67855 253.15625,423.04915 253.15625,423.53125 L 253.15625,427.6875 L 254.21875,427.6875 L 254.21875,423.96875 C 254.21874,423.30988 254.36718,422.82854 254.65625,422.53125 C 254.94531,422.22994 255.31249,422.09377 255.75,422.09375 C 255.99218,422.09376 256.19529,422.1335 256.375,422.25 C 256.55468,422.36651 256.68357,422.52592 256.75,422.71875 C 256.8203,422.90758 256.84373,423.22235 256.84375,423.65625 L 256.84375,427.6875 L 257.90625,427.6875 L 257.90625,423.3125 C 257.90624,422.58132 257.73826,422.03702 257.40625,421.6875 C 257.07421,421.33397 256.58593,421.15627 255.96875,421.15625 C 255.17968,421.15626 254.55468,421.53402 254.0625,422.28125 C 253.9414,421.92772 253.73437,421.63437 253.4375,421.4375 C 253.14453,421.24065 252.77343,421.15627 252.3125,421.15625 z M 111.5625,421.28125 L 113.6875,424.375 L 111.40625,427.6875 L 112.6875,427.6875 L 114.3125,425.15625 L 114.65625,425.71875 L 115.9375,427.6875 L 117.21875,427.6875 L 114.90625,424.3125 L 117.0625,421.28125 L 115.8125,421.28125 L 114.75,422.8125 C 114.60547,423.0174 114.45312,423.23485 114.28125,423.5 C 114.17187,423.30716 114.02343,423.0665 113.84375,422.78125 L 112.875,421.28125 L 111.5625,421.28125 z M 151.6875,421.28125 L 151.6875,422.53125 L 152.90625,422.53125 L 152.90625,421.28125 L 151.6875,421.28125 z M 260,422 C 259.98958,422.01115 259.97906,422.01988 259.96875,422.03125 C 259.42969,422.62584 259.15624,423.48583 259.15625,424.5625 C 259.15625,425.60303 259.40624,426.39023 259.9375,426.96875 C 259.95796,426.99072 259.97899,427.01012 260,427.03125 L 260,422 z M 134.03125,422.03125 C 134.48828,422.03126 134.86718,422.22727 135.1875,422.625 C 135.51171,423.02274 135.68749,423.66436 135.6875,424.5 C 135.68749,425.31555 135.52343,425.92995 135.1875,426.34375 C 134.85156,426.75354 134.42968,426.93749 133.96875,426.9375 C 133.40234,426.9375 132.95702,426.65217 132.625,426.09375 C 132.42187,425.75226 132.31249,425.20486 132.3125,424.4375 C 132.3125,423.65811 132.50781,423.06604 132.84375,422.65625 C 133.17968,422.24245 133.57031,422.03125 134.03125,422.03125 z M 127.03125,422.0625 C 127.51172,422.06251 127.92187,422.24647 128.25,422.65625 C 128.57812,423.06604 128.74999,423.71793 128.75,424.59375 C 128.75,425.38922 128.57421,425.9853 128.25,426.375 C 127.92968,426.76068 127.55469,426.93749 127.09375,426.9375 C 126.63672,426.9375 126.24219,426.74953 125.90625,426.34375 C 125.57031,425.93798 125.375,425.31956 125.375,424.5 C 125.375,423.65231 125.53125,423.01872 125.84375,422.625 C 126.16015,422.23129 126.5625,422.06251 127.03125,422.0625 z M 169.25,422.0625 C 169.76953,422.06251 170.21483,422.24647 170.5625,422.65625 C 170.91406,423.06202 171.09374,423.67732 171.09375,424.46875 C 171.09374,425.30841 170.91015,425.93397 170.5625,426.34375 C 170.21484,426.75354 169.77343,426.93749 169.25,426.9375 C 168.72265,426.9375 168.28515,426.74953 167.9375,426.34375 C 167.58984,425.93397 167.43749,425.31958 167.4375,424.5 C 167.4375,423.68043 167.58984,423.06204 167.9375,422.65625 C 168.28515,422.25049 168.72265,422.06251 169.25,422.0625 z M 140.625,422.90625 C 141.10546,422.90625 141.49609,423.08397 141.8125,423.4375 C 142.1289,423.78703 142.31249,424.2956 142.3125,424.90625 C 142.31249,425.54102 142.1328,426.03665 141.8125,426.40625 C 141.49218,426.77586 141.10155,426.93751 140.65625,426.9375 C 140.35156,426.9375 140.08984,426.86426 139.8125,426.6875 C 139.53515,426.50671 139.31249,426.24773 139.15625,425.90625 C 139.0039,425.56476 138.90624,425.21739 138.90625,424.84375 C 138.90625,424.27327 139.07421,423.78703 139.40625,423.4375 C 139.73828,423.08396 140.14843,422.90626 140.625,422.90625 z M 120.5,423.375 C 121.00781,423.375 121.44531,423.53351 121.78125,423.875 C 122.12109,424.21649 122.28124,424.66521 122.28125,425.1875 C 122.28124,425.70174 122.10937,426.10406 121.78125,426.4375 C 121.45312,426.77095 121.03515,426.93751 120.53125,426.9375 C 120.20703,426.9375 119.90624,426.87543 119.625,426.71875 C 119.34375,426.55805 119.14453,426.32053 119,426.03125 C 118.85937,425.74199 118.78125,425.46559 118.78125,425.15625 C 118.78125,424.65005 118.95703,424.21249 119.28125,423.875 C 119.60937,423.53753 120.0039,423.37501 120.5,423.375 z M 148.6875,424.46875 L 148.6875,424.875 C 148.6875,425.35308 148.64452,425.7237 148.53125,425.96875 C 148.38281,426.28613 148.16015,426.53394 147.84375,426.71875 C 147.52734,426.89954 147.15624,427 146.75,427 C 146.33984,427 146.02734,426.88033 145.8125,426.6875 C 145.60156,426.49466 145.49999,426.25802 145.5,425.96875 C 145.5,425.77993 145.52734,425.6214 145.625,425.46875 C 145.72265,425.31207 145.8828,425.1741 146.0625,425.09375 C 146.24219,425.0134 146.53515,424.97054 146.96875,424.90625 C 147.73437,424.79376 148.30468,424.62946 148.6875,424.46875 z M 184.03125,424.46875 L 184.03125,424.875 C 184.03125,425.35308 183.98828,425.7237 183.875,425.96875 C 183.72656,426.28613 183.50391,426.53394 183.1875,426.71875 C 182.87109,426.89954 182.5,427 182.09375,427 C 181.68359,427 181.3711,426.88033 181.15625,426.6875 C 180.94531,426.49466 180.84375,426.25802 180.84375,425.96875 C 180.84375,425.77993 180.8711,425.6214 180.96875,425.46875 C 181.0664,425.31207 181.22657,425.1741 181.40625,425.09375 C 181.58594,425.0134 181.87891,424.97054 182.3125,424.90625 C 183.07812,424.79376 183.64844,424.62946 184.03125,424.46875 z M 246.75,424.46875 L 246.75,424.875 C 246.75,425.35308 246.70702,425.7237 246.59375,425.96875 C 246.44531,426.28613 246.22265,426.53394 245.90625,426.71875 C 245.58984,426.89954 245.21875,427 244.8125,427 C 244.40234,427 244.08984,426.88033 243.875,426.6875 C 243.66406,426.49466 243.5625,426.25802 243.5625,425.96875 C 243.5625,425.77993 243.58984,425.6214 243.6875,425.46875 C 243.78515,425.31207 243.94531,425.1741 244.125,425.09375 C 244.30469,425.0134 244.59765,424.97054 245.03125,424.90625 C 245.79687,424.79376 246.36718,424.62946 246.75,424.46875 z M 151.6875,426.46875 L 151.6875,427.6875 L 152.90625,427.6875 L 152.90625,426.46875 L 151.6875,426.46875 z M 107.9375,434.25 C 107.3125,434.25001 106.78906,434.43576 106.375,434.78125 C 105.96484,435.12676 105.64843,435.61122 105.4375,436.25 C 105.23047,436.88477 105.125,437.70544 105.125,438.75 C 105.125,440.40923 105.40234,441.60854 105.96875,442.34375 C 106.4414,442.95441 107.10937,443.28124 107.9375,443.28125 C 108.5664,443.28125 109.08984,443.09552 109.5,442.75 C 109.91406,442.40048 110.19921,441.91601 110.40625,441.28125 C 110.61328,440.64247 110.71874,439.78651 110.71875,438.75 C 110.71874,437.87419 110.66015,437.20173 110.53125,436.6875 C 110.40234,436.16925 110.22655,435.73255 110,435.375 C 109.77343,435.01343 109.5039,434.7201 109.15625,434.53125 C 108.80859,434.33842 108.39843,434.25001 107.9375,434.25 z M 120.5,434.25 C 119.7539,434.25001 119.16796,434.46835 118.71875,434.90625 C 118.26953,435.34417 118.0625,435.88846 118.0625,436.53125 C 118.0625,436.95711 118.16406,437.31968 118.375,437.625 C 118.58594,437.93034 118.90625,438.17903 119.34375,438.34375 C 118.82031,438.48437 118.41015,438.7353 118.125,439.125 C 117.84375,439.51068 117.6875,439.98799 117.6875,440.5625 C 117.6875,441.33386 117.94922,441.98174 118.46875,442.5 C 118.98828,443.01424 119.68359,443.28124 120.53125,443.28125 C 121.3789,443.28125 122.07421,443.01423 122.59375,442.5 C 123.11328,441.98576 123.37499,441.34904 123.375,440.59375 C 123.37499,440.04737 123.21483,439.58123 122.9375,439.1875 C 122.66406,438.79379 122.27734,438.52052 121.75,438.34375 C 122.17578,438.17904 122.48046,437.92631 122.6875,437.625 C 122.89843,437.31968 122.99999,436.9723 123,436.5625 C 122.99999,435.91971 122.76952,435.38346 122.3125,434.9375 C 121.85546,434.48755 121.24999,434.25001 120.5,434.25 z M 128.65625,434.28125 L 128.65625,437.46875 C 128.47265,437.20762 128.23047,436.9732 127.9375,436.8125 C 127.64453,436.64779 127.3125,436.5625 126.9375,436.5625 C 126.42578,436.56251 125.97656,436.7228 125.5625,437 C 125.14844,437.27721 124.83203,437.66523 124.625,438.1875 C 124.41797,438.70576 124.3125,439.29872 124.3125,439.9375 C 124.3125,440.59235 124.42969,441.15005 124.65625,441.65625 C 124.88672,442.15844 125.21094,442.56254 125.625,442.84375 C 126.04297,443.12497 126.47266,443.28126 126.96875,443.28125 C 127.73437,443.28125 128.32421,442.94727 128.71875,442.3125 L 128.71875,443.125 L 129.6875,443.125 L 129.6875,434.28125 L 128.65625,434.28125 z M 140.65625,434.28125 L 136.71875,440 L 136.71875,441 L 140.46875,441 L 140.46875,443.125 L 141.5,443.125 L 141.5,441 L 142.65625,441 L 142.65625,440 L 141.5,440 L 141.5,434.28125 L 140.65625,434.28125 z M 148,434.28125 L 148,437.46875 C 147.8164,437.20762 147.60546,436.9732 147.3125,436.8125 C 147.01953,436.64779 146.65624,436.5625 146.28125,436.5625 C 145.76953,436.56251 145.32031,436.7228 144.90625,437 C 144.49219,437.27721 144.17578,437.66523 143.96875,438.1875 C 143.76172,438.70576 143.65625,439.29872 143.65625,439.9375 C 143.65625,440.59235 143.77343,441.15005 144,441.65625 C 144.23047,442.15844 144.55468,442.56254 144.96875,442.84375 C 145.38672,443.12497 145.84765,443.28126 146.34375,443.28125 C 147.10937,443.28125 147.69921,442.94727 148.09375,442.3125 L 148.09375,443.125 L 149.0625,443.125 L 149.0625,434.28125 L 148,434.28125 z M 157.5,434.28125 L 157.5,443.125 L 158.59375,443.125 L 158.59375,436.1875 L 163.09375,443.125 L 164.28125,443.125 L 164.28125,434.28125 L 163.1875,434.28125 L 163.1875,441.21875 L 158.6875,434.28125 L 157.5,434.28125 z M 189.0625,434.28125 L 191.96875,438.53125 L 188.65625,443.125 L 190.03125,443.125 L 192.1875,440.03125 C 192.26953,439.91073 192.40234,439.69641 192.59375,439.375 C 192.72265,439.58793 192.84765,439.78797 192.96875,439.96875 L 195.125,443.125 L 196.53125,443.125 L 193.28125,438.4375 L 196.3125,434.28125 L 195.0625,434.28125 L 193.34375,436.625 C 193.08203,436.97453 192.84765,437.30361 192.65625,437.625 C 192.51953,437.3719 192.29296,437.03255 191.96875,436.5625 L 190.40625,434.28125 L 189.0625,434.28125 z M 197.375,434.28125 L 197.375,435.53125 L 198.4375,435.53125 L 198.4375,434.28125 L 197.375,434.28125 z M 173.96875,434.5 L 172.9375,435.125 L 172.9375,436.71875 L 172.15625,436.71875 L 172.15625,437.5625 L 172.9375,437.5625 L 172.9375,441.25 C 172.9375,441.90084 172.97657,442.32636 173.0625,442.53125 C 173.14844,442.73213 173.28907,442.90671 173.5,443.03125 C 173.71094,443.15579 174.02344,443.21874 174.40625,443.21875 C 174.64062,443.21875 174.89063,443.15803 175.1875,443.09375 L 175.03125,442.15625 C 174.83984,442.18437 174.67969,442.1875 174.5625,442.1875 C 174.40625,442.1875 174.30469,442.17722 174.21875,442.125 C 174.13672,442.07277 174.07032,441.99465 174.03125,441.90625 C 173.99609,441.81787 173.96875,441.62185 173.96875,441.3125 L 173.96875,437.5625 L 175.03125,437.5625 L 175.03125,436.71875 L 173.96875,436.71875 L 173.96875,434.5 z M 223.96875,434.5 L 222.90625,435.125 L 222.90625,436.71875 L 222.15625,436.71875 L 222.15625,437.5625 L 222.90625,437.5625 L 222.90625,441.25 C 222.90625,441.90084 222.97656,442.32636 223.0625,442.53125 C 223.14844,442.73213 223.28906,442.90671 223.5,443.03125 C 223.71094,443.15579 223.99218,443.21874 224.375,443.21875 C 224.60937,443.21875 224.89062,443.15803 225.1875,443.09375 L 225.03125,442.15625 C 224.83984,442.18437 224.67968,442.1875 224.5625,442.1875 C 224.40625,442.1875 224.27343,442.17722 224.1875,442.125 C 224.10547,442.07277 224.07031,441.99465 224.03125,441.90625 C 223.99609,441.81787 223.96874,441.62185 223.96875,441.3125 L 223.96875,437.5625 L 225.03125,437.5625 L 225.03125,436.71875 L 223.96875,436.71875 L 223.96875,434.5 z M 107.90625,435.15625 C 108.39843,435.15626 108.82812,435.39694 109.15625,435.875 C 109.48828,436.35309 109.65624,437.29566 109.65625,438.75 C 109.65624,440.1963 109.48827,441.17416 109.15625,441.65625 C 108.82812,442.13835 108.42187,442.37501 107.9375,442.375 C 107.45312,442.375 107.05078,442.13433 106.71875,441.65625 C 106.39062,441.17415 106.21875,440.20031 106.21875,438.75 C 106.21875,437.29969 106.38671,436.3196 106.75,435.78125 C 107.03906,435.35942 107.42187,435.15625 107.90625,435.15625 z M 120.25,435.15625 C 120.34204,435.13968 120.43066,435.15625 120.53125,435.15625 C 120.92968,435.15626 121.26562,435.28932 121.53125,435.5625 C 121.80078,435.83168 121.93749,436.16477 121.9375,436.5625 C 121.9375,436.94417 121.79296,437.26611 121.53125,437.53125 C 121.27343,437.79239 120.93749,437.90624 120.53125,437.90625 C 120.11328,437.90626 119.79296,437.7964 119.53125,437.53125 C 119.26953,437.2661 119.125,436.91783 119.125,436.5 C 119.125,436.1304 119.26562,435.79642 119.53125,435.53125 C 119.73047,435.33239 119.97388,435.20597 120.25,435.15625 z M 140.46875,436.03125 L 140.46875,440 L 137.75,440 L 140.46875,436.03125 z M 133.875,436.5625 C 133.33984,436.56251 132.86327,436.70762 132.40625,436.96875 C 131.95312,437.22588 131.59765,437.60676 131.375,438.125 C 131.15234,438.64326 131.03125,439.2465 131.03125,439.9375 C 131.03125,441.00616 131.29687,441.83174 131.8125,442.40625 C 132.33203,442.97673 133.02343,443.28126 133.875,443.28125 C 134.55468,443.28125 135.1289,443.07005 135.59375,442.65625 C 136.06249,442.23843 136.35546,441.64144 136.46875,440.90625 L 135.4375,440.78125 C 135.36328,441.32361 135.18358,441.7076 134.90625,441.96875 C 134.6289,442.22989 134.28905,442.375 133.875,442.375 C 133.35937,442.375 132.91406,442.17093 132.59375,441.78125 C 132.27344,441.39155 132.12499,440.766 132.125,439.90625 C 132.125,439.05856 132.29296,438.4522 132.625,438.0625 C 132.95703,437.66879 133.37499,437.46875 133.90625,437.46875 C 134.25781,437.46876 134.5664,437.56432 134.8125,437.78125 C 135.0625,437.9982 135.24608,438.32012 135.34375,438.75 L 136.375,438.59375 C 136.2539,437.94694 135.96093,437.44327 135.53125,437.09375 C 135.10156,436.74022 134.55077,436.5625 133.875,436.5625 z M 168.59375,436.5625 C 167.82422,436.56251 167.16015,436.80719 166.625,437.28125 C 165.98437,437.85174 165.65625,438.72111 165.65625,439.90625 C 165.65625,440.98696 165.93359,441.83176 166.46875,442.40625 C 167.00781,442.98075 167.72265,443.28126 168.59375,443.28125 C 169.13671,443.28125 169.63671,443.13613 170.09375,442.875 C 170.55468,442.61386 170.88671,442.25129 171.125,441.78125 C 171.36718,441.30719 171.49999,440.66735 171.5,439.84375 C 171.49999,438.82733 171.23046,438.01201 170.6875,437.4375 C 170.14453,436.85899 169.44921,436.5625 168.59375,436.5625 z M 182.03125,436.5625 C 181.49609,436.56251 180.99999,436.65986 180.59375,436.8125 C 180.1875,436.96115 179.90234,437.15627 179.6875,437.4375 C 179.47266,437.71471 179.3125,438.10852 179.21875,438.5625 L 180.25,438.6875 C 180.36328,438.23353 180.54687,437.92679 180.78125,437.75 C 181.01953,437.56922 181.3789,437.46877 181.875,437.46875 C 182.40625,437.46876 182.79296,437.59869 183.0625,437.84375 C 183.26171,438.02454 183.37499,438.33932 183.375,438.78125 C 183.375,438.82143 183.3789,438.91384 183.375,439.0625 C 182.97265,439.20713 182.32031,439.33304 181.46875,439.4375 C 181.05078,439.48973 180.73828,439.53751 180.53125,439.59375 C 180.25,439.6741 180.00781,439.78081 179.78125,439.9375 C 179.55859,440.09419 179.39062,440.30138 179.25,440.5625 C 179.11328,440.81962 179.03125,441.12414 179.03125,441.4375 C 179.03125,441.97183 179.22656,442.40451 179.59375,442.75 C 179.96094,443.09149 180.47265,443.28126 181.15625,443.28125 C 181.57031,443.28125 181.95312,443.20311 182.3125,443.0625 C 182.67578,442.92189 183.04687,442.68523 183.4375,442.34375 C 183.46875,442.64506 183.54687,442.90002 183.65625,443.125 L 184.75,443.125 C 184.61718,442.87993 184.54687,442.60889 184.5,442.34375 C 184.45703,442.07458 184.43749,441.44589 184.4375,440.4375 L 184.4375,439 C 184.43749,438.5179 184.41015,438.1848 184.375,438 C 184.31249,437.70271 184.21874,437.44283 184.0625,437.25 C 183.90624,437.05315 183.64452,436.90981 183.3125,436.78125 C 182.98046,436.6527 182.56249,436.5625 182.03125,436.5625 z M 202.96875,436.5625 C 202.10547,436.56251 201.45702,436.92193 201,437.625 L 201,436.71875 L 200.03125,436.71875 L 200.03125,443.125 L 201.09375,443.125 L 201.09375,439.625 C 201.09375,438.80543 201.26952,438.26203 201.59375,437.96875 C 201.92187,437.67548 202.30079,437.53125 202.75,437.53125 C 203.03125,437.53126 203.26172,437.58618 203.46875,437.71875 C 203.67968,437.84732 203.82422,438.02904 203.90625,438.25 C 203.98828,438.46695 204.03125,438.77682 204.03125,439.21875 L 204.03125,443.125 L 205.09375,443.125 L 205.09375,439.1875 C 205.09374,438.68532 205.07031,438.32589 205.03125,438.125 C 204.96874,437.81566 204.875,437.56874 204.71875,437.34375 C 204.56249,437.11878 204.31641,436.91785 204,436.78125 C 203.6875,436.64064 203.34375,436.5625 202.96875,436.5625 z M 209,436.5625 C 208.44922,436.56251 207.97265,436.7188 207.5625,437 C 207.15625,437.28123 206.83984,437.66924 206.625,438.1875 C 206.41016,438.70174 206.31249,439.26433 206.3125,439.875 C 206.3125,440.76287 206.56249,441.52149 207.03125,442.15625 C 207.5,442.79102 208.14452,443.125 209,443.125 C 209.6875,443.125 210.2578,442.83968 210.71875,442.28125 C 210.72265,442.98833 210.71093,443.46654 210.65625,443.6875 C 210.5625,444.04907 210.39061,444.33036 210.125,444.53125 C 209.85937,444.73212 209.45702,444.8125 208.96875,444.8125 C 208.51562,444.8125 208.16796,444.73211 207.90625,444.53125 C 207.71094,444.3826 207.60546,444.13793 207.5625,443.8125 L 206.53125,443.65625 C 206.51562,444.34726 206.73046,444.84603 207.1875,445.1875 C 207.64453,445.533 208.2578,445.71874 209,445.71875 C 209.625,445.71875 210.13671,445.58479 210.5625,445.34375 C 210.99218,445.1027 211.30468,444.79282 211.5,444.375 C 211.69921,443.9612 211.81249,443.24633 211.8125,442.25 L 211.8125,436.71875 L 210.8125,436.71875 L 210.8125,437.5 C 210.33593,436.88935 209.73437,436.5625 209,436.5625 z M 218.78125,436.5625 C 218.45703,436.56251 218.1289,436.63037 217.84375,436.71875 C 217.5625,436.80312 217.35156,436.90672 217.1875,437.03125 C 216.96875,437.19196 216.78515,437.37993 216.65625,437.625 C 216.53125,437.86606 216.46875,438.12101 216.46875,438.40625 C 216.46875,438.71962 216.5664,439.02011 216.71875,439.28125 C 216.875,439.53837 217.07812,439.75761 217.375,439.90625 C 217.67578,440.05088 218.22656,440.20539 219,440.40625 C 219.57422,440.5549 219.91796,440.68483 220.0625,440.78125 C 220.26953,440.92186 220.37499,441.09868 220.375,441.34375 C 220.375,441.61694 220.26562,441.8576 220.03125,442.0625 C 219.79687,442.26338 219.45312,442.375 218.96875,442.375 C 218.48828,442.375 218.11327,442.26026 217.84375,442.03125 C 217.57812,441.80225 217.40234,441.46111 217.34375,441.03125 L 216.3125,441.21875 C 216.42969,441.89771 216.70312,442.4045 217.125,442.75 C 217.55078,443.0955 218.16015,443.28126 218.96875,443.28125 C 219.45703,443.28125 219.89452,443.17276 220.28125,443 C 220.66796,442.82323 220.95312,442.56737 221.15625,442.25 C 221.36328,441.9286 221.46874,441.61158 221.46875,441.25 C 221.46874,440.88039 221.38671,440.56158 221.21875,440.3125 C 221.05078,440.06342 220.82812,439.87856 220.53125,439.75 C 220.23828,439.61743 219.71484,439.45488 218.96875,439.25 C 218.45312,439.10537 218.13671,439.00893 218.03125,438.96875 C 217.84765,438.89242 217.71093,438.804 217.625,438.6875 C 217.53906,438.57501 217.49999,438.42187 217.5,438.28125 C 217.5,438.06029 217.60546,437.88348 217.8125,437.71875 C 218.01953,437.55404 218.35937,437.46875 218.84375,437.46875 C 219.2539,437.46876 219.55859,437.56522 219.78125,437.75 C 220.00781,437.93481 220.17187,438.20183 220.21875,438.53125 L 221.25,438.375 C 221.18359,437.9612 221.05077,437.62009 220.875,437.375 C 220.69921,437.12592 220.43358,436.92587 220.0625,436.78125 C 219.69531,436.63663 219.26952,436.5625 218.78125,436.5625 z M 228.34375,436.5625 C 228.09765,436.56251 227.86327,436.63661 227.65625,436.78125 C 227.45312,436.92589 227.24218,437.23354 227,437.6875 L 227,436.71875 L 226.03125,436.71875 L 226.03125,443.125 L 227.09375,443.125 L 227.09375,439.78125 C 227.09375,439.32326 227.16405,438.8857 227.28125,438.5 C 227.35937,438.2469 227.47265,438.04686 227.65625,437.90625 C 227.83984,437.76163 228.05077,437.6875 228.28125,437.6875 C 228.53906,437.68751 228.80468,437.78082 229.0625,437.9375 L 229.4375,436.9375 C 229.07031,436.70449 228.69921,436.5625 228.34375,436.5625 z M 232.625,436.5625 C 231.76562,436.56251 231.07031,436.87417 230.53125,437.46875 C 229.99219,438.06334 229.71875,438.89205 229.71875,439.96875 C 229.71875,441.00928 229.96874,441.82774 230.5,442.40625 C 231.03515,442.98075 231.77734,443.28126 232.6875,443.28125 C 233.41015,443.28125 234.0039,443.08033 234.46875,442.71875 C 234.93359,442.35718 235.23436,441.84234 235.40625,441.1875 L 234.3125,441.0625 C 234.15234,441.5205 233.92968,441.85358 233.65625,442.0625 C 233.38281,442.27141 233.07421,442.375 232.6875,442.375 C 232.16797,442.375 231.72265,442.18614 231.375,441.8125 C 231.02734,441.43887 230.85156,440.89056 230.8125,440.1875 L 235.4375,440.1875 C 235.4414,440.05894 235.43749,439.97052 235.4375,439.90625 C 235.43749,438.84965 235.18358,438.02003 234.65625,437.4375 C 234.1289,436.85497 233.45702,436.5625 232.625,436.5625 z M 239.375,436.5625 C 238.83984,436.56251 238.375,436.65986 237.96875,436.8125 C 237.5625,436.96115 237.2461,437.15627 237.03125,437.4375 C 236.81641,437.71471 236.65625,438.10852 236.5625,438.5625 L 237.59375,438.6875 C 237.70703,438.23353 237.89063,437.92679 238.125,437.75 C 238.36328,437.56922 238.72266,437.46877 239.21875,437.46875 C 239.75,437.46876 240.13672,437.59869 240.40625,437.84375 C 240.60546,438.02454 240.71875,438.33932 240.71875,438.78125 C 240.71875,438.82143 240.72266,438.91384 240.71875,439.0625 C 240.3164,439.20713 239.69531,439.33304 238.84375,439.4375 C 238.42578,439.48973 238.11328,439.53751 237.90625,439.59375 C 237.625,439.6741 237.35157,439.78081 237.125,439.9375 C 236.90234,440.09419 236.73438,440.30138 236.59375,440.5625 C 236.45703,440.81962 236.37501,441.12414 236.375,441.4375 C 236.375,441.97183 236.57032,442.40451 236.9375,442.75 C 237.30469,443.09149 237.81641,443.28126 238.5,443.28125 C 238.91406,443.28125 239.29688,443.20311 239.65625,443.0625 C 240.01953,442.92189 240.42188,442.68523 240.8125,442.34375 C 240.84375,442.64506 240.89063,442.90002 241,443.125 L 242.125,443.125 C 241.99218,442.87993 241.89062,442.60889 241.84375,442.34375 C 241.80078,442.07458 241.78125,441.44589 241.78125,440.4375 L 241.78125,439 C 241.78124,438.5179 241.75391,438.1848 241.71875,438 C 241.65624,437.70271 241.5625,437.44283 241.40625,437.25 C 241.24999,437.05315 240.98828,436.90981 240.65625,436.78125 C 240.32421,436.6527 239.90625,436.5625 239.375,436.5625 z M 246.25,436.5625 C 245.83593,436.56251 245.48047,436.68217 245.15625,436.875 C 244.83203,437.06383 244.57032,437.31163 244.375,437.625 L 244.375,436.71875 L 243.40625,436.71875 L 243.40625,443.125 L 244.46875,443.125 L 244.46875,439.8125 C 244.46875,439.22997 244.54297,438.77811 244.65625,438.46875 C 244.76953,438.15941 244.93751,437.91072 245.1875,437.75 C 245.4414,437.58931 245.73438,437.53125 246.03125,437.53125 C 246.42187,437.53126 246.70313,437.63395 246.875,437.875 C 247.04687,438.11605 247.125,438.48666 247.125,438.96875 L 247.125,443.125 L 248.1875,443.125 L 248.1875,439.40625 C 248.18749,438.74738 248.30469,438.26604 248.59375,437.96875 C 248.88281,437.66744 249.25,437.53125 249.6875,437.53125 C 249.92968,437.53126 250.16406,437.57101 250.34375,437.6875 C 250.52343,437.80401 250.62109,437.96342 250.6875,438.15625 C 250.7578,438.34508 250.8125,438.65986 250.8125,439.09375 L 250.8125,443.125 L 251.84375,443.125 L 251.84375,438.71875 C 251.84374,437.98757 251.67578,437.44327 251.34375,437.09375 C 251.01171,436.74022 250.55469,436.5625 249.9375,436.5625 C 249.14843,436.56251 248.49219,436.94024 248,437.6875 C 247.8789,437.33397 247.67188,437.07185 247.375,436.875 C 247.08203,436.67815 246.71094,436.5625 246.25,436.5625 z M 111.5625,436.71875 L 113.6875,439.78125 L 111.40625,443.125 L 112.6875,443.125 L 114.3125,440.59375 L 114.65625,441.125 L 115.9375,443.125 L 117.21875,443.125 L 114.90625,439.71875 L 117.0625,436.71875 L 115.8125,436.71875 L 114.75,438.21875 C 114.60547,438.42365 114.45312,438.67235 114.28125,438.9375 C 114.17187,438.74466 114.02343,438.50401 113.84375,438.21875 L 112.875,436.71875 L 111.5625,436.71875 z M 151.03125,436.71875 L 151.03125,437.96875 L 152.21875,437.96875 L 152.21875,436.71875 L 151.03125,436.71875 z M 197.375,436.71875 L 197.375,443.125 L 198.4375,443.125 L 198.4375,436.71875 L 197.375,436.71875 z M 127.03125,437.46875 C 127.51172,437.46876 127.92187,437.68398 128.25,438.09375 C 128.57812,438.50354 128.74999,439.15544 128.75,440.03125 C 128.75,440.82672 128.57421,441.39156 128.25,441.78125 C 127.92968,442.16693 127.55469,442.375 127.09375,442.375 C 126.63672,442.375 126.24219,442.15576 125.90625,441.75 C 125.57031,441.34423 125.375,440.75707 125.375,439.9375 C 125.375,439.08981 125.53125,438.45623 125.84375,438.0625 C 126.16015,437.66879 126.5625,437.46877 127.03125,437.46875 z M 146.40625,437.46875 C 146.88672,437.46876 147.26562,437.68398 147.59375,438.09375 C 147.92187,438.50354 148.09374,439.15544 148.09375,440.03125 C 148.09375,440.82672 147.94921,441.39156 147.625,441.78125 C 147.30468,442.16693 146.89843,442.375 146.4375,442.375 C 145.98047,442.375 145.58593,442.15576 145.25,441.75 C 144.91406,441.34423 144.74999,440.75707 144.75,439.9375 C 144.75,439.08981 144.90624,438.45623 145.21875,438.0625 C 145.53515,437.66879 145.93749,437.46877 146.40625,437.46875 z M 168.59375,437.46875 C 169.11328,437.46876 169.52734,437.68398 169.875,438.09375 C 170.22656,438.49952 170.40624,439.08355 170.40625,439.875 C 170.40624,440.71466 170.22265,441.34022 169.875,441.75 C 169.52734,442.15979 169.11718,442.375 168.59375,442.375 C 168.0664,442.375 167.6289,442.15576 167.28125,441.75 C 166.93359,441.34022 166.74999,440.72584 166.75,439.90625 C 166.75,439.08668 166.93359,438.49951 167.28125,438.09375 C 167.6289,437.68799 168.0664,437.46877 168.59375,437.46875 z M 209.09375,437.46875 C 209.57031,437.46876 209.97655,437.66477 210.3125,438.0625 C 210.65234,438.46024 210.81249,439.06035 210.8125,439.84375 C 210.8125,440.66332 210.64061,441.27057 210.3125,441.65625 C 209.98437,442.03791 209.57812,442.21876 209.09375,442.21875 C 208.60547,442.21875 208.19921,442.04194 207.875,441.65625 C 207.55078,441.27057 207.40624,440.65215 207.40625,439.8125 C 207.40625,439.04114 207.54687,438.45221 207.875,438.0625 C 208.20312,437.66879 208.62499,437.46877 209.09375,437.46875 z M 232.625,437.46875 C 233.16015,437.46876 233.60155,437.67592 233.9375,438.09375 C 234.15625,438.36293 234.29687,438.77415 234.34375,439.3125 L 230.875,439.3125 C 230.91015,438.75407 231.07812,438.3022 231.40625,437.96875 C 231.73828,437.6353 232.14062,437.46875 232.625,437.46875 z M 120.5,438.8125 C 121.00781,438.8125 121.44531,438.97102 121.78125,439.3125 C 122.12109,439.65399 122.28124,440.07147 122.28125,440.59375 C 122.28124,441.10799 122.10937,441.54154 121.78125,441.875 C 121.45312,442.20845 121.03515,442.37501 120.53125,442.375 C 120.20703,442.375 119.90624,442.31294 119.625,442.15625 C 119.34375,441.99555 119.14453,441.758 119,441.46875 C 118.85937,441.17949 118.78125,440.87185 118.78125,440.5625 C 118.78125,440.0563 118.95703,439.64996 119.28125,439.3125 C 119.60937,438.97503 120.0039,438.81252 120.5,438.8125 z M 183.375,439.90625 L 183.375,440.3125 C 183.375,440.79058 183.30077,441.16117 183.1875,441.40625 C 183.03906,441.72363 182.8164,441.97145 182.5,442.15625 C 182.18359,442.33704 181.81249,442.40626 181.40625,442.40625 C 180.99609,442.40625 180.68359,442.31783 180.46875,442.125 C 180.25781,441.93216 180.15624,441.6955 180.15625,441.40625 C 180.15625,441.21743 180.21484,441.05891 180.3125,440.90625 C 180.41015,440.74957 180.53906,440.61161 180.71875,440.53125 C 180.89844,440.4509 181.1914,440.37679 181.625,440.3125 C 182.39062,440.20001 182.99218,440.06694 183.375,439.90625 z M 240.71875,439.90625 L 240.71875,440.3125 C 240.71875,440.79058 240.64453,441.16117 240.53125,441.40625 C 240.38281,441.72363 240.16016,441.97145 239.84375,442.15625 C 239.52734,442.33704 239.15625,442.40626 238.75,442.40625 C 238.33984,442.40625 238.02735,442.31783 237.8125,442.125 C 237.60156,441.93216 237.5,441.6955 237.5,441.40625 C 237.5,441.21743 237.5586,441.05891 237.65625,440.90625 C 237.7539,440.74957 237.88282,440.61161 238.0625,440.53125 C 238.24219,440.4509 238.56641,440.37679 239,440.3125 C 239.76562,440.20001 240.33594,440.06694 240.71875,439.90625 z M 151.03125,441.875 L 151.03125,443.125 L 152.21875,443.125 L 152.21875,441.875 L 151.03125,441.875 z M 253.75,441.875 L 253.75,443.125 L 254.9375,443.125 L 254.9375,441.875 L 253.75,441.875 z M 190.53125,449.5625 C 189.95312,449.56251 189.41015,449.67413 188.9375,449.875 C 188.46484,450.07588 188.12109,450.3603 187.875,450.75 C 187.62891,451.13569 187.49999,451.55408 187.5,452 C 187.5,452.40577 187.61328,452.76433 187.8125,453.09375 C 188.01562,453.41917 188.30859,453.68529 188.71875,453.90625 C 189.03515,454.07901 189.58593,454.27189 190.375,454.46875 C 191.16406,454.66159 191.67577,454.81385 191.90625,454.90625 C 192.26562,455.04687 192.53124,455.22859 192.6875,455.4375 C 192.84374,455.6424 192.90624,455.87904 192.90625,456.15625 C 192.90624,456.42944 192.85155,456.67324 192.6875,456.90625 C 192.52734,457.13525 192.26952,457.30493 191.9375,457.4375 C 191.60546,457.57008 191.21483,457.65624 190.78125,457.65625 C 190.29297,457.65625 189.85937,457.57902 189.46875,457.40625 C 189.07812,457.22948 188.78124,456.99998 188.59375,456.71875 C 188.41015,456.43351 188.30078,456.06694 188.25,455.625 L 187.1875,455.71875 C 187.20312,456.30932 187.35937,456.84247 187.65625,457.3125 C 187.95703,457.77853 188.35156,458.11073 188.875,458.34375 C 189.40234,458.57676 190.0664,458.6875 190.84375,458.6875 C 191.45703,458.6875 192.01171,458.57276 192.5,458.34375 C 192.99218,458.11074 193.36327,457.7888 193.625,457.375 C 193.88671,456.95718 193.99999,456.53256 194,456.0625 C 193.99999,455.58844 193.89452,455.17408 193.65625,454.8125 C 193.41796,454.44691 193.06249,454.14328 192.5625,453.90625 C 192.21874,453.74555 191.58202,453.55669 190.65625,453.34375 C 189.73437,453.12681 189.15624,452.89241 188.9375,452.6875 C 188.71484,452.48261 188.59374,452.22365 188.59375,451.90625 C 188.59375,451.54066 188.74999,451.25712 189.0625,451 C 189.3789,450.73887 189.87499,450.59377 190.5625,450.59375 C 191.22265,450.59376 191.72655,450.746 192.0625,451.03125 C 192.40234,451.3165 192.59765,451.72282 192.65625,452.28125 L 193.75,452.1875 C 193.73046,451.66925 193.60546,451.2223 193.34375,450.8125 C 193.08202,450.40272 192.70702,450.08392 192.21875,449.875 C 191.73437,449.66208 191.16796,449.56252 190.53125,449.5625 z M 107.9375,449.6875 C 107.3125,449.68751 106.78906,449.84199 106.375,450.1875 C 105.96484,450.53301 105.64843,451.04873 105.4375,451.6875 C 105.23047,452.32227 105.125,453.14295 105.125,454.1875 C 105.125,455.84673 105.40234,457.04604 105.96875,457.78125 C 106.4414,458.39191 107.10937,458.6875 107.9375,458.6875 C 108.5664,458.6875 109.08984,458.533 109.5,458.1875 C 109.91406,457.83798 110.19921,457.35352 110.40625,456.71875 C 110.61328,456.07997 110.71874,455.22401 110.71875,454.1875 C 110.71874,453.31169 110.66015,452.60799 110.53125,452.09375 C 110.40234,451.5755 110.22655,451.13881 110,450.78125 C 109.77343,450.41968 109.5039,450.15757 109.15625,449.96875 C 108.80859,449.77592 108.39843,449.68752 107.9375,449.6875 z M 120.5,449.6875 C 119.7539,449.68751 119.16796,449.90586 118.71875,450.34375 C 118.26953,450.78167 118.0625,451.32596 118.0625,451.96875 C 118.0625,452.39461 118.16406,452.75719 118.375,453.0625 C 118.58594,453.36784 118.90625,453.58529 119.34375,453.75 C 118.82031,453.89062 118.41015,454.17281 118.125,454.5625 C 117.84375,454.94818 117.6875,455.4255 117.6875,456 C 117.6875,456.77136 117.94922,457.41925 118.46875,457.9375 C 118.98828,458.45174 119.68359,458.6875 120.53125,458.6875 C 121.3789,458.6875 122.07421,458.45174 122.59375,457.9375 C 123.11328,457.42326 123.37499,456.78655 123.375,456.03125 C 123.37499,455.48487 123.21483,455.01871 122.9375,454.625 C 122.66406,454.23129 122.27734,453.92678 121.75,453.75 C 122.17578,453.58529 122.48046,453.36381 122.6875,453.0625 C 122.89843,452.75718 122.99999,452.40978 123,452 C 122.99999,451.35721 122.76952,450.78969 122.3125,450.34375 C 121.85546,449.8938 121.24999,449.68752 120.5,449.6875 z M 128.65625,449.71875 L 128.65625,452.875 C 128.47265,452.61387 128.23047,452.41071 127.9375,452.25 C 127.64453,452.08529 127.3125,452 126.9375,452 C 126.42578,452.00001 125.97656,452.12906 125.5625,452.40625 C 125.14844,452.68346 124.83203,453.10274 124.625,453.625 C 124.41797,454.14326 124.3125,454.70498 124.3125,455.34375 C 124.3125,455.9986 124.42969,456.58756 124.65625,457.09375 C 124.88672,457.59594 125.21094,458.00002 125.625,458.28125 C 126.04297,458.56247 126.47266,458.68748 126.96875,458.6875 C 127.73437,458.6875 128.32421,458.38475 128.71875,457.75 L 128.71875,458.5625 L 129.6875,458.5625 L 129.6875,449.71875 L 128.65625,449.71875 z M 140.65625,449.71875 L 136.71875,455.4375 L 136.71875,456.4375 L 140.46875,456.4375 L 140.46875,458.5625 L 141.5,458.5625 L 141.5,456.4375 L 142.65625,456.4375 L 142.65625,455.4375 L 141.5,455.4375 L 141.5,449.71875 L 140.65625,449.71875 z M 148,449.71875 L 148,452.875 C 147.8164,452.61387 147.60546,452.41071 147.3125,452.25 C 147.01953,452.08529 146.65624,452 146.28125,452 C 145.76953,452.00001 145.32031,452.12906 144.90625,452.40625 C 144.49219,452.68346 144.17578,453.10274 143.96875,453.625 C 143.76172,454.14326 143.65625,454.70498 143.65625,455.34375 C 143.65625,455.9986 143.77343,456.58756 144,457.09375 C 144.23047,457.59594 144.55468,458.00002 144.96875,458.28125 C 145.38672,458.56247 145.84765,458.68748 146.34375,458.6875 C 147.10937,458.6875 147.69921,458.38475 148.09375,457.75 L 148.09375,458.5625 L 149.0625,458.5625 L 149.0625,449.71875 L 148,449.71875 z M 157.46875,449.71875 L 157.46875,458.5625 L 158.5625,458.5625 L 158.5625,451.03125 L 161.0625,458.5625 L 162.09375,458.5625 L 164.59375,451.15625 L 164.59375,458.5625 L 165.6875,458.5625 L 165.6875,449.71875 L 164.15625,449.71875 L 162.09375,455.875 C 161.88671,456.49771 161.72265,456.95984 161.625,457.28125 C 161.53906,456.99199 161.40624,456.55129 161.21875,455.96875 L 159.1875,449.71875 L 157.46875,449.71875 z M 226.25,449.71875 L 226.25,458.5625 L 229.53125,458.5625 C 230.07812,458.5625 230.53124,458.50267 230.90625,458.40625 C 231.28515,458.30581 231.62499,458.16159 231.875,457.96875 C 232.12499,457.77591 232.33202,457.5098 232.5,457.15625 C 232.67187,456.79869 232.74999,456.41381 232.75,456 C 232.74999,455.48576 232.59374,455.03391 232.3125,454.65625 C 232.03515,454.27861 231.64452,454.00044 231.125,453.84375 C 231.52734,453.63886 231.83202,453.36472 232.03125,453.03125 C 232.23046,452.6978 232.34374,452.34639 232.34375,451.96875 C 232.34374,451.56299 232.22655,451.18213 232,450.8125 C 231.77734,450.43888 231.46092,450.17678 231.0625,450 C 230.66796,449.81922 230.12499,449.71876 229.46875,449.71875 L 226.25,449.71875 z M 256.875,449.71875 L 256.875,458.5625 L 257.84375,458.5625 L 257.84375,457.75 C 258.26172,458.38075 258.82812,458.68748 259.5625,458.6875 C 259.70655,458.6875 259.86398,458.64779 260,458.625 L 260,457.6875 C 259.83513,457.75352 259.68501,457.8125 259.5,457.8125 C 258.93359,457.8125 258.45703,457.52719 258.125,456.96875 C 257.92187,456.62726 257.84375,456.07984 257.84375,455.3125 C 257.84375,454.53311 258.00781,453.94105 258.34375,453.53125 C 258.67968,453.11745 259.07031,452.90626 259.53125,452.90625 C 259.69502,452.90625 259.85379,452.91768 260,452.96875 L 260,452.03125 C 259.87753,452.0135 259.75221,452 259.625,452 C 258.93359,452.00001 258.38281,452.3005 257.9375,452.875 L 257.9375,449.71875 L 256.875,449.71875 z M 196.6875,449.90625 L 195.625,450.5625 L 195.625,452.15625 L 194.875,452.15625 L 194.875,453 L 195.625,453 L 195.625,456.6875 C 195.625,457.33834 195.69532,457.76387 195.78125,457.96875 C 195.86719,458.16963 196.00782,458.31297 196.21875,458.4375 C 196.42969,458.56204 196.71094,458.62499 197.09375,458.625 C 197.32812,458.625 197.60938,458.59554 197.90625,458.53125 L 197.75,457.5625 C 197.55859,457.59062 197.39844,457.62501 197.28125,457.625 C 197.125,457.625 196.99219,457.58348 196.90625,457.53125 C 196.82422,457.47902 196.78907,457.43213 196.75,457.34375 C 196.71484,457.25537 196.6875,457.05936 196.6875,456.75 L 196.6875,453 L 197.75,453 L 197.75,452.15625 L 196.6875,452.15625 L 196.6875,449.90625 z M 107.90625,450.5625 C 108.39843,450.56251 108.82812,450.80317 109.15625,451.28125 C 109.48828,451.75934 109.65624,452.73317 109.65625,454.1875 C 109.65624,455.6338 109.48827,456.61164 109.15625,457.09375 C 108.82812,457.57585 108.42187,457.81249 107.9375,457.8125 C 107.45312,457.8125 107.05078,457.57183 106.71875,457.09375 C 106.39062,456.61165 106.21875,455.63782 106.21875,454.1875 C 106.21875,452.73719 106.38671,451.75711 106.75,451.21875 C 107.03906,450.79692 107.42187,450.56251 107.90625,450.5625 z M 120.53125,450.5625 C 120.92968,450.56251 121.26562,450.69558 121.53125,450.96875 C 121.80078,451.23793 121.93749,451.57103 121.9375,451.96875 C 121.9375,452.35042 121.79296,452.67236 121.53125,452.9375 C 121.27343,453.19864 120.93749,453.34375 120.53125,453.34375 C 120.11328,453.34376 119.79296,453.20266 119.53125,452.9375 C 119.26953,452.67235 119.125,452.32409 119.125,451.90625 C 119.125,451.53665 119.26562,451.23393 119.53125,450.96875 C 119.79687,450.7036 120.1289,450.56249 120.53125,450.5625 z M 227.40625,450.75 L 229.125,450.75 C 229.74218,450.75001 230.15233,450.79064 230.40625,450.875 C 230.66015,450.95536 230.86327,451.11879 231,451.34375 C 231.13671,451.56472 231.21874,451.83174 231.21875,452.125 C 231.21874,452.43435 231.14842,452.67012 231,452.875 C 230.85546,453.0799 230.6328,453.22413 230.34375,453.3125 C 230.125,453.3808 229.75389,453.43752 229.25,453.4375 L 227.40625,453.4375 L 227.40625,450.75 z M 140.46875,451.46875 L 140.46875,455.4375 L 137.75,455.4375 L 140.46875,451.46875 z M 133.875,452 C 133.33984,452.00001 132.86327,452.14513 132.40625,452.40625 C 131.95312,452.66338 131.59765,453.04424 131.375,453.5625 C 131.15234,454.08076 131.03125,454.68398 131.03125,455.375 C 131.03125,456.44366 131.29687,457.26925 131.8125,457.84375 C 132.33203,458.41423 133.02343,458.68748 133.875,458.6875 C 134.55468,458.6875 135.1289,458.47631 135.59375,458.0625 C 136.06249,457.64468 136.35546,457.07895 136.46875,456.34375 L 135.4375,456.21875 C 135.36328,456.76111 135.18358,457.14511 134.90625,457.40625 C 134.6289,457.66739 134.28905,457.81251 133.875,457.8125 C 133.35937,457.8125 132.91406,457.60844 132.59375,457.21875 C 132.27344,456.82905 132.12499,456.2035 132.125,455.34375 C 132.125,454.49606 132.29296,453.8897 132.625,453.5 C 132.95703,453.10629 133.37499,452.90626 133.90625,452.90625 C 134.25781,452.90626 134.5664,453.00183 134.8125,453.21875 C 135.0625,453.4357 135.24608,453.75763 135.34375,454.1875 L 136.375,454.03125 C 136.2539,453.38444 135.96093,452.88078 135.53125,452.53125 C 135.10156,452.17772 134.55077,452 133.875,452 z M 170.15625,452 C 169.75,452.00001 169.41015,452.08529 169.125,452.25 C 168.83984,452.41071 168.5703,452.64333 168.34375,452.96875 L 168.34375,452.15625 L 167.375,452.15625 L 167.375,461 L 168.4375,461 L 168.4375,457.875 C 168.61719,458.10802 168.84765,458.31608 169.125,458.46875 C 169.40625,458.62141 169.74218,458.68748 170.09375,458.6875 C 170.57421,458.6875 171.00389,458.55846 171.4375,458.28125 C 171.87499,458.00003 172.21092,457.58476 172.4375,457.0625 C 172.66796,456.53621 172.78124,455.96735 172.78125,455.3125 C 172.78124,454.70184 172.67577,454.13524 172.46875,453.625 C 172.26171,453.11077 171.96874,452.71872 171.5625,452.4375 C 171.15625,452.15628 170.68749,452 170.15625,452 z M 176.625,452 C 175.76562,452.00001 175.07032,452.31167 174.53125,452.90625 C 173.99219,453.50084 173.71876,454.32956 173.71875,455.40625 C 173.71875,456.44678 173.96876,457.26522 174.5,457.84375 C 175.03515,458.41825 175.77735,458.68748 176.6875,458.6875 C 177.41015,458.6875 178.00391,458.51784 178.46875,458.15625 C 178.93359,457.79468 179.23438,457.27985 179.40625,456.625 L 178.34375,456.5 C 178.18359,456.958 177.96094,457.29109 177.6875,457.5 C 177.41406,457.70891 177.07422,457.81251 176.6875,457.8125 C 176.16797,457.8125 175.72266,457.62362 175.375,457.25 C 175.02734,456.87637 174.85157,456.32807 174.8125,455.625 L 179.4375,455.625 C 179.4414,455.49644 179.46875,455.40803 179.46875,455.34375 C 179.46874,454.28715 179.18359,453.45754 178.65625,452.875 C 178.1289,452.29247 177.45703,452 176.625,452 z M 183.03125,452 C 182.48047,452.00001 182.0039,452.15627 181.59375,452.4375 C 181.1875,452.71873 180.87109,453.10674 180.65625,453.625 C 180.44141,454.13924 180.34374,454.70184 180.34375,455.3125 C 180.34375,456.20037 180.59374,456.959 181.0625,457.59375 C 181.53125,458.22852 182.17577,458.56251 183.03125,458.5625 C 183.71875,458.5625 184.28905,458.27719 184.75,457.71875 C 184.7539,458.42583 184.74218,458.8728 184.6875,459.09375 C 184.59375,459.45532 184.42186,459.73662 184.15625,459.9375 C 183.89062,460.13837 183.48827,460.25001 183,460.25 C 182.54687,460.25 182.19921,460.13837 181.9375,459.9375 C 181.74219,459.78885 181.63671,459.57541 181.59375,459.25 L 180.5625,459.09375 C 180.54687,459.78476 180.76171,460.2835 181.21875,460.625 C 181.67578,460.9705 182.28905,461.15625 183.03125,461.15625 C 183.65625,461.15625 184.16796,461.0223 184.59375,460.78125 C 185.02343,460.5402 185.33593,460.19907 185.53125,459.78125 C 185.73046,459.36745 185.84374,458.68384 185.84375,457.6875 L 185.84375,452.15625 L 184.84375,452.15625 L 184.84375,452.90625 C 184.36718,452.2956 183.76561,452 183.03125,452 z M 201.0625,452 C 200.8164,452.00001 200.58203,452.07412 200.375,452.21875 C 200.17187,452.36339 199.96093,452.67101 199.71875,453.125 L 199.71875,452.15625 L 198.75,452.15625 L 198.75,458.5625 L 199.8125,458.5625 L 199.8125,455.1875 C 199.8125,454.72951 199.88281,454.32318 200,453.9375 C 200.07812,453.6844 200.1914,453.48436 200.375,453.34375 C 200.55859,453.19913 200.76953,453.12501 201,453.125 C 201.25781,453.12501 201.52343,453.21833 201.78125,453.375 L 202.15625,452.34375 C 201.78906,452.11074 201.41796,452 201.0625,452 z M 205.34375,452 C 204.48437,452.00001 203.78907,452.31167 203.25,452.90625 C 202.71094,453.50084 202.43751,454.32956 202.4375,455.40625 C 202.4375,456.44678 202.68751,457.26522 203.21875,457.84375 C 203.7539,458.41825 204.4961,458.68748 205.40625,458.6875 C 206.1289,458.6875 206.72266,458.51784 207.1875,458.15625 C 207.65234,457.79468 207.95313,457.27985 208.125,456.625 L 207.03125,456.5 C 206.87109,456.958 206.64844,457.29109 206.375,457.5 C 206.10156,457.70891 205.79297,457.81251 205.40625,457.8125 C 204.88672,457.8125 204.44141,457.62362 204.09375,457.25 C 203.74609,456.87637 203.57032,456.32807 203.53125,455.625 L 208.15625,455.625 C 208.16015,455.49644 208.15625,455.40803 208.15625,455.34375 C 208.15624,454.28715 207.90234,453.45754 207.375,452.875 C 206.84765,452.29247 206.17578,452 205.34375,452 z M 212.09375,452 C 211.55859,452.00001 211.09374,452.06608 210.6875,452.21875 C 210.28125,452.3674 209.96484,452.59378 209.75,452.875 C 209.53516,453.15221 209.37499,453.51478 209.28125,453.96875 L 210.3125,454.125 C 210.42578,453.67103 210.60937,453.36427 210.84375,453.1875 C 211.08203,453.00672 211.4414,452.90625 211.9375,452.90625 C 212.46875,452.90626 212.85546,453.0362 213.125,453.28125 C 213.32421,453.46204 213.43749,453.77682 213.4375,454.21875 C 213.4375,454.25893 213.44139,454.35135 213.4375,454.5 C 213.03515,454.64463 212.41405,454.77054 211.5625,454.875 C 211.14453,454.92723 210.83202,454.97502 210.625,455.03125 C 210.34375,455.1116 210.0703,455.21832 209.84375,455.375 C 209.62109,455.53169 209.45312,455.73886 209.3125,456 C 209.17578,456.25712 209.09374,456.56164 209.09375,456.875 C 209.09375,457.40933 209.28905,457.84199 209.65625,458.1875 C 210.02344,458.52899 210.53515,458.68748 211.21875,458.6875 C 211.63281,458.6875 212.01561,458.60937 212.375,458.46875 C 212.73828,458.32814 213.14061,458.09149 213.53125,457.75 C 213.5625,458.05131 213.60936,458.33753 213.71875,458.5625 L 214.84375,458.5625 C 214.71093,458.31743 214.60936,458.0464 214.5625,457.78125 C 214.51953,457.51208 214.49999,456.88339 214.5,455.875 L 214.5,454.40625 C 214.49999,453.92415 214.47264,453.59106 214.4375,453.40625 C 214.37499,453.10896 214.28124,452.88034 214.125,452.6875 C 213.96874,452.49065 213.70702,452.31606 213.375,452.1875 C 213.04296,452.05895 212.62499,452 212.09375,452 z M 218.96875,452 C 218.55468,452.00001 218.19921,452.08843 217.875,452.28125 C 217.55078,452.47008 217.28906,452.71789 217.09375,453.03125 L 217.09375,452.15625 L 216.125,452.15625 L 216.125,458.5625 L 217.1875,458.5625 L 217.1875,455.21875 C 217.1875,454.63622 217.26171,454.18437 217.375,453.875 C 217.48828,453.56566 217.65624,453.3482 217.90625,453.1875 C 218.16015,453.02681 218.45312,452.9375 218.75,452.9375 C 219.14062,452.93751 219.42187,453.07146 219.59375,453.3125 C 219.76562,453.55355 219.84374,453.89291 219.84375,454.375 L 219.84375,458.5625 L 220.90625,458.5625 L 220.90625,454.84375 C 220.90624,454.18488 221.02343,453.70355 221.3125,453.40625 C 221.60156,453.10494 221.96874,452.9375 222.40625,452.9375 C 222.64843,452.93751 222.8828,453.00848 223.0625,453.125 C 223.24218,453.24151 223.33983,453.4009 223.40625,453.59375 C 223.47655,453.78258 223.53124,454.09737 223.53125,454.53125 L 223.53125,458.5625 L 224.5625,458.5625 L 224.5625,454.15625 C 224.56249,453.42507 224.39452,452.88078 224.0625,452.53125 C 223.73046,452.17772 223.27342,452 222.65625,452 C 221.86718,452.00001 221.21093,452.37775 220.71875,453.125 C 220.59765,452.77147 220.39061,452.50936 220.09375,452.3125 C 219.80078,452.11565 219.42968,452 218.96875,452 z M 236.8125,452 C 236.27734,452.00001 235.81249,452.06608 235.40625,452.21875 C 235,452.3674 234.68359,452.59378 234.46875,452.875 C 234.25391,453.15221 234.09374,453.51478 234,453.96875 L 235.03125,454.125 C 235.14453,453.67103 235.32812,453.36427 235.5625,453.1875 C 235.80078,453.00672 236.16015,452.90625 236.65625,452.90625 C 237.1875,452.90626 237.60546,453.0362 237.875,453.28125 C 238.07421,453.46204 238.15624,453.77682 238.15625,454.21875 C 238.15625,454.25893 238.16015,454.35135 238.15625,454.5 C 237.7539,454.64463 237.1328,454.77054 236.28125,454.875 C 235.86328,454.92723 235.55077,454.97502 235.34375,455.03125 C 235.0625,455.1116 234.82031,455.21832 234.59375,455.375 C 234.37109,455.53169 234.17187,455.73886 234.03125,456 C 233.89453,456.25712 233.84375,456.56164 233.84375,456.875 C 233.84375,457.40933 234.00781,457.84199 234.375,458.1875 C 234.74219,458.52899 235.28515,458.68748 235.96875,458.6875 C 236.38281,458.6875 236.76562,458.60937 237.125,458.46875 C 237.48828,458.32814 237.85937,458.09149 238.25,457.75 C 238.28125,458.05131 238.35937,458.33753 238.46875,458.5625 L 239.5625,458.5625 C 239.42968,458.31743 239.32811,458.0464 239.28125,457.78125 C 239.23828,457.51208 239.21874,456.88339 239.21875,455.875 L 239.21875,454.40625 C 239.21874,453.92415 239.22265,453.59106 239.1875,453.40625 C 239.12499,453.10896 238.99999,452.88034 238.84375,452.6875 C 238.68749,452.49065 238.45702,452.31606 238.125,452.1875 C 237.79296,452.05895 237.34374,452 236.8125,452 z M 242.90625,452 C 242.58203,452.00001 242.28515,452.03663 242,452.125 C 241.71875,452.20937 241.50781,452.31295 241.34375,452.4375 C 241.125,452.59821 240.9414,452.81743 240.8125,453.0625 C 240.6875,453.30356 240.625,453.55852 240.625,453.84375 C 240.625,454.15712 240.6914,454.45762 240.84375,454.71875 C 241,454.97587 241.23437,455.16387 241.53125,455.3125 C 241.83203,455.45713 242.35156,455.64287 243.125,455.84375 C 243.69922,455.9924 244.07421,456.12234 244.21875,456.21875 C 244.42578,456.35936 244.53124,456.53619 244.53125,456.78125 C 244.53125,457.05444 244.42187,457.2951 244.1875,457.5 C 243.95312,457.70088 243.57812,457.81251 243.09375,457.8125 C 242.61328,457.8125 242.23828,457.69773 241.96875,457.46875 C 241.70312,457.23975 241.55859,456.89862 241.5,456.46875 L 240.4375,456.625 C 240.55469,457.30396 240.82812,457.842 241.25,458.1875 C 241.67578,458.533 242.28515,458.68748 243.09375,458.6875 C 243.58203,458.6875 244.01952,458.61026 244.40625,458.4375 C 244.79296,458.26073 245.10937,458.00488 245.3125,457.6875 C 245.51953,457.3661 245.62499,457.01783 245.625,456.65625 C 245.62499,456.28664 245.54296,455.99909 245.375,455.75 C 245.20703,455.50092 244.95312,455.31607 244.65625,455.1875 C 244.36328,455.05493 243.83984,454.86114 243.09375,454.65625 C 242.57812,454.51162 242.29296,454.41519 242.1875,454.375 C 242.0039,454.29867 241.86718,454.21026 241.78125,454.09375 C 241.69531,453.98126 241.625,453.85938 241.625,453.71875 C 241.625,453.49779 241.73046,453.32099 241.9375,453.15625 C 242.14453,452.99154 242.51562,452.90626 243,452.90625 C 243.41015,452.90626 243.71484,453.00269 243.9375,453.1875 C 244.16406,453.37231 244.29687,453.60806 244.34375,453.9375 L 245.375,453.8125 C 245.30859,453.3987 245.17577,453.05756 245,452.8125 C 244.82421,452.56342 244.55859,452.36338 244.1875,452.21875 C 243.82031,452.07413 243.39453,452 242.90625,452 z M 249.40625,452 C 248.54687,452.00001 247.85156,452.31167 247.3125,452.90625 C 246.77344,453.50084 246.5,454.32956 246.5,455.40625 C 246.5,456.44678 246.78125,457.26522 247.3125,457.84375 C 247.84765,458.41825 248.55859,458.68748 249.46875,458.6875 C 250.1914,458.6875 250.78515,458.51784 251.25,458.15625 C 251.71484,457.79468 252.04687,457.27985 252.21875,456.625 L 251.125,456.5 C 250.96484,456.958 250.74218,457.29109 250.46875,457.5 C 250.19531,457.70891 249.88671,457.81251 249.5,457.8125 C 248.98047,457.8125 248.53515,457.62362 248.1875,457.25 C 247.83984,456.87637 247.63281,456.32807 247.59375,455.625 L 252.25,455.625 C 252.2539,455.49644 252.24999,455.40803 252.25,455.34375 C 252.24999,454.28715 251.99609,453.45754 251.46875,452.875 C 250.9414,452.29247 250.23827,452 249.40625,452 z M 111.5625,452.15625 L 113.6875,455.21875 L 111.40625,458.5625 L 112.6875,458.5625 L 114.3125,456.03125 L 114.65625,456.5625 L 115.9375,458.5625 L 117.21875,458.5625 L 114.90625,455.15625 L 117.0625,452.15625 L 115.8125,452.15625 L 114.75,453.65625 C 114.60547,453.86115 114.45312,454.10986 114.28125,454.375 C 114.17187,454.18216 114.02343,453.94149 113.84375,453.65625 L 112.875,452.15625 L 111.5625,452.15625 z M 151.03125,452.15625 L 151.03125,453.375 L 152.21875,453.375 L 152.21875,452.15625 L 151.03125,452.15625 z M 170.0625,452.84375 C 170.51562,452.84376 170.89452,453.06299 171.21875,453.46875 C 171.54687,453.87452 171.71874,454.46569 171.71875,455.28125 C 171.71874,456.13698 171.55468,456.77772 171.21875,457.1875 C 170.88671,457.59327 170.46874,457.81251 170,457.8125 C 169.53906,457.8125 169.16796,457.61248 168.84375,457.21875 C 168.51953,456.82504 168.34374,456.19858 168.34375,455.375 C 168.34375,454.55142 168.53124,453.92989 168.875,453.5 C 169.22265,453.06612 169.61327,452.84375 170.0625,452.84375 z M 127.03125,452.90625 C 127.51172,452.90626 127.92187,453.12148 128.25,453.53125 C 128.57812,453.94104 128.74999,454.5617 128.75,455.4375 C 128.75,456.23297 128.57421,456.82906 128.25,457.21875 C 127.92968,457.60443 127.55469,457.81251 127.09375,457.8125 C 126.63672,457.8125 126.24219,457.59327 125.90625,457.1875 C 125.57031,456.78173 125.375,456.16333 125.375,455.34375 C 125.375,454.49606 125.53125,453.89371 125.84375,453.5 C 126.16015,453.10629 126.5625,452.90625 127.03125,452.90625 z M 146.40625,452.90625 C 146.88672,452.90626 147.26562,453.12148 147.59375,453.53125 C 147.92187,453.94104 148.09374,454.5617 148.09375,455.4375 C 148.09375,456.23297 147.94921,456.82906 147.625,457.21875 C 147.30468,457.60443 146.89843,457.81251 146.4375,457.8125 C 145.98047,457.8125 145.58593,457.59327 145.25,457.1875 C 144.91406,456.78173 144.74999,456.16333 144.75,455.34375 C 144.75,454.49606 144.90624,453.89371 145.21875,453.5 C 145.53515,453.10629 145.93749,452.90625 146.40625,452.90625 z M 176.625,452.90625 C 177.16015,452.90626 177.60156,453.11343 177.9375,453.53125 C 178.15625,453.80043 178.29688,454.18041 178.34375,454.71875 L 174.875,454.71875 C 174.91015,454.16032 175.07813,453.73971 175.40625,453.40625 C 175.73828,453.0728 176.14063,452.90626 176.625,452.90625 z M 183.125,452.90625 C 183.60156,452.90626 184.0078,453.10227 184.34375,453.5 C 184.68359,453.89774 184.84374,454.49783 184.84375,455.28125 C 184.84375,456.10082 184.67186,456.67682 184.34375,457.0625 C 184.01562,457.44416 183.60936,457.65624 183.125,457.65625 C 182.63672,457.65625 182.23046,457.44817 181.90625,457.0625 C 181.58203,456.67682 181.43749,456.0584 181.4375,455.21875 C 181.4375,454.44739 181.57812,453.88969 181.90625,453.5 C 182.23437,453.10629 182.65624,452.90625 183.125,452.90625 z M 205.34375,452.90625 C 205.8789,452.90626 206.32031,453.11343 206.65625,453.53125 C 206.875,453.80043 207.01563,454.18041 207.0625,454.71875 L 203.5625,454.71875 C 203.59765,454.16032 203.79688,453.73971 204.125,453.40625 C 204.45703,453.0728 204.85938,452.90626 205.34375,452.90625 z M 249.4375,452.90625 C 249.97265,452.90626 250.41406,453.11343 250.75,453.53125 C 250.96875,453.80043 251.07812,454.18041 251.125,454.71875 L 247.65625,454.71875 C 247.6914,454.16032 247.89062,453.73971 248.21875,453.40625 C 248.55078,453.0728 248.95312,452.90626 249.4375,452.90625 z M 120.5,454.21875 C 121.00781,454.21875 121.44531,454.40853 121.78125,454.75 C 122.12109,455.09149 122.28124,455.50898 122.28125,456.03125 C 122.28124,456.54549 122.10937,456.97904 121.78125,457.3125 C 121.45312,457.64595 121.03515,457.81249 120.53125,457.8125 C 120.20703,457.8125 119.90624,457.7192 119.625,457.5625 C 119.34375,457.4018 119.14453,457.19551 119,456.90625 C 118.85937,456.61699 118.78125,456.30936 118.78125,456 C 118.78125,455.4938 118.95703,455.05622 119.28125,454.71875 C 119.60937,454.38128 120.0039,454.21874 120.5,454.21875 z M 227.40625,454.46875 L 229.375,454.46875 C 229.92187,454.46875 230.33593,454.52457 230.625,454.625 C 230.91796,454.72142 231.14842,454.87993 231.3125,455.125 C 231.47656,455.36605 231.56249,455.67058 231.5625,456 C 231.56249,456.28123 231.51952,456.53307 231.40625,456.75 C 231.29296,456.96293 231.14452,457.10627 230.96875,457.21875 C 230.79296,457.33124 230.57421,457.42054 230.3125,457.46875 C 230.16406,457.49687 229.89843,457.50001 229.53125,457.5 L 227.40625,457.5 L 227.40625,454.46875 z M 213.4375,455.34375 L 213.4375,455.71875 C 213.4375,456.19683 213.36327,456.56743 213.25,456.8125 C 213.10156,457.12988 212.87889,457.37771 212.5625,457.5625 C 212.24609,457.74329 211.87499,457.84374 211.46875,457.84375 C 211.05859,457.84375 210.74608,457.75534 210.53125,457.5625 C 210.32031,457.36966 210.21874,457.13301 210.21875,456.84375 C 210.21875,456.65493 210.27734,456.46517 210.375,456.3125 C 210.47265,456.15582 210.60155,456.04912 210.78125,455.96875 C 210.96094,455.8884 211.28515,455.81427 211.71875,455.75 C 212.48437,455.63751 213.05468,455.50445 213.4375,455.34375 z M 238.15625,455.34375 L 238.15625,455.71875 C 238.15625,456.19683 238.11327,456.56743 238,456.8125 C 237.85156,457.12988 237.59765,457.37771 237.28125,457.5625 C 236.96484,457.74329 236.62499,457.84374 236.21875,457.84375 C 235.80859,457.84375 235.49609,457.75534 235.28125,457.5625 C 235.07031,457.36966 234.96874,457.13301 234.96875,456.84375 C 234.96875,456.65493 234.99609,456.46517 235.09375,456.3125 C 235.1914,456.15582 235.35156,456.04912 235.53125,455.96875 C 235.71094,455.8884 236.0039,455.81427 236.4375,455.75 C 237.20312,455.63751 237.77343,455.50445 238.15625,455.34375 z M 151.03125,457.3125 L 151.03125,458.5625 L 152.21875,458.5625 L 152.21875,457.3125 L 151.03125,457.3125 z M 107.9375,465.09375 C 107.3125,465.09376 106.78906,465.2795 106.375,465.625 C 105.96484,465.97051 105.64843,466.45499 105.4375,467.09375 C 105.23047,467.72852 105.125,468.58046 105.125,469.625 C 105.125,471.28423 105.40234,472.48355 105.96875,473.21875 C 106.4414,473.82941 107.10937,474.12501 107.9375,474.125 C 108.5664,474.125 109.08984,473.93925 109.5,473.59375 C 109.91406,473.24423 110.19921,472.75978 110.40625,472.125 C 110.61328,471.48622 110.71874,470.66152 110.71875,469.625 C 110.71874,468.74919 110.66015,468.0455 110.53125,467.53125 C 110.40234,467.013 110.22655,466.57632 110,466.21875 C 109.77343,465.85718 109.5039,465.59508 109.15625,465.40625 C 108.80859,465.21342 108.39843,465.09374 107.9375,465.09375 z M 120.5,465.09375 C 119.7539,465.09376 119.16796,465.31209 118.71875,465.75 C 118.26953,466.18792 118.0625,466.73222 118.0625,467.375 C 118.0625,467.80086 118.16406,468.16342 118.375,468.46875 C 118.58594,468.77409 118.90625,469.0228 119.34375,469.1875 C 118.82031,469.32812 118.41015,469.57906 118.125,469.96875 C 117.84375,470.35443 117.6875,470.83175 117.6875,471.40625 C 117.6875,472.17761 117.94922,472.8255 118.46875,473.34375 C 118.98828,473.85799 119.68359,474.12501 120.53125,474.125 C 121.3789,474.125 122.07421,473.858 122.59375,473.34375 C 123.11328,472.82951 123.37499,472.1928 123.375,471.4375 C 123.37499,470.89112 123.21483,470.42496 122.9375,470.03125 C 122.66406,469.63754 122.27734,469.36429 121.75,469.1875 C 122.17578,469.02279 122.48046,468.80132 122.6875,468.5 C 122.89843,468.19468 122.99999,467.81604 123,467.40625 C 122.99999,466.76346 122.76952,466.2272 122.3125,465.78125 C 121.85546,465.3313 121.24999,465.09374 120.5,465.09375 z M 128.65625,465.15625 L 128.65625,468.3125 C 128.47265,468.05137 128.23047,467.84822 127.9375,467.6875 C 127.64453,467.52279 127.3125,467.43751 126.9375,467.4375 C 126.42578,467.43751 125.97656,467.56653 125.5625,467.84375 C 125.14844,468.12096 124.83203,468.50897 124.625,469.03125 C 124.41797,469.54951 124.3125,470.14249 124.3125,470.78125 C 124.3125,471.4361 124.42969,472.02504 124.65625,472.53125 C 124.88672,473.03344 125.21094,473.40628 125.625,473.6875 C 126.04297,473.96872 126.47266,474.12499 126.96875,474.125 C 127.73437,474.125 128.32421,473.79101 128.71875,473.15625 L 128.71875,473.96875 L 129.6875,473.96875 L 129.6875,465.15625 L 128.65625,465.15625 z M 140.65625,465.15625 L 136.71875,470.875 L 136.71875,471.875 L 140.46875,471.875 L 140.46875,473.96875 L 141.5,473.96875 L 141.5,471.875 L 142.65625,471.875 L 142.65625,470.875 L 141.5,470.875 L 141.5,465.15625 L 140.65625,465.15625 z M 148,465.15625 L 148,468.3125 C 147.8164,468.05137 147.60546,467.84822 147.3125,467.6875 C 147.01953,467.52279 146.65624,467.43751 146.28125,467.4375 C 145.76953,467.43751 145.32031,467.56653 144.90625,467.84375 C 144.49219,468.12096 144.17578,468.50897 143.96875,469.03125 C 143.76172,469.54951 143.65625,470.14249 143.65625,470.78125 C 143.65625,471.4361 143.77343,472.02504 144,472.53125 C 144.23047,473.03344 144.55468,473.40628 144.96875,473.6875 C 145.38672,473.96872 145.84765,474.12499 146.34375,474.125 C 147.10937,474.125 147.69921,473.79101 148.09375,473.15625 L 148.09375,473.96875 L 149.0625,473.96875 L 149.0625,465.15625 L 148,465.15625 z M 157.5,465.15625 L 157.5,473.96875 L 158.59375,473.96875 L 158.59375,467.03125 L 163.09375,473.96875 L 164.28125,473.96875 L 164.28125,465.15625 L 163.1875,465.15625 L 163.1875,472.0625 L 158.6875,465.15625 L 157.5,465.15625 z M 188.65625,465.15625 L 192,473.96875 L 193.15625,473.96875 L 196.53125,465.15625 L 195.34375,465.15625 L 193.03125,471.5625 C 192.85546,472.0446 192.69531,472.51791 192.5625,473 C 192.4414,472.55004 192.30468,472.07674 192.125,471.5625 L 189.875,465.15625 L 188.65625,465.15625 z M 197.5,465.15625 L 197.5,473.96875 L 200.78125,473.96875 C 201.32812,473.96875 201.78124,473.94018 202.15625,473.84375 C 202.53515,473.74331 202.84375,473.59909 203.09375,473.40625 C 203.34374,473.21341 203.55078,472.91606 203.71875,472.5625 C 203.89062,472.20494 204,471.82004 204,471.40625 C 203.99999,470.89201 203.84375,470.44014 203.5625,470.0625 C 203.28515,469.68486 202.89452,469.43795 202.375,469.28125 C 202.77734,469.07636 203.08203,468.8022 203.28125,468.46875 C 203.48046,468.1353 203.5625,467.7839 203.5625,467.40625 C 203.56249,467.00049 203.44531,466.6196 203.21875,466.25 C 202.99609,465.87638 202.71092,465.58304 202.3125,465.40625 C 201.91796,465.22547 201.37499,465.15627 200.71875,465.15625 L 197.5,465.15625 z M 205.59375,465.15625 L 205.59375,473.96875 L 206.71875,473.96875 L 206.71875,470.0625 L 208.03125,470.0625 C 208.32422,470.0625 208.52733,470.06563 208.65625,470.09375 C 208.83203,470.13795 209.01952,470.23127 209.1875,470.34375 C 209.35937,470.45624 209.53515,470.62504 209.75,470.90625 C 209.96484,471.18748 210.26171,471.59469 210.59375,472.125 L 211.71875,473.96875 L 213.15625,473.96875 L 211.65625,471.5625 C 211.35937,471.09246 211.05077,470.7196 210.71875,470.40625 C 210.56249,470.26162 210.33202,470.11741 210.03125,469.96875 C 210.85546,469.85225 211.44921,469.55487 211.84375,469.125 C 212.23827,468.69513 212.43749,468.18922 212.4375,467.5625 C 212.43749,467.07639 212.33202,466.62051 212.09375,466.21875 C 211.85546,465.81701 211.52343,465.53169 211.125,465.375 C 210.72656,465.21431 210.14061,465.15627 209.375,465.15625 L 205.59375,465.15625 z M 214.4375,465.15625 L 214.4375,473.96875 L 215.5625,473.96875 L 215.5625,465.15625 L 214.4375,465.15625 z M 173.96875,465.34375 L 172.9375,466 L 172.9375,467.5625 L 172.15625,467.5625 L 172.15625,468.40625 L 172.9375,468.40625 L 172.9375,472.09375 C 172.9375,472.74459 172.97657,473.1701 173.0625,473.375 C 173.14844,473.57588 173.28907,473.75045 173.5,473.875 C 173.71094,473.99954 174.02344,474.0625 174.40625,474.0625 C 174.64062,474.0625 174.89063,474.03302 175.1875,473.96875 L 175.03125,473 C 174.83984,473.02812 174.67969,473.06251 174.5625,473.0625 C 174.40625,473.0625 174.30469,473.02099 174.21875,472.96875 C 174.13672,472.91652 174.07032,472.83839 174.03125,472.75 C 173.99609,472.66162 173.96875,472.46559 173.96875,472.15625 L 173.96875,468.40625 L 175.03125,468.40625 L 175.03125,467.5625 L 173.96875,467.5625 L 173.96875,465.34375 z M 228,465.34375 L 226.9375,466 L 226.9375,467.5625 L 226.1875,467.5625 L 226.1875,468.40625 L 226.9375,468.40625 L 226.9375,472.09375 C 226.9375,472.74459 227.0078,473.1701 227.09375,473.375 C 227.17969,473.57588 227.3203,473.75045 227.53125,473.875 C 227.74219,473.99954 228.02343,474.0625 228.40625,474.0625 C 228.64062,474.0625 228.92187,474.03302 229.21875,473.96875 L 229.0625,473 C 228.87109,473.02812 228.71093,473.06251 228.59375,473.0625 C 228.4375,473.0625 228.30468,473.02099 228.21875,472.96875 C 228.13672,472.91652 228.10155,472.83839 228.0625,472.75 C 228.02734,472.66162 227.99999,472.46559 228,472.15625 L 228,468.40625 L 229.0625,468.40625 L 229.0625,467.5625 L 228,467.5625 L 228,465.34375 z M 107.90625,466 C 108.39843,466.00001 108.82812,466.24067 109.15625,466.71875 C 109.48828,467.19684 109.65624,468.17068 109.65625,469.625 C 109.65624,471.0713 109.48827,472.0179 109.15625,472.5 C 108.82812,472.9821 108.42187,473.21875 107.9375,473.21875 C 107.45312,473.21875 107.05078,473.00934 106.71875,472.53125 C 106.39062,472.04915 106.21875,471.07532 106.21875,469.625 C 106.21875,468.17469 106.38671,467.16336 106.75,466.625 C 107.03906,466.20317 107.42187,466.00002 107.90625,466 z M 120.53125,466 C 120.92968,466.00001 121.26562,466.13306 121.53125,466.40625 C 121.80078,466.67543 121.93749,467.00854 121.9375,467.40625 C 121.9375,467.78792 121.79296,468.10984 121.53125,468.375 C 121.27343,468.63614 120.93749,468.78126 120.53125,468.78125 C 120.11328,468.78126 119.79296,468.64017 119.53125,468.375 C 119.26953,468.10985 119.125,467.76157 119.125,467.34375 C 119.125,466.97415 119.26562,466.6714 119.53125,466.40625 C 119.79687,466.1411 120.1289,466 120.53125,466 z M 206.71875,466.125 L 209.4375,466.125 C 210.07421,466.12501 210.55077,466.26207 210.84375,466.53125 C 211.14062,466.80043 211.28124,467.14467 211.28125,467.5625 C 211.28124,467.84775 211.21483,468.0987 211.0625,468.34375 C 210.91015,468.58481 210.66796,468.7625 210.375,468.875 C 210.08203,468.98348 209.67577,469.03126 209.15625,469.03125 L 206.71875,469.03125 L 206.71875,466.125 z M 198.625,466.1875 L 200.34375,466.1875 C 200.96093,466.18751 201.40233,466.22814 201.65625,466.3125 C 201.91015,466.39286 202.11327,466.55627 202.25,466.78125 C 202.38671,467.00222 202.4375,467.23797 202.4375,467.53125 C 202.43749,467.8406 202.36717,468.1076 202.21875,468.3125 C 202.07421,468.5174 201.8828,468.66161 201.59375,468.75 C 201.375,468.8183 201.00389,468.84375 200.5,468.84375 L 198.625,468.84375 L 198.625,466.1875 z M 140.46875,466.875 L 140.46875,470.875 L 137.75,470.875 L 140.46875,466.875 z M 133.875,467.4375 C 133.33984,467.43751 132.86327,467.55136 132.40625,467.8125 C 131.95312,468.06963 131.59765,468.48175 131.375,469 C 131.15234,469.51826 131.03125,470.12149 131.03125,470.8125 C 131.03125,471.88116 131.29687,472.67551 131.8125,473.25 C 132.33203,473.82048 133.02343,474.12499 133.875,474.125 C 134.55468,474.125 135.1289,473.91379 135.59375,473.5 C 136.06249,473.08218 136.35546,472.51646 136.46875,471.78125 L 135.4375,471.625 C 135.36328,472.16736 135.18358,472.58262 134.90625,472.84375 C 134.6289,473.10489 134.28905,473.21877 133.875,473.21875 C 133.35937,473.21875 132.91406,473.04595 132.59375,472.65625 C 132.27344,472.26655 132.12499,471.64098 132.125,470.78125 C 132.125,469.93356 132.29296,469.29596 132.625,468.90625 C 132.95703,468.51254 133.37499,468.31252 133.90625,468.3125 C 134.25781,468.31251 134.5664,468.4393 134.8125,468.65625 C 135.0625,468.8732 135.24608,469.19514 135.34375,469.625 L 136.375,469.46875 C 136.2539,468.82194 135.96093,468.31829 135.53125,467.96875 C 135.10156,467.61522 134.55077,467.43751 133.875,467.4375 z M 168.59375,467.4375 C 167.82422,467.43751 167.16015,467.68221 166.625,468.15625 C 165.98437,468.72674 165.65625,469.59609 165.65625,470.78125 C 165.65625,471.86196 165.93359,472.67549 166.46875,473.25 C 167.00781,473.8245 167.72265,474.12499 168.59375,474.125 C 169.13671,474.125 169.63671,473.9799 170.09375,473.71875 C 170.55468,473.45761 170.88671,473.09505 171.125,472.625 C 171.36718,472.15094 171.49999,471.51109 171.5,470.6875 C 171.49999,469.67108 171.23046,468.887 170.6875,468.3125 C 170.14453,467.73399 169.44921,467.43751 168.59375,467.4375 z M 182.03125,467.4375 C 181.49609,467.43751 180.99999,467.50359 180.59375,467.65625 C 180.1875,467.8049 179.90234,468.03128 179.6875,468.3125 C 179.47266,468.58971 179.3125,468.95229 179.21875,469.40625 L 180.25,469.53125 C 180.36328,469.07728 180.54687,468.77053 180.78125,468.59375 C 181.01953,468.41297 181.3789,468.34375 181.875,468.34375 C 182.40625,468.34376 182.79296,468.44242 183.0625,468.6875 C 183.26171,468.86829 183.37499,469.18308 183.375,469.625 C 183.375,469.66518 183.3789,469.75761 183.375,469.90625 C 182.97265,470.05088 182.32031,470.1768 181.46875,470.28125 C 181.05078,470.33348 180.73828,470.38125 180.53125,470.4375 C 180.25,470.51785 180.00781,470.65583 179.78125,470.8125 C 179.55859,470.96919 179.39062,471.17637 179.25,471.4375 C 179.11328,471.69462 179.03125,471.9679 179.03125,472.28125 C 179.03125,472.81558 179.22656,473.24825 179.59375,473.59375 C 179.96094,473.93524 180.47265,474.12499 181.15625,474.125 C 181.57031,474.125 181.95312,474.04687 182.3125,473.90625 C 182.67578,473.76564 183.04687,473.52899 183.4375,473.1875 C 183.46875,473.48881 183.54687,473.74376 183.65625,473.96875 L 184.75,473.96875 C 184.61718,473.72368 184.54687,473.48391 184.5,473.21875 C 184.45703,472.94958 184.43749,472.28965 184.4375,471.28125 L 184.4375,469.84375 C 184.43749,469.36165 184.41015,469.02857 184.375,468.84375 C 184.31249,468.54646 184.21874,468.31785 184.0625,468.125 C 183.90624,467.92815 183.64452,467.75357 183.3125,467.625 C 182.98046,467.49645 182.56249,467.43751 182.03125,467.4375 z M 222.8125,467.4375 C 222.48828,467.43751 222.16015,467.47411 221.875,467.5625 C 221.59375,467.64687 221.3828,467.75046 221.21875,467.875 C 221,468.03571 220.8164,468.25494 220.6875,468.5 C 220.5625,468.74106 220.49999,468.99603 220.5,469.28125 C 220.5,469.59462 220.59765,469.86388 220.75,470.125 C 220.90625,470.38212 221.10937,470.60135 221.40625,470.75 C 221.70703,470.89463 222.2578,471.04913 223.03125,471.25 C 223.60547,471.39865 223.94921,471.5286 224.09375,471.625 C 224.30078,471.76561 224.40624,471.9737 224.40625,472.21875 C 224.40625,472.49194 224.29686,472.73261 224.0625,472.9375 C 223.82812,473.13838 223.48436,473.21877 223,473.21875 C 222.51953,473.21875 222.14452,473.10399 221.875,472.875 C 221.60937,472.646 221.43359,472.33613 221.375,471.90625 L 220.34375,472.0625 C 220.46094,472.74146 220.73437,473.24823 221.15625,473.59375 C 221.58203,473.93925 222.1914,474.12499 223,474.125 C 223.48828,474.125 223.92577,474.04774 224.3125,473.875 C 224.69921,473.69823 224.98436,473.44239 225.1875,473.125 C 225.39453,472.8036 225.49999,472.45531 225.5,472.09375 C 225.49999,471.72414 225.41796,471.40535 225.25,471.15625 C 225.08203,470.90717 224.85936,470.72233 224.5625,470.59375 C 224.26953,470.46118 223.74608,470.29865 223,470.09375 C 222.48437,469.94912 222.16796,469.85267 222.0625,469.8125 C 221.8789,469.73617 221.74218,469.64776 221.65625,469.53125 C 221.57031,469.41876 221.53124,469.29686 221.53125,469.15625 C 221.53125,468.93529 221.63671,468.72721 221.84375,468.5625 C 222.05078,468.39779 222.39062,468.31252 222.875,468.3125 C 223.28515,468.31251 223.58983,468.40895 223.8125,468.59375 C 224.03906,468.77856 224.20311,469.04557 224.25,469.375 L 225.28125,469.21875 C 225.21484,468.80495 225.08202,468.49507 224.90625,468.25 C 224.73046,468.00092 224.46483,467.80089 224.09375,467.65625 C 223.72656,467.51163 223.30077,467.43751 222.8125,467.4375 z M 232.375,467.4375 C 232.1289,467.43751 231.89454,467.51163 231.6875,467.65625 C 231.48437,467.80089 231.27344,468.07727 231.03125,468.53125 L 231.03125,467.5625 L 230.0625,467.5625 L 230.0625,473.96875 L 231.125,473.96875 L 231.125,470.625 C 231.125,470.16701 231.19532,469.72943 231.3125,469.34375 C 231.39062,469.09065 231.50391,468.92187 231.6875,468.78125 C 231.87109,468.63663 232.08204,468.56251 232.3125,468.5625 C 232.57031,468.56251 232.83594,468.62456 233.09375,468.78125 L 233.46875,467.78125 C 233.10156,467.54824 232.73047,467.43751 232.375,467.4375 z M 236.65625,467.4375 C 235.79687,467.43751 235.10155,467.71793 234.5625,468.3125 C 234.02344,468.90709 233.74999,469.76707 233.75,470.84375 C 233.75,471.88428 233.99999,472.67148 234.53125,473.25 C 235.0664,473.8245 235.80858,474.12499 236.71875,474.125 C 237.4414,474.125 238.03514,473.92406 238.5,473.5625 C 238.96484,473.20093 239.26561,472.71736 239.4375,472.0625 L 238.34375,471.90625 C 238.18359,472.36425 237.96093,472.69735 237.6875,472.90625 C 237.41406,473.11516 237.10546,473.21877 236.71875,473.21875 C 236.19922,473.21875 235.7539,473.02988 235.40625,472.65625 C 235.05859,472.28262 234.8828,471.76555 234.84375,471.0625 L 239.46875,471.0625 C 239.47265,470.93394 239.46874,470.81428 239.46875,470.75 C 239.46874,469.6934 239.21483,468.89504 238.6875,468.3125 C 238.16015,467.72997 237.48827,467.43751 236.65625,467.4375 z M 243.40625,467.4375 C 242.87109,467.43751 242.40624,467.50359 242,467.65625 C 241.59375,467.8049 241.27734,468.03128 241.0625,468.3125 C 240.84766,468.58971 240.68749,468.95229 240.59375,469.40625 L 241.625,469.53125 C 241.73828,469.07728 241.92187,468.77053 242.15625,468.59375 C 242.39453,468.41297 242.7539,468.34375 243.25,468.34375 C 243.78125,468.34376 244.16796,468.44242 244.4375,468.6875 C 244.63671,468.86829 244.74999,469.18308 244.75,469.625 C 244.75,469.66518 244.7539,469.75761 244.75,469.90625 C 244.34765,470.05088 243.72655,470.1768 242.875,470.28125 C 242.45703,470.33348 242.14452,470.38125 241.9375,470.4375 C 241.65625,470.51785 241.38281,470.65583 241.15625,470.8125 C 240.93359,470.96919 240.76562,471.17637 240.625,471.4375 C 240.48828,471.69462 240.40625,471.9679 240.40625,472.28125 C 240.40625,472.81558 240.60156,473.24825 240.96875,473.59375 C 241.33594,473.93524 241.84765,474.12499 242.53125,474.125 C 242.94531,474.125 243.32812,474.04687 243.6875,473.90625 C 244.05078,473.76564 244.45312,473.52899 244.84375,473.1875 C 244.875,473.48881 244.92187,473.74376 245.03125,473.96875 L 246.15625,473.96875 C 246.02343,473.72368 245.92186,473.48391 245.875,473.21875 C 245.83203,472.94958 245.81249,472.28965 245.8125,471.28125 L 245.8125,469.84375 C 245.81249,469.36165 245.78515,469.02857 245.75,468.84375 C 245.68749,468.54646 245.59374,468.31785 245.4375,468.125 C 245.28124,467.92815 245.01952,467.75357 244.6875,467.625 C 244.35546,467.49645 243.93749,467.43751 243.40625,467.4375 z M 250.28125,467.4375 C 249.86718,467.43751 249.51171,467.52591 249.1875,467.71875 C 248.86328,467.90758 248.60156,468.1554 248.40625,468.46875 L 248.40625,467.5625 L 247.4375,467.5625 L 247.4375,473.96875 L 248.5,473.96875 L 248.5,470.65625 C 248.5,470.07372 248.57421,469.62184 248.6875,469.3125 C 248.80078,469.00316 248.96875,468.7857 249.21875,468.625 C 249.47265,468.46431 249.76562,468.37501 250.0625,468.375 C 250.45312,468.37501 250.73437,468.47772 250.90625,468.71875 C 251.07812,468.9598 251.15624,469.33039 251.15625,469.8125 L 251.15625,473.96875 L 252.21875,473.96875 L 252.21875,470.25 C 252.21874,469.59113 252.33593,469.10981 252.625,468.8125 C 252.91406,468.51119 253.28124,468.37501 253.71875,468.375 C 253.96093,468.37501 254.1953,468.41474 254.375,468.53125 C 254.55468,468.64776 254.65233,468.80716 254.71875,469 C 254.78905,469.18883 254.84374,469.50363 254.84375,469.9375 L 254.84375,473.96875 L 255.875,473.96875 L 255.875,469.59375 C 255.87499,468.86257 255.70702,468.31829 255.375,467.96875 C 255.04296,467.61522 254.58593,467.43751 253.96875,467.4375 C 253.17968,467.43751 252.52343,467.81526 252.03125,468.5625 C 251.91015,468.20897 251.70312,467.91562 251.40625,467.71875 C 251.11328,467.5219 250.74218,467.43751 250.28125,467.4375 z M 111.5625,467.5625 L 113.6875,470.65625 L 111.40625,473.96875 L 112.6875,473.96875 L 114.3125,471.4375 L 114.65625,472 L 115.9375,473.96875 L 117.21875,473.96875 L 114.90625,470.59375 L 117.0625,467.5625 L 115.8125,467.5625 L 114.75,469.09375 C 114.60547,469.29865 114.45312,469.51609 114.28125,469.78125 C 114.17187,469.58841 114.02343,469.34775 113.84375,469.0625 L 112.875,467.5625 L 111.5625,467.5625 z M 151.03125,467.5625 L 151.03125,468.8125 L 152.21875,468.8125 L 152.21875,467.5625 L 151.03125,467.5625 z M 236.65625,468.3125 C 237.1914,468.31251 237.6328,468.51969 237.96875,468.9375 C 238.1875,469.20668 238.32811,469.61792 238.375,470.15625 L 234.875,470.15625 C 234.91015,469.59782 235.10937,469.14597 235.4375,468.8125 C 235.76953,468.47905 236.17187,468.31252 236.65625,468.3125 z M 127.03125,468.34375 C 127.51172,468.34376 127.92187,468.52771 128.25,468.9375 C 128.57812,469.34729 128.74999,469.9992 128.75,470.875 C 128.75,471.67047 128.57421,472.26654 128.25,472.65625 C 127.92968,473.04193 127.55469,473.21877 127.09375,473.21875 C 126.63672,473.21875 126.24219,473.03078 125.90625,472.625 C 125.57031,472.21923 125.375,471.60084 125.375,470.78125 C 125.375,469.93356 125.53125,469.29996 125.84375,468.90625 C 126.16015,468.51254 126.5625,468.34375 127.03125,468.34375 z M 146.40625,468.34375 C 146.88672,468.34376 147.26562,468.52771 147.59375,468.9375 C 147.92187,469.34729 148.09374,469.9992 148.09375,470.875 C 148.09375,471.67047 147.94921,472.26654 147.625,472.65625 C 147.30468,473.04193 146.89843,473.21877 146.4375,473.21875 C 145.98047,473.21875 145.58593,473.03078 145.25,472.625 C 144.91406,472.21923 144.74999,471.60084 144.75,470.78125 C 144.75,469.93356 144.90624,469.29996 145.21875,468.90625 C 145.53515,468.51254 145.93749,468.34375 146.40625,468.34375 z M 168.59375,468.34375 C 169.11328,468.34376 169.52734,468.52771 169.875,468.9375 C 170.22656,469.34327 170.40624,469.95856 170.40625,470.75 C 170.40624,471.58966 170.22265,472.21521 169.875,472.625 C 169.52734,473.03479 169.11718,473.21877 168.59375,473.21875 C 168.0664,473.21875 167.6289,473.03078 167.28125,472.625 C 166.93359,472.21522 166.74999,471.60082 166.75,470.78125 C 166.75,469.96168 166.93359,469.34328 167.28125,468.9375 C 167.6289,468.53174 168.0664,468.34375 168.59375,468.34375 z M 120.5,469.65625 C 121.00781,469.65625 121.44531,469.81476 121.78125,470.15625 C 122.12109,470.49774 122.28124,470.94649 122.28125,471.46875 C 122.28124,471.98299 122.10937,472.3853 121.78125,472.71875 C 121.45312,473.0522 121.03515,473.21875 120.53125,473.21875 C 120.20703,473.21875 119.90624,473.15667 119.625,473 C 119.34375,472.8393 119.14453,472.60177 119,472.3125 C 118.85937,472.02324 118.78125,471.74684 118.78125,471.4375 C 118.78125,470.9313 118.95703,470.49373 119.28125,470.15625 C 119.60937,469.81878 120.0039,469.65625 120.5,469.65625 z M 198.625,469.90625 L 200.625,469.90625 C 201.17187,469.90625 201.58592,469.93083 201.875,470.03125 C 202.16796,470.12767 202.39844,470.31744 202.5625,470.5625 C 202.72656,470.80355 202.8125,471.07681 202.8125,471.40625 C 202.81249,471.68748 202.73828,471.9393 202.625,472.15625 C 202.51171,472.36918 202.39452,472.54375 202.21875,472.65625 C 202.04296,472.76874 201.82421,472.85805 201.5625,472.90625 C 201.41406,472.93437 201.14843,472.93749 200.78125,472.9375 L 198.625,472.9375 L 198.625,469.90625 z M 183.375,470.75 L 183.375,471.15625 C 183.375,471.63433 183.30077,472.00494 183.1875,472.25 C 183.03906,472.56738 182.8164,472.81519 182.5,473 C 182.18359,473.18079 181.81249,473.28124 181.40625,473.28125 C 180.99609,473.28125 180.68359,473.1616 180.46875,472.96875 C 180.25781,472.77591 180.15624,472.53927 180.15625,472.25 C 180.15625,472.06118 180.21484,471.90268 180.3125,471.75 C 180.41015,471.59332 180.53906,471.45534 180.71875,471.375 C 180.89844,471.29465 181.1914,471.25178 181.625,471.1875 C 182.39062,471.07501 182.99218,470.9107 183.375,470.75 z M 244.75,470.75 L 244.75,471.15625 C 244.75,471.63433 244.67577,472.00494 244.5625,472.25 C 244.41406,472.56738 244.1914,472.81519 243.875,473 C 243.55859,473.18079 243.18749,473.28124 242.78125,473.28125 C 242.37109,473.28125 242.05859,473.1616 241.84375,472.96875 C 241.63281,472.77591 241.53124,472.53927 241.53125,472.25 C 241.53125,472.06118 241.58984,471.90268 241.6875,471.75 C 241.78515,471.59332 241.91406,471.45534 242.09375,471.375 C 242.27344,471.29465 242.59765,471.25178 243.03125,471.1875 C 243.79687,471.07501 244.36718,470.9107 244.75,470.75 z M 151.03125,472.75 L 151.03125,473.96875 L 152.21875,473.96875 L 152.21875,472.75 L 151.03125,472.75 z M 257.78125,472.75 L 257.78125,473.96875 L 259,473.96875 L 259,472.75 L 257.78125,472.75 z M 190.53125,480.40625 C 189.95312,480.40626 189.41015,480.51789 188.9375,480.71875 C 188.46484,480.91963 188.12109,481.20406 187.875,481.59375 C 187.62891,481.97944 187.49999,482.39782 187.5,482.84375 C 187.5,483.24952 187.61328,483.63931 187.8125,483.96875 C 188.01562,484.29417 188.30859,484.5603 188.71875,484.78125 C 189.03515,484.95401 189.58593,485.14691 190.375,485.34375 C 191.16406,485.53659 191.67577,485.65759 191.90625,485.75 C 192.26562,485.89062 192.53124,486.07235 192.6875,486.28125 C 192.84374,486.48615 192.90624,486.72278 192.90625,487 C 192.90624,487.27319 192.85155,487.517 192.6875,487.75 C 192.52734,487.979 192.26952,488.17991 191.9375,488.3125 C 191.60546,488.44508 191.21483,488.5 190.78125,488.5 C 190.29297,488.5 189.85937,488.42275 189.46875,488.25 C 189.07812,488.07323 188.78124,487.84371 188.59375,487.5625 C 188.41015,487.27726 188.30078,486.91067 188.25,486.46875 L 187.1875,486.5625 C 187.20312,487.15307 187.35937,487.6862 187.65625,488.15625 C 187.95703,488.62228 188.35156,488.98575 188.875,489.21875 C 189.40234,489.45176 190.0664,489.56248 190.84375,489.5625 C 191.45703,489.5625 192.01171,489.44774 192.5,489.21875 C 192.99218,488.98574 193.36327,488.66382 193.625,488.25 C 193.88671,487.83218 193.99999,487.3763 194,486.90625 C 193.99999,486.43219 193.89452,486.01782 193.65625,485.65625 C 193.41796,485.29066 193.06249,484.98705 192.5625,484.75 C 192.21874,484.5893 191.58202,484.40043 190.65625,484.1875 C 189.73437,483.97056 189.15624,483.76739 188.9375,483.5625 C 188.71484,483.35761 188.59374,483.09864 188.59375,482.78125 C 188.59375,482.41566 188.74999,482.10089 189.0625,481.84375 C 189.3789,481.58262 189.87499,481.43751 190.5625,481.4375 C 191.22265,481.43751 191.72655,481.58977 192.0625,481.875 C 192.40234,482.16025 192.59765,482.59784 192.65625,483.15625 L 193.75,483.0625 C 193.73046,482.54425 193.60546,482.06604 193.34375,481.65625 C 193.08202,481.24647 192.70702,480.95891 192.21875,480.75 C 191.73437,480.53708 191.16796,480.40626 190.53125,480.40625 z M 107.9375,480.53125 C 107.3125,480.53126 106.78906,480.71701 106.375,481.0625 C 105.96484,481.40801 105.64843,481.89247 105.4375,482.53125 C 105.23047,483.16602 105.125,483.98672 105.125,485.03125 C 105.125,486.69048 105.40234,487.88981 105.96875,488.625 C 106.4414,489.23566 107.10937,489.56248 107.9375,489.5625 C 108.5664,489.5625 109.08984,489.37676 109.5,489.03125 C 109.91406,488.68173 110.19921,488.19725 110.40625,487.5625 C 110.61328,486.92372 110.71874,486.06778 110.71875,485.03125 C 110.71874,484.15544 110.66015,483.48301 110.53125,482.96875 C 110.40234,482.4505 110.22655,482.01383 110,481.65625 C 109.77343,481.29468 109.5039,481.00134 109.15625,480.8125 C 108.80859,480.61967 108.39843,480.53125 107.9375,480.53125 z M 120.5,480.53125 C 119.7539,480.53126 119.16796,480.7496 118.71875,481.1875 C 118.26953,481.62542 118.0625,482.1697 118.0625,482.8125 C 118.0625,483.23836 118.16406,483.60092 118.375,483.90625 C 118.58594,484.21159 118.90625,484.46028 119.34375,484.625 C 118.82031,484.76562 118.41015,485.01657 118.125,485.40625 C 117.84375,485.79193 117.6875,486.26926 117.6875,486.84375 C 117.6875,487.61511 117.94922,488.26298 118.46875,488.78125 C 118.98828,489.29549 119.68359,489.56248 120.53125,489.5625 C 121.3789,489.5625 122.07421,489.29548 122.59375,488.78125 C 123.11328,488.26701 123.37499,487.63028 123.375,486.875 C 123.37499,486.32862 123.21483,485.86247 122.9375,485.46875 C 122.66406,485.07504 122.27734,484.80177 121.75,484.625 C 122.17578,484.46029 122.48046,484.20758 122.6875,483.90625 C 122.89843,483.60093 122.99999,483.25354 123,482.84375 C 122.99999,482.20096 122.76952,481.66471 122.3125,481.21875 C 121.85546,480.7688 121.24999,480.53125 120.5,480.53125 z M 128.65625,480.5625 L 128.65625,483.75 C 128.47265,483.48887 128.23047,483.25445 127.9375,483.09375 C 127.64453,482.92904 127.3125,482.84377 126.9375,482.84375 C 126.42578,482.84376 125.97656,483.00404 125.5625,483.28125 C 125.14844,483.55846 124.83203,483.94648 124.625,484.46875 C 124.41797,484.98701 124.3125,485.57996 124.3125,486.21875 C 124.3125,486.8736 124.42969,487.4313 124.65625,487.9375 C 124.88672,488.43969 125.21094,488.84378 125.625,489.125 C 126.04297,489.40622 126.47266,489.5625 126.96875,489.5625 C 127.73437,489.5625 128.32421,489.22852 128.71875,488.59375 L 128.71875,489.40625 L 129.6875,489.40625 L 129.6875,480.5625 L 128.65625,480.5625 z M 140.65625,480.5625 L 136.71875,486.28125 L 136.71875,487.28125 L 140.46875,487.28125 L 140.46875,489.40625 L 141.5,489.40625 L 141.5,487.28125 L 142.65625,487.28125 L 142.65625,486.28125 L 141.5,486.28125 L 141.5,480.5625 L 140.65625,480.5625 z M 148,480.5625 L 148,483.75 C 147.8164,483.48887 147.60546,483.25445 147.3125,483.09375 C 147.01953,482.92904 146.65624,482.84377 146.28125,482.84375 C 145.76953,482.84376 145.32031,483.00404 144.90625,483.28125 C 144.49219,483.55846 144.17578,483.94648 143.96875,484.46875 C 143.76172,484.98701 143.65625,485.57996 143.65625,486.21875 C 143.65625,486.8736 143.77343,487.4313 144,487.9375 C 144.23047,488.43969 144.55468,488.84378 144.96875,489.125 C 145.38672,489.40622 145.84765,489.5625 146.34375,489.5625 C 147.10937,489.5625 147.69921,489.22852 148.09375,488.59375 L 148.09375,489.40625 L 149.0625,489.40625 L 149.0625,480.5625 L 148,480.5625 z M 157.46875,480.5625 L 157.46875,489.40625 L 158.5625,489.40625 L 158.5625,481.875 L 161.0625,489.40625 L 162.09375,489.40625 L 164.59375,482 L 164.59375,489.40625 L 165.6875,489.40625 L 165.6875,480.5625 L 164.15625,480.5625 L 162.09375,486.71875 C 161.88671,487.34146 161.72265,487.8036 161.625,488.125 C 161.53906,487.83574 161.40624,487.39505 161.21875,486.8125 L 159.1875,480.5625 L 157.46875,480.5625 z M 226.25,480.5625 L 226.25,489.40625 L 229.53125,489.40625 C 230.07812,489.40625 230.53124,489.34641 230.90625,489.25 C 231.28515,489.14956 231.62499,489.00535 231.875,488.8125 C 232.12499,488.61966 232.33202,488.35353 232.5,488 C 232.67187,487.64244 232.74999,487.25755 232.75,486.84375 C 232.74999,486.32951 232.59374,485.87765 232.3125,485.5 C 232.03515,485.12236 231.64452,484.84418 231.125,484.6875 C 231.52734,484.48261 231.83202,484.23971 232.03125,483.90625 C 232.23046,483.5728 232.34374,483.19016 232.34375,482.8125 C 232.34374,482.40674 232.22655,482.02586 232,481.65625 C 231.77734,481.28263 231.46092,481.02052 231.0625,480.84375 C 230.66796,480.66297 230.12499,480.5625 229.46875,480.5625 L 226.25,480.5625 z M 256.875,480.5625 L 256.875,489.40625 L 257.84375,489.40625 L 257.84375,488.59375 C 258.26172,489.2245 258.82812,489.5625 259.5625,489.5625 C 259.70655,489.5625 259.86398,489.52279 260,489.5 L 260,488.5625 C 259.83687,488.62694 259.68278,488.65625 259.5,488.65625 C 258.93359,488.65625 258.45703,488.37092 258.125,487.8125 C 257.92187,487.47101 257.84375,486.92358 257.84375,486.15625 C 257.84375,485.37686 258.00781,484.78479 258.34375,484.375 C 258.67968,483.9612 259.07031,483.75 259.53125,483.75 C 259.69733,483.75 259.85197,483.79122 260,483.84375 L 260,482.875 C 259.87753,482.85725 259.75221,482.84376 259.625,482.84375 C 258.93359,482.84376 258.38281,483.14427 257.9375,483.71875 L 257.9375,480.5625 L 256.875,480.5625 z M 196.6875,480.78125 L 195.625,481.40625 L 195.625,483 L 194.875,483 L 194.875,483.84375 L 195.625,483.84375 L 195.625,487.53125 C 195.625,488.18209 195.69532,488.60761 195.78125,488.8125 C 195.86719,489.01338 196.00782,489.18795 196.21875,489.3125 C 196.42969,489.43704 196.71094,489.50001 197.09375,489.5 C 197.32812,489.5 197.60938,489.43928 197.90625,489.375 L 197.75,488.4375 C 197.55859,488.46562 197.39844,488.46874 197.28125,488.46875 C 197.125,488.46875 196.99219,488.45847 196.90625,488.40625 C 196.82422,488.35402 196.78907,488.27589 196.75,488.1875 C 196.71484,488.09912 196.6875,487.9031 196.6875,487.59375 L 196.6875,483.84375 L 197.75,483.84375 L 197.75,483 L 196.6875,483 L 196.6875,480.78125 z M 107.90625,481.4375 C 108.39843,481.43751 108.82812,481.67818 109.15625,482.15625 C 109.48828,482.63434 109.65624,483.57693 109.65625,485.03125 C 109.65624,486.47755 109.48827,487.4554 109.15625,487.9375 C 108.82812,488.4196 108.42187,488.65626 107.9375,488.65625 C 107.45312,488.65625 107.05078,488.41557 106.71875,487.9375 C 106.39062,487.4554 106.21875,486.48158 106.21875,485.03125 C 106.21875,483.58094 106.38671,482.60084 106.75,482.0625 C 107.03906,481.64067 107.42187,481.43749 107.90625,481.4375 z M 120.25,481.4375 C 120.34204,481.42093 120.43066,481.4375 120.53125,481.4375 C 120.92968,481.43751 121.26562,481.57057 121.53125,481.84375 C 121.80078,482.11293 121.93749,482.44601 121.9375,482.84375 C 121.9375,483.22542 121.79296,483.54735 121.53125,483.8125 C 121.27343,484.07364 120.93749,484.18752 120.53125,484.1875 C 120.11328,484.18751 119.79296,484.07768 119.53125,483.8125 C 119.26953,483.54735 119.125,483.19907 119.125,482.78125 C 119.125,482.41165 119.26562,482.07766 119.53125,481.8125 C 119.73047,481.61364 119.97388,481.48722 120.25,481.4375 z M 227.40625,481.625 L 229.125,481.625 C 229.74218,481.62501 230.15233,481.66565 230.40625,481.75 C 230.66015,481.83036 230.86327,481.96253 231,482.1875 C 231.13671,482.40847 231.21874,482.67548 231.21875,482.96875 C 231.21874,483.2781 231.14842,483.54511 231,483.75 C 230.85546,483.9549 230.6328,484.09912 230.34375,484.1875 C 230.125,484.2558 229.75389,484.28125 229.25,484.28125 L 227.40625,484.28125 L 227.40625,481.625 z M 140.46875,482.3125 L 140.46875,486.28125 L 137.75,486.28125 L 140.46875,482.3125 z M 133.875,482.84375 C 133.33984,482.84376 132.86327,482.98887 132.40625,483.25 C 131.95312,483.50713 131.59765,483.88801 131.375,484.40625 C 131.15234,484.92451 131.03125,485.52775 131.03125,486.21875 C 131.03125,487.28741 131.29687,488.11299 131.8125,488.6875 C 132.33203,489.25798 133.02343,489.5625 133.875,489.5625 C 134.55468,489.5625 135.1289,489.3513 135.59375,488.9375 C 136.06249,488.51968 136.35546,487.92272 136.46875,487.1875 L 135.4375,487.0625 C 135.36328,487.60486 135.18358,487.98887 134.90625,488.25 C 134.6289,488.51114 134.28905,488.65624 133.875,488.65625 C 133.35937,488.65625 132.91406,488.45221 132.59375,488.0625 C 132.27344,487.6728 132.12499,487.04724 132.125,486.1875 C 132.125,485.33981 132.29296,484.73344 132.625,484.34375 C 132.95703,483.95004 133.37499,483.75 133.90625,483.75 C 134.25781,483.75001 134.5664,483.84556 134.8125,484.0625 C 135.0625,484.27945 135.24608,484.60139 135.34375,485.03125 L 136.375,484.875 C 136.2539,484.22819 135.96093,483.72452 135.53125,483.375 C 135.10156,483.02147 134.55077,482.84377 133.875,482.84375 z M 170.15625,482.84375 C 169.75,482.84376 169.41015,482.92903 169.125,483.09375 C 168.83984,483.25446 168.5703,483.51835 168.34375,483.84375 L 168.34375,483 L 167.375,483 L 167.375,491.84375 L 168.4375,491.84375 L 168.4375,488.75 C 168.61719,488.98302 168.84765,489.15984 169.125,489.3125 C 169.40625,489.46516 169.74218,489.5625 170.09375,489.5625 C 170.57421,489.5625 171.00389,489.4022 171.4375,489.125 C 171.87499,488.84378 172.21092,488.45978 172.4375,487.9375 C 172.66796,487.41121 172.78124,486.81109 172.78125,486.15625 C 172.78124,485.54559 172.67577,484.97897 172.46875,484.46875 C 172.26171,483.95452 171.96874,483.56249 171.5625,483.28125 C 171.15625,483.00003 170.68749,482.84377 170.15625,482.84375 z M 176.625,482.84375 C 175.76562,482.84376 175.07032,483.15541 174.53125,483.75 C 173.99219,484.34459 173.71876,485.17333 173.71875,486.25 C 173.71875,487.29053 173.96876,488.10898 174.5,488.6875 C 175.03515,489.262 175.77735,489.5625 176.6875,489.5625 C 177.41015,489.5625 178.00391,489.36157 178.46875,489 C 178.93359,488.63843 179.23438,488.12362 179.40625,487.46875 L 178.34375,487.34375 C 178.18359,487.80175 177.96094,488.13485 177.6875,488.34375 C 177.41406,488.55266 177.07422,488.65624 176.6875,488.65625 C 176.16797,488.65625 175.72266,488.46739 175.375,488.09375 C 175.02734,487.72012 174.85157,487.17181 174.8125,486.46875 L 179.4375,486.46875 C 179.4414,486.34019 179.46875,486.25179 179.46875,486.1875 C 179.46874,485.1309 179.18359,484.3013 178.65625,483.71875 C 178.1289,483.13622 177.45703,482.84377 176.625,482.84375 z M 183.03125,482.84375 C 182.48047,482.84376 182.0039,483.00004 181.59375,483.28125 C 181.1875,483.56248 180.87109,483.95051 180.65625,484.46875 C 180.44141,484.98299 180.34374,485.54561 180.34375,486.15625 C 180.34375,487.04412 180.59374,487.80273 181.0625,488.4375 C 181.53125,489.07227 182.17577,489.40624 183.03125,489.40625 C 183.71875,489.40625 184.28905,489.12092 184.75,488.5625 C 184.7539,489.26958 184.74218,489.74778 184.6875,489.96875 C 184.59375,490.33032 184.42186,490.61164 184.15625,490.8125 C 183.89062,491.01337 183.48827,491.09374 183,491.09375 C 182.54687,491.09375 182.19921,491.01339 181.9375,490.8125 C 181.74219,490.66385 181.63671,490.41917 181.59375,490.09375 L 180.5625,489.9375 C 180.54687,490.62851 180.76171,491.12727 181.21875,491.46875 C 181.67578,491.81425 182.28905,491.99998 183.03125,492 C 183.65625,492 184.16796,491.86606 184.59375,491.625 C 185.02343,491.38395 185.33593,491.07406 185.53125,490.65625 C 185.73046,490.24245 185.84374,489.5276 185.84375,488.53125 L 185.84375,483 L 184.84375,483 L 184.84375,483.78125 C 184.36718,483.1706 183.76561,482.84377 183.03125,482.84375 z M 201.0625,482.84375 C 200.8164,482.84376 200.58203,482.91789 200.375,483.0625 C 200.17187,483.20714 199.96093,483.51478 199.71875,483.96875 L 199.71875,483 L 198.75,483 L 198.75,489.40625 L 199.8125,489.40625 L 199.8125,486.0625 C 199.8125,485.60451 199.88281,485.16694 200,484.78125 C 200.07812,484.52815 200.1914,484.32813 200.375,484.1875 C 200.55859,484.04288 200.76953,483.96874 201,483.96875 C 201.25781,483.96876 201.52343,484.06207 201.78125,484.21875 L 202.15625,483.21875 C 201.78906,482.98574 201.41796,482.84377 201.0625,482.84375 z M 205.34375,482.84375 C 204.48437,482.84376 203.78907,483.15541 203.25,483.75 C 202.71094,484.34459 202.43751,485.17333 202.4375,486.25 C 202.4375,487.29053 202.68751,488.10898 203.21875,488.6875 C 203.7539,489.262 204.4961,489.5625 205.40625,489.5625 C 206.1289,489.5625 206.72266,489.36157 207.1875,489 C 207.65234,488.63843 207.95313,488.12362 208.125,487.46875 L 207.03125,487.34375 C 206.87109,487.80175 206.64844,488.13485 206.375,488.34375 C 206.10156,488.55266 205.79297,488.65624 205.40625,488.65625 C 204.88672,488.65625 204.44141,488.46739 204.09375,488.09375 C 203.74609,487.72012 203.57032,487.17181 203.53125,486.46875 L 208.15625,486.46875 C 208.16015,486.34019 208.15625,486.25179 208.15625,486.1875 C 208.15624,485.1309 207.90234,484.3013 207.375,483.71875 C 206.84765,483.13622 206.17578,482.84377 205.34375,482.84375 z M 212.09375,482.84375 C 211.55859,482.84376 211.09374,482.9411 210.6875,483.09375 C 210.28125,483.2424 209.96484,483.43754 209.75,483.71875 C 209.53516,483.99596 209.37499,484.38976 209.28125,484.84375 L 210.3125,484.96875 C 210.42578,484.51478 210.60937,484.20803 210.84375,484.03125 C 211.08203,483.85047 211.4414,483.75001 211.9375,483.75 C 212.46875,483.75001 212.85546,483.87993 213.125,484.125 C 213.32421,484.30579 213.43749,484.62059 213.4375,485.0625 C 213.4375,485.10268 213.44139,485.19512 213.4375,485.34375 C 213.03515,485.48838 212.41405,485.61431 211.5625,485.71875 C 211.14453,485.77098 210.83202,485.81876 210.625,485.875 C 210.34375,485.95535 210.0703,486.06206 209.84375,486.21875 C 209.62109,486.37544 209.45312,486.61387 209.3125,486.875 C 209.17578,487.13212 209.09374,487.40538 209.09375,487.71875 C 209.09375,488.25308 209.28905,488.68575 209.65625,489.03125 C 210.02344,489.37274 210.53515,489.5625 211.21875,489.5625 C 211.63281,489.5625 212.01561,489.48435 212.375,489.34375 C 212.73828,489.20314 213.14061,488.9665 213.53125,488.625 C 213.5625,488.92631 213.60936,489.18126 213.71875,489.40625 L 214.84375,489.40625 C 214.71093,489.16118 214.60936,488.89017 214.5625,488.625 C 214.51953,488.35583 214.49999,487.72713 214.5,486.71875 L 214.5,485.28125 C 214.49999,484.79915 214.47264,484.46607 214.4375,484.28125 C 214.37499,483.98396 214.28124,483.72411 214.125,483.53125 C 213.96874,483.3344 213.70702,483.19108 213.375,483.0625 C 213.04296,482.93395 212.62499,482.84377 212.09375,482.84375 z M 218.96875,482.84375 C 218.55468,482.84376 218.19921,482.96341 217.875,483.15625 C 217.55078,483.34508 217.28906,483.5929 217.09375,483.90625 L 217.09375,483 L 216.125,483 L 216.125,489.40625 L 217.1875,489.40625 L 217.1875,486.09375 C 217.1875,485.51122 217.26171,485.05935 217.375,484.75 C 217.48828,484.44066 217.65624,484.19196 217.90625,484.03125 C 218.16015,483.87056 218.45312,483.81252 218.75,483.8125 C 219.14062,483.81251 219.42187,483.91519 219.59375,484.15625 C 219.76562,484.3973 219.84374,484.7679 219.84375,485.25 L 219.84375,489.40625 L 220.90625,489.40625 L 220.90625,485.6875 C 220.90624,485.02863 221.02343,484.54729 221.3125,484.25 C 221.60156,483.94869 221.96874,483.81252 222.40625,483.8125 C 222.64843,483.81251 222.8828,483.85225 223.0625,483.96875 C 223.24218,484.08526 223.33983,484.24467 223.40625,484.4375 C 223.47655,484.62633 223.53124,484.9411 223.53125,485.375 L 223.53125,489.40625 L 224.5625,489.40625 L 224.5625,485 C 224.56249,484.26882 224.39452,483.72452 224.0625,483.375 C 223.73046,483.02147 223.27342,482.84377 222.65625,482.84375 C 221.86718,482.84376 221.21093,483.22149 220.71875,483.96875 C 220.59765,483.61522 220.39061,483.35313 220.09375,483.15625 C 219.80078,482.9594 219.42968,482.84377 218.96875,482.84375 z M 236.8125,482.84375 C 236.27734,482.84376 235.81249,482.9411 235.40625,483.09375 C 235,483.2424 234.68359,483.43754 234.46875,483.71875 C 234.25391,483.99596 234.09374,484.38976 234,484.84375 L 235.03125,484.96875 C 235.14453,484.51478 235.32812,484.20803 235.5625,484.03125 C 235.80078,483.85047 236.16015,483.75001 236.65625,483.75 C 237.1875,483.75001 237.60546,483.87993 237.875,484.125 C 238.07421,484.30579 238.15624,484.62059 238.15625,485.0625 C 238.15625,485.10268 238.16015,485.19512 238.15625,485.34375 C 237.7539,485.48838 237.1328,485.61431 236.28125,485.71875 C 235.86328,485.77098 235.55077,485.81876 235.34375,485.875 C 235.0625,485.95535 234.82031,486.06206 234.59375,486.21875 C 234.37109,486.37544 234.17187,486.61387 234.03125,486.875 C 233.89453,487.13212 233.84375,487.40538 233.84375,487.71875 C 233.84375,488.25308 234.00781,488.68575 234.375,489.03125 C 234.74219,489.37274 235.28515,489.5625 235.96875,489.5625 C 236.38281,489.5625 236.76562,489.48435 237.125,489.34375 C 237.48828,489.20314 237.85937,488.9665 238.25,488.625 C 238.28125,488.92631 238.35937,489.18126 238.46875,489.40625 L 239.5625,489.40625 C 239.42968,489.16118 239.32811,488.89017 239.28125,488.625 C 239.23828,488.35583 239.21874,487.72713 239.21875,486.71875 L 239.21875,485.28125 C 239.21874,484.79915 239.22265,484.46607 239.1875,484.28125 C 239.12499,483.98396 238.99999,483.72411 238.84375,483.53125 C 238.68749,483.3344 238.45702,483.19108 238.125,483.0625 C 237.79296,482.93395 237.34374,482.84377 236.8125,482.84375 z M 242.90625,482.84375 C 242.58203,482.84376 242.28515,482.91161 242,483 C 241.71875,483.08437 241.50781,483.18797 241.34375,483.3125 C 241.125,483.47321 240.9414,483.6612 240.8125,483.90625 C 240.6875,484.14731 240.625,484.40225 240.625,484.6875 C 240.625,485.00087 240.6914,485.30136 240.84375,485.5625 C 241,485.81962 241.23437,486.03885 241.53125,486.1875 C 241.83203,486.33213 242.35156,486.48663 243.125,486.6875 C 243.69922,486.83615 244.07421,486.96607 244.21875,487.0625 C 244.42578,487.20311 244.53124,487.37992 244.53125,487.625 C 244.53125,487.89819 244.42187,488.13887 244.1875,488.34375 C 243.95312,488.54463 243.57812,488.65624 243.09375,488.65625 C 242.61328,488.65625 242.23828,488.5415 241.96875,488.3125 C 241.70312,488.0835 241.55859,487.74238 241.5,487.3125 L 240.4375,487.5 C 240.55469,488.17896 240.82812,488.68574 241.25,489.03125 C 241.67578,489.37675 242.28515,489.5625 243.09375,489.5625 C 243.58203,489.5625 244.01952,489.454 244.40625,489.28125 C 244.79296,489.10448 245.10937,488.87989 245.3125,488.5625 C 245.51953,488.2411 245.62499,487.89282 245.625,487.53125 C 245.62499,487.16164 245.54296,486.84283 245.375,486.59375 C 245.20703,486.34467 244.95312,486.1598 244.65625,486.03125 C 244.36328,485.89868 243.83984,485.73616 243.09375,485.53125 C 242.57812,485.38662 242.29296,485.29017 242.1875,485.25 C 242.0039,485.17367 241.86718,485.08527 241.78125,484.96875 C 241.69531,484.85626 241.625,484.70311 241.625,484.5625 C 241.625,484.34154 241.73046,484.16472 241.9375,484 C 242.14453,483.83529 242.51562,483.75 243,483.75 C 243.41015,483.75001 243.71484,483.84646 243.9375,484.03125 C 244.16406,484.21606 244.29687,484.48308 244.34375,484.8125 L 245.375,484.65625 C 245.30859,484.24245 245.17577,483.90133 245,483.65625 C 244.82421,483.40717 244.55859,483.20715 244.1875,483.0625 C 243.82031,482.91788 243.39453,482.84377 242.90625,482.84375 z M 249.40625,482.84375 C 248.54687,482.84376 247.85156,483.15541 247.3125,483.75 C 246.77344,484.34459 246.5,485.17333 246.5,486.25 C 246.5,487.29053 246.78125,488.10898 247.3125,488.6875 C 247.84765,489.262 248.55859,489.5625 249.46875,489.5625 C 250.1914,489.5625 250.78515,489.36157 251.25,489 C 251.71484,488.63843 252.04687,488.12362 252.21875,487.46875 L 251.125,487.34375 C 250.96484,487.80175 250.74218,488.13485 250.46875,488.34375 C 250.19531,488.55266 249.88671,488.65624 249.5,488.65625 C 248.98047,488.65625 248.53515,488.46739 248.1875,488.09375 C 247.83984,487.72012 247.63281,487.17181 247.59375,486.46875 L 252.25,486.46875 C 252.2539,486.34019 252.24999,486.25179 252.25,486.1875 C 252.24999,485.1309 251.99609,484.3013 251.46875,483.71875 C 250.9414,483.13622 250.23827,482.84377 249.40625,482.84375 z M 111.5625,483 L 113.6875,486.0625 L 111.40625,489.40625 L 112.6875,489.40625 L 114.3125,486.875 L 114.65625,487.40625 L 115.9375,489.40625 L 117.21875,489.40625 L 114.90625,486.03125 L 117.0625,483 L 115.8125,483 L 114.75,484.5 C 114.60547,484.7049 114.45312,484.9536 114.28125,485.21875 C 114.17187,485.02591 114.02343,484.78526 113.84375,484.5 L 112.875,483 L 111.5625,483 z M 151.03125,483 L 151.03125,484.25 L 152.21875,484.25 L 152.21875,483 L 151.03125,483 z M 170.0625,483.71875 C 170.51562,483.71876 170.89452,483.90673 171.21875,484.3125 C 171.54687,484.71827 171.71874,485.3407 171.71875,486.15625 C 171.71874,487.01198 171.55468,487.62148 171.21875,488.03125 C 170.88671,488.43702 170.46874,488.65624 170,488.65625 C 169.53906,488.65625 169.16796,488.45621 168.84375,488.0625 C 168.51953,487.66879 168.34374,487.07359 168.34375,486.25 C 168.34375,485.42642 168.53124,484.77363 168.875,484.34375 C 169.22265,483.90987 169.61327,483.71877 170.0625,483.71875 z M 127.03125,483.75 C 127.51172,483.75001 127.92187,483.96522 128.25,484.375 C 128.57812,484.78479 128.74999,485.43668 128.75,486.3125 C 128.75,487.10797 128.57421,487.6728 128.25,488.0625 C 127.92968,488.44818 127.55469,488.65624 127.09375,488.65625 C 126.63672,488.65625 126.24219,488.43703 125.90625,488.03125 C 125.57031,487.62548 125.375,487.03831 125.375,486.21875 C 125.375,485.37106 125.53125,484.73747 125.84375,484.34375 C 126.16015,483.95004 126.5625,483.75001 127.03125,483.75 z M 146.40625,483.75 C 146.88672,483.75001 147.26562,483.96522 147.59375,484.375 C 147.92187,484.78479 148.09374,485.43668 148.09375,486.3125 C 148.09375,487.10797 147.94921,487.6728 147.625,488.0625 C 147.30468,488.44818 146.89843,488.65624 146.4375,488.65625 C 145.98047,488.65625 145.58593,488.43703 145.25,488.03125 C 144.91406,487.62548 144.74999,487.03831 144.75,486.21875 C 144.75,485.37106 144.90624,484.73747 145.21875,484.34375 C 145.53515,483.95004 145.93749,483.75001 146.40625,483.75 z M 176.625,483.75 C 177.16015,483.75001 177.60156,483.9572 177.9375,484.375 C 178.15625,484.64418 178.29688,485.05539 178.34375,485.59375 L 174.875,485.59375 C 174.91015,485.03532 175.07813,484.58345 175.40625,484.25 C 175.73828,483.91655 176.14063,483.75 176.625,483.75 z M 183.125,483.75 C 183.60156,483.75001 184.0078,483.94601 184.34375,484.34375 C 184.68359,484.74149 184.84374,485.3416 184.84375,486.125 C 184.84375,486.94457 184.67186,487.55181 184.34375,487.9375 C 184.01562,488.31916 183.60936,488.5 183.125,488.5 C 182.63672,488.5 182.23046,488.32318 181.90625,487.9375 C 181.58203,487.55182 181.43749,486.93342 181.4375,486.09375 C 181.4375,485.32239 181.57812,484.73345 181.90625,484.34375 C 182.23437,483.95004 182.65624,483.75001 183.125,483.75 z M 205.34375,483.75 C 205.8789,483.75001 206.32031,483.9572 206.65625,484.375 C 206.875,484.64418 207.01563,485.05539 207.0625,485.59375 L 203.5625,485.59375 C 203.59765,485.03532 203.79688,484.58345 204.125,484.25 C 204.45703,483.91655 204.85938,483.75 205.34375,483.75 z M 249.4375,483.75 C 249.97265,483.75001 250.41406,483.9572 250.75,484.375 C 250.96875,484.64418 251.07812,485.05539 251.125,485.59375 L 247.65625,485.59375 C 247.6914,485.03532 247.89062,484.58345 248.21875,484.25 C 248.55078,483.91655 248.95312,483.75 249.4375,483.75 z M 120.5,485.09375 C 121.00781,485.09375 121.44531,485.25227 121.78125,485.59375 C 122.12109,485.93524 122.28124,486.35272 122.28125,486.875 C 122.28124,487.38924 122.10937,487.82281 121.78125,488.15625 C 121.45312,488.4897 121.03515,488.65626 120.53125,488.65625 C 120.20703,488.65625 119.90624,488.59418 119.625,488.4375 C 119.34375,488.2768 119.14453,488.03925 119,487.75 C 118.85937,487.46074 118.78125,487.15309 118.78125,486.84375 C 118.78125,486.33755 118.95703,485.93121 119.28125,485.59375 C 119.60937,485.25628 120.0039,485.09376 120.5,485.09375 z M 227.40625,485.3125 L 229.375,485.3125 C 229.92187,485.3125 230.33593,485.36831 230.625,485.46875 C 230.91796,485.56517 231.14842,485.75495 231.3125,486 C 231.47656,486.24105 231.56249,486.51431 231.5625,486.84375 C 231.56249,487.12498 231.51952,487.3768 231.40625,487.59375 C 231.29296,487.80668 231.14452,487.95001 230.96875,488.0625 C 230.79296,488.17499 230.57421,488.26428 230.3125,488.3125 C 230.16406,488.34062 229.89843,488.375 229.53125,488.375 L 227.40625,488.375 L 227.40625,485.3125 z M 213.4375,486.1875 L 213.4375,486.59375 C 213.4375,487.07183 213.36327,487.44245 213.25,487.6875 C 213.10156,488.00488 212.87889,488.2527 212.5625,488.4375 C 212.24609,488.61829 211.87499,488.6875 211.46875,488.6875 C 211.05859,488.6875 210.74608,488.59908 210.53125,488.40625 C 210.32031,488.21341 210.21874,487.97677 210.21875,487.6875 C 210.21875,487.49868 210.27734,487.34016 210.375,487.1875 C 210.47265,487.03082 210.60155,486.89285 210.78125,486.8125 C 210.96094,486.73215 211.28515,486.65804 211.71875,486.59375 C 212.48437,486.48126 213.05468,486.34821 213.4375,486.1875 z M 238.15625,486.1875 L 238.15625,486.59375 C 238.15625,487.07183 238.11327,487.44245 238,487.6875 C 237.85156,488.00488 237.59765,488.2527 237.28125,488.4375 C 236.96484,488.61829 236.62499,488.6875 236.21875,488.6875 C 235.80859,488.6875 235.49609,488.59908 235.28125,488.40625 C 235.07031,488.21341 234.96874,487.97677 234.96875,487.6875 C 234.96875,487.49868 234.99609,487.34016 235.09375,487.1875 C 235.1914,487.03082 235.35156,486.89285 235.53125,486.8125 C 235.71094,486.73215 236.0039,486.65804 236.4375,486.59375 C 237.20312,486.48126 237.77343,486.34821 238.15625,486.1875 z M 151.03125,488.15625 L 151.03125,489.40625 L 152.21875,489.40625 L 152.21875,488.15625 L 151.03125,488.15625 z " style="fill:#000000;fill-opacity:1" id="rect2455" /> </g> <g transform="matrix(0.714286,0,0,0.714286,72.100616,67.733076)" id="g4308"> <path d="M 10.628479,8.4652472 C 8.8673095,8.5903719 8.0050972,9.6618224 8.0050972,11.406299 L 8.0050972,82.02096 C 32.521811,46.530692 55.281152,23.649512 75.73056,8.788763 L 19.282623,8.788763 L 19.282623,8.4652472 L 10.990325,8.4652472 C 10.864909,8.4652472 10.74589,8.4569056 10.628479,8.4652472 z M 119.72497,14.81792 C 83.579397,52.816092 54.569378,102.04945 43.891728,125.76385 L 116.07995,125.76385 C 118.25389,125.76385 119.99994,124.06084 119.99995,121.94048 L 119.93605,15.023794 L 119.72497,14.81792 z " style="opacity:0.08196722;fill:url(#linearGradient2366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path12057" /> <path d="M 11.003129,8.0400556 C 8.9964822,8.0400556 8.0157887,9.1208673 8.0157887,10.988425 L 7.9999986,121.93277 C 7.9999986,124.06085 9.750128,125.77405 11.924069,125.77406 L 116.07588,125.77406 C 118.24982,125.77406 119.99994,124.06085 119.99995,121.93277 L 119.92103,14.623657 L 113.09906,8.0400556 L 107.9769,8.0400556 L 107.9769,8.354299 L 98.69035,8.354299 L 97.499269,10.773777 L 94.527713,10.861354 L 94.527713,8.354299 L 19.279281,8.354299 L 19.279281,8.0400556 L 11.003129,8.0400556 z " style="fill:#1c1c1c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path1410" /> <path d="M 11.003129,8.0400556 C 8.9964822,8.0400556 8.0157887,9.1208673 8.0157887,10.988425 L 7.9999986,121.93277 C 7.9999986,124.06085 9.750128,125.77405 11.924069,125.77406 L 116.07588,125.77406 C 118.24982,125.77406 119.99994,124.06085 119.99995,121.93277 L 119.92103,14.623657 L 113.09906,8.0400556 L 107.9769,8.0400556 L 107.9769,8.354299 L 98.69035,8.354299 L 97.499269,10.773777 L 94.527713,10.861354 L 94.527713,8.354299 L 19.279281,8.354299 L 19.279281,8.0400556 L 11.003129,8.0400556 z " style="opacity:0.2213115;fill:url(#linearGradient2368);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path11174" /> <path d="M 107.99408,122.78378 L 107.99408,62.851569 C 107.99408,60.811972 106.24395,59.169994 104.07001,59.169994 L 22.997753,59.169994 C 22.963786,59.169994 22.92977,59.169197 22.896011,59.169994 C 20.769396,59.220203 19.073688,60.843841 19.073688,62.851569 L 19.073688,122.78378" style="fill:url(#linearGradient2370);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.88860911;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect2296" /> <path d="M 41.808705,11.471733 L 41.599985,43.969469 C 41.599997,45.833574 42.95943,47.335102 44.647697,47.335102 L 89.05451,47.199925 C 90.742788,47.199925 92.10222,45.69841 92.10222,43.834292 L 91.999965,11.43162 L 41.808705,11.471733 z M 75.199972,19.199936 L 86.399967,19.199936 L 86.399967,41.599927 L 75.199972,41.599927 L 75.199972,19.199936 z " style="fill:url(#radialGradient2372);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect2478" /> <rect width="67.199974" height="2.799999" x="30.399988" y="72.399918" style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4174" /> <rect width="67.199974" height="2.799999" x="30.399988" y="89.199936" style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4176" /> <rect width="67.199974" height="2.799999" x="30.399988" y="105.99995" style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4178" /> </g> <rect width="146.2" height="136.3793" x="-102.66896" y="207.33794" style="fill:#ffffff;fill-opacity:1" id="rect2417" /> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/configure.svg��������������������������������������������������������0000644�0001750�0000144�00000204265�11074212714�017232� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg5676" sodipodi:version="0.32" inkscape:version="0.45+devel" sodipodi:docname="settings-wip.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" version="1.0"> <defs id="defs5678"> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4322" id="linearGradient4338" gradientUnits="userSpaceOnUse" gradientTransform="translate(-2.6296821,21.172877)" x1="5.1934605" y1="88.98745" x2="5.1934605" y2="145.64882" /> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient8081"> <stop id="stop8083" style="stop-color:#ffd700;stop-opacity:1;" offset="0" /> <stop offset="0.25242719" style="stop-color:#ffea00;stop-opacity:1;" id="stop8087" /> <stop id="stop8085" style="stop-color:#b06d00;stop-opacity:1;" offset="1" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8081" id="linearGradient7698" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0872079,0,0,1.0872079,-59.143229,30.210796)" x1="58.557281" y1="107.76735" x2="63.943447" y2="107.76735" /> <linearGradient id="linearGradient6924"> <stop style="stop-color:#ffffff;stop-opacity:0.73885351;" offset="0" id="stop6926" /> <stop id="stop10395" offset="0.24999999" style="stop-color:#ffffff;stop-opacity:0;" /> <stop id="stop10393" offset="0.5" style="stop-color:#cccccc;stop-opacity:0;" /> <stop style="stop-color:#9a9a9a;stop-opacity:1;" offset="1" id="stop6928" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6924" id="linearGradient6930" x1="8.3827581" y1="8.3199806" x2="15.021504" y2="14.958727" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.2050468,0,0,1.2050468,-2.1016162,-2.0259658)" /> <linearGradient inkscape:collect="always" id="linearGradient4529"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop4531" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop4533" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4529" id="linearGradient4640" gradientUnits="userSpaceOnUse" x1="9.3031492" y1="133.25163" x2="-5.8540711" y2="130.59308" /> <filter inkscape:collect="always" x="-0.10337079" width="1.2067416" y="-0.10337079" height="1.2067416" id="filter4626"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.42488862" id="feGaussianBlur4628" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4529" id="linearGradient4604" gradientUnits="userSpaceOnUse" x1="9.3031492" y1="133.25163" x2="-5.8540711" y2="130.59308" /> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4632"> <rect style="opacity:0.83895126;fill:url(#linearGradient4604);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4626)" id="rect4634" width="13.334369" height="3.7415669" x="-2.9263651" y="130.97287" rx="0" ry="0" inkscape:transform-center-x="-16.434708" inkscape:transform-center-y="-5.5242717" /> </clipPath> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4434" id="radialGradient4602" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.3939752,0.4817163,48.449986)" cx="4.7494926" cy="132.25244" fx="4.7494926" fy="132.25244" r="5.3222656" /> <filter inkscape:collect="always" id="filter4584"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.0829419" id="feGaussianBlur4586" /> </filter> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4588"> <path sodipodi:nodetypes="ccsccccsccc" id="path4590" d="M 13.037731,82.09273 L 18.342123,87.397123 C 21.331352,87.817882 24.407038,89.18508 26.895219,91.673261 C 29.411177,94.189215 30.893289,97.328601 31.294715,100.34972 L 56.289372,125.34436 C 62.090282,131.14528 77.301422,116.01036 71.462392,110.17133 L 46.467742,85.176682 C 43.446635,84.775254 40.307258,83.29314 37.791293,80.777186 C 35.303111,78.289007 33.935917,75.213314 33.515156,72.22409 L 28.210762,66.919697 L 13.037731,82.09273 z" style="opacity:1;fill:url(#linearGradient4529);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> </clipPath> <filter inkscape:collect="always" id="filter4551"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.15501048" id="feGaussianBlur4553" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4529" id="linearGradient4537" x1="9.3031492" y1="133.25163" x2="-5.8540711" y2="130.59308" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2575" id="linearGradient4525" x1="58.557281" y1="107.76735" x2="63.943447" y2="107.76735" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0872079,0,0,1.0872079,-71.164046,29.503688)" /> <linearGradient inkscape:collect="always" id="linearGradient4509"> <stop style="stop-color:#ffe900;stop-opacity:1;" offset="0" id="stop4511" /> <stop style="stop-color:#ffe900;stop-opacity:0;" offset="1" id="stop4513" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4509" id="linearGradient4515" x1="75.585938" y1="85.083641" x2="89.453125" y2="79.224266" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" id="filter4501"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.48665741" id="feGaussianBlur4503" /> </filter> <linearGradient inkscape:collect="always" id="linearGradient4465"> <stop style="stop-color:#ffa300;stop-opacity:1;" offset="0" id="stop4467" /> <stop style="stop-color:#ffa300;stop-opacity:0;" offset="1" id="stop4469" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4465" id="linearGradient4471" x1="83.886719" y1="77.661766" x2="86.300743" y2="86.671021" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-4)" /> <linearGradient inkscape:collect="always" id="linearGradient4434"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop4436" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop4438" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4434" id="radialGradient4440" cx="4.7494926" cy="132.25244" fx="4.7494926" fy="132.25244" r="5.3222656" gradientTransform="matrix(1,0,0,0.3939752,-7.0710881e-2,74.137847)" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" id="filter4404"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.15249406" id="feGaussianBlur4406" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4322" id="linearGradient4342" gradientUnits="userSpaceOnUse" gradientTransform="translate(1.6836694,24.213436)" x1="3.5450988" y1="107.64014" x2="3.190912" y2="104.64899" /> <linearGradient inkscape:collect="always" id="linearGradient4322"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop4324" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop4326" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4322" id="linearGradient4346" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-2.6879854,-4.0690534)" x1="5.1934605" y1="103.9544" x2="5.1348171" y2="115.65614" /> <filter inkscape:collect="always" x="-0.074906364" width="1.1498127" y="-0.11235955" height="1.224719" id="filter4238"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.1235955" id="feGaussianBlur4240" /> </filter> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4242"> <path sodipodi:nodetypes="ccsccccsccc" id="path4244" d="M -4,77.788157 L -4,83.381653 C -2.645772,85.179573 -1.744968,87.522089 -1.744968,90.145881 C -1.744968,92.798965 -2.618764,95.23565 -4,97.040192 L -4,123.39712 C -4,129.51419 12,129.55437 12,123.39712 L 12,97.040192 C 10.618764,95.23565 9.744972,92.798965 9.744968,90.145881 C 9.744968,87.522089 10.645776,85.179573 12,83.381653 L 12,77.788157 L -4,77.788157 z" style="opacity:1;fill:url(#linearGradient4338);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2575" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop2577" /> <stop offset="1" style="stop-color:#cd8000;stop-opacity:1;" id="stop2579" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2575" id="linearGradient4190" x1="36" y1="100" x2="28" y2="100" gradientUnits="userSpaceOnUse" spreadMethod="reflect" gradientTransform="matrix(0.9483145,-0.9483145,0.9483145,0.9483145,-36.790528,30.877897)" /> <linearGradient id="linearGradient6511"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6513" /> <stop style="stop-color:#393939;stop-opacity:1;" offset="1" id="stop6515" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6511" id="linearGradient6517" x1="38.074299" y1="4.2695875" x2="38.074299" y2="-10.42289" gradientUnits="userSpaceOnUse" /> <linearGradient id="linearGradient3916"> <stop style="stop-color:#d3d6d6;stop-opacity:1;" offset="0" id="stop3918" /> <stop style="stop-color:#f7f7f7;stop-opacity:1;" offset="1" id="stop3921" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3916" id="linearGradient3943" gradientUnits="userSpaceOnUse" x1="34.165016" y1="4.863008" x2="34.165016" y2="-14.006344" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3904" id="linearGradient6112" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1550511,0,0,1.1550511,-41.26484,21.101778)" x1="38.827515" y1="104.49192" x2="36.460194" y2="17.509802" /> <filter inkscape:collect="always" x="-0.26177245" width="1.5235449" y="-0.075698018" height="1.151396" id="filter3838"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.41890191" id="feGaussianBlur3840" /> </filter> <filter inkscape:collect="always" x="-0.26177242" width="1.5235448" y="-0.075698018" height="1.151396" id="filter3834"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.41890191" id="feGaussianBlur3836" /> </filter> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3850"> <path id="path3852" d="M 5.6835937,-4 C 6.7672977,-0.13901249 7.6835937,4 7.6835937,8 C 7.6835937,25.92781 15.683594,26.507796 15.683594,8 C 15.683594,4 16.274299,-0.44557713 17.683594,-4 C 16.034701,-11.286281 10.22872,-24.562662 5.6835937,-4 z" style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke:none;stroke-width:0.47008219;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" sodipodi:nodetypes="ccccc" /> </clipPath> <linearGradient id="linearGradient3904"> <stop style="stop-color:#141515;stop-opacity:1;" offset="0" id="stop3906" /> <stop style="stop-color:#535557;stop-opacity:0;" offset="1" id="stop3908" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3904" id="linearGradient6119" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1550511,0,0,1.1550511,-40.633471,-152.2263)" x1="36.460194" y1="108.28275" x2="39.503891" y2="69.41713" /> <linearGradient inkscape:collect="always" id="linearGradient3220"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3222" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3224" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3220" id="linearGradient6122" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6737798,0,0,1.4175761,-25.92314,-147.94457)" x1="36.460194" y1="89.611626" x2="36.460194" y2="17.509802" /> <radialGradient gradientUnits="userSpaceOnUse" r="139.55859" cy="112.3047" cx="102" id="radialGradient9613"> <stop id="stop9615" style="stop-color:#535557" offset="0" /> <stop id="stop9617" style="stop-color:#898A8C" offset="0.13804179" /> <stop id="stop9619" style="stop-color:#ECECEC" offset="0.20296688" /> <stop id="stop9621" style="stop-color:#FAFAFA" offset="0.33539036" /> <stop id="stop9623" style="stop-color:#FFFFFF" offset="0.39464113" /> <stop id="stop9625" style="stop-color:#FAFAFA" offset="0.5313" /> <stop id="stop9627" style="stop-color:#EBECEC" offset="0.8449" /> <stop id="stop9629" style="stop-color:#E1E2E3" offset="1" /> </radialGradient> <linearGradient inkscape:collect="always" xlink:href="#radialGradient9613" id="linearGradient6125" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8398488,-0.8398488,0.8167445,0.8167445,-15.712841,44.354581)" spreadMethod="reflect" x1="32.228344" y1="47.999996" x2="35.935673" y2="47.999996" /> <filter inkscape:collect="always" id="filter4503"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.43775175" id="feGaussianBlur4505" /> </filter> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4092"> <path style="fill:#9c0f56" d="M 59.849,42.398 C 57.593,46.987 10.717,106.259 8.774,111.066 C 4.67,121.218 16.431,133.433 25.989,124.269 C 32.291,118.227 66.959,56.111 72.129,51.415 C 75.623,48.241 95.004,41.083 95.004,41.083 L 80.924,18.23 C 80.924,18.23 62.724,36.552 59.849,42.398 z" inkscape:r_cy="true" inkscape:r_cx="true" sodipodi:nodetypes="csssscc" id="path4094" /> </clipPath> <linearGradient id="XMLID_3_" gradientUnits="userSpaceOnUse" x1="11.9185" y1="119.0576" x2="98.418404" y2="44.057598"> <stop offset="0" style="stop-color:#C9C9C9" id="stop49" /> <stop offset="0.0229" style="stop-color:#B2B2B2" id="stop51" /> <stop offset="0.05" style="stop-color:#9F9F9F" id="stop53" /> <stop offset="0.0819" style="stop-color:#929292" id="stop55" /> <stop offset="0.1225" style="stop-color:#8A8A8A" id="stop57" /> <stop offset="0.2012" style="stop-color:#888888" id="stop59" /> <stop offset="1" style="stop-color:#686868;stop-opacity:1;" id="stop63" /> </linearGradient> <linearGradient id="XMLID_11_" gradientUnits="userSpaceOnUse" x1="31.4995" y1="80.0439" x2="32.347698" y2="80.671898" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0" style="stop-color:#000000" id="stop183" /> <stop offset="1" style="stop-color:#000000;stop-opacity:0;" id="stop185" /> </linearGradient> <linearGradient id="XMLID_10_" gradientUnits="userSpaceOnUse" x1="23.9844" y1="120.7646" x2="12.7283" y2="109.8655" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0" style="stop-color:#EEEEEE" id="stop176" /> <stop offset="1" style="stop-color:#535353;stop-opacity:1;" id="stop178" /> </linearGradient> <linearGradient id="XMLID_9_" gradientUnits="userSpaceOnUse" x1="18.776899" y1="129.5986" x2="18.776899" y2="114.6055" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0" style="stop-color:#000000" id="stop169" /> <stop offset="1" style="stop-color:#000000;stop-opacity:0;" id="stop171" /> </linearGradient> <radialGradient id="XMLID_8_" cx="64.988297" cy="15.9429" r="19.6182" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0" style="stop-color:#FFFFFF" id="stop162" /> <stop offset="1" style="stop-color:#888A85" id="stop164" /> </radialGradient> <linearGradient id="XMLID_7_" gradientUnits="userSpaceOnUse" x1="40.711899" y1="75.171898" x2="48.5495" y2="80.899803" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0.213" style="stop-color:#555753" id="stop155" /> <stop offset="1" style="stop-color:#000000" id="stop157" /> </linearGradient> <linearGradient id="path30758_1_" gradientUnits="userSpaceOnUse" x1="16.7803" y1="80.697304" x2="67.723602" y2="80.697304" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0" style="stop-color:#888888" id="stop149" /> <stop offset="0.8935" style="stop-color:#DDDDDD" id="stop151" /> </linearGradient> <linearGradient id="path34280_1_" gradientUnits="userSpaceOnUse" x1="93.023399" y1="39.3867" x2="93.023399" y2="25.928699" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0" style="stop-color:#555555" id="stop141" /> <stop offset="0.3965" style="stop-color:#888888" id="stop143" /> <stop offset="1" style="stop-color:#555555" id="stop145" /> </linearGradient> <linearGradient id="rect22846_1_" gradientUnits="userSpaceOnUse" x1="247.60249" y1="-288.60791" x2="261.97269" y2="-288.60791" gradientTransform="matrix(0.9428,-0.2511,-0.2421,-0.9089,6.0921912,215.38258)"> <stop offset="0" style="stop-color:#888888" id="stop135" /> <stop offset="1" style="stop-color:#555555" id="stop137" /> </linearGradient> <radialGradient id="rect14944_1_" cx="274.56641" cy="36.065399" r="6.8733001" gradientTransform="matrix(0.523,-0.2146,-2.627,-7.0521,27.4228,356.0237)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#888A85" id="stop127" /> <stop offset="0.6213" style="stop-color:#FFFFFF" id="stop129" /> <stop offset="1" style="stop-color:#555753" id="stop131" /> </radialGradient> <radialGradient id="rect14938_1_" cx="290.8428" cy="36.069801" r="6.8736" gradientTransform="matrix(0.4892,-0.2059,-2.5913,-7.0931,29.692,361.6149)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#888A85" id="stop119" /> <stop offset="0.6213" style="stop-color:#FFFFFF" id="stop121" /> <stop offset="1" style="stop-color:#555753" id="stop123" /> </radialGradient> <radialGradient id="rect10553_1_" cx="292.49219" cy="43.388699" r="6.8727999" gradientTransform="matrix(0.498,-0.2212,-2.9368,-8.3284,56.2613,466.2682)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#888A85" id="stop111" /> <stop offset="0.6213" style="stop-color:#FFFFFF" id="stop113" /> <stop offset="1" style="stop-color:#555753" id="stop115" /> </radialGradient> <radialGradient id="rect14950_1_" cx="92.734398" cy="20.4307" r="4.1451998" gradientTransform="matrix(0.6131,-0.2916,-5.2659,-7.9645,125.0096,227.992)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop103" /> <stop offset="0.5266" style="stop-color:#BABDB6" id="stop105" /> <stop offset="1" style="stop-color:#888A85" id="stop107" /> </radialGradient> <radialGradient id="rect10551_3_" cx="78.776398" cy="44.608398" r="14.3205" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#2E3436" id="stop95" /> <stop offset="0.72189999" style="stop-color:#000000;stop-opacity:1;" id="stop97" /> <stop offset="1" style="stop-color:#2E3436" id="stop99" /> </radialGradient> <linearGradient id="rect10551_1_" gradientUnits="userSpaceOnUse" x1="77.216797" y1="44.765598" x2="73.449203" y2="30.555201"> <stop offset="0.7219" style="stop-color:#DDDDDD" id="stop89" /> <stop offset="1" style="stop-color:#EEEEEC" id="stop91" /> </linearGradient> <radialGradient id="XMLID_6_" cx="77.004028" cy="13.140214" r="64.405701" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" fx="77.004028" fy="13.140214"> <stop offset="0" style="stop-color:#FFFFFF" id="stop82" /> <stop id="stop13256" style="stop-color:#c3c4c2;stop-opacity:1;" offset="0.5" /> <stop offset="1" style="stop-color:#000000;stop-opacity:1;" id="stop84" /> </radialGradient> <linearGradient id="XMLID_5_" gradientUnits="userSpaceOnUse" x1="15.7207" y1="125.7861" x2="24.9356" y2="108.3428" gradientTransform="translate(-80,0)"> <stop offset="0" style="stop-color:#000000" id="stop75" /> <stop offset="0.8935" style="stop-color:#FFFFFF" id="stop77" /> </linearGradient> <linearGradient id="XMLID_4_" gradientUnits="userSpaceOnUse" x1="40.527802" y1="55.75" x2="52.981899" y2="64.646004" gradientTransform="translate(-80,0)"> <stop offset="0" style="stop-color:#ffffff;stop-opacity:0;" id="stop68" /> <stop offset="0.8935" style="stop-color:#FFFFFF" id="stop70" /> </linearGradient> <linearGradient id="path2388_1_" gradientUnits="userSpaceOnUse" x1="14.9214" y1="124.6768" x2="107.7549" y2="-17.989599" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0" style="stop-color:#DDDDDD" id="stop32" /> <stop offset="0.6864" style="stop-color:#888888" id="stop34" /> <stop offset="0.8935" style="stop-color:#DDDDDD" id="stop36" /> </linearGradient> <radialGradient id="path5936_1_" cx="172.123" cy="4.7476001" r="4.6967001" gradientTransform="matrix(6.7917,-1.4855,-1.2014,-5.506,-845.12621,725.19548)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop26" /> <stop offset="1" style="stop-color:#3E3E3E" id="stop28" /> </radialGradient> <linearGradient id="XMLID_1_" gradientUnits="userSpaceOnUse" x1="92.627899" y1="26.589399" x2="104.5325" y2="31.2349" gradientTransform="translate(229.83849,405.96228)"> <stop offset="0" style="stop-color:#FFFFFF" id="stop19" /> <stop offset="0.6391" style="stop-color:#888888" id="stop21" /> </linearGradient> <linearGradient id="rect25493_1_" gradientUnits="userSpaceOnUse" x1="258.88379" y1="-326.0903" x2="286.16019" y2="-287.6532" gradientTransform="matrix(0.9065,-0.2414,-0.2421,-0.9089,10.723991,214.40698)"> <stop offset="0" style="stop-color:#555555" id="stop5" /> <stop offset="0.6864" style="stop-color:#888888" id="stop7" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#XMLID_5_" id="linearGradient10549" gradientUnits="userSpaceOnUse" gradientTransform="translate(-80,0)" x1="15.7207" y1="125.7861" x2="24.9356" y2="108.3428" /> <mask maskUnits="userSpaceOnUse" id="mask10545"> <path style="fill:url(#linearGradient10549)" id="path10547" d="M -0.051,18.554 L -0.847,9.66 C -0.847,9.66 8.141,4.482 10.38,3.193 C 3.985,-0.79 -3.654,1.07 -3.741,1.093 C -10.903,2.996 -15.908,8.865 -15.908,15.222 C -15.908,15.461 -15.901,15.701 -15.887,15.94 C -15.887,15.941 -15.887,15.941 -15.887,15.942 C -15.887,16.299 -16.25,36.73 -19.253,42.838 C -20.334,45.036 -30.401,58.18 -42.058,73.4 C -54.195,89.247 -69.3,108.968 -70.298,111.44 C -70.839,112.778 -71.079,114.126 -71.079,115.435 C -71.079,119.221 -69.06,122.663 -66.483,124.621 C -66.083,123.92 -65.655,123.178 -65.197,122.392 C -67.02,121.101 -68.463,119.074 -68.895,116.783 C -69.291,114.687 -68.831,112.48 -67.631,110.726 C -66.46,109.013 -64.659,107.855 -62.561,107.463 C -60.935,107.16 -59.182,107.593 -57.621,108.682 C -57.428,108.817 -57.245,108.966 -57.063,109.118 C -46.315,92.233 -27.938,65.35 3.195,23.824 C 1.323,20.784 -0.051,18.554 -0.051,18.554 z" /> </mask> <linearGradient inkscape:collect="always" xlink:href="#rect25493_1_" id="linearGradient11382" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9065,-0.2414,-0.2421,-0.9089,10.723991,214.40698)" x1="258.88379" y1="-326.0903" x2="286.16019" y2="-287.6532" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_1_" id="linearGradient11384" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="92.627899" y1="26.589399" x2="104.5325" y2="31.2349" /> <radialGradient inkscape:collect="always" xlink:href="#path5936_1_" id="radialGradient11386" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.7917,-1.4855,-1.2014,-5.506,-845.12621,725.19548)" cx="172.123" cy="4.7476001" r="4.6967001" /> <linearGradient inkscape:collect="always" xlink:href="#path2388_1_" id="linearGradient11388" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="14.9214" y1="124.6768" x2="107.7549" y2="-17.989599" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="linearGradient11390" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="77.040016" y1="14.124305" x2="92.612343" y2="4.8821697" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="linearGradient11392" gradientUnits="userSpaceOnUse" gradientTransform="translate(-80,0)" x1="40.527802" y1="55.75" x2="52.981899" y2="64.646004" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_6_" id="radialGradient11394" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4337031,0.4442839,-0.7150071,0.6987259,282.84098,375.70944)" cx="77.004028" cy="13.140214" fx="77.004028" fy="13.140214" r="64.405701" /> <linearGradient inkscape:collect="always" xlink:href="#rect10551_1_" id="linearGradient11396" gradientUnits="userSpaceOnUse" x1="77.216797" y1="44.765598" x2="73.449203" y2="30.555201" /> <radialGradient inkscape:collect="always" xlink:href="#rect10551_3_" id="radialGradient11398" gradientUnits="userSpaceOnUse" cx="78.776398" cy="44.608398" r="14.3205" /> <radialGradient inkscape:collect="always" xlink:href="#rect14950_1_" id="radialGradient11400" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6131,-0.2916,-5.2659,-7.9645,125.0096,227.992)" cx="92.734398" cy="20.4307" r="4.1451998" /> <radialGradient inkscape:collect="always" xlink:href="#rect10553_1_" id="radialGradient11402" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.498,-0.2212,-2.9368,-8.3284,56.2613,466.2682)" cx="292.49219" cy="43.388699" r="6.8727999" /> <radialGradient inkscape:collect="always" xlink:href="#rect14938_1_" id="radialGradient11404" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4892,-0.2059,-2.5913,-7.0931,29.692,361.6149)" cx="290.8428" cy="36.069801" r="6.8736" /> <radialGradient inkscape:collect="always" xlink:href="#rect14944_1_" id="radialGradient11406" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.523,-0.2146,-2.627,-7.0521,27.4228,356.0237)" cx="274.56641" cy="36.065399" r="6.8733001" /> <linearGradient inkscape:collect="always" xlink:href="#rect22846_1_" id="linearGradient11408" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9428,-0.2511,-0.2421,-0.9089,6.0921912,215.38258)" x1="247.60249" y1="-288.60791" x2="261.97269" y2="-288.60791" /> <linearGradient inkscape:collect="always" xlink:href="#path34280_1_" id="linearGradient11410" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="93.023399" y1="39.3867" x2="93.023399" y2="25.928699" /> <linearGradient inkscape:collect="always" xlink:href="#path30758_1_" id="linearGradient11412" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="16.7803" y1="80.697304" x2="67.723602" y2="80.697304" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="linearGradient11414" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="40.711899" y1="75.171898" x2="48.5495" y2="80.899803" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient11416" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" cx="64.988297" cy="15.9429" r="19.6182" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient11418" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="18.776899" y1="129.5986" x2="18.776899" y2="114.6055" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient11420" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="17.509325" y1="123.23078" x2="18.875885" y2="107.20945" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient11422" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="31.4995" y1="80.0439" x2="32.347698" y2="80.671898" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_3_" id="linearGradient11424" gradientUnits="userSpaceOnUse" x1="11.9185" y1="119.0576" x2="98.418404" y2="44.057598" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4529" id="linearGradient11510" gradientUnits="userSpaceOnUse" x1="9.3031492" y1="133.25163" x2="-5.8540711" y2="130.59308" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4529" id="linearGradient11512" gradientUnits="userSpaceOnUse" x1="9.3031492" y1="133.25163" x2="-5.8540711" y2="130.59308" /> <filter inkscape:collect="always" id="filter11957"> <feGaussianBlur inkscape:collect="always" stdDeviation="2.339831" id="feGaussianBlur11959" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="linearGradient12019" gradientUnits="userSpaceOnUse" gradientTransform="translate(-80,0)" x1="40.527802" y1="55.75" x2="52.981899" y2="64.646004" /> <linearGradient inkscape:collect="always" xlink:href="#path34280_1_" id="linearGradient12037" gradientUnits="userSpaceOnUse" gradientTransform="translate(229.83849,405.96228)" x1="93.023399" y1="39.3867" x2="93.023399" y2="25.928699" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_3_" id="linearGradient12051" gradientUnits="userSpaceOnUse" x1="11.9185" y1="119.0576" x2="98.418404" y2="44.057598" /> <filter inkscape:collect="always" id="filter12490"> <feGaussianBlur inkscape:collect="always" stdDeviation="2.3509538" id="feGaussianBlur12492" /> </filter> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="13" inkscape:cy="18.5" inkscape:document-units="px" inkscape:current-layer="g11357" inkscape:window-width="1024" inkscape:window-height="697" inkscape:window-x="0" inkscape:window-y="0" height="128px" width="128px" /> <metadata id="metadata5681"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1"> <path style="fill:#000000;fill-opacity:1;filter:url(#filter12490);opacity:0.8" d="M 97.46875,6 C 97.18152,6.0094408 97.00831,6.0304757 97,6.03125 C 88.50154,6.7547259 81.81102,12.649899 80.96875,19.9375 C 80.96299,19.970198 76.86754,40.857308 72.875,46.3125 C 69.74177,50.594872 11.13376,102.7197 8.28125,107.28125 C 6.43475,110.23375 6.09196,113.64754 6.8125,116.75 C 6.81481,116.75995 6.81016,116.77131 6.8125,116.78125 C 7.27817,118.76618 8.16525,120.60725 9.40625,122.125 C 9.47154,122.20534 9.55786,122.26531 9.625,122.34375 C 9.73846,122.47566 9.85017,122.62373 9.96875,122.75 C 10.13123,122.9234 10.29696,123.08786 10.46875,123.25 C 10.78531,123.54834 11.12253,123.83716 11.46875,124.09375 C 11.51009,124.12442 11.55201,124.15746 11.59375,124.1875 C 11.75577,124.30387 11.92581,124.39345 12.09375,124.5 C 12.34901,124.66192 12.60676,124.83089 12.875,124.96875 C 12.90463,124.98396 12.93897,124.98509 12.96875,125 C 13.16389,125.09785 13.36099,125.19684 13.5625,125.28125 C 13.66656,125.32459 13.76932,125.36661 13.875,125.40625 C 13.96058,125.43847 14.03838,125.47026 14.125,125.5 C 14.26755,125.5489 14.41722,125.58297 14.5625,125.625 C 15.11282,125.78408 15.69527,125.91534 16.28125,125.96875 C 16.62585,125.99943 16.98844,126.00883 17.34375,126 C 17.49276,125.99631 17.6305,125.97967 17.78125,125.96875 C 18.30718,125.93117 18.83023,125.84877 19.375,125.71875 C 19.49773,125.68971 19.62642,125.65895 19.75,125.625 C 19.94658,125.5707 20.14518,125.50448 20.34375,125.4375 C 20.68974,125.32116 21.02361,125.18743 21.375,125.03125 C 21.51637,124.96837 21.67036,124.91327 21.8125,124.84375 C 22.01661,124.74364 22.23195,124.64533 22.4375,124.53125 C 22.50876,124.4917 22.58484,124.44751 22.65625,124.40625 C 22.93651,124.24411 23.21755,124.06393 23.5,123.875 C 23.72992,123.72139 24.01123,123.49888 24.3125,123.25 C 24.51715,123.08053 24.76474,122.86659 25,122.65625 C 25.31217,122.37641 25.73134,121.97195 26.09375,121.625 C 26.40496,121.32709 26.7476,121.00087 27.09375,120.65625 C 27.10095,120.64393 27.11785,120.63734 27.125,120.625 C 40.39609,107.39872 78.3196,61.213642 83.8125,57.75 C 87.95646,55.136652 109.0625,51.3125 109.0625,51.3125 C 113.21925,49.41573 118.90506,43.445638 121.3125,34.4375 C 121.72869,32.077134 121.4811,29.596922 121.375,30.03125 L 108.59375,35.78125 L 100.21875,29.0625 L 98.78125,25.40625 L 99.28125,19.21875 L 113.34375,13.96875 L 113.125,12.15625 C 107.67312,6.0868239 99.47934,5.9339145 97.46875,6 z M 17.8125,106.1875 C 21.2472,106.15572 24.40096,109.89596 24.375,114.15625 C 24.3535,117.67982 20.93573,121.18715 17.5,121.21875 C 14.06408,121.25138 10.73518,117.39784 10.6875,113.53125 C 10.68465,113.29896 10.66822,113.04283 10.6875,112.8125 C 10.70682,112.58223 10.74047,112.35167 10.78125,112.125 C 10.90349,111.44483 11.13404,110.80542 11.4375,110.1875 C 11.53867,109.98155 11.63003,109.78948 11.75,109.59375 C 12.94961,107.63625 15.09816,106.21329 17.8125,106.1875 z" id="path11963" /> <g id="g11357" transform="matrix(1.0223499,0.1802679,-0.1801715,1.0218034,-142.50883,-466.04399)"> <path style="fill:url(#linearGradient11382)" d="M 322.52649,444.25728 C 326.15949,443.01428 332.35849,434.45128 332.98149,424.78428 C 333.00949,424.35428 333.65649,426.67828 333.65649,428.98828 C 332.87949,437.94128 328.47049,444.55028 324.84449,447.04628 L 322.52649,444.25728 z" inkscape:r_cy="true" inkscape:r_cx="true" sodipodi:nodetypes="csssc" id="rect25493" /> <path style="fill:#888a85" d="M 332.98149,424.78428 L 321.82849,432.38828 L 312.74849,427.41628 C 312.08149,428.88428 315.95449,447.98028 320.22749,446.96228 C 328.04849,445.09828 332.16349,435.78528 332.98149,424.78428 z" inkscape:r_cy="true" inkscape:r_cx="true" sodipodi:nodetypes="cccsc" id="path3285" /> <path style="fill:url(#linearGradient11384)" id="path23" d="M 322.07549,432.68428 L 323.06949,441.37828 L 324.97749,444.59028 C 326.91449,443.03428 328.49449,440.87628 329.72849,438.28428 C 331.33649,434.63428 332.30349,430.21428 332.65649,425.47228 L 322.07549,432.68428 z" enable-background="new " /> <path style="opacity:0.51380005;fill:url(#radialGradient11386)" d="M 313.59749,428.19228 C 313.59449,428.19728 313.57749,428.21928 313.57649,428.22628 C 313.57149,428.23928 313.56449,428.27228 313.56049,428.28828 C 313.04649,430.36728 316.00549,448.15728 320.19449,447.15928 C 321.12049,446.93828 322.00949,446.60928 322.83249,446.18928 L 320.58049,431.94628 L 313.59749,428.19228 z" enable-background="new " inkscape:r_cy="true" inkscape:r_cx="true" id="path5936" /> <path style="fill:url(#linearGradient11388)" d="M 305.84149,406.08928 C 297.90049,408.19828 292.53349,414.90528 292.95349,421.96328 C 292.95349,421.99528 292.56249,442.51428 289.68749,448.36028 C 287.43149,452.94928 240.55549,512.22128 238.61249,517.02828 C 234.50849,527.18028 246.26949,539.39528 255.82749,530.23128 C 262.12949,524.18928 296.79749,462.07328 301.96749,457.37728 C 305.46149,454.20328 324.84249,447.04528 324.84249,447.04528 L 310.76249,424.19228 L 310.04449,416.17028 L 322.15949,409.19128 C 315.08849,403.65028 305.90349,406.07228 305.84149,406.08928 z M 247.46049,514.40928 C 250.71349,513.80428 254.33749,516.82428 255.02549,520.87228 C 255.59449,524.22028 252.93349,528.13028 249.67949,528.73528 C 246.42549,529.34128 242.61749,526.22128 241.92549,522.55928 C 241.26149,519.04028 243.34849,515.17628 247.46049,514.40928 z" inkscape:r_cy="true" inkscape:r_cx="true" sodipodi:nodetypes="cccssssccccssssccssss" id="path2388" /> <path transform="translate(309.83849,405.96228)" mask="url(#mask10545)" style="fill:url(#linearGradient11392)" id="path72" d="M -0.051,18.554 L -0.847,9.66 C -0.847,9.66 8.141,4.482 10.38,3.193 C 3.985,-0.79 -3.654,1.07 -3.741,1.093 C -10.903,2.996 -15.908,8.865 -15.908,15.222 C -15.908,15.461 -15.901,15.701 -15.887,15.94 C -15.887,15.941 -15.887,15.941 -15.887,15.942 C -15.887,16.299 -16.25,36.73 -19.253,42.838 C -20.334,45.036 -30.401,58.18 -42.058,73.4 C -54.195,89.247 -69.3,108.968 -70.298,111.44 C -70.839,112.778 -71.079,114.126 -71.079,115.435 C -71.079,119.221 -69.06,122.663 -66.483,124.621 C -66.083,123.92 -65.655,123.178 -65.197,122.392 C -67.02,121.101 -68.463,119.074 -68.895,116.783 C -69.291,114.687 -68.831,112.48 -67.631,110.726 C -66.46,109.013 -64.659,107.855 -62.561,107.463 C -60.935,107.16 -59.182,107.593 -57.621,108.682 C -57.428,108.817 -57.245,108.966 -57.063,109.118 C -46.315,92.233 -27.938,65.35 3.195,23.824 C 1.323,20.784 -0.051,18.554 -0.051,18.554 z" /> <path style="fill:url(#radialGradient11394)" id="path86" d="M 310.76249,424.19228 L 310.04449,416.17028 L 322.15949,409.19128 C 320.21949,407.64028 317.84449,406.51628 315.23549,405.92928 C 312.04649,405.90828 308.79349,406.38428 306.47749,407.16528 C 298.74149,409.77428 294.69849,415.49528 294.85149,422.31128 L 303.63249,437.15128 L 306.31749,435.47228 L 312.56749,446.29728 L 310.37649,447.80128 L 313.73849,451.42828 L 324.84249,447.04628 L 310.76249,424.19228 z" /> <polygon transform="translate(229.83849,405.96228)" style="fill:url(#linearGradient11396)" points="65.82,36.446 76.487,27.791 85.179,40.128 72.511,46.783 65.82,36.446 " inkscape:r_cy="true" inkscape:r_cx="true" id="rect10551_2_" /> <polygon transform="translate(229.83849,405.96228)" style="fill:url(#radialGradient11398)" points="65.82,36.446 76.487,29.791 83.179,40.128 72.511,46.783 65.82,36.446 " inkscape:r_cy="true" inkscape:r_cx="true" id="rect10551" /> <polygon transform="translate(229.83849,405.96228)" style="fill:url(#radialGradient11400)" points="68.311,35.653 74.616,32.078 80.237,40.809 73.932,44.384 68.311,35.653 " inkscape:r_cy="true" inkscape:r_cx="true" id="rect14950" /> <polygon transform="translate(229.83849,405.96228)" style="fill:url(#radialGradient11402)" points="67.891,36.615 77.497,32.233 77.891,33.323 68.284,37.705 67.891,36.615 " inkscape:r_cy="true" inkscape:r_cx="true" id="rect10553" /> <polygon transform="translate(229.83849,405.96228)" style="fill:url(#radialGradient11404)" points="72.212,42.972 81.653,38.899 82.001,39.827 72.56,43.9 72.212,42.972 " inkscape:r_cy="true" inkscape:r_cx="true" id="rect14938" /> <polygon transform="translate(229.83849,405.96228)" style="fill:url(#radialGradient11406)" points="69.661,39.991 79.757,35.751 80.11,36.673 70.015,40.914 69.661,39.991 " inkscape:r_cy="true" inkscape:r_cx="true" id="rect14944" /> <path style="fill:url(#linearGradient11410)" d="M 320.80249,431.89128 C 320.76149,432.16128 322.10049,439.91928 322.18149,440.18928 C 322.85449,444.45728 323.83149,444.59528 324.03549,445.34928 C 324.76349,444.93528 324.29249,445.39528 324.92349,444.84628 C 324.80849,444.48028 323.48549,441.99528 322.95849,441.11128 C 322.71249,438.97728 321.93149,433.00328 321.86449,432.43528 C 321.45549,432.21328 321.29849,432.12528 320.80249,431.89128 z" inkscape:r_cy="true" inkscape:r_cx="true" sodipodi:nodetypes="ccccccc" id="path34280" /> <path style="fill:url(#linearGradient11412)" d="M 246.62049,511.92528 C 251.42949,510.02428 257.88249,515.30428 257.53849,521.11028 C 260.82449,517.31028 296.88449,460.33528 297.44649,457.74428 C 298.30649,453.77728 294.17949,450.82228 290.89849,452.88728 C 288.60949,454.32628 246.30749,512.04828 246.62049,511.92528 z" inkscape:r_cy="true" inkscape:r_cx="true" sodipodi:nodetypes="ccsss" id="path30758" /> <path style="fill:url(#linearGradient11414);stroke:#000000" id="path159" d="M 292.02849,454.56028 C 289.53249,456.91828 266.85449,487.60628 250.66249,509.77928 C 252.02149,510.08228 253.37949,510.67028 254.63749,511.58128 C 256.37949,512.84228 257.66849,514.51428 258.50849,516.33428 C 267.27449,503.42428 294.06749,460.80328 295.50149,457.24628 C 295.53749,457.05828 295.56249,456.87128 295.56249,456.69028 C 295.56249,455.85828 295.18949,455.11828 294.50449,454.63828 C 293.74349,454.10528 292.82549,454.08928 292.02849,454.56028 z" /> <path style="fill:url(#radialGradient11416)" id="path166" d="M 294.94349,422.46628 C 294.86849,425.66728 294.31649,443.48028 291.48249,449.24328 C 291.40649,449.39728 291.28449,449.60828 291.13649,449.84928 C 291.56049,449.26728 291.86549,448.81828 292.01449,448.54228 C 294.75749,443.48028 297.55549,430.48328 297.76449,427.23428 L 294.94349,422.46628 z" /> <path style="opacity:0.5;fill:url(#linearGradient11418)" id="path173" d="M 258.69149,526.59428 C 259.24949,525.08628 259.45349,523.49328 259.17549,521.97428 C 258.59949,518.81928 256.61749,515.87328 253.87449,514.09028 C 251.69549,512.67428 249.24349,512.11128 246.97049,512.50528 C 244.03849,513.01528 241.52249,514.52228 239.88549,516.74928 C 238.45149,518.70028 237.78049,521.08528 237.96049,523.44028 C 239.33149,531.34628 248.26549,537.48228 255.82849,530.23128 C 256.49049,529.59728 257.46949,528.33628 258.69149,526.59428 z M 249.67949,528.73528 C 246.42549,529.34128 242.61749,526.22128 241.92549,522.55928 C 241.26049,519.03928 243.34749,515.17528 247.46049,514.40928 C 250.71349,513.80428 254.33749,516.82428 255.02549,520.87228 C 255.59449,524.22028 252.93349,528.13028 249.67949,528.73528 z" /> <path style="fill:url(#linearGradient11420)" id="path180" d="M 256.01149,520.70428 C 255.59949,518.27928 254.18149,516.01528 252.21849,514.64428 C 250.65849,513.55528 248.90449,513.12328 247.27849,513.42528 C 245.18049,513.81728 243.38049,514.97528 242.20849,516.68828 C 241.00949,518.44128 240.54849,520.64928 240.94449,522.74528 C 241.75449,527.03328 246.08849,530.42228 249.86349,529.71928 C 253.62049,529.02028 256.66649,524.55528 256.01149,520.70428 z M 249.67949,528.73528 C 246.42549,529.34128 242.61749,526.22128 241.92549,522.55928 C 241.26049,519.03928 243.34749,515.17528 247.46049,514.40928 C 250.71349,513.80428 254.33749,516.82428 255.02549,520.87228 C 255.59449,524.22028 252.93349,528.13028 249.67949,528.73528 z" /> <path style="opacity:0.4;fill:url(#linearGradient11422)" id="path187" d="M 285.39049,455.48028 C 285.64549,454.95828 285.88049,454.31028 286.09549,453.56728 C 274.64749,469.16528 240.27149,512.92628 238.61349,517.02828 C 238.29049,517.82728 238.07649,518.63728 237.94149,519.45128 C 242.96749,511.10428 283.36449,459.62828 285.39049,455.48028 z" /> <path transform="translate(229.83849,405.96228)" clip-path="url(#clipPath4092)" style="fill:url(#linearGradient11424);filter:url(#filter4503)" id="path65" d="M 72.13,49.416 C 66.96,54.112 32.292,116.228 25.99,122.27 C 18.09,129.844 8.695,122.813 7.986,114.414 C 7.207,123.618 17.468,132.44 25.99,124.27 C 32.292,118.228 66.96,56.112 72.13,51.416 C 75.624,48.242 95.005,41.084 95.005,41.084 L 94.004,39.459 C 90.005,40.965 75.147,46.674 72.13,49.416 z" /> <path style="fill:url(#linearGradient11408)" d="M 310.04449,416.17028 L 322.15949,409.19128 L 322.67749,410.88528 L 310.13349,418.26728 L 310.04449,416.17028 z" inkscape:r_cy="true" inkscape:r_cx="true" sodipodi:nodetypes="ccccc" id="rect22846" /> <path style="fill:url(#linearGradient11390);fill-opacity:1" id="path46" d="M 310.21449,416.07228 L 322.15949,409.19128 C 321.63949,408.78428 321.10749,408.43228 320.56949,408.10728 L 310.04449,414.17028 L 310.21449,416.07228 z" /> </g> <path style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.47008219000000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1;filter:url(#filter11957);opacity:0.80000000000000004" d="M 10.375,9 L 4.21875,15.46875 L 9.125,23.1875 C 13.08003,25.264868 17.14186,27.693549 20.375,30.75 L 69.625,77.3125 L 65.5625,81.5625 L 70.8125,86.53125 C 73.7103,86.859904 76.69384,88.078409 79.15625,90.40625 C 81.64614,92.760071 83.16605,95.732279 83.625,98.625 L 108.34375,122.03125 C 114.08456,127.45836 128.43479,112.52526 122.65625,107.0625 L 97.90625,83.6875 C 94.97813,83.378226 91.9274,82.010074 89.4375,79.65625 C 86.9751,77.328414 85.57063,74.424084 85.09375,71.5625 L 79.84375,66.59375 L 75.78125,70.84375 L 26.53125,24.28125 C 23.29811,21.224799 20.16307,17.382339 18.375,13.53125 L 10.375,9 z" id="path11428" /> <g id="g10397" transform="matrix(0.9660937,-2.5302336e-2,2.3546854e-2,0.9608617,2.3338765,6.1294086)"> <path id="rect3006" d="M 1.750754,7.673054 L 6.651221,15.840499 C 10.689771,18.10883 14.818666,20.740966 18.085644,24.007944 L 103.30145,109.22375 L 109.83541,102.68979 L 24.6196,17.473988 C 21.352622,14.20701 18.204176,10.093654 16.452155,6.039565 L 8.28471,1.139098 L 1.750754,7.673054 z" style="fill:url(#linearGradient6125);fill-opacity:1;stroke:none;stroke-width:0.47008219;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" sodipodi:nodetypes="ccccccccc" /> <rect transform="matrix(0.7071068,-0.7071068,-0.7071068,-0.7071068,0,0)" style="fill:url(#linearGradient6122);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="rect3912" width="1.1166428" height="98.671562" x="-1.357038" y="-123.11634" /> <rect style="opacity:0.3857678;fill:url(#linearGradient6119);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="rect4944" width="1.6020314" height="63.508739" x="0.89394951" y="-85.707031" transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)" /> <g transform="matrix(0.8167445,-0.8167445,0.8167445,0.8167445,5.2761549,23.749521)" clip-path="url(#clipPath3850)" id="g3842"> <path style="fill:#535557;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3834)" d="M 4.296875,-4.12891 L 5.6640625,-4.12891 C 8.3203089,-0.31380448 8.5987355,3.8409896 7.6171875,8.17578 L 4.9804688,9.1523436 L 4.296875,-4.12891 z" id="path3726" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path3728" d="M 18.977324,-4.12891 L 17.610137,-4.12891 C 14.95389,-0.31380448 14.675464,3.8409896 15.657012,8.17578 L 18.293731,9.1523436 L 18.977324,-4.12891 z" style="fill:#535557;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3838)" /> <path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3838)" d="M 18.977324,-4.12891 L 18.231618,-4.0598566 C 16.117808,-1.3279433 15.743286,-1.0597872 15.864172,4.9302704 L 18.293731,9.1523436 L 18.977324,-4.12891 z" id="path3969" sodipodi:nodetypes="ccccc" /> </g> <rect transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" y="41.331993" x="0.84851468" height="109.04897" width="1.9142449" id="rect3886" style="fill:url(#linearGradient6112);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path transform="matrix(0.8167445,-0.8167445,0.8167445,0.8167445,-14.584136,43.609812)" id="path3925" d="M 32,-12 L 30,-4 C 34.143852,8.2009511 38.115959,5.0342786 42,-4 L 40,-12 L 32,-12 z" style="fill:url(#linearGradient3943);fill-opacity:1;stroke:url(#linearGradient6517);stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccsccccsccc" id="rect3956" d="M 63.529919,78.09273 L 68.834311,83.397123 C 71.82354,83.817882 74.899226,85.18508 77.387407,87.673261 C 79.903365,90.189215 81.385477,93.328601 81.786903,96.34972 L 106.78156,121.34436 C 112.58247,127.14528 127.79361,112.01036 121.95458,106.17133 L 96.95993,81.176682 C 93.938823,80.775254 90.799446,79.29314 88.283481,76.777186 C 85.795299,74.289007 84.428105,71.213314 84.007344,68.22409 L 78.70295,62.919697 L 63.529919,78.09273 z" style="opacity:1;fill:url(#linearGradient4190);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path transform="matrix(0.9483145,-0.9483145,0.9483145,0.9483145,-6.4444639,0.531831)" clip-path="url(#clipPath4242)" sodipodi:nodetypes="cccccc" id="path4196" d="M -8,120 C 1.7462188,130.07566 10.00314,126.89342 16,120 L 12,136 L -16,128 L -20,112 L -8,120 z" style="fill:#ffa700;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4238)" /> <rect transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" y="100.16766" x="-10.297462" height="1.1132338" width="21.457907" id="rect4249" style="opacity:0.48689138;fill:#ffa500;fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccccc" id="rect4320" d="M 72.972033,68.720893 L 75.892922,65.800004 L 81.066844,70.973925 C 80.921148,71.564914 80.822369,72.165286 81.579665,72.936868 L 79.073097,75.857759 C 78.372014,75.392484 77.997186,74.796708 78.21501,73.963871 L 72.972033,68.720893 z" style="opacity:0.83895126;fill:url(#linearGradient4346);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="rect4340" d="M 4.6713727,129.88196 L 7.2816355,129.49996 C 7.2464436,130.37087 7.2584731,130.8014 7.8438776,132.01123 L 5.1273299,132.01123 C 4.7973883,130.83537 4.6035939,130.49599 4.6713727,129.88196 z" style="opacity:0.74531836;fill:url(#linearGradient4342);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4404)" transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-4,-4)" /> <rect transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" y="126.0467" x="-0.6434837" height="0.390625" width="10.644531" id="rect4432" style="opacity:1;fill:url(#radialGradient4440);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path sodipodi:nodetypes="ccc" id="path4454" d="M 83.597656,68.53125 L 68.753906,82.984375 C 84.820174,88.576948 78.33289,74.329762 83.597656,68.53125 z" style="fill:url(#linearGradient4471);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4501)" /> <path transform="matrix(-1,0,0,-1,169.63281,168.51104)" style="fill:url(#linearGradient4515);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4501)" d="M 87.597656,72.53125 L 72.753906,86.984375 C 88.820174,92.576948 82.33289,78.329762 87.597656,72.53125 z" id="path4505" sodipodi:nodetypes="ccc" /> <rect transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" ry="2.9279406" rx="2.9279406" y="132.02951" x="-7.5001087" height="29.279404" width="5.8558812" id="rect4517" style="opacity:0.83895126;fill:url(#linearGradient4525);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <rect inkscape:transform-center-y="-5.5242717" inkscape:transform-center-x="-16.434708" transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-4,-4)" ry="0.5577029" rx="2.9279406" y="130.97287" x="-1.1929667" height="1.1048541" width="11.60097" id="rect4527" style="opacity:0.83895126;fill:url(#linearGradient4537);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4551)" /> <path transform="translate(50.492188,-4.0046875)" clip-path="url(#clipPath4588)" id="path4559" d="M 13.83125,81.09375 L 12.33125,82.59375 L 17.64375,87.90625 C 20.632979,88.327007 23.718069,89.699319 26.20625,92.1875 C 28.722207,94.703451 30.179824,97.822631 30.58125,100.84375 L 55.58125,125.84375 C 59.791769,130.05428 68.947177,123.22603 71.425,116.9375 C 68.058606,122.54366 60.345306,127.60781 56.58125,123.84375 L 31.58125,98.84375 C 31.179824,95.822631 29.722207,92.703451 27.20625,90.1875 C 24.718069,87.699319 21.632979,86.327007 18.64375,85.90625 L 13.83125,81.09375 z" style="opacity:1;fill:#996100;fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4584)" /> <rect style="opacity:0.576779;fill:url(#radialGradient4602);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="rect4596" width="10.644531" height="0.390625" x="-0.091056541" y="100.35886" transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" /> <rect clip-path="url(#clipPath4632)" style="opacity:0.576779;fill:url(#linearGradient4604);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4626)" id="rect4598" width="12.602244" height="4.0530515" x="-1.1929667" y="129.5918" rx="0" ry="0" transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-21.221011,-22.313001)" inkscape:transform-center-x="-16.434708" inkscape:transform-center-y="-5.5242717" /> <rect inkscape:transform-center-y="-5.5242717" inkscape:transform-center-x="-16.434708" transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-21.321011,-22.413001)" ry="0" rx="0" y="130.07516" x="3.1573973" height="1.7051741" width="7.9066095" id="rect4638" style="opacity:0.576779;fill:url(#linearGradient4640);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4626)" clip-path="url(#clipPath4632)" /> <path sodipodi:nodetypes="ccccc" style="fill:url(#linearGradient6930);fill-opacity:1;stroke:none;stroke-width:0.30655462;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 2.9032773,7.9724105 L 7.1391831,15.032254 C 18.678358,20.720438 19.246981,15.680572 15.610994,6.5604419 L 8.5511516,2.3245361 L 2.9032773,7.9724105 z" id="path6537" /> <rect style="opacity:0.83895126;fill:url(#linearGradient7698);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="rect7696" width="5.8558812" height="29.279404" x="4.5207062" y="132.73663" rx="2.9279406" ry="2.9279406" transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" /> <rect style="opacity:0.95131088;fill:url(#linearGradient4338);fill-opacity:1;stroke:none;stroke-width:0.37;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="rect4336" width="2.5833137" height="38.179485" x="0.94721299" y="126.14276" transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" /> </g> </g> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/assgn-none.svg�������������������������������������������������������0000644�0001750�0000144�00000006200�11163114147�017306� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="680" height="680" id="svg2273" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" sodipodi:docname="assgn-none.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2275" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="375" inkscape:cy="405.71429" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" showgrid="false" showguides="true" height="680px" width="680px" /> <metadata id="metadata2278"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-47.400002,-191.39075)"> <rect style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:15;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4135" width="660" height="630" x="59.899994" y="217.46219" /> <path id="path3155" d="M 68.114294,417.81933 L 708.11429,417.81933" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path3160" d="M 68.114294,657.81933 L 708.11429,657.81933" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 608.11429,237.81933 L 608.11429,817.81932" id="path3164" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 163.11429,242.81934 L 163.11429,822.81933" id="path3162" /> </g> </svg> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/go-next.svg����������������������������������������������������������0000644�0001750�0000144�00000101546�10737543470�016643� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2606" sodipodi:version="0.32" inkscape:version="0.45+devel" version="1.0" sodipodi:docname="go-next.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" sodipodi:docbase="/home/pinheiro/artwork/Oxygen/scribus/scalable" inkscape:export-filename="/home/pinheiro/pics/oxygen/scalable/actions/go-next.png" inkscape:export-xdpi="180" inkscape:export-ydpi="180"> <defs id="defs2608"> <linearGradient inkscape:collect="always" id="linearGradient3449"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3451" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3453" /> </linearGradient> <linearGradient id="linearGradient3295"> <stop style="stop-color:#63e9ff;stop-opacity:1;" offset="0" id="stop3297" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3299" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3260"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3262" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3264" /> </linearGradient> <linearGradient id="linearGradient3202"> <stop style="stop-color:#cdeeff;stop-opacity:1;" offset="0" id="stop3204" /> <stop style="stop-color:#d2e8ed;stop-opacity:0;" offset="1" id="stop3206" /> </linearGradient> <radialGradient id="XMLID_4_" cx="48" cy="-0.2148" r="55.148" gradientTransform="matrix(0.9792,0,0,0.9725,133.0002,20.8762)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#72D13D" id="stop3082" /> <stop offset="0.3553" style="stop-color:#35AC1C" id="stop3084" /> <stop offset="0.6194" style="stop-color:#0F9508" id="stop3086" /> <stop offset="0.7574" style="stop-color:#008C00" id="stop3088" /> <stop offset="1" style="stop-color:#007A00" id="stop3090" /> </radialGradient> <radialGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="radialGradient3629" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="172" cy="76" fx="172" fy="76" r="56" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient3213" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="172" cy="76" fx="188.88173" fy="121.44213" r="56" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3301" x1="73.742638" y1="15.336544" x2="78.939339" y2="16.750759" gradientUnits="userSpaceOnUse" spreadMethod="reflect" /> <filter inkscape:collect="always" x="-0.10207015" width="1.2041403" y="-0.12495601" height="1.249912" id="filter3387"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.44655691" id="feGaussianBlur3389" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3393" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="74.75" y1="14.275884" x2="78.939339" y2="16.750759" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6404" id="linearGradient3409" gradientUnits="userSpaceOnUse" x1="194.5" y1="123.90683" x2="104.25" y2="5.1559582" gradientTransform="matrix(-1,0,0,0.8610463,236,-1.4361867)" /> <filter inkscape:collect="always" x="-0.11573034" width="1.2314607" y="-0.12753956" height="1.2550791" id="filter3443"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.32549158" id="feGaussianBlur3445" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3455" cx="72.020813" cy="66.344505" fx="72.020813" fy="66.344505" r="60" gradientTransform="matrix(-0.5816285,1.767767e-2,2.6986249e-2,0.8878982,96.078154,5.9419094)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3521" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8610463,-108.16138,-1.4361867)" spreadMethod="reflect" x1="223.32712" y1="53.784153" x2="226.659" y2="57.279232" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient2226" gradientUnits="userSpaceOnUse" x1="179.17224" y1="123.75864" x2="173.98071" y2="65.448112" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient2228" gradientUnits="userSpaceOnUse" x1="179.17224" y1="123.75864" x2="173.98071" y2="65.448112" gradientTransform="translate(97,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3253" x1="47.968472" y1="16.138517" x2="49.218472" y2="85.427559" gradientUnits="userSpaceOnUse" gradientTransform="translate(-0.5,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3504" gradientUnits="userSpaceOnUse" gradientTransform="translate(-0.2125256,-0.1385179)" x1="87.468468" y1="-0.36148256" x2="116.71847" y2="106.42756" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3526" gradientUnits="userSpaceOnUse" gradientTransform="translate(-0.2125256,-0.1385179)" x1="196.46846" y1="63.138515" x2="52.218468" y2="66.224457" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3530" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8610463,-108.16138,-1.4361867)" spreadMethod="reflect" x1="223.32712" y1="53.784153" x2="226.659" y2="57.279232" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3534" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2586607,-0.5212474,-0.8274344,0.4106011,163.53945,50.055595)" cx="-16.668488" cy="86.826965" fx="-16.668488" fy="86.826965" r="60" /> <radialGradient r="43.474762" fy="51.592991" fx="88.042809" cy="74.979416" cx="77.533371" spreadMethod="reflect" gradientTransform="matrix(-0.4961056,0.4409829,-0.7360594,-0.8280666,-11.726835,87.897058)" gradientUnits="userSpaceOnUse" id="radialGradient3139" xlink:href="#linearGradient2990" inkscape:collect="always" /> <clipPath id="clipPath3135" clipPathUnits="userSpaceOnUse"> <path style="fill:url(#radialGradient3139);fill-opacity:1;stroke:none;stroke-width:16.49500084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15;stroke-opacity:1" d="M -97.32181,27.94375 C -107.56112,27.943751 -117.79103,31.818176 -125.55562,39.582762 C -133.56284,47.589993 -137.44486,58.222613 -137.19463,68.779409 L -137.19463,96.822041 C -137.19463,100.87378 -133.94013,104.12828 -129.88839,104.12828 L -64.755235,104.12828 C -60.703495,104.12828 -57.448995,100.87378 -57.448995,96.822041 L -57.448995,68.779409 C -57.198765,58.222612 -61.080775,47.589993 -69.088001,39.582762 C -76.852581,31.818171 -87.082497,27.943749 -97.32181,27.94375 z M -97.32181,43.481014 C -90.982458,43.481015 -84.633535,45.9179 -79.764176,50.787256 C -74.95275,55.59868 -72.515179,61.833382 -72.457934,68.090021 L -122.15737,68.090021 C -122.10012,61.833381 -119.69086,55.598679 -114.87944,50.787256 C -110.01008,45.917895 -103.66116,43.481013 -97.32181,43.481014 z" id="path3137" sodipodi:nodetypes="csccccccsccsccsc" /> </clipPath> <radialGradient r="43.474762" fy="51.592991" fx="88.042809" cy="74.979416" cx="77.533371" spreadMethod="reflect" gradientTransform="matrix(-0.4961056,0.4409829,-0.7360594,-0.8280666,-99.14147,87.897058)" gradientUnits="userSpaceOnUse" id="radialGradient3133" xlink:href="#linearGradient2990" inkscape:collect="always" /> <clipPath id="clipPath3129" clipPathUnits="userSpaceOnUse"> <path sodipodi:nodetypes="csccccccsccsccsc" id="path3131" d="M -184.73645,27.94375 C -194.97576,27.943751 -205.20567,31.818176 -212.97026,39.582762 C -220.97748,47.589993 -224.8595,58.222613 -224.60927,68.779409 L -224.60927,96.822041 C -224.60927,100.87378 -221.35477,104.12828 -217.30303,104.12828 L -152.16987,104.12828 C -148.11813,104.12828 -144.86363,100.87378 -144.86363,96.822041 L -144.86363,68.779409 C -144.6134,58.222612 -148.49541,47.589993 -156.50264,39.582762 C -164.26722,31.818171 -174.49713,27.943749 -184.73645,27.94375 z M -184.73645,43.481014 C -178.39709,43.481015 -172.04817,45.9179 -167.17881,50.787256 C -162.36739,55.59868 -159.92981,61.833382 -159.87257,68.090021 L -209.57201,68.090021 C -209.51476,61.833381 -207.1055,55.598679 -202.29408,50.787256 C -197.42472,45.917895 -191.0758,43.481013 -184.73645,43.481014 z" style="fill:url(#radialGradient3133);fill-opacity:1;stroke:none;stroke-width:16.49500084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4.15;stroke-opacity:1" /> </clipPath> <radialGradient r="43.474762" fy="51.592991" fx="73.551216" cy="74.979408" cx="63.041775" spreadMethod="reflect" gradientTransform="matrix(-1.1040885,0.8280667,-0.6647496,-0.8863327,191.44623,62.253906)" gradientUnits="userSpaceOnUse" id="radialGradient2409" xlink:href="#linearGradient2990" inkscape:collect="always" /> <linearGradient y2="-20.962214" x2="60.402065" y1="64.076149" x1="60.402065" gradientUnits="userSpaceOnUse" id="linearGradient3289" xlink:href="#linearGradient6674" inkscape:collect="always" /> <linearGradient gradientUnits="userSpaceOnUse" y2="8" x2="-60" y1="105.83054" x1="-60.945251" id="linearGradient3243" xlink:href="#linearGradient3237" inkscape:collect="always" /> <linearGradient y2="21.03125" x2="31.376678" y1="71.084908" x1="115.76678" gradientTransform="translate(0.2332229,1.9150941)" gradientUnits="userSpaceOnUse" id="linearGradient3233" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient y2="46.228859" x2="59.225807" y1="7.8973217" x1="59.225807" gradientTransform="translate(0.2623629,1)" gradientUnits="userSpaceOnUse" id="linearGradient3231" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient y2="82.029854" x2="74.447762" y1="-26.936626" x1="64" gradientUnits="userSpaceOnUse" id="linearGradient2816" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient gradientUnits="userSpaceOnUse" y2="88.633484" x2="19.934336" y1="50.580647" x1="19.096775" id="linearGradient6680" xlink:href="#linearGradient6674" inkscape:collect="always" /> <linearGradient gradientTransform="translate(0,3)" gradientUnits="userSpaceOnUse" y2="50.728985" x2="62.038712" y1="15.91371" x1="62.038712" id="linearGradient6649" xlink:href="#linearGradient6643" inkscape:collect="always" /> <linearGradient gradientUnits="userSpaceOnUse" y2="74.913147" x2="55.329033" y1="112" x1="55.329033" id="linearGradient6637" xlink:href="#linearGradient6631" inkscape:collect="always" /> <linearGradient y2="28.235947" x2="13.96104" y1="21.101994" x1="21.094994" spreadMethod="reflect" gradientTransform="translate(0.4129032,0.6193548)" gradientUnits="userSpaceOnUse" id="linearGradient6472" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient y2="28.235947" x2="13.96104" y1="21.101994" x1="21.094994" spreadMethod="reflect" gradientTransform="translate(0.4129032,0.6193548)" gradientUnits="userSpaceOnUse" id="linearGradient6470" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient y2="27.070099" x2="15.126888" y1="21.101994" x1="21.094994" spreadMethod="reflect" gradientTransform="translate(0.4129032,0.6193548)" gradientUnits="userSpaceOnUse" id="linearGradient6464" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient gradientTransform="translate(-7.5870968,-7.3806452)" spreadMethod="reflect" gradientUnits="userSpaceOnUse" y2="27.007854" x2="15.189133" y1="21.101994" x1="21.094994" id="linearGradient6452" xlink:href="#linearGradient6446" inkscape:collect="always" /> <linearGradient gradientUnits="userSpaceOnUse" y2="-24" x2="24" y1="88" x1="32" id="linearGradient6410" xlink:href="#linearGradient6404" inkscape:collect="always" /> <radialGradient r="42.559486" fy="103.5803" fx="42.700352" cy="103.5803" cx="42.700352" spreadMethod="pad" gradientTransform="matrix(1.3965253,6.9831451e-3,-7.781496e-3,1.5561835,-122.82611,-69.698616)" gradientUnits="userSpaceOnUse" id="radialGradient9692" xlink:href="#linearGradient6666" inkscape:collect="always" /> <linearGradient id="linearGradient6404"> <stop id="stop6406" offset="0" style="stop-color:#081e3e;stop-opacity:1;" /> <stop id="stop6408" offset="1" style="stop-color:#387de4;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient6446"> <stop id="stop6448" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop6450" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6631"> <stop id="stop6633" offset="0" style="stop-color:#703700;stop-opacity:1;" /> <stop id="stop6635" offset="1" style="stop-color:#bf5e00;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6643"> <stop id="stop6645" offset="0" style="stop-color:#fffddc;stop-opacity:1;" /> <stop id="stop6647" offset="1" style="stop-color:#ffdfbf;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6666"> <stop style="stop-color:#9fc1f2;stop-opacity:1;" offset="0" id="stop6668" /> <stop id="stop3183" offset="0.5" style="stop-color:#587eb5;stop-opacity:1;" /> <stop style="stop-color:#0c2a58;stop-opacity:1;" offset="1" id="stop6670" /> </linearGradient> <linearGradient id="linearGradient6674"> <stop id="stop6676" offset="0" style="stop-color:#001648;stop-opacity:1;" /> <stop id="stop6678" offset="1" style="stop-color:#11a9ff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3237"> <stop id="stop3239" offset="0" style="stop-color:#d5e6ff;stop-opacity:1;" /> <stop id="stop3241" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient2990"> <stop id="stop2992" offset="0" style="stop-color:#d7d7d7;stop-opacity:1;" /> <stop id="stop2994" offset="1" style="stop-color:#ffffff;stop-opacity:1;" /> </linearGradient> <filter inkscape:collect="always" id="filter3187"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.56525828" id="feGaussianBlur3189" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6404" id="linearGradient3219" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,0.8610463,375,-1.4361867)" x1="194.5" y1="123.90683" x2="104.25" y2="5.1559582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3221" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.2586607,-0.5212474,-0.8274344,0.4106011,302.53945,50.055595)" cx="-16.668488" cy="86.826965" fx="-16.668488" fy="86.826965" r="60" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3223" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="73.742638" y1="15.336544" x2="78.939339" y2="16.750759" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3225" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8610463,-108.16138,-1.4361867)" spreadMethod="reflect" x1="223.32712" y1="53.784153" x2="226.659" y2="57.279232" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3227" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.5816285,1.767767e-2,2.6986249e-2,0.8878982,235.07816,5.9419094)" cx="72.020813" cy="66.344505" fx="72.020813" fy="66.344505" r="60" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3229" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="74.75" y1="14.275884" x2="78.939339" y2="16.750759" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3232" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8610463,-108.16138,-1.4361867)" spreadMethod="reflect" x1="223.32712" y1="53.784153" x2="226.659" y2="57.279232" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6666" id="radialGradient3234" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="172" cy="76" fx="188.88173" fy="121.44213" r="56" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="radialGradient3236" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1383929,0,-10.517857)" cx="172" cy="76" fx="172" fy="76" r="56" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3238" gradientUnits="userSpaceOnUse" gradientTransform="translate(97,0)" x1="179.17224" y1="123.75864" x2="173.98071" y2="65.448112" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3240" gradientUnits="userSpaceOnUse" x1="179.17224" y1="123.75864" x2="173.98071" y2="65.448112" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3202" id="linearGradient3242" gradientUnits="userSpaceOnUse" gradientTransform="translate(138.5,0)" x1="47.968472" y1="16.138517" x2="49.218472" y2="85.427559" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3244" gradientUnits="userSpaceOnUse" gradientTransform="translate(138.78748,-0.1385179)" x1="87.468468" y1="-0.36148256" x2="116.71847" y2="106.42756" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3246" gradientUnits="userSpaceOnUse" gradientTransform="translate(138.78748,-0.1385179)" x1="196.46846" y1="63.138515" x2="52.218468" y2="66.224457" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.99999999" inkscape:cx="346.93235" inkscape:cy="4.4643894" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" showgrid="false" inkscape:grid-points="true" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1016" inkscape:window-height="692" inkscape:window-x="360" inkscape:window-y="67"> <inkscape:grid type="xygrid" id="grid2576" spacingx="4px" spacingy="4px" empspacing="2" /> </sodipodi:namedview> <metadata id="metadata2611"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1"> <path sodipodi:nodetypes="ccsccccccccccc" id="path2488" d="M 54.78125,12.165446 L 122.44806,61.147784 C 123.4314,61.853052 124,62.898046 124,64 C 124,65.101954 123.4314,66.146948 122.44806,66.852216 L 54.09375,115.82531 C 49.95063,118.4557 44,118.82842 44,113 L 44,88.000004 L 12,88.000004 C 9.61796,88.000658 7.9992403,86.051051 8.0000003,84 L 8.0000003,44 C 7.9992403,41.94895 9.61796,39.999344 12,40 L 44,40 L 44,15.999999 C 44,12.108863 51.02052,9.4467058 54.78125,12.165446 z" style="fill:url(#linearGradient3409);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.62137889999999985;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path sodipodi:nodetypes="ccsccccccccccc" id="path3532" d="M 54.78125,12.165446 L 122.44806,61.147784 C 123.4314,61.853052 124,62.898046 124,64 C 124,65.101954 123.4314,66.146948 122.44806,66.852216 L 54.09375,115.82531 C 49.95063,118.4557 44,118.82842 44,113 L 44,88.000004 L 12,88.000004 C 9.61796,88.000658 7.9992403,86.051051 8.0000003,84 L 8.0000003,44 C 7.9992403,41.94895 9.61796,39.999344 12,40 L 44,40 L 44,15.999999 C 44,12.108863 51.02052,9.4467058 54.78125,12.165446 z" style="opacity:0.25468164;fill:url(#radialGradient3534);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path style="fill:url(#linearGradient3301);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" d="M 72.5,11.0625 C 71.422912,11.127783 70.386099,11.439286 69.5,12 L 71.875,19.625 L 80,16.46875 L 80,16 C 80,13.081648 76.061079,10.84666 72.5,11.0625 z" id="path3272" transform="matrix(-1,0,0,1,124,0)" /> <path id="path3519" d="M 115.65112,40 C 115.31168,41.154561 113.08862,46.125 113.08862,46.125 L 119.83862,46.09375 L 119.83862,44 C 119.83938,41.94895 118.22066,39.999344 115.83862,40 L 115.65112,40 z " style="opacity:0.6142322;fill:url(#linearGradient3521);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3443)" transform="matrix(-1,0,0,-1,128,128.125)" /> <path style="fill:url(#radialGradient3455);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 54.78125,12.165446 L 122.44806,61.147784 C 123.4314,61.853052 124,62.898046 124,64 C 124,65.101954 123.4314,66.146948 122.44806,66.852216 L 54.09375,115.82531 C 49.95063,118.4557 44,118.82842 44,113 L 44,88.000004 L 12,88.000004 C 9.61796,88.000658 7.9992403,86.051051 8.0000003,84 L 8.0000003,44 C 7.9992403,41.94895 9.61796,39.999344 12,40 L 44,40 L 44,15.999999 C 44,12.108863 51.02052,9.4467058 54.78125,12.165446 z" id="path3447" sodipodi:nodetypes="ccsccccccccccc" /> <path id="path3391" d="M 72.5,11.0625 C 71.422912,11.127783 70.386099,11.439286 69.5,12 L 71.875,19.625 L 80,16.46875 L 80,16 C 80,13.081648 76.061079,10.84666 72.5,11.0625 z" style="opacity:0.70411987;fill:url(#linearGradient3393);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3387)" transform="matrix(-0.8316412,0,0,-1,110.5313,128.78415)" sodipodi:nodetypes="cccccc" /> <path transform="matrix(2.8382138e-2,-0.9995972,0.9995972,2.8382138e-2,-35.118048,158.48653)" style="opacity:0.74906365;fill:url(#linearGradient3530);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8.6213789;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3443)" d="M 115.65112,40 C 115.31168,41.154561 113.08862,46.125 113.08862,46.125 L 119.83862,46.09375 L 119.83862,44 C 119.83938,41.94895 118.22066,39.999344 115.83862,40 L 115.65112,40 z " id="path3528" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> <g style="fill:url(#radialGradient3629);fill-opacity:1;stroke:none;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" transform="matrix(-1,0,0,0.8609865,236,-1.4349776)" id="g3472"> <path sodipodi:nodetypes="ccccccccccc" id="path3474" d="M 181.55044,21.46494 L 117.50547,73.806959 C 116.11967,75.416501 116.3415,76.828137 117.40303,78.061061 L 180,129.07866 C 184,132.6608 188,132.85189 188,129.07866 L 188,99.229172 L 224,99.229172 L 224,52.770836 L 188,52.770836 L 188,23.929232 C 188,20.738359 184.84713,19.254283 181.55044,21.46494 z" style="fill:url(#radialGradient3213);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> <g style="fill:none;fill-opacity:1;stroke:url(#linearGradient2226);stroke-width:1.07770978999999989;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3187)" transform="matrix(-1,0,0,0.8609865,333.40303,-1.4349776)" id="g3469"> <path sodipodi:nodetypes="ccccccccccc" id="path3471" d="M 278.55044,21.46494 L 214.10547,73.806959 C 212.71967,75.416501 212.9415,76.828137 214.00303,78.061061 L 277,129.07866 C 281,132.6608 285,132.85189 285,129.07866 L 285,99.229172 L 321,99.229172 L 321,52.770836 L 285,52.770836 L 285,23.929232 C 285,20.738359 281.84713,19.254283 278.55044,21.46494 z" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2228);stroke-width:1.07770979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> <path style="fill:url(#linearGradient3253);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 50.96875,16.15625 C 49.240202,16.307374 48,17.439188 48,19.15625 L 48,44 L 12,44 L 12,65.15625 C 21.939409,66.360551 28.451562,67.000001 39.3125,67 C 66.254354,67 90.98579,63.028043 110.375,56.40625 L 54.4375,17.03125 C 53.201241,16.317495 52.005879,16.065575 50.96875,16.15625 z" id="path2232" sodipodi:nodetypes="cccccsccc" /> <path style="fill:url(#linearGradient3504);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 50.96875,16.117187 C 50.09558,16.193525 49.37078,16.528828 48.84375,17.054687 C 48.58829,17.309579 48.35908,17.58696 48.21875,17.929687 C 48.21509,17.938382 48.22233,17.952189 48.21875,17.960937 C 48.15242,18.127922 48.09786,18.306702 48.0625,18.492187 C 48.06048,18.502221 48.06442,18.51335 48.0625,18.523437 C 48.02875,18.710259 48,18.913179 48,19.117187 C 47.99991,19.127767 48,19.137812 48,19.148437 L 48,20.148437 L 48,43.742187 L 48.03125,43.742187 L 49.13125,18.998437 C 49.502929,16.724737 52.430578,16.81446 54.4375,18.023437 L 109.2875,56.042187 C 95.76171,60.964822 78.06048,64.465479 60.3125,66.085937 C 78.61652,64.639265 95.35134,61.359487 109.375,56.679687 L 109.40625,56.710937 C 109.72671,56.603896 110.05739,56.506907 110.375,56.398437 L 110.34375,56.367187 L 79.90625,34.929687 L 54.4375,17.023437 C 53.37955,16.412627 52.36202,16.157535 51.4375,16.148437 C 51.45997,16.140063 51.47725,16.12513 51.5,16.117187 C 51.32253,16.113177 51.13828,16.102367 50.96875,16.117187 z M 12,43.960937 L 12,43.992187 L 12,44.992187 L 12,65.117187 L 12.9375,44.992187 L 48,43.992187 L 48,43.992187 L 13,43.992187 L 13,43.960937 L 12,43.960937 z" id="path3462" sodipodi:nodetypes="cssssssccccccccccccccssccccccccccc" /> <path sodipodi:nodetypes="cssssssccccccccccccccssccccccccccc" id="path3524" d="M 50.96875,16.117187 C 50.09558,16.193525 49.37078,16.528828 48.84375,17.054687 C 48.58829,17.309579 48.35908,17.58696 48.21875,17.929687 C 48.21509,17.938382 48.22233,17.952189 48.21875,17.960937 C 48.15242,18.127922 48.09786,18.306702 48.0625,18.492187 C 48.06048,18.502221 48.06442,18.51335 48.0625,18.523437 C 48.02875,18.710259 48,18.913179 48,19.117187 C 47.99991,19.127767 48,19.137812 48,19.148437 L 48,20.148437 L 48,43.742187 L 48.03125,43.742187 L 49.13125,18.998437 C 49.502929,16.724737 52.430578,16.81446 54.4375,18.023437 L 109.2875,56.042187 C 95.76171,60.964822 78.06048,64.465479 60.3125,66.085937 C 78.61652,64.639265 95.35134,61.359487 109.375,56.679687 L 109.40625,56.710937 C 109.72671,56.603896 110.05739,56.506907 110.375,56.398437 L 110.34375,56.367187 L 79.90625,34.929687 L 54.4375,17.023437 C 53.37955,16.412627 52.36202,16.157535 51.4375,16.148437 C 51.45997,16.140063 51.47725,16.12513 51.5,16.117187 C 51.32253,16.113177 51.13828,16.102367 50.96875,16.117187 z M 12,43.960937 L 12,43.992187 L 12,44.992187 L 12,65.117187 L 12.9375,44.992187 L 48,43.992187 L 48,43.992187 L 13,43.992187 L 13,43.960937 L 12,43.960937 z" style="fill:url(#linearGradient3526);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> </svg> ����������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/rename.svg�����������������������������������������������������������0000644�0001750�0000144�00000201227�10737543475�016533� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="128" height="128" id="svg2365"> <defs id="defs2367"> <filter x="-0.085532367" width="1.1710647" y="-0.10938701" height="1.218774" id="filter6906"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.5212367" id="feGaussianBlur6908" /> </filter> <clipPath id="clipPath6130"> <path d="M 125.16669,12.099598 C 122.19641,9.254864 111.282,2.992388 109.84175,5.187905 C 108.10513,7.835221 117.93885,14.870955 121.74406,16.587139 C 123.04716,17.174853 126.16385,13.054607 125.16669,12.099598 z" id="path6132" style="fill:#e20071;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient3168"> <stop id="stop3170" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop3172" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="29.344007" y1="35.892609" x2="5.8861146" y2="54.610104" id="linearGradient6134" xlink:href="#linearGradient3168" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.8205678,0.1491734,0.1491734,0.8205678,119.95493,-30.558073)" /> <linearGradient id="linearGradient2878"> <stop id="stop2880" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2882" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="47.794022" cy="43.680889" r="0.046902865" fx="47.817745" fy="43.681263" id="radialGradient2257" xlink:href="#linearGradient2878" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,140,0,-6071.644)" /> <linearGradient id="linearGradient2926"> <stop id="stop2928" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2934" style="stop-color:#ffffff;stop-opacity:0" offset="0.31868133" /> <stop id="stop2930" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="59.887943" cy="-16.594898" r="15.014902" fx="59.887943" fy="-16.594898" id="radialGradient4868" xlink:href="#linearGradient2926" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2908472,-1.2912538,-0.4877278,0.8613771,257.00005,93.121214)" spreadMethod="reflect" /> <linearGradient id="linearGradient2916"> <stop id="stop2918" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2920" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="58.079144" cy="51.897194" r="15.014902" fx="60.050133" fy="51.985794" id="radialGradient4871" xlink:href="#linearGradient2916" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.9412787,-1.1615663,-0.2846191,0.7136661,292.2596,68.533501)" /> <linearGradient id="linearGradient2948"> <stop id="stop2950" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2956" style="stop-color:#000000;stop-opacity:0" offset="0.14835165" /> <stop id="stop2960" style="stop-color:#000000;stop-opacity:0.39607844" offset="0.42443547" /> <stop id="stop2958" style="stop-color:#000000;stop-opacity:0.79061371" offset="0.57417583" /> <stop id="stop2962" style="stop-color:#000000;stop-opacity:0.09386282" offset="0.78708792" /> <stop id="stop2952" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.277409" y1="41.758987" x2="75.465431" y2="41.511894" id="linearGradient4874" xlink:href="#linearGradient2948" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <filter x="-0.081383675" width="1.1627673" y="-0.11701577" height="1.2340316" id="filter7303"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5574454" id="feGaussianBlur7305" /> </filter> <clipPath id="clipPath6914"> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 81.839741,-15.69481 90.48863,-25.23053 103.93871,-26.883344 C 107.28591,-26.458991 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.52863,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z" id="path6916" style="opacity:1;fill:#34176e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2938"> <stop id="stop2940" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2942" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="61.870293" y1="33.318996" x2="61.870293" y2="40.550549" id="linearGradient4880" xlink:href="#linearGradient2938" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <linearGradient id="linearGradient2854"> <stop id="stop2856" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2858" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="106.03028" y1="59.273457" x2="108.78728" y2="55.574818" id="linearGradient4888" xlink:href="#linearGradient2854" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="94.435982" cy="42.709927" r="16.633095" fx="94.435982" fy="42.709927" id="radialGradient4891" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2134389,-1.5580054,-0.9195638,1.2855562,320.80105,101.437)" /> <radialGradient cx="94.932045" cy="43.032188" r="16.633095" fx="94.932045" fy="43.032188" id="radialGradient4894" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="93.747849" cy="43.102612" r="16.633095" fx="93.747849" fy="43.102612" id="radialGradient4897" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="92.990265" cy="42.850105" r="16.633095" fx="92.990265" fy="42.850105" id="radialGradient4900" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <linearGradient id="linearGradient2830"> <stop id="stop2832" style="stop-color:#111111;stop-opacity:1" offset="0" /> <stop id="stop2838" style="stop-color:#6e6e70;stop-opacity:1" offset="0.14285715" /> <stop id="stop2864" style="stop-color:#101010;stop-opacity:1" offset="0.5714286" /> <stop id="stop2834" style="stop-color:#0d0d0d;stop-opacity:1" offset="1" /> </linearGradient> <radialGradient cx="92.496124" cy="43.249184" r="16.633095" fx="92.496124" fy="43.249184" id="radialGradient4903" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <filter x="-0.059171364" width="1.1183428" y="-0.25424162" height="1.5084833" id="filter5739"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5280665" id="feGaussianBlur5741" /> </filter> <clipPath id="clipPath5354"> <path d="M 103.98397,-1.574449 C 105.35028,-1.792233 108.98473,-2.914664 106.17093,-5.692155 C 76.173344,-27.291403 51.99515,-18.323699 42.936426,-12.159439 C 53.098952,-17.891025 78.771948,-21.925123 103.98397,-1.574449 z" id="path5356" style="opacity:1;fill:#00583f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2803"> <stop id="stop2809" style="stop-color:#e2dcdc;stop-opacity:1" offset="0" /> <stop id="stop2811" style="stop-color:#ffffff;stop-opacity:1" offset="0.39074388" /> <stop id="stop2813" style="stop-color:#dfd9df;stop-opacity:1" offset="0.82692307" /> <stop id="stop2815" style="stop-color:#c3c3c3;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="62.987843" y1="46.469597" x2="118.02947" y2="62.350033" id="linearGradient4910" xlink:href="#linearGradient2803" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2231" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2229" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2227" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2225" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2223" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2221" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2219" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2217" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2215" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2213" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2211" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2209" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2207" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2205" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2203" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2201" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2199" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2197" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2195" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2193" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2191" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2189" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2187" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2185" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2183" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2181" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2179" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2177" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2175" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2173" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2171" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2169" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient id="linearGradient2370"> <stop id="stop2378" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2374" style="stop-color:#2a2a2a;stop-opacity:0.29537368" offset="1" /> </linearGradient> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2167" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient x1="-66.905724" y1="78.000954" x2="-66.905724" y2="77.232819" id="linearGradient4946" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-75.354716)" /> <linearGradient x1="-74.01326" y1="49.46249" x2="-58.206917" y2="65.268829" id="linearGradient4952" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833612,-4.797835,-79.665584)" /> <linearGradient x1="36.909187" y1="75.415688" x2="38.451817" y2="75.479614" id="linearGradient4955" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.983361,0.6663259,-0.6582589,0.9697357,55.439719,-32.927491)" /> <linearGradient id="linearGradient2322"> <stop id="stop2324" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2326" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="37.235054" y1="75.415688" x2="38.61475" y2="75.479614" id="linearGradient4958" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.44832,27.448631)" /> <linearGradient x1="45.615768" y1="128.00496" x2="45.615768" y2="125.89983" id="linearGradient4961" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2310"> <stop id="stop2312" style="stop-color:#020202;stop-opacity:1" offset="0" /> <stop id="stop2314" style="stop-color:#020202;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.24057" y1="61.083416" x2="45.24057" y2="62.415165" id="linearGradient4964" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.36527,27.463989)" /> <linearGradient id="linearGradient3058"> <stop id="stop3060" style="stop-color:#9a7600;stop-opacity:1" offset="0" /> <stop id="stop3066" style="stop-color:#e3ad00;stop-opacity:1" offset="0.32522252" /> <stop id="stop3070" style="stop-color:#ffcd2c;stop-opacity:1" offset="0.6670348" /> <stop id="stop3068" style="stop-color:#e3ad00;stop-opacity:1" offset="0.91571385" /> <stop id="stop3062" style="stop-color:#b98d00;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="34.91254" y1="94.734375" x2="55.089256" y2="94.734375" id="linearGradient4967" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2352"> <stop id="stop2354" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2356" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="-66.905724" y1="77.09996" x2="-66.905724" y2="75.717079" id="linearGradient4949" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764965,0,0,1.1833623,-4.7827195,-79.650397)" /> <linearGradient id="linearGradient2334"> <stop id="stop2336" style="stop-color:#8d8d8d;stop-opacity:1" offset="0" /> <stop id="stop2342" style="stop-color:#e2dcdc;stop-opacity:1" offset="0.2767916" /> <stop id="stop2348" style="stop-color:#ffffff;stop-opacity:1" offset="0.71460712" /> <stop id="stop2344" style="stop-color:#dfd9df;stop-opacity:1" offset="0.80711305" /> <stop id="stop2338" style="stop-color:#888888;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="-70.588905" y1="67.754272" x2="-59.581383" y2="67.754272" id="linearGradient4970" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-79.665581)" /> <linearGradient id="linearGradient6959"> <stop id="stop6961" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop6963" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="0.16120911" y1="117.27959" x2="128.16121" y2="117.27959" id="linearGradient8078" xlink:href="#linearGradient6959" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.785268,-7.3677219e-2,3.9462543e-2,0.4492806,22.778321,70.710911)" /> </defs> <g id="layer1"> <path d="M 128.04736,113.95979 C 128.28089,116.61848 67.411471,124.50507 39.669521,127.10794 C 11.927571,129.71081 27.766581,126.04917 27.533061,123.39048 C 27.299531,120.73178 11.081461,120.07787 38.823411,117.475 C 66.565361,114.87213 127.81383,111.3011 128.04736,113.95979 z" id="path6957" style="opacity:0.32093027;fill:url(#linearGradient8078);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31099999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.274934,34.905639 C 85.204914,25.922787 89.34177,14.198553 102.63801,12.53741 C 105.94693,12.9639 108.13372,18.737744 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z" id="path2874" style="fill:#bfbfc0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <rect width="12.941447" height="29.58403" ry="0" x="-87.844696" y="-16.94743" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2266" style="fill:url(#linearGradient4970);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="13.038667" height="2.5542164" ry="0" x="-87.829575" y="9.101737" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2360" style="opacity:0.36065578;fill:url(#linearGradient4949);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.429289,63.172679 C 65.635414,64.820033 54.923018,83.195864 49.729102,91.344581 C 39.34128,107.642 26.239281,125.86158 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 19.376879,93.833728 30.860819,78.294436 C 36.602784,70.52478 49.810698,53.88547 51.006314,52.505467 C 52.212736,51.113002 53.417042,50.730504 54.693928,51.613654 C 58.435834,54.201727 62.17774,56.7898 65.919646,59.377862 C 66.995538,60.122005 67.369194,61.222275 66.429289,63.172679 z" id="rect1388" style="fill:url(#linearGradient4967);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.247591,63.206257 C 65.453717,64.853621 49.629,53.919059 50.824616,52.539056 C 52.031038,51.146581 53.235344,50.764082 54.51223,51.647242 C 58.254136,54.235305 61.996042,56.823378 65.737948,59.411451 C 66.81384,60.155584 67.187497,61.255863 66.247591,63.206257 z" id="path2290" style="opacity:0.09157511;fill:url(#linearGradient4964);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 26.239281,125.86158 26.239281,125.86158 z" id="path2308" style="opacity:0.3699634;fill:url(#linearGradient4961);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.33068,63.19091 C 65.536805,64.838264 54.824409,83.214095 49.630493,91.362803 C 39.242661,107.66022 26.140672,125.8798 26.140672,125.8798 C 24.569135,128.14762 62.079131,56.808021 65.821037,59.396094 C 66.896928,60.140227 67.270585,61.240506 66.33068,63.19091 z" id="path2320" style="opacity:0.3699634;fill:url(#linearGradient4958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 51.020737,52.411747 C 49.776998,53.730231 36.591653,70.167669 30.909012,77.870037 C 19.543739,93.274764 7.3898106,111.88362 7.3898106,111.88362 C 5.8550281,114.14465 58.555163,54.129906 54.752313,51.55311 C 53.658913,50.812203 52.49326,50.850706 51.020737,52.411747 z" id="path2330" style="opacity:0.23809521;fill:url(#linearGradient4955);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="22.48386" ry="0" x="-87.844696" y="-16.947432" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2350" style="opacity:0.25;fill:url(#linearGradient4952);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="4.1249256" ry="0" x="-87.844696" y="12.822533" transform="matrix(-0.8224474,-0.5688412,0.5695776,-0.8219376,0,0)" id="rect2364" style="opacity:0.29098361;fill:url(#linearGradient4946);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.339764,-119.62564)" id="path2368" style="opacity:0.21245422;fill:url(#radialGradient2167);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.295704,-113.78978)" id="path2486" style="opacity:0.21245422;fill:url(#radialGradient2169);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.251654,-107.95391)" id="path2490" style="opacity:0.21245422;fill:url(#radialGradient2171);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.207455,-102.11799)" id="path2494" style="opacity:0.21245422;fill:url(#radialGradient2173);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.163405,-96.282126)" id="path2498" style="opacity:0.21245422;fill:url(#radialGradient2175);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.119257,-90.446221)" id="path2502" style="opacity:0.21245422;fill:url(#radialGradient2177);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.401175,-83.637696)" id="path2506" style="opacity:0.21245422;fill:url(#radialGradient2179);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.357125,-77.801811)" id="path2510" style="opacity:0.21245422;fill:url(#radialGradient2181);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.312966,-71.965905)" id="path2514" style="opacity:0.21245422;fill:url(#radialGradient2183);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2518" style="opacity:0.21245422;fill:url(#radialGradient2185);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2522" style="opacity:0.21245422;fill:url(#radialGradient2187);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.51209,-120.72315)" id="path2524" style="opacity:0.21245422;fill:url(#radialGradient2189);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.468031,-114.88732)" id="path2526" style="opacity:0.21245422;fill:url(#radialGradient2191);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.423951,-109.05138)" id="path2528" style="opacity:0.21245422;fill:url(#radialGradient2193);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.379792,-103.21548)" id="path2530" style="opacity:0.21245422;fill:url(#radialGradient2195);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,58.335742,-97.379601)" id="path2532" style="opacity:0.21245422;fill:url(#radialGradient2197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,54.291593,-91.543696)" id="path2534" style="opacity:0.21245422;fill:url(#radialGradient2199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.573512,-84.735171)" id="path2536" style="opacity:0.21245422;fill:url(#radialGradient2201);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.529462,-78.899296)" id="path2538" style="opacity:0.21245422;fill:url(#radialGradient2203);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,41.485303,-73.063401)" id="path2540" style="opacity:0.21245422;fill:url(#radialGradient2205);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2542" style="opacity:0.21245422;fill:url(#radialGradient2207);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2544" style="opacity:0.21245422;fill:url(#radialGradient2209);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,86.123367,-112.6923)" id="path2568" style="opacity:0.21245422;fill:url(#radialGradient2211);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.079218,-106.85639)" id="path2570" style="opacity:0.21245422;fill:url(#radialGradient2213);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.035168,-101.02052)" id="path2572" style="opacity:0.21245422;fill:url(#radialGradient2215);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,73.991108,-95.18463)" id="path2574" style="opacity:0.21245422;fill:url(#radialGradient2217);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,69.947019,-89.348755)" id="path2576" style="opacity:0.21245422;fill:url(#radialGradient2219);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,65.90286,-83.51285)" id="path2578" style="opacity:0.21245422;fill:url(#radialGradient2221);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,61.184788,-76.704325)" id="path2580" style="opacity:0.21245422;fill:url(#radialGradient2223);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.14063,-70.86842)" id="path2582" style="opacity:0.21245422;fill:url(#radialGradient2225);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.09658,-65.032544)" id="path2584" style="opacity:0.21245422;fill:url(#radialGradient2227);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2586" style="opacity:0.21245422;fill:url(#radialGradient2229);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z" transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2588" style="opacity:0.21245422;fill:url(#radialGradient2231);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 101.38809,11.479353 C 102.63809,12.398423 103.84894,13.381344 105.0387,14.408949 C 104.01321,16.577326 100.48534,20.746249 99.007199,22.467323 C 98.01495,23.622639 93.281961,23.36178 91.998392,24.319263 C 87.944052,27.343595 84.815519,31.864815 80.922501,35.138608 L 72.655729,29.510877 C 72.667829,29.490354 72.685732,29.470645 72.697861,29.450092 C 72.67379,29.475982 72.628395,29.495037 72.604432,29.520354 L 71.432076,28.709507 C 71.432067,28.709497 76.539137,19.842938 71.897343,16.081861 C 61.421124,7.5933688 42.104321,12.7028 40.367328,14.0543 L 42.083541,7.259695 C 42.083541,7.259695 42.33779,7.1294014 42.380871,7.1146373 C 59.53124,-3.8488001 84.402814,-1.0092155 101.38809,11.479353 z" id="path2783" style="fill:url(#linearGradient4910);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 103.83475,-5.0595755 C 104.3991,-4.5551745 105.41114,-5.6873565 104.63008,-6.2226895 C 74.632493,-27.821939 51.99515,-17.681556 42.936426,-11.517296 C 52.35952,-18.300887 76.609727,-26.230729 103.83475,-5.0595755 z" transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath5354)" id="path2823" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5739)" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.128521,13.402952 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.101176,-0.96025992 73.950973,7.4166021 C 82.164175,13.221703 76.243429,25.456347 72.232891,29.69503 z" id="path2842" style="opacity:0.23360656;fill:url(#radialGradient4903);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.523172,29.895808 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.022844,13.705088 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.235986,-1.1547857 74.085773,7.2220662 C 82.298976,13.027177 76.53371,25.657124 72.523172,29.895808 z" id="path2827" style="opacity:0.23360656;fill:url(#radialGradient4900);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 73.103735,30.297352 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.89179,13.624865 40.576201,14.168322 L 42.322269,7.4456578 C 42.322269,7.4456578 62.640397,-1.7383733 74.490184,6.6384787 C 82.703386,12.44359 77.114273,26.058669 73.103735,30.297352 z" id="path2844" style="opacity:0.0737705;fill:url(#radialGradient4897);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.984171,13.626222 40.566444,14.182412 L 42.334152,7.4434568 C 42.334152,7.4434568 61.966375,-0.76572405 73.816172,7.6111279 C 82.029375,13.416239 76.243429,25.456347 72.232891,29.69503 z" id="path2840" style="opacity:0.23360656;fill:url(#radialGradient4894);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.13613,29.628115 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.921635,13.665037 40.571002,14.184262 L 42.322269,7.4456578 C 42.322269,7.4456578 61.764175,-0.47393028 73.613962,7.9029217 C 81.827164,13.708033 76.146668,25.389432 72.13613,29.628115 z" id="path2862" style="opacity:0.37000002;fill:url(#radialGradient4891);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 61.41113,8.3780551 C 54.11035,6.6553332 42.963569,9.4974003 40.902427,12.001391 L 41.0016,10.631158 C 43.787546,7.6855914 53.80009,5.6303314 60.912865,6.8618995 C 62.075305,7.0631792 62.003061,8.5177258 61.41113,8.3780551 z" id="path2868" style="opacity:0.31000001;fill:url(#linearGradient4888);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 42.085054,7.2558055 L 40.347458,14.03836 L 40.579642,14.198955 L 42.326056,7.4656582 L 42.085054,7.2558055 z" id="path2872" style="opacity:0.11000001;fill:#b7b7b7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.793503,23.516486 95.950625,22.98307 C 98.195669,22.788575 103.22118,19.851069 102.52483,17.34553 C 101.28955,12.900833 104.51185,12.778691 106.76072,16.351101 C 107.83597,18.05917 108.68046,20.615514 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 121.44894,38.490512 117.56384,42.696451 L 111.17842,38.965656 L 103.77633,29.053301 C 97.649281,27.059128 88.562348,29.712528 81.865056,36.103558 z" id="path2936" style="opacity:0.5286885;fill:url(#linearGradient4880);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 96.447179,-28.288297 105.15658,-12.530013 103.93871,-26.883344 C 105.73798,-25.86955 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.528633,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z" transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,39.556289)" clip-path="url(#clipPath6914)" id="path2902" style="opacity:0.3;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7303)" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.936568,23.945458 96.09369,23.412042 C 98.338733,23.217547 99.058515,23.054066 102.62556,17.81605 C 104.97193,14.370546 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z" id="path2904" style="opacity:0.11065572;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 90.178924,23.81633 96.336045,23.282914 C 98.581099,23.088419 99.46084,22.257119 102.66207,17.556297 C 105.00842,14.110793 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z" id="path2946" style="opacity:0.78278689;fill:url(#linearGradient4874);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.186467,36.425805 L 80.943143,35.163804 C 90.771765,25.89748 90.156661,24.109531 96.307061,23.50126 C 99.068954,23.228099 101.46217,20.125666 103.03896,17.817699 C 105.39113,14.376285 105.82661,13.986851 107.08213,16.673348 C 108.04323,18.729874 109.11134,20.957278 109.76753,22.854566 L 120.19358,26.450685 L 126,30.829783 C 123.46105,35.966762 120.42231,40.758067 116.53723,44.964006 L 110.15179,41.233211 L 102.74972,31.320856 C 96.622659,29.326673 88.883759,30.034785 82.186467,36.425805 z" id="path2906" style="opacity:0.55;fill:url(#radialGradient4871);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.052576,35.677069 L 80.809252,34.415058 C 90.637874,25.148744 90.316354,23.346463 96.463708,22.707247 C 99.198595,22.422217 99.463846,21.382923 102.80287,17.054108 C 105.34611,13.756144 105.69272,13.238105 106.94825,15.924612 C 107.90935,17.981128 108.97746,20.208542 109.63365,22.10582 L 120.05969,25.701939 L 125.86612,30.081037 C 123.32716,35.218016 120.28843,40.009321 116.40334,44.21526 L 110.0179,40.484465 L 102.61584,30.57211 C 96.488778,28.577937 88.749878,29.286039 82.052576,35.677069 z" id="path2924" style="opacity:0.76000001;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 47.840924,43.680889 C 47.84099,46.032991 47.832065,48.210404 47.817526,49.389142 C 47.802987,50.56788 47.785056,50.56788 47.770517,49.389142 C 47.755978,48.210404 47.747053,46.032991 47.747119,43.680889 C 47.747053,41.328787 47.755978,39.151374 47.770517,37.972636 C 47.785056,36.793898 47.802987,36.793898 47.817526,37.972636 C 47.832065,39.151374 47.84099,41.328787 47.840924,43.680889 z" transform="matrix(-10.643649,-7.3616191,-0.6740154,0.9726479,659.11339,347.51792)" id="path2876" style="fill:url(#radialGradient2257);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 125.16669,12.099598 C 121.62206,9.685606 112.43786,3.516506 110.99761,5.712023 C 109.26099,8.35934 118.0322,14.038156 121.74406,16.587139 C 122.92246,17.396368 126.3079,12.876785 125.16669,12.099598 z" transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath6130)" id="path3178" style="fill:url(#linearGradient6134);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6906)" /> </g> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/arrow-left-double.svg������������������������������������������������0000644�0001750�0000144�00000113526�10737543470�020615� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/david/Documents" sodipodi:docname="arrow-left-double.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" inkscape:export-filename="arrow-left.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> <defs id="defs4"> <linearGradient inkscape:collect="always" id="linearGradient4167"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop4169" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop4171" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient4150"> <stop style="stop-color:#bfffbf;stop-opacity:1;" offset="0" id="stop4152" /> <stop style="stop-color:#bfffbf;stop-opacity:0;" offset="1" id="stop4154" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3409"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3411" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3413" /> </linearGradient> <linearGradient id="linearGradient3362" inkscape:collect="always"> <stop id="stop3364" offset="0" style="stop-color:#bfffbf;stop-opacity:1" /> <stop id="stop3366" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient id="linearGradient3355" inkscape:collect="always"> <stop id="stop3357" offset="0" style="stop-color:#e0ffe0;stop-opacity:1" /> <stop id="stop3359" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient id="linearGradient3349" inkscape:collect="always"> <stop id="stop3351" offset="0" style="stop-color:#00dd00;stop-opacity:1" /> <stop id="stop3353" offset="1" style="stop-color:#000e00;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3342"> <stop style="stop-color:#00ff00;stop-opacity:1" offset="0" id="stop3344" /> <stop style="stop-color:#004d00;stop-opacity:1" offset="1" id="stop3346" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3710"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3712" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3714" /> </linearGradient> <linearGradient id="linearGradient3689" inkscape:collect="always"> <stop id="stop3691" offset="0" style="stop-color:#f0ff80;stop-opacity:1" /> <stop id="stop3693" offset="1" style="stop-color:#f0ff80;stop-opacity:0" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3669"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3671" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3673" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3511"> <stop style="stop-color:#002a0d;stop-opacity:1;" offset="0" id="stop3513" /> <stop style="stop-color:#002a0d;stop-opacity:0;" offset="1" id="stop3515" /> </linearGradient> <radialGradient id="radialGradient2854" cx="538.77338" cy="651.10352" r="126.0234" gradientTransform="translate(-484,-674)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#cbcbcb;stop-opacity:1;" id="stop2856" /> <stop offset="0.53930002" style="stop-color:#282828;stop-opacity:1;" id="stop2858" /> <stop offset="1" style="stop-color:#9d9d9d;stop-opacity:1;" id="stop2860" /> </radialGradient> <linearGradient id="linearGradient2862" gradientUnits="userSpaceOnUse" x1="538.77338" y1="677.87701" x2="538.77338" y2="789.12207" gradientTransform="translate(-484,-674)"> <stop offset="0.0056" style="stop-color:#4d4d4d;stop-opacity:1;" id="stop2864" /> <stop offset="0.1348" style="stop-color:#676767;stop-opacity:1;" id="stop2866" /> <stop offset="0.4831" style="stop-color:#b2b2b2;stop-opacity:1;" id="stop2868" /> <stop offset="0.62989998" style="stop-color:#aaa;stop-opacity:1;" id="stop2870" /> <stop offset="0.85280001" style="stop-color:#a1a1a1;stop-opacity:1;" id="stop2872" /> <stop offset="1" style="stop-color:#9d9d9d;stop-opacity:1;" id="stop2874" /> </linearGradient> <radialGradient id="radialGradient2876" cx="538.77252" cy="792.99609" r="121.5466" gradientTransform="translate(-484,-674)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#d9d9d9;stop-opacity:1;" id="stop2878" /> <stop offset="0.0494" style="stop-color:#c7c7c7;stop-opacity:1;" id="stop2880" /> <stop offset="0.1049" style="stop-color:#b9b9b9;stop-opacity:1;" id="stop2882" /> <stop offset="0.14321923" style="stop-color:#aeaeae;stop-opacity:1;" id="stop2884" /> <stop offset="0.2156" style="stop-color:#a9a9a9;stop-opacity:1;" id="stop2886" /> <stop offset="0.26969999" style="stop-color:#a6a6a6;stop-opacity:1;" id="stop2888" /> <stop offset="0.3989" style="stop-color:#676767;stop-opacity:1;" id="stop2890" /> <stop offset="0.39950001" style="stop-color:#676767;stop-opacity:1;" id="stop2892" /> <stop offset="0.44839999" style="stop-color:#545454;stop-opacity:1;" id="stop2894" /> <stop offset="0.49559999" style="stop-color:#414141;stop-opacity:1;" id="stop2896" /> <stop offset="0.53988957" style="stop-color:#353535;stop-opacity:1;" id="stop2898" /> <stop offset="0.57096523" style="stop-color:#313131;stop-opacity:1;" id="stop2900" /> <stop offset="0.5948" style="stop-color:#3e3e3e;stop-opacity:1;" id="stop2902" /> <stop offset="0.64560002" style="stop-color:#5f5f5f;stop-opacity:1;" id="stop2904" /> <stop offset="0.69319999" style="stop-color:#707070;stop-opacity:1;" id="stop2906" /> <stop offset="0.73589998" style="stop-color:#7b7b7b;stop-opacity:1;" id="stop2908" /> <stop offset="0.76969999" style="stop-color:#7f7f7f;stop-opacity:1;" id="stop2910" /> <stop offset="1" style="stop-color:#313131;stop-opacity:1;" id="stop2912" /> </radialGradient> <linearGradient id="linearGradient2914" gradientUnits="userSpaceOnUse" x1="538.77338" y1="793" x2="538.77338" y2="674" gradientTransform="translate(-484,-674)"> <stop offset="0" style="stop-color:#262626;stop-opacity:1;" id="stop2916" /> <stop offset="0.1124" style="stop-color:#313131;stop-opacity:1;" id="stop2918" /> <stop offset="0.37450001" style="stop-color:#4d4d4d;stop-opacity:1;" id="stop2920" /> <stop offset="0.42309999" style="stop-color:#505050;stop-opacity:1;" id="stop2922" /> <stop offset="0.43689999" style="stop-color:#575757;stop-opacity:1;" id="stop2924" /> <stop offset="0.44909999" style="stop-color:#646464;stop-opacity:1;" id="stop2926" /> <stop offset="0.4605" style="stop-color:#757575;stop-opacity:1;" id="stop2928" /> <stop offset="0.47119999" style="stop-color:#8a8a8a;stop-opacity:1;" id="stop2930" /> <stop offset="0.48140001" style="stop-color:#a3a3a3;stop-opacity:1;" id="stop2932" /> <stop offset="0.49110001" style="stop-color:silver;stop-opacity:1;" id="stop2934" /> <stop offset="0.49439999" style="stop-color:#dfdfdf;stop-opacity:1;" id="stop2936" /> <stop offset="0.51748788" style="stop-color:#afafaf;stop-opacity:1;" id="stop2938" /> <stop offset="0.53259999" style="stop-color:#949494;stop-opacity:1;" id="stop2940" /> <stop offset="0.55519998" style="stop-color:#7c7c7c;stop-opacity:1;" id="stop2942" /> <stop offset="0.58454067" style="stop-color:#656565;stop-opacity:1;" id="stop2944" /> <stop offset="0.60860002" style="stop-color:#525252;stop-opacity:1;" id="stop2946" /> <stop offset="0.64160001" style="stop-color:#434343;stop-opacity:1;" id="stop2948" /> <stop offset="0.69285822" style="stop-color:#393939;stop-opacity:1;" id="stop2951" /> <stop offset="0.73979998" style="stop-color:#333;stop-opacity:1;" id="stop2953" /> <stop offset="0.89889997" style="stop-color:#313131;stop-opacity:1;" id="stop2955" /> <stop offset="1" style="stop-color:#a6a8a4;stop-opacity:1;" id="stop2957" /> </linearGradient> <radialGradient cx="265.3931" cy="-6078.353" r="253.01871" fx="369.5242" fy="-6078.353" id="path2295_1_" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.183616,0,0,-1.462967e-2,-0.962917,-7.25873)"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop8" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop10" /> <a:midPointStop style="stop-color:#000000" offset="0" /> <a:midPointStop style="stop-color:#000000" offset="0.5" /> <a:midPointStop style="stop-color:#FFFFFF" offset="1" /> </radialGradient> <filter inkscape:collect="always" x="-0.12239107" width="1.2447821" y="-0.078971461" height="1.1579429" id="filter3681"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.321914" id="feGaussianBlur3683" /> </filter> <filter inkscape:collect="always" x="-0.45196507" width="1.9039301" y="-0.29913295" height="1.5982659" id="filter3722"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.3476562" id="feGaussianBlur3724" /> </filter> <filter inkscape:collect="always" id="filter3435"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.395" id="feGaussianBlur3437" /> </filter> <filter inkscape:collect="always" id="filter3467"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.4349886" id="feGaussianBlur3469" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4009" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4011" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,-6.690938,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4013" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient4015" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4017" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-54.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4021" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4023" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4025" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4027" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4029" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4031" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,-6.690938,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4033" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient4035" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4037" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4039" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-54.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4041" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4043" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4045" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4047" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4068" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4071" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4074" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4077" gradientUnits="userSpaceOnUse" gradientTransform="translate(-16,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4080" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-46.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4085" gradientUnits="userSpaceOnUse" gradientTransform="translate(-16,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4088" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,1.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4091" gradientUnits="userSpaceOnUse" gradientTransform="translate(-20,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4095" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4098" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4101" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4104" gradientUnits="userSpaceOnUse" gradientTransform="translate(36,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4107" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,5.634754,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4112" gradientUnits="userSpaceOnUse" gradientTransform="translate(36,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4115" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4118" gradientUnits="userSpaceOnUse" gradientTransform="translate(12,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4122" gradientUnits="userSpaceOnUse" gradientTransform="translate(16,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4129" gradientUnits="userSpaceOnUse" gradientTransform="translate(32,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4132" gradientUnits="userSpaceOnUse" gradientTransform="translate(12,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4136" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-14.365246,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4139" gradientUnits="userSpaceOnUse" gradientTransform="translate(16,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4145" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,5.634754,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4156" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4162" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="matrix(0.988811,0,0,0.9872502,-4.2657949e-2,0.2039966)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4164" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="translate(20,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4167" id="linearGradient4173" x1="117.15954" y1="85.009705" x2="88.276085" y2="25.99531" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4179" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="matrix(0.9955244,0,0,0.9872502,0.3938517,0.8203689)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4181" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="translate(20,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4167" id="linearGradient4184" gradientUnits="userSpaceOnUse" gradientTransform="translate(20,0)" x1="25.151232" y1="36.751064" x2="23.062586" y2="56.203735" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="64" inkscape:cy="64" inkscape:document-units="px" inkscape:current-layer="g3936" width="128px" height="128px" showgrid="false" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" inkscape:window-width="747" inkscape:window-height="731" inkscape:window-x="0" inkscape:window-y="0" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g3936" transform="translate(20,0)"> <path style="opacity:0.53694584;fill:#004d00;fill-opacity:1;fill-rule:evenodd;stroke:#004d00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3467)" d="M 55.875,12 C 55.009497,12.02693 54.176101,12.33398 53.5,12.875 L -6.5,60.875 C -7.449856,61.63413 -8,62.78406 -8,64 C -8,65.21594 -7.449856,66.36587 -6.5,67.125 L 53.5,115.125 C 54.700963,116.08613 56.332437,116.26025 57.71875,115.59375 C 59.105067,114.92725 60.000642,113.53821 60,112 L 60,94.71875 L 85.5,115.125 C 86.70096,116.08613 88.33244,116.26025 89.71875,115.59375 C 91.10507,114.92725 92.00064,113.53821 92,112 L 92,88.3125 L 92,83.875 L 92,83.1875 L 92,78.0625 L 92,49.9375 L 92,45 L 92,44.8125 L 92,39.6875 L 92,16 C 92.00042,14.91715 91.55863,13.87882 90.78125,13.125 C 90.00387,12.37118 88.95732,11.96627 87.875,12 C 87.0095,12.02693 86.1761,12.33398 85.5,12.875 L 60,33.28125 L 60,16 C 60.000417,14.91715 59.558627,13.87882 58.78125,13.125 C 58.003873,12.37118 56.957323,11.96627 55.875,12 z " id="path3987" /> <path style="fill:url(#linearGradient4132);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 55.875,12 C 55.009497,12.02693 54.176101,12.33398 53.5,12.875 L -6.5,60.875 C -7.449856,61.63413 -8,62.78406 -8,64 C -8,65.21594 -7.449856,66.36587 -6.5,67.125 L 53.5,115.125 C 54.700963,116.08613 56.332437,116.26025 57.71875,115.59375 C 59.105067,114.92725 60.000642,113.53821 60,112 L 60,94.71875 L 85.5,115.125 C 86.70096,116.08613 88.33244,116.26025 89.71875,115.59375 C 91.10507,114.92725 92.00064,113.53821 92,112 L 92,88.3125 L 92,83.875 L 92,78.0625 L 92,49.9375 L 92,45 L 92,39.6875 L 92,16 C 92.00042,14.91715 91.55863,13.87882 90.78125,13.125 C 90.00387,12.37118 88.95732,11.96627 87.875,12 C 87.0095,12.02693 86.1761,12.33398 85.5,12.875 L 60,33.28125 L 60,16 C 60.000417,14.91715 59.558627,13.87882 58.78125,13.125 C 58.003873,12.37118 56.957323,11.96627 55.875,12 z M 52,24.3125 L 52,39.6875 L 46.59375,44 L 37,44 C 36.446,44 36,44.446 36,45 L 36,52.46875 L 25.5,60.875 C 24.550144,61.63413 24,62.78406 24,64 C 24,65.21594 24.550144,66.36587 25.5,67.125 L 36,75.53125 L 36,83.875 C 36,84.429 36.446,84.875 37,84.875 L 47.6875,84.875 L 52,88.3125 L 52,103.6875 L 2.40625,64 L 52,24.3125 z M 84,24.3125 L 84,44 L 69,44 C 68.446,44 68,44.446 68,45 L 68,83.875 C 68,84.429 68.446,84.875 69,84.875 L 84,84.875 L 84,103.6875 L 60,84.46875 L 60,83.875 L 60,78.0625 L 60,49.9375 L 60,45 L 60,43.53125 L 84,24.3125 z M 36,62.71875 L 36,65.28125 L 34.40625,64 L 36,62.71875 z " id="path3989" /> <path style="opacity:0.53694584;fill:url(#linearGradient4122);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 55.875,12 C 55.009497,12.02693 54.176101,12.33398 53.5,12.875 L -6.5,60.875 C -7.449856,61.63413 -8,62.78406 -8,64 C -8,65.21594 -7.449856,66.36587 -6.5,67.125 L 53.5,115.125 C 54.700963,116.08613 56.332437,116.26025 57.71875,115.59375 C 59.105067,114.92725 60.000642,113.53821 60,112 L 60,94.71875 L 85.5,115.125 C 86.70096,116.08613 88.33244,116.26025 89.71875,115.59375 C 91.10507,114.92725 92.00064,113.53821 92,112 L 92,88.3125 L 92,83.875 L 92,83.1875 L 92,78.0625 L 92,49.9375 L 92,45 L 92,44.8125 L 92,39.6875 L 92,16 C 92.00042,14.91715 91.55863,13.87882 90.78125,13.125 C 90.00387,12.37118 88.95732,11.96627 87.875,12 C 87.0095,12.02693 86.1761,12.33398 85.5,12.875 L 60,33.28125 L 60,16 C 60.000417,14.91715 59.558627,13.87882 58.78125,13.125 C 58.003873,12.37118 56.957323,11.96627 55.875,12 z M 52,24.3125 L 52,39.6875 L 46.59375,44 L 37,44 C 36.446,44 36,44.446 36,45 L 36,52.46875 L 25.5,60.875 C 24.550144,61.63413 24,62.78406 24,64 C 24,65.21594 24.550144,66.36587 25.5,67.125 L 36,75.53125 L 36,83.875 C 36,84.429 36.446,84.875 37,84.875 L 47.6875,84.875 L 52,88.3125 L 52,103.6875 L 2.40625,64 L 52,24.3125 z M 84,24.3125 L 84,44 L 69,44 C 68.446,44 68,44.446 68,45 L 68,83.875 C 68,84.429 68.446,84.875 69,84.875 L 84,84.875 L 84,103.6875 L 60,84.46875 L 60,83.875 L 60,83.1875 L 60,78.0625 L 60,49.9375 L 60,45 L 60,44.8125 L 60,43.53125 L 84,24.3125 z M 36,62.71875 L 36,65.28125 L 34.40625,64 L 36,62.71875 z " id="path3993" /> <path style="fill:url(#radialGradient4136);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 56,16 L -4,64 L 56,112 L 56,86.40625 L 88,112 L 88,80 L 88,48 L 88,16 L 56,41.59375 L 56,16 z " id="path3999" /> <path style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4139);stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3435)" d="M 56,16 L -4,64 L 56,112 L 56,86.40625 L 88,112 L 88,80 L 88,48 L 88,16 L 56,41.59375 L 56,16 z " id="path4001" /> <path style="opacity:0.85;fill:url(#radialGradient4115);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " id="path3991" /> <path id="path3995" d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " style="opacity:0.35;fill:url(#radialGradient4015);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" transform="matrix(1,0,0,-1,16,127.7793)" /> <path id="path3651" d="M 55.875,12 C 55.075959,12.024867 54.302054,12.283948 53.65625,12.75 L 54.625,21.78125 L 59.96875,15.625 C 59.880958,14.678789 59.469257,13.792159 58.78125,13.125 C 58.003873,12.37118 56.957323,11.966273 55.875,12 z " style="opacity:0.85;fill:url(#radialGradient4088);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> <path transform="matrix(1,0,0,-1,-16,127.7793)" style="opacity:0.35;fill:url(#radialGradient4035);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " id="path3685" /> <path transform="matrix(1,0,0,-1,-16,128.5625)" id="path3705" d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " style="opacity:0.5;fill:url(#radialGradient4037);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> <path style="fill:url(#linearGradient4156);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 56,16 L -3.8125,63.84375 C 4.238841,64.168797 12.513445,64.34375 20.90625,64.34375 C 44.837882,64.34375 67.533203,62.960664 88,60.5 L 88,48 L 88,16 L 56,41.59375 L 56,16 z " id="path4143" /> <path style="fill:url(#linearGradient4173);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 76,16 L 75.34375,16.53125 L 75.34375,41.28125 L 76,40.75 L 76,16 z M 108,16 L 107.46875,16.8125 L 107.46875,47.59375 L 107.46875,59.9375 C 87.230955,62.366791 64.288861,63.718749 40.625,63.71875 C 32.585491,63.71875 24.663189,63.551875 16.9375,63.25 L 16.1875,63.84375 C 24.238841,64.168797 32.513445,64.34375 40.90625,64.34375 C 64.837882,64.34375 87.533203,62.960664 108,60.5 L 108,48 L 108,16 z " transform="translate(-20,0)" id="path4158" sodipodi:nodetypes="cccccccccsccsccc" /> <path style="fill:url(#linearGradient4184);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 76 16 L 16.1875 63.84375 C 16.321516 63.84916 16.45961 63.838423 16.59375 63.84375 L 76 16.75 L 76 16 z M 108 16 L 76.15625 41.46875 L 76.15625 41.875 L 108 16.625 L 108 16 z " transform="translate(-20,0)" id="path4175" /> </g> </g> </svg> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/edit-paste.svg�������������������������������������������������������0000644�0001750�0000144�00000257041�11151311737�017311� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> <svg xmlns:ns="http://ns.adobe.com/SaveForWeb/1.0/" xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" id="Layer_1" width="128" height="128" viewBox="0 0 128 128" overflow="visible" enable-background="new 0 0 128 128" xml:space="preserve" sodipodi:version="0.32" inkscape:version="0.45+devel" sodipodi:docname="edit-paste.svg" sodipodi:docbase="/home/pinheiro/Documents/pics/trabalhos pagos2007/gexcon/128x128" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:export-filename="/home/pinheiro/pics/oxygen/22x22/actions/edit-paste.png" inkscape:export-xdpi="15.46875" inkscape:export-ydpi="15.46875"><defs id="defs105"><linearGradient inkscape:collect="always" id="linearGradient4811"><stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop4813" /><stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop4815" /></linearGradient><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient4207"> <stop id="stop4209" style="stop-color:#FFEA00" offset="0" /> <stop id="stop4211" style="stop-color:#c17900;stop-opacity:1" offset="1" /> </linearGradient><linearGradient inkscape:collect="always" id="linearGradient4077"><stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop4079" /><stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop4081" /></linearGradient><linearGradient inkscape:collect="always" id="linearGradient4005"><stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop4007" /><stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop4009" /></linearGradient><linearGradient inkscape:collect="always" xlink:href="#linearGradient2575" id="linearGradient3816" x1="12.848921" y1="34.078983" x2="88.5625" y2="165.21875" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9696099,0,0,0.9809017,-3.8713421,0.6517971)" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient3287"> <stop id="stop3289" style="stop-color:#FFEA00" offset="0" /> <stop id="stop3291" style="stop-color:#ffa000;stop-opacity:1;" offset="1" /> </linearGradient><linearGradient id="linearGradient3291"><stop style="stop-color:black;stop-opacity:1" offset="0" id="stop3293" /><stop style="stop-color:black;stop-opacity:0" offset="1" id="stop3295" /></linearGradient><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient18668"> <stop id="stop18670" style="stop-color:#fff8a8;stop-opacity:1;" offset="0" /> <stop id="stop18672" style="stop-color:white;stop-opacity:0;" offset="1" /> </linearGradient><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient15967"> <stop id="stop15969" style="stop-color:white;stop-opacity:1;" offset="0" /> <stop id="stop15971" style="stop-color:white;stop-opacity:0;" offset="1" /> </linearGradient><linearGradient id="XMLID_2_" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop12" /> <stop offset="1" style="stop-color:#FFCC00" id="stop14" /> </linearGradient><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient2391" gradientUnits="userSpaceOnUse" x1="94.3438" y1="102.3447" x2="86.5356" y2="94.5366" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient2393" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="86.5865" y2="94.5865" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient2395" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="87.293" y2="95.293" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient2397" gradientUnits="userSpaceOnUse" x1="96" y1="104" x2="88.0002" y2="96.0002" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient2465" gradientUnits="userSpaceOnUse" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient2467" gradientUnits="userSpaceOnUse" cx="102" cy="112.3047" r="139.55859" /> <foreignObject requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/" x="0" y="0" width="1" height="1" id="foreignObject7"> <i:pgfRef xlink:href="#adobe_illustrator_pgf"> </i:pgfRef> </foreignObject> <linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient12378" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient14180" gradientUnits="userSpaceOnUse" x1="-74.820707" y1="100.82378" x2="-18.121965" y2="100.82378" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient14189" gradientUnits="userSpaceOnUse" x1="-74.820707" y1="100.82378" x2="-18.121965" y2="100.82378" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient15967" id="linearGradient15973" gradientUnits="userSpaceOnUse" x1="27.719746" y1="7.881104" x2="27.719746" y2="30.441185" gradientTransform="translate(1.470416e-5,0)" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient15977" gradientUnits="userSpaceOnUse" x1="-74.820707" y1="100.82378" x2="-18.121965" y2="100.82378" /><radialGradient inkscape:collect="always" xlink:href="#linearGradient15967" id="radialGradient15986" cx="26.954102" cy="31.045055" fx="26.954102" fy="31.045055" r="8.968153" gradientTransform="matrix(0.754978,-2.959381e-2,0,0.905772,7.650275,10.87807)" gradientUnits="userSpaceOnUse" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient18657" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /> <linearGradient id="linearGradient18649" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop18651" /> <stop offset="1" style="stop-color:#FFCC00" id="stop18653" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient18674" gradientUnits="userSpaceOnUse" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient18744" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient18746" gradientUnits="userSpaceOnUse" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient18749" gradientUnits="userSpaceOnUse" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" gradientTransform="translate(69.54139,-45.18897)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient4708" gradientUnits="userSpaceOnUse" gradientTransform="translate(69.54139,-45.18897)" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3287" id="linearGradient3456" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /> <linearGradient id="linearGradient3446" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop3448" /> <stop offset="1" style="stop-color:#FFCC00" id="stop3450" /> </linearGradient> <radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.1822917,0,36.388019)" r="48" fy="44.499996" fx="-85.9375" cy="44.499996" cx="-85.9375" id="radialGradient4153" xlink:href="#linearGradient3290" inkscape:collect="always" /><linearGradient y2="96.142189" x2="78.843246" y1="139.71719" x1="78.843246" gradientTransform="matrix(1,0,0,1.016882,-149.9375,-1.0166985)" gradientUnits="userSpaceOnUse" id="linearGradient4150" xlink:href="#linearGradient3291" inkscape:collect="always" /><linearGradient y2="56.623283" x2="-22.311716" y1="56.623283" x1="75.130096" gradientTransform="matrix(1,0,0,1.016882,-149.9375,-1.0166985)" gradientUnits="userSpaceOnUse" id="linearGradient4148" xlink:href="#radialGradient3888" inkscape:collect="always" /><radialGradient r="52" fy="3.9355147" fx="54.254757" cy="3.9355147" cx="54.254757" gradientTransform="matrix(1.23137,0,0,1.730769,-165.54517,-5.5510275)" gradientUnits="userSpaceOnUse" id="radialGradient4146" xlink:href="#radialGradient4016" inkscape:collect="always" /><linearGradient y2="116.65697" x2="63.9995" y1="25.1577" x1="63.9995" gradientTransform="matrix(1,0,0,1.016882,-149.9375,-1.0166985)" gradientUnits="userSpaceOnUse" id="linearGradient4144" xlink:href="#linearGradient3287" inkscape:collect="always" /><radialGradient r="52" fy="0.17394008" fx="64" cy="0.17394008" cx="64" gradientTransform="matrix(1.23137,0,0,1.730769,-164.74518,-7.0510245)" gradientUnits="userSpaceOnUse" id="radialGradient4140" xlink:href="#linearGradient3785" inkscape:collect="always" /><linearGradient inkscape:collect="always" id="linearGradient3465"><stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3467" /><stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3469" /></linearGradient><linearGradient id="linearGradient3443"><stop style="stop-color:#747474;stop-opacity:1;" offset="0" id="stop3445" /><stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop3447" /></linearGradient><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient3785"> <stop id="stop3787" style="stop-color:#FFEA00" offset="0" /> <stop id="stop3789" style="stop-color:#f49900;stop-opacity:1;" offset="1" /> </linearGradient><linearGradient id="linearGradient3791"><stop style="stop-color:black;stop-opacity:1" offset="0" id="stop3793" /><stop style="stop-color:black;stop-opacity:0" offset="1" id="stop3795" /></linearGradient><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient3797"> <stop id="stop3799" style="stop-color:#fff8a8;stop-opacity:1;" offset="0" /> <stop id="stop3801" style="stop-color:white;stop-opacity:0;" offset="1" /> </linearGradient><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient3803"> <stop id="stop3805" style="stop-color:white;stop-opacity:1;" offset="0" /> <stop id="stop3807" style="stop-color:white;stop-opacity:0;" offset="1" /> </linearGradient><linearGradient id="linearGradient3809" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop3811" /> <stop offset="1" style="stop-color:#FFCC00" id="stop3813" /> </linearGradient><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient3815" gradientUnits="userSpaceOnUse" x1="94.3438" y1="102.3447" x2="86.5356" y2="94.5366" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient3817" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="86.5865" y2="94.5865" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient3819" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="87.293" y2="95.293" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient3821" gradientUnits="userSpaceOnUse" x1="96" y1="104" x2="88.0002" y2="96.0002" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient3823" gradientUnits="userSpaceOnUse" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient3825" gradientUnits="userSpaceOnUse" cx="102" cy="112.3047" r="139.55859" /> <foreignObject requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/" x="0" y="0" width="1" height="1" id="foreignObject3827"> <i:pgfRef xlink:href="#adobe_illustrator_pgf"> </i:pgfRef> </foreignObject> <linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient3829" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient3831" gradientUnits="userSpaceOnUse" x1="-74.820707" y1="100.82378" x2="-18.121965" y2="100.82378" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient3833" gradientUnits="userSpaceOnUse" x1="-74.820707" y1="100.82378" x2="-18.121965" y2="100.82378" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient15967" id="linearGradient3835" gradientUnits="userSpaceOnUse" x1="27.719746" y1="7.881104" x2="27.719746" y2="30.441185" gradientTransform="translate(1.470416e-5,0)" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2309" id="linearGradient3837" gradientUnits="userSpaceOnUse" x1="-74.820707" y1="100.82378" x2="-18.121965" y2="100.82378" /><radialGradient inkscape:collect="always" xlink:href="#linearGradient15967" id="radialGradient3839" cx="26.954102" cy="31.045055" fx="26.954102" fy="31.045055" r="8.968153" gradientTransform="matrix(0.754978,-2.959381e-2,0,0.905772,7.650275,10.87807)" gradientUnits="userSpaceOnUse" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient3841" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /> <linearGradient id="linearGradient3843" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop3845" /> <stop offset="1" style="stop-color:#FFCC00" id="stop3847" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient3849" gradientUnits="userSpaceOnUse" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_2_" id="linearGradient3851" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient3853" gradientUnits="userSpaceOnUse" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient3855" gradientUnits="userSpaceOnUse" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" gradientTransform="translate(69.54139,-45.18897)" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient3857" gradientUnits="userSpaceOnUse" cx="102" cy="112.3047" r="139.55859" fx="101.5" fy="112" gradientTransform="translate(-8,0)" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient3859" gradientUnits="userSpaceOnUse" cx="102" cy="112.3047" r="139.5585" gradientTransform="translate(-8,0)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient3861" gradientUnits="userSpaceOnUse" x1="96" y1="104" x2="88.0002" y2="96.0002" gradientTransform="translate(-2,4)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient3863" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="87.293" y2="95.293" gradientTransform="translate(-2,4)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient3865" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="86.5865" y2="94.5865" gradientTransform="translate(-2,4)" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient3867" gradientUnits="userSpaceOnUse" x1="94.3438" y1="102.3447" x2="86.5356" y2="94.5366" gradientTransform="translate(-2,4)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient18668" id="linearGradient3869" gradientUnits="userSpaceOnUse" gradientTransform="translate(69.54139,-45.18897)" x1="-39.53125" y1="78" x2="-39.53125" y2="51.1875" /> <linearGradient id="linearGradient3875" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop3877" /> <stop offset="1" style="stop-color:#FFCC00" id="stop3879" /> </linearGradient> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3560"><path sodipodi:nodetypes="cccc" id="path3562" d="M 174,120 C 150.49117,120 164,89.333333 159,74 C 175.06733,78.466333 206,73.457434 206,88 L 174,120 z " style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3554)" /></clipPath><radialGradient r="122.3935" fy="24.1598" fx="63.066601" cy="6.0488" cx="42.378899" gradientTransform="matrix(1.0151,0,0,1.0491,-1.0186,-1.3463)" gradientUnits="userSpaceOnUse" id="radialGradient3954" xlink:href="#XMLID_6_" inkscape:collect="always" /><linearGradient y2="157.6319" x2="63.9995" y1="25.1577" x1="63.9995" gradientTransform="matrix(1,0,0,0.635551,0,42.02081)" gradientUnits="userSpaceOnUse" id="linearGradient1922" xlink:href="#XMLID_7_" inkscape:collect="always" /><linearGradient y2="56.623283" x2="129.05333" y1="56.623283" x1="0" gradientTransform="matrix(1,0,0,1.016882,0,-0.766697)" gradientUnits="userSpaceOnUse" id="linearGradient5885" xlink:href="#XMLID_8_" inkscape:collect="always" /> <radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0151,0,0,1.0491,-1.0186,-1.3463)" fy="24.1598" fx="63.066601" r="122.3935" cy="6.0488" cx="42.378899" id="radialGradient3888"> <stop id="stop3890" style="stop-color:#FFFFFF" offset="0" /> <stop id="stop3892" style="stop-color:#DDDDDD" offset="1" /> </radialGradient> <linearGradient id="linearGradient2355" gradientUnits="userSpaceOnUse" x1="-37.875" y1="48.787102" x2="230.237" y2="48.787102"> <stop offset="0" style="stop-color:#a2c3eb;stop-opacity:0.50196081;" id="stop2357" /> <stop offset="0.12634172" style="stop-color:white;stop-opacity:1;" id="stop2359" /><stop id="stop3897" style="stop-color:white;stop-opacity:1;" offset="0.80858696" /> <stop offset="1" style="stop-color:#a7cbf7;stop-opacity:0.50196081;" id="stop2362" /> </linearGradient> <linearGradient id="linearGradient2345" gradientUnits="userSpaceOnUse" x1="63.9995" y1="25.1577" x2="63.9995" y2="157.6319"> <stop offset="0" style="stop-color:#BFD9FF" id="stop2347" /> <stop offset="0.2189" style="stop-color:#80B3FF" id="stop2349" /> <stop offset="0.2933" style="stop-color:#6EA5F3" id="stop3903" /> <stop offset="0.4426" style="stop-color:#3E80D3" id="stop3905" /> <stop offset="0.4941" style="stop-color:#2C72C7" id="stop3907" /> <stop offset="0.7" style="stop-color:#00438A" id="stop3909" /> </linearGradient> <radialGradient gradientTransform="translate(-103.157,-34.959)" id="radialGradient3911" cx="51.9995" cy="-9" r="111.0006" gradientUnits="userSpaceOnUse"> <stop offset="0.15" style="stop-color:#80B3FF" id="stop2338" /> <stop offset="0.316" style="stop-color:#69A1F0" id="stop2340" /> <stop offset="0.6029" style="stop-color:#4888DA" id="stop3915" /> <stop offset="0.8412" style="stop-color:#3378CC" id="stop3917" /> <stop offset="1" style="stop-color:#2C72C7" id="stop3919" /> </radialGradient> <foreignObject requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/" x="0" y="0" width="1" height="1" id="foreignObject2335"> <i:pgfRef xlink:href="#adobe_illustrator_pgf"> </i:pgfRef> </foreignObject> <radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0151,0,0,1.0491,-1.0186,-1.3463)" fy="24.1598" fx="63.066601" r="122.3935" cy="6.0488" cx="42.378899" id="radialGradient3922"> <stop id="stop3924" style="stop-color:#FFFFFF" offset="0" /><stop offset="0.59375" style="stop-color:white;stop-opacity:1;" id="stop3926" /> <stop id="stop3928" style="stop-color:white;stop-opacity:0.70886075;" offset="1" /> </radialGradient><radialGradient id="radialGradient3930" cx="42.378899" cy="6.0488" r="122.3935" fx="63.066601" fy="24.1598" gradientTransform="matrix(1.0151,0,0,1.0491,-1.0186,-1.3463)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#00438a;stop-opacity:0;" id="stop3932" /> <stop offset="1" style="stop-color:#00438a;stop-opacity:1;" id="stop3934" /> </radialGradient><linearGradient id="linearGradient2321"><stop id="stop2323" offset="0" style="stop-color:black;stop-opacity:1" /><stop id="stop2325" offset="1" style="stop-color:black;stop-opacity:0" /></linearGradient><linearGradient inkscape:collect="always" xlink:href="#radialGradient4962" id="linearGradient2396" gradientUnits="userSpaceOnUse" gradientTransform="translate(-147.5,22.440458)" x1="64" y1="39.358757" x2="55.187801" y2="72.246338" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient18649" id="linearGradient2400" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.635551,-147.5,42.461268)" x1="63.9995" y1="25.1577" x2="63.9995" y2="157.6319" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2321" id="linearGradient2403" gradientUnits="userSpaceOnUse" gradientTransform="translate(-147.5,22.440458)" x1="66.82843" y1="73.299881" x2="66.82843" y2="36" /><radialGradient inkscape:collect="always" xlink:href="#radialGradient4016" id="radialGradient2413" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.23137,0,0,1.730769,-161.30768,-3.860568)" cx="31.268095" cy="5.2808232" fx="31.268095" fy="5.2808232" r="52" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3287" id="linearGradient2416" gradientUnits="userSpaceOnUse" x1="61.572254" y1="-16" x2="61.803467" y2="-98.624275" gradientTransform="translate(-147.5,-2.440458)" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3443" id="linearGradient3449" x1="-147.5" y1="74.268583" x2="-108.55761" y2="74.268585" gradientUnits="userSpaceOnUse" /><radialGradient inkscape:collect="always" xlink:href="#radialGradient4016" id="radialGradient3453" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.23137,0,0,-1.730769,-51.782417,67.30103)" cx="31.268095" cy="5.2808232" fx="31.268095" fy="5.2808232" r="52" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3465" id="linearGradient3471" x1="-83.500114" y1="127.94046" x2="-83.500114" y2="104.94046" gradientUnits="userSpaceOnUse" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3287" id="linearGradient3473" gradientUnits="userSpaceOnUse" gradientTransform="translate(-147.5,-2.440458)" x1="61.572254" y1="-16" x2="61.803467" y2="-98.624275" /><radialGradient inkscape:collect="always" xlink:href="#radialGradient4016" id="radialGradient3475" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.23137,0,0,1.730769,-161.30768,-3.860568)" cx="31.268095" cy="5.2808232" fx="31.268095" fy="5.2808232" r="52" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2321" id="linearGradient3477" gradientUnits="userSpaceOnUse" gradientTransform="translate(-147.5,22.440458)" x1="66.82843" y1="73.299881" x2="66.82843" y2="36" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient18649" id="linearGradient3479" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.635551,-147.5,42.461268)" x1="63.9995" y1="25.1577" x2="63.9995" y2="157.6319" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3443" id="linearGradient3481" gradientUnits="userSpaceOnUse" x1="-147.5" y1="74.268583" x2="-108.55761" y2="74.268585" /><clipPath id="clipPath2536" clipPathUnits="userSpaceOnUse"><path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3554)" d="M 174,120 C 150.49117,120 164,89.333333 159,74 C 175.06733,78.466333 206,73.457434 206,88 L 174,120 z " id="path2538" sodipodi:nodetypes="cccc" /></clipPath> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2525"> <stop id="stop2527" style="stop-color:#FFEA00" offset="0" /> <stop id="stop2529" style="stop-color:#FFCC00" offset="1" /> </linearGradient> <linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientTransform="translate(69.54139,-45.18897)" gradientUnits="userSpaceOnUse" id="linearGradient2516" xlink:href="#linearGradient18668" inkscape:collect="always" /> <linearGradient gradientTransform="translate(8,0)" y2="94.5366" x2="86.5356" y1="102.3447" x1="94.3438" gradientUnits="userSpaceOnUse" id="linearGradient2514" xlink:href="#XMLID_9_" inkscape:collect="always" /><linearGradient gradientTransform="translate(8,0)" y2="94.5865" x2="86.5865" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2512" xlink:href="#XMLID_10_" inkscape:collect="always" /><linearGradient gradientTransform="translate(8,0)" y2="95.293" x2="87.293" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2510" xlink:href="#XMLID_11_" inkscape:collect="always" /><linearGradient gradientTransform="translate(8,0)" y2="96.0002" x2="88.0002" y1="104" x1="96" gradientUnits="userSpaceOnUse" id="linearGradient2508" xlink:href="#XMLID_12_" inkscape:collect="always" /><radialGradient r="139.5585" cy="112.3047" cx="102" gradientTransform="translate(8,0)" gradientUnits="userSpaceOnUse" id="radialGradient2506" xlink:href="#XMLID_7_" inkscape:collect="always" /><radialGradient fy="112" fx="101.5" r="139.55859" cy="112.3047" cx="102" gradientTransform="translate(8,0)" gradientUnits="userSpaceOnUse" id="radialGradient2504" xlink:href="#XMLID_8_" inkscape:collect="always" /><linearGradient gradientTransform="translate(69.54139,-45.18897)" y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient2502" xlink:href="#linearGradient18668" inkscape:collect="always" /><linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient2500" xlink:href="#linearGradient18668" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2498" xlink:href="#XMLID_2_" inkscape:collect="always" /><linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient2496" xlink:href="#linearGradient18668" inkscape:collect="always" /> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2490"> <stop id="stop2492" style="stop-color:#FFEA00" offset="0" /> <stop id="stop2494" style="stop-color:#FFCC00" offset="1" /> </linearGradient> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2488" xlink:href="#XMLID_2_" inkscape:collect="always" /><radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.754978,-2.959381e-2,0,0.905772,7.650275,10.87807)" r="8.968153" fy="31.045055" fx="26.954102" cy="31.045055" cx="26.954102" id="radialGradient2486" xlink:href="#linearGradient15967" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient2484" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient gradientTransform="translate(1.470416e-5,0)" y2="30.441185" x2="27.719746" y1="7.881104" x1="27.719746" gradientUnits="userSpaceOnUse" id="linearGradient2482" xlink:href="#linearGradient15967" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient2480" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient2478" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2476" xlink:href="#XMLID_2_" inkscape:collect="always" /> <foreignObject id="foreignObject2474" height="1" width="1" y="0" x="0" requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/"> <i:pgfRef xlink:href="#adobe_illustrator_pgf"> </i:pgfRef> </foreignObject> <radialGradient r="139.55859" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient2472" xlink:href="#XMLID_8_" inkscape:collect="always" /><radialGradient r="139.5585" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient2470" xlink:href="#XMLID_7_" inkscape:collect="always" /><linearGradient y2="96.0002" x2="88.0002" y1="104" x1="96" gradientUnits="userSpaceOnUse" id="linearGradient2468" xlink:href="#XMLID_12_" inkscape:collect="always" /><linearGradient y2="95.293" x2="87.293" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2466" xlink:href="#XMLID_11_" inkscape:collect="always" /><linearGradient y2="94.5865" x2="86.5865" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2464" xlink:href="#XMLID_10_" inkscape:collect="always" /><linearGradient y2="94.5366" x2="86.5356" y1="102.3447" x1="94.3438" gradientUnits="userSpaceOnUse" id="linearGradient2462" xlink:href="#XMLID_9_" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2456"> <stop id="stop2458" style="stop-color:#FFEA00" offset="0" /> <stop id="stop2460" style="stop-color:#FFCC00" offset="1" /> </linearGradient><linearGradient id="linearGradient2450" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:white;stop-opacity:1;" id="stop2452" /> <stop offset="1" style="stop-color:white;stop-opacity:0;" id="stop2454" /> </linearGradient><linearGradient id="linearGradient2444" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#fff8a8;stop-opacity:1;" id="stop2446" /> <stop offset="1" style="stop-color:white;stop-opacity:0;" id="stop4003" /> </linearGradient><linearGradient id="linearGradient2438"><stop id="stop2440" offset="0" style="stop-color:black;stop-opacity:1" /><stop id="stop2442" offset="1" style="stop-color:black;stop-opacity:0" /></linearGradient><linearGradient id="linearGradient2432" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop2434" /> <stop offset="1" style="stop-color:#ffa000;stop-opacity:1;" id="stop2436" /> </linearGradient><linearGradient id="linearGradient1563"><stop id="stop1565" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /><stop id="stop1567" offset="1" style="stop-color:white;stop-opacity:0;" /></linearGradient><linearGradient id="linearGradient12948"><stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop12950" /><stop style="stop-color:#c0c0c0;stop-opacity:0;" offset="1" id="stop12952" /></linearGradient><linearGradient id="linearGradient3638"><stop style="stop-color:#ffffff;stop-opacity:0;" offset="0" id="stop3640" /><stop id="stop3661" offset="0.06868132" style="stop-color:#ffffff;stop-opacity:1;" /><stop id="stop3659" offset="0.5" style="stop-color:#ffffff;stop-opacity:1;" /><stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3642" /></linearGradient><linearGradient id="linearGradient3273"><stop id="stop3275" offset="0" style="stop-color:#ffffff;stop-opacity:0.55035973;" /><stop id="stop3277" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /></linearGradient><linearGradient id="linearGradient3290"><stop style="stop-color:yellow;stop-opacity:1;" offset="0" id="stop3292" /><stop style="stop-color:#ffb66d;stop-opacity:1;" offset="1" id="stop3294" /></linearGradient><linearGradient id="linearGradient2407"><stop style="stop-color:black;stop-opacity:1" offset="0" id="stop2409" /><stop style="stop-color:black;stop-opacity:0" offset="1" id="stop2411" /></linearGradient><radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0151,0,0,1.0491,-1.0186,-1.3463)" fy="24.1598" fx="63.066601" r="122.3935" cy="6.0488" cx="42.378899" id="radialGradient4962"> <stop id="stop4964" style="stop-color:#00438a;stop-opacity:0;" offset="0" /> <stop id="stop4970" style="stop-color:#00438a;stop-opacity:1;" offset="1" /> </radialGradient><radialGradient id="radialGradient4016" cx="42.378899" cy="6.0488" r="122.3935" fx="63.066601" fy="24.1598" gradientTransform="matrix(1.0151,0,0,1.0491,-1.0186,-1.3463)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop4018" /><stop id="stop4026" style="stop-color:white;stop-opacity:1;" offset="0.59375" /> <stop offset="1" style="stop-color:white;stop-opacity:0.70886075;" id="stop4020" /> </radialGradient> <foreignObject id="foreignObject2421" height="1" width="1" y="0" x="0" requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/"> <i:pgfRef xlink:href="#adobe_illustrator_pgf"> </i:pgfRef> </foreignObject> <radialGradient gradientUnits="userSpaceOnUse" r="111.0006" cy="-9" cx="51.9995" id="XMLID_5_" gradientTransform="translate(-103.157,-34.959)"> <stop id="stop2424" style="stop-color:#80B3FF" offset="0.15" /> <stop id="stop2426" style="stop-color:#69A1F0" offset="0.316" /> <stop id="stop18" style="stop-color:#4888DA" offset="0.6029" /> <stop id="stop20" style="stop-color:#3378CC" offset="0.8412" /> <stop id="stop22" style="stop-color:#2C72C7" offset="1" /> </radialGradient> <linearGradient y2="157.6319" x2="63.9995" y1="25.1577" x1="63.9995" gradientUnits="userSpaceOnUse" id="linearGradient2431"> <stop id="stop2433" style="stop-color:#BFD9FF" offset="0" /> <stop id="stop2435" style="stop-color:#80B3FF" offset="0.2189" /> <stop id="stop80" style="stop-color:#6EA5F3" offset="0.2933" /> <stop id="stop82" style="stop-color:#3E80D3" offset="0.4426" /> <stop id="stop84" style="stop-color:#2C72C7" offset="0.4941" /> <stop id="stop86" style="stop-color:#00438A" offset="0.7" /> </linearGradient> <linearGradient y2="48.787102" x2="230.237" y1="48.787102" x1="-37.875" gradientUnits="userSpaceOnUse" id="linearGradient2441"> <stop id="stop2443" style="stop-color:#a2c3eb;stop-opacity:0.50196081;" offset="0" /> <stop id="stop2445" style="stop-color:#FFFFFF" offset="0.12634172" /><stop offset="0.80858696" style="stop-color:white;stop-opacity:1;" id="stop4930" /> <stop id="stop2448" style="stop-color:#a7cbf7;stop-opacity:0.50196081;" offset="1" /> </linearGradient> <radialGradient id="XMLID_6_" cx="42.378899" cy="6.0488" r="122.3935" fx="63.066601" fy="24.1598" gradientTransform="matrix(1.0151,0,0,1.0491,-1.0186,-1.3463)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop33" /> <stop offset="0.3728" style="stop-color:#DDDDDD" id="stop35" /> <stop offset="0.7692" style="stop-color:#BABDB6" id="stop2456" /> <stop offset="1" style="stop-color:#888888" id="stop39" /> </radialGradient> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2667"> <stop id="stop2669" style="stop-color:#FFEA00" offset="0" /> <stop id="stop2671" style="stop-color:#FFCC00" offset="1" /> </linearGradient> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2665" xlink:href="#linearGradient3287" inkscape:collect="always" /><linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientTransform="translate(69.54139,-45.18897)" gradientUnits="userSpaceOnUse" id="linearGradient2659" xlink:href="#linearGradient18668" inkscape:collect="always" /> <linearGradient gradientTransform="translate(-12,0)" y2="94.5366" x2="86.5356" y1="102.3447" x1="94.3438" gradientUnits="userSpaceOnUse" id="linearGradient2657" xlink:href="#XMLID_9_" inkscape:collect="always" /><linearGradient gradientTransform="translate(-12,0)" y2="94.5865" x2="86.5865" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2655" xlink:href="#XMLID_10_" inkscape:collect="always" /><linearGradient gradientTransform="translate(-12,0)" y2="95.293" x2="87.293" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2653" xlink:href="#XMLID_11_" inkscape:collect="always" /><linearGradient gradientTransform="translate(-12,0)" y2="96.0002" x2="88.0002" y1="104" x1="96" gradientUnits="userSpaceOnUse" id="linearGradient2651" xlink:href="#XMLID_12_" inkscape:collect="always" /><radialGradient gradientTransform="translate(-12,0)" r="139.5585" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient2649" xlink:href="#XMLID_7_" inkscape:collect="always" /><radialGradient gradientTransform="translate(-12,0)" r="139.55859" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient2647" xlink:href="#XMLID_8_" inkscape:collect="always" /><linearGradient gradientTransform="translate(69.54139,-45.18897)" y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient2645" xlink:href="#linearGradient18668" inkscape:collect="always" /><linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient2643" xlink:href="#linearGradient18668" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2641" xlink:href="#XMLID_2_" inkscape:collect="always" /><linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient2639" xlink:href="#linearGradient18668" inkscape:collect="always" /> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2633"> <stop id="stop2635" style="stop-color:#FFEA00" offset="0" /> <stop id="stop2637" style="stop-color:#FFCC00" offset="1" /> </linearGradient> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2631" xlink:href="#XMLID_2_" inkscape:collect="always" /><radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.754978,-2.959381e-2,0,0.905772,7.650275,10.87807)" r="8.968153" fy="31.045055" fx="26.954102" cy="31.045055" cx="26.954102" id="radialGradient2629" xlink:href="#linearGradient15967" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient2627" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient gradientTransform="translate(1.470416e-5,0)" y2="30.441185" x2="27.719746" y1="7.881104" x1="27.719746" gradientUnits="userSpaceOnUse" id="linearGradient2625" xlink:href="#linearGradient15967" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient2623" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient2621" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2619" xlink:href="#XMLID_2_" inkscape:collect="always" /> <foreignObject id="foreignObject2617" height="1" width="1" y="0" x="0" requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/"> <i:pgfRef xlink:href="#adobe_illustrator_pgf"> </i:pgfRef> </foreignObject> <radialGradient r="139.55859" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient2615" xlink:href="#XMLID_8_" inkscape:collect="always" /><radialGradient r="139.5585" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient2613" xlink:href="#XMLID_7_" inkscape:collect="always" /><linearGradient y2="96.0002" x2="88.0002" y1="104" x1="96" gradientUnits="userSpaceOnUse" id="linearGradient2611" xlink:href="#XMLID_12_" inkscape:collect="always" /><linearGradient y2="95.293" x2="87.293" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2609" xlink:href="#XMLID_11_" inkscape:collect="always" /><linearGradient y2="94.5865" x2="86.5865" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2607" xlink:href="#XMLID_10_" inkscape:collect="always" /><linearGradient y2="94.5366" x2="86.5356" y1="102.3447" x1="94.3438" gradientUnits="userSpaceOnUse" id="linearGradient2605" xlink:href="#XMLID_9_" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2599"> <stop id="stop2601" style="stop-color:#FFEA00" offset="0" /> <stop id="stop2603" style="stop-color:#FFCC00" offset="1" /> </linearGradient><linearGradient id="linearGradient2593" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:white;stop-opacity:1;" id="stop2595" /> <stop offset="1" style="stop-color:white;stop-opacity:0;" id="stop2597" /> </linearGradient><linearGradient id="linearGradient2587" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#fff8a8;stop-opacity:1;" id="stop2589" /> <stop offset="1" style="stop-color:white;stop-opacity:0;" id="stop2591" /> </linearGradient><linearGradient id="linearGradient2581"><stop id="stop2583" offset="0" style="stop-color:black;stop-opacity:1" /><stop id="stop2585" offset="1" style="stop-color:black;stop-opacity:0" /></linearGradient><linearGradient id="linearGradient2575" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#7f7f7f;stop-opacity:1;" id="stop2577" /> <stop offset="1" style="stop-color:#1a1a1a;stop-opacity:1;" id="stop2579" /> </linearGradient><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient2910" gradientUnits="userSpaceOnUse" gradientTransform="translate(-12,-4)" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient2912" gradientUnits="userSpaceOnUse" gradientTransform="translate(-12,-4)" cx="102" cy="112.3047" r="139.55859" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient2914" gradientUnits="userSpaceOnUse" gradientTransform="translate(-12,-4)" x1="94.3438" y1="102.3447" x2="86.5356" y2="94.5366" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient2916" gradientUnits="userSpaceOnUse" gradientTransform="translate(-12,-4)" x1="95" y1="103" x2="86.5865" y2="94.5865" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient2918" gradientUnits="userSpaceOnUse" gradientTransform="translate(-12,-4)" x1="95" y1="103" x2="87.293" y2="95.293" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient2920" gradientUnits="userSpaceOnUse" gradientTransform="translate(-12,-4)" x1="96" y1="104" x2="88.0002" y2="96.0002" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient3899" gradientUnits="userSpaceOnUse" gradientTransform="translate(-185.19828,-18.5)" x1="96" y1="104" x2="88.0002" y2="96.0002" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient3902" gradientUnits="userSpaceOnUse" gradientTransform="translate(-185.19828,-18.5)" x1="95" y1="103" x2="87.293" y2="95.293" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient3905" gradientUnits="userSpaceOnUse" gradientTransform="translate(-185.19828,-18.5)" x1="95" y1="103" x2="86.5865" y2="94.5865" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient3908" gradientUnits="userSpaceOnUse" gradientTransform="translate(-185.19828,-18.5)" x1="94.3438" y1="102.3447" x2="86.5356" y2="94.5366" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient3912" gradientUnits="userSpaceOnUse" gradientTransform="translate(-337.44962,-79.054366)" cx="102" cy="112.3047" r="139.55859" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient3915" gradientUnits="userSpaceOnUse" gradientTransform="translate(-337.44962,-79.054366)" cx="102" cy="112.3047" r="139.5585" /><linearGradient id="linearGradient3075"><stop id="stop3077" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /><stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.42597079" id="stop3093" /><stop style="stop-color:#f1f1f1;stop-opacity:1;" offset="0.5892781" id="stop3085" /><stop id="stop3087" offset="0.80219781" style="stop-color:#eaeaea;stop-opacity:1;" /><stop id="stop3079" offset="1" style="stop-color:#dfdfdf;stop-opacity:1;" /></linearGradient><linearGradient id="linearGradient3139"><stop id="stop3141" offset="0" style="stop-color:#000000;stop-opacity:1;" /><stop style="stop-color:#000000;stop-opacity:0.68235294;" offset="0.40659341" id="stop3162" /><stop id="stop3164" offset="0.45329672" style="stop-color:#000000;stop-opacity:0.48736462;" /><stop style="stop-color:#000000;stop-opacity:0.36101082;" offset="0.5" id="stop3158" /><stop id="stop3160" offset="0.70604396" style="stop-color:#000000;stop-opacity:0.15162455;" /><stop id="stop3143" offset="1" style="stop-color:#000000;stop-opacity:0;" /></linearGradient><linearGradient id="linearGradient3149"><stop id="stop3151" offset="0" style="stop-color:#454545;stop-opacity:1;" /><stop style="stop-color:#cacaca;stop-opacity:1;" offset="0.48275861" id="stop3920" /><stop id="stop3153" offset="1" style="stop-color:#f8f8f8;stop-opacity:1;" /></linearGradient><linearGradient id="linearGradient2763"><stop id="stop2765" offset="0" style="stop-color:#000000;stop-opacity:1;" /><stop id="stop2767" offset="1" style="stop-color:#000000;stop-opacity:0;" /></linearGradient><linearGradient id="linearGradient3235" inkscape:collect="always"><stop id="stop3237" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /><stop id="stop3239" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /></linearGradient><linearGradient id="linearGradient4181"><stop id="stop4183" offset="0" style="stop-color:#000000;stop-opacity:0.29602888;" /><stop id="stop4185" offset="1" style="stop-color:#000000;stop-opacity:0;" /></linearGradient><linearGradient id="linearGradient4206"><stop id="stop4208" offset="0" style="stop-color:#f7f7f7;stop-opacity:1;" /><stop id="stop4210" offset="1" style="stop-color:#f7f7f7;stop-opacity:0;" /></linearGradient><linearGradient id="linearGradient4221"><stop style="stop-color:#f7f7f7;stop-opacity:1;" offset="0" id="stop4223" /><stop style="stop-color:#f7f7f7;stop-opacity:0;" offset="1" id="stop4225" /></linearGradient><linearGradient id="linearGradient2741"><stop id="stop2743" offset="0" style="stop-color:black;stop-opacity:1" /><stop id="stop2745" offset="1" style="stop-color:black;stop-opacity:0" /></linearGradient><linearGradient id="linearGradient2898"><stop style="stop-color:black;stop-opacity:0;" offset="0" id="stop2900" /><stop id="stop2738" offset="0" style="stop-color:#262626;stop-opacity:1;" /><stop style="stop-color:#4c4c4c;stop-opacity:1;" offset="1" id="stop2902" /></linearGradient><linearGradient id="linearGradient6456"><stop style="stop-color:#888;stop-opacity:1;" offset="0" id="stop6458" /><stop style="stop-color:#b6b6b6;stop-opacity:1;" offset="1" id="stop6460" /></linearGradient><radialGradient gradientUnits="userSpaceOnUse" r="139.5585" cy="112.3047" cx="102" id="radialGradient2714"><stop id="stop2716" style="stop-color:#00537D" offset="0" /><stop id="stop2718" style="stop-color:#186389" offset="0.0151" /><stop id="stop2720" style="stop-color:#558CA8" offset="0.0558" /><stop id="stop2722" style="stop-color:#89AFC3" offset="0.0964" /><stop id="stop24" style="stop-color:#B3CCD8" offset="0.1357" /><stop id="stop2725" style="stop-color:#D4E2E9" offset="0.1737" /><stop id="stop2727" style="stop-color:#ECF2F5" offset="0.2099" /><stop id="stop2729" style="stop-color:#FAFCFD" offset="0.2435" /><stop id="stop2731" style="stop-color:#FFFFFF" offset="0.2722" /></radialGradient><radialGradient gradientUnits="userSpaceOnUse" r="139.55859" cy="112.3047" cx="102" id="radialGradient2696"><stop id="stop2698" style="stop-color:#535557" offset="0" /><stop id="stop2700" style="stop-color:#898A8C" offset="0.11366145" /><stop id="stop2702" style="stop-color:#ECECEC" offset="0.20296688" /><stop id="stop2704" style="stop-color:#FAFAFA" offset="0.2363" /><stop id="stop2706" style="stop-color:#FFFFFF" offset="0.2722" /><stop id="stop2708" style="stop-color:#FAFAFA" offset="0.5313" /><stop id="stop2710" style="stop-color:#EBECEC" offset="0.8449" /><stop id="stop2712" style="stop-color:#E1E2E3" offset="1" /></radialGradient><linearGradient y2="94.536598" x2="86.535599" y1="102.3447" x1="94.343803" gradientUnits="userSpaceOnUse" id="linearGradient2690"><stop id="stop2692" style="stop-color:#FFFFFF" offset="0" /><stop id="stop2694" style="stop-color:#555753" offset="1" /></linearGradient><linearGradient y2="94.586502" x2="86.586502" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2684"><stop id="stop2686" style="stop-color:#FFFFFF" offset="0" /><stop id="stop2688" style="stop-color:#555753" offset="1" /></linearGradient><linearGradient y2="95.292999" x2="87.292999" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient2678"><stop id="stop2680" style="stop-color:#FFFFFF" offset="0" /><stop id="stop2682" style="stop-color:#393B38" offset="1" /></linearGradient><linearGradient y2="96.000198" x2="88.000198" y1="104" x1="96" gradientUnits="userSpaceOnUse" id="linearGradient2658"><stop id="stop2660" style="stop-color:#888A85" offset="0" /><stop id="stop2662" style="stop-color:#8C8E89" offset="0.0072" /><stop id="stop2664" style="stop-color:#ABACA9" offset="0.0673" /><stop id="stop2666" style="stop-color:#C5C6C4" offset="0.1347" /><stop id="stop2668" style="stop-color:#DBDBDA" offset="0.2115" /><stop id="stop2670" style="stop-color:#EBEBEB" offset="0.3012" /><stop id="stop2672" style="stop-color:#F7F7F6" offset="0.4122" /><stop id="stop2674" style="stop-color:#FDFDFD" offset="0.5679" /><stop id="stop2676" style="stop-color:#FFFFFF" offset="1" /></linearGradient><linearGradient inkscape:collect="always" xlink:href="#linearGradient3149" id="linearGradient3884" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1111117,0,0,1.6,-12.8889,-0.81587)" spreadMethod="reflect" x1="58.073513" y1="5.5073318" x2="58.073513" y2="12.044647" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3149" id="linearGradient3891" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.227818,0,0,1.286432,98.3596,13.42714)" x1="-34.499901" y1="-1.3553318" x2="-34.499901" y2="-11.966981" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3235" id="linearGradient3931" x1="48.61359" y1="10.752187" x2="84" y2="10.752187" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1303775,0,0,1,-18.951707,2.1)" /><filter inkscape:collect="always" x="-0.018968365" width="1.0379367" y="-0.34415792" height="1.6883158" id="filter3999"><feGaussianBlur inkscape:collect="always" stdDeviation="0.31613941" id="feGaussianBlur4001" /></filter><filter inkscape:collect="always" x="-0.035955056" width="1.0719101" y="-0.25168539" height="1.5033708" id="filter4033"><feGaussianBlur inkscape:collect="always" stdDeviation="0.6349485" id="feGaussianBlur4035" /></filter><linearGradient inkscape:collect="always" xlink:href="#linearGradient2593" id="linearGradient4053" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9696099,0,0,0.9809017,-3.8622501,4.5754039)" x1="106.78104" y1="15.098409" x2="-88.071037" y2="15.098409" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient4077" id="linearGradient4083" x1="56.827953" y1="-34.582161" x2="54.1763" y2="32.055855" gradientUnits="userSpaceOnUse" /><filter inkscape:collect="always" id="filter4109"><feGaussianBlur inkscape:collect="always" stdDeviation="0.42944571" id="feGaussianBlur4111" /></filter><linearGradient inkscape:collect="always" xlink:href="#linearGradient3235" id="linearGradient4135" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.1489125,-138.10679,0)" x1="56.623783" y1="21.105345" x2="101.6466" y2="21.381557" /><mask maskUnits="userSpaceOnUse" id="mask4131"><rect style="opacity:1;fill:url(#linearGradient4135);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" id="rect4133" width="65.186401" height="28.561073" x="-101.64659" y="10.285005" transform="matrix(-1,0,-0.3481553,0.9374369,0,0)" /></mask><linearGradient inkscape:collect="always" xlink:href="#linearGradient3235" id="linearGradient4147" x1="48.461166" y1="1.3560734" x2="75.130096" y2="1.3560734" gradientUnits="userSpaceOnUse" gradientTransform="translate(-7.8,1.3)" /><filter inkscape:collect="always" x="-0.014460673" width="1.0289213" y="-0.19945781" height="1.3989156" id="filter4177"><feGaussianBlur inkscape:collect="always" stdDeviation="0.16068779" id="feGaussianBlur4179" /></filter><linearGradient inkscape:collect="always" xlink:href="#linearGradient2575" id="linearGradient4190" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9696099,0,0,0.9809017,-3.869031,0.6517971)" x1="79.587105" y1="-25.960203" x2="110.8327" y2="90.649948" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient2575" id="linearGradient4194" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9696099,0,0,0.9809017,120.23535,0.6517971)" x1="79.587105" y1="-25.960203" x2="110.8327" y2="90.649948" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient3638" id="linearGradient4215" gradientUnits="userSpaceOnUse" gradientTransform="translate(-8.000004,-3.9999969)" x1="73.615906" y1="97.608109" x2="73.943695" y2="138.20813" /><filter inkscape:collect="always" x="-0.023605747" width="1.0472115" y="-0.46785067" height="1.9357013" id="filter4253"><feGaussianBlur inkscape:collect="always" stdDeviation="0.94422987" id="feGaussianBlur4255" /></filter><linearGradient gradientTransform="translate(-127.99999,0)" gradientUnits="userSpaceOnUse" y2="53.669254" x2="157.3817" y1="7.9986315" x1="157.3817" id="linearGradient3470" xlink:href="#linearGradient3464" inkscape:collect="always" /> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient4477"> <stop id="stop4479" style="stop-color:#FFEA00" offset="0" /> <stop id="stop4481" style="stop-color:#FFCC00" offset="1" /> </linearGradient> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient4475" xlink:href="#linearGradient3287" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient2298" xlink:href="#linearGradient3287" inkscape:collect="always" /><linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientTransform="translate(69.54139,-45.18897)" gradientUnits="userSpaceOnUse" id="linearGradient4468" xlink:href="#linearGradient18668" inkscape:collect="always" /> <linearGradient gradientTransform="translate(-20,-16)" y2="94.5366" x2="86.5356" y1="102.3447" x1="94.3438" gradientUnits="userSpaceOnUse" id="linearGradient4466" xlink:href="#XMLID_9_" inkscape:collect="always" /><linearGradient gradientTransform="translate(-20,-16)" y2="94.5865" x2="86.5865" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient4464" xlink:href="#XMLID_10_" inkscape:collect="always" /><linearGradient gradientTransform="translate(-20,-16)" y2="95.293" x2="87.293" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient4462" xlink:href="#XMLID_11_" inkscape:collect="always" /><linearGradient gradientTransform="translate(-20,-16)" y2="96.0002" x2="88.0002" y1="104" x1="96" gradientUnits="userSpaceOnUse" id="linearGradient4460" xlink:href="#XMLID_12_" inkscape:collect="always" /><radialGradient gradientTransform="translate(-20,-16)" r="139.5585" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient4458" xlink:href="#XMLID_7_" inkscape:collect="always" /><radialGradient gradientTransform="translate(-20,-16)" r="139.55859" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient4456" xlink:href="#XMLID_8_" inkscape:collect="always" /><linearGradient gradientTransform="translate(69.54139,-45.18897)" y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient4454" xlink:href="#linearGradient18668" inkscape:collect="always" /><linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient4452" xlink:href="#linearGradient18668" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient4450" xlink:href="#XMLID_2_" inkscape:collect="always" /><linearGradient y2="51.1875" x2="-39.53125" y1="78" x1="-39.53125" gradientUnits="userSpaceOnUse" id="linearGradient4448" xlink:href="#linearGradient18668" inkscape:collect="always" /> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient4442"> <stop id="stop4444" style="stop-color:#FFEA00" offset="0" /> <stop id="stop4446" style="stop-color:#FFCC00" offset="1" /> </linearGradient> <linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient4440" xlink:href="#XMLID_2_" inkscape:collect="always" /><radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.754978,-2.959381e-2,0,0.905772,7.650275,10.87807)" r="8.968153" fy="31.045055" fx="26.954102" cy="31.045055" cx="26.954102" id="radialGradient4438" xlink:href="#linearGradient15967" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient4436" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient gradientTransform="translate(1.470416e-5,0)" y2="30.441185" x2="27.719746" y1="7.881104" x1="27.719746" gradientUnits="userSpaceOnUse" id="linearGradient4434" xlink:href="#linearGradient15967" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient4432" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient y2="100.82378" x2="-18.121965" y1="100.82378" x1="-74.820707" gradientUnits="userSpaceOnUse" id="linearGradient4430" xlink:href="#linearGradient2309" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient4428" xlink:href="#XMLID_2_" inkscape:collect="always" /> <foreignObject id="foreignObject4426" height="1" width="1" y="0" x="0" requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/"> <i:pgfRef xlink:href="#adobe_illustrator_pgf"> </i:pgfRef> </foreignObject> <radialGradient r="139.55859" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient4424" xlink:href="#XMLID_8_" inkscape:collect="always" /><radialGradient r="139.5585" cy="112.3047" cx="102" gradientUnits="userSpaceOnUse" id="radialGradient4422" xlink:href="#XMLID_7_" inkscape:collect="always" /><linearGradient y2="96.0002" x2="88.0002" y1="104" x1="96" gradientUnits="userSpaceOnUse" id="linearGradient4420" xlink:href="#XMLID_12_" inkscape:collect="always" /><linearGradient y2="95.293" x2="87.293" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient4418" xlink:href="#XMLID_11_" inkscape:collect="always" /><linearGradient y2="94.5865" x2="86.5865" y1="103" x1="95" gradientUnits="userSpaceOnUse" id="linearGradient4416" xlink:href="#XMLID_10_" inkscape:collect="always" /><linearGradient y2="94.5366" x2="86.5356" y1="102.3447" x1="94.3438" gradientUnits="userSpaceOnUse" id="linearGradient4414" xlink:href="#XMLID_9_" inkscape:collect="always" /><linearGradient y2="0" x2="28" y1="57.5" x1="28" gradientUnits="userSpaceOnUse" id="linearGradient4408"> <stop id="stop4410" style="stop-color:#FFEA00" offset="0" /> <stop id="stop4412" style="stop-color:#FFCC00" offset="1" /> </linearGradient><linearGradient id="linearGradient4402" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:white;stop-opacity:1;" id="stop4404" /> <stop offset="1" style="stop-color:white;stop-opacity:0;" id="stop4406" /> </linearGradient><linearGradient id="linearGradient4396" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#fff8a8;stop-opacity:1;" id="stop4398" /> <stop offset="1" style="stop-color:white;stop-opacity:0;" id="stop4400" /> </linearGradient><linearGradient id="linearGradient4390"><stop id="stop4392" offset="0" style="stop-color:black;stop-opacity:1" /><stop id="stop4394" offset="1" style="stop-color:black;stop-opacity:0" /></linearGradient><linearGradient id="linearGradient4384" gradientUnits="userSpaceOnUse" x1="28" y1="57.5" x2="28" y2="0"> <stop offset="0" style="stop-color:#FFEA00" id="stop4386" /> <stop offset="1" style="stop-color:#ffa000;stop-opacity:1;" id="stop4388" /> </linearGradient><linearGradient id="linearGradient3464" inkscape:collect="always"><stop id="stop3466" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /><stop id="stop3468" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /></linearGradient><linearGradient inkscape:collect="always" xlink:href="#linearGradient4077" id="linearGradient4590" gradientUnits="userSpaceOnUse" x1="56.827953" y1="-34.582161" x2="71.632996" y2="26.701014" /><linearGradient inkscape:collect="always" xlink:href="#linearGradient4005" id="linearGradient4648" gradientUnits="userSpaceOnUse" gradientTransform="translate(-8,5.6)" x1="63.085938" y1="19.992191" x2="63.085938" y2="13.937426" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient4659" gradientUnits="userSpaceOnUse" gradientTransform="translate(-7.9999972,-4.0000003)" cx="102" cy="112.3047" r="139.5585" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient4661" gradientUnits="userSpaceOnUse" gradientTransform="translate(-7.9999972,-4.0000003)" cx="102" cy="112.3047" r="139.55859" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient4663" gradientUnits="userSpaceOnUse" gradientTransform="translate(-7.9999972,-4.0000003)" x1="94.3438" y1="102.3447" x2="86.5356" y2="94.5366" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient4665" gradientUnits="userSpaceOnUse" gradientTransform="translate(-7.9999972,-4.0000003)" x1="95" y1="103" x2="86.5865" y2="94.5865" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient4667" gradientUnits="userSpaceOnUse" gradientTransform="translate(-7.9999972,-4.0000003)" x1="95" y1="103" x2="87.293" y2="95.293" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient4669" gradientUnits="userSpaceOnUse" gradientTransform="translate(-7.9999972,-4.0000003)" x1="96" y1="104" x2="88.0002" y2="96.0002" /><filter inkscape:collect="always" id="filter4787"><feGaussianBlur inkscape:collect="always" stdDeviation="2.2677902" id="feGaussianBlur4789" /></filter><linearGradient inkscape:collect="always" xlink:href="#linearGradient4811" id="linearGradient4817" x1="50.759903" y1="-2.1362097" x2="50.759903" y2="1.3951097" gradientUnits="userSpaceOnUse" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_12_" id="linearGradient4840" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0631606,0,0,1.0273678,3.7231885,0.4979025)" x1="96" y1="104" x2="88.0002" y2="96.0002" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_11_" id="linearGradient4843" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0630031,0,0,1.0272733,3.7407288,0.5060461)" x1="95" y1="103" x2="87.293" y2="95.293" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_10_" id="linearGradient4846" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0627359,0,0,1.0271452,3.7705054,0.5170742)" x1="95" y1="103" x2="86.5865" y2="94.5865" /><linearGradient inkscape:collect="always" xlink:href="#XMLID_9_" id="linearGradient4849" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0629384,0,0,1.0272913,3.7479449,0.504476)" x1="94.3438" y1="102.3447" x2="86.5356" y2="94.5366" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_8_" id="radialGradient4852" gradientUnits="userSpaceOnUse" gradientTransform="translate(8.7000028,3.9999997)" cx="98.761642" cy="106.54063" r="139.55859" fx="98.761642" fy="106.54063" /><radialGradient inkscape:collect="always" xlink:href="#XMLID_7_" id="radialGradient4855" gradientUnits="userSpaceOnUse" gradientTransform="translate(8.7000028,3.9999997)" cx="102" cy="112.3047" r="139.5585" /></defs><sodipodi:namedview inkscape:window-height="670" inkscape:window-width="1049" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" inkscape:zoom="2.5600001" inkscape:cx="10.231966" inkscape:cy="64.336453" inkscape:window-x="341" inkscape:window-y="122" inkscape:current-layer="Layer_1" showgrid="true" gridspacingy="4px" gridspacingx="4px" gridempspacing="2" showguides="true" inkscape:guide-bbox="true"><inkscape:grid type="xygrid" id="grid3298" spacingx="5.8181818px" spacingy="4.82px" empspacing="2" /></sodipodi:namedview> <metadata id="metadata3"> <ns:sfw> <ns:slices> <ns:slice y="0" x="0" height="128" width="128" sliceID="1316743234" /> </ns:slices> <ns:sliceSourceBounds y="0" x="0" height="128" width="128" bottomLeftOrigin="true" /> <ns:optimizationSettings> <ns:targetSettings targetSettingsID="0" fileFormat="PNG24Format"> <ns:PNG24Format transparency="true" filtered="false" matteColor="#FFFFFF" noMatteColor="false" interlaced="false"> </ns:PNG24Format> </ns:targetSettings> <ns:targetSettings targetSettingsID="1696735251" fileFormat="PNG24Format"> <ns:PNG24Format transparency="true" filtered="false" matteColor="#FFFFFF" noMatteColor="false" interlaced="false"> </ns:PNG24Format> </ns:targetSettings> </ns:optimizationSettings> </ns:sfw> <rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata> <radialGradient id="XMLID_7_" cx="102" cy="112.3047" r="139.5585" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#3e3e3e;stop-opacity:1;" id="stop16" /> <stop offset="0.1737" style="stop-color:#dfdfdf;stop-opacity:1;" id="stop26" /> <stop offset="0.2099" style="stop-color:#ECF2F5" id="stop28" /> <stop offset="0.2435" style="stop-color:#FAFCFD" id="stop30" /> <stop offset="0.2722" style="stop-color:#FFFFFF" id="stop32" /> </radialGradient> <radialGradient id="XMLID_8_" cx="102" cy="112.3047" r="139.55859" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#535557" id="stop37" /> <stop offset="0.11366145" style="stop-color:#898A8C" id="stop41" /> <stop offset="0.20296688" style="stop-color:#ECECEC" id="stop47" /> <stop offset="0.2363" style="stop-color:#FAFAFA" id="stop49" /> <stop offset="0.2722" style="stop-color:#FFFFFF" id="stop51" /> <stop offset="0.5313" style="stop-color:#FAFAFA" id="stop53" /> <stop offset="0.8449" style="stop-color:#EBECEC" id="stop55" /> <stop offset="1" style="stop-color:#cfd0d2;stop-opacity:1;" id="stop57" /> </radialGradient> <linearGradient id="XMLID_9_" gradientUnits="userSpaceOnUse" x1="94.3438" y1="102.3447" x2="86.5356" y2="94.5366"> <stop offset="0" style="stop-color:#FFFFFF" id="stop62" /> <stop offset="1" style="stop-color:#555753" id="stop64" /> </linearGradient> <linearGradient id="XMLID_10_" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="86.5865" y2="94.5865"> <stop offset="0" style="stop-color:#FFFFFF" id="stop69" /> <stop offset="1" style="stop-color:#555753" id="stop71" /> </linearGradient> <linearGradient id="XMLID_11_" gradientUnits="userSpaceOnUse" x1="95" y1="103" x2="87.293" y2="95.293"> <stop offset="0" style="stop-color:#FFFFFF" id="stop76" /> <stop offset="1" style="stop-color:#393B38" id="stop78" /> </linearGradient> <linearGradient id="XMLID_12_" gradientUnits="userSpaceOnUse" x1="96" y1="104" x2="88.0002" y2="96.0002"> <stop offset="0" style="stop-color:#888A85" id="stop83" /> <stop offset="0.0072" style="stop-color:#8C8E89" id="stop85" /> <stop offset="0.0673" style="stop-color:#ABACA9" id="stop87" /> <stop offset="0.1347" style="stop-color:#C5C6C4" id="stop89" /> <stop offset="0.2115" style="stop-color:#DBDBDA" id="stop91" /> <stop offset="0.3012" style="stop-color:#EBEBEB" id="stop93" /> <stop offset="0.4122" style="stop-color:#F7F7F6" id="stop95" /> <stop offset="0.5679" style="stop-color:#FDFDFD" id="stop97" /> <stop offset="1" style="stop-color:#FFFFFF" id="stop99" /> </linearGradient> <path style="opacity:1;fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4787)" d="M 41.700003,31.7 L 41.700003,121.2 C 41.700003,122.304 42.596003,123.2 43.700003,123.2 L 86.787503,123.2 C 87.317503,123.2 87.818753,122.98125 88.193753,122.60625 C 88.193753,122.60625 99.200003,112.7 104.7,107.2 C 110.2,101.7 122.10625,89.79375 122.10625,89.79375 C 122.48125,89.418751 122.7,88.9175 122.7,88.3875 L 122.7,31.7 L 41.700003,31.7 z" id="path4749" sodipodi:nodetypes="cccccscccc" /><path id="path4213" d="M 8,111.15625 L 8,112.15625 C 8,114.28318 9.71681,116 11.84375,116 L 100.15625,116 C 102.28318,116 104,114.28318 104,112.15625 L 104,111.15625 C 104,113.28318 102.28318,114 100.15625,114 L 11.84375,114 C 9.71681,114 8,113.28318 8,111.15625 z" style="opacity:1;fill:url(#linearGradient4215);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4253)" sodipodi:nodetypes="ccccccccc" transform="matrix(0.9696099,0,0,0.9809017,3.8855413,0.6517971)" /><rect style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="rect1327" width="1" height="0" x="60.000023" y="-83" /><path style="opacity:1;fill:url(#linearGradient3816);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 19.914405,12.422617 C 15.32978,12.422617 11.642421,16.152925 11.642421,20.790935 L 11.642421,114.58966 C 11.642421,116.67597 13.307057,118.36 15.369359,118.36 L 100.99803,118.36 C 103.06033,118.36 104.72497,116.67597 104.72497,114.58966 L 104.72497,20.790935 C 104.72497,16.152925 101.03761,12.422617 96.452989,12.422617 L 19.914405,12.422617 z" id="rect2834" sodipodi:nodetypes="ccccccccc" /><path style="fill:url(#linearGradient3891);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.19512191" d="M 39.3,0 L 43.060192,16 L 49.122542,16 L 61.477458,16 L 67.539808,16 L 71.3,0 L 57.717266,0 L 52.882734,0 L 39.3,0 z" id="rect3276" sodipodi:nodetypes="ccccccccc" /><path style="opacity:1;fill:url(#linearGradient4190);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 95.485678,12.422617 C 100.07029,12.422617 103.75767,16.152925 103.75766,20.790935 L 103.75766,114.58966 C 103.75766,116.67597 102.09303,118.36 100.03072,118.36 L 101.00033,118.36 C 103.06264,118.36 104.72727,116.67597 104.72727,114.58966 L 104.72727,20.790935 C 104.72728,16.152925 101.03991,12.422617 96.455288,12.422617 L 95.485678,12.422617 z" id="path4181" /><path style="opacity:1;fill:url(#linearGradient4053);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 19.938648,17.346224 C 15.354012,17.346224 11.636364,21.076532 11.636364,25.714542 L 11.636364,26.695443 C 11.636364,22.057433 15.354012,20.28893 19.938648,20.28893 L 96.44693,20.28893 C 101.03154,20.28893 104.71892,22.057433 104.71892,26.695443 L 104.71892,25.714542 C 104.71892,21.076532 101.03154,17.346224 96.44693,17.346224 L 19.938648,17.346224 z" id="path4037" sodipodi:nodetypes="ccccccccc" /><rect style="opacity:0.47191013;fill:url(#linearGradient4648);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4033)" id="rect4003" width="42.382812" height="6.0546875" x="34.96875" y="19.537506" rx="1.6114728" ry="1.5929222" transform="matrix(0.9696099,0,0,1.5540024,3.8855413,-14.015107)" /><path transform="matrix(0.9696099,0,0.3601041,0.9107444,-3.8713382,0.6517971)" style="opacity:0.54681648;fill:url(#linearGradient4590);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4109)" mask="url(#mask4131)" d="M 36.111931,14.503877 L 83.012997,13.908895 C 83.727578,15.756474 84.556527,18.968682 79.20125,30.865909 L 36.111931,32.353364 L 36.111931,14.503877 z" id="rect4075" sodipodi:nodetypes="ccccc" /><rect style="fill:url(#linearGradient3884);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.19512191" id="rect3259" width="40.727272" height="16.011719" x="34.909092" y="7.5" /><rect style="opacity:1;fill:url(#linearGradient3931);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3999)" id="rect3922" width="40" height="2.2046118" x="36" y="11.895385" rx="0" ry="0" transform="matrix(0.9696099,0,0,0.9809017,3.8855413,0.6517971)" /><path style="opacity:0.77902623;fill:url(#linearGradient4147);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter4177)" d="M 40.661165,1.6893259 L 67.330096,1.6893259 L 67.330096,3.6228209 L 41.198274,3.6228209 L 40.661165,1.6893259 z " id="rect4138" sodipodi:nodetypes="ccccc" /><path id="path4192" d="M 20.880634,12.422617 C 16.296018,12.422617 12.60864,16.152925 12.608649,20.790935 L 12.608649,114.58966 C 12.608649,116.67597 14.273286,118.36 16.335588,118.36 L 15.365978,118.36 C 13.303675,118.36 11.63904,116.67597 11.63904,114.58966 L 11.63904,20.790935 C 11.63903,16.152925 15.326409,12.422617 19.911024,12.422617 L 20.880634,12.422617 z" style="opacity:1;fill:url(#linearGradient4194);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /><path style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 11.642421,113.60876 L 11.642421,114.58966 C 11.642421,116.67597 13.307057,118.36 15.369359,118.36 L 100.99803,118.36 C 103.06033,118.36 104.72497,116.67597 104.72497,114.58966 L 104.72497,113.60876 C 104.72497,115.69507 103.06033,115.41729 100.99803,115.41729 L 15.369359,115.41729 C 13.307057,115.41729 11.642421,115.69507 11.642421,113.60876 z" id="path4196" sodipodi:nodetypes="ccccccccc" /><path sodipodi:nodetypes="cccccscccc" id="path2260" d="M 40.900003,31.7 L 40.900003,121.2 C 40.900003,122.304 41.796003,123.2 42.900003,123.2 L 86.787503,123.2 C 87.317503,123.2 87.818753,122.98125 88.193753,122.60625 C 88.193753,122.60625 99.200003,112.7 104.7,107.2 C 110.2,101.7 120.90625,89.79375 120.90625,89.79375 C 121.28125,89.418751 121.5,88.9175 121.5,88.3875 L 121.5,31.7 L 40.900003,31.7 z" style="opacity:0.55805209;fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path sodipodi:nodetypes="ccccccccc" id="path2262" d="M 40.700003,31.7 L 40.700003,121.2 C 40.700003,122.304 41.596003,123.2 42.700003,123.2 L 86.972003,123.2 C 87.502003,123.2 88.011003,122.989 88.386003,122.614 L 121.514,89.786 C 121.889,89.411 122.1,88.902 122.1,88.372 L 122.1,31.7 L 40.700003,31.7 z" style="fill:url(#radialGradient4855)" /><path sodipodi:nodetypes="ccccccccccc" id="path2264" d="M 47.500003,36.4 C 46.949003,36.4 46.500003,36.849 46.500003,37.4 L 46.500003,117.4 C 46.500003,117.952 46.949003,118.4 47.500003,118.4 L 88.872003,118.4 C 89.135003,118.4 89.393003,118.294 89.579003,118.107 L 116.107,92.879 C 116.294,92.692 116.4,92.435 116.4,92.172 L 116.4,37.4 C 116.4,36.849 115.952,36.4 115.4,36.4 L 47.500003,36.4 z" style="fill:url(#radialGradient4852);fill-opacity:1" /><path style="opacity:0.15;fill:url(#linearGradient4849)" id="path2266" d="M 122.17416,89.453522 C 122.43989,89.196699 97.63841,91.042568 92.286523,91.042568 C 90.528423,91.042568 89.097708,92.425302 89.097708,94.124443 C 89.097708,99.29685 87.014286,123.43426 87.280021,123.17744 L 122.17416,89.453522 z" sodipodi:nodetypes="csscc" /><path style="opacity:0.2;fill:url(#linearGradient4846)" id="path2268" d="M 122.17416,89.453475 C 122.57268,89.068295 102.32774,92.06873 92.291265,92.06873 C 91.119067,92.06873 90.165792,92.990079 90.165792,94.123021 C 90.165792,103.82338 86.888143,123.55777 87.286669,123.1726 L 122.17416,89.453475 z" sodipodi:nodetypes="csscc" /><path style="opacity:0.25;fill:url(#linearGradient4843)" id="path2270" d="M 122.17416,89.453536 C 122.42821,89.208018 102.70988,93.097014 92.285007,93.097014 C 91.697165,93.097014 91.222004,93.556206 91.222004,94.124288 C 91.222004,104.19876 87.023837,123.42238 87.277895,123.17686 L 122.17416,89.453536 z" sodipodi:nodetypes="csscc" /><path sodipodi:nodetypes="csccc" style="fill:url(#linearGradient4840)" id="path2272" d="M 87.272727,123.18 C 87.272727,123.18 99.939222,112.99467 105.7866,107.34415 C 111.63398,101.69363 122.17416,89.453571 122.17416,89.453571 C 122.17416,89.453571 103.17872,94.077049 92.281321,94.077049 C 92.281321,104.60758 87.272727,123.18 87.272727,123.18 z" /><path id="path4809" d="M 39.3,0 L 43.060192,16 L 49.122542,16 L 61.477458,16 L 67.539808,16 L 71.3,0 L 57.717266,0 L 52.882734,0 L 39.3,0 z" style="fill:url(#linearGradient4817);fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.19512191" sodipodi:nodetypes="ccccccccc" /></svg>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/filter-note.svg������������������������������������������������������0000644�0001750�0000144�00000115242�11074310715�017475� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg1307" sodipodi:version="0.32" inkscape:version="0.46" version="1.0" sodipodi:docbase="/home/david/Progetti/sandbox" sodipodi:docname="filter-note.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:modified="true"> <defs id="defs1309"> <filter inkscape:collect="always" id="filter3305"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.0460516" id="feGaussianBlur3307" /> </filter> <linearGradient id="linearGradient3058"> <stop id="stop3060" offset="0" style="stop-color:#9a7600;stop-opacity:1;" /> <stop style="stop-color:#e3ad00;stop-opacity:1;" offset="0.09292036" id="stop3066" /> <stop id="stop3070" offset="0.5043171" style="stop-color:#ffcd2c;stop-opacity:1;" /> <stop id="stop3068" offset="0.91571385" style="stop-color:#e3ad00;stop-opacity:1;" /> <stop id="stop3113" offset="1" style="stop-color:#b98d00;stop-opacity:1;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3058" id="linearGradient2960" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.986412,0,0,0.928394,-32.37105,71.502774)" x1="32.526917" y1="9.3526363" x2="104.60481" y2="130.28703" /> <linearGradient id="linearGradient4309"> <stop style="stop-color:#fff727;stop-opacity:0.73333335;" offset="0" id="stop4311" /> <stop style="stop-color:#ffb266;stop-opacity:0;" offset="1" id="stop4313" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4309" id="radialGradient2957" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.5775266,-1.1711111,0.1996751,1.4444656,47.1149,78.217676)" cx="77.520203" cy="116.66548" fx="58.694687" fy="91.699684" r="64.071327" /> <linearGradient id="linearGradient4318"> <stop id="stop4320" offset="0" style="stop-color:#fffaa8;stop-opacity:1;" /> <stop id="stop4322" offset="1" style="stop-color:white;stop-opacity:0;" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4318" id="radialGradient2954" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.301238,-9.370473e-2,-1.427156e-2,0.255192,-9.2416499,104.51159)" cx="68.972214" cy="74.718201" fx="68.972214" fy="74.718201" r="47.781246" /> <linearGradient id="linearGradient2019"> <stop id="stop2912" offset="0" style="stop-color:#fff823;stop-opacity:0.84313726;" /> <stop style="stop-color:#ffff02;stop-opacity:0;" offset="1" id="stop2023" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient5904"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop5906" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop5908" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5904" id="linearGradient2973" x1="173.96887" y1="100.2915" x2="57.130394" y2="27.459507" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.004372,-213.14363,85.063201)" /> <filter inkscape:collect="always" id="filter3637"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.26548265" id="feGaussianBlur3639" /> </filter> <linearGradient inkscape:collect="always" id="linearGradient3609"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3611" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3613" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3609" id="radialGradient3615" cx="105.60236" cy="61.783173" fx="106.32523" fy="51.090271" r="19.974998" gradientTransform="matrix(0.8124666,-0.5830077,1.3642054,1.9011265,-227.25034,73.040198)" gradientUnits="userSpaceOnUse" /> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective2925" /> <linearGradient inkscape:collect="always" id="linearGradient2897"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2899" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2901" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2884"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2886" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2888" /> </linearGradient> <linearGradient id="linearGradient3054"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3056" /> <stop id="stop3062" offset="0.5714286" style="stop-color:black;stop-opacity:1;" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3058" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3040"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3042" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3044" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3027"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3029" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3031" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3012"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop3014" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop3016" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2999"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3001" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3003" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2981"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2983" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2985" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2947"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop2949" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop2951" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient2929"> <stop style="stop-color:#bdbdbd;stop-opacity:1;" offset="0" id="stop2931" /> <stop style="stop-color:#bdbdbd;stop-opacity:0;" offset="1" id="stop2933" /> </linearGradient> <linearGradient id="linearGradient2903"> <stop style="stop-color:white;stop-opacity:0.53790611;" offset="0" id="stop2905" /> <stop id="stop2911" offset="0.21464799" style="stop-color:white;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:0.41516244;" offset="0.66342056" id="stop2913" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop2907" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3291"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3293" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3295" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3291" id="radialGradient3297" cx="63.912209" cy="115.70919" fx="63.912209" fy="115.7093" r="63.912209" gradientTransform="matrix(1,0,0,0.197802,0,92.82166)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3054" id="radialGradient3060" cx="63.816387" cy="120.57538" fx="63.816387" fy="120.57538" r="14.672465" gradientTransform="matrix(1,0,0,0.289157,0,85.71021)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2897" id="linearGradient2904" x1="67.25" y1="72.375" x2="65.25" y2="17.625" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient2256" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient2258" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871796,19.248866,2.1082206)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2260" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2262" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.1392194,15.358897,56.83334)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2264" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.5047306,-0.9375819,1.2433202,3.3256839,-79.061389,-69.19504)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2266" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.1392194,15.358897,56.83334)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2268" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.5047306,-0.9375819,1.2433202,3.3256839,-79.061389,-69.19504)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2270" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.556928,-2.91845e-8,0,0.138799,37.13478,97.17706)" cx="57.214077" cy="124.00706" fx="49.233025" fy="124.00705" r="11.383312" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2272" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8268423,0,0,0.2437132,15.358897,49.893028)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2274" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.396982,-6.091903e-3,2.173148e-3,-0.138782,90.77277,126.4457)" cx="76.055191" cy="102.52346" fx="70.111389" fy="106.1347" r="11.383312" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2276" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2999" id="linearGradient2278" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="48.326965" y1="241.35539" x2="60.750298" y2="67.1054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient2280" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient2282" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.7646663,0,0,0.9871806,19.248865,2.1082198)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient2284" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8601654,0,0,0.9472313,14.250514,3.8818714)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2884" id="linearGradient2287" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9384891,0,0,0.9797769,5.3602634,-0.1102297)" x1="48.648247" y1="123.09119" x2="63.212357" y2="60.341194" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3040" id="linearGradient2290" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,0.6237166,10.813747,4.9721139)" x1="27.080584" y1="-14.285192" x2="59.768688" y2="17.40625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3027" id="linearGradient2293" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8332988,-4.0741942e-2,4.3563196e-2,0.8910022,10.908193,1.2960712)" x1="26.516504" y1="6.2892451" x2="67.55307" y2="6.2892451" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2999" id="linearGradient2297" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="48.326965" y1="241.35539" x2="60.750298" y2="67.1054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2300" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2304" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.2520869,6.5695719,47.48181)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2308" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6417463,-0.8079979,1.3565327,2.8660381,-96.448304,-52.309632)" cx="52.715279" cy="41.561275" fx="52.715279" fy="41.561275" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2312" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.1440028,6.5695719,54.660582)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="radialGradient2315" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.6417463,-0.8125119,1.3565327,2.88205,-96.448304,-52.949828)" cx="51.78791" cy="41.299831" fx="51.78791" fy="41.299831" r="15.995545" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2947" id="radialGradient2318" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9021317,0,0,0.1440028,6.5695719,54.660582)" cx="63.462833" cy="66.417244" fx="63.462833" fy="66.417244" r="13.788582" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2903" id="linearGradient2321" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210988,10.813747,-1.9448217)" x1="55.875" y1="91.296875" x2="70.71875" y2="91.296875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient2325" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,1.0210978,10.813748,-1.9448209)" spreadMethod="reflect" x1="55.826965" y1="61.3554" x2="121.36113" y2="52.6054" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2981" id="linearGradient2328" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8342942,0,0,0.8975001,10.813747,5.9409483)" x1="94.42218" y1="30.355696" x2="100.78125" y2="35.359375" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2330" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.396982,-6.091903e-3,2.173148e-3,-0.138782,90.77277,126.4457)" cx="76.055191" cy="102.52346" fx="70.111389" fy="106.1347" r="11.383312" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3012" id="radialGradient2332" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.556928,-2.91845e-8,0,0.138799,37.13478,97.17706)" cx="57.214077" cy="124.00706" fx="49.233025" fy="124.00705" r="11.383312" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2929" id="linearGradient3126" gradientTransform="matrix(1.1833921,0,0,0.8450285,-160.63605,67.628171)" x1="10.932556" y1="112.1857" x2="56.167988" y2="112.1857" gradientUnits="userSpaceOnUse" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2" inkscape:cx="90.481778" inkscape:cy="106.17217" inkscape:current-layer="layer1" showgrid="true" inkscape:document-units="px" inkscape:grid-bbox="true" guidetolerance="0.1px" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1018" inkscape:window-height="729" inkscape:window-x="0" inkscape:window-y="34"> <inkscape:grid id="GridFromPre046Settings" type="xygrid" originx="0px" originy="0px" spacingx="8px" spacingy="8px" color="#0000ff" empcolor="#0000ff" opacity="0.2" empopacity="0.4" empspacing="0" visible="true" enabled="true" /> </sodipodi:namedview> <metadata id="metadata1312"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:contributor> <cc:Agent> <dc:title>Oxygen team</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/LGPL/2.1/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer" transform="translate(-2.8572,5.1129792e-5)"> <g id="g3128" transform="matrix(0.9881341,0,0,0.921875,161.6742,-47.890631)"> <path sodipodi:nodetypes="ccccc" id="path4289" d="M -158.49781,118.32095 L -137.63069,171.86465 L -132.252,183.88524 C -100.88385,181.20298 -67.940267,179.09401 -36.46966,171.52206 C -69.591569,97.95755 -90.881365,121.01263 -158.49781,118.32095 z" style="opacity:1;fill:#222222;fill-opacity:0.31048387;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3305)" /> <path sodipodi:nodetypes="ccccscc" id="path3189" d="M -72.850661,103.25513 C -93.366199,118.54288 -131.74685,115.24491 -159.1953,114.75925 L -136.65745,170.72029 L -130.9832,181.22958 C -127.60234,181.57325 -124.93678,181.6299 -121.26746,181.37439 C -90.289929,179.21738 -54.59063,177.18297 -32.79387,160.15179 C -48.41059,141.88127 -60.727013,122.59778 -72.850661,103.25513 z" style="fill:url(#linearGradient2960);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="opacity:0.61904764;fill:url(#radialGradient2957);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M -73.146565,104.76751 C -93.662103,120.05526 -131.74685,115.24491 -159.1953,114.75925 L -136.45727,171.21733 L -130.99771,181.18901 C -127.12254,181.73865 -123.78982,181.54886 -119.51426,181.25268 C -88.951648,179.13552 -54.18057,176.86257 -32.79387,160.15179 C -48.41059,141.88127 -61.022918,124.11017 -73.146565,104.76751 z" id="path4254" sodipodi:nodetypes="ccccscc" /> <path id="path4270" d="M -72.684353,102.65949 C -70.064877,106.83872 -67.431048,111.01794 -64.762232,115.18202 C -86.861983,129.73485 -125.10729,127.16727 -154.06333,126.48028 L -159.02622,114.16763 C -131.57776,114.65328 -93.199889,117.94724 -72.684353,102.65949 z" style="opacity:0.57875462;fill:url(#radialGradient2954);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path id="path2017" d="M -147.69855,143.31567 L -136.44855,171.22192 L -131.01105,181.19067 C -127.13588,181.74031 -123.78661,181.54935 -119.51105,181.25317 C -111.25437,180.68121 -102.6914,180.09823 -94.1673,179.22192 L -94.1673,146.78442 C -94.1673,144.85905 -94.839378,143.31567 -95.6673,143.31567 L -147.69855,143.31567 z" style="opacity:0.61904764;fill:url(#linearGradient3126);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cccsccscccc" id="path2914" d="M -159.20613,114.75494 L -136.45613,171.21946 L -130.98738,181.20041 C -127.11221,181.75005 -123.79419,181.55936 -119.51863,181.26318 C -88.95602,179.14601 -54.18658,176.88215 -32.79988,160.17137 C -33.00448,159.932 -33.19006,159.68868 -33.39363,159.44948 C -54.81129,175.8859 -89.062885,178.71942 -119.4405,180.82377 C -123.71607,181.11995 -127.06533,181.31064 -130.9405,180.76099 L -136.67488,170.21509 L -158.98738,114.75494 C -159.05852,114.75362 -159.13514,114.75619 -159.20613,114.75494 z" style="opacity:0.41904811;fill:url(#linearGradient2973);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.85733783px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path3607" d="M -73.166379,104.01205 C -61.582464,123.26777 -48.65392,141.82338 -33.82799,159.9085" style="opacity:0.6457565;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#radialGradient3615);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3637)" /> </g> <g id="g3137" transform="matrix(0.9881341,0,0,0.921875,1.5339032,6.499996)"> <path transform="matrix(0.6102121,0,0,0.416667,24.999997,74.520305)" d="M 127.82442,115.70919 A 63.912209,12.641975 0 1 1 0,115.70919 A 63.912209,12.641975 0 1 1 127.82442,115.70919 z" sodipodi:ry="12.641975" sodipodi:rx="63.912209" sodipodi:cy="115.70919" sodipodi:cx="63.912209" id="path3289" style="opacity:0.38139535;fill:url(#radialGradient3297);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" sodipodi:type="arc" /> <path transform="matrix(0.9702784,0,0,0.9820563,2.080338,1.4216782)" d="M 78.488853,120.57538 A 14.672465,4.2426405 0 1 1 49.143922,120.57538 A 14.672465,4.2426405 0 1 1 78.488853,120.57538 z" sodipodi:ry="4.2426405" sodipodi:rx="14.672465" sodipodi:cy="120.57538" sodipodi:cx="63.816387" id="path3052" style="opacity:0.41393445;fill:url(#radialGradient3060);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" sodipodi:type="arc" /> <path style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 53.349575,3.2933654 L 53.349575,0.49920781 L 53.349575,3.2933654 z" id="path2276" sodipodi:nodetypes="ccc" /> <path sodipodi:nodetypes="ccccc" id="path2978" d="M 102.76856,18.730326 C 92.024693,33.884991 79.448035,48.048049 72.117251,63.202716 L 73.288437,63.163051 L 108.97363,16.991419 C 106.68706,17.962299 104.63818,18.507029 102.76856,18.730326 z" style="opacity:0.41999996;fill:url(#linearGradient2328);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" /> <path sodipodi:nodetypes="cccccsscccsc" id="path1969" d="M 64.07844,0.4721712 C 37.58961,0.4721712 16.092299,5.7132236 16.092299,11.718435 C 16.092299,24.096447 53.39715,62.252891 53.39715,62.252891 C 53.55139,62.473797 53.73502,62.839504 53.72186,63.265829 L 53.72186,117.72963 C 53.72186,119.07259 55.58016,119.9077 62.88947,119.9077 C 70.04254,119.9077 74.43501,119.26405 74.43501,117.72963 C 74.43501,117.72109 74.43573,117.70417 74.43501,117.69564 L 74.3799,63.265838 C 74.3799,63.015828 74.41383,62.731875 74.53013,62.518927 C 74.53013,62.518927 111.90814,23.750824 111.90814,11.251924 C 111.90814,6.9947672 90.56726,0.4721713 64.07844,0.4721712 z" style="fill:url(#linearGradient2325);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.18459648;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path id="path2880" d="M 64.077815,9.398298 C 44.544101,9.398298 28.36902,13.356343 25.791837,18.484968 C 34.209824,21.787518 48.209741,24 64.077815,24 C 79.928558,24 93.917453,21.833952 102.33849,18.537495 C 99.811032,13.39477 83.64834,9.398298 64.077815,9.398298 z" style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" /> <path sodipodi:nodetypes="ccsccc" id="path2900" d="M 57.429913,63.660786 L 57.429913,119.26952 C 59.214996,119.64495 61.433104,119.9077 64.07819,119.9077 C 66.27883,119.9077 68.183409,119.72504 69.813958,119.46096 L 69.813958,63.660786 C 65.685944,64.582695 61.557928,65.119361 57.429913,63.660786 z" style="opacity:0.61475375;fill:url(#linearGradient2321);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" /> <path sodipodi:nodetypes="cssscsc" id="path2945" d="M 54.05364,62.480138 C 54.050373,62.503 54.030261,62.520928 54.030261,62.543957 C 54.030261,63.764542 58.646106,65.770396 64.340254,65.770396 C 70.034397,65.770396 74.673621,63.764543 74.673625,62.543957 C 74.673625,62.521598 74.653326,62.50234 74.650245,62.480138 C 72.379359,62.994783 68.608504,63.309781 64.340254,63.309781 C 60.073012,63.30978 56.3247,62.994578 54.05364,62.480138 z" style="opacity:0.11000001;fill:url(#radialGradient2318);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path style="opacity:0.75819672;fill:url(#radialGradient2315);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" d="M 57.429913,63.807359 L 44.598832,24 C 53.424982,25.007037 62.430518,24.599508 71.288795,24.160406 L 69.813958,63.807359 C 65.685944,64.57975 61.557928,65.029378 57.429913,63.807359 z" id="path2915" sodipodi:nodetypes="ccccc" /> <path style="opacity:0.11000001;fill:url(#radialGradient2312);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" d="M 54.05364,62.480138 C 54.050373,62.503 54.030261,62.520928 54.030261,62.543957 C 54.030261,63.764542 58.646106,64.958119 64.340254,64.958119 C 70.034397,64.958119 74.673621,63.764543 74.673625,62.543957 C 74.673625,62.521598 74.653326,62.50234 74.650245,62.480138 C 72.379359,62.994783 68.54238,63.8513 64.274128,63.8513 C 60.006886,63.851299 56.3247,62.994578 54.05364,62.480138 z" id="path2962" sodipodi:nodetypes="cssscsc" /> <path transform="matrix(4.2019807,0,0,7.7206883,-221.93924,-859.19522)" d="M 79.338449,112.83906 A 11.285211,1.4818963 0 1 1 56.768027,112.83906 A 11.285211,1.4818963 0 1 1 79.338449,112.83906 z" sodipodi:ry="1.4818963" sodipodi:rx="11.285211" sodipodi:cy="112.83906" sodipodi:cx="68.053238" id="path2871" style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#5b5b5b;stroke-width:0.19620273;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" sodipodi:type="arc" /> <path sodipodi:nodetypes="ccccc" id="path2939" d="M 56.729366,63.68609 L 41.887377,24 C 50.713529,25.001442 64.724826,24.808862 73.583104,24.3722 L 70.367024,63.798885 C 66.239006,64.566985 60.857381,64.90132 56.729366,63.68609 z" style="opacity:0.75819672;fill:url(#radialGradient2308);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" /> <path sodipodi:type="arc" style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient2332);stroke-width:0.13700832;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" id="path3010" sodipodi:cx="68.053238" sodipodi:cy="112.83906" sodipodi:rx="11.285211" sodipodi:ry="1.4818963" d="M 79.338449,112.83906 A 11.285211,1.4818963 0 1 1 56.768027,112.83906 A 11.285211,1.4818963 0 1 1 79.338449,112.83906 z" transform="matrix(4.2043803,0,0,7.832456,-222.10254,-871.80695)" /> <path sodipodi:nodetypes="cssscsc" id="path2964" d="M 54.05364,62.480138 C 54.050373,62.503 54.030261,62.520928 54.030261,62.543957 C 54.030261,63.764542 58.679169,66.672928 64.373314,66.672928 C 70.067458,66.672928 74.673621,63.764543 74.673625,62.543957 C 74.673625,62.521598 74.653326,62.50234 74.650245,62.480138 C 72.379359,62.994783 68.344005,64.076933 64.075754,64.076933 C 59.80851,64.076932 56.3247,62.994578 54.05364,62.480138 z" style="opacity:0.11000001;fill:url(#radialGradient2304);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path style="opacity:0.61475375;fill:url(#linearGradient2300);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.31707315" d="M 56.752048,63.49897 L 57.429913,119.26952 C 59.214996,119.64495 61.433104,119.9077 64.07819,119.9077 C 66.27883,119.9077 68.183409,119.72504 69.813958,119.46096 L 70.283249,63.660786 C 66.155234,64.582695 60.880065,64.957546 56.752048,63.49897 z" id="path2943" sodipodi:nodetypes="ccsccc" /> <path sodipodi:nodetypes="ccccc" id="rect3007" d="M 72.189405,63.195363 L 73.23227,63.195363 L 73.23227,118.84109 L 72.15253,119.23497 L 72.189405,63.195363 z" style="opacity:0.21311478;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="rect3024" d="M 33.561894,4.0688722 C 38.714737,3.0721977 43.838836,2.2854781 48.91922,1.8181091 L 49.037348,8.8932006 C 44.819109,9.1859388 41.106601,10.362191 37.109709,11.168653 L 33.561894,4.0688722 z" style="opacity:0.83606561;fill:url(#linearGradient2293);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccsc" id="path3035" d="M 45.279272,11.288602 C 40.829452,11.474899 40.007663,11.54473 36.59864,11.871979 C 39.812937,13.236 43.503323,14.352439 46.584092,15.536315 C 50.68162,15.702374 55.063348,15.785167 59.646005,15.828683 C 56.702723,14.361914 53.045552,10.674121 48.669828,10.129129 C 45.59708,9.7464214 45.346835,11.317702 45.279272,11.288602 z" style="opacity:0.83606561;fill:url(#linearGradient2290);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path style="opacity:0.53278689;fill:url(#linearGradient2287);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" d="M 53.730639,62.885731 L 53.714243,62.870422 L 53.875545,118.19758 C 54.023651,118.79808 54.525843,118.88716 54.955285,119.08134 C 55.694913,96.275115 54.450528,80.511284 53.730639,62.885731 z" id="path2882" sodipodi:nodetypes="ccccc" /> </g> <path sodipodi:nodetypes="ccc" id="path3117" d="M -109.74325,70.909467 L -109.74325,68.114759 L -109.74325,70.909467 z" style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> </g> </svg> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/arrow-right.svg������������������������������������������������������0000644�0001750�0000144�00000105056�10737543470�017527� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/david" sodipodi:docname="arrow-right.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" inkscape:export-filename="arrow-left.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> <defs id="defs4"> <linearGradient inkscape:collect="always" id="linearGradient3327"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3329" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3331" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient4150"> <stop style="stop-color:#bfffbf;stop-opacity:1;" offset="0" id="stop4152" /> <stop style="stop-color:#bfffbf;stop-opacity:0;" offset="1" id="stop4154" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3409"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3411" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3413" /> </linearGradient> <linearGradient id="linearGradient3362" inkscape:collect="always"> <stop id="stop3364" offset="0" style="stop-color:#bfffbf;stop-opacity:1" /> <stop id="stop3366" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient id="linearGradient3355" inkscape:collect="always"> <stop id="stop3357" offset="0" style="stop-color:#e0ffe0;stop-opacity:1" /> <stop id="stop3359" offset="1" style="stop-color:#bfffbf;stop-opacity:0" /> </linearGradient> <linearGradient id="linearGradient3349" inkscape:collect="always"> <stop id="stop3351" offset="0" style="stop-color:#00dd00;stop-opacity:1" /> <stop id="stop3353" offset="1" style="stop-color:#000e00;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3342"> <stop style="stop-color:#00ff00;stop-opacity:1" offset="0" id="stop3344" /> <stop style="stop-color:#004d00;stop-opacity:1" offset="1" id="stop3346" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3710"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3712" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3714" /> </linearGradient> <linearGradient id="linearGradient3689" inkscape:collect="always"> <stop id="stop3691" offset="0" style="stop-color:#f0ff80;stop-opacity:1" /> <stop id="stop3693" offset="1" style="stop-color:#f0ff80;stop-opacity:0" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3669"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3671" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3673" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3511"> <stop style="stop-color:#002a0d;stop-opacity:1;" offset="0" id="stop3513" /> <stop style="stop-color:#002a0d;stop-opacity:0;" offset="1" id="stop3515" /> </linearGradient> <radialGradient id="radialGradient2854" cx="538.77338" cy="651.10352" r="126.0234" gradientTransform="translate(-484,-674)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#cbcbcb;stop-opacity:1;" id="stop2856" /> <stop offset="0.53930002" style="stop-color:#282828;stop-opacity:1;" id="stop2858" /> <stop offset="1" style="stop-color:#9d9d9d;stop-opacity:1;" id="stop2860" /> </radialGradient> <linearGradient id="linearGradient2862" gradientUnits="userSpaceOnUse" x1="538.77338" y1="677.87701" x2="538.77338" y2="789.12207" gradientTransform="translate(-484,-674)"> <stop offset="0.0056" style="stop-color:#4d4d4d;stop-opacity:1;" id="stop2864" /> <stop offset="0.1348" style="stop-color:#676767;stop-opacity:1;" id="stop2866" /> <stop offset="0.4831" style="stop-color:#b2b2b2;stop-opacity:1;" id="stop2868" /> <stop offset="0.62989998" style="stop-color:#aaa;stop-opacity:1;" id="stop2870" /> <stop offset="0.85280001" style="stop-color:#a1a1a1;stop-opacity:1;" id="stop2872" /> <stop offset="1" style="stop-color:#9d9d9d;stop-opacity:1;" id="stop2874" /> </linearGradient> <radialGradient id="radialGradient2876" cx="538.77252" cy="792.99609" r="121.5466" gradientTransform="translate(-484,-674)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#d9d9d9;stop-opacity:1;" id="stop2878" /> <stop offset="0.0494" style="stop-color:#c7c7c7;stop-opacity:1;" id="stop2880" /> <stop offset="0.1049" style="stop-color:#b9b9b9;stop-opacity:1;" id="stop2882" /> <stop offset="0.14321923" style="stop-color:#aeaeae;stop-opacity:1;" id="stop2884" /> <stop offset="0.2156" style="stop-color:#a9a9a9;stop-opacity:1;" id="stop2886" /> <stop offset="0.26969999" style="stop-color:#a6a6a6;stop-opacity:1;" id="stop2888" /> <stop offset="0.3989" style="stop-color:#676767;stop-opacity:1;" id="stop2890" /> <stop offset="0.39950001" style="stop-color:#676767;stop-opacity:1;" id="stop2892" /> <stop offset="0.44839999" style="stop-color:#545454;stop-opacity:1;" id="stop2894" /> <stop offset="0.49559999" style="stop-color:#414141;stop-opacity:1;" id="stop2896" /> <stop offset="0.53988957" style="stop-color:#353535;stop-opacity:1;" id="stop2898" /> <stop offset="0.57096523" style="stop-color:#313131;stop-opacity:1;" id="stop2900" /> <stop offset="0.5948" style="stop-color:#3e3e3e;stop-opacity:1;" id="stop2902" /> <stop offset="0.64560002" style="stop-color:#5f5f5f;stop-opacity:1;" id="stop2904" /> <stop offset="0.69319999" style="stop-color:#707070;stop-opacity:1;" id="stop2906" /> <stop offset="0.73589998" style="stop-color:#7b7b7b;stop-opacity:1;" id="stop2908" /> <stop offset="0.76969999" style="stop-color:#7f7f7f;stop-opacity:1;" id="stop2910" /> <stop offset="1" style="stop-color:#313131;stop-opacity:1;" id="stop2912" /> </radialGradient> <linearGradient id="linearGradient2914" gradientUnits="userSpaceOnUse" x1="538.77338" y1="793" x2="538.77338" y2="674" gradientTransform="translate(-484,-674)"> <stop offset="0" style="stop-color:#262626;stop-opacity:1;" id="stop2916" /> <stop offset="0.1124" style="stop-color:#313131;stop-opacity:1;" id="stop2918" /> <stop offset="0.37450001" style="stop-color:#4d4d4d;stop-opacity:1;" id="stop2920" /> <stop offset="0.42309999" style="stop-color:#505050;stop-opacity:1;" id="stop2922" /> <stop offset="0.43689999" style="stop-color:#575757;stop-opacity:1;" id="stop2924" /> <stop offset="0.44909999" style="stop-color:#646464;stop-opacity:1;" id="stop2926" /> <stop offset="0.4605" style="stop-color:#757575;stop-opacity:1;" id="stop2928" /> <stop offset="0.47119999" style="stop-color:#8a8a8a;stop-opacity:1;" id="stop2930" /> <stop offset="0.48140001" style="stop-color:#a3a3a3;stop-opacity:1;" id="stop2932" /> <stop offset="0.49110001" style="stop-color:silver;stop-opacity:1;" id="stop2934" /> <stop offset="0.49439999" style="stop-color:#dfdfdf;stop-opacity:1;" id="stop2936" /> <stop offset="0.51748788" style="stop-color:#afafaf;stop-opacity:1;" id="stop2938" /> <stop offset="0.53259999" style="stop-color:#949494;stop-opacity:1;" id="stop2940" /> <stop offset="0.55519998" style="stop-color:#7c7c7c;stop-opacity:1;" id="stop2942" /> <stop offset="0.58454067" style="stop-color:#656565;stop-opacity:1;" id="stop2944" /> <stop offset="0.60860002" style="stop-color:#525252;stop-opacity:1;" id="stop2946" /> <stop offset="0.64160001" style="stop-color:#434343;stop-opacity:1;" id="stop2948" /> <stop offset="0.69285822" style="stop-color:#393939;stop-opacity:1;" id="stop2951" /> <stop offset="0.73979998" style="stop-color:#333;stop-opacity:1;" id="stop2953" /> <stop offset="0.89889997" style="stop-color:#313131;stop-opacity:1;" id="stop2955" /> <stop offset="1" style="stop-color:#a6a8a4;stop-opacity:1;" id="stop2957" /> </linearGradient> <radialGradient cx="265.3931" cy="-6078.353" r="253.01871" fx="369.5242" fy="-6078.353" id="path2295_1_" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.183616,0,0,-1.462967e-2,-0.962917,-7.25873)"> <stop style="stop-color:#000000;stop-opacity:1" offset="0" id="stop8" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop10" /> <a:midPointStop style="stop-color:#000000" offset="0" /> <a:midPointStop style="stop-color:#000000" offset="0.5" /> <a:midPointStop style="stop-color:#FFFFFF" offset="1" /> </radialGradient> <filter inkscape:collect="always" x="-0.12239107" width="1.2447821" y="-0.078971461" height="1.1579429" id="filter3681"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.321914" id="feGaussianBlur3683" /> </filter> <filter inkscape:collect="always" x="-0.45196507" width="1.9039301" y="-0.29913295" height="1.5982659" id="filter3722"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.3476562" id="feGaussianBlur3724" /> </filter> <filter inkscape:collect="always" id="filter3435"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.395" id="feGaussianBlur3437" /> </filter> <filter inkscape:collect="always" id="filter3467"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.4349886" id="feGaussianBlur3469" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4009" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4011" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,-6.690938,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4013" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4017" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4019" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-54.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4021" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4023" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4025" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4027" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4029" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4031" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,-6.690938,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4033" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3689" id="radialGradient4035" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3710" id="radialGradient4037" gradientUnits="userSpaceOnUse" gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" cx="11.578125" cy="64.53125" fx="11.578125" fy="64.53125" r="3.578125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4039" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-54.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4041" gradientUnits="userSpaceOnUse" gradientTransform="translate(-24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4043" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4045" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4047" gradientUnits="userSpaceOnUse" gradientTransform="translate(-44,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4068" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4071" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4074" gradientUnits="userSpaceOnUse" gradientTransform="translate(-36,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4077" gradientUnits="userSpaceOnUse" gradientTransform="translate(-16,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4080" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-46.365246,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4085" gradientUnits="userSpaceOnUse" gradientTransform="translate(-16,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3669" id="radialGradient4088" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,9.309062,-57.693239)" cx="71.775223" cy="16.0865" fx="71.775223" fy="16.0865" r="3.15625" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4091" gradientUnits="userSpaceOnUse" gradientTransform="translate(-20,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4095" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="93.469109" y1="10.426203" x2="97.777351" y2="55.544682" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3409" id="linearGradient4098" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="103.74913" y1="84.078735" x2="72.5" y2="37.75" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="linearGradient4101" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,0)" x1="62" y1="12.899632" x2="87.010635" y2="69.692802" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient4104" gradientUnits="userSpaceOnUse" gradientTransform="translate(36,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4107" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,5.634754,-31.441692)" cx="53.630272" cy="79.055809" fx="57.058514" fy="91.805016" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient4112" gradientUnits="userSpaceOnUse" gradientTransform="translate(36,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4118" gradientUnits="userSpaceOnUse" gradientTransform="translate(12,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient4129" gradientUnits="userSpaceOnUse" gradientTransform="translate(32,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient4145" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,5.634754,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4162" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="matrix(0.988811,0,0,0.9872502,-4.2657949e-2,0.2039966)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4164" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="translate(20,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4179" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="matrix(0.9955244,0,0,0.9872502,0.3938517,0.8203689)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient4181" gradientUnits="userSpaceOnUse" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" gradientTransform="translate(20,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3511" id="linearGradient3296" gradientUnits="userSpaceOnUse" gradientTransform="translate(24,0)" x1="96.373123" y1="120.42788" x2="96.373123" y2="46.089832" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3310" gradientUnits="userSpaceOnUse" gradientTransform="translate(20,0)" x1="71.626404" y1="123.73875" x2="46.225941" y2="28.942928" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3349" id="radialGradient3312" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4429896,7.9739349e-8,-7.654978e-8,1.3852701,-6.365246,-31.441692)" cx="47.934944" cy="77.572655" fx="48.230755" fy="84.389229" r="50" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3355" id="linearGradient3314" gradientUnits="userSpaceOnUse" gradientTransform="translate(24,0)" x1="91.785248" y1="112.5" x2="91.992706" y2="44.287056" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4150" id="linearGradient3316" gradientUnits="userSpaceOnUse" gradientTransform="translate(8,0)" x1="35.629562" y1="11.479795" x2="46.758774" y2="70.827744" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3327" id="linearGradient3344" gradientUnits="userSpaceOnUse" gradientTransform="translate(28,0)" x1="56" y1="67.238144" x2="34.345421" y2="40.171875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3327" id="linearGradient3356" gradientUnits="userSpaceOnUse" gradientTransform="translate(28,0)" x1="42.548481" y1="13.921767" x2="46.758774" y2="70.827744" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="4.9140625" inkscape:cx="64" inkscape:cy="64" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" showgrid="true" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" inkscape:window-width="794" inkscape:window-height="732" inkscape:window-x="0" inkscape:window-y="0" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g3936" transform="matrix(-1,0,0,1,104,0)"> <path style="opacity:0.53694584;fill:#004d00;fill-opacity:1;fill-rule:evenodd;stroke:#004d00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3467)" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z " id="path3987" /> <path style="fill:url(#linearGradient3310);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,84.46875 L 68,83.875 L 68,78.0625 L 68,49.9375 L 68,45 L 68,43.53125 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z M 60,24.3125 L 60,39.6875 L 54.59375,44 L 45,44 C 44.446,44 44,44.446 44,45 L 44,52.46875 L 33.5,60.875 C 32.550144,61.63413 32,62.78406 32,64 C 32,65.21594 32.550144,66.36587 33.5,67.125 L 44,75.53125 L 44,83.875 C 44,84.429 44.446,84.875 45,84.875 L 55.6875,84.875 L 60,88.3125 L 60,103.6875 L 10.40625,64 L 60,24.3125 z M 44,62.71875 L 44,65.28125 L 42.40625,64 L 44,62.71875 z " id="path3989" /> <path style="opacity:0.53694584;fill:url(#linearGradient3296);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 63.875,12 C 63.009497,12.02693 62.176101,12.33398 61.5,12.875 L 1.5,60.875 C 0.550144,61.63413 0,62.78406 0,64 C 0,65.21594 0.550144,66.36587 1.5,67.125 L 61.5,115.125 C 62.700963,116.08613 64.332437,116.26025 65.71875,115.59375 C 67.105067,114.92725 68.000642,113.53821 68,112 L 68,94.71875 L 68,84.46875 L 68,83.875 L 68,83.1875 L 68,78.0625 L 68,49.9375 L 68,45 L 68,44.8125 L 68,43.53125 L 68,33.28125 L 68,16 C 68.000417,14.91715 67.558627,13.87882 66.78125,13.125 C 66.003873,12.37118 64.957323,11.96627 63.875,12 z M 60,24.3125 L 60,39.6875 L 54.59375,44 L 45,44 C 44.446,44 44,44.446 44,45 L 44,52.46875 L 33.5,60.875 C 32.550144,61.63413 32,62.78406 32,64 C 32,65.21594 32.550144,66.36587 33.5,67.125 L 44,75.53125 L 44,83.875 C 44,84.429 44.446,84.875 45,84.875 L 55.6875,84.875 L 60,88.3125 L 60,103.6875 L 10.40625,64 L 60,24.3125 z M 44,62.71875 L 44,65.28125 L 42.40625,64 L 44,62.71875 z " id="path3993" /> <path style="fill:url(#radialGradient3312);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 64,16 L 4,64 L 64,112 L 64,86.40625 L 64,41.59375 L 64,16 z " id="path3999" /> <path style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3314);stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3435)" d="M 64,16 L 4,64 L 64,112 L 64,86.40625 L 64,41.59375 L 64,16 z " id="path4001" /> <path id="path3651" d="M 63.875,12 C 63.075959,12.024867 62.302054,12.283948 61.65625,12.75 L 62.625,21.78125 L 67.96875,15.625 C 67.880958,14.678789 67.469257,13.792159 66.78125,13.125 C 66.003873,12.37118 64.957323,11.966273 63.875,12 z " style="opacity:0.85;fill:url(#radialGradient4088);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> <path transform="matrix(1,0,0,-1,-8,127.7793)" style="opacity:0.35;fill:url(#radialGradient4035);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " id="path3685" /> <path transform="matrix(1,0,0,-1,-8,128.5625)" id="path3705" d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " style="opacity:0.5;fill:url(#radialGradient4037);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> <path style="fill:url(#linearGradient3316);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 64,16 L 4.1875,63.84375 C 12.238841,64.168797 20.513445,64.34375 28.90625,64.34375 C 40.962046,64.34375 52.698537,63.975426 64,63.3125 L 64,41.59375 L 64,16 z " id="path4143" /> <path style="fill:url(#linearGradient3344);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 84,16 L 83.65625,16.28125 L 83.65625,41.375 L 83.65625,62.90625 C 72.417269,63.563595 60.770394,63.937499 48.78125,63.9375 C 40.607993,63.9375 32.537203,63.778318 24.6875,63.46875 L 24.1875,63.84375 C 32.238841,64.168797 40.513445,64.34375 48.90625,64.34375 C 60.962046,64.34375 72.698537,63.975426 84,63.3125 L 84,41.59375 L 84,16 z " transform="translate(-20,0)" id="path3335" /> <path style="fill:url(#linearGradient3356);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 84,16 L 24.1875,63.84375 L 83.75,16.90625 L 83.75,42.03125 L 83.75,63.3125 C 83.832324,63.307705 83.917722,63.317326 84,63.3125 L 84,41.59375 L 84,16 z " transform="translate(-20,0)" id="path3347" /> </g> </g> </svg> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/assgn-all.svg��������������������������������������������������������0000644�0001750�0000144�00000006777�11163114125�017136� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="680" height="680" id="svg2273" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" sodipodi:docname="assgn-all.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0"> <defs id="defs2275" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="375" inkscape:cy="405.71429" inkscape:document-units="px" inkscape:current-layer="layer1" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" showgrid="false" showguides="true" height="680px" width="680px" /> <metadata id="metadata2278"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-47.400002,-191.39075)"> <rect style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:15;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4135" width="660" height="630" x="59.899994" y="217.46219" /> <path style="fill:#ccccff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 161.68572,655.67647 L 604.54286,652.81933 L 604.54286,421.39076 L 158.20257,422.81933 L 161.68572,655.67647 z " id="path5108" sodipodi:nodetypes="ccccc" /> <path id="path3155" d="M 68.114294,417.81933 L 708.11429,417.81933" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path3160" d="M 68.114294,657.81933 L 708.11429,657.81933" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 608.11429,237.81933 L 608.11429,817.81932" id="path3164" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 163.11429,242.81934 L 163.11429,822.81933" id="path3162" /> </g> </svg> �MP3Diags-1.0.12.079/src/images/mode_all.svg���������������������������������������������������������0000644�0001750�0000144�00000634015�11074211623�017023� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="88" height="88" id="svg2" sodipodi:version="0.32" inkscape:version="0.46" version="1.0" sodipodi:docbase="/home/david" sodipodi:docname="computer-laptop22.svgz" inkscape:output_extension="org.inkscape.output.svgz.inkscape" inkscape:export-filename="/home/david/computer-laptop22.png" inkscape:export-xdpi="22.5" inkscape:export-ydpi="22.5"> <defs id="defs4"> <linearGradient id="linearGradient6919"> <stop id="stop6921" offset="0" style="stop-color:#ffffff;stop-opacity:1" /> <stop id="stop6923" offset="1" style="stop-color:#404040;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient6901"> <stop style="stop-color:#9a9a9a;stop-opacity:1;" offset="0" id="stop6903" /> <stop id="stop6905" offset="0.39151657" style="stop-color:#d0d0d0;stop-opacity:1;" /> <stop id="stop6907" offset="0.47794837" style="stop-color:#e4e4e4;stop-opacity:1;" /> <stop style="stop-color:#e2e2e2;stop-opacity:1;" offset="0.55253351" id="stop6909" /> <stop style="stop-color:#acacac;stop-opacity:1;" offset="1" id="stop6911" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6893"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop6895" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop6897" /> </linearGradient> <linearGradient id="linearGradient4663"> <stop id="stop4665" offset="0" style="stop-color:#939393;stop-opacity:1;" /> <stop id="stop4667" offset="1" style="stop-color:#ffffff;stop-opacity:1;" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient4575"> <stop style="stop-color:#aaaaaa;stop-opacity:1" offset="0" id="stop4577" /> <stop style="stop-color:#f6f6f6;stop-opacity:1" offset="1" id="stop4579" /> </linearGradient> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="-50 : 600 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="700 : 600 : 1" inkscape:persp3d-origin="300 : 400 : 1" id="perspective1285" /> <linearGradient inkscape:collect="always" id="linearGradient8929"> <stop style="stop-color:#dddddd;stop-opacity:1;" offset="0" id="stop8931" /> <stop style="stop-color:#f4f4f4;stop-opacity:1" offset="1" id="stop8933" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient8919"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop8921" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop8923" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient8309"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop8311" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop8313" /> </linearGradient> <linearGradient id="linearGradient6016"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6018" /> <stop id="stop6031" offset="0.5" style="stop-color:#ffffff;stop-opacity:1;" /> <stop style="stop-color:#000000;stop-opacity:0" offset="1" id="stop6020" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3612"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3614" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3616" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3571"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3573" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3575" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3532"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3534" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3536" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3485"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3487" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3489" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3434"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3436" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3438" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3383"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3385" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3387" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3154"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3156" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3158" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3154" id="linearGradient3160" x1="68.290016" y1="120" x2="68.290016" y2="117.71922" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6659784,0,0,0.674911,1.3108923,-0.2305625)" /> <linearGradient gradientUnits="userSpaceOnUse" y2="0.60519463" x2="69" y1="35.035378" x1="69" id="linearGradient4056" xlink:href="#linearGradient4050" inkscape:collect="always" /> <linearGradient id="linearGradient4838"> <stop id="stop4840" offset="0" style="stop-color:#9a9a9a;stop-opacity:1;" /> <stop style="stop-color:#d0d0d0;stop-opacity:1;" offset="0.26439792" id="stop4846" /> <stop style="stop-color:#e4e4e4;stop-opacity:1;" offset="0.52879584" id="stop4842" /> <stop id="stop4848" offset="0.76439792" style="stop-color:#e2e2e2;stop-opacity:1;" /> <stop id="stop4844" offset="1" style="stop-color:#acacac;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient3722"> <stop style="stop-color:#ececec;stop-opacity:1;" offset="0" id="stop3724" /> <stop style="stop-color:#404040;stop-opacity:1;" offset="1" id="stop3726" /> </linearGradient> <linearGradient y2="69" x2="220" y1="69" x1="26" gradientUnits="userSpaceOnUse" id="XMLID_18_"> <stop id="stop3354" style="stop-color:#3383E6" offset="0" /> <stop id="stop3364" style="stop-color:#6ECAF7" offset="1" /> </linearGradient> <linearGradient id="linearGradient6148" inkscape:collect="always"> <stop id="stop6150" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop6152" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6160"> <stop id="stop6162" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop6164" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient4050"> <stop id="stop4052" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop4054" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4838" id="linearGradient3375" x1="16" y1="46" x2="112" y2="46" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6575669,0,0,0.6393894,2.1220616,2.7532546)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6901" id="linearGradient3377" x1="-17.344589" y1="100" x2="145.34457" y2="100" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6659784,0,0,0.674911,1.3108923,-0.2305625)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3383" id="linearGradient3389" x1="62.250397" y1="87.318779" x2="62.250397" y2="79.317192" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6399935,0,0,1.349822,3.2467577,-56.923086)" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_18_" id="linearGradient3391" x1="48.704517" y1="74.100822" x2="100.87797" y2="-16.266243" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.5509319,0,0,0.5413142,8.9466987,7.6456772)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6148" id="linearGradient3395" x1="40.080582" y1="-24.26848" x2="64.757896" y2="67.828522" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.5509319,0,0,0.5298935,8.9466987,7.6007165)" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_18_" id="linearGradient3406" gradientUnits="userSpaceOnUse" x1="48.704517" y1="74.100822" x2="100.87797" y2="-16.266243" /> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3402"> <rect y="16" x="20" height="56" width="88" id="rect3404" style="opacity:1;fill:url(#linearGradient3406);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <filter inkscape:collect="always" id="filter3408"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.36" id="feGaussianBlur3410" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6160" id="linearGradient3414" x1="80.745766" y1="-32.698048" x2="80.745766" y2="111.42319" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4838" id="linearGradient3424" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.9473684,0,4.4210526)" x1="16" y1="46" x2="112" y2="46" /> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3420"> <rect ry="3.0427892" rx="3.0427892" style="opacity:1;fill:url(#linearGradient3424);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect3422" width="96" height="72" x="16" y="12" /> </clipPath> <filter inkscape:collect="always" id="filter3430"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.42" id="feGaussianBlur3432" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3434" id="linearGradient3440" x1="74.624405" y1="12" x2="75.030113" y2="136.3132" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6148" id="linearGradient3469" x1="16.125" y1="44" x2="21.435581" y2="44" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4591099,0,0,0.567743,10.783139,6.995124)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6148" id="linearGradient3473" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4591099,0,0,0.567743,-77.629552,6.995124)" x1="16.125" y1="44" x2="21.435581" y2="44" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3532" id="radialGradient3540" cx="64" cy="6.077126" fx="64" fy="6.077126" r="48" gradientTransform="matrix(0.7916589,0,0,0.2797531,-6.459816,9.2444147)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3571" id="linearGradient3577" x1="66.05864" y1="80" x2="66.05864" y2="108.73045" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6659784,0,0,0.674911,1.3108923,-0.2305625)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3571" id="linearGradient3581" gradientUnits="userSpaceOnUse" x1="66.05864" y1="80" x2="66.05864" y2="82.152748" gradientTransform="matrix(0.6659784,0,0,0.674911,1.3108923,-0.2305625)" /> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3599"> <path style="opacity:0.60962572;fill:#000000;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" d="M 8.042789,120 L 119.95721,120 C 121.64292,120 123,118.64292 123,116.95721 L 113,83.042789 C 113,81.357084 111.64292,80 109.95721,80 L 18.042789,80 C 16.357084,80 15,81.357084 15,83.042789 L 5,116.95721 C 5,118.64292 6.357084,120 8.042789,120 z" id="path3601" sodipodi:nodetypes="ccccccccc" /> </clipPath> <filter inkscape:collect="always" id="filter3607"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.395" id="feGaussianBlur3609" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3612" id="linearGradient3618" x1="56.524563" y1="120" x2="56.524563" y2="65.894577" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" id="filter3622"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.2" id="feGaussianBlur3624" /> </filter> <linearGradient y2="456.74942" x2="234.51614" y1="425.57565" x1="233.39261" gradientTransform="translate(-4.8462737e-7,-153.12148)" gradientUnits="userSpaceOnUse" id="linearGradient3492" xlink:href="#linearGradient4910" inkscape:collect="always" /> <linearGradient id="linearGradient3459"> <stop id="stop3461" offset="0" style="stop-color:#bebebe;stop-opacity:1;" /> <stop id="stop3463" offset="1" style="stop-color:#ededed;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient4910"> <stop id="stop4912" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop4914" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6016" id="linearGradient6080" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1398964,0,0,1.037561,-528.28101,-25.298464)" spreadMethod="pad" x1="459.76901" y1="88.303291" x2="560.26788" y2="88.303291" /> <mask maskUnits="userSpaceOnUse" id="mask6076"> <rect ry="1.9275723" rx="1.8991808" y="30.092897" x="-6.4667706" height="72.457382" width="116.83311" id="rect6078" style="opacity:0.91443846;fill:url(#linearGradient6080);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="matrix(1,0,0.2666309,0.9637987,0,0)" /> </mask> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6016" id="linearGradient6086" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="509.02063" y1="88.303291" x2="560.26788" y2="88.303291" gradientTransform="translate(-446.33644,-24.382627)" /> <mask maskUnits="userSpaceOnUse" id="mask6082"> <rect style="opacity:0.91443846;fill:url(#linearGradient6086);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect6084" width="102.49451" height="69.834335" x="11.436936" y="29.003496" rx="1.8991808" ry="1.9275723" /> </mask> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6016" id="linearGradient6092" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0803109,0,0,1.0373429,-628.44728,-25.293145)" spreadMethod="pad" x1="459.76901" y1="88.303291" x2="560.26788" y2="88.303291" /> <mask maskUnits="userSpaceOnUse" id="mask6088"> <rect transform="matrix(-1,0,-0.2658972,0.9640014,0,0)" style="opacity:0.91443846;fill:url(#linearGradient6092);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect6090" width="110.72593" height="72.442154" x="-133.90971" y="30.086571" rx="1.8991808" ry="1.9275723" /> </mask> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath8305"> <path sodipodi:nodetypes="ccccsccsccc" id="path8307" d="M 99.5625,82.5625 L 28.25,82.71875 C 26.492454,82.72624 24.945654,83.880001 24.4375,85.5625 L 18.71875,104.46875 C 18.352322,105.68284 18.58327,106.99876 19.341218,108.01552 C 20.099166,109.03228 21.294326,109.62943 22.5625,109.625 L 105.4375,109.625 C 106.70567,109.62943 107.90083,109.03228 108.65878,108.01552 C 109.41673,106.99876 109.64768,105.68284 109.28125,104.46875 L 103.40625,85.375 C 102.88348,83.693821 101.32305,82.55204 99.5625,82.5625 z" style="fill:#888888;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8309" id="linearGradient8315" x1="62.769958" y1="83.922569" x2="62.769958" y2="108.09335" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8309" id="linearGradient8351" gradientUnits="userSpaceOnUse" x1="62.769958" y1="83.922569" x2="62.769958" y2="108.09335" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8919" id="linearGradient8925" x1="55.285706" y1="88.726128" x2="76.559944" y2="135.07617" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8929" id="linearGradient8935" x1="70.111084" y1="117.62029" x2="65.577614" y2="100.70116" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9270266,0,0,0.9270266,4.6702948,8.5831474)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3722" id="radialGradient8957" cx="64" cy="115.875" fx="64" fy="115.875" r="16.1875" gradientTransform="matrix(1.1003228,0,0,0.2292628,-6.4206622,89.309167)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6919" id="radialGradient8968" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1003228,0,0,0.2292628,-6.4206622,89.309167)" cx="64" cy="110.59166" fx="64" fy="110.59166" r="16.1875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3485" id="radialGradient8982" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9840669,0,0,5.5184959e-2,-19.046764,72.56553)" cx="64" cy="115.5" fx="64" fy="115.5" r="58.71875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient8309" id="linearGradient10671" gradientUnits="userSpaceOnUse" x1="62.769958" y1="83.922569" x2="62.769958" y2="108.09335" /> <filter inkscape:collect="always" id="filter11695"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.41124814" id="feGaussianBlur11697" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient6055" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,59.882251,4.0008339)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient6057" gradientUnits="userSpaceOnUse" gradientTransform="translate(59.882251,15.749368)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6160" id="linearGradient6913" gradientUnits="userSpaceOnUse" x1="80.745766" y1="-32.698048" x2="80.745766" y2="111.42319" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6893" id="linearGradient3384" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0076295,0,0,1.0076295,-0.4934465,-0.7152404)" x1="53.867825" y1="69.816917" x2="53.867825" y2="110.53412" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3386" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,8.2851637e-2,0.4950431,47.021782,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3388" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,7.7457295e-2,0.4628116,47.931792,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3390" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,8.2851637e-2,0.4950431,42.969622,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3392" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,7.7457295e-2,0.4628116,43.879632,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3394" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,54.479598,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3396" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,54.479598,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3398" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,50.427438,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3400" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,50.427438,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3402" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,46.375278,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3404" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,46.375278,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3407" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8412778,0,-4.4207941e-2,0.4950431,3.4386548,89.332617)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3409" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8412778,0,-4.1329629e-2,0.4628116,2.9530922,94.769975)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3411" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,-8.3351118e-2,0.4950431,13.555542,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3413" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,-7.7924254e-2,0.4628116,12.640046,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3415" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,2.1728689,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3417" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,2.1728689,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3419" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,6.1652951,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3421" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,6.1652951,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3423" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,10.157722,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3425" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,10.157722,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3427" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,14.074819,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3429" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,14.074819,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3431" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,18.142574,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3433" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,18.142574,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3435" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,22.210329,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3437" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,22.210329,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3439" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,26.127427,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3441" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,26.127427,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3443" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,30.195182,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3445" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,30.195182,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3447" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,34.262937,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3449" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,34.262937,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3451" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,38.330692,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3453" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,38.330692,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3455" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4950431,42.323118,89.414431)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3457" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.8522481,0,0,0.4628116,42.323118,94.851789)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3460" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-9.5520399e-2,1.069643,1.3277381,-5.9870492)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3462" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-8.9301196e-2,1,0.2785799,5.7614848)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3464" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-8.2258689e-2,1.069643,3.852811,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3466" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-7.6902938e-2,1,2.9493143,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3468" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-5.7019031,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3470" gradientUnits="userSpaceOnUse" gradientTransform="translate(-5.7019031,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3472" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-1.0173207,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3474" gradientUnits="userSpaceOnUse" gradientTransform="translate(-1.0173207,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3476" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,3.6672617,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3478" gradientUnits="userSpaceOnUse" gradientTransform="translate(3.6672617,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3480" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,8.2634558,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3482" gradientUnits="userSpaceOnUse" gradientTransform="translate(8.2634558,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3484" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,13.036427,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3486" gradientUnits="userSpaceOnUse" gradientTransform="translate(13.036427,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3488" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,17.809398,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3490" gradientUnits="userSpaceOnUse" gradientTransform="translate(17.809398,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3493" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,22.405592,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3495" gradientUnits="userSpaceOnUse" gradientTransform="translate(22.405592,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3497" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,27.178563,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3499" gradientUnits="userSpaceOnUse" gradientTransform="translate(27.178563,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3501" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,31.951534,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3503" gradientUnits="userSpaceOnUse" gradientTransform="translate(31.951534,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3505" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,36.724505,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3507" gradientUnits="userSpaceOnUse" gradientTransform="translate(36.724505,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3509" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,41.409087,-5.8102725)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3511" gradientUnits="userSpaceOnUse" gradientTransform="translate(41.409087,5.9382615)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3513" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0.1767137,1.069643,21.452302,-5.8102727)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3515" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0.1652082,1,23.393255,5.9382613)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3517" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4614728,0,-9.5520399e-2,1.069643,-29.264116,-2.7166805)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3519" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.4614728,0,-8.9301196e-2,1,-30.313274,9.0318535)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3521" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-8.2258689e-2,1.069643,5.0223208,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3523" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-7.6902938e-2,1,4.118824,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3525" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.7277071,0,-8.7981592e-2,0.985223,-48.391394,14.618285)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3527" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.780954,0,-8.2253224e-2,0.9210764,-53.068052,25.439582)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3529" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.2307364,0,-9.5520399e-2,1.069643,-15.498533,3.3821155)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3531" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.2307364,0,-8.9301196e-2,1,-16.547691,15.130649)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3533" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-4.2876895,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3535" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4.2876895,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3537" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,0.3968929,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3539" gradientUnits="userSpaceOnUse" gradientTransform="translate(0.3968929,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3541" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,5.0814753,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3543" gradientUnits="userSpaceOnUse" gradientTransform="translate(5.0814753,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3545" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,9.6776694,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3547" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.6776694,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3549" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,14.45064,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3551" gradientUnits="userSpaceOnUse" gradientTransform="translate(14.45064,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3553" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,19.223611,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3555" gradientUnits="userSpaceOnUse" gradientTransform="translate(19.223611,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3557" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,23.819805,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3559" gradientUnits="userSpaceOnUse" gradientTransform="translate(23.819805,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3561" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,28.592776,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3563" gradientUnits="userSpaceOnUse" gradientTransform="translate(28.592776,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3565" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,33.365747,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3567" gradientUnits="userSpaceOnUse" gradientTransform="translate(33.365747,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3569" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,38.138718,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3572" gradientUnits="userSpaceOnUse" gradientTransform="translate(38.138718,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3574" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,42.8233,-2.628292)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3576" gradientUnits="userSpaceOnUse" gradientTransform="translate(42.8233,9.120242)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3578" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-8.1767767,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3580" gradientUnits="userSpaceOnUse" gradientTransform="translate(-8.1767767,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3582" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-3.3154176,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3584" gradientUnits="userSpaceOnUse" gradientTransform="translate(-3.3154176,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3586" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,1.3691648,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3588" gradientUnits="userSpaceOnUse" gradientTransform="translate(1.3691648,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3590" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,6.0537472,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3592" gradientUnits="userSpaceOnUse" gradientTransform="translate(6.0537472,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3594" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,10.649942,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3596" gradientUnits="userSpaceOnUse" gradientTransform="translate(10.649942,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3598" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,15.422912,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3600" gradientUnits="userSpaceOnUse" gradientTransform="translate(15.422912,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3602" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,20.195883,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3604" gradientUnits="userSpaceOnUse" gradientTransform="translate(20.195883,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3606" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,24.792077,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3608" gradientUnits="userSpaceOnUse" gradientTransform="translate(24.792077,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3610" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,29.565048,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3613" gradientUnits="userSpaceOnUse" gradientTransform="translate(29.565048,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3615" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,34.338019,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3617" gradientUnits="userSpaceOnUse" gradientTransform="translate(34.338019,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3619" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,39.11099,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3621" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1443296,0,0.1767137,1.069643,7.5124657,-2.6019574)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3623" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.6754787,0,0,1.069643,-67.709856,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3625" gradientUnits="userSpaceOnUse" gradientTransform="translate(39.11099,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3627" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1443296,0,0.1652082,1,9.4534193,9.1465766)" x1="67.1912" y1="168.69659" x2="67.1912" y2="174.46774" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3629" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,43.795572,0.4653)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3631" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.7256803,0,0,1,-70.957963,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3633" gradientUnits="userSpaceOnUse" gradientTransform="translate(43.795572,12.213834)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3635" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-8.2258689e-2,1.069643,3.0507041,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3637" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-7.6902938e-2,1,2.1472073,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3639" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-5.7902913,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3641" gradientUnits="userSpaceOnUse" gradientTransform="translate(-5.7902913,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3643" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-1.1057089,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3645" gradientUnits="userSpaceOnUse" gradientTransform="translate(-1.1057089,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3647" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,3.5788735,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3649" gradientUnits="userSpaceOnUse" gradientTransform="translate(3.5788735,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3651" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,8.1750683,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3653" gradientUnits="userSpaceOnUse" gradientTransform="translate(8.1750683,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3655" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,12.948038,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3657" gradientUnits="userSpaceOnUse" gradientTransform="translate(12.948038,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3659" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,17.721009,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3661" gradientUnits="userSpaceOnUse" gradientTransform="translate(17.721009,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3663" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,22.317203,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3665" gradientUnits="userSpaceOnUse" gradientTransform="translate(22.317203,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3667" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,27.090174,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3669" gradientUnits="userSpaceOnUse" gradientTransform="translate(27.090174,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3671" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,31.863145,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3673" gradientUnits="userSpaceOnUse" gradientTransform="translate(31.863145,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3675" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,36.636116,3.470504)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3677" gradientUnits="userSpaceOnUse" gradientTransform="translate(36.636116,15.219038)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3679" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-8.2258689e-2,1.069643,2.8127978,6.564096)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3681" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,-7.6902938e-2,1,1.909301,18.31263)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3683" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-5.7902913,6.564096)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3685" gradientUnits="userSpaceOnUse" gradientTransform="translate(-5.7902913,18.31263)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3687" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,-1.1057089,6.564096)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3689" gradientUnits="userSpaceOnUse" gradientTransform="translate(-1.1057089,18.31263)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3691" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,3.5788735,6.564096)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3693" gradientUnits="userSpaceOnUse" gradientTransform="translate(3.5788735,18.31263)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3695" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,31.863145,6.564096)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3697" gradientUnits="userSpaceOnUse" gradientTransform="translate(31.863145,18.31263)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3699" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,36.636116,6.564096)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3701" gradientUnits="userSpaceOnUse" gradientTransform="translate(36.636116,18.31263)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3703" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.069643,41.320698,6.564096)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3705" gradientUnits="userSpaceOnUse" gradientTransform="translate(41.320698,18.31263)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3707" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.2307364,0,-9.5520399e-2,1.069643,-15.782687,6.564096)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3709" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.2307364,0,-8.9301196e-2,1,-16.831845,18.31263)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3711" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.71626,0,0.126573,0.7661425,45.418757,60.219494)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3713" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.71626,0,0.118332,0.71626,46.808984,68.634499)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3715" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.71626,0,0.126573,0.7661425,48.710827,60.219494)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3717" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.71626,0,0.118332,0.71626,50.101054,68.634499)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3719" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.71626,0,0.126573,0.7661425,52.129516,60.219494)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3721" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.71626,0,0.118332,0.71626,53.519743,68.634499)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3723" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.71626,0,0.126573,0.7661425,48.397607,57.940369)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3725" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.71626,0,0.118332,0.71626,49.787834,66.355373)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3727" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0.1767137,1.069643,22.110961,-2.8934572)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3729" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0.1652082,1,24.051914,8.8550768)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3731" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0.1767137,1.069643,22.9756,0.200135)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3733" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0.1652082,1,24.916554,11.948669)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3735" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0.1767137,1.069643,23.884821,3.0285621)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3737" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0.1652082,1,25.825775,14.777096)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4663" id="linearGradient3739" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.3904769,0,0,1.069643,20.564163,-5.898661)" x1="67.1912" y1="172.16859" x2="67.1912" y2="167.88409" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4575" id="linearGradient3741" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.3904769,0,0,1,20.564163,5.849873)" x1="67.1912" y1="168.69659" x2="67.1912" y2="171.41859" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="7.2159091" inkscape:cx="44" inkscape:cy="44" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" showgrid="true" inkscape:grid-points="true" inkscape:window-width="703" inkscape:window-height="731" inkscape:window-x="0" inkscape:window-y="0" inkscape:snap-bbox="true"> <inkscape:grid id="GridFromPre046Settings" type="xygrid" originx="0px" originy="0px" spacingx="4px" spacingy="4px" color="#0000ff" empcolor="#0000ff" opacity="0.2" empopacity="0.4" empspacing="4" visible="true" enabled="true" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title /> <dc:date /> <dc:creator> <cc:Agent> <dc:title /> </cc:Agent> </dc:creator> <dc:rights> <cc:Agent> <dc:title /> </cc:Agent> </dc:rights> <dc:publisher> <cc:Agent> <dc:title /> </cc:Agent> </dc:publisher> <dc:identifier /> <dc:source /> <dc:relation /> <dc:language /> <dc:subject> <rdf:Bag /> </dc:subject> <dc:coverage /> <dc:description /> <dc:contributor> <cc:Agent> <dc:title /> </cc:Agent> </dc:contributor> <cc:license rdf:resource="" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" style="display:inline"> <path transform="matrix(0.6696346,0,0,0.6099167,1.0769012,7.8407121)" sodipodi:nodetypes="ccccccccc" id="path11693" d="M 8.042789,120 L 119.95721,120 C 121.64292,120 123,118.64292 123,116.95721 L 113,83.042789 C 113,81.357084 111.64292,80 109.95721,80 L 18.042789,80 C 16.357084,80 15,81.357084 15,83.042789 L 5,116.95721 C 5,118.64292 6.357084,120 8.042789,120 z" style="opacity:0.61000001;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.57334316;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter11695)" /> <path style="opacity:0.37563453;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.57334316;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter3622)" d="M 8.042789,120 L 119.95721,120 C 121.64292,120 123,118.64292 123,116.95721 L 113,83.042789 C 113,81.357084 111.64292,80 109.95721,80 L 18.042789,80 C 16.357084,80 15,81.357084 15,83.042789 L 5,116.95721 C 5,118.64292 6.357084,120 8.042789,120 z" id="path3620" sodipodi:nodetypes="ccccccccc" transform="matrix(0.6769468,0,0,0.6165768,0.6089195,7.1747004)" /> <rect y="7.8683696" x="12.643131" height="48.593586" width="63.126434" id="rect3134" style="opacity:1;fill:url(#linearGradient3375);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" rx="3.0427892" ry="3.0427892" /> <rect ry="3.0427892" rx="3.0427892" style="opacity:0.78609625;fill:url(#radialGradient3540);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" id="rect3530" width="63.126434" height="48.593586" x="12.643131" y="7.8683696" /> <rect style="opacity:1;fill:url(#linearGradient3391);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" id="rect2160" width="48.482014" height="30.313601" x="19.965338" y="16.306707" /> <rect ry="3.0427892" rx="3.0427892" style="opacity:1;fill:url(#linearGradient3389);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" id="rect3379" width="61.439388" height="10.798576" x="13.486653" y="45.663383" /> <rect y="12" x="16" height="72" width="96" id="rect3418" style="opacity:0.08474576;fill:none;fill-opacity:1;stroke:url(#linearGradient3440);stroke-width:3.00218033999999978;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter3430)" rx="4.6273451" ry="4.50843" clip-path="url(#clipPath3420)" transform="matrix(0.6575669,0,0,0.674911,2.1220616,-0.2305625)" /> <path style="fill:url(#linearGradient3395);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" d="M 19.965338,16.079013 L 63.902166,16.079013 L 44.206347,47.872625 L 19.965338,47.872625 L 19.965338,16.079013 z" id="rect3393" sodipodi:nodetypes="ccccc" /> <rect style="opacity:1;fill:none;fill-opacity:1;stroke:url(#linearGradient6913);stroke-width:1.78694832;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter3408)" id="rect3400" width="88" height="56" x="20" y="16" clip-path="url(#clipPath3402)" transform="matrix(0.5509319,0,0,0.5684314,8.9011084,6.9648443)" /> <rect ry="0" rx="0" style="opacity:1;fill:url(#linearGradient3469);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" id="rect3461" width="1.3773299" height="31.793606" x="18.588007" y="16.079012" /> <rect y="16.079012" x="-69.824684" height="31.793606" width="1.3773299" id="rect3471" style="opacity:1;fill:url(#linearGradient3473);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" rx="0" ry="0" transform="scale(-1,1)" /> <path style="fill:url(#linearGradient3377);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" d="M 6.6672171,80.75877 L 81.199815,80.75877 C 82.322465,80.75877 83.226249,79.842847 83.226249,78.705144 L 76.566459,55.81593 C 76.566459,54.678228 75.662675,53.762319 74.540033,53.762319 L 13.327001,53.762319 C 12.204359,53.762319 11.300569,54.678228 11.300569,55.81593 L 4.6407848,78.705144 C 4.6407848,79.842847 5.5445737,80.75877 6.6672171,80.75877 z" id="rect3136" sodipodi:nodetypes="ccccccccc" /> <path style="opacity:0.69518714;fill:url(#linearGradient3160);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" d="M 4.8280915,78.059112 L 4.6407848,78.712929 C 4.6407848,79.850646 5.536889,80.75877 6.6595323,80.75877 L 81.207496,80.75877 C 82.330152,80.75877 83.226249,79.850646 83.226249,78.712929 L 83.038945,78.059112 L 4.8280915,78.059112 z" id="path3149" /> <path sodipodi:nodetypes="ccccccccc" id="path3597" d="M 8.042789,120 L 119.95721,120 C 121.64292,120 123,118.64292 123,116.95721 L 113,83.042789 C 113,81.357084 111.64292,80 109.95721,80 L 18.042789,80 C 16.357084,80 15,81.357084 15,83.042789 L 5,116.95721 C 5,118.64292 6.357084,120 8.042789,120 z" style="opacity:0.33689838;fill:none;fill-opacity:1;stroke:url(#linearGradient3618);stroke-width:2.98316073;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter3607)" clip-path="url(#clipPath3599)" transform="matrix(0.6659784,0,0,0.674911,1.3108923,-0.2305625)" /> <path style="fill:url(#linearGradient3581);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" d="M 6.6672171,80.75877 L 81.199815,80.75877 C 82.322465,80.75877 83.226249,79.842847 83.226249,78.705144 L 76.566459,55.81593 C 76.566459,54.678228 75.662675,53.762319 74.540033,53.762319 L 13.327001,53.762319 C 12.204359,53.762319 11.300569,54.678228 11.300569,55.81593 L 4.6407848,78.705144 C 4.6407848,79.842847 5.5445737,80.75877 6.6672171,80.75877 z" id="path3579" sodipodi:nodetypes="ccccccccc" /> <path sodipodi:nodetypes="ccccccccc" id="path3569" d="M 6.6672171,80.75877 L 81.199815,80.75877 C 82.322465,80.75877 83.226249,79.842847 83.226249,78.705144 L 76.566459,55.81593 C 76.566459,54.678228 75.662675,53.762319 74.540033,53.762319 L 13.327001,53.762319 C 12.204359,53.762319 11.300569,54.678228 11.300569,55.81593 L 4.6407848,78.705144 C 4.6407848,79.842847 5.5445737,80.75877 6.6672171,80.75877 z" style="opacity:0.32994923;fill:url(#linearGradient3577);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" /> <path id="path8980" d="M 4.6407848,78.807292 C 4.6432465,78.900482 4.6903474,78.988605 4.7656558,79.071477 L 83.101387,79.071477 C 83.176697,78.988605 83.22379,78.900482 83.226249,78.807292 L 4.6407848,78.807292 z" style="fill:url(#radialGradient8982);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" /> <g style="display:inline" id="g6571" transform="matrix(0.759847,0,0,0.7911826,-20.764844,-80.867991)"> <g id="g3050" transform="translate(-0.4265204,0)"> <path transform="matrix(0.8530407,0,0,0.8530407,30.561565,101.92012)" sodipodi:nodetypes="ccccc" id="path6891" d="M 23.731611,83.017484 L 17.982156,104.47474 L 111.36931,104.47474 L 105.48638,83.023148 L 23.731611,83.017484 z" style="fill:url(#linearGradient3384);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" /> <path sodipodi:nodetypes="ccccc" id="path6559" d="M 116.333,172.92652 L 116.40032,174.48146 L 120.64444,174.48146 L 120.19129,172.92652 L 116.333,172.92652 z" style="fill:url(#linearGradient3386);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3388);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 116.5751,172.92652 L 116.61905,174.19704 C 117.87288,174.27425 119.1325,174.28421 120.33052,174.19704 L 119.94917,172.92652 L 116.5751,172.92652 z" id="path6561" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3390);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 112.28084,172.92652 L 112.34816,174.48146 L 116.59228,174.48146 L 116.13913,172.92652 L 112.28084,172.92652 z" id="path6547" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6549" d="M 112.52294,172.92652 L 112.56689,174.19704 C 113.82072,174.27425 115.08034,174.28421 116.27836,174.19704 L 115.89701,172.92652 L 112.52294,172.92652 z" style="fill:url(#linearGradient3392);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6535" d="M 109.81402,172.92652 L 109.62111,174.48146 L 113.86522,174.48146 L 113.67231,172.92652 L 109.81402,172.92652 z" style="fill:url(#linearGradient3394);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3396);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 110.05614,172.92652 L 109.88743,174.19704 C 111.12835,174.27425 112.38632,174.28421 113.59891,174.19704 L 113.43019,172.92652 L 110.05614,172.92652 z" id="path6537" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3398);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 105.76186,172.92652 L 105.56895,174.48146 L 109.81306,174.48146 L 109.62015,172.92652 L 105.76186,172.92652 z" id="path6523" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6525" d="M 106.00398,172.92652 L 105.83527,174.19704 C 107.07619,174.27425 108.33416,174.28421 109.54675,174.19704 L 109.37803,172.92652 L 106.00398,172.92652 z" style="fill:url(#linearGradient3400);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6511" d="M 101.7097,172.92652 L 101.51679,174.48146 L 105.7609,174.48146 L 105.56799,172.92652 L 101.7097,172.92652 z" style="fill:url(#linearGradient3402);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3404);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 101.95182,172.92652 L 101.78311,174.19704 C 103.02403,174.27425 104.282,174.28421 105.49459,174.19704 L 105.32587,172.92652 L 101.95182,172.92652 z" id="path6513" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3407);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 50.603074,172.8447 L 50.273785,174.39964 L 54.463279,174.39964 L 54.411707,172.8447 L 50.603074,172.8447 z" id="path6339" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6341" d="M 50.842073,172.8447 L 50.562083,174.11522 C 51.78013,174.19244 53.021009,174.2024 54.225779,174.11522 L 54.172707,172.8447 L 50.842073,172.8447 z" style="fill:url(#linearGradient3409);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6347" d="M 54.828912,172.92652 L 54.37419,174.48146 L 58.618316,174.48146 L 58.687209,172.92652 L 54.828912,172.92652 z" style="fill:url(#linearGradient3411);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3413);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 55.071028,172.92652 L 54.688406,174.19704 C 55.916322,174.27425 57.172605,174.28421 58.399877,174.19704 L 58.445094,172.92652 L 55.071028,172.92652 z" id="path6349" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3415);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 57.50729,172.92652 L 57.314376,174.48146 L 61.558501,174.48146 L 61.365587,172.92652 L 57.50729,172.92652 z" id="path6355" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6357" d="M 57.749406,172.92652 L 57.580704,174.19704 C 58.82162,174.27425 60.079581,174.28421 61.292174,174.19704 L 61.123472,172.92652 L 57.749406,172.92652 z" style="fill:url(#linearGradient3417);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6363" d="M 61.499716,172.92652 L 61.306802,174.48146 L 65.550928,174.48146 L 65.358014,172.92652 L 61.499716,172.92652 z" style="fill:url(#linearGradient3419);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3421);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 61.741833,172.92652 L 61.57313,174.19704 C 62.814046,174.27425 64.072007,174.28421 65.284601,174.19704 L 65.115898,172.92652 L 61.741833,172.92652 z" id="path6365" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3423);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 65.492143,172.92652 L 65.299228,174.48146 L 69.543355,174.48146 L 69.35044,172.92652 L 65.492143,172.92652 z" id="path6371" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6373" d="M 65.734259,172.92652 L 65.565556,174.19704 C 66.806471,174.27425 68.064433,174.28421 69.277026,174.19704 L 69.108324,172.92652 L 65.734259,172.92652 z" style="fill:url(#linearGradient3425);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6379" d="M 69.40924,172.92652 L 69.216325,174.48146 L 73.460452,174.48146 L 73.267537,172.92652 L 69.40924,172.92652 z" style="fill:url(#linearGradient3427);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3429);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 69.651355,172.92652 L 69.482654,174.19704 C 70.72357,174.27425 71.98153,174.28421 73.194124,174.19704 L 73.025421,172.92652 L 69.651355,172.92652 z" id="path6381" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3431);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 73.476995,172.92652 L 73.284082,174.48146 L 77.528206,174.48146 L 77.335293,172.92652 L 73.476995,172.92652 z" id="path6387" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6389" d="M 73.719112,172.92652 L 73.550409,174.19704 C 74.791325,174.27425 76.049286,174.28421 77.261879,174.19704 L 77.093176,172.92652 L 73.719112,172.92652 z" style="fill:url(#linearGradient3433);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6395" d="M 77.544751,172.92652 L 77.351837,174.48146 L 81.595963,174.48146 L 81.403048,172.92652 L 77.544751,172.92652 z" style="fill:url(#linearGradient3435);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3437);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 77.786867,172.92652 L 77.618165,174.19704 C 78.85908,174.27425 80.11704,174.28421 81.329634,174.19704 L 81.160932,172.92652 L 77.786867,172.92652 z" id="path6397" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3439);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 81.461848,172.92652 L 81.268934,174.48146 L 85.51306,174.48146 L 85.320146,172.92652 L 81.461848,172.92652 z" id="path6403" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6405" d="M 81.703964,172.92652 L 81.535262,174.19704 C 82.776177,174.27425 84.034138,174.28421 85.246732,174.19704 L 85.078029,172.92652 L 81.703964,172.92652 z" style="fill:url(#linearGradient3441);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6411" d="M 85.529604,172.92652 L 85.336689,174.48146 L 89.580814,174.48146 L 89.3879,172.92652 L 85.529604,172.92652 z" style="fill:url(#linearGradient3443);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3445);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 85.771719,172.92652 L 85.603016,174.19704 C 86.843933,174.27425 88.101894,174.28421 89.314487,174.19704 L 89.145785,172.92652 L 85.771719,172.92652 z" id="path6413" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3447);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 89.597358,172.92652 L 89.404445,174.48146 L 93.648576,174.48146 L 93.455661,172.92652 L 89.597358,172.92652 z" id="path6419" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6421" d="M 89.839475,172.92652 L 89.670773,174.19704 C 90.911688,174.27425 92.16965,174.28421 93.382248,174.19704 L 93.213545,172.92652 L 89.839475,172.92652 z" style="fill:url(#linearGradient3449);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6427" d="M 93.665119,172.92652 L 93.472203,174.48146 L 97.71633,174.48146 L 97.523416,172.92652 L 93.665119,172.92652 z" style="fill:url(#linearGradient3451);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3453);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 93.907233,172.92652 L 93.738532,174.19704 C 94.979446,174.27425 96.237407,174.28421 97.450003,174.19704 L 97.281301,172.92652 L 93.907233,172.92652 z" id="path6429" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3455);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 97.657542,172.92652 L 97.464627,174.48146 L 101.70874,174.48146 L 101.51583,172.92652 L 97.657542,172.92652 z" id="path6435" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6437" d="M 97.899658,172.92652 L 97.730956,174.19704 C 98.971871,174.27425 100.22984,174.28421 101.44243,174.19704 L 101.27371,172.92652 L 97.899658,172.92652 z" style="fill:url(#linearGradient3457);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6327" d="M 50.141373,174.45807 L 49.614983,177.81784 L 54.594901,177.81784 L 54.668573,174.45807 L 50.141373,174.45807 z" style="fill:url(#linearGradient3460);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3462);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 50.425464,174.45807 L 49.982362,177.2033 C 51.423514,177.37013 52.897642,177.39165 54.33728,177.2033 L 54.384482,174.45807 L 50.425464,174.45807 z" id="path6329" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="72.291672" y="175.88593" id="text6331" transform="matrix(1,0,-0.1234387,1,0,0)"><tspan sodipodi:role="line" id="tspan6333" x="72.291672" y="175.88593" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">¡</tspan></text> <path style="fill:url(#linearGradient3464);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 54.903651,174.63485 L 54.418916,177.99462 L 59.398834,177.99462 L 59.430851,174.63485 L 54.903651,174.63485 z" id="path6179" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6181" d="M 55.187742,174.63485 L 54.778676,177.38008 C 56.221896,177.54691 57.696291,177.56843 59.133594,177.38008 L 59.14676,174.63485 L 55.187742,174.63485 z" style="fill:url(#linearGradient3466);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-0.2003416,1,0,0)" id="text6183" y="176.0627" x="91.128311" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="176.0627" x="91.128311" id="tspan6185" sodipodi:role="line">!</tspan></text> <path sodipodi:nodetypes="ccccc" id="path6187" d="M 59.225697,174.63485 L 58.999338,177.99462 L 63.979256,177.99462 L 63.752898,174.63485 L 59.225697,174.63485 z" style="fill:url(#linearGradient3468);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3470);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 59.509789,174.63485 L 59.311838,177.38008 C 60.767889,177.54691 62.243939,177.56843 63.666756,177.38008 L 63.468807,174.63485 L 59.509789,174.63485 z" id="path6189" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="79.828888" y="176.05872" id="text6191" transform="matrix(1,0,-0.1110404,1,0,0)"><tspan sodipodi:role="line" id="tspan6193" x="79.828888" y="176.05872" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">"</tspan></text> <path style="fill:url(#linearGradient3472);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 63.91028,174.63485 L 63.683921,177.99462 L 68.663839,177.99462 L 68.43748,174.63485 L 63.91028,174.63485 z" id="path6195" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6197" d="M 64.194371,174.63485 L 63.996421,177.38008 C 65.452471,177.54691 66.928521,177.56843 68.351339,177.38008 L 68.153389,174.63485 L 64.194371,174.63485 z" style="fill:url(#linearGradient3474);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text6199" y="176.05872" x="70.456467" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="176.05872" x="70.456467" id="tspan6201" sodipodi:role="line">£</tspan></text> <path sodipodi:nodetypes="ccccc" id="path6203" d="M 68.594862,174.63485 L 68.368503,177.99462 L 73.348421,177.99462 L 73.122062,174.63485 L 68.594862,174.63485 z" style="fill:url(#linearGradient3476);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3478);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 68.878953,174.63485 L 68.681003,177.38008 C 70.137053,177.54691 71.613103,177.56843 73.035921,177.38008 L 72.837971,174.63485 L 68.878953,174.63485 z" id="path6205" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="75.213562" y="176.0685" id="text6207" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan6209" x="75.213562" y="176.0685" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">$</tspan></text> <path style="fill:url(#linearGradient3480);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 73.191056,174.63485 L 72.964697,177.99462 L 77.944615,177.99462 L 77.718256,174.63485 L 73.191056,174.63485 z" id="path6211" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6213" d="M 73.475147,174.63485 L 73.277197,177.38008 C 74.733247,177.54691 76.209297,177.56843 77.632115,177.38008 L 77.434165,174.63485 L 73.475147,174.63485 z" style="fill:url(#linearGradient3482);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text6215" y="176.05872" x="79.704262" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="176.05872" x="79.704262" id="tspan6217" sodipodi:role="line">%</tspan></text> <path sodipodi:nodetypes="ccccc" id="path6219" d="M 77.964027,174.63485 L 77.737668,177.99462 L 82.717586,177.99462 L 82.491227,174.63485 L 77.964027,174.63485 z" style="fill:url(#linearGradient3484);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3486);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 78.248118,174.63485 L 78.050168,177.38008 C 79.506218,177.54691 80.982268,177.56843 82.405086,177.38008 L 82.207136,174.63485 L 78.248118,174.63485 z" id="path6221" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="84.500786" y="176.05872" id="text6223" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan6225" x="84.500786" y="176.05872" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">^</tspan></text> <path style="fill:url(#linearGradient3488);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 82.736998,174.63485 L 82.510639,177.99462 L 87.490557,177.99462 L 87.264198,174.63485 L 82.736998,174.63485 z" id="path6227" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6229" d="M 83.021089,174.63485 L 82.823139,177.38008 C 84.279189,177.54691 85.755239,177.56843 87.178057,177.38008 L 86.980107,174.63485 L 83.021089,174.63485 z" style="fill:url(#linearGradient3490);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text6231" y="176.09242" x="89.292976" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="176.09242" x="89.292976" id="tspan6233" sodipodi:role="line">&</tspan></text> <path sodipodi:nodetypes="ccccc" id="path6235" d="M 87.333192,174.63485 L 87.106833,177.99462 L 92.086751,177.99462 L 91.860392,174.63485 L 87.333192,174.63485 z" style="fill:url(#linearGradient3493);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3495);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 87.617283,174.63485 L 87.419333,177.38008 C 88.875383,177.54691 90.351433,177.56843 91.774251,177.38008 L 91.576301,174.63485 L 87.617283,174.63485 z" id="path6237" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="93.724564" y="176.05872" id="text6239" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan6241" x="93.724564" y="176.05872" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">*</tspan></text> <path style="fill:url(#linearGradient3497);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 92.106163,174.63485 L 91.879804,177.99462 L 96.859722,177.99462 L 96.633363,174.63485 L 92.106163,174.63485 z" id="path6243" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6245" d="M 92.390254,174.63485 L 92.192304,177.38008 C 93.648354,177.54691 95.124404,177.56843 96.547222,177.38008 L 96.349272,174.63485 L 92.390254,174.63485 z" style="fill:url(#linearGradient3499);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text6247" y="176.06161" x="98.681007" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="176.06161" x="98.681007" id="tspan6249" sodipodi:role="line">(</tspan></text> <path sodipodi:nodetypes="ccccc" id="path6251" d="M 96.879134,174.63485 L 96.652775,177.99462 L 101.6327,177.99462 L 101.40634,174.63485 L 96.879134,174.63485 z" style="fill:url(#linearGradient3501);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3503);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 97.163225,174.63485 L 96.965275,177.38008 C 98.421325,177.54691 99.897377,177.56843 101.3202,177.38008 L 101.12225,174.63485 L 97.163225,174.63485 z" id="path6253" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="103.50763" y="175.98184" id="text6255" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan6257" x="103.50763" y="175.98184" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">)</tspan></text> <path style="fill:url(#linearGradient3505);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 101.65211,174.63485 L 101.42575,177.99462 L 106.40567,177.99462 L 106.17931,174.63485 L 101.65211,174.63485 z" id="path6259" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6261" d="M 101.9362,174.63485 L 101.73825,177.38008 C 103.1943,177.54691 104.67035,177.56843 106.09317,177.38008 L 105.89522,174.63485 L 101.9362,174.63485 z" style="fill:url(#linearGradient3507);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text6263" y="176.13123" x="108.08408" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="176.13123" x="108.08408" id="tspan6265" sodipodi:role="line">-</tspan></text> <path sodipodi:nodetypes="ccccc" id="path6267" d="M 106.33669,174.63485 L 106.11033,177.99462 L 111.09025,177.99462 L 110.86389,174.63485 L 106.33669,174.63485 z" style="fill:url(#linearGradient3509);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3511);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 106.62078,174.63485 L 106.42283,177.38008 C 107.87888,177.54691 109.35493,177.56843 110.77775,177.38008 L 110.5798,174.63485 L 106.62078,174.63485 z" id="path6269" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="112.76941" y="176.13123" id="text6271" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan6273" x="112.76941" y="176.13123" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">+</tspan></text> <path sodipodi:nodetypes="ccccc" id="path6059" d="M 116.19091,174.63485 L 116.51961,177.99462 L 121.49953,177.99462 L 120.71811,174.63485 L 116.19091,174.63485 z" style="fill:url(#linearGradient3513);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3515);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 116.475,174.63485 L 116.73058,177.38008 C 118.2142,177.54691 119.6938,177.56843 121.0855,177.38008 L 120.43402,174.63485 L 116.475,174.63485 z" id="path6061" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3517);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 49.511841,177.72844 L 48.880991,181.08821 L 56.159007,181.08821 L 56.128221,177.72844 L 49.511841,177.72844 z" id="path5953" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5955" d="M 49.927032,177.72844 L 49.392582,180.47367 C 51.50566,180.6405 53.660946,180.66202 55.757176,180.47367 L 55.713028,177.72844 L 49.927032,177.72844 z" style="fill:url(#linearGradient3519);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1.2089139,0,-0.1151382,0.8271888,0,0)" id="text5957" y="216.26392" x="62.175896" style="font-size:1.30712211px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="216.26392" x="62.175896" id="tspan5959" sodipodi:role="line">ctrl</tspan></text> <path sodipodi:nodetypes="ccccc" id="path4783" d="M 56.07316,177.81683 L 55.588425,181.1766 L 60.568343,181.1766 L 60.60036,177.81683 L 56.07316,177.81683 z" style="fill:url(#linearGradient3521);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3523);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 56.357251,177.81683 L 55.948185,180.56206 C 57.391405,180.72889 58.8658,180.75041 60.303103,180.56206 L 60.316269,177.81683 L 56.357251,177.81683 z" id="path4785" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="92.651154" y="179.24469" id="text4787" transform="matrix(1,0,-0.2003416,1,0,0)"><tspan sodipodi:role="line" id="tspan4789" x="92.651154" y="179.24469" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">Q</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5941" d="M 48.94229,180.82204 L 48.274856,183.91664 L 56.878697,183.91664 L 56.763966,180.82204 L 48.94229,180.82204 z" style="fill:url(#linearGradient3525);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3527);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 49.195131,180.82204 L 48.616788,183.3506 C 51.196223,183.50426 53.82323,183.52409 56.372697,183.3506 L 56.245959,180.82204 L 49.195131,180.82204 z" id="path5943" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38482523px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="56.012951" y="252.92647" id="text5945" transform="matrix(1.3905241,0,-0.1116902,0.7191533,0,0)"><tspan sodipodi:role="line" id="tspan5947" x="56.012951" y="252.92647" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">ctrl</tspan></text> <path style="fill:url(#linearGradient3529);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 48.296263,183.82724 L 47.717643,187.18701 L 53.84661,187.18701 L 53.868053,183.82724 L 48.296263,183.82724 z" id="path5929" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5931" d="M 48.645904,183.82724 L 48.157128,186.57247 C 49.934243,186.7393 51.74895,186.76082 53.516884,186.57247 L 53.518411,183.82724 L 48.645904,183.82724 z" style="fill:url(#linearGradient3531);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3533);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 60.63991,177.81683 L 60.413551,181.1766 L 65.393469,181.1766 L 65.167111,177.81683 L 60.63991,177.81683 z" id="path4867" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path4869" d="M 60.924002,177.81683 L 60.726051,180.56206 C 62.182102,180.72889 63.658152,180.75041 65.080969,180.56206 L 64.88302,177.81683 L 60.924002,177.81683 z" style="fill:url(#linearGradient3535);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text4871" y="179.24071" x="67.382484" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="179.24071" x="67.382484" id="tspan4873" sodipodi:role="line">W</tspan></text> <path sodipodi:nodetypes="ccccc" id="path4881" d="M 65.324493,177.81683 L 65.098134,181.1766 L 70.078052,181.1766 L 69.851693,177.81683 L 65.324493,177.81683 z" style="fill:url(#linearGradient3537);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3539);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 65.608584,177.81683 L 65.410634,180.56206 C 66.866684,180.72889 68.342734,180.75041 69.765552,180.56206 L 69.567602,177.81683 L 65.608584,177.81683 z" id="path4883" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="71.979309" y="179.24071" id="text4885" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan4887" x="71.979309" y="179.24071" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">E</tspan></text> <path style="fill:url(#linearGradient3541);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 70.009075,177.81683 L 69.782716,181.1766 L 74.762634,181.1766 L 74.536275,177.81683 L 70.009075,177.81683 z" id="path4895" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path4897" d="M 70.293166,177.81683 L 70.095216,180.56206 C 71.551266,180.72889 73.027316,180.75041 74.450134,180.56206 L 74.252184,177.81683 L 70.293166,177.81683 z" style="fill:url(#linearGradient3543);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text4899" y="179.25049" x="76.736404" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="179.25049" x="76.736404" id="tspan4901" sodipodi:role="line">R</tspan></text> <path sodipodi:nodetypes="ccccc" id="path4909" d="M 74.605269,177.81683 L 74.37891,181.1766 L 79.358828,181.1766 L 79.132469,177.81683 L 74.605269,177.81683 z" style="fill:url(#linearGradient3545);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3547);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 74.88936,177.81683 L 74.69141,180.56206 C 76.14746,180.72889 77.62351,180.75041 79.046328,180.56206 L 78.848378,177.81683 L 74.88936,177.81683 z" id="path4911" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="81.227104" y="179.24071" id="text4913" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan4915" x="81.227104" y="179.24071" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">T</tspan></text> <path style="fill:url(#linearGradient3549);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 79.37824,177.81683 L 79.151881,181.1766 L 84.131799,181.1766 L 83.90544,177.81683 L 79.37824,177.81683 z" id="path4923" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path4925" d="M 79.662331,177.81683 L 79.464381,180.56206 C 80.920431,180.72889 82.396481,180.75041 83.819299,180.56206 L 83.621349,177.81683 L 79.662331,177.81683 z" style="fill:url(#linearGradient3551);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text4927" y="179.24071" x="86.023628" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="179.24071" x="86.023628" id="tspan4929" sodipodi:role="line">Y</tspan></text> <path sodipodi:nodetypes="ccccc" id="path4937" d="M 84.151211,177.81683 L 83.924852,181.1766 L 88.90477,181.1766 L 88.678411,177.81683 L 84.151211,177.81683 z" style="fill:url(#linearGradient3553);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3555);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 84.435302,177.81683 L 84.237352,180.56206 C 85.693402,180.72889 87.169452,180.75041 88.59227,180.56206 L 88.39432,177.81683 L 84.435302,177.81683 z" id="path4939" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="90.815819" y="179.27441" id="text4941" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan4943" x="90.815819" y="179.27441" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">U</tspan></text> <path style="fill:url(#linearGradient3557);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 88.747405,177.81683 L 88.521046,181.1766 L 93.500964,181.1766 L 93.274605,177.81683 L 88.747405,177.81683 z" id="path4951" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path4953" d="M 89.031496,177.81683 L 88.833546,180.56206 C 90.289596,180.72889 91.765646,180.75041 93.188464,180.56206 L 92.990514,177.81683 L 89.031496,177.81683 z" style="fill:url(#linearGradient3559);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text4955" y="179.24071" x="95.247406" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="179.24071" x="95.247406" id="tspan4957" sodipodi:role="line">I</tspan></text> <path sodipodi:nodetypes="ccccc" id="path4965" d="M 93.520376,177.81683 L 93.294017,181.1766 L 98.273935,181.1766 L 98.047576,177.81683 L 93.520376,177.81683 z" style="fill:url(#linearGradient3561);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3563);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 93.804467,177.81683 L 93.606517,180.56206 C 95.062567,180.72889 96.538617,180.75041 97.961435,180.56206 L 97.763485,177.81683 L 93.804467,177.81683 z" id="path4967" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="100.20385" y="179.24361" id="text4969" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan4971" x="100.20385" y="179.24361" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">O</tspan></text> <path style="fill:url(#linearGradient3565);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 98.293347,177.81683 L 98.066988,181.1766 L 103.04691,181.1766 L 102.82055,177.81683 L 98.293347,177.81683 z" id="path4979" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path4981" d="M 98.577438,177.81683 L 98.379488,180.56206 C 99.835538,180.72889 101.31159,180.75041 102.73441,180.56206 L 102.53646,177.81683 L 98.577438,177.81683 z" style="fill:url(#linearGradient3567);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text4983" y="179.16383" x="105.03047" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="179.16383" x="105.03047" id="tspan4985" sodipodi:role="line">P</tspan></text> <path sodipodi:nodetypes="ccccc" id="path4993" d="M 103.06632,177.81683 L 102.83996,181.1766 L 107.81988,181.1766 L 107.59352,177.81683 L 103.06632,177.81683 z" style="fill:url(#linearGradient3569);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3572);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 103.35041,177.81683 L 103.15246,180.56206 C 104.60851,180.72889 106.08456,180.75041 107.50738,180.56206 L 107.30943,177.81683 L 103.35041,177.81683 z" id="path4995" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="109.60692" y="179.31322" id="text4997" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan4999" x="109.60692" y="179.31322" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">{</tspan></text> <path style="fill:url(#linearGradient3574);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 107.7509,177.81683 L 107.52454,181.1766 L 112.50446,181.1766 L 112.2781,177.81683 L 107.7509,177.81683 z" id="path5007" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5009" d="M 108.03499,177.81683 L 107.83704,180.56206 C 109.29309,180.72889 110.76914,180.75041 112.19196,180.56206 L 111.99401,177.81683 L 108.03499,177.81683 z" style="fill:url(#linearGradient3576);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5011" y="179.31322" x="114.29225" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="179.31322" x="114.29225" id="tspan5013" sodipodi:role="line">}</tspan></text> <path style="fill:url(#linearGradient3578);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 56.750823,180.91042 L 56.524464,184.27019 L 61.504382,184.27019 L 61.278023,180.91042 L 56.750823,180.91042 z" id="path5021" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5023" d="M 57.034914,180.91042 L 56.836964,183.65565 C 58.293014,183.82248 59.769064,183.844 61.191882,183.65565 L 60.993932,180.91042 L 57.034914,180.91042 z" style="fill:url(#linearGradient3580);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-0.2003416,1,0,0)" id="text5025" y="182.3343" x="93.707634" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="182.3343" x="93.707634" id="tspan5027" sodipodi:role="line">A</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5031" d="M 61.612182,180.91042 L 61.385823,184.27019 L 66.365741,184.27019 L 66.139382,180.91042 L 61.612182,180.91042 z" style="fill:url(#linearGradient3582);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3584);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 61.896273,180.91042 L 61.698323,183.65565 C 63.154373,183.82248 64.630423,183.844 66.053241,183.65565 L 65.855291,180.91042 L 61.896273,180.91042 z" id="path5033" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="68.362099" y="182.34734" id="text5035" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5037" x="68.362099" y="182.34734" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">S</tspan></text> <path style="fill:url(#linearGradient3586);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 66.296765,180.91042 L 66.070406,184.27019 L 71.050324,184.27019 L 70.823965,180.91042 L 66.296765,180.91042 z" id="path5041" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5043" d="M 66.580856,180.91042 L 66.382906,183.65565 C 67.838956,183.82248 69.315006,183.844 70.737824,183.65565 L 70.539874,180.91042 L 66.580856,180.91042 z" style="fill:url(#linearGradient3588);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5045" y="182.33359" x="73.107964" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="182.33359" x="73.107964" id="tspan5047" sodipodi:role="line">D</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5051" d="M 70.981347,180.91042 L 70.754988,184.27019 L 75.734906,184.27019 L 75.508547,180.91042 L 70.981347,180.91042 z" style="fill:url(#linearGradient3590);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3592);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 71.265438,180.91042 L 71.067488,183.65565 C 72.523538,183.82248 73.999588,183.844 75.422406,183.65565 L 75.224456,180.91042 L 71.265438,180.91042 z" id="path5053" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="77.726181" y="182.3343" id="text5055" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5057" x="77.726181" y="182.3343" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">F</tspan></text> <path style="fill:url(#linearGradient3594);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 75.577542,180.91042 L 75.351183,184.27019 L 80.331101,184.27019 L 80.104742,180.91042 L 75.577542,180.91042 z" id="path5061" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5063" d="M 75.861633,180.91042 L 75.663683,183.65565 C 77.119733,183.82248 78.595783,183.844 80.018601,183.65565 L 79.820651,180.91042 L 75.861633,180.91042 z" style="fill:url(#linearGradient3596);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5065" y="182.33177" x="82.332527" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="182.33177" x="82.332527" id="tspan5067" sodipodi:role="line">G</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5071" d="M 80.350512,180.91042 L 80.124153,184.27019 L 85.104071,184.27019 L 84.877712,180.91042 L 80.350512,180.91042 z" style="fill:url(#linearGradient3598);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3600);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 80.634603,180.91042 L 80.436653,183.65565 C 81.892703,183.82248 83.368753,183.844 84.791571,183.65565 L 84.593621,180.91042 L 80.634603,180.91042 z" id="path5073" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="87.118912" y="182.3343" id="text5075" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5077" x="87.118912" y="182.3343" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">H</tspan></text> <path style="fill:url(#linearGradient3602);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 85.123483,180.91042 L 84.897124,184.27019 L 89.877042,184.27019 L 89.650683,180.91042 L 85.123483,180.91042 z" id="path5081" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5083" d="M 85.407574,180.91042 L 85.209624,183.65565 C 86.665674,183.82248 88.141724,183.844 89.564542,183.65565 L 89.366592,180.91042 L 85.407574,180.91042 z" style="fill:url(#linearGradient3604);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5085" y="182.41335" x="91.866508" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="182.41335" x="91.866508" id="tspan5087" sodipodi:role="line">J</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5091" d="M 89.719677,180.91042 L 89.493318,184.27019 L 94.473236,184.27019 L 94.246877,180.91042 L 89.719677,180.91042 z" style="fill:url(#linearGradient3606);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3608);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 90.003768,180.91042 L 89.805818,183.65565 C 91.261868,183.82248 92.737918,183.844 94.160736,183.65565 L 93.962786,180.91042 L 90.003768,180.91042 z" id="path5093" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="96.512001" y="182.3343" id="text5095" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5097" x="96.512001" y="182.3343" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">K</tspan></text> <path style="fill:url(#linearGradient3610);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 94.492648,180.91042 L 94.266289,184.27019 L 99.246207,184.27019 L 99.019848,180.91042 L 94.492648,180.91042 z" id="path5101" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5103" d="M 94.776739,180.91042 L 94.578789,183.65565 C 96.034839,183.82248 97.510889,183.844 98.933707,183.65565 L 98.735757,180.91042 L 94.776739,180.91042 z" style="fill:url(#linearGradient3613);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5105" y="182.3343" x="101.2371" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="182.3343" x="101.2371" id="tspan5107" sodipodi:role="line">L</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5111" d="M 99.265619,180.91042 L 99.03926,184.27019 L 104.01918,184.27019 L 103.79282,180.91042 L 99.265619,180.91042 z" style="fill:url(#linearGradient3615);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3617);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 99.54971,180.91042 L 99.35176,183.65565 C 100.80781,183.82248 102.28386,183.844 103.70668,183.65565 L 103.50873,180.91042 L 99.54971,180.91042 z" id="path5113" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="105.90748" y="182.4101" id="text5115" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5117" x="105.90748" y="182.4101" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">:</tspan></text> <path style="fill:url(#linearGradient3619);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 104.03859,180.91042 L 103.81223,184.27019 L 108.79215,184.27019 L 108.56579,180.91042 L 104.03859,180.91042 z" id="path5121" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3621);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 111.62081,177.83395 L 111.92838,181.20895 L 112.42838,181.20895 L 112.68977,184.1152 L 118.37727,184.1152 L 117.56969,180.7402 L 117.50719,180.7402 L 116.80831,177.83395 L 111.62081,177.83395 z" id="path5973" /> <path style="fill:url(#linearGradient3623);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 106.00257,183.91563 L 105.39694,187.2754 L 118.72061,187.2754 L 118.11499,183.91563 L 106.00257,183.91563 z" id="path5299" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5123" d="M 104.32268,180.91042 L 104.12473,183.65565 C 105.58078,183.82248 107.05683,183.844 108.47965,183.65565 L 108.2817,180.91042 L 104.32268,180.91042 z" style="fill:url(#linearGradient3625);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5125" y="182.36366" x="110.89001" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="182.36366" x="110.89001" id="tspan5127" sodipodi:role="line">@</tspan></text> <path style="fill:url(#linearGradient3627);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 111.93331,177.83395 L 112.16888,180.58395 C 112.32757,180.59958 112.4842,180.60217 112.64279,180.6152 L 112.9251,183.45895 C 114.62305,183.65113 116.33277,183.67592 117.9251,183.45895 L 117.15367,180.3027 L 117.09117,180.3027 L 116.46456,177.83395 L 111.93331,177.83395 z" id="path5975" /> <path sodipodi:nodetypes="ccccc" id="path5131" d="M 108.72317,180.91042 L 108.49681,184.27019 L 113.47673,184.27019 L 113.25037,180.91042 L 108.72317,180.91042 z" style="fill:url(#linearGradient3629);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path5301" d="M 106.78826,183.91563 L 106.24872,186.66086 C 110.21744,186.82769 114.24068,186.84921 118.11883,186.66086 L 117.57929,183.91563 L 106.78826,183.91563 z" style="fill:url(#linearGradient3631);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3633);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 109.00726,180.91042 L 108.80931,183.65565 C 110.26536,183.82248 111.74141,183.844 113.16423,183.65565 L 112.96628,180.91042 L 109.00726,180.91042 z" id="path5133" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="115.4397" y="182.43402" id="text5135" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5137" x="115.4397" y="182.43402" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">~</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5189" d="M 54.101544,183.91563 L 53.616809,187.2754 L 58.596727,187.2754 L 58.628744,183.91563 L 54.101544,183.91563 z" style="fill:url(#linearGradient3635);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3637);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 54.385635,183.91563 L 53.976568,186.66086 C 55.419789,186.82769 56.894184,186.84921 58.331486,186.66086 L 58.344653,183.91563 L 54.385635,183.91563 z" id="path5191" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="91.172546" y="185.41202" id="text5193" transform="matrix(1,0,-0.2003416,1,0,0)"><tspan sodipodi:role="line" id="tspan5195" x="91.172546" y="185.41202" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">|</tspan></text> <path style="fill:url(#linearGradient3639);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 59.137309,183.91563 L 58.91095,187.2754 L 63.890868,187.2754 L 63.664509,183.91563 L 59.137309,183.91563 z" id="path5199" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5201" d="M 59.4214,183.91563 L 59.22345,186.66086 C 60.6795,186.82769 62.15555,186.84921 63.578368,186.66086 L 63.380418,183.91563 L 59.4214,183.91563 z" style="fill:url(#linearGradient3641);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-0.1110404,1,0,0)" id="text5203" y="185.33951" x="79.93512" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="185.33951" x="79.93512" id="tspan5205" sodipodi:role="line">Z</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5209" d="M 63.821891,183.91563 L 63.595532,187.2754 L 68.57545,187.2754 L 68.349091,183.91563 L 63.821891,183.91563 z" style="fill:url(#linearGradient3643);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3645);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 64.105982,183.91563 L 63.908032,186.66086 C 65.364082,186.82769 66.840132,186.84921 68.26295,186.66086 L 68.065,183.91563 L 64.105982,183.91563 z" id="path5211" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="70.674759" y="185.33951" id="text5213" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5215" x="70.674759" y="185.33951" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">X</tspan></text> <path style="fill:url(#linearGradient3647);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 68.506473,183.91563 L 68.280114,187.2754 L 73.260032,187.2754 L 73.033674,183.91563 L 68.506473,183.91563 z" id="path5219" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5221" d="M 68.790565,183.91563 L 68.592614,186.66086 C 70.048665,186.82769 71.524715,186.84921 72.947532,186.66086 L 72.749583,183.91563 L 68.790565,183.91563 z" style="fill:url(#linearGradient3649);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5223" y="185.34204" x="75.360062" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="185.34204" x="75.360062" id="tspan5225" sodipodi:role="line">C</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5229" d="M 73.102668,183.91563 L 72.876309,187.2754 L 77.856227,187.2754 L 77.629868,183.91563 L 73.102668,183.91563 z" style="fill:url(#linearGradient3651);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3653);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 73.386759,183.91563 L 73.188809,186.66086 C 74.644859,186.82769 76.120909,186.84921 77.543727,186.66086 L 77.345777,183.91563 L 73.386759,183.91563 z" id="path5231" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="79.954086" y="185.33951" id="text5233" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5235" x="79.954086" y="185.33951" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">V</tspan></text> <path style="fill:url(#linearGradient3655);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 77.875638,183.91563 L 77.649279,187.2754 L 82.629197,187.2754 L 82.402838,183.91563 L 77.875638,183.91563 z" id="path5239" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5241" d="M 78.159729,183.91563 L 77.961779,186.66086 C 79.417829,186.82769 80.893879,186.84921 82.316697,186.66086 L 82.118747,183.91563 L 78.159729,183.91563 z" style="fill:url(#linearGradient3657);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5243" y="185.33951" x="84.800293" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="185.33951" x="84.800293" id="tspan5245" sodipodi:role="line">B</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5249" d="M 82.648609,183.91563 L 82.42225,187.2754 L 87.402168,187.2754 L 87.175809,183.91563 L 82.648609,183.91563 z" style="fill:url(#linearGradient3659);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3661);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 82.9327,183.91563 L 82.73475,186.66086 C 84.1908,186.82769 85.66685,186.84921 87.089668,186.66086 L 86.891718,183.91563 L 82.9327,183.91563 z" id="path5251" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="89.521049" y="185.33951" id="text5253" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5255" x="89.521049" y="185.33951" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">N</tspan></text> <path style="fill:url(#linearGradient3663);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 87.244803,183.91563 L 87.018444,187.2754 L 91.998362,187.2754 L 91.772003,183.91563 L 87.244803,183.91563 z" id="path5259" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5261" d="M 87.528894,183.91563 L 87.330944,186.66086 C 88.786994,186.82769 90.263044,186.84921 91.685862,186.66086 L 91.487912,183.91563 L 87.528894,183.91563 z" style="fill:url(#linearGradient3665);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5263" y="185.33951" x="94.158218" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="185.33951" x="94.158218" id="tspan5265" sodipodi:role="line">M</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5269" d="M 92.017774,183.91563 L 91.791415,187.2754 L 96.771333,187.2754 L 96.544974,183.91563 L 92.017774,183.91563 z" style="fill:url(#linearGradient3667);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3669);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 92.301865,183.91563 L 92.103915,186.66086 C 93.559965,186.82769 95.036015,186.84921 96.458833,186.66086 L 96.260883,183.91563 L 92.301865,183.91563 z" id="path5271" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="98.832191" y="185.43559" id="text5273" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5275" x="98.832191" y="185.43559" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold"><</tspan></text> <path style="fill:url(#linearGradient3671);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 96.790745,183.91563 L 96.564386,187.2754 L 101.5443,187.2754 L 101.31795,183.91563 L 96.790745,183.91563 z" id="path5279" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5281" d="M 97.074836,183.91563 L 96.876886,186.66086 C 98.332936,186.82769 99.808986,186.84921 101.2318,186.66086 L 101.03385,183.91563 L 97.074836,183.91563 z" style="fill:url(#linearGradient3673);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5283" y="185.43559" x="103.60517" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="185.43559" x="103.60517" id="tspan5285" sodipodi:role="line">></tspan></text> <path sodipodi:nodetypes="ccccc" id="path5289" d="M 101.56372,183.91563 L 101.33736,187.2754 L 106.31727,187.2754 L 106.09092,183.91563 L 101.56372,183.91563 z" style="fill:url(#linearGradient3675);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3677);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 101.84781,183.91563 L 101.64986,186.66086 C 103.10591,186.82769 104.58196,186.84921 106.00477,186.66086 L 105.80683,183.91563 L 101.84781,183.91563 z" id="path5291" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="108.4474" y="185.26953" id="text5293" transform="matrix(1,0,-3.413746e-2,1,0,0)"><tspan sodipodi:role="line" id="tspan5295" x="108.4474" y="185.26953" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">?</tspan></text> <text transform="matrix(1,0,-3.413746e-2,1,0,0)" id="text5303" y="185.25394" x="113.06779" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="185.25394" x="113.06779" id="tspan5305" sodipodi:role="line">^</tspan></text> <path style="fill:url(#linearGradient3679);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 53.863638,187.00922 L 53.378902,190.36899 L 58.35882,190.36899 L 58.390838,187.00922 L 53.863638,187.00922 z" id="path5357" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5359" d="M 54.147729,187.00922 L 53.738662,189.75445 C 55.181883,189.92128 56.656278,189.9428 58.09358,189.75445 L 58.106747,187.00922 L 54.147729,187.00922 z" style="fill:url(#linearGradient3681);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <text transform="matrix(1,0,-0.2003416,1,0,0)" id="text5361" y="188.38306" x="91.534843" style="font-size:1.38353634px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" xml:space="preserve"><tspan style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold" y="188.38306" x="91.534843" id="tspan5363" sodipodi:role="line">fn</tspan></text> <path sodipodi:nodetypes="ccccc" id="path5367" d="M 59.137309,187.00922 L 58.91095,190.36899 L 63.890868,190.36899 L 63.664509,187.00922 L 59.137309,187.00922 z" style="fill:url(#linearGradient3683);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3685);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 59.4214,187.00922 L 59.22345,189.75445 C 60.6795,189.92128 62.15555,189.9428 63.578368,189.75445 L 63.380418,187.00922 L 59.4214,187.00922 z" id="path5369" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3687);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 63.821891,187.00922 L 63.595532,190.36899 L 68.57545,190.36899 L 68.349091,187.00922 L 63.821891,187.00922 z" id="path5377" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5379" d="M 64.105982,187.00922 L 63.908032,189.75445 C 65.364082,189.92128 66.840132,189.9428 68.26295,189.75445 L 68.065,187.00922 L 64.105982,187.00922 z" style="fill:url(#linearGradient3689);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path5387" d="M 68.506473,187.00922 L 68.280114,190.36899 L 96.760032,190.36899 L 96.533674,187.00922 L 68.506473,187.00922 z" style="fill:url(#linearGradient3691);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3693);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 68.790565,187.00922 L 68.592614,189.75445 C 70.048665,189.92128 95.024715,189.9428 96.447532,189.75445 L 96.249583,187.00922 L 68.790565,187.00922 z" id="path5389" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5447" d="M 96.790745,187.00922 L 96.564386,190.36899 L 101.5443,190.36899 L 101.31795,187.00922 L 96.790745,187.00922 z" style="fill:url(#linearGradient3695);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3697);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 97.074836,187.00922 L 96.876886,189.75445 C 98.332936,189.92128 99.808986,189.9428 101.2318,189.75445 L 101.03385,187.00922 L 97.074836,187.00922 z" id="path5449" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3699);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 101.56372,187.00922 L 101.33736,190.36899 L 106.31727,190.36899 L 106.09092,187.00922 L 101.56372,187.00922 z" id="path5457" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5459" d="M 101.84781,187.00922 L 101.64986,189.75445 C 103.10591,189.92128 104.58196,189.9428 106.00477,189.75445 L 105.80683,187.00922 L 101.84781,187.00922 z" style="fill:url(#linearGradient3701);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path5467" d="M 106.2483,187.00922 L 106.02194,190.36899 L 111.00186,190.36899 L 110.7755,187.00922 L 106.2483,187.00922 z" style="fill:url(#linearGradient3703);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3705);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 106.53239,187.00922 L 106.33444,189.75445 C 107.79049,189.92128 109.26654,189.9428 110.68936,189.75445 L 110.49141,187.00922 L 106.53239,187.00922 z" id="path5469" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5525" d="M 48.012108,187.00922 L 47.433488,190.36899 L 53.562455,190.36899 L 53.583898,187.00922 L 48.012108,187.00922 z" style="fill:url(#linearGradient3707);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3709);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 48.361749,187.00922 L 47.872973,189.75445 C 49.650088,189.92128 51.464795,189.9428 53.232729,189.75445 L 53.234256,187.00922 L 48.361749,187.00922 z" id="path5527" sodipodi:nodetypes="ccccc" /> <text xml:space="preserve" style="font-size:1.19950843px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#3b3b3b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" x="66.108566" y="208.75516" id="text5529" transform="matrix(1.1093856,0,-0.1183677,0.9013998,0,0)"><tspan sodipodi:role="line" id="tspan5531" x="66.108566" y="208.75516" style="font-weight:bold;text-align:start;text-anchor:start;fill:#3b3b3b;fill-opacity:1;-inkscape-font-specification:Nimbus Sans L Bold">ctrl</tspan></text> <path style="fill:url(#linearGradient3711);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 113.27623,189.46511 L 113.51166,191.87159 L 117.07858,191.87159 L 116.51888,189.46511 L 113.27623,189.46511 z" id="path5995" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path5997" d="M 113.47971,189.46511 L 113.66277,191.43141 C 114.72543,191.5509 115.78521,191.56632 116.78203,191.43141 L 116.3154,189.46511 L 113.47971,189.46511 z" style="fill:url(#linearGradient3713);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6003" d="M 116.5683,189.46511 L 116.80373,191.87159 L 120.37065,191.87159 L 119.81095,189.46511 L 116.5683,189.46511 z" style="fill:url(#linearGradient3715);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3717);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 116.77178,189.46511 L 116.95484,191.43141 C 118.0175,191.5509 119.07728,191.56632 120.0741,191.43141 L 119.60746,189.46511 L 116.77178,189.46511 z" id="path6005" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3719);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 119.98698,189.46511 L 120.22242,191.87159 L 123.78934,191.87159 L 123.22963,189.46511 L 119.98698,189.46511 z" id="path6011" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6013" d="M 120.19046,189.46511 L 120.37353,191.43141 C 121.43618,191.5509 122.49596,191.56632 123.49279,191.43141 L 123.02615,189.46511 L 120.19046,189.46511 z" style="fill:url(#linearGradient3721);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6019" d="M 116.25507,187.18599 L 116.49052,189.59246 L 120.05742,189.59246 L 119.49773,187.18599 L 116.25507,187.18599 z" style="fill:url(#linearGradient3723);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3725);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 116.45855,187.18599 L 116.64163,189.15228 C 117.70427,189.27178 118.76406,189.28719 119.76087,189.15228 L 119.29425,187.18599 L 116.45855,187.18599 z" id="path6021" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3727);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 116.84957,177.55167 L 117.17827,180.91144 L 122.15819,180.91144 L 121.37677,177.55167 L 116.84957,177.55167 z" id="path6027" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6029" d="M 117.13366,177.55167 L 117.38925,180.2969 C 118.87286,180.46373 120.35246,180.48525 121.74417,180.2969 L 121.09268,177.55167 L 117.13366,177.55167 z" style="fill:url(#linearGradient3729);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6035" d="M 117.71421,180.64526 L 118.04291,184.00503 L 123.02283,184.00503 L 122.24141,180.64526 L 117.71421,180.64526 z" style="fill:url(#linearGradient3731);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3733);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 117.9983,180.64526 L 118.25388,183.39049 C 119.73749,183.55732 121.2171,183.57884 122.6088,183.39049 L 121.95732,180.64526 L 117.9983,180.64526 z" id="path6037" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient3735);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 118.62343,183.47369 L 118.95213,186.83346 L 123.93205,186.83346 L 123.15063,183.47369 L 118.62343,183.47369 z" id="path6043" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6045" d="M 118.90752,183.47369 L 119.1631,186.21892 C 120.64671,186.38575 122.12632,186.40727 123.51802,186.21892 L 122.86654,183.47369 L 118.90752,183.47369 z" style="fill:url(#linearGradient3737);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path style="fill:url(#linearGradient3739);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 110.84449,174.54646 L 110.52975,177.90623 L 117.45421,177.90623 L 117.13946,174.54646 L 110.84449,174.54646 z" id="path6067" sodipodi:nodetypes="ccccc" /> <path sodipodi:nodetypes="ccccc" id="path6069" d="M 111.23952,174.54646 L 110.96427,177.29169 C 112.98887,177.45852 115.04129,177.48004 117.01969,177.29169 L 116.74444,174.54646 L 111.23952,174.54646 z" style="fill:url(#linearGradient3741);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path transform="matrix(0.8530407,0,0,0.8530407,30.561565,101.92012)" id="path6941" d="M 96.40625,85.90625 L 95.299119,86.545452 L 96.471515,87.222335 L 97.78125,87.222335 L 97.78125,85.90625 L 96.40625,85.90625 z" style="opacity:0.65250962;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.15119201;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path transform="matrix(0.8530407,0,0,0.8530407,30.561565,101.92012)" id="path6943" d="M 96.5625,86.3125 L 97.375,86.90625" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.15119201;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path style="opacity:0.65250962;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.1289729;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 113.6264,175.5482 L 112.93331,176.05469" id="path6945" /> <path transform="matrix(0.8530407,0,0,0.8530407,30.561565,101.92012)" id="path6947" d="M 99.875,90.0625 L 100.82271,93.599389 L 99.125,93.599389" style="opacity:0.65250962;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.15119201;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path id="path6949" d="M 115.57098,181.36033 L 115.15227,181.7859 L 115.72737,182.12338" style="opacity:0.65250962;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.1289729;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> </g> <rect style="opacity:0.11934156;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect3387" width="60.96727" height="43.682003" x="13.590461" y="8.8828611" rx="3.042789" ry="3.0427887" /> <rect style="opacity:0.23045265;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.99999964;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect4161" width="46.386017" height="28.894892" x="20.895304" y="16.825495" rx="3.042789" ry="3.0427887" /> <path style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 18.675785,53.596158 L 69.904048,53.596158" id="path4166" /> <path id="path4170" d="M 6.5914563,77.121626 L 81.54345,77.121626" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path style="opacity:0.25514401;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 6.5914563,82.282782 L 81.54345,82.282782" id="path4172" /> <rect style="opacity:0.09745763;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.99999988000000006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect3060" width="44.784832" height="29.187614" x="21.87866" y="16.714867" /> <rect style="opacity:0.09958506;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect3834" width="50.236374" height="3.0871515" x="19.364859" y="8.0147123" /> <g id="g3743" transform="matrix(0.6659784,0,0,0.674911,1.3108923,1.4533383)"> <path sodipodi:nodetypes="ccccccccc" id="path8917" d="M 48.02277,117.86388 L 79.97723,117.86388 C 80.458544,117.86388 80.846024,117.47011 80.846024,116.98098 L 79.055641,107.14033 C 79.055641,106.6512 78.66816,106.25743 78.186845,106.25743 L 49.813155,106.25743 C 49.33184,106.25743 48.944359,106.6512 48.944359,107.14033 L 47.153976,116.98098 C 47.153976,117.47011 47.541459,117.86388 48.02277,117.86388 z" style="opacity:0.60962572;fill:url(#linearGradient8925);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" /> <path style="opacity:1;fill:url(#linearGradient8935);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" d="M 48.590578,117.62029 L 79.409422,117.62029 C 79.843506,117.62029 80.192963,117.27058 80.192963,116.83617 L 78.578266,108.09655 C 78.578266,107.66214 78.228807,107.31243 77.794723,107.31243 L 50.205277,107.31243 C 49.771193,107.31243 49.421734,107.66214 49.421734,108.09655 L 47.807037,116.83617 C 47.807037,117.27058 48.156497,117.62029 48.590578,117.62029 z" id="path8927" sodipodi:nodetypes="ccccccccc" /> <path id="path8937" d="M 48.3125,114.125 L 47.8125,116.84375 C 47.8125,117.27816 48.159669,117.625 48.59375,117.625 L 79.40625,117.625 C 79.840332,117.625 80.1875,117.27816 80.1875,116.84375 L 79.6875,114.125 L 48.3125,114.125 z" style="opacity:0.4919786;fill:url(#radialGradient8957);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" /> <path id="path8959" d="M 59.53125,114.125 L 59.53125,117.625 L 68.46875,117.625 L 68.46875,114.125 L 59.53125,114.125 z" style="opacity:0.69543146;fill:url(#radialGradient8968);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" /> </g> <path sodipodi:nodetypes="ccccccccc" id="path4168" d="M 35.273296,71.5143 L 52.325839,71.5143 C 52.7132,71.5143 53.025046,72.126125 53.025046,72.886087 L 54.173998,78.803448 C 54.173998,79.563409 53.862153,80.175234 53.474793,80.175234 L 34.124342,80.175234 C 33.736983,80.175234 33.425136,79.563409 33.425136,78.803448 L 34.574091,72.886087 C 34.574091,72.126125 34.885937,71.5143 35.273296,71.5143 z" style="opacity:0.24279833;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.99999964;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> <path style="opacity:0.6473029;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 36 72 L 36 80 L 40 80 L 40 76 L 48 76 L 48 80 L 52 80 L 52 72 L 36 72 z " id="rect3840" /> <rect style="opacity:0.11618257;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect3845" width="54.503407" height="4" x="16.753811" y="68" /> <path style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.99999988000000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:0.56846473" d="M 16,50.121626 L 72.134901,50.121626" id="path3847" /> <path id="path3849" d="M 16,54.621626 L 72.134901,54.621626" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99999988000000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:0.39419087" /> <path id="path3851" d="M 20.000001,58.121626 L 68.134904,58.121626" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/discogs.png����������������������������������������������������������0000644�0001750�0000144�00000006331�11163131036�016657� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR������<���Lꩼ���bKGD������ pHYs�� �� ����tIME 2)���tEXtComment�Created with The GIMPd%n�� =IDATx\AhW@M% #Zґ!u٠Ub+lؐ@jX2>쐃pqDk9dJR‚\f`J7{Fg; ̼!B"D!B"D!B"D�ӈ%H$ijdrX#ha"13fLv:=JnhPd<e9AC>cLKs֡DSPX] yxp`/PPlqdoo?4F#{r+##'QJ(ll\G:=ƴ amcaNN&0SD0 f^GxBgъ_TKVG(JJ�rhsߐs0 koz凾((ΟǏ'21"関,0T@zVwu~aVi`s4wJe"ϲj,czzϿ :۪e |'ĒkR'B嗺"aօ 8-7t" ðzK"1o+2ڎ_>ϵ%(I{zzGTEʕM$}dҪv9su9f{i�E6oT|w:%$ȵEB䘤}޸m�`qqk=.Xz5wayEe6NC oQc~+W~X" PG*?(0 LOrr>g1 \.25 -ppP[<{ZmڰDb>hUܣ_N].0M3 VG,$IB*u¶0G& bىX,�TtJe9P*fW17w8ᚦjTA`qqi1$ $A!㘞dy�p"vv6-?ױqzwCCǡi:9ܿ~+9WL&'H$ y|#ܼG¼2@##'ihī;0GT*Mc}}ͥCdYif?tz B^H&drX>zkI$(JJM0ZB]&1߬FKB@vV4M{qfӰIj Mcddl4z鱎y~;ؙLN[$I4ݚKՓYECꁃ&I`0 oGNTm?(4,aE,,|#uX8#Fgv?,ӎv\JgruʊDlu ZZi[E hX rB.fg?6$IPVc�nob}U׾4PȻ"\ }mK1}g7XyVGا~UpqN2~߱_AQRK;\S9ݸJe ȩXe_O/pju,ƽ)Ǻ3ڑAsr4M)AhATE ?f>܇(6Cn29 Ph,#kAVëAzE "f> ' dEa0O8ܭ `9nPk?]rč}#C,,AFa$I׆ ne<-A&GPz<&}NВ:<mEu�ڏ+q1xL&C4\<nPM39$r&͍<~&ڏܮ9Hw%U;9$ wL"k^RW'>rEAR9y=R$H˴}!G"1ؑ A>4oX\#!,E{?r�S"Ր>I-DUre%{;  ٕE&VX eO 㘚CG&>|/ o2J\Ԯwgަ mgYI<>okD_PUTaĻpg"ec3WiX,Zm*nwDM07)eY")lab4 knC9bZ+װ##s.,OO ³gl.,<TջX]� ֞vVtܫKhAԻoo C.AGǡiu G<.AQF1Ae /!CQF}뎉uk4v Z m9Hk h…rRYOi6;EyY] U]Rk}30.-Y]dKN!:Q蜆((?$YޓvyJ<,j"/i!cU@|9UZI *Ӥ cXYُQVN|<%%EkyaǮ./i\D&7"Xu:AQMj<&PJe !>JMRDA tA; T`((Z-(ʨK5TAhL AK04'ytz ׻~Ϛ_ygʹ95slnCfOcYyVkf¶\;XnT̓L&v$ <uٽ6<<a~}} aPIu-^Kw4"NKF NSmDchx 6Zmj6 adhjŕCb\ϾiݼM4]OcO->I$}0͏d{{5ܼ=ÝɦR'_M>Aw>|R/("r,+,._~O][y/Rcʗrxbh1č*x#Wa9[O.B#AكrA904jy^\KD(����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/transform4.svg�������������������������������������������������������0000644�0001750�0000144�00000205726�11207733001�017346� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:ns="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="156" height="156" id="svg2365" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docname="transform4.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/MP3Diags/src/images"> <metadata id="metadata198"> <rdf:RDF> <ns:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </ns:Work> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <sodipodi:namedview inkscape:window-height="956" inkscape:window-width="891" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" showgrid="true" inkscape:zoom="1.463932" inkscape:cx="-43.819174" inkscape:cy="64" inkscape:window-x="251" inkscape:window-y="72" inkscape:current-layer="svg2365" /> <defs id="defs2367"> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 64 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="128 : 64 : 1" inkscape:persp3d-origin="64 : 42.666667 : 1" id="perspective200" /> <filter x="-0.085532367" width="1.1710647" y="-0.10938701" height="1.218774" id="filter6906"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.5212367" id="feGaussianBlur6908" /> </filter> <clipPath id="clipPath6130"> <path d="M 125.16669,12.099598 C 122.19641,9.254864 111.282,2.992388 109.84175,5.187905 C 108.10513,7.835221 117.93885,14.870955 121.74406,16.587139 C 123.04716,17.174853 126.16385,13.054607 125.16669,12.099598 z" id="path6132" style="fill:#e20071;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient3168"> <stop id="stop3170" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop3172" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="29.344007" y1="35.892609" x2="5.8861146" y2="54.610104" id="linearGradient6134" xlink:href="#linearGradient3168" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.8205678,0.1491734,0.1491734,0.8205678,119.95493,-30.558073)" /> <linearGradient id="linearGradient2878"> <stop id="stop2880" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2882" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="47.794022" cy="43.680889" r="0.046902865" fx="47.817745" fy="43.681263" id="radialGradient2257" xlink:href="#linearGradient2878" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,140,0,-6071.644)" /> <linearGradient id="linearGradient2926"> <stop id="stop2928" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2934" style="stop-color:#ffffff;stop-opacity:0" offset="0.31868133" /> <stop id="stop2930" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="59.887943" cy="-16.594898" r="15.014902" fx="59.887943" fy="-16.594898" id="radialGradient4868" xlink:href="#linearGradient2926" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2908472,-1.2912538,-0.4877278,0.8613771,257.00005,93.121214)" spreadMethod="reflect" /> <linearGradient id="linearGradient2916"> <stop id="stop2918" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2920" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <radialGradient cx="58.079144" cy="51.897194" r="15.014902" fx="60.050133" fy="51.985794" id="radialGradient4871" xlink:href="#linearGradient2916" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.9412787,-1.1615663,-0.2846191,0.7136661,292.2596,68.533501)" /> <linearGradient id="linearGradient2948"> <stop id="stop2950" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2956" style="stop-color:#000000;stop-opacity:0" offset="0.14835165" /> <stop id="stop2960" style="stop-color:#000000;stop-opacity:0.39607844" offset="0.42443547" /> <stop id="stop2958" style="stop-color:#000000;stop-opacity:0.79061371" offset="0.57417583" /> <stop id="stop2962" style="stop-color:#000000;stop-opacity:0.09386282" offset="0.78708792" /> <stop id="stop2952" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.277409" y1="41.758987" x2="75.465431" y2="41.511894" id="linearGradient4874" xlink:href="#linearGradient2948" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <filter x="-0.081383675" width="1.1627673" y="-0.11701577" height="1.2340316" id="filter7303"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5574454" id="feGaussianBlur7305" /> </filter> <clipPath id="clipPath6914"> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 81.839741,-15.69481 90.48863,-25.23053 103.93871,-26.883344 C 107.28591,-26.458991 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.52863,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z" id="path6916" style="opacity:1;fill:#34176e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2938"> <stop id="stop2940" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2942" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="61.870293" y1="33.318996" x2="61.870293" y2="40.550549" id="linearGradient4880" xlink:href="#linearGradient2938" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <linearGradient id="linearGradient2854"> <stop id="stop2856" style="stop-color:#ffffff;stop-opacity:1" offset="0" /> <stop id="stop2858" style="stop-color:#ffffff;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="106.03028" y1="59.273457" x2="108.78728" y2="55.574818" id="linearGradient4888" xlink:href="#linearGradient2854" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="94.435982" cy="42.709927" r="16.633095" fx="94.435982" fy="42.709927" id="radialGradient4891" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.2134389,-1.5580054,-0.9195638,1.2855562,320.80105,101.437)" /> <radialGradient cx="94.932045" cy="43.032188" r="16.633095" fx="94.932045" fy="43.032188" id="radialGradient4894" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="93.747849" cy="43.102612" r="16.633095" fx="93.747849" fy="43.102612" id="radialGradient4897" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <radialGradient cx="92.990265" cy="42.850105" r="16.633095" fx="92.990265" fy="42.850105" id="radialGradient4900" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <linearGradient id="linearGradient2830"> <stop id="stop2832" style="stop-color:#111111;stop-opacity:1" offset="0" /> <stop id="stop2838" style="stop-color:#6e6e70;stop-opacity:1" offset="0.14285715" /> <stop id="stop2864" style="stop-color:#101010;stop-opacity:1" offset="0.5714286" /> <stop id="stop2834" style="stop-color:#0d0d0d;stop-opacity:1" offset="1" /> </linearGradient> <radialGradient cx="92.496124" cy="43.249184" r="16.633095" fx="92.496124" fy="43.249184" id="radialGradient4903" xlink:href="#linearGradient2830" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.7759891,-0.8986225,-1.0601326,2.082617,285.11609,4.6753809)" /> <filter x="-0.059171364" width="1.1183428" y="-0.25424162" height="1.5084833" id="filter5739"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.5280665" id="feGaussianBlur5741" /> </filter> <clipPath id="clipPath5354"> <path d="M 103.98397,-1.574449 C 105.35028,-1.792233 108.98473,-2.914664 106.17093,-5.692155 C 76.173344,-27.291403 51.99515,-18.323699 42.936426,-12.159439 C 53.098952,-17.891025 78.771948,-21.925123 103.98397,-1.574449 z" id="path5356" style="opacity:1;fill:#00583f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </clipPath> <linearGradient id="linearGradient2803"> <stop id="stop2809" style="stop-color:#e2dcdc;stop-opacity:1" offset="0" /> <stop id="stop2811" style="stop-color:#ffffff;stop-opacity:1" offset="0.39074388" /> <stop id="stop2813" style="stop-color:#dfd9df;stop-opacity:1" offset="0.82692307" /> <stop id="stop2815" style="stop-color:#c3c3c3;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="62.987843" y1="46.469597" x2="118.02947" y2="62.350033" id="linearGradient4910" xlink:href="#linearGradient2803" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,196.65813,26.204038)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2231" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2229" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2227" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2225" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2223" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2221" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2219" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2217" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2215" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2213" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2211" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2209" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2207" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2205" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2203" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2201" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2199" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2197" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2195" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2193" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2191" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2189" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2187" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2185" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2183" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2181" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2179" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2177" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2175" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2173" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2171" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2169" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient id="linearGradient2370"> <stop id="stop2378" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2374" style="stop-color:#2a2a2a;stop-opacity:0.29537368" offset="1" /> </linearGradient> <radialGradient cx="-67.615143" cy="84.213043" r="1.4498374" fx="-67.047073" fy="83.803413" id="radialGradient2167" xlink:href="#linearGradient2370" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.636364,0,30.62293)" /> <linearGradient x1="-66.905724" y1="78.000954" x2="-66.905724" y2="77.232819" id="linearGradient4946" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-75.354716)" /> <linearGradient x1="-74.01326" y1="49.46249" x2="-58.206917" y2="65.268829" id="linearGradient4952" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833612,-4.797835,-79.665584)" /> <linearGradient x1="36.909187" y1="75.415688" x2="38.451817" y2="75.479614" id="linearGradient4955" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.983361,0.6663259,-0.6582589,0.9697357,55.439719,-32.927491)" /> <linearGradient id="linearGradient2322"> <stop id="stop2324" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2326" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="37.235054" y1="75.415688" x2="38.61475" y2="75.479614" id="linearGradient4958" xlink:href="#linearGradient2322" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.44832,27.448631)" /> <linearGradient x1="45.615768" y1="128.00496" x2="45.615768" y2="125.89983" id="linearGradient4961" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2310"> <stop id="stop2312" style="stop-color:#020202;stop-opacity:1" offset="0" /> <stop id="stop2314" style="stop-color:#020202;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="45.24057" y1="61.083416" x2="45.24057" y2="62.415165" id="linearGradient4964" xlink:href="#linearGradient2310" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.36527,27.463989)" /> <linearGradient id="linearGradient3058"> <stop id="stop3060" style="stop-color:#9a7600;stop-opacity:1" offset="0" /> <stop id="stop3066" style="stop-color:#e3ad00;stop-opacity:1" offset="0.32522252" /> <stop id="stop3070" style="stop-color:#ffcd2c;stop-opacity:1" offset="0.6670348" /> <stop id="stop3068" style="stop-color:#e3ad00;stop-opacity:1" offset="0.91571385" /> <stop id="stop3062" style="stop-color:#b98d00;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="34.91254" y1="94.734375" x2="55.089256" y2="94.734375" id="linearGradient4967" xlink:href="#linearGradient3058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.9676045,-0.6692381,-0.6740154,0.9726479,144.54699,27.4304)" /> <linearGradient id="linearGradient2352"> <stop id="stop2354" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop2356" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="-66.905724" y1="77.09996" x2="-66.905724" y2="75.717079" id="linearGradient4949" xlink:href="#linearGradient2352" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764965,0,0,1.1833623,-4.7827195,-79.650397)" /> <linearGradient id="linearGradient2334"> <stop id="stop2336" style="stop-color:#8d8d8d;stop-opacity:1" offset="0" /> <stop id="stop2342" style="stop-color:#e2dcdc;stop-opacity:1" offset="0.2767916" /> <stop id="stop2348" style="stop-color:#ffffff;stop-opacity:1" offset="0.71460712" /> <stop id="stop2344" style="stop-color:#dfd9df;stop-opacity:1" offset="0.80711305" /> <stop id="stop2338" style="stop-color:#888888;stop-opacity:1" offset="1" /> </linearGradient> <linearGradient x1="-70.588905" y1="67.754272" x2="-59.581383" y2="67.754272" id="linearGradient4970" xlink:href="#linearGradient2334" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1764954,0,0,1.1833613,-4.7978353,-79.665581)" /> <linearGradient id="linearGradient6959"> <stop id="stop6961" style="stop-color:#000000;stop-opacity:1" offset="0" /> <stop id="stop6963" style="stop-color:#000000;stop-opacity:0" offset="1" /> </linearGradient> <linearGradient x1="0.16120911" y1="117.27959" x2="128.16121" y2="117.27959" id="linearGradient8078" xlink:href="#linearGradient6959" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.785268,-7.3677219e-2,3.9462543e-2,0.4492806,22.778321,70.710911)" /> </defs> <g id="layer1" transform="translate(11.95197,16)"> <path d="M 128.04736,113.95979 C 128.28089,116.61848 67.411471,124.50507 39.669521,127.10794 C 11.927571,129.71081 27.766581,126.04917 27.533061,123.39048 C 27.299531,120.73178 11.081461,120.07787 38.823411,117.475 C 66.565361,114.87213 127.81383,111.3011 128.04736,113.95979 z " id="path6957" style="opacity:0.32093027;fill:url(#linearGradient8078);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31099999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.274934,34.905639 C 85.204914,25.922787 89.34177,14.198553 102.63801,12.53741 C 105.94693,12.9639 108.13372,18.737744 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2874" style="fill:#bfbfc0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <rect width="12.941447" height="29.58403" ry="0" x="-87.844696" y="-16.94743" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2266" style="fill:url(#linearGradient4970);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="13.038667" height="2.5542164" ry="0" x="-87.829575" y="9.101737" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2360" style="opacity:0.36065578;fill:url(#linearGradient4949);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.429289,63.172679 C 65.635414,64.820033 54.923018,83.195864 49.729102,91.344581 C 39.34128,107.642 26.239281,125.86158 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 19.376879,93.833728 30.860819,78.294436 C 36.602784,70.52478 49.810698,53.88547 51.006314,52.505467 C 52.212736,51.113002 53.417042,50.730504 54.693928,51.613654 C 58.435834,54.201727 62.17774,56.7898 65.919646,59.377862 C 66.995538,60.122005 67.369194,61.222275 66.429289,63.172679 z " id="rect1388" style="fill:url(#linearGradient4967);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.247591,63.206257 C 65.453717,64.853621 49.629,53.919059 50.824616,52.539056 C 52.031038,51.146581 53.235344,50.764082 54.51223,51.647242 C 58.254136,54.235305 61.996042,56.823378 65.737948,59.411451 C 66.81384,60.155584 67.187497,61.255863 66.247591,63.206257 z " id="path2290" style="opacity:0.09157511;fill:url(#linearGradient4964);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 26.239281,125.86158 C 24.667744,128.1294 21.590814,128.67159 19.334757,127.1112 L 8.1468219,119.37313 C 5.8907745,117.81274 5.3156686,114.74463 6.887186,112.47682 C 6.887186,112.47682 26.239281,125.86158 26.239281,125.86158 z " id="path2308" style="opacity:0.3699634;fill:url(#linearGradient4961);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 66.33068,63.19091 C 65.536805,64.838264 54.824409,83.214095 49.630493,91.362803 C 39.242661,107.66022 26.140672,125.8798 26.140672,125.8798 C 24.569135,128.14762 62.079131,56.808021 65.821037,59.396094 C 66.896928,60.140227 67.270585,61.240506 66.33068,63.19091 z " id="path2320" style="opacity:0.3699634;fill:url(#linearGradient4958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 51.020737,52.411747 C 49.776998,53.730231 36.591653,70.167669 30.909012,77.870037 C 19.543739,93.274764 7.3898106,111.88362 7.3898106,111.88362 C 5.8550281,114.14465 58.555163,54.129906 54.752313,51.55311 C 53.658913,50.812203 52.49326,50.850706 51.020737,52.411747 z " id="path2330" style="opacity:0.23809521;fill:url(#linearGradient4955);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="22.48386" ry="0" x="-87.844696" y="-16.947432" transform="matrix(-0.8224474,-0.5688412,-0.5695776,0.8219376,0,0)" id="rect2350" style="opacity:0.25;fill:url(#linearGradient4952);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <rect width="12.941447" height="4.1249256" ry="0" x="-87.844696" y="12.822533" transform="matrix(-0.8224474,-0.5688412,0.5695776,-0.8219376,0,0)" id="rect2364" style="opacity:0.29098361;fill:url(#linearGradient4946);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.339764,-119.62564)" id="path2368" style="opacity:0.21245422;fill:url(#radialGradient2167);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.295704,-113.78978)" id="path2486" style="opacity:0.21245422;fill:url(#radialGradient2169);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.251654,-107.95391)" id="path2490" style="opacity:0.21245422;fill:url(#radialGradient2171);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.207455,-102.11799)" id="path2494" style="opacity:0.21245422;fill:url(#radialGradient2173);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.163405,-96.282126)" id="path2498" style="opacity:0.21245422;fill:url(#radialGradient2175);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.119257,-90.446221)" id="path2502" style="opacity:0.21245422;fill:url(#radialGradient2177);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.401175,-83.637696)" id="path2506" style="opacity:0.21245422;fill:url(#radialGradient2179);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.357125,-77.801811)" id="path2510" style="opacity:0.21245422;fill:url(#radialGradient2181);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.312966,-71.965905)" id="path2514" style="opacity:0.21245422;fill:url(#radialGradient2183);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2518" style="opacity:0.21245422;fill:url(#radialGradient2185);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.268916,-66.13003)" id="path2522" style="opacity:0.21245422;fill:url(#radialGradient2187);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,74.51209,-120.72315)" id="path2524" style="opacity:0.21245422;fill:url(#radialGradient2189);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,70.468031,-114.88732)" id="path2526" style="opacity:0.21245422;fill:url(#radialGradient2191);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,66.423951,-109.05138)" id="path2528" style="opacity:0.21245422;fill:url(#radialGradient2193);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,62.379792,-103.21548)" id="path2530" style="opacity:0.21245422;fill:url(#radialGradient2195);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,58.335742,-97.379601)" id="path2532" style="opacity:0.21245422;fill:url(#radialGradient2197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,54.291593,-91.543696)" id="path2534" style="opacity:0.21245422;fill:url(#radialGradient2199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.573512,-84.735171)" id="path2536" style="opacity:0.21245422;fill:url(#radialGradient2201);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,45.529462,-78.899296)" id="path2538" style="opacity:0.21245422;fill:url(#radialGradient2203);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,41.485303,-73.063401)" id="path2540" style="opacity:0.21245422;fill:url(#radialGradient2205);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2542" style="opacity:0.21245422;fill:url(#radialGradient2207);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,37.441253,-67.227515)" id="path2544" style="opacity:0.21245422;fill:url(#radialGradient2209);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,86.123367,-112.6923)" id="path2568" style="opacity:0.21245422;fill:url(#radialGradient2211);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,82.079218,-106.85639)" id="path2570" style="opacity:0.21245422;fill:url(#radialGradient2213);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,78.035168,-101.02052)" id="path2572" style="opacity:0.21245422;fill:url(#radialGradient2215);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,73.991108,-95.18463)" id="path2574" style="opacity:0.21245422;fill:url(#radialGradient2217);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,69.947019,-89.348755)" id="path2576" style="opacity:0.21245422;fill:url(#radialGradient2219);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,65.90286,-83.51285)" id="path2578" style="opacity:0.21245422;fill:url(#radialGradient2221);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,61.184788,-76.704325)" id="path2580" style="opacity:0.21245422;fill:url(#radialGradient2223);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,57.14063,-70.86842)" id="path2582" style="opacity:0.21245422;fill:url(#radialGradient2225);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,53.09658,-65.032544)" id="path2584" style="opacity:0.21245422;fill:url(#radialGradient2227);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2586" style="opacity:0.21245422;fill:url(#radialGradient2229);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M -66.165305,84.213043 C -66.165305,84.722594 -66.814419,85.135667 -67.615143,85.135667 C -68.415866,85.135667 -69.06498,84.722594 -69.06498,84.213043 C -69.06498,83.703492 -68.415866,83.290419 -67.615143,83.290419 C -66.814419,83.290419 -66.165305,83.703492 -66.165305,84.213043 z " transform="matrix(-1.0010823,-0.6923933,-1.0958111,1.5813273,49.05253,-59.196659)" id="path2588" style="opacity:0.21245422;fill:url(#radialGradient2231);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 101.38809,11.479353 C 102.63809,12.398423 103.84894,13.381344 105.0387,14.408949 C 104.01321,16.577326 100.48534,20.746249 99.007199,22.467323 C 98.01495,23.622639 93.281961,23.36178 91.998392,24.319263 C 87.944052,27.343595 84.815519,31.864815 80.922501,35.138608 L 72.655729,29.510877 C 72.667829,29.490354 72.685732,29.470645 72.697861,29.450092 C 72.67379,29.475982 72.628395,29.495037 72.604432,29.520354 L 71.432076,28.709507 C 71.432067,28.709497 76.539137,19.842938 71.897343,16.081861 C 61.421124,7.5933688 42.104321,12.7028 40.367328,14.0543 L 42.083541,7.259695 C 42.083541,7.259695 42.33779,7.1294014 42.380871,7.1146373 C 59.53124,-3.8488001 84.402814,-1.0092155 101.38809,11.479353 z " id="path2783" style="fill:url(#linearGradient4910);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 103.83475,-5.0595755 C 104.3991,-4.5551745 105.41114,-5.6873565 104.63008,-6.2226895 C 74.632493,-27.821939 51.99515,-17.681556 42.936426,-11.517296 C 52.35952,-18.300887 76.609727,-26.230729 103.83475,-5.0595755 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath5354)" id="path2823" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter5739)" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.128521,13.402952 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.101176,-0.96025992 73.950973,7.4166021 C 82.164175,13.221703 76.243429,25.456347 72.232891,29.69503 z " id="path2842" style="opacity:0.23360656;fill:url(#radialGradient4903);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.523172,29.895808 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 41.022844,13.705088 40.58322,14.173176 L 42.107732,7.2764289 C 42.107732,7.2764289 62.235986,-1.1547857 74.085773,7.2220662 C 82.298976,13.027177 76.53371,25.657124 72.523172,29.895808 z " id="path2827" style="opacity:0.23360656;fill:url(#radialGradient4900);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 73.103735,30.297352 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.89179,13.624865 40.576201,14.168322 L 42.322269,7.4456578 C 42.322269,7.4456578 62.640397,-1.7383733 74.490184,6.6384787 C 82.703386,12.44359 77.114273,26.058669 73.103735,30.297352 z " id="path2844" style="opacity:0.0737705;fill:url(#radialGradient4897);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.232891,29.69503 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.984171,13.626222 40.566444,14.182412 L 42.334152,7.4434568 C 42.334152,7.4434568 61.966375,-0.76572405 73.816172,7.6111279 C 82.029375,13.416239 76.243429,25.456347 72.232891,29.69503 z " id="path2840" style="opacity:0.23360656;fill:url(#radialGradient4894);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 72.13613,29.628115 L 71.135399,28.798503 C 71.135399,28.798503 76.660088,19.926598 72.018284,16.16551 C 60.890029,7.1486982 40.921635,13.665037 40.571002,14.184262 L 42.322269,7.4456578 C 42.322269,7.4456578 61.764175,-0.47393028 73.613962,7.9029217 C 81.827164,13.708033 76.146668,25.389432 72.13613,29.628115 z " id="path2862" style="opacity:0.37000002;fill:url(#radialGradient4891);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 61.41113,8.3780551 C 54.11035,6.6553332 42.963569,9.4974003 40.902427,12.001391 L 41.0016,10.631158 C 43.787546,7.6855914 53.80009,5.6303314 60.912865,6.8618995 C 62.075305,7.0631792 62.003061,8.5177258 61.41113,8.3780551 z " id="path2868" style="opacity:0.31000001;fill:url(#linearGradient4888);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 42.085054,7.2558055 L 40.347458,14.03836 L 40.579642,14.198955 L 42.326056,7.4656582 L 42.085054,7.2558055 z " id="path2872" style="opacity:0.11000001;fill:#b7b7b7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.793503,23.516486 95.950625,22.98307 C 98.195669,22.788575 103.22118,19.851069 102.52483,17.34553 C 101.28955,12.900833 104.51185,12.778691 106.76072,16.351101 C 107.83597,18.05917 108.68046,20.615514 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 121.44894,38.490512 117.56384,42.696451 L 111.17842,38.965656 L 103.77633,29.053301 C 97.649281,27.059128 88.562348,29.712528 81.865056,36.103558 z " id="path2936" style="opacity:0.5286885;fill:url(#linearGradient4880);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.925411,-3.435412 L 81.316892,-4.627315 C 96.447179,-28.288297 105.15658,-12.530013 103.93871,-26.883344 C 105.73798,-25.86955 109.49801,-20.714107 110.82559,-16.938578 L 121.37226,-13.3605 L 127.24587,-9.003369 C 124.67754,-3.892162 121.60365,0.875112 117.6736,5.059949 L 111.2143,1.347869 L 103.72658,-8.514759 C 97.528633,-10.498934 89.700195,-9.79438 82.925411,-3.435412 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,39.556289)" clip-path="url(#clipPath6914)" id="path2902" style="opacity:0.3;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7303)" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 89.936568,23.945458 96.09369,23.412042 C 98.338733,23.217547 99.058515,23.054066 102.62556,17.81605 C 104.97193,14.370546 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2904" style="opacity:0.11065572;fill:#4b4b4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 81.865056,36.103558 L 80.621731,34.841548 C 90.450353,25.575234 90.178924,23.81633 96.336045,23.282914 C 98.581099,23.088419 99.46084,22.257119 102.66207,17.556297 C 105.00842,14.110793 105.5052,13.664595 106.76072,16.351101 C 107.72182,18.407618 108.78993,20.635031 109.44612,22.532309 L 119.87216,26.128429 L 125.67859,30.507526 C 123.13963,35.644506 120.1009,40.435811 116.2158,44.64175 L 109.83038,40.910954 L 102.42831,30.9986 C 96.301248,29.004426 88.562348,29.712528 81.865056,36.103558 z " id="path2946" style="opacity:0.78278689;fill:url(#linearGradient4874);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.186467,36.425805 L 80.943143,35.163804 C 90.771765,25.89748 90.156661,24.109531 96.307061,23.50126 C 99.068954,23.228099 101.46217,20.125666 103.03896,17.817699 C 105.39113,14.376285 105.82661,13.986851 107.08213,16.673348 C 108.04323,18.729874 109.11134,20.957278 109.76753,22.854566 L 120.19358,26.450685 L 126,30.829783 C 123.46105,35.966762 120.42231,40.758067 116.53723,44.964006 L 110.15179,41.233211 L 102.74972,31.320856 C 96.622659,29.326673 88.883759,30.034785 82.186467,36.425805 z " id="path2906" style="opacity:0.55;fill:url(#radialGradient4871);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 82.052576,35.677069 L 80.809252,34.415058 C 90.637874,25.148744 90.316354,23.346463 96.463708,22.707247 C 99.198595,22.422217 99.463846,21.382923 102.80287,17.054108 C 105.34611,13.756144 105.69272,13.238105 106.94825,15.924612 C 107.90935,17.981128 108.97746,20.208542 109.63365,22.10582 L 120.05969,25.701939 L 125.86612,30.081037 C 123.32716,35.218016 120.28843,40.009321 116.40334,44.21526 L 110.0179,40.484465 L 102.61584,30.57211 C 96.488778,28.577937 88.749878,29.286039 82.052576,35.677069 z " id="path2924" style="opacity:0.76000001;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path d="M 47.840924,43.680889 C 47.84099,46.032991 47.832065,48.210404 47.817526,49.389142 C 47.802987,50.56788 47.785056,50.56788 47.770517,49.389142 C 47.755978,48.210404 47.747053,46.032991 47.747119,43.680889 C 47.747053,41.328787 47.755978,39.151374 47.770517,37.972636 C 47.785056,36.793898 47.802987,36.793898 47.817526,37.972636 C 47.832065,39.151374 47.84099,41.328787 47.840924,43.680889 z " transform="matrix(-10.643649,-7.3616191,-0.6740154,0.9726479,659.11339,347.51792)" id="path2876" style="fill:url(#radialGradient2257);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" /> <path d="M 125.16669,12.099598 C 121.62206,9.685606 112.43786,3.516506 110.99761,5.712023 C 109.26099,8.35934 118.0322,14.038156 121.74406,16.587139 C 122.92246,17.396368 126.3079,12.876785 125.16669,12.099598 z " transform="matrix(0.9885623,0,0,1.0050417,-0.1118743,19.455454)" clip-path="url(#clipPath6130)" id="path3178" style="fill:url(#linearGradient6134);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6906)" /> </g> <path style="font-size:72px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" d="M 117,134.78125 L 117,118.32812 L 87.1875,118.32812 L 87.1875,110.59375 L 118.54688,66.0625 L 125.4375,66.0625 L 125.4375,110.59375 L 134.71875,110.59375 L 134.71875,118.32812 L 125.4375,118.32812 L 125.4375,134.78125 L 117,134.78125 M 117,110.59375 L 117,79.609375 L 95.484375,110.59375 L 117,110.59375" id="text2573" /> </svg> ������������������������������������������MP3Diags-1.0.12.079/src/images/debug.svg������������������������������������������������������������0000644�0001750�0000144�00000370167�11162224611�016341� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg7658" sodipodi:version="0.32" inkscape:version="0.44.1" version="1.0" sodipodi:docbase="/Users/david/Progetti/oxygen-svn/theme/svg/apps" sodipodi:docname="kbugbuster.svg"> <defs id="defs7660"> <radialGradient inkscape:collect="always" xlink:href="#XMLID_104_" id="radialGradient6765" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="57.453342" cy="82.885696" r="145.1954" fx="57.453342" fy="82.885696" /> <radialGradient id="XMLID_105_" cx="9.7201996" cy="48.1143" r="48.695599" fx="18.775499" fy="36.806099" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:white;stop-opacity:1;" id="stop649" /> <stop id="stop4981" style="stop-color:white;stop-opacity:0;" offset="0.27083334" /> <stop id="stop4979" style="stop-color:black;stop-opacity:0;" offset="1" /> </radialGradient> <radialGradient id="XMLID_108_" cx="36.5532" cy="155.7373" r="161.05859" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop696" /> <stop offset="0.2727" style="stop-color:#040404" id="stop698" /> <stop offset="0.5095" style="stop-color:#111111" id="stop700" /> <stop offset="0.7531" style="stop-color:#262626" id="stop702" /> <stop offset="1" style="stop-color:#444444" id="stop704" /> </radialGradient> <linearGradient id="XMLID_107_" gradientUnits="userSpaceOnUse" x1="35.433601" y1="79.257797" x2="51.6982" y2="79.257797"> <stop offset="0" style="stop-color:#ff0606;stop-opacity:0;" id="stop669" /> <stop offset="0.77083331" style="stop-color:#910000;stop-opacity:0.3607595;" id="stop687" /> <stop offset="1" style="stop-color:#000000" id="stop691" /> </linearGradient> <linearGradient id="XMLID_106_" gradientUnits="userSpaceOnUse" x1="49.412102" y1="106.0049" x2="49.412102" y2="98.5186"> <stop offset="0" style="stop-color:black;stop-opacity:0;" id="stop654" /> <stop id="stop4983" style="stop-color:black;stop-opacity:0.49803922;" offset="0.13541667" /> <stop offset="1" style="stop-color:black;stop-opacity:1;" id="stop664" /> </linearGradient> <radialGradient id="XMLID_104_" cx="1.5898" cy="91.173798" r="108.4177" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0393" style="stop-color:#FFFFFF" id="stop600" /> <stop offset="0.4862" style="stop-color:white;stop-opacity:0;" id="stop610" /> <stop offset="0.52810001" style="stop-color:black;stop-opacity:0;" id="stop612" /> <stop offset="0.60049999" style="stop-color:#030303;stop-opacity:0;" id="stop614" /> <stop offset="0.66159999" style="stop-color:#0e0e0e;stop-opacity:0;" id="stop616" /> <stop offset="0.71850002" style="stop-color:#1f1f1f;stop-opacity:0;" id="stop618" /> <stop offset="1" style="stop-color:#FFFFFF" id="stop630" /> </radialGradient> <radialGradient inkscape:collect="always" xlink:href="#XMLID_104_" id="radialGradient7656" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="1.5898" cy="91.173798" r="108.4177" /> <radialGradient id="XMLID_102_" cx="80.555199" cy="-35.5938" r="19.511101" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFA7E" id="stop584" /> <stop offset="1" style="stop-color:#DEA200" id="stop586" /> </radialGradient> <radialGradient id="XMLID_101_" cx="80.555199" cy="-36.084499" r="21.673401" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFA7E" id="stop575" /> <stop offset="0.8202" style="stop-color:#FFE600" id="stop577" /> <stop offset="1" style="stop-color:#DEA200" id="stop579" /> </radialGradient> <radialGradient id="XMLID_100_" cx="1.8848" cy="-36.837898" r="21.6022" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFA7E" id="stop568" /> <stop offset="1" style="stop-color:#BD8A00" id="stop570" /> </radialGradient> <radialGradient id="XMLID_99_" cx="1.8848" cy="-37.862301" r="24.0919" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFA7E" id="stop559" /> <stop offset="0.8202" style="stop-color:#FFE600" id="stop561" /> <stop offset="1" style="stop-color:#DEA200" id="stop563" /> </radialGradient> <radialGradient id="XMLID_98_" cx="36.550301" cy="158.7334" r="165.3475" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop546" /> <stop offset="0.2727" style="stop-color:#040404" id="stop548" /> <stop offset="0.5095" style="stop-color:#111111" id="stop550" /> <stop offset="0.7531" style="stop-color:#262626" id="stop552" /> <stop offset="1" style="stop-color:#444444" id="stop554" /> </radialGradient> <radialGradient id="XMLID_97_" cx="36.557598" cy="158.73441" r="165.3082" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop533" /> <stop offset="0.2727" style="stop-color:#040404" id="stop535" /> <stop offset="0.5095" style="stop-color:#111111" id="stop537" /> <stop offset="0.7531" style="stop-color:#262626" id="stop539" /> <stop offset="1" style="stop-color:#444444" id="stop541" /> </radialGradient> <radialGradient id="XMLID_96_" cx="36.5522" cy="158.7422" r="165.369" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop520" /> <stop offset="0.2727" style="stop-color:#040404" id="stop522" /> <stop offset="0.5095" style="stop-color:#111111" id="stop524" /> <stop offset="0.7531" style="stop-color:#262626" id="stop526" /> <stop offset="1" style="stop-color:#444444" id="stop528" /> </radialGradient> <radialGradient id="XMLID_95_" cx="36.5527" cy="158.7334" r="165.3454" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop507" /> <stop offset="0.2727" style="stop-color:#040404" id="stop509" /> <stop offset="0.5095" style="stop-color:#111111" id="stop511" /> <stop offset="0.7531" style="stop-color:#262626" id="stop513" /> <stop offset="1" style="stop-color:#444444" id="stop515" /> </radialGradient> <radialGradient id="XMLID_94_" cx="36.555698" cy="158.7373" r="165.3446" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop494" /> <stop offset="0.2727" style="stop-color:#040404" id="stop496" /> <stop offset="0.5095" style="stop-color:#111111" id="stop498" /> <stop offset="0.7531" style="stop-color:#262626" id="stop500" /> <stop offset="1" style="stop-color:#444444" id="stop502" /> </radialGradient> <radialGradient id="XMLID_93_" cx="36.556198" cy="158.73441" r="165.334" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop481" /> <stop offset="0.2727" style="stop-color:#040404" id="stop483" /> <stop offset="0.5095" style="stop-color:#111111" id="stop485" /> <stop offset="0.7531" style="stop-color:#262626" id="stop487" /> <stop offset="1" style="stop-color:#444444" id="stop489" /> </radialGradient> <radialGradient id="XMLID_92_" cx="36.5532" cy="158.72951" r="165.3324" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop468" /> <stop offset="0.2727" style="stop-color:#040404" id="stop470" /> <stop offset="0.5095" style="stop-color:#111111" id="stop472" /> <stop offset="0.7531" style="stop-color:#262626" id="stop474" /> <stop offset="1" style="stop-color:#444444" id="stop476" /> </radialGradient> <radialGradient id="XMLID_91_" cx="36.555199" cy="158.74609" r="165.35831" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0506" style="stop-color:#000000" id="stop455" /> <stop offset="0.2727" style="stop-color:#040404" id="stop457" /> <stop offset="0.5095" style="stop-color:#111111" id="stop459" /> <stop offset="0.7531" style="stop-color:#262626" id="stop461" /> <stop offset="1" style="stop-color:#444444" id="stop463" /> </radialGradient> <radialGradient id="XMLID_90_" cx="-76.899498" cy="78.245316" r="22.7651" gradientTransform="matrix(-0.132702,0.248203,0.258208,0.138055,43.36688,66.95719)" gradientUnits="userSpaceOnUse" fx="-76.899498" fy="78.245316"> <stop offset="0" style="stop-color:#000000" id="stop432" /> <stop offset="1" style="stop-color:black;stop-opacity:0;" id="stop448" /> </radialGradient> <radialGradient id="XMLID_89_" cx="-17.5312" cy="53.155411" r="22.7672" gradientTransform="matrix(0.237741,0.127932,-0.190571,0.354161,38.73408,42.72459)" gradientUnits="userSpaceOnUse" fx="-17.5312" fy="53.155411"> <stop offset="0" style="stop-color:#000000" id="stop409" /> <stop offset="1" style="stop-color:#626262;stop-opacity:0;" id="stop427" /> </radialGradient> <linearGradient id="XMLID_88_" gradientUnits="userSpaceOnUse" x1="50.424801" y1="49.349098" x2="50.424801" y2="43.158699"> <stop offset="0" style="stop-color:#FFFA7E" id="stop402" /> <stop offset="1" style="stop-color:#FFF740" id="stop404" /> </linearGradient> <radialGradient id="XMLID_87_" cx="100.8159" cy="-76.519997" r="6.1027999" fx="104.1129" fy="-72.0867" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop393" /> <stop offset="0.309" style="stop-color:#444444" id="stop395" /> <stop offset="0.8876" style="stop-color:#111111" id="stop397" /> </radialGradient> <radialGradient id="XMLID_86_" cx="94.171402" cy="-61.1348" r="8.6471996" fx="91.795998" fy="-52.820202" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop384" /> <stop offset="0.309" style="stop-color:#444444" id="stop386" /> <stop offset="0.8876" style="stop-color:#111111" id="stop388" /> </radialGradient> <radialGradient id="XMLID_85_" cx="83.2202" cy="-27.638201" r="22.666599" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop375" /> <stop offset="0.309" style="stop-color:#444444" id="stop377" /> <stop offset="0.8876" style="stop-color:#111111" id="stop379" /> </radialGradient> <radialGradient id="XMLID_84_" cx="-22.561001" cy="-70.751999" r="9.0004997" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop366" /> <stop offset="0.309" style="stop-color:#444444" id="stop368" /> <stop offset="0.8876" style="stop-color:#111111" id="stop370" /> </radialGradient> <radialGradient id="XMLID_83_" cx="-12.2515" cy="-60.837898" r="8.6471996" fx="-9.4611998" fy="-52.653198" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop357" /> <stop offset="0.309" style="stop-color:#444444" id="stop359" /> <stop offset="0.8876" style="stop-color:#111111" id="stop361" /> </radialGradient> <radialGradient id="XMLID_82_" cx="-34.1143" cy="-21.860399" r="42.539001" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop348" /> <stop offset="0.309" style="stop-color:#444444" id="stop350" /> <stop offset="0.8876" style="stop-color:#111111" id="stop352" /> </radialGradient> <radialGradient id="XMLID_81_" cx="11.7153" cy="-56.350601" r="13.2925" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop335" /> <stop offset="0.1635" style="stop-color:#BA7878" id="stop337" /> <stop offset="0.2753" style="stop-color:#8D2222" id="stop339" /> <stop offset="0.3258" style="stop-color:#7C0000" id="stop341" /> <stop offset="1" style="stop-color:#600000" id="stop343" /> </radialGradient> <radialGradient id="XMLID_80_" cx="50.997101" cy="-36.084" r="11.1695" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop322" /> <stop offset="0.0556" style="stop-color:#CCCCCC" id="stop324" /> <stop offset="0.1524" style="stop-color:#777777" id="stop326" /> <stop offset="0.1966" style="stop-color:#555555" id="stop328" /> <stop offset="1" style="stop-color:#000000" id="stop330" /> </radialGradient> <radialGradient id="XMLID_79_" cx="30.774401" cy="-32.5298" r="15.8458" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop309" /> <stop offset="0.0762" style="stop-color:#CCCCCC" id="stop311" /> <stop offset="0.2091" style="stop-color:#777777" id="stop313" /> <stop offset="0.2697" style="stop-color:#555555" id="stop315" /> <stop offset="1" style="stop-color:#000000" id="stop317" /> </radialGradient> <radialGradient id="XMLID_78_" cx="-35.521999" cy="131.7178" r="19.2798" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#494949" id="stop300" /> <stop offset="0.309" style="stop-color:#222222" id="stop302" /> <stop offset="0.8876" style="stop-color:#111111" id="stop304" /> </radialGradient> <radialGradient id="XMLID_77_" cx="-58.267101" cy="141.5488" r="33.4053" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop291" /> <stop offset="0.309" style="stop-color:#444444" id="stop293" /> <stop offset="0.8876" style="stop-color:#111111" id="stop295" /> </radialGradient> <radialGradient id="XMLID_76_" cx="145.59621" cy="154.58791" r="36.692799" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop282" /> <stop offset="0.309" style="stop-color:#444444" id="stop284" /> <stop offset="0.8876" style="stop-color:#111111" id="stop286" /> </radialGradient> <radialGradient id="XMLID_75_" cx="126.0396" cy="164.0674" r="69.160103" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#494949" id="stop273" /> <stop offset="0.309" style="stop-color:#222222" id="stop275" /> <stop offset="0.8876" style="stop-color:#111111" id="stop277" /> </radialGradient> <linearGradient id="XMLID_74_" gradientUnits="userSpaceOnUse" x1="50.508301" y1="43.935101" x2="50.508301" y2="38.158699"> <stop offset="0" style="stop-color:#474747" id="stop266" /> <stop offset="1" style="stop-color:#000000" id="stop268" /> </linearGradient> <radialGradient id="XMLID_73_" cx="28.556601" cy="-13.4165" r="39.595501" fx="26.7798" fy="-10.7512" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0112" style="stop-color:#FFFFFF" id="stop257" /> <stop offset="0.3146" style="stop-color:#222222" id="stop259" /> <stop offset="1" style="stop-color:#000000" id="stop261" /> </radialGradient> <radialGradient id="XMLID_72_" cx="48.8979" cy="-22.6245" r="18.8305" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop244" /> <stop offset="0.0921" style="stop-color:#CCCCCC" id="stop246" /> <stop offset="0.2526" style="stop-color:#777777" id="stop248" /> <stop offset="0.3258" style="stop-color:#555555" id="stop250" /> <stop offset="1" style="stop-color:#000000" id="stop252" /> </radialGradient> <radialGradient id="XMLID_71_" cx="27.0278" cy="-28.074699" r="12.7562" fx="32.151699" fy="-24.978901" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop231" /> <stop offset="0.0921" style="stop-color:#CCCCCC" id="stop233" /> <stop offset="0.2526" style="stop-color:#777777" id="stop235" /> <stop offset="0.3258" style="stop-color:#555555" id="stop237" /> <stop offset="1" style="stop-color:#000000" id="stop239" /> </radialGradient> <radialGradient id="XMLID_70_" cx="53.378399" cy="-35.2603" r="5.3807001" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFF740" id="stop222" /> <stop offset="0.7584" style="stop-color:#F0C000" id="stop224" /> <stop offset="1" style="stop-color:#BD8A00" id="stop226" /> </radialGradient> <radialGradient id="XMLID_69_" cx="17.292999" cy="-34.751499" r="22.371" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFF740" id="stop213" /> <stop offset="0.7584" style="stop-color:#DEA200" id="stop215" /> <stop offset="1" style="stop-color:#BD8A00" id="stop217" /> </radialGradient> <radialGradient id="XMLID_68_" cx="40.101601" cy="14.7876" r="84.2295" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.1236" style="stop-color:#FA746B" id="stop200" /> <stop offset="0.2416" style="stop-color:#FB3A3C" id="stop202" /> <stop offset="0.3596" style="stop-color:#FF0000" id="stop204" /> <stop offset="0.6685" style="stop-color:#C70010" id="stop206" /> <stop offset="0.9438" style="stop-color:#910018" id="stop208" /> </radialGradient> <linearGradient id="XMLID_67_" gradientUnits="userSpaceOnUse" x1="50.508301" y1="70.394501" x2="50.508301" y2="114.999"> <stop offset="0" style="stop-color:#FA746B" id="stop191" /> <stop offset="0.5674" style="stop-color:#910018" id="stop193" /> <stop offset="1" style="stop-color:#220000" id="stop195" /> </linearGradient> <radialGradient id="XMLID_66_" cx="40.101601" cy="43.173801" r="130.98061" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FA746B" id="stop174" /> <stop offset="0.1629" style="stop-color:#FB3A3C" id="stop176" /> <stop offset="0.309" style="stop-color:#EE0000" id="stop178" /> <stop offset="0.4245" style="stop-color:#E10000" id="stop180" /> <stop offset="0.5337" style="stop-color:#DD0000" id="stop182" /> <stop offset="0.7697" style="stop-color:#770000" id="stop184" /> <stop offset="0.9888" style="stop-color:#440000" id="stop186" /> </radialGradient> <linearGradient id="XMLID_65_" gradientUnits="userSpaceOnUse" x1="50.507801" y1="5.8593998" x2="50.507801" y2="38.317501"> <stop offset="0" style="stop-color:#FFFFFF" id="stop149" /> <stop offset="0.0176" style="stop-color:#F0F0F0" id="stop151" /> <stop offset="0.0817" style="stop-color:#BEBEBE" id="stop153" /> <stop offset="0.1506" style="stop-color:#919191" id="stop155" /> <stop offset="0.2229" style="stop-color:#6A6A6A" id="stop157" /> <stop offset="0.2992" style="stop-color:#494949" id="stop159" /> <stop offset="0.3808" style="stop-color:#2E2E2E" id="stop161" /> <stop offset="0.4697" style="stop-color:#1A1A1A" id="stop163" /> <stop offset="0.5695" style="stop-color:#0B0B0B" id="stop165" /> <stop offset="0.6892" style="stop-color:#030303" id="stop167" /> <stop offset="0.882" style="stop-color:#000000" id="stop169" /> </linearGradient> <radialGradient id="XMLID_64_" cx="67.939003" cy="-55.795898" r="13.2393" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop136" /> <stop offset="0.1635" style="stop-color:#BA7878" id="stop138" /> <stop offset="0.2753" style="stop-color:#8D2222" id="stop140" /> <stop offset="0.3258" style="stop-color:#7C0000" id="stop142" /> <stop offset="1" style="stop-color:#600000" id="stop144" /> </radialGradient> <radialGradient id="XMLID_63_" cx="89.190903" cy="-11.6396" r="5.9789" fx="85.496696" fy="-16.340799" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop127" /> <stop offset="0.309" style="stop-color:#444444" id="stop129" /> <stop offset="0.6854" style="stop-color:#111111" id="stop131" /> </radialGradient> <radialGradient id="XMLID_62_" cx="-7.27" cy="-11.3428" r="5.9793" fx="-4.6608" fy="-16.722799" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop118" /> <stop offset="0.309" style="stop-color:#444444" id="stop120" /> <stop offset="0.6236" style="stop-color:#111111" id="stop122" /> </radialGradient> <radialGradient id="XMLID_61_" cx="47.221199" cy="-21.4165" r="23.8853" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop105" /> <stop offset="0.1667" style="stop-color:#CCCCCC" id="stop107" /> <stop offset="0.4573" style="stop-color:#777777" id="stop109" /> <stop offset="0.5899" style="stop-color:#555555" id="stop111" /> <stop offset="1" style="stop-color:#000000" id="stop113" /> </radialGradient> <radialGradient id="XMLID_60_" cx="27.2197" cy="-28.824699" r="17.7062" fx="34.331902" fy="-24.527599" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF" id="stop92" /> <stop offset="0.1667" style="stop-color:#CCCCCC" id="stop94" /> <stop offset="0.4573" style="stop-color:#777777" id="stop96" /> <stop offset="0.5899" style="stop-color:#555555" id="stop98" /> <stop offset="1" style="stop-color:#000000" id="stop100" /> </radialGradient> <radialGradient id="XMLID_59_" cx="-55.985802" cy="44.3311" r="9.8990002" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#494949" id="stop83" /> <stop offset="0.309" style="stop-color:#222222" id="stop85" /> <stop offset="0.8876" style="stop-color:#111111" id="stop87" /> </radialGradient> <radialGradient id="XMLID_58_" cx="-24.189899" cy="39.027302" r="22.420799" fx="-21.2267" fy="23.0264" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#494949" id="stop74" /> <stop offset="0.309" style="stop-color:#222222" id="stop76" /> <stop offset="0.8876" style="stop-color:#111111" id="stop78" /> </radialGradient> <radialGradient id="XMLID_57_" cx="-40.504398" cy="32.028301" r="8.1883001" fx="-33.486801" fy="27.809099" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#AAAAAA" id="stop65" /> <stop offset="0.309" style="stop-color:#444444" id="stop67" /> <stop offset="0.8876" style="stop-color:#111111" id="stop69" /> </radialGradient> <radialGradient id="XMLID_56_" cx="100.5571" cy="33.695301" r="27.628901" fx="101.446" fy="19.0292" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0.0169" style="stop-color:#494949" id="stop56" /> <stop offset="0.309" style="stop-color:#222222" id="stop58" /> <stop offset="0.8876" style="stop-color:#111111" id="stop60" /> </radialGradient> <radialGradient id="XMLID_55_" cx="118.7778" cy="28.805201" r="44.627998" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#444444" id="stop49" /> <stop offset="0.8876" style="stop-color:#111111" id="stop51" /> </radialGradient> <radialGradient inkscape:collect="always" xlink:href="#XMLID_55_" id="radialGradient8565" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="118.7778" cy="28.805201" r="44.627998" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_56_" id="radialGradient8567" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="100.5571" cy="33.695301" fx="101.446" fy="19.0292" r="27.628901" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_57_" id="radialGradient8569" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-40.504398" cy="32.028301" fx="-33.486801" fy="27.809099" r="8.1883001" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_58_" id="radialGradient8571" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-24.189899" cy="39.027302" fx="-21.2267" fy="23.0264" r="22.420799" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_59_" id="radialGradient8573" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-55.985802" cy="44.3311" r="9.8990002" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_60_" id="radialGradient8575" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="27.2197" cy="-28.824699" fx="34.331902" fy="-24.527599" r="17.7062" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_61_" id="radialGradient8577" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="47.221199" cy="-21.4165" r="23.8853" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_62_" id="radialGradient8579" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-7.27" cy="-11.3428" fx="-4.6608" fy="-16.722799" r="5.9793" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_63_" id="radialGradient8581" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="89.190903" cy="-11.6396" fx="85.496696" fy="-16.340799" r="5.9789" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_64_" id="radialGradient8583" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="67.939003" cy="-55.795898" r="13.2393" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_65_" id="linearGradient8585" gradientUnits="userSpaceOnUse" x1="50.507801" y1="5.8593998" x2="50.507801" y2="38.317501" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_66_" id="radialGradient8587" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="40.101601" cy="43.173801" r="130.98061" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_67_" id="linearGradient8589" gradientUnits="userSpaceOnUse" x1="50.508301" y1="70.394501" x2="50.508301" y2="114.999" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_68_" id="radialGradient8591" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="40.101601" cy="14.7876" r="84.2295" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_69_" id="radialGradient8593" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="17.292999" cy="-34.751499" r="22.371" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_70_" id="radialGradient8595" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="53.378399" cy="-35.2603" r="5.3807001" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_71_" id="radialGradient8597" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="27.0278" cy="-28.074699" fx="32.151699" fy="-24.978901" r="12.7562" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_72_" id="radialGradient8599" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="48.8979" cy="-22.6245" r="18.8305" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_73_" id="radialGradient8601" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="28.556601" cy="-13.4165" fx="26.7798" fy="-10.7512" r="39.595501" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_74_" id="linearGradient8603" gradientUnits="userSpaceOnUse" x1="50.508301" y1="43.935101" x2="50.508301" y2="38.158699" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_75_" id="radialGradient8605" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="126.0396" cy="164.0674" r="69.160103" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_76_" id="radialGradient8607" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="145.59621" cy="154.58791" r="36.692799" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_77_" id="radialGradient8609" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-58.267101" cy="141.5488" r="33.4053" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_78_" id="radialGradient8611" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-35.521999" cy="131.7178" r="19.2798" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_79_" id="radialGradient8613" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="30.774401" cy="-32.5298" r="15.8458" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_80_" id="radialGradient8615" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="50.997101" cy="-36.084" r="11.1695" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_81_" id="radialGradient8617" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="11.7153" cy="-56.350601" r="13.2925" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_82_" id="radialGradient8619" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-34.1143" cy="-21.860399" r="42.539001" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_83_" id="radialGradient8621" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-12.2515" cy="-60.837898" fx="-9.4611998" fy="-52.653198" r="8.6471996" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_84_" id="radialGradient8623" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="-22.561001" cy="-70.751999" r="9.0004997" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_85_" id="radialGradient8625" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="83.2202" cy="-27.638201" r="22.666599" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_86_" id="radialGradient8627" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="94.171402" cy="-61.1348" fx="91.795998" fy="-52.820202" r="8.6471996" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_87_" id="radialGradient8629" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="100.8159" cy="-76.519997" fx="104.1129" fy="-72.0867" r="6.1027999" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_88_" id="linearGradient8631" gradientUnits="userSpaceOnUse" x1="50.424801" y1="49.349098" x2="50.424801" y2="43.158699" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_89_" id="radialGradient8633" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.237741,0.127932,-0.190571,0.354161,38.73408,42.72459)" cx="-17.5312" cy="53.155411" fx="-17.5312" fy="53.155411" r="22.7672" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_90_" id="radialGradient8635" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.132702,0.248203,0.258208,0.138055,43.36688,66.95719)" cx="-76.899498" cy="78.245316" fx="-76.899498" fy="78.245316" r="22.7651" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_91_" id="radialGradient8637" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.555199" cy="158.74609" r="165.35831" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_92_" id="radialGradient8639" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.5532" cy="158.72951" r="165.3324" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_93_" id="radialGradient8641" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.556198" cy="158.73441" r="165.334" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_94_" id="radialGradient8643" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.555698" cy="158.7373" r="165.3446" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_95_" id="radialGradient8645" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.5527" cy="158.7334" r="165.3454" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_96_" id="radialGradient8647" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.5522" cy="158.7422" r="165.369" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_97_" id="radialGradient8649" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.557598" cy="158.73441" r="165.3082" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_98_" id="radialGradient8651" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.550301" cy="158.7334" r="165.3475" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_99_" id="radialGradient8653" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="1.8848" cy="-37.862301" r="24.0919" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_100_" id="radialGradient8655" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="1.8848" cy="-36.837898" r="21.6022" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_101_" id="radialGradient8657" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="80.555199" cy="-36.084499" r="21.673401" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_102_" id="radialGradient8659" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="80.555199" cy="-35.5938" r="19.511101" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_104_" id="radialGradient8661" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="1.5898" cy="91.173798" r="108.4177" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_106_" id="linearGradient8663" gradientUnits="userSpaceOnUse" x1="49.412102" y1="106.0049" x2="49.412102" y2="98.5186" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_107_" id="linearGradient8665" gradientUnits="userSpaceOnUse" x1="35.433601" y1="79.257797" x2="51.6982" y2="79.257797" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_108_" id="radialGradient8667" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="36.5532" cy="155.7373" r="161.05859" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_105_" id="radialGradient8669" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="9.7201996" cy="48.1143" fx="18.775499" fy="36.806099" r="48.695599" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_104_" id="radialGradient8671" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.4279,0,0,0.4279,32.8183,38.6081)" cx="57.453342" cy="82.885696" fx="57.453342" fy="82.885696" r="145.1954" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_104_" id="radialGradient8674" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="57.453342" cy="82.885696" fx="57.453342" fy="82.885696" r="145.1954" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_108_" id="radialGradient8682" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.5532" cy="155.7373" r="161.05859" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_107_" id="linearGradient8685" gradientUnits="userSpaceOnUse" x1="35.433601" y1="79.257797" x2="51.6982" y2="79.257797" gradientTransform="matrix(1.000022,0,0,1.000022,13.30156,4.003145)" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_106_" id="linearGradient8688" gradientUnits="userSpaceOnUse" x1="49.412102" y1="106.0049" x2="49.412102" y2="98.5186" gradientTransform="matrix(1.000022,0,0,1.000022,13.30156,4.003145)" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_104_" id="radialGradient8691" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="1.5898" cy="91.173798" r="108.4177" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_102_" id="radialGradient8694" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="80.555199" cy="-35.5938" r="19.511101" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_101_" id="radialGradient8697" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="80.555199" cy="-36.084499" r="21.673401" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_100_" id="radialGradient8700" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="1.8848" cy="-36.837898" r="21.6022" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_99_" id="radialGradient8703" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="1.8848" cy="-37.862301" r="24.0919" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_98_" id="radialGradient8706" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.550301" cy="158.7334" r="165.3475" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_97_" id="radialGradient8709" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.557598" cy="158.73441" r="165.3082" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_96_" id="radialGradient8712" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.5522" cy="158.7422" r="165.369" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_95_" id="radialGradient8715" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.5527" cy="158.7334" r="165.3454" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_94_" id="radialGradient8718" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.555698" cy="158.7373" r="165.3446" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_93_" id="radialGradient8721" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.556198" cy="158.73441" r="165.334" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_92_" id="radialGradient8724" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.5532" cy="158.72951" r="165.3324" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_91_" id="radialGradient8727" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="36.555199" cy="158.74609" r="165.35831" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_90_" id="radialGradient8730" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.132705,0.248208,0.258214,0.138058,56.66939,70.96181)" cx="-76.899498" cy="78.245316" fx="-76.899498" fy="78.245316" r="22.7651" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_89_" id="radialGradient8733" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.237746,0.127935,-0.190575,0.354169,52.03649,46.72867)" cx="-17.5312" cy="53.155411" fx="-17.5312" fy="53.155411" r="22.7672" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_88_" id="linearGradient8736" gradientUnits="userSpaceOnUse" x1="50.424801" y1="49.349098" x2="50.424801" y2="43.158699" gradientTransform="matrix(1.000022,0,0,1.000022,13.30156,4.003145)" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_87_" id="radialGradient8739" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="100.8159" cy="-76.519997" fx="104.1129" fy="-72.0867" r="6.1027999" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_86_" id="radialGradient8742" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="94.171402" cy="-61.1348" fx="91.795998" fy="-52.820202" r="8.6471996" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_85_" id="radialGradient8745" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="83.2202" cy="-27.638201" r="22.666599" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_84_" id="radialGradient8748" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-22.561001" cy="-70.751999" r="9.0004997" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_83_" id="radialGradient8751" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-12.2515" cy="-60.837898" fx="-9.4611998" fy="-52.653198" r="8.6471996" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_82_" id="radialGradient8754" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-34.1143" cy="-21.860399" r="42.539001" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_81_" id="radialGradient8757" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="11.7153" cy="-56.350601" r="13.2925" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_80_" id="radialGradient8760" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="50.997101" cy="-36.084" r="11.1695" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_79_" id="radialGradient8763" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="30.774401" cy="-32.5298" r="15.8458" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_78_" id="radialGradient8766" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-35.521999" cy="131.7178" r="19.2798" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_77_" id="radialGradient8769" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-58.267101" cy="141.5488" r="33.4053" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_76_" id="radialGradient8772" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="145.59621" cy="154.58791" r="36.692799" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_75_" id="radialGradient8775" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="126.0396" cy="164.0674" r="69.160103" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_74_" id="linearGradient8778" gradientUnits="userSpaceOnUse" x1="50.508301" y1="43.935101" x2="50.508301" y2="38.158699" gradientTransform="matrix(1.000022,0,0,1.000022,13.30156,4.003145)" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_73_" id="radialGradient8781" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="28.556601" cy="-13.4165" fx="26.7798" fy="-10.7512" r="39.595501" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_72_" id="radialGradient8784" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="48.8979" cy="-22.6245" r="18.8305" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_71_" id="radialGradient8787" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="27.0278" cy="-28.074699" fx="32.151699" fy="-24.978901" r="12.7562" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_70_" id="radialGradient8790" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="53.378399" cy="-35.2603" r="5.3807001" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_69_" id="radialGradient8793" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="17.292999" cy="-34.751499" r="22.371" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_68_" id="radialGradient8796" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="40.101601" cy="14.7876" r="84.2295" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_67_" id="linearGradient8799" gradientUnits="userSpaceOnUse" x1="50.508301" y1="70.394501" x2="50.508301" y2="114.999" gradientTransform="matrix(1.000022,0,0,1.000022,13.30156,4.003145)" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_66_" id="radialGradient8802" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="40.101601" cy="43.173801" r="130.98061" /> <linearGradient inkscape:collect="always" xlink:href="#XMLID_65_" id="linearGradient8805" gradientUnits="userSpaceOnUse" x1="50.507801" y1="5.8593998" x2="50.507801" y2="38.317501" gradientTransform="matrix(1.000022,0,0,1.000022,13.30156,4.003145)" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_64_" id="radialGradient8808" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="67.939003" cy="-55.795898" r="13.2393" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_63_" id="radialGradient8811" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="89.190903" cy="-11.6396" fx="85.496696" fy="-16.340799" r="5.9789" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_62_" id="radialGradient8814" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-7.27" cy="-11.3428" fx="-4.6608" fy="-16.722799" r="5.9793" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_61_" id="radialGradient8817" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="47.221199" cy="-21.4165" r="23.8853" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_60_" id="radialGradient8820" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="27.2197" cy="-28.824699" fx="34.331902" fy="-24.527599" r="17.7062" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_59_" id="radialGradient8823" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-55.985802" cy="44.3311" r="9.8990002" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_58_" id="radialGradient8826" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-24.189899" cy="39.027302" fx="-21.2267" fy="23.0264" r="22.420799" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_57_" id="radialGradient8829" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="-40.504398" cy="32.028301" fx="-33.486801" fy="27.809099" r="8.1883001" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_56_" id="radialGradient8832" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="100.5571" cy="33.695301" fx="101.446" fy="19.0292" r="27.628901" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_55_" id="radialGradient8835" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427909,0,0,0.427909,46.12058,42.61209)" cx="118.7778" cy="28.805201" r="44.627998" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="64" inkscape:cy="34" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" inkscape:window-width="823" inkscape:window-height="577" inkscape:window-x="454" inkscape:window-y="355" /> <metadata id="metadata7663"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <path d="M 27.939882,109.04546 L 27.813879,109.22346 C 27.813879,109.22346 27.82688,109.20846 27.84488,109.18646 C 27.84688,109.18246 27.84688,109.18246 27.84988,109.17946 C 27.871881,109.15146 27.901881,109.10946 27.939882,109.04546 L 27.932882,109.05646 C 27.934882,109.05146 27.936882,109.05046 27.939882,109.04546 z " id="path20" style="opacity:0.05;fill:none;stroke:black;stroke-width:8.00017643;stroke-linejoin:round" /> <path d="M 27.939882,109.04546 L 27.813879,109.22346 C 27.813879,109.22346 27.82688,109.20846 27.84488,109.18646 C 27.84688,109.18246 27.84688,109.18246 27.84988,109.17946 C 27.871881,109.15146 27.901881,109.10946 27.939882,109.04546 L 27.932882,109.05646 C 27.934882,109.05146 27.936882,109.05046 27.939882,109.04546 z " id="path28" style="opacity:0.1;fill:none;stroke:black;stroke-width:6.00013208;stroke-linejoin:round" /> <path d="M 109.92669,61.454409 C 109.92669,61.454409 110.31669,63.134446 109.18267,62.721437 C 109.18267,62.721437 102.25352,56.662303 97.222406,57.536323 L 97.622415,58.820351 C 97.622415,58.820351 100.70348,60.860396 102.03451,60.622391 C 102.03451,60.622391 102.86753,61.144402 102.86753,61.620413 C 102.86753,62.096423 105.69559,63.071444 106.57561,62.524432 C 106.57561,62.524432 108.26365,62.810439 108.26365,64.283471 C 108.26365,64.283471 107.07462,64.996487 106.43361,64.616478 C 106.43361,64.616478 107.70564,66.649523 110.21269,64.140468 C 111.46072,62.891441 109.92669,61.454409 109.92669,61.454409 z " id="path34" style="opacity:0.1;fill:none;stroke:black;stroke-width:4.00008821;stroke-linejoin:round" /> <path d="M 27.939882,109.04546 L 27.813879,109.22346 C 27.813879,109.22346 27.82688,109.20846 27.84488,109.18646 C 27.84688,109.18246 27.84688,109.18246 27.84988,109.17946 C 27.871881,109.15146 27.901881,109.10946 27.939882,109.04546 L 27.932882,109.05646 C 27.934882,109.05146 27.936882,109.05046 27.939882,109.04546 z " id="path36" style="opacity:0.1;fill:none;stroke:black;stroke-width:4.00008821;stroke-linejoin:round" /> <g id="g8849" transform="translate(0,1.000041)"> <path style="opacity:0.1;fill:none;stroke:black;stroke-width:4.00008821;stroke-linejoin:round" id="path32" d="M 107.97764,116.44766 C 107.97764,116.44766 104.39856,110.23053 98.326431,107.56947 L 98.226428,107.59147 C 98.449433,107.54047 98.594436,107.50647 98.594436,107.50647 C 101.2585,96.476223 94.462345,87.470025 94.462345,87.470025 L 94.450345,87.507026 C 95.388366,83.836945 95.971379,79.994861 96.136382,76.076775 C 96.148383,75.803769 96.147383,75.537763 96.154383,75.265757 C 96.156383,75.300758 96.159383,75.333758 96.160383,75.368759 C 96.166383,75.164755 96.162383,74.96775 96.166383,74.764746 C 96.174383,74.354737 96.181383,73.945728 96.180383,73.540719 C 96.179383,73.493718 96.182383,73.444717 96.182383,73.396716 C 96.182383,73.435716 96.179383,73.475717 96.179383,73.514718 C 96.179383,73.500718 96.178383,73.487718 96.178383,73.473717 C 96.177383,73.186711 96.168383,72.904705 96.162383,72.619699 C 96.152383,72.191689 96.142382,71.76568 96.122382,71.34367 C 96.109382,71.070664 96.091381,70.799658 96.073381,70.528653 C 96.04738,70.104643 96.01838,69.681634 95.981379,69.264625 C 95.958378,69.003619 95.928378,68.746613 95.901377,68.489608 C 95.857376,68.070598 95.811375,67.652589 95.756374,67.24158 C 95.723373,66.989575 95.684372,66.742569 95.646372,66.494564 C 95.58537,66.084555 95.523369,65.675546 95.451367,65.272537 C 95.408366,65.031532 95.359365,64.793526 95.313364,64.555521 C 95.234362,64.153512 95.155361,63.750503 95.066359,63.355495 C 95.014358,63.12549 94.957356,62.899485 94.901355,62.67048 C 94.806353,62.277471 94.711351,61.885462 94.605349,61.499454 C 94.543347,61.275449 94.476346,61.057444 94.412344,60.835439 C 94.301342,60.454431 94.189339,60.073423 94.068337,59.700414 C 93.999335,59.48441 93.922334,59.273405 93.849332,59.0604 C 93.722329,58.690392 93.595326,58.321384 93.458323,57.958376 C 93.379322,57.750371 93.29532,57.548367 93.213318,57.343362 C 93.071315,56.986355 92.929312,56.628347 92.777308,56.279339 C 92.689306,56.078335 92.596304,55.88233 92.506302,55.683326 C 92.350299,55.339318 92.194296,54.996311 92.027292,54.661303 C 91.93129,54.466299 91.829288,54.276295 91.729285,54.084291 C 91.559282,53.755284 91.389278,53.425276 91.210274,53.105269 C 91.105272,52.917265 90.994269,52.734261 90.886267,52.549257 C 90.713263,52.25325 90.543259,51.955244 90.363255,51.666238 L 90.371255,51.672238 C 92.988313,52.768262 94.283342,55.585324 95.10836,56.408342 C 95.931378,57.23236 97.769418,57.296361 97.769418,57.296361 L 96.564392,53.429276 L 94.473346,51.33723 C 91.05027,45.504102 84.717131,44.876088 84.717131,44.876088 L 84.720131,44.887088 C 84.65113,44.824087 84.578128,44.764086 84.508127,44.701084 C 84.286122,44.50408 84.067117,44.302076 83.840112,44.111071 C 85.208142,43.545059 86.066161,42.871044 86.066161,42.069026 C 86.066161,41.79502 86.04016,41.508014 85.999159,41.216008 C 85.996159,41.197007 85.997159,41.180007 85.994159,41.161006 C 85.993159,41.163006 85.991159,41.166007 85.990159,41.168007 C 85.880157,40.42499 85.646152,39.627973 85.300144,38.792954 C 85.542149,38.103939 85.934158,37.166919 86.327167,37.009915 C 86.559172,36.916913 86.363167,36.445903 85.967159,35.88889 L 86.121162,36.026894 L 86.121162,35.88389 C 86.121162,35.88389 86.216164,35.502882 87.072183,35.502882 C 87.926202,35.502882 88.070205,25.946672 85.930158,20.573554 C 85.930158,20.573554 85.59215,19.917539 84.773132,19.869538 L 85.170141,19.812537 C 85.59815,18.053498 86.880179,15.533443 88.260209,13.821405 C 89.073227,12.812383 89.115228,12.073367 88.817221,11.584356 C 89.050226,10.917341 90.256253,7.5452669 90.256253,7.5452669 C 90.779264,7.3552627 91.588282,8.163281 91.588282,8.163281 C 89.400234,3.9321874 86.92918,7.2122596 86.92918,7.2122596 C 87.546193,7.1172575 88.164207,6.7372491 88.592216,7.3072617 C 89.020226,7.8782743 87.8312,10.921341 87.8312,10.921341 C 86.833178,10.683336 85.739154,12.157368 85.739154,12.157368 C 84.420125,14.06841 83.885113,19.49353 83.842112,19.95654 C 83.085095,20.126544 82.37608,20.563553 82.41208,21.665578 C 82.459081,23.13961 81.983071,24.376637 81.983071,24.376637 L 85.406146,30.937782 C 85.406146,30.937782 85.406146,33.267833 85.643151,33.932847 C 85.814155,34.409858 85.304144,34.663864 84.999137,34.771866 C 84.395124,34.184853 83.731109,33.710843 83.2821,33.710843 L 82.648086,34.217854 L 82.624085,34.265855 C 82.569084,34.192853 82.511083,34.119852 82.455081,34.04585 C 82.259077,33.788844 82.059073,33.531839 81.852068,33.275833 C 81.760066,33.16283 81.665064,33.050828 81.572062,32.937826 C 81.388058,32.717821 81.203054,32.497816 81.01105,32.278811 C 80.902047,32.152808 80.790045,32.028806 80.678042,31.903803 C 80.492038,31.697798 80.305034,31.492794 80.11403,31.288789 C 79.994027,31.160786 79.873025,31.032784 79.750022,30.904781 C 79.556018,30.702776 79.358013,30.503772 79.158009,30.305768 C 79.034006,30.181765 78.911003,30.057762 78.784001,29.93576 C 78.566996,29.725755 78.345991,29.51975 78.122986,29.313746 C 78.009984,29.208744 77.897981,29.101741 77.782979,28.997739 C 77.444971,28.691732 77.100964,28.390726 76.752956,28.096719 C 76.381948,28.310724 75.985939,28.514728 75.57093,28.709733 C 75.392926,28.792734 75.198922,28.867736 75.012918,28.947738 C 74.769912,29.05174 74.531907,29.158742 74.275901,29.256745 C 74.254901,29.264745 74.2299,29.271745 74.2089,29.279745 L 74.487906,29.006739 C 74.487906,29.006739 73.425883,27.626709 75.073919,24.709645 C 76.325947,22.496596 72.613865,23.716623 70.750824,25.264657 C 70.749824,25.264657 70.749824,25.263657 70.748824,25.263657 C 70.746824,25.264657 70.745824,25.266657 70.743824,25.267657 C 70.343815,24.927649 69.935806,24.601642 69.517797,24.305636 C 69.513797,24.302636 69.509797,24.299636 69.505796,24.296635 L 69.504796,24.296635 C 69.490796,24.286635 69.476796,24.277635 69.461795,24.267635 L 69.505796,24.295635 C 69.505796,23.469617 71.252835,23.805625 70.538819,23.091609 C 70.407816,22.961606 70.280814,22.833603 70.155811,22.708601 C 70.729823,21.364571 73.218878,20.935562 76.307946,19.699534 C 79.635019,18.368505 80.778044,15.230436 81.157053,14.089411 C 81.538061,12.948386 79.256011,11.33235 79.065007,13.519398 C 78.876003,15.706446 77.732977,17.70349 75.926938,18.749513 C 73.163877,19.806537 70.201812,21.481574 69.395794,21.949584 C 69.239791,21.79358 69.143789,21.697578 69.143789,21.697578 L 68.699779,21.697578 C 69.143789,22.141588 68.255769,23.486618 68.255769,23.486618 L 68.401772,23.58062 C 66.737736,22.583598 65.074699,21.982585 63.807671,21.982585 C 62.473642,21.982585 60.698603,22.641599 58.946564,23.736623 L 58.951564,23.733623 C 58.951564,23.733623 58.334551,22.173589 58.334551,21.127566 L 56.792517,21.589576 C 55.826496,21.034564 53.014434,19.467529 50.390376,18.464507 C 48.583336,17.418484 47.443311,15.42144 47.252307,13.234392 C 47.062303,11.047344 44.780253,12.66338 45.160261,13.804405 C 45.540269,14.94643 46.681294,18.083499 50.010368,19.414528 C 52.978433,20.602554 55.679492,21.110565 56.433509,22.352593 L 56.433509,23.312614 C 56.433509,23.312614 57.708537,23.674622 57.708537,24.587642 L 57.823539,24.50864 C 57.711537,24.591642 57.601535,24.675644 57.490532,24.761646 L 57.487532,24.757646 L 57.456531,24.787646 C 57.185525,24.998651 56.92152,25.218656 56.661514,25.447661 C 56.660514,25.446661 56.658514,25.444661 56.657514,25.443661 C 56.656514,25.444661 56.655514,25.445661 56.653514,25.447661 C 54.879475,23.816625 50.822385,22.406594 52.122414,24.707644 C 53.697449,27.494706 52.799429,28.874736 52.716427,28.992739 C 52.690427,28.981739 52.663426,28.970738 52.636425,28.959738 C 52.438421,28.875736 52.231416,28.794734 52.041412,28.706732 C 51.627403,28.512728 51.232394,28.309724 50.862386,28.095719 C 50.282374,28.58473 49.717361,29.093741 49.168349,29.613752 C 49.130348,29.650753 49.090347,29.685754 49.052346,29.721755 C 48.529335,30.220766 48.026324,30.730777 47.539313,31.248788 C 47.482312,31.30979 47.424311,31.369791 47.367309,31.430792 C 46.898299,31.935804 46.451289,32.446815 46.02528,32.961826 C 45.963279,33.035828 45.901277,33.109829 45.840276,33.183831 C 45.460267,33.649841 45.10026,34.117852 44.760252,34.583862 L 44.641249,34.344857 L 44.007236,33.837845 C 43.558226,33.837845 42.893211,34.310856 42.290198,34.898869 C 41.985191,34.790866 41.47518,34.536861 41.645184,34.05985 C 41.883189,33.393836 41.883189,31.063784 41.883189,31.063784 L 45.306264,24.50164 C 45.306264,24.50164 44.830254,23.265613 44.879255,21.79158 C 44.914255,20.689556 44.20524,20.252546 43.448223,20.082543 C 43.405222,19.620533 42.87021,14.194413 41.551181,12.282371 C 41.551181,12.282371 40.457157,10.808339 39.458135,11.046344 C 39.458135,11.046344 38.270109,8.003277 38.697119,7.4322644 C 39.126128,6.8622519 39.744142,7.2422603 40.362155,7.3372623 C 40.362155,7.3372623 37.889101,4.0571902 35.702053,8.288283 C 35.702053,8.288283 36.510071,7.4802655 37.033082,7.6702697 C 37.033082,7.6702697 38.240109,11.040344 38.473114,11.708359 C 38.174107,12.198369 38.216108,12.936386 39.029126,13.946408 C 40.408156,15.658445 41.692185,18.178501 42.120194,19.93754 L 42.517203,19.994541 C 41.697185,20.042542 41.359177,20.698556 41.359177,20.698556 C 39.22013,26.071674 39.362133,35.627885 40.218152,35.627885 C 41.074171,35.627885 41.169173,36.008893 41.169173,36.008893 L 41.169173,36.150896 L 41.323176,36.013893 C 40.927168,36.570905 40.730163,37.039916 40.963169,37.133918 C 41.438179,37.323922 41.912189,38.649951 42.120194,39.304966 C 41.882189,39.95198 41.713185,40.575994 41.626183,41.164007 C 41.626183,41.162006 41.624183,41.161006 41.623183,41.159006 C 41.621183,41.173007 41.622183,41.186007 41.620183,41.201007 C 41.578182,41.498014 41.550181,41.78902 41.550181,42.068026 C 41.550181,42.871044 42.4082,43.544059 43.77723,44.110071 C 43.77623,44.111071 43.77523,44.112071 43.77423,44.113071 L 43.77423,44.113071 C 43.77423,44.113071 38.30111,44.870088 36.779076,46.138116 C 35.258043,47.406144 32.595984,51.463233 32.595984,51.463233 C 32.595984,51.463233 30.313934,53.619281 30.186931,54.633303 L 30.914947,54.099291 L 30.13293,54.880308 C 30.13293,54.880308 25.336825,55.40932 24.766812,56.739349 C 24.766812,56.739349 24.893815,56.888352 25.10682,57.085357 L 25.093819,57.078357 C 25.093819,57.078357 19.821703,57.929375 18.77568,60.40143 C 18.77568,60.40143 18.537675,59.593412 18.204668,59.260405 C 18.204668,59.260405 17.752658,61.043444 17.39665,61.399452 C 17.040642,61.75546 17.633655,64.300516 19.440695,64.06251 C 19.440695,64.06251 18.632677,61.399452 21.294736,60.115423 C 21.294736,60.115423 22.721767,60.259427 22.721767,61.542455 C 22.721767,61.542455 24.005795,60.211426 24.005795,59.354407 L 27.021862,58.12838 L 27.002861,58.11838 C 27.242867,58.174381 27.492872,58.213382 27.761878,58.213382 L 31.200954,56.914353 C 31.834968,57.166359 34.877035,55.519322 35.259043,55.266317 C 35.273043,55.257317 35.301044,55.227316 35.337045,55.189315 C 35.262043,55.347319 35.192042,55.509322 35.11904,55.668326 C 35.026038,55.87333 34.930036,56.074335 34.840034,56.282339 C 34.691031,56.627347 34.550027,56.979354 34.410024,57.331362 C 34.327023,57.541367 34.240021,57.748371 34.160019,57.960376 C 34.024016,58.319384 33.898013,58.686392 33.77201,59.0534 C 33.698009,59.268405 33.621007,59.48241 33.551005,59.699414 C 33.430003,60.072422 33.319,60.451431 33.207998,60.832439 C 33.143997,61.054444 33.075995,61.273449 33.014994,61.497454 C 32.909991,61.883462 32.813989,62.275471 32.717987,62.66848 C 32.662986,62.897485 32.604985,63.12249 32.552984,63.353495 C 32.463982,63.751503 32.38398,64.157512 32.303978,64.563521 C 32.257977,64.796526 32.209976,65.028532 32.167975,65.264537 C 32.094973,65.674546 32.031972,66.090555 31.968971,66.507564 C 31.93297,66.748569 31.894969,66.988575 31.862968,67.23258 C 31.806967,67.652589 31.760966,68.078599 31.715965,68.504608 C 31.689965,68.754614 31.661964,69.002619 31.638963,69.253624 C 31.600963,69.682634 31.571962,70.116643 31.544961,70.552653 C 31.527961,70.811659 31.509961,71.068664 31.49796,71.32867 C 31.47696,71.76568 31.46596,72.207689 31.456959,72.650699 C 31.450959,72.918705 31.442959,73.184711 31.441959,73.455717 C 31.441959,73.477717 31.440959,73.499718 31.440959,73.521718 C 31.440959,73.479717 31.438959,73.435716 31.437959,73.393716 C 31.437959,73.445717 31.440959,73.498718 31.440959,73.550719 C 31.438959,73.962728 31.446959,74.379737 31.454959,74.796746 C 31.457959,74.986751 31.454959,75.172755 31.459959,75.363759 C 31.460959,75.331758 31.46396,75.300758 31.46496,75.267757 C 31.47296,75.536763 31.47196,75.800769 31.48296,76.071774 C 31.638963,79.784856 32.175975,83.425936 33.028994,86.921013 L 32.973993,86.724009 C 32.973993,86.724009 27.270867,94.06317 28.222888,99.9573 C 28.989905,104.7154 28.250889,106.51944 27.936882,107.04046 L 28.834902,105.78143 L 28.823901,105.79843 L 28.601897,107.56447 C 22.530763,110.22553 18.951684,116.44266 18.951684,116.44266 C 18.380672,116.44266 18.000663,114.41362 18.000663,114.41362 C 17.176645,119.29673 21.804747,117.77369 21.804747,117.77369 C 19.902705,117.07768 21.551741,114.60262 21.551741,114.22361 C 21.551741,113.84161 24.024796,114.34962 24.024796,114.34962 C 24.975817,110.99054 27.701877,112.38457 27.701877,112.38457 C 28.398892,109.1515 29.919926,110.16552 29.919926,110.16552 L 30.295934,107.24646 L 30.886947,109.2155 L 31.329957,107.94648 C 31.329957,107.94648 32.153975,109.2155 32.724987,109.2155 C 32.724987,109.2155 28.100886,93.788164 34.026016,90.501092 L 33.964015,90.279087 C 37.107084,100.34831 42.952212,108.8715 50.175371,113.7646 C 50.196372,113.7806 50.214372,113.8016 50.235373,113.8166 L 50.329375,113.86861 C 51.749406,114.81763 53.220438,115.63064 54.735472,116.28366 L 54.786473,116.31166 C 54.812473,116.32266 54.839474,116.33266 54.865474,116.34266 C 55.187481,116.47966 55.512489,116.60167 55.837496,116.72367 C 55.983499,116.77867 56.128502,116.83967 56.275505,116.89167 C 56.619513,117.01368 56.967521,117.12068 57.315528,117.22668 C 57.450531,117.26768 57.584534,117.31568 57.720537,117.35368 C 58.075545,117.45568 58.434553,117.54069 58.793561,117.62369 C 58.924564,117.65469 59.054567,117.69269 59.186569,117.72169 C 59.67658,117.82669 60.168591,117.9157 60.664602,117.9887 C 60.783605,118.0067 60.901607,117.9977 61.02061,117.9777 C 61.01561,117.9787 61.01061,117.9807 61.005609,117.9817 C 61.01761,117.9847 61.03261,117.9867 61.04561,117.9887 C 62.007632,118.1277 62.979653,116.89767 63.961674,116.71867 C 64.967697,116.84467 65.965719,118.1327 66.95274,117.9887 C 78.405992,116.32466 88.340211,105.71043 93.131316,91.871122 L 93.076315,92.052126 C 97.576414,98.22026 93.712329,110.42053 93.712329,110.42053 L 94.853354,109.2775 L 95.551369,110.73554 L 95.361365,108.20148 C 95.449367,108.20148 95.977379,108.09148 96.581392,107.95848 L 97.010402,110.16652 C 97.010402,110.16652 98.531435,109.1515 99.22845,112.38557 C 99.22845,112.38557 101.95551,110.99054 102.90653,114.35062 C 102.90653,114.35062 105.37959,113.84261 105.37959,114.22461 C 105.37959,114.60362 107.02662,117.07868 105.12458,117.77469 C 105.12458,117.77469 109.75268,119.29673 108.92966,114.41462 C 108.92866,114.41862 108.54866,116.44766 107.97764,116.44766 z M 29.544917,104.79841 L 29.556918,104.78141 L 29.617919,104.98241 L 29.544917,104.79841 z M 61.238615,117.9237 C 61.289616,117.90669 61.340617,117.89469 61.391618,117.87369 C 61.339617,117.89469 61.288616,117.90669 61.238615,117.9237 z M 61.621623,117.76469 C 61.666624,117.74169 61.711625,117.71969 61.756626,117.69469 C 61.711625,117.71969 61.666624,117.74069 61.621623,117.76469 z M 62.025632,117.53369 C 62.050632,117.51669 62.076633,117.50169 62.101634,117.48469 C 62.076633,117.50169 62.051632,117.51769 62.025632,117.53369 z M 62.551643,117.19668 C 62.584644,117.17568 62.616645,117.15568 62.649646,117.13468 C 62.615645,117.15568 62.583644,117.17668 62.551643,117.19668 z M 62.913651,116.98467 C 62.958652,116.96067 63.003653,116.93467 63.049654,116.91267 C 63.003653,116.93467 62.958652,116.95967 62.913651,116.98467 z M 63.30666,116.80667 C 63.348661,116.79167 63.389662,116.77267 63.431663,116.75967 C 63.390662,116.77267 63.348661,116.79167 63.30666,116.80667 z " /> <path style="opacity:0.1;fill:none;stroke:black;stroke-width:2.00004411;stroke-linejoin:round" id="path40" d="M 107.97764,116.44766 C 107.97764,116.44766 104.39856,110.23053 98.326431,107.56947 L 98.226428,107.59147 C 98.449433,107.54047 98.594436,107.50647 98.594436,107.50647 C 101.2585,96.476223 94.462345,87.470025 94.462345,87.470025 L 94.450345,87.507026 C 95.388366,83.836945 95.971379,79.994861 96.136382,76.076775 C 96.148383,75.803769 96.147383,75.537763 96.154383,75.265757 C 96.156383,75.300758 96.159383,75.333758 96.160383,75.368759 C 96.166383,75.164755 96.162383,74.96775 96.166383,74.764746 C 96.174383,74.354737 96.181383,73.945728 96.180383,73.540719 C 96.179383,73.493718 96.182383,73.444717 96.182383,73.396716 C 96.182383,73.435716 96.179383,73.475717 96.179383,73.514718 C 96.179383,73.500718 96.178383,73.487718 96.178383,73.473717 C 96.177383,73.186711 96.168383,72.904705 96.162383,72.619699 C 96.152383,72.191689 96.142382,71.76568 96.122382,71.34367 C 96.109382,71.070664 96.091381,70.799658 96.073381,70.528653 C 96.04738,70.104643 96.01838,69.681634 95.981379,69.264625 C 95.958378,69.003619 95.928378,68.746613 95.901377,68.489608 C 95.857376,68.070598 95.811375,67.652589 95.756374,67.24158 C 95.723373,66.989575 95.684372,66.742569 95.646372,66.494564 C 95.58537,66.084555 95.523369,65.675546 95.451367,65.272537 C 95.408366,65.031532 95.359365,64.793526 95.313364,64.555521 C 95.234362,64.153512 95.155361,63.750503 95.066359,63.355495 C 95.014358,63.12549 94.957356,62.899485 94.901355,62.67048 C 94.806353,62.277471 94.711351,61.885462 94.605349,61.499454 C 94.543347,61.275449 94.476346,61.057444 94.412344,60.835439 C 94.301342,60.454431 94.189339,60.073423 94.068337,59.700414 C 93.999335,59.48441 93.922334,59.273405 93.849332,59.0604 C 93.722329,58.690392 93.595326,58.321384 93.458323,57.958376 C 93.379322,57.750371 93.29532,57.548367 93.213318,57.343362 C 93.071315,56.986355 92.929312,56.628347 92.777308,56.279339 C 92.689306,56.078335 92.596304,55.88233 92.506302,55.683326 C 92.350299,55.339318 92.194296,54.996311 92.027292,54.661303 C 91.93129,54.466299 91.829288,54.276295 91.729285,54.084291 C 91.559282,53.755284 91.389278,53.425276 91.210274,53.105269 C 91.105272,52.917265 90.994269,52.734261 90.886267,52.549257 C 90.713263,52.25325 90.543259,51.955244 90.363255,51.666238 L 90.371255,51.672238 C 92.988313,52.768262 94.283342,55.585324 95.10836,56.408342 C 95.931378,57.23236 97.769418,57.296361 97.769418,57.296361 L 96.564392,53.429276 L 94.473346,51.33723 C 91.05027,45.504102 84.717131,44.876088 84.717131,44.876088 L 84.720131,44.887088 C 84.65113,44.824087 84.578128,44.764086 84.508127,44.701084 C 84.286122,44.50408 84.067117,44.302076 83.840112,44.111071 C 85.208142,43.545059 86.066161,42.871044 86.066161,42.069026 C 86.066161,41.79502 86.04016,41.508014 85.999159,41.216008 C 85.996159,41.197007 85.997159,41.180007 85.994159,41.161006 C 85.993159,41.163006 85.991159,41.166007 85.990159,41.168007 C 85.880157,40.42499 85.646152,39.627973 85.300144,38.792954 C 85.542149,38.103939 85.934158,37.166919 86.327167,37.009915 C 86.559172,36.916913 86.363167,36.445903 85.967159,35.88889 L 86.121162,36.026894 L 86.121162,35.88389 C 86.121162,35.88389 86.216164,35.502882 87.072183,35.502882 C 87.926202,35.502882 88.070205,25.946672 85.930158,20.573554 C 85.930158,20.573554 85.59215,19.917539 84.773132,19.869538 L 85.170141,19.812537 C 85.59815,18.053498 86.880179,15.533443 88.260209,13.821405 C 89.073227,12.812383 89.115228,12.073367 88.817221,11.584356 C 89.050226,10.917341 90.256253,7.5452669 90.256253,7.5452669 C 90.779264,7.3552627 91.588282,8.163281 91.588282,8.163281 C 89.400234,3.9321874 86.92918,7.2122596 86.92918,7.2122596 C 87.546193,7.1172575 88.164207,6.7372491 88.592216,7.3072617 C 89.020226,7.8782743 87.8312,10.921341 87.8312,10.921341 C 86.833178,10.683336 85.739154,12.157368 85.739154,12.157368 C 84.420125,14.06841 83.885113,19.49353 83.842112,19.95654 C 83.085095,20.126544 82.37608,20.563553 82.41208,21.665578 C 82.459081,23.13961 81.983071,24.376637 81.983071,24.376637 L 85.406146,30.937782 C 85.406146,30.937782 85.406146,33.267833 85.643151,33.932847 C 85.814155,34.409858 85.304144,34.663864 84.999137,34.771866 C 84.395124,34.184853 83.731109,33.710843 83.2821,33.710843 L 82.648086,34.217854 L 82.624085,34.265855 C 82.569084,34.192853 82.511083,34.119852 82.455081,34.04585 C 82.259077,33.788844 82.059073,33.531839 81.852068,33.275833 C 81.760066,33.16283 81.665064,33.050828 81.572062,32.937826 C 81.388058,32.717821 81.203054,32.497816 81.01105,32.278811 C 80.902047,32.152808 80.790045,32.028806 80.678042,31.903803 C 80.492038,31.697798 80.305034,31.492794 80.11403,31.288789 C 79.994027,31.160786 79.873025,31.032784 79.750022,30.904781 C 79.556018,30.702776 79.358013,30.503772 79.158009,30.305768 C 79.034006,30.181765 78.911003,30.057762 78.784001,29.93576 C 78.566996,29.725755 78.345991,29.51975 78.122986,29.313746 C 78.009984,29.208744 77.897981,29.101741 77.782979,28.997739 C 77.444971,28.691732 77.100964,28.390726 76.752956,28.096719 C 76.381948,28.310724 75.985939,28.514728 75.57093,28.709733 C 75.392926,28.792734 75.198922,28.867736 75.012918,28.947738 C 74.769912,29.05174 74.531907,29.158742 74.275901,29.256745 C 74.254901,29.264745 74.2299,29.271745 74.2089,29.279745 L 74.487906,29.006739 C 74.487906,29.006739 73.425883,27.626709 75.073919,24.709645 C 76.325947,22.496596 72.613865,23.716623 70.750824,25.264657 C 70.749824,25.264657 70.749824,25.263657 70.748824,25.263657 C 70.746824,25.264657 70.745824,25.266657 70.743824,25.267657 C 70.343815,24.927649 69.935806,24.601642 69.517797,24.305636 C 69.513797,24.302636 69.509797,24.299636 69.505796,24.296635 L 69.504796,24.296635 C 69.490796,24.286635 69.476796,24.277635 69.461795,24.267635 L 69.505796,24.295635 C 69.505796,23.469617 71.252835,23.805625 70.538819,23.091609 C 70.407816,22.961606 70.280814,22.833603 70.155811,22.708601 C 70.729823,21.364571 73.218878,20.935562 76.307946,19.699534 C 79.635019,18.368505 80.778044,15.230436 81.157053,14.089411 C 81.538061,12.948386 79.256011,11.33235 79.065007,13.519398 C 78.876003,15.706446 77.732977,17.70349 75.926938,18.749513 C 73.163877,19.806537 70.201812,21.481574 69.395794,21.949584 C 69.239791,21.79358 69.143789,21.697578 69.143789,21.697578 L 68.699779,21.697578 C 69.143789,22.141588 68.255769,23.486618 68.255769,23.486618 L 68.401772,23.58062 C 66.737736,22.583598 65.074699,21.982585 63.807671,21.982585 C 62.473642,21.982585 60.698603,22.641599 58.946564,23.736623 L 58.951564,23.733623 C 58.951564,23.733623 58.334551,22.173589 58.334551,21.127566 L 56.792517,21.589576 C 55.826496,21.034564 53.014434,19.467529 50.390376,18.464507 C 48.583336,17.418484 47.443311,15.42144 47.252307,13.234392 C 47.062303,11.047344 44.780253,12.66338 45.160261,13.804405 C 45.540269,14.94643 46.681294,18.083499 50.010368,19.414528 C 52.978433,20.602554 55.679492,21.110565 56.433509,22.352593 L 56.433509,23.312614 C 56.433509,23.312614 57.708537,23.674622 57.708537,24.587642 L 57.823539,24.50864 C 57.711537,24.591642 57.601535,24.675644 57.490532,24.761646 L 57.487532,24.757646 L 57.456531,24.787646 C 57.185525,24.998651 56.92152,25.218656 56.661514,25.447661 C 56.660514,25.446661 56.658514,25.444661 56.657514,25.443661 C 56.656514,25.444661 56.655514,25.445661 56.653514,25.447661 C 54.879475,23.816625 50.822385,22.406594 52.122414,24.707644 C 53.697449,27.494706 52.799429,28.874736 52.716427,28.992739 C 52.690427,28.981739 52.663426,28.970738 52.636425,28.959738 C 52.438421,28.875736 52.231416,28.794734 52.041412,28.706732 C 51.627403,28.512728 51.232394,28.309724 50.862386,28.095719 C 50.282374,28.58473 49.717361,29.093741 49.168349,29.613752 C 49.130348,29.650753 49.090347,29.685754 49.052346,29.721755 C 48.529335,30.220766 48.026324,30.730777 47.539313,31.248788 C 47.482312,31.30979 47.424311,31.369791 47.367309,31.430792 C 46.898299,31.935804 46.451289,32.446815 46.02528,32.961826 C 45.963279,33.035828 45.901277,33.109829 45.840276,33.183831 C 45.460267,33.649841 45.10026,34.117852 44.760252,34.583862 L 44.641249,34.344857 L 44.007236,33.837845 C 43.558226,33.837845 42.893211,34.310856 42.290198,34.898869 C 41.985191,34.790866 41.47518,34.536861 41.645184,34.05985 C 41.883189,33.393836 41.883189,31.063784 41.883189,31.063784 L 45.306264,24.50164 C 45.306264,24.50164 44.830254,23.265613 44.879255,21.79158 C 44.914255,20.689556 44.20524,20.252546 43.448223,20.082543 C 43.405222,19.620533 42.87021,14.194413 41.551181,12.282371 C 41.551181,12.282371 40.457157,10.808339 39.458135,11.046344 C 39.458135,11.046344 38.270109,8.003277 38.697119,7.4322644 C 39.126128,6.8622519 39.744142,7.2422603 40.362155,7.3372623 C 40.362155,7.3372623 37.889101,4.0571902 35.702053,8.288283 C 35.702053,8.288283 36.510071,7.4802655 37.033082,7.6702697 C 37.033082,7.6702697 38.240109,11.040344 38.473114,11.708359 C 38.174107,12.198369 38.216108,12.936386 39.029126,13.946408 C 40.408156,15.658445 41.692185,18.178501 42.120194,19.93754 L 42.517203,19.994541 C 41.697185,20.042542 41.359177,20.698556 41.359177,20.698556 C 39.22013,26.071674 39.362133,35.627885 40.218152,35.627885 C 41.074171,35.627885 41.169173,36.008893 41.169173,36.008893 L 41.169173,36.150896 L 41.323176,36.013893 C 40.927168,36.570905 40.730163,37.039916 40.963169,37.133918 C 41.438179,37.323922 41.912189,38.649951 42.120194,39.304966 C 41.882189,39.95198 41.713185,40.575994 41.626183,41.164007 C 41.626183,41.162006 41.624183,41.161006 41.623183,41.159006 C 41.621183,41.173007 41.622183,41.186007 41.620183,41.201007 C 41.578182,41.498014 41.550181,41.78902 41.550181,42.068026 C 41.550181,42.871044 42.4082,43.544059 43.77723,44.110071 C 43.77623,44.111071 43.77523,44.112071 43.77423,44.113071 L 43.77423,44.113071 C 43.77423,44.113071 38.30111,44.870088 36.779076,46.138116 C 35.258043,47.406144 32.595984,51.463233 32.595984,51.463233 C 32.595984,51.463233 30.313934,53.619281 30.186931,54.633303 L 30.914947,54.099291 L 30.13293,54.880308 C 30.13293,54.880308 25.336825,55.40932 24.766812,56.739349 C 24.766812,56.739349 24.893815,56.888352 25.10682,57.085357 L 25.093819,57.078357 C 25.093819,57.078357 19.821703,57.929375 18.77568,60.40143 C 18.77568,60.40143 18.537675,59.593412 18.204668,59.260405 C 18.204668,59.260405 17.752658,61.043444 17.39665,61.399452 C 17.040642,61.75546 17.633655,64.300516 19.440695,64.06251 C 19.440695,64.06251 18.632677,61.399452 21.294736,60.115423 C 21.294736,60.115423 22.721767,60.259427 22.721767,61.542455 C 22.721767,61.542455 24.005795,60.211426 24.005795,59.354407 L 27.021862,58.12838 L 27.002861,58.11838 C 27.242867,58.174381 27.492872,58.213382 27.761878,58.213382 L 31.200954,56.914353 C 31.834968,57.166359 34.877035,55.519322 35.259043,55.266317 C 35.273043,55.257317 35.301044,55.227316 35.337045,55.189315 C 35.262043,55.347319 35.192042,55.509322 35.11904,55.668326 C 35.026038,55.87333 34.930036,56.074335 34.840034,56.282339 C 34.691031,56.627347 34.550027,56.979354 34.410024,57.331362 C 34.327023,57.541367 34.240021,57.748371 34.160019,57.960376 C 34.024016,58.319384 33.898013,58.686392 33.77201,59.0534 C 33.698009,59.268405 33.621007,59.48241 33.551005,59.699414 C 33.430003,60.072422 33.319,60.451431 33.207998,60.832439 C 33.143997,61.054444 33.075995,61.273449 33.014994,61.497454 C 32.909991,61.883462 32.813989,62.275471 32.717987,62.66848 C 32.662986,62.897485 32.604985,63.12249 32.552984,63.353495 C 32.463982,63.751503 32.38398,64.157512 32.303978,64.563521 C 32.257977,64.796526 32.209976,65.028532 32.167975,65.264537 C 32.094973,65.674546 32.031972,66.090555 31.968971,66.507564 C 31.93297,66.748569 31.894969,66.988575 31.862968,67.23258 C 31.806967,67.652589 31.760966,68.078599 31.715965,68.504608 C 31.689965,68.754614 31.661964,69.002619 31.638963,69.253624 C 31.600963,69.682634 31.571962,70.116643 31.544961,70.552653 C 31.527961,70.811659 31.509961,71.068664 31.49796,71.32867 C 31.47696,71.76568 31.46596,72.207689 31.456959,72.650699 C 31.450959,72.918705 31.442959,73.184711 31.441959,73.455717 C 31.441959,73.477717 31.440959,73.499718 31.440959,73.521718 C 31.440959,73.479717 31.438959,73.435716 31.437959,73.393716 C 31.437959,73.445717 31.440959,73.498718 31.440959,73.550719 C 31.438959,73.962728 31.446959,74.379737 31.454959,74.796746 C 31.457959,74.986751 31.454959,75.172755 31.459959,75.363759 C 31.460959,75.331758 31.46396,75.300758 31.46496,75.267757 C 31.47296,75.536763 31.47196,75.800769 31.48296,76.071774 C 31.638963,79.784856 32.175975,83.425936 33.028994,86.921013 L 32.973993,86.724009 C 32.973993,86.724009 27.270867,94.06317 28.222888,99.9573 C 28.989905,104.7154 28.250889,106.51944 27.936882,107.04046 L 28.834902,105.78143 L 28.823901,105.79843 L 28.601897,107.56447 C 22.530763,110.22553 18.951684,116.44266 18.951684,116.44266 C 18.380672,116.44266 18.000663,114.41362 18.000663,114.41362 C 17.176645,119.29673 21.804747,117.77369 21.804747,117.77369 C 19.902705,117.07768 21.551741,114.60262 21.551741,114.22361 C 21.551741,113.84161 24.024796,114.34962 24.024796,114.34962 C 24.975817,110.99054 27.701877,112.38457 27.701877,112.38457 C 28.398892,109.1515 29.919926,110.16552 29.919926,110.16552 L 30.295934,107.24646 L 30.886947,109.2155 L 31.329957,107.94648 C 31.329957,107.94648 32.153975,109.2155 32.724987,109.2155 C 32.724987,109.2155 28.100886,93.788164 34.026016,90.501092 L 33.964015,90.279087 C 37.107084,100.34831 42.952212,108.8715 50.175371,113.7646 C 50.196372,113.7806 50.214372,113.8016 50.235373,113.8166 L 50.329375,113.86861 C 51.749406,114.81763 53.220438,115.63064 54.735472,116.28366 L 54.786473,116.31166 C 54.812473,116.32266 54.839474,116.33266 54.865474,116.34266 C 55.187481,116.47966 55.512489,116.60167 55.837496,116.72367 C 55.983499,116.77867 56.128502,116.83967 56.275505,116.89167 C 56.619513,117.01368 56.967521,117.12068 57.315528,117.22668 C 57.450531,117.26768 57.584534,117.31568 57.720537,117.35368 C 58.075545,117.45568 58.434553,117.54069 58.793561,117.62369 C 58.924564,117.65469 59.054567,117.69269 59.186569,117.72169 C 59.67658,117.82669 60.168591,117.9157 60.664602,117.9887 C 60.783605,118.0067 60.901607,117.9977 61.02061,117.9777 C 61.01561,117.9787 61.01061,117.9807 61.005609,117.9817 C 61.01761,117.9847 61.03261,117.9867 61.04561,117.9887 C 62.007632,118.1277 62.979653,116.89767 63.961674,116.71867 C 64.967697,116.84467 65.965719,118.1327 66.95274,117.9887 C 78.405992,116.32466 88.340211,105.71043 93.131316,91.871122 L 93.076315,92.052126 C 97.576414,98.22026 93.712329,110.42053 93.712329,110.42053 L 94.853354,109.2775 L 95.551369,110.73554 L 95.361365,108.20148 C 95.449367,108.20148 95.977379,108.09148 96.581392,107.95848 L 97.010402,110.16652 C 97.010402,110.16652 98.531435,109.1515 99.22845,112.38557 C 99.22845,112.38557 101.95551,110.99054 102.90653,114.35062 C 102.90653,114.35062 105.37959,113.84261 105.37959,114.22461 C 105.37959,114.60362 107.02662,117.07868 105.12458,117.77469 C 105.12458,117.77469 109.75268,119.29673 108.92966,114.41462 C 108.92866,114.41862 108.54866,116.44766 107.97764,116.44766 z M 29.544917,104.79841 L 29.556918,104.78141 L 29.617919,104.98241 L 29.544917,104.79841 z M 61.238615,117.9237 C 61.289616,117.90669 61.340617,117.89469 61.391618,117.87369 C 61.339617,117.89469 61.288616,117.90669 61.238615,117.9237 z M 61.621623,117.76469 C 61.666624,117.74169 61.711625,117.71969 61.756626,117.69469 C 61.711625,117.71969 61.666624,117.74069 61.621623,117.76469 z M 62.025632,117.53369 C 62.050632,117.51669 62.076633,117.50169 62.101634,117.48469 C 62.076633,117.50169 62.051632,117.51769 62.025632,117.53369 z M 62.551643,117.19668 C 62.584644,117.17568 62.616645,117.15568 62.649646,117.13468 C 62.615645,117.15568 62.583644,117.17668 62.551643,117.19668 z M 62.913651,116.98467 C 62.958652,116.96067 63.003653,116.93467 63.049654,116.91267 C 63.003653,116.93467 62.958652,116.95967 62.913651,116.98467 z M 63.30666,116.80667 C 63.348661,116.79167 63.389662,116.77267 63.431663,116.75967 C 63.390662,116.77267 63.348661,116.79167 63.30666,116.80667 z " /> </g> <path d="M 109.92669,61.454409 C 109.92669,61.454409 110.31669,63.134446 109.18267,62.721437 C 109.18267,62.721437 102.25352,56.662303 97.222406,57.536323 L 97.622415,58.820351 C 97.622415,58.820351 100.70348,60.860396 102.03451,60.622391 C 102.03451,60.622391 102.86753,61.144402 102.86753,61.620413 C 102.86753,62.096423 105.69559,63.071444 106.57561,62.524432 C 106.57561,62.524432 108.26365,62.810439 108.26365,64.283471 C 108.26365,64.283471 107.07462,64.996487 106.43361,64.616478 C 106.43361,64.616478 107.70564,66.649523 110.21269,64.140468 C 111.46072,62.891441 109.92669,61.454409 109.92669,61.454409 z " id="path42" style="opacity:0.15;fill:none;stroke:black;stroke-width:2.00004411;stroke-linejoin:round" /> <path d="M 27.939882,109.04546 L 27.813879,109.22346 C 27.813879,109.22346 27.82688,109.20846 27.84488,109.18646 C 27.84688,109.18246 27.84688,109.18246 27.84988,109.17946 C 27.871881,109.15146 27.901881,109.10946 27.939882,109.04546 L 27.932882,109.05646 C 27.934882,109.05146 27.936882,109.05046 27.939882,109.04546 z " id="path44" style="opacity:0.15;fill:none;stroke:black;stroke-width:2.00004411;stroke-linejoin:round" /> <path d="M 109.18167,61.721415 C 109.18167,61.721415 102.25252,55.662281 97.221406,56.536301 L 97.621415,57.820329 C 97.621415,57.820329 100.70248,59.860374 102.03351,59.622369 C 102.03351,59.622369 102.86653,60.14438 102.86653,60.620391 C 102.86653,61.096401 105.69459,62.071422 106.57461,61.52441 C 106.57461,61.52441 108.26265,61.810417 108.26265,63.283449 C 108.26265,63.283449 107.07362,63.996465 106.43261,63.616456 C 106.43261,63.616456 107.70464,65.649501 110.21169,63.141446 C 111.45972,61.892419 109.92569,60.455387 109.92569,60.455387 C 109.92569,60.455387 110.31569,62.133424 109.18167,61.721415 z " id="path53" style="fill:url(#radialGradient8835)" /> <path d="M 84.719131,45.878066 C 84.719131,45.878066 91.05227,46.50608 94.475346,52.339208 L 96.566392,54.431254 L 97.771418,58.298339 C 97.771418,58.298339 95.933378,58.234338 95.11036,57.41032 C 94.285342,56.586302 92.990313,53.76924 90.373256,52.674216 L 85.510149,48.955134 L 84.719131,45.878066 z " id="path62" style="fill:url(#radialGradient8832)" /> <path d="M 30.918948,55.102269 L 30.13693,55.884286 C 30.13693,55.884286 25.340825,56.413298 24.770812,57.743327 C 24.770812,57.743327 25.958838,59.21736 27.766878,59.21736 L 31.205954,57.918331 L 32.806989,53.417232 L 30.918948,55.102269 z " id="path71" style="fill:url(#radialGradient8829)" /> <path d="M 43.77823,45.116049 C 43.77823,45.116049 38.30511,45.873066 36.783077,47.141094 C 35.262043,48.409122 32.599985,52.466211 32.599985,52.466211 C 32.599985,52.466211 30.317934,54.622259 30.190932,55.636281 L 32.092973,54.24125 C 32.092973,54.24125 30.57194,57.665326 31.204954,57.918331 C 31.838968,58.170337 34.881035,56.5233 35.263043,56.270295 C 35.642051,56.016289 43.77823,45.116049 43.77823,45.116049 z " id="path80" style="fill:url(#radialGradient8826)" /> <path d="M 25.096819,58.082335 C 25.096819,58.082335 19.824704,58.933353 18.77868,61.405408 C 18.77868,61.405408 18.540675,60.59739 18.207668,60.264383 C 18.207668,60.264383 17.755658,62.047422 17.39965,62.40343 C 17.043642,62.760438 17.636655,65.304494 19.443695,65.066488 C 19.443695,65.066488 18.635677,62.40343 21.297736,61.119402 C 21.297736,61.119402 22.724767,61.263405 22.724767,62.546433 C 22.724767,62.546433 24.008796,61.215404 24.008796,60.358385 L 27.024862,59.132358 L 25.096819,58.082335 z " id="path89" style="fill:url(#radialGradient8823)" /> <path d="M 52.710427,30.009717 C 52.710427,30.009717 53.77345,28.629687 52.125414,25.712623 C 50.478378,22.796558 57.451531,25.839625 57.451531,27.741667 C 57.451531,29.643709 56.793517,31.279745 56.793517,31.279745 L 54.154459,31.419748 L 52.710427,30.009717 z " id="path102" style="fill:url(#radialGradient8820)" /> <path d="M 74.490906,30.009717 C 74.490906,30.009717 73.428883,28.629687 75.076919,25.712623 C 76.725955,22.796558 69.751802,25.839625 69.751802,27.741667 C 69.751802,29.643709 70.409816,31.279745 70.409816,31.279745 L 73.048874,31.419748 L 74.490906,30.009717 z " id="path115" style="fill:url(#radialGradient8817)" /> <path d="M 42.236197,40.673952 C 42.236197,40.673952 41.602183,38.391902 40.968169,38.137896 C 40.334155,37.88489 42.87021,34.841823 44.011236,34.841823 L 44.64525,35.348835 L 45.152261,36.362857 L 42.236197,40.673952 z " id="path124" style="fill:url(#radialGradient8814)" /> <path d="M 85.060139,40.546949 C 85.060139,40.546949 85.694153,38.264899 86.328167,38.011893 C 86.96218,37.757888 84.426125,34.714821 83.2851,34.714821 L 82.651086,35.221832 L 82.144075,36.235854 L 85.060139,40.546949 z " id="path133" style="fill:url(#radialGradient8811)" /> <path d="M 69.179789,23.081565 C 69.179789,23.081565 72.697867,20.990519 75.930938,19.753491 C 77.736978,18.707468 78.879003,16.710425 79.069007,14.523376 C 79.259011,12.336328 81.542061,13.952364 81.161053,15.093389 C 80.782045,16.235414 79.640019,19.372483 76.311946,20.703512 C 72.982873,22.035542 70.319814,22.41555 70.035808,24.031586 L 69.179789,23.081565 z " id="path146" style="fill:url(#radialGradient8808)" /> <path d="M 52.506422,32.892781 C 51.280396,39.20892 56.224504,44.288031 63.810671,44.288031 C 71.396838,44.288031 76.339947,39.20892 75.11592,32.892781 C 74.109898,27.702666 67.38275,22.986563 63.810671,22.986563 C 60.238593,22.986563 53.513445,27.702666 52.506422,32.892781 z " id="path171" style="fill:url(#linearGradient8805)" /> <path d="M 31.48596,77.077753 C 32.366979,98.001213 45.12326,116.73463 60.667602,118.99367 C 61.704625,119.14468 62.752648,117.70065 63.811671,117.70065 C 64.869694,117.70065 65.917718,119.14468 66.95574,118.99367 C 82.500082,116.73463 95.256363,98.001213 96.138382,77.077753 C 97.137404,53.380231 82.690087,38.011893 63.812671,38.011893 C 44.934256,38.011893 30.486938,53.380231 31.48596,77.077753 z " id="path188" style="fill:url(#radialGradient8802)" /> <path d="M 96.136382,76.222734 C 95.254363,96.687184 82.498082,115.00859 66.95374,117.21964 C 65.916718,117.36564 64.868694,115.95461 63.809671,115.95461 C 62.750648,115.95461 61.702625,117.36564 60.665602,117.21964 C 45.12126,115.00859 32.364979,96.687184 31.48396,76.222734 C 31.456959,75.60772 31.442959,75.000707 31.438959,74.399694 C 31.432959,75.280713 31.445959,76.172733 31.48396,77.078753 C 32.364979,98.002213 45.12126,116.73563 60.665602,118.99467 C 61.702625,119.14568 62.750648,117.70165 63.809671,117.70165 C 64.867694,117.70165 65.915717,119.14568 66.95374,118.99467 C 82.498082,116.73563 95.254363,98.002213 96.136382,77.078753 C 96.175383,76.173733 96.188383,75.280713 96.181383,74.399694 C 96.178383,75.000707 96.163383,75.60772 96.136382,76.222734 z " id="path197" style="fill:url(#linearGradient8799)" /> <path d="M 63.810671,43.591016 C 81.641063,43.591016 95.517369,56.359297 96.160383,76.369737 C 96.843398,53.074225 82.499082,38.011893 63.810671,38.011893 C 45.12226,38.011893 30.778944,53.074225 31.46296,76.369737 C 32.104974,56.358297 45.980279,43.591016 63.810671,43.591016 z " id="path210" style="fill:url(#radialGradient8796)" /> <path d="M 57.490532,25.763624 C 57.490532,25.763624 58.908563,27.678666 60.874607,27.361659 C 60.874607,27.361659 58.689559,32.277767 54.790473,28.377681 L 57.490532,25.763624 z " id="path219" style="fill:url(#radialGradient8793)" /> <path d="M 68.544775,29.453705 C 69.012786,29.66771 70.446817,30.017717 70.910827,29.401704 C 71.441839,28.693688 70.866826,26.791646 71.339837,26.790646 C 70.756824,26.248634 70.13981,25.747623 69.509797,25.300614 C 69.508797,25.300614 68.102766,27.235656 66.643734,27.235656 C 66.231724,27.266657 68.077765,29.2397 68.544775,29.453705 z " id="path228" style="fill:url(#radialGradient8790)" /> <path d="M 53.31844,30.60273 L 54.153459,31.418748 L 56.792517,31.278745 C 56.792517,31.278745 57.450531,29.643709 57.450531,27.740667 C 57.450531,27.338658 57.136524,26.885648 56.659514,26.448639 C 55.301484,27.643665 54.099458,29.068696 53.31844,30.60273 z " id="path241" style="fill:url(#radialGradient8787)" /> <path d="M 74.160899,30.332724 C 73.336881,28.823691 72.116854,27.42766 70.751824,26.266635 C 70.158811,26.758646 69.751802,27.283657 69.751802,27.741667 C 69.751802,29.643709 70.409816,31.279745 70.409816,31.279745 L 73.048874,31.419748 L 74.160899,30.332724 z " id="path254" style="fill:url(#radialGradient8784)" /> <path d="M 76.755956,29.099697 C 73.675888,30.879736 69.020786,32.013761 63.811671,32.013761 C 58.602557,32.013761 53.947454,30.879736 50.866386,29.099697 C 45.678272,33.474793 41.554182,39.24392 41.554182,43.071004 C 41.554182,47.178095 63.810671,47.939112 63.810671,47.939112 C 63.810671,47.939112 86.067161,47.178095 86.067161,43.071004 C 86.067161,39.24392 81.94507,33.475793 76.755956,29.099697 z " id="path263" style="fill:url(#radialGradient8781)" /> <path d="M 63.810671,46.228074 C 63.810671,46.228074 43.006213,45.58106 41.627183,42.162984 C 41.581182,42.474991 41.553182,42.779998 41.553182,43.071004 C 41.553182,47.178095 63.809671,47.939112 63.809671,47.939112 C 63.809671,47.939112 86.066161,47.178095 86.066161,43.071004 C 86.066161,42.778998 86.04016,42.474991 85.994159,42.162984 C 84.617129,45.58106 63.810671,46.228074 63.810671,46.228074 z " id="path270" style="fill:url(#linearGradient8778)" /> <path d="M 94.463346,88.471003 C 94.463346,88.471003 101.2595,97.477201 98.595436,108.50744 C 98.595436,108.50744 95.58337,109.20646 95.363365,109.20646 L 95.553369,111.74052 L 94.855354,110.28248 L 93.714329,111.42551 C 93.714329,111.42551 97.578414,99.22524 93.078315,93.057104 L 94.463346,88.471003 z " id="path279" style="fill:url(#radialGradient8775)" /> <path d="M 107.97764,117.44764 C 107.97764,117.44764 104.39856,111.2305 98.326431,108.56945 L 96.582392,108.96245 L 97.011402,111.1715 C 97.011402,111.1715 98.532435,110.15648 99.22945,113.39055 C 99.22945,113.39055 101.95651,111.99552 102.90753,115.35559 C 102.90753,115.35559 105.38059,114.84758 105.38059,115.22959 C 105.38059,115.6086 107.02762,118.08365 105.12558,118.77967 C 105.12558,118.77967 109.75368,120.3017 108.93066,115.4196 C 108.92866,115.4186 108.54866,117.44764 107.97764,117.44764 z " id="path288" style="fill:url(#radialGradient8772)" /> <path d="M 18.954684,117.44764 C 18.954684,117.44764 22.534763,111.2305 28.604897,108.56945 L 28.826902,106.80341 L 29.532917,105.76738 L 30.349935,107.85043 L 29.921926,111.1705 C 29.921926,111.1705 28.400892,110.15548 27.703877,113.38955 C 27.703877,113.38955 24.976817,111.99452 24.026796,115.35459 C 24.026796,115.35459 21.553742,114.84658 21.553742,115.22859 C 21.553742,115.6076 19.905705,118.08265 21.806747,118.77867 C 21.806747,118.77867 17.179645,120.3007 18.002663,115.4186 C 18.003663,115.4186 18.383672,117.44764 18.954684,117.44764 z " id="path297" style="fill:url(#radialGradient8769)" /> <path d="M 32.976993,87.729987 C 32.976993,87.729987 27.273867,95.069148 28.225888,100.96328 C 29.175909,106.85941 27.812879,108.22344 27.812879,108.22344 L 29.555918,105.78238 L 30.887947,110.22148 L 31.330957,108.95245 C 31.330957,108.95245 32.154975,110.22148 32.725987,110.22148 C 32.725987,110.22148 28.101886,94.794142 34.027016,91.50707 L 32.976993,87.729987 z " id="path306" style="fill:url(#radialGradient8766)" /> <path d="M 58.954564,24.737601 C 58.954564,24.737601 58.337551,23.177567 58.337551,22.131544 L 56.435509,22.701556 L 56.435509,24.318592 C 56.435509,24.318592 57.710537,24.6806 57.710537,25.59362 L 58.954564,24.737601 z " id="path319" style="fill:url(#radialGradient8763)" /> <path d="M 68.259769,24.490596 C 68.259769,24.490596 69.148789,23.145566 68.703779,22.701556 L 69.147789,22.701556 C 69.147789,22.701556 69.829804,23.383571 70.542819,24.096587 C 71.256835,24.809603 69.509797,24.474595 69.509797,25.300614 L 68.259769,24.490596 z " id="path332" style="fill:url(#radialGradient8760)" /> <path d="M 57.145525,22.796558 C 57.145525,22.796558 53.626447,20.704512 50.393376,19.468485 C 48.586336,18.422462 47.446311,16.425418 47.255307,14.23837 C 47.065303,12.051322 44.783253,13.667358 45.163261,14.808383 C 45.543269,15.950408 46.684294,19.087477 50.013368,20.418506 C 53.342441,21.750535 56.341507,22.225546 56.627513,23.842581 L 57.145525,22.796558 z " id="path345" style="fill:url(#radialGradient8757)" /> <path d="M 41.174173,37.013871 C 41.174173,37.013871 41.079171,36.632863 40.223152,36.632863 C 39.367133,36.632863 39.22413,27.075653 41.364177,21.703534 C 41.364177,21.703534 41.744186,20.942518 42.696207,20.990519 C 43.647228,21.03752 44.931256,21.323526 44.884255,22.796558 C 44.836254,24.270591 45.311264,25.506618 45.311264,25.506618 L 41.888189,32.068762 C 41.888189,32.068762 41.888189,34.398814 41.650184,35.064828 C 41.413178,35.730843 42.506202,35.967848 42.506202,35.967848 L 41.175173,37.155874" id="path354" style="fill:url(#radialGradient8754)" /> <path d="M 41.554182,13.287349 C 41.554182,13.287349 40.460157,11.813317 39.461135,12.051322 C 38.463114,12.289327 37.655096,13.239348 39.033126,14.951386 C 40.412156,16.663424 41.696185,19.183479 42.124194,20.942518 L 43.456223,21.132522 C 43.456223,21.132522 42.932212,15.284393 41.554182,13.287349 z " id="path363" style="fill:url(#radialGradient8751)" /> <path d="M 40.365155,8.3422405 C 40.365155,8.3422405 37.892101,5.0621683 35.705053,9.2932614 C 35.705053,9.2932614 36.513071,8.4852436 37.036082,8.6752478 C 37.036082,8.6752478 38.415112,12.526333 38.510115,12.812339 C 38.605117,13.097345 39.460135,12.051322 39.460135,12.051322 C 39.460135,12.051322 38.272109,9.0082551 38.699119,8.4372425 C 39.129128,7.86723 39.748142,8.2472384 40.365155,8.3422405 z " id="path372" style="fill:url(#radialGradient8748)" /> <path d="M 86.122162,36.886868 C 86.122162,36.886868 86.217164,36.50586 87.073183,36.50586 C 87.927202,36.50586 88.071205,26.94965 85.931158,21.576532 C 85.931158,21.576532 85.551149,20.815515 84.600129,20.863516 C 83.649108,20.910517 82.365079,21.196523 82.41308,22.669556 C 82.460081,24.143588 81.984071,25.380615 81.984071,25.380615 L 85.407146,31.94176 C 85.407146,31.94176 85.407146,34.271811 85.644152,34.936826 C 85.882157,35.60284 84.789133,35.839845 84.789133,35.839845 L 86.121162,37.028872" id="path381" style="fill:url(#radialGradient8745)" /> <path d="M 85.741154,13.160346 C 85.741154,13.160346 86.835178,11.686314 87.8332,11.924319 C 88.832222,12.162324 89.641239,13.113345 88.262209,14.824383 C 86.882179,16.536421 85.600151,19.056476 85.172141,20.815515 L 83.840112,21.005519 C 83.840112,21.005519 84.362123,15.15739 85.741154,13.160346 z " id="path390" style="fill:url(#radialGradient8742)" /> <path d="M 86.93018,8.2152377 C 86.93018,8.2152377 89.402234,4.9351655 91.589282,9.1662586 C 91.589282,9.1662586 90.780264,8.3582408 90.257253,8.548245 C 90.257253,8.548245 88.879223,12.40033 88.783221,12.685336 C 88.688218,12.970342 87.8322,11.924319 87.8322,11.924319 C 87.8322,11.924319 89.020226,8.8812523 88.593216,8.3102398 C 88.166207,7.7402272 87.548193,8.1202356 86.93018,8.2152377 z " id="path399" style="fill:url(#radialGradient8739)" /> <path d="M 63.810671,47.939112 C 63.810671,47.939112 58.875563,47.770108 53.653448,47.163094 C 53.651448,47.198095 53.646448,47.232096 53.646448,47.268097 C 53.646448,49.754151 58.460553,53.353231 63.694669,53.353231 C 68.929784,53.353231 73.806891,49.817153 73.806891,47.331098 C 73.806891,47.280097 73.800891,47.232096 73.797891,47.183095 C 68.639777,47.774108 63.810671,47.939112 63.810671,47.939112 z " id="path406" style="fill:url(#linearGradient8736)" /> <path d="M 37.931102,57.153314 C 35.466048,61.446409 35.324044,65.993509 37.614095,67.307538 C 39.903145,68.621567 43.75823,66.207513 46.223284,61.914419 C 48.688338,57.622325 48.830342,53.075225 46.541291,51.761196 C 44.251241,50.446167 40.396156,52.86122 37.931102,57.153314 z " id="path429" style="fill:url(#radialGradient8733)" /> <path d="M 87.203186,57.153314 C 89.66824,61.446409 89.810243,65.993509 87.521193,67.307538 C 85.231142,68.621567 81.376058,66.207513 78.912003,61.914419 C 76.445949,57.622325 76.304946,53.075225 78.594996,51.761196 C 80.884047,50.446167 84.738132,52.86122 87.203186,57.153314 z " id="path452" style="fill:url(#radialGradient8730)" /> <path d="M 42.030192,75.002707 C 42.030192,75.002707 42.084193,74.976706 42.183195,74.927705 C 43.050214,74.499696 47.37831,72.359649 48.829342,71.675634 C 50.391376,70.939618 51.421399,71.671634 53.680448,73.094665 C 53.75745,73.144666 53.836452,73.193667 53.916454,73.242668 L 56.104502,73.242668 L 57.436531,75.289713 C 57.436531,75.289713 59.100568,76.667744 58.481554,77.808769 C 58.481554,77.808769 59.813583,79.996817 58.861562,81.375847 C 58.861562,81.375847 57.293528,87.649985 53.156437,87.608984 C 53.093435,87.608984 53.029434,87.606984 52.966433,87.602984 C 48.687338,87.364979 48.544335,87.744987 47.83132,88.079995 C 47.83132,88.079995 46.167283,85.653941 45.406266,85.177931 C 44.64525,84.70392 44.074237,85.034928 44.074237,85.034928 C 44.074237,85.034928 41.649184,83.181887 43.029214,79.710811 L 42.030192,75.002707 z " id="path465" style="fill:url(#radialGradient8727)" /> <path d="M 43.630227,65.778504 L 42.235197,58.932353 C 39.572138,54.368253 35.768054,59.312362 35.768054,59.312362 C 35.768054,59.312362 34.374024,61.720415 33.74001,68.695568 C 33.105996,75.668722 41.47418,70.721613 41.727185,69.836593 C 41.980191,68.949574 43.375222,65.778504 43.375222,65.778504 L 43.630227,65.778504 L 43.630227,65.778504 z " id="path478" style="fill:url(#radialGradient8724)" /> <path d="M 92.952312,69.710591 C 92.952312,69.710591 91.685284,60.073379 89.65724,58.170337 C 89.65724,58.170337 83.354101,56.866308 83.190098,61.97442 C 83.063095,65.905507 85.090139,66.540521 85.726153,67.552543 C 86.360167,68.567565 87.37319,72.117643 87.37319,73.385671 C 87.37419,73.386671 92.572304,74.779702 92.952312,69.710591 z " id="path491" style="fill:url(#radialGradient8721)" /> <path d="M 38.051104,98.998235 C 36.783077,96.716185 37.417091,95.322154 37.290088,94.434134 C 37.164085,93.547115 41.348177,94.180129 41.855188,93.675118 C 42.362199,93.165107 46.546291,93.801121 48.829342,98.998235 C 48.829342,98.998235 49.969367,102.54931 50.603381,102.93032 C 50.603381,102.93032 51.111392,108.63545 46.293286,107.11441 C 46.293286,107.11441 44.898255,105.46538 43.503224,105.46538 C 43.504224,105.46438 39.319132,101.28029 38.051104,98.998235 z " id="path504" style="fill:url(#radialGradient8718)" /> <path d="M 78.624997,106.7324 C 78.624997,106.7324 75.455927,95.323154 86.360167,92.913101 C 86.360167,92.913101 89.910245,93.548115 89.403234,97.099193 C 89.403234,97.099193 85.217142,102.55031 84.331123,105.21137 C 84.331123,105.21037 82.303078,107.87443 78.624997,106.7324 z " id="path517" style="fill:url(#radialGradient8715)" /> <path d="M 57.070523,105.84639 C 57.070523,105.84639 58.465554,106.4814 59.478576,105.46438 C 60.493598,104.45135 59.22557,103.18233 59.22557,103.18233 C 59.22557,103.18233 56.562512,102.54931 56.562512,101.02828 C 56.563512,101.02728 55.929498,104.07035 57.070523,105.84639 z " id="path530" style="fill:url(#radialGradient8712)" /> <path d="M 68.73478,106.09939 C 68.73478,106.09939 66.706735,104.57836 66.453729,103.81734 C 66.200724,103.05632 69.749802,103.43833 70.257813,102.1703 C 70.763824,100.90128 71.01783,105.46438 68.73478,106.09939 z " id="path543" style="fill:url(#radialGradient8709)" /> <path d="M 73.173877,90.378045 C 72.285858,89.743031 72.793869,87.078973 70.511819,87.206975 C 68.228768,87.334978 70.511819,86.826967 70.511819,86.826967 C 70.511819,86.826967 68.355771,87.206975 68.355771,83.402892 C 68.355771,79.599808 66.834738,77.443761 67.594754,76.93675 C 68.355771,76.428738 68.73578,77.443761 69.115788,76.682744 C 69.495796,75.921727 70.636821,71.357627 74.186899,71.357627 C 77.736978,71.357627 76.723955,72.625655 78.752,72.625655 C 80.781045,72.625655 81.92207,73.514674 82.556084,75.668722 C 83.190098,77.825769 84.837134,75.415716 83.951114,82.516872 C 83.063095,89.618028 79.386014,86.827967 79.386014,86.827967 L 77.484972,91.391067 C 77.484972,91.391067 76.850958,86.574962 75.58393,87.713987 C 74.313902,88.855012 73.173877,90.378045 73.173877,90.378045 z " id="path556" style="fill:url(#radialGradient8706)" /> <path d="M 44.582248,35.834845 L 43.959234,36.749865 C 43.958234,36.749865 43.958234,36.750865 43.958234,36.750865 C 43.958234,36.750865 44.077237,39.055916 46.263285,39.055916 C 46.263285,39.055916 47.622315,39.154918 48.067325,37.251876 L 52.37742,35.811845 C 52.37742,35.811845 56.113502,34.185809 56.113502,31.122742 L 56.109502,31.119742 C 54.087457,30.619731 52.303418,29.931715 50.865386,29.100697 C 48.431333,31.152742 46.231284,33.512794 44.582248,35.834845 z " id="path565" style="fill:url(#radialGradient8703)" /> <path d="M 44.582248,36.722865 C 46.231284,34.400814 48.042324,32.583774 50.478378,30.531729 C 52.39142,31.636753 56.056501,31.419748 56.056501,31.419748 C 56.056501,31.606752 56.0415,31.789756 56.0155,31.96976 C 56.078501,31.700754 56.114502,31.418748 56.114502,31.122742 L 56.110502,31.119742 C 54.088457,30.619731 52.304418,29.931715 50.866386,29.100697 C 48.432333,31.153742 46.232284,33.513794 44.582248,35.835845 L 43.959234,36.750865 C 43.958234,36.750865 43.958234,36.751865 43.958234,36.751865 C 43.958234,36.751865 43.975235,37.051872 44.097237,37.43488 L 44.582248,36.722865 z " id="path572" style="fill:url(#radialGradient8700)" /> <path d="M 76.755956,29.099697 C 75.319924,29.929715 73.535885,30.617731 71.517841,31.117742 L 71.513841,31.119742 C 71.513841,31.119742 72.666866,36.362857 79.704021,36.362857 C 79.704021,36.362857 81.794067,41.460969 84.046116,37.358879 C 82.346079,34.566817 79.727021,31.604752 76.755956,29.099697 z " id="path581" style="fill:url(#radialGradient8697)" /> <path d="M 71.905849,31.418748 C 73.924894,30.918737 75.413926,30.854736 76.850958,30.023717 C 79.782023,32.495772 82.030072,35.12983 83.721109,37.88289 C 83.828112,37.726887 83.937114,37.555883 84.045116,37.358879 C 82.346079,34.566817 79.727021,31.604752 76.754956,29.099697 C 75.318924,29.929715 73.534885,30.617731 71.516841,31.117742 L 71.512841,31.119742 C 71.512841,31.119742 71.550841,31.284745 71.647844,31.552751 L 71.905849,31.418748 z " id="path588" style="fill:url(#radialGradient8694)" /> <path d="M 44.264241,47.141094 C 44.264241,47.141094 32.091973,57.792328 33.106996,73.514674 C 34.121018,89.23602 35.643052,93.801121 38.686118,99.380243 C 41.729185,104.95737 52.205416,116.02861 56.436509,116.62262 C 60.667602,117.21964 60.747604,115.35459 62.015632,114.08657 C 63.28266,112.81854 54.407464,108.50744 47.307308,104.95737 C 40.206152,101.40829 38.431113,96.590182 37.164085,90.250042 C 35.896057,83.909903 36.656074,77.825769 35.389046,70.722613 C 34.121018,63.623457 41.981191,49.423144 44.771252,49.170139 C 47.561314,48.916133 44.264241,47.141094 44.264241,47.141094 z " id="path632" style="fill:url(#radialGradient8691)" /> <path d="M 69.179789,102.94032 C 69.179789,102.94032 64.803693,103.96634 57.957542,102.59731 C 51.111392,101.23128 66.897739,119.69469 69.179789,102.94032 z " id="path666" style="fill:url(#linearGradient8688)" /> <path d="M 60.620601,47.521102 C 60.620601,47.521102 43.700229,110.41649 50.237373,114.82258 L 54.789473,117.31764 C 56.688514,118.12966 58.654558,118.70167 60.666602,118.99367 C 61.703625,119.14468 62.751648,117.70065 63.810671,117.70065 C 63.898673,117.70065 63.987675,117.71465 64.076677,117.73165 C 64.065677,117.59564 64.056677,117.46364 64.043676,117.31964 C 63.663668,113.32555 63.473664,101.15428 63.854672,99.25224 C 64.23368,97.351199 64.804693,83.276889 64.425685,78.33078 C 64.044676,73.386671 64.804693,55.889286 64.995697,52.466211 C 65.184701,49.043136 60.620601,47.521102 60.620601,47.521102 z " id="path693" style="fill:url(#linearGradient8685)" /> <path d="M 67.257747,47.758108 C 65.189702,47.892111 63.811671,47.939112 63.811671,47.939112 C 63.811671,47.939112 62.37864,47.89011 60.240593,47.750107 L 60.240593,49.827153 C 60.240593,49.827153 55.930498,52.746217 55.676492,55.13527 C 55.423487,57.523322 57.071523,59.912375 57.071523,59.912375 L 56.564512,60.177381 L 58.085545,61.371407 C 59.986587,64.026465 63.917674,62.830439 63.917674,62.830439 C 66.96074,65.220492 71.779846,60.839395 71.779846,60.839395 C 74.187899,57.654325 71.145833,51.9482 71.145833,51.9482 C 67.545753,49.868154 67.201746,48.378121 67.257747,47.758108 z " id="path706" style="fill:url(#radialGradient8682)" /> <circle cx="37.618999" cy="59.301998" r="11.792" id="circle651" style="fill:url(#radialGradient8669)" sodipodi:cx="37.618999" sodipodi:cy="59.301998" sodipodi:rx="11.792" sodipodi:ry="11.792" transform="matrix(1.000022,0,0,1.000022,13.30156,4.003145)" /> <path d="M 63.810671,117.70065 C 62.86865,117.70065 61.93363,118.84367 61.00761,118.98667 C 61.01961,118.98967 61.03461,118.99167 61.04761,118.99367 C 62.014632,119.13368 62.990653,117.88965 63.977675,117.72065 C 63.921674,117.71265 63.865672,117.70065 63.810671,117.70065 z " id="path708" style="fill:white" /> <path d="M 61.001609,47.521102 C 61.001609,47.521102 60.988609,47.567103 60.965609,47.653105 C 62.023632,48.088115 65.153701,49.618149 64.995697,52.465211 C 64.804693,55.888286 64.043676,73.385671 64.425685,78.32978 C 64.804693,83.275889 64.234681,97.350199 63.854672,99.25124 C 63.474664,101.15328 63.663668,113.32455 64.043676,117.31864 C 64.056677,117.45564 64.064677,117.57964 64.074677,117.70965 C 64.114678,117.70565 64.151679,117.69965 64.19068,117.69965 C 64.279681,117.69965 64.367683,117.71365 64.456685,117.73065 C 64.445685,117.59464 64.436685,117.46264 64.424685,117.31864 C 64.043676,113.32455 63.853672,101.15328 64.23368,99.25124 C 64.614689,97.350199 65.185701,83.275889 64.804693,78.32978 C 64.425685,73.385671 65.185701,55.888286 65.375706,52.465211 C 65.56571,49.042136 61.001609,47.521102 61.001609,47.521102 z " id="path710" style="opacity:0.3;fill:white" /> <path d="M 109.92669,60.454387 C 109.92669,60.454387 110.31669,62.133424 109.18267,61.721415 C 109.18267,61.721415 102.25352,55.662281 97.222406,56.536301 L 97.622415,57.820329 C 97.622415,57.820329 100.70348,59.860374 102.03451,59.622369 C 102.03451,59.622369 102.86753,60.14438 102.86753,60.620391 C 102.86753,61.096401 105.69559,62.071422 106.57561,61.52441 C 106.57561,61.52441 108.26365,61.810417 108.26365,63.283449 C 108.26365,63.283449 107.07462,63.996465 106.43361,63.616456 C 106.43361,63.616456 107.70564,65.649501 110.21269,63.141446 C 111.46072,61.891419 109.92669,60.454387 109.92669,60.454387 z " id="path712" style="opacity:0.3" /> <path d="M 27.939882,108.04543 L 27.813879,108.22344 C 27.812879,108.22344 27.86388,108.17044 27.939882,108.04543 z " id="path714" style="opacity:0.3" /> <path style="fill:url(#radialGradient8674);fill-opacity:1" id="path6763" d="M 84.839134,47.3951 C 84.839134,47.3951 97.39241,59.041356 95.236363,76.05073 C 95.236363,76.05073 93.206318,95.829165 87.628195,102.67732 C 87.628195,102.67732 79.007005,115.10159 71.398838,115.86261 C 71.398838,115.86261 67.340749,117.13263 65.819715,113.83456 C 65.819715,113.83456 64.552687,114.08757 69.624799,112.81954 C 74.695911,111.55251 79.514017,109.77847 83.064095,104.70636 C 86.614173,99.634249 89.404234,95.830165 88.642217,93.041104 C 87.882201,90.251042 90.418257,78.077775 92.446301,72.754658 C 94.475346,67.42954 88.136206,58.807351 85.727153,58.299339 C 83.3181,57.791328 84.839134,47.3951 84.839134,47.3951 z " /> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/reset_settings.svg���������������������������������������������������0000644�0001750�0000144�00000110002�11075400475�020300� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2606" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docname="undo_settings.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/Mp3TagDoctorQt4/src/images" inkscape:export-filename="edit-undo.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> <defs id="defs2608"> <linearGradient inkscape:collect="always" id="linearGradient3342"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3344" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3347" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3326"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3328" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3330" /> </linearGradient> <linearGradient id="linearGradient3825"> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="0" id="stop3827" /> <stop id="stop3833" offset="0.5" style="stop-color:#ffffff;stop-opacity:0.18705036;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop3829" /> </linearGradient> <linearGradient id="linearGradient3751"> <stop style="stop-color:#beba2c;stop-opacity:1;" offset="0" id="stop3753" /> <stop style="stop-color:#b6be2c;stop-opacity:0;" offset="1" id="stop3755" /> </linearGradient> <linearGradient id="linearGradient3528"> <stop style="stop-color:#eaf209;stop-opacity:1;" offset="0" id="stop3530" /> <stop style="stop-color:#c7c634;stop-opacity:0;" offset="1" id="stop3532" /> </linearGradient> <linearGradient id="linearGradient3295"> <stop style="stop-color:#fffe63;stop-opacity:1;" offset="0" id="stop3297" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3299" /> </linearGradient> <linearGradient id="linearGradient3202"> <stop style="stop-color:#fcff9c;stop-opacity:1;" offset="0" id="stop3204" /> <stop style="stop-color:#c1a965;stop-opacity:0;" offset="1" id="stop3206" /> </linearGradient> <radialGradient id="XMLID_4_" cx="48" cy="-0.2148" r="55.148" gradientTransform="matrix(0.9792,0,0,0.9725,133.0002,20.8762)" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#cfd13d;stop-opacity:1;" id="stop3082" /> <stop offset="1" style="stop-color:#db8900;stop-opacity:1;" id="stop3090" /> </radialGradient> <linearGradient id="linearGradient3260" inkscape:collect="always"> <stop id="stop3262" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop3264" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3344"> <stop id="stop3346" offset="0" style="stop-color:#fdff63;stop-opacity:1;" /> <stop id="stop3348" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient3449"> <stop id="stop3451" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop3453" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="linearGradient3516" x1="147.09375" y1="33.40625" x2="8.083992" y2="123.90625" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#XMLID_4_" id="radialGradient3524" cx="67.09375" cy="116.90625" fx="67.09375" fy="116.90625" r="56" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3528" id="radialGradient3535" cx="99.726295" cy="27.418272" fx="64.689766" fy="68.231934" r="56" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.693735,5.8671246e-2,-3.6242796e-2,0.4285387,33.939389,26.8809)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3548" x1="75.09375" y1="4.5317035" x2="75.09375" y2="80.172485" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3581" gradientUnits="userSpaceOnUse" gradientTransform="translate(4.2161108e-3,1.9705695e-3)" x1="75.09375" y1="4.5317035" x2="75.09375" y2="80.172485" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3613" x1="208.59375" y1="130.40625" x2="208.59375" y2="63.426777" gradientUnits="userSpaceOnUse" gradientTransform="translate(-137,0)" /> <filter inkscape:collect="always" id="filter3639"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.0580524" id="feGaussianBlur3641" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3654" cx="-10.165252" cy="66.906013" fx="-10.165252" fy="66.906013" r="59.995121" gradientTransform="matrix(0.4582893,-2.1035589e-8,4.5903973e-8,1.0000813,20.447953,-5.1974351e-3)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3658" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.2676699,0.521376,-0.7037472,0.3612977,108.99386,-36.062981)" cx="167.67001" cy="80.404922" fx="167.67001" fy="80.404922" r="59.995121" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="linearGradient3676" x1="120.0625" y1="12.569496" x2="125.30366" y2="14.444496" gradientUnits="userSpaceOnUse" spreadMethod="reflect" /> <filter inkscape:collect="always" x="-0.15096202" width="1.301924" y="-0.13732364" height="1.2746473" id="filter3738"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.39257441" id="feGaussianBlur3740" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3449" id="radialGradient3744" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.982366,1.671718e-2,-3.5801148e-3,0.2103843,-18.56344,30.477792)" cx="72.684891" cy="48.228905" fx="74.871155" fy="26.862719" r="59.995121" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3751" id="radialGradient3757" cx="66.01458" cy="126.69183" fx="66.01458" fy="126.69183" r="59.99512" gradientTransform="matrix(0.675025,0,0,0.3583625,19.527377,41.004647)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3260" id="radialGradient3767" cx="64.088867" cy="7.4108429" fx="64.088867" fy="7.4108429" r="59.995121" gradientTransform="matrix(0.3093869,0,0,0.4779247,44.260611,3.8644223)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3344" id="linearGradient3771" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="120.0625" y1="12.569496" x2="125.30366" y2="14.444496" /> <filter inkscape:collect="always" id="filter3438"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.3342697" id="feGaussianBlur3440" /> </filter> <filter inkscape:collect="always" id="filter3630"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.89883985" id="feGaussianBlur3632" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient2361" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2363" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2365" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient2367" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3349" x1="-73" y1="105.625" x2="-163" y2="86.125" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" x="-0.087741371" width="1.1754827" y="-0.10211017" height="1.2042203" id="filter3363"> <feGaussianBlur inkscape:collect="always" stdDeviation="3.0526685" id="feGaussianBlur3365" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3372" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3376" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient3388" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3390" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3392" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3394" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3396" gradientUnits="userSpaceOnUse" x1="-73" y1="105.625" x2="-163" y2="86.125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3398" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3400" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3825" id="radialGradient3422" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6484284,0.1017206,-3.1257154e-2,0.1992521,-4.56257,53.15916)" cx="-112.17241" cy="118.60459" fx="-113.14772" fy="59.708473" r="59.99512" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3424" gradientUnits="userSpaceOnUse" x1="-151.43935" y1="37.68198" x2="-152.26776" y2="57.25" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3426" gradientUnits="userSpaceOnUse" x1="-132.51041" y1="39.803303" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3326" id="linearGradient3428" gradientUnits="userSpaceOnUse" x1="-83.012932" y1="44.753052" x2="-158.92462" y2="72.881729" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3430" gradientUnits="userSpaceOnUse" x1="-73" y1="105.625" x2="-163" y2="86.125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3432" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-83.593941" y1="137.13324" x2="-138.0043" y2="92.603989" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3342" id="linearGradient3434" gradientUnits="userSpaceOnUse" gradientTransform="translate(-40.5,-1.5)" x1="-61.802711" y1="99.979607" x2="-136.51074" y2="112.70422" /> <mask maskUnits="userSpaceOnUse" id="mask3402"> <g id="g3404" transform="translate(167.50257,-3.755156e-3)"> <g id="g3406" transform="translate(80.51637,30.885255)"> <path style="opacity:1;fill:url(#radialGradient3422);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M -184.42232,-32.47243 C -217.54751,-32.47243 -248.42232,-0.097625 -248.42232,33.02757 C -248.42232,66.15276 -217.04751,97.02757 -183.92232,97.02757 C -153.6332,97.02757 -128.58571,70.81131 -124.51607,41.68382 L -159.54732,36.65257 C -161.172,48.6137 -171.47739,57.62132 -183.92232,57.62132 C -197.49395,57.62132 -206.01607,46.0992 -206.01607,32.52757 C -206.01607,18.955936 -199.99395,12.43382 -186.42232,12.43382 C -179.6365,12.433819 -176.50103,10.198864 -172.04732,14.65257 L -176.8745,25.979749 C -178.93037,28.035619 -179.11822,29.285529 -178.55411,30.595278 C -178.04554,31.776057 -177.03338,33.12132 -174.34438,33.12132 L -130.39107,33.12132 C -126.54518,33.12132 -123.93208,30.466941 -123.93208,26.871189 L -124.00095,-17.206829 C -124.00095,-19.687584 -124.90346,-21.050058 -126.18242,-21.556444 C -127.49674,-22.076829 -129.21563,-21.679122 -131.28951,-19.605244 L -141.48482,-19.40993 C -152.34417,-30.269281 -167.85972,-32.47243 -184.42232,-32.47243 z " id="path3408" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="ccccc" style="fill:url(#linearGradient3424);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" d="M -161.5,34.5 C -162,37 -180,54 -180,54 L -132.5,80 L -112,38.5 L -161.5,34.5 z " id="path3410" /> <path sodipodi:nodetypes="ccccc" id="path3412" d="M -161.5,34.5 C -162,37 -181.27817,54.389087 -181.27817,54.389087 L -151.62742,97.591883 L -112,38.5 L -161.5,34.5 z " style="fill:url(#linearGradient3426);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" /> <path style="fill:url(#linearGradient3428);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3438)" d="M -161.5,34.5 C -162,37 -181.27817,54.389087 -181.27817,54.389087 L -151.62742,97.591883 L -112,38.5 L -161.5,34.5 z " id="path3414" sodipodi:nodetypes="ccccc" /> </g> <rect y="69.75" x="-119" height="71.75" width="83.5" id="rect3416" style="opacity:1;fill:url(#linearGradient3430);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" /> <path sodipodi:nodetypes="ccccc" id="path3418" d="M -159.5,68.25 L -39.138259,55.983708 L -93.453327,162.55286 L -197.79465,128.96507 L -159.5,68.25 z " style="fill:url(#linearGradient3432);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" transform="matrix(0.6393762,0.7688941,-0.7688941,0.6393762,37.597642,128.08723)" /> <path transform="matrix(0.6393762,0.7688941,-0.7688941,0.6393762,37.597642,128.08723)" style="fill:url(#linearGradient3434);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3363)" d="M -159.5,68.25 L -39.138259,55.983708 L -93.453327,162.55286 L -197.79465,128.96507 L -159.5,68.25 z " id="path3420" sodipodi:nodetypes="ccccc" /> </g> </mask> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3751" id="linearGradient3565" x1="-267.47665" y1="18.103027" x2="-33.476654" y2="18.103027" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3295" id="linearGradient3567" gradientUnits="userSpaceOnUse" gradientTransform="translate(-137,0)" x1="208.59375" y1="130.40625" x2="208.59375" y2="63.426777" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="4.6484375" inkscape:cx="64" inkscape:cy="64" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" gridspacingx="4px" gridspacingy="4px" gridempspacing="2" showgrid="false" inkscape:grid-points="true" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1600" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="33" /> <metadata id="metadata2611"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1"> <g id="g3835" mask="url(#mask3402)" transform="matrix(-1,0,0,1,128.17774,0)"> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="rect3204" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:1;fill:url(#linearGradient3516);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:0.79775277;fill:url(#radialGradient3757);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " id="path3749" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="path3656" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:0.68913861;fill:url(#radialGradient3658);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:1;fill:url(#radialGradient3654);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " id="path3643" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cssccsssccsccccsccc" id="path3742" d="M 64.09375,3.90625 C 30.968558,3.9062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,3.90625 64.09375,3.90625 z " style="opacity:0.79775277;fill:url(#radialGradient3744);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:0.74531836;fill:url(#radialGradient3767);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3630)" d="M 64.09375,4.20625 C 30.968558,4.2062499 4.0937499,30.781055 4.09375,63.90625 C 4.0937501,97.031442 30.96856,123.90625 64.09375,123.90625 C 94.382866,123.90625 119.43036,101.68999 123.5,72.5625 L 88.46875,67.53125 C 86.844066,79.492379 76.538676,88.5 64.09375,88.5 C 50.522122,88.499999 39.5,77.477881 39.5,63.90625 C 39.500001,50.334616 50.522119,39.3125 64.09375,39.3125 C 70.879568,39.312499 77.015044,42.077544 81.46875,46.53125 L 71.141571,56.858429 C 69.085701,58.914299 68.897846,60.164209 69.461963,61.473958 C 69.970531,62.654737 70.982695,64 73.671688,64 L 117.625,64 C 121.47089,64 124.08399,61.345621 124.08399,57.749869 L 124.01512,13.671851 C 124.01512,11.191096 123.11261,9.8286218 121.83365,9.3222363 C 120.51933,8.8018514 118.80044,9.1995576 116.72656,11.273436 L 106.53125,21.46875 C 95.671902,10.609399 80.656349,4.20625 64.09375,4.20625 z " id="path3759" sodipodi:nodetypes="cssccsssccsccccsccc" /> <path sodipodi:nodetypes="cccczc" id="path3660" d="M 117.6875,10.75 L 118.625,15.125 L 119.875,16 L 123.875,13.375 C 124.12188,11.651249 123.52383,10.027571 121.9375,9.3749999 C 120.35116,8.7224285 118.77622,9.5017032 117.6875,10.75 z " style="opacity:0.82022472;fill:url(#linearGradient3676);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3738)" /> <path transform="matrix(0,1,1,0,60.363582,-60.363586)" style="opacity:0.82022472;fill:url(#linearGradient3771);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3738)" d="M 117.6875,10.75 L 119.875,13.875 L 120.375,13.75 L 123.875,13.375 C 124.12188,11.651249 123.52383,10.027571 121.9375,9.3749999 C 120.35116,8.7224285 118.77622,9.5017032 117.6875,10.75 z " id="path3769" sodipodi:nodetypes="cccczc" /> <path id="path3494" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.0937501,94.867948 33.132054,119.90625 64.09375,119.90625 C 91.026646,119.90625 113.21548,101.0995 118.625,75.90625 L 91.5,72.03125 C 88.061436,83.928551 77.059621,92.5 64.09375,92.5 C 48.356404,92.499999 35.5,79.643599 35.5,63.90625 C 35.500001,48.168899 48.356402,35.3125 64.09375,35.3125 C 71.966166,35.312499 79.145304,38.520304 84.3125,43.6875 C 85.071964,44.438909 85.499997,45.462886 85.5,46.53125 C 85.5,47.599614 85.071964,48.623591 84.3125,49.375 L 73.6875,60 L 117.625,60 C 119.63039,60 120.09375,59.407836 120.09375,57.75 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " style="opacity:1;fill:url(#radialGradient3524);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path style="opacity:1;fill:url(#radialGradient3535);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.0937501,94.867948 33.132054,119.90625 64.09375,119.90625 C 91.026646,119.90625 113.21548,101.0995 118.625,75.90625 L 91.5,72.03125 C 88.061436,83.928551 77.059621,92.5 64.09375,92.5 C 48.356404,92.499999 35.5,79.643599 35.5,63.90625 C 35.500001,48.168899 48.356402,35.3125 64.09375,35.3125 C 71.966166,35.312499 79.145304,38.520304 84.3125,43.6875 C 85.071964,44.438909 85.499997,45.462886 85.5,46.53125 C 85.5,47.599614 85.071964,48.623591 84.3125,49.375 L 73.6875,60 L 117.625,60 C 119.63039,60 120.09375,59.407836 120.09375,57.75 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " id="path3526" /> <path sodipodi:nodetypes="csccssccccccscc" id="path3537" d="M 64.09375,7.90625 C 33.132052,7.9062499 8.0937499,32.944549 8.09375,63.90625 C 8.09375,64.474122 8.1082724,65.029981 8.125,65.59375 C 14.11447,66.271402 20.266218,66.74388 26.53125,67 C 26.260548,56.540958 30.202859,46.025084 38.34375,38.21875 C 53.683067,23.509813 78.072313,24.004431 92.78125,39.34375 C 95.545099,42.226046 97.537852,45.032117 99.34375,48.59375 L 78.84375,59 L 98,59 C 105.9282,56.973373 113.18621,55.563033 120.09375,52.8125 L 120,13.65625 L 109.375,24.3125 C 108.62359,25.071964 107.59961,25.5 106.53125,25.5 C 105.46289,25.5 104.43891,25.071964 103.6875,24.3125 C 93.549835,14.174833 79.577106,7.90625 64.09375,7.90625 z " style="opacity:1;fill:url(#linearGradient3548);fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path sodipodi:nodetypes="cscscscccccccccccssssssccscscc" id="path3553" d="M 64.099866,7.9087646 C 33.138176,7.9087644 8.0998661,32.947063 8.0998661,63.908764 C 8.0998761,64.087476 8.0973761,64.263059 8.0998661,64.440014 C 8.3531061,33.696509 33.295846,8.9087645 64.099866,8.9087646 C 79.583236,8.9087645 93.555946,15.177347 103.69361,25.315014 C 104.44503,26.074479 105.469,26.502514 106.53736,26.502514 C 107.60573,26.502515 108.6297,26.074478 109.38111,25.315014 L 119.50611,15.158764 L 119.99986,52.708764 C 113.09232,55.459294 105.43431,56.569624 97.506116,58.596264 L 78.849866,59.002514 L 98.006116,59.002514 C 105.93431,56.975884 113.19232,55.565544 120.09986,52.815014 L 120.00611,14.658764 L 120.00611,13.658764 L 119.50611,14.158764 L 109.38111,24.315014 C 108.62971,25.074479 107.60572,25.502514 106.53736,25.502514 C 105.46901,25.502515 104.44502,25.074478 103.69361,24.315014 C 103.68314,24.304548 103.67283,24.294222 103.66236,24.283764 C 103.60999,24.231473 103.55869,24.179598 103.50611,24.127514 C 102.93231,23.559643 102.35524,23.012364 101.75611,22.471264 C 101.67459,22.397145 101.58807,22.326157 101.50611,22.252514 C 91.590066,13.342335 78.496526,7.9087646 64.099866,7.9087646 z M 63.443616,27.127514 C 54.205446,27.378034 45.040176,30.920194 37.849866,37.815014 C 30.217786,45.133448 26.722316,55.187931 26.537366,65.033764 C 26.777246,55.231884 30.717786,45.539698 38.349866,38.221264 C 51.665996,25.452364 71.803196,24.123207 86.506116,34.033764 C 79.627056,29.22869 71.518656,26.908534 63.443616,27.127514 z " style="opacity:1;fill:url(#linearGradient3581);fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> <path id="path3603" d="M 63.59375,7.90625 C 32.63205,7.9062499 7.59375,32.944549 7.59375,63.90625 C 7.59375,94.867948 32.63205,119.90625 63.59375,119.90625 C 90.52665,119.90625 112.71548,101.0995 118.125,75.90625 L 91,72.03125 C 87.56144,83.928551 76.55962,92.5 63.59375,92.5 C 47.8564,92.499999 35,79.643599 35,63.90625 C 35,48.168899 47.8564,35.3125 63.59375,35.3125 C 71.46617,35.312499 78.6453,38.520304 83.8125,43.6875 C 84.57196,44.438909 85,45.462886 85,46.53125 C 85,47.599614 84.57196,48.623591 83.8125,49.375 L 73.1875,60 L 117.125,60 C 119.13039,60 119.59375,59.407836 119.59375,57.75 L 119.5,13.65625 L 108.875,24.3125 C 108.12359,25.071964 107.09961,25.5 106.03125,25.5 C 104.96289,25.5 103.93891,25.071964 103.1875,24.3125 C 93.04984,14.174833 79.07711,7.90625 63.59375,7.90625 z " style="opacity:1;fill:none;fill-opacity:1;stroke:url(#linearGradient3567);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1;filter:url(#filter3639)" /> </g> <path sodipodi:type="star" style="fill:#ffff00;fill-opacity:1" id="path2263" sodipodi:sides="10" sodipodi:cx="-30.763025" sodipodi:cy="31.408403" sodipodi:r1="35.454052" sodipodi:r2="14.181621" sodipodi:arg1="0.91880028" sodipodi:arg2="1.2329595" inkscape:flatsided="false" inkscape:rounded="0" inkscape:randomized="0" d="M -9.2504206,59.589916 L -26.06257,44.788392 L -29.92364,66.852518 L -34.824837,44.995899 L -50.917476,60.576673 L -42.03563,40.013446 L -64.212997,43.15954 L -44.940671,31.744158 L -64.731765,21.253873 L -42.430333,23.346624 L -52.27563,3.226891 L -35.46348,18.028415 L -31.602411,-4.0357108 L -26.701214,17.820907 L -10.608575,2.2401342 L -19.490421,22.803361 L 2.6869461,19.657267 L -16.58538,31.072649 L 3.2057149,41.562934 L -19.095717,39.470183 L -9.2504206,59.589916 z " transform="translate(70.346218,55.932773)" /> </g> </svg> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/images/logo.svg�������������������������������������������������������������0000644�0001750�0000144�00000023435�11206457071�016213� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="184" height="184" id="svg2" sodipodi:version="0.32" inkscape:version="0.46" version="1.0" sodipodi:docbase="/home/ciobi/cpp/Mp3Utils/MP3Diags/src/images" sodipodi:docname="logo.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 92 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="184 : 92 : 1" inkscape:persp3d-origin="92 : 61.333333 : 1" id="perspective22" /> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2200"> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M -974.28571,75.219323 L 591.42857,75.219323 L 591.42857,1200.9336 L -974.28571,1200.9336 L -974.28571,75.219323 z " id="path2202" /> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2208"> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M -965.71429,75.219323 L 580,75.219323 L 580,1200.9336 L -965.71429,1200.9336 L -965.71429,75.219323 z " id="path2210" /> </clipPath> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8" inkscape:cx="191.13664" inkscape:cy="60.93956" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" showguides="true" inkscape:guide-bbox="true" width="184px" height="184px" inkscape:window-width="1592" inkscape:window-height="1098" inkscape:window-x="0" inkscape:window-y="0" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(731.90603,-336.5424)"> <g id="g2311" transform="matrix(1.2959182,0,0,1.2092152,-80.048211,-110.14351)" style="fill:#e6e6e6"> <rect style="fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect2313" width="140" height="100.00002" x="-501.90604" y="395.54239" /> <path sodipodi:type="arc" style="fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path2315" sodipodi:cx="264.10715" sodipodi:cy="215.42857" sodipodi:rx="38.75" sodipodi:ry="28.214285" d="M 283.48215,239.86286 A 38.75,28.214285 0 0 1 244.73215,239.86286" transform="matrix(3.6129035,0,0,2.2841675,-1386.0997,-52.344552)" sodipodi:start="1.0471976" sodipodi:end="2.0943951" sodipodi:open="true" /> <path sodipodi:open="true" sodipodi:end="2.0943951" sodipodi:start="1.0471976" transform="matrix(-3.6129035,0,0,-2.2841675,522.28761,943.42935)" d="M 283.48215,239.86286 A 38.75,28.214285 0 0 1 244.73215,239.86286" sodipodi:ry="28.214285" sodipodi:rx="38.75" sodipodi:cy="215.42857" sodipodi:cx="264.10715" id="path2317" style="fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" sodipodi:type="arc" /> </g> <path sodipodi:type="arc" style="fill:#800000;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path2302" sodipodi:cx="297.14285" sodipodi:cy="232.21428" sodipodi:rx="0" sodipodi:ry="2.8571429" d="M 297.14285,233.64285 A 0,2.8571429 0 0 1 297.14285,233.64285" transform="translate(-731.90603,336.5424)" sodipodi:start="0.52359878" sodipodi:end="2.6179939" sodipodi:open="true" /> <g id="g2306" transform="matrix(1.1785714,0,0,1.060642,-131.44537,-43.44719)"> <rect y="395.54239" x="-501.90604" height="100.00002" width="140" id="rect2286" style="fill:#800000;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> <path sodipodi:open="true" sodipodi:end="2.0943951" sodipodi:start="1.0471976" transform="matrix(3.6129035,0,0,2.2841675,-1386.0997,-52.344552)" d="M 283.48215,239.86286 A 38.75,28.214285 0 0 1 244.73215,239.86286" sodipodi:ry="28.214285" sodipodi:rx="38.75" sodipodi:cy="215.42857" sodipodi:cx="264.10715" id="path2300" style="fill:#800000;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" sodipodi:type="arc" /> <path sodipodi:type="arc" style="fill:#800000;fill-opacity:1;stroke:none;stroke-width:21.10000038;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path2304" sodipodi:cx="264.10715" sodipodi:cy="215.42857" sodipodi:rx="38.75" sodipodi:ry="28.214285" d="M 283.48215,239.86286 A 38.75,28.214285 0 0 1 244.73215,239.86286" transform="matrix(-3.6129035,0,0,-2.2841675,522.28761,943.42935)" sodipodi:start="1.0471976" sodipodi:end="2.0943951" sodipodi:open="true" /> </g> <path style="font-size:82.37410736px;font-style:normal;font-weight:bold;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Tahoma" d="M -706.16909,390.0008 L -691.91737,390.0008 L -682.02843,430.16738 L -672.08131,390.0008 L -657.85868,390.0008 L -657.85868,465.05548 L -668.44567,465.05548 L -668.44567,410.1595 L -678.45096,450.62769 L -685.54772,450.62769 L -695.55301,410.1595 L -695.55301,465.05548 L -706.16909,465.05548 L -706.16909,390.0008 M -646.83541,390.0008 L -628.25002,390.0008 C -622.72387,390.00088 -618.48714,392.12902 -615.5398,396.38522 C -612.57316,400.60806 -611.08982,406.64058 -611.08977,414.48281 C -611.08982,422.35865 -612.57316,428.42468 -615.5398,432.68093 C -618.48714,436.90372 -622.72387,439.0151 -628.25002,439.01507 L -635.63764,439.01507 L -635.63764,465.05548 L -646.83541,465.05548 L -646.83541,390.0008 M -635.63764,404.02643 L -635.63764,424.98946 L -629.4425,424.98946 C -627.27083,424.98949 -625.5936,424.08462 -624.41078,422.27482 C -623.22801,420.4316 -622.63661,417.83425 -622.63658,414.48281 C -622.63661,411.13145 -623.22801,408.55088 -624.41078,406.74106 C -625.5936,404.93137 -627.27083,404.02649 -629.4425,404.02643 L -635.63764,404.02643 M -580.92849,424.58729 C -578.00062,425.89437 -575.78045,428.17333 -574.268,431.42415 C -572.73621,434.64153 -571.97031,438.74699 -571.97027,443.74056 C -571.97031,451.18068 -573.61846,456.84455 -576.91473,460.73217 C -580.21108,464.58629 -585.01982,466.51334 -591.34096,466.51334 C -593.57084,466.51334 -595.8104,466.19495 -598.05963,465.55819 C -600.2895,464.95494 -602.49997,464.0333 -604.69105,462.79328 L -604.69105,447.86278 C -602.59693,449.67255 -600.52218,451.04663 -598.46683,451.98501 C -596.39209,452.8899 -594.35614,453.34234 -592.35895,453.34233 C -589.39228,453.34234 -587.12364,452.45421 -585.55303,450.67797 C -583.96306,448.90173 -583.16807,446.35467 -583.16805,443.03676 C -583.16807,439.61835 -583.98245,437.03778 -585.6112,435.29503 C -587.22059,433.51881 -589.60557,432.63069 -592.76614,432.63065 L -597.24525,432.63065 L -597.24525,420.16343 L -592.53346,420.16343 C -589.72192,420.16348 -587.62779,419.40941 -586.25107,417.90124 C -584.8744,416.35964 -584.18605,414.03041 -584.18603,410.91357 C -584.18605,408.03141 -584.85501,405.80273 -586.1929,404.22751 C -587.53083,402.65241 -589.42137,401.86483 -591.8645,401.86477 C -593.66779,401.86483 -595.49046,402.21674 -597.3325,402.92047 C -599.17457,403.62432 -601.00694,404.66325 -602.8296,406.03727 L -602.8296,391.86084 C -600.61914,390.78846 -598.42806,389.98413 -596.25636,389.44783 C -594.08468,388.91167 -591.95178,388.64357 -589.85762,388.64349 C -584.21514,388.64357 -579.99779,390.25223 -577.20559,393.4695 C -574.39406,396.65342 -572.98829,401.46267 -572.98825,407.8973 C -572.98829,412.28769 -573.65725,415.89045 -574.99512,418.70557 C -576.33307,421.48728 -578.31086,423.44786 -580.92849,424.58729" id="text2282" /> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/TagEdtPatternsDlgImpl.cpp���������������������������������������������������0000644�0001750�0000144�00000013665�11477265265�020153� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QMessageBox> #include "TagEdtPatternsDlgImpl.h" #include "Helpers.h" #include "SongInfoParser.h" #include "StoredSettings.h" using namespace std; TagEdtPatternsDlgImpl::TagEdtPatternsDlgImpl(QWidget* pParent, SessionSettings& settings, const vector<string>& vstrPredef) : QDialog(pParent, getDialogWndFlags()), Ui::PatternsDlg(), m_settings(settings), m_vstrPredef(vstrPredef), m_nCrtLine(-1), m_nCrtCol(-1) { setupUi(this); QPalette grayPalette (m_infoM->palette()); grayPalette.setColor(QPalette::Base, grayPalette.color(QPalette::Disabled, QPalette::Window)); m_infoM->setPalette(grayPalette); m_infoM->setTabStopWidth(fontMetrics().width("%ww")); #ifndef WIN32 QString qsSep (getPathSep()); #else QString qsSep ("\\"); #endif m_infoM->setText("%n\ttrack number\n%a\tartist\n%t\ttitle\n%b\talbum\n%y\tyear\n%g\tgenre\n%r\trating (a lowercase letter)\n%c\tcomposer\n%i\tignored" "\n\nTo include the special characters \"%\", \"[\", \"]\" and \"" + qsSep + "\", preced them by a \"%\": \"%%\", \"%[\", \"%]\" and \"%" + qsSep + "\"" "\n\nFor a pattern to be considered a \"file pattern\" (as opposed to a \"table pattern\"), it must contain at least a \"" + qsSep + "\", even if you don't care about what's in the file's parent directory (see the fourth predefined pattern for an example.)" "\n\nLeading and trailing spaces are removed automatically, so \"-[ ]%t\" is equivalent to \"-%t\""); //ttt0 improve wording - see https://sourceforge.net/projects/mp3diags/forums/forum/947207/topic/3962666: int nWidth, nHeight; m_settings.loadTagEdtPatternsSettings(nWidth, nHeight); if (nWidth > 400 && nHeight > 300) { resize(nWidth, nHeight); } connect(m_pTextM, SIGNAL(cursorPositionChanged()), this, SLOT(onCrtPosChanged())); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } TagEdtPatternsDlgImpl::~TagEdtPatternsDlgImpl() { } /*$SPECIALIZATION$*/ void TagEdtPatternsDlgImpl::on_m_pCancelB_clicked() { reject(); } void TagEdtPatternsDlgImpl::on_m_pOkB_clicked() { m_vPatterns.clear(); string s (convStr(m_pTextM->toPlainText())); const char* p (s.c_str()); if (0 == *p) { accept(); return; } for (; '\n' == *p; ++p) {} const char* q (p); for (;;) { if ('\n' == *p || 0 == *p) { string s1 (q, p - q); s1 = fromNativeSeparators(s1); string strCheck (SongInfoParser::testPattern(s1)); if (!strCheck.empty()) { QMessageBox::critical(this, "Error", convStr(strCheck)); return; } m_vPatterns.push_back(s1); for (; '\n' == *p; ++p) {} if (0 == *p) { break; } q = p; } ++p; } m_settings.saveTagEdtPatternsSettings(width(), height()); accept(); } bool TagEdtPatternsDlgImpl::run(vector<pair<string, int> >& v) { string s; for (int i = 0, n = cSize(v); i < n; ++i) { if (!s.empty()) { s += "\n"; } s += toNativeSeparators(v[i].first); } m_pTextM->setText(convStr(s)); if (QDialog::Accepted != exec()) { return false; } set<int> sPos; vector<pair<string, int> > v1; for (int i = 0, n = cSize(m_vPatterns); i < n; ++i) { int j (0); int m (cSize(v)); for (; j < m; ++j) { if (m_vPatterns[i] == v[j].first && sPos.end() == sPos.find(j)) { sPos.insert(j); break; } } if (m == j) { j = -1; } v1.push_back(make_pair(m_vPatterns[i], j)); } //v.clear(); v.swap(v1); return true; } void TagEdtPatternsDlgImpl::on_m_pAddPredefB_clicked() { string s (convStr(m_pTextM->toPlainText())); for (unsigned i = 0; i < m_vstrPredef.size(); ++i) { if (!s.empty() && !endsWith(s, "\n")) { s += "\n"; } s += toNativeSeparators(m_vstrPredef[i]); } m_pTextM->setText(convStr(s)); } void TagEdtPatternsDlgImpl::onHelp() { openHelp("220_tag_editor_patterns.html"); } void TagEdtPatternsDlgImpl::onCrtPosChanged() { QTextCursor crs (m_pTextM->textCursor()); m_nCrtLine = crs.blockNumber(); m_nCrtCol = crs.columnNumber(); m_pCrtPosL->setText(QString("Line %1, Col %2").arg(m_nCrtLine + 1).arg(m_nCrtCol + 1)); } ���������������������������������������������������������������������������MP3Diags-1.0.12.079/src/CommonTypes.cpp�������������������������������������������������������������0000644�0001750�0000144�00000034624�11310374564�016251� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <cmath> #include <map> #include <set> #include <QBuffer> #include <QPainter> #include "CommonTypes.h" #include "Helpers.h" #include "FullSizeImgDlg.h" using namespace std; ImageInfo::ImageInfo(int nImageType, Status eStatus, Compr eCompr, QByteArray compressedImg, int nWidth, int nHeight) : m_eCompr(eCompr), m_eStatus(eStatus), m_nWidth(nWidth), m_nHeight(nHeight), m_compressedImg(compressedImg), m_nImageType(nImageType) { } // the picture is scaled down, keeping the aspect ratio, if the limits are exceeded; 0 and negative limits are ignored; // if nMaxWidth>0 and nMaxHeight<=0, nMaxHeight has the same value as nMaxWidth; QImage ImageInfo::getImage(int nMaxWidth /*= -1*/, int nMaxHeight /*= -1*/) const { CB_ASSERT (NO_PICTURE_FOUND != m_eStatus); if (nMaxHeight <= 0) { nMaxHeight = nMaxWidth; } if (nMaxWidth <= 0) { nMaxWidth = nMaxHeight; } QImage pic; if (USES_LINK == m_eStatus || ERROR_LOADING == m_eStatus || !pic.loadFromData(m_compressedImg)) //ttt2 not sure how loadFromData() handles huge images; { if (nMaxWidth < 0) { nMaxWidth = m_nWidth; } if (nMaxHeight < 0) { nMaxHeight = m_nHeight; } if (nMaxWidth <= 0) { nMaxWidth = 200; } if (nMaxHeight <= 0) { nMaxHeight = 200; } QImage errImg (nMaxWidth, nMaxHeight, QImage::Format_ARGB32); QPainter pntr (&errImg); pntr.fillRect(0, 0, nMaxWidth, nMaxHeight, QColor(255, 128, 128)); pntr.drawRect(0, 0, nMaxWidth - 1, nMaxHeight - 1); //pntr.drawText(5, nMaxHeight/2 + 10, USES_LINK == m_eStatus ? "Link" : (ERROR_LOADING == m_eStatus ? "Error" : "Uncompr error")); pntr.drawText(QRectF(0, 0, nMaxWidth, nMaxHeight), Qt::AlignCenter | Qt::TextWordWrap, USES_LINK == m_eStatus ? "Link" : (ERROR_LOADING == m_eStatus ? "Error" : "Uncompr error")); return errImg; } if (nMaxWidth <= 0 || (pic.width() <= nMaxWidth && pic.height() <= nMaxHeight)) { return pic; } return pic.scaled(nMaxWidth, nMaxHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); } bool ImageInfo::operator==(const ImageInfo& other) const { return m_eCompr == other.m_eCompr /*&& m_eStatus == other.m_eStatus*/ && m_nWidth == other.m_nWidth && m_compressedImg == other.m_compressedImg; // !!! related to Id3V230StreamWriter::addImage() status is ignored in both places //ttt2 review decision to ignore status } /*static*/ int ImageInfo::MAX_IMAGE_SIZE (100000); ImageInfo::ImageInfo(int nImageType, Status eStatus, const QImage& pic) : m_eCompr(JPG), m_eStatus(eStatus), m_nImageType(nImageType) { QImage scaledPic; compress(pic, scaledPic, m_compressedImg); m_nWidth = scaledPic.width(); m_nHeight = scaledPic.height(); } /*static*/ const char* ImageInfo::getImageType(int nImageType) { switch (nImageType) { case 0x00: return "other"; case 0x01: return "32x32 icon"; case 0x02: return "other file icon"; case 0x03: return "front cover"; case 0x04: return "back cover"; case 0x05: return "leaflet page"; case 0x06: return "media"; case 0x07: return "lead artist"; case 0x08: return "artist"; case 0x09: return "conductor"; case 0x0a: return "band"; case 0x0b: return "composer"; case 0x0c: return "lyricist"; case 0x0d: return "recording location"; case 0x0e: return "during recording"; case 0x0f: return "during performance"; case 0x10: return "screen capture"; //case 0x11: return "a bright coloured fish"; case 0x12: return "illustration"; case 0x13: return "band/artist logotype"; case 0x14: return "publisher/studio logotype"; default: return "unknown"; } } const char* ImageInfo::getImageType() const { return getImageType(m_nImageType); } /*static*/ const char* ImageInfo::getComprStr(Compr eCompr) { switch (eCompr) { case INVALID: return "invalid"; case JPG: return "JPEG"; case PNG: return "PNG"; } CB_ASSERT (false); } // scales down origPic and stores the pixmap in scaledPic, as well as a compressed version in comprImg; the algorithm coninues until comprImg becomes smaller than MAX_IMAGE_SIZE or until the width and the height of scaledPic get smaller than 150; no scaling is done if comprImg turns out to be small enough for the original image; /*static*/ void ImageInfo::compress(const QImage& origPic, QImage& scaledPic, QByteArray& comprImg) { const int QUAL (-1); //ttt2 hard-coded //QPixmap scaledImg; int n (max(origPic.width(), origPic.height())); //qDebug("-------------"); for (int i = n;;) { scaledPic = origPic.scaled(i, i, Qt::KeepAspectRatio, Qt::SmoothTransformation); comprImg.clear(); QBuffer bfr (&comprImg); //nWidth = scaledPic.width(); nHeight = scaledPic.height(); scaledPic.save(&bfr, "jpg", QUAL); int nSize (comprImg.size()); //qDebug("width=%d, size=%d", i, nSize); if (nSize <= MAX_IMAGE_SIZE) { break; } //double d (min(4.0/5, 1/sqrt(nSize*1.0/MAX_IMAGE_SIZE))); double d (min(4.0/5, sqrt(MAX_IMAGE_SIZE*1.0/nSize))); // ttt2 review this; the "1.0" is quite wrong in some cases i = int(i*d); if (i <= 150) { break; } } } QString ImageInfo::getTextDescr(const QString& qstrSep /*= "\n"*/) const { QString s; s.sprintf("%dx%d", getWidth(), getHeight()); s += qstrSep + getImageType(); return s; } void ImageInfo::showFull(QWidget* pParent) const { FullSizeImgDlg dlg (pParent, *this); dlg.exec(); } ostream& operator<<(ostream& out, const AlbumInfo& inf) { out << "title: \"" << inf.m_strTitle << /*"\", artist: \"" << inf.m_strArtist << "\", composer: \"" << inf.m_strComposer <<*/ /*"\", format: \"" << inf.m_strFormat <<*/ "\", genre: \"" << inf.m_strGenre << "\", released: \"" << inf.m_strReleased << "\", var artists: \"" << int(inf.m_eVarArtists) << "\"\n\nnotes: " << inf.m_strNotes << endl; /*for (int i = 0, n = cSize(inf.m_vstrImageNames); i < n; ++i) { out << inf.m_vstrImageNames[i] << endl; }*/ out << "\ntracks:" << endl; for (int i = 0, n = cSize(inf.m_vTracks); i < n; ++i) { out << "pos: \"" << inf.m_vTracks[i].m_strPos << "\", artist: \"" << inf.m_vTracks[i].m_strArtist << "\", title: \"" << inf.m_vTracks[i].m_strTitle << "\", composer: \"" << inf.m_vTracks[i].m_strComposer << "\"" << endl; } return out; } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== static const set<QString>& getLowerCaseSet() { static set<QString> sqstrLowCase; static bool bInit (false); if (!bInit) { bInit = true; const char* aszList[] = { "a","an","the", // from http://avalon-internet.com/Capitalize_an_English_Title/en "about","above","across","after","against","along", "amid","among","around","at","before","behind","below", "beneath", "beside","besides","between","beyond","but","by","concerning","despite", "down","during","except","from","in","including", "inside","into","like", "minus","near","notwithstanding","of","off","on", "onto","opposite","out", "outside","over","past","per","plus","regarding","since","through", "throughout","till","to","toward","towards","under","underneath","unless", "unlike","until","up","upon","versus","via","with","within","without", "and","but","for","nor","or","so","yet", "after","although","as","because","if", "lest","than","that","though","when","whereas","while", "also","both","each","either","neither","whether", 0 }; for (const char** p = &aszList[0]; 0 != *p; ++p) { sqstrLowCase.insert(*p); } /* alternative lists/opinions: http://aitech.ac.jp/~ckelly/midi/help/caps.html http://www.cumbrowski.com/CarstenC/articles/20070623_Title_Capitalization_in_the_English_Language.asp http://www.searchenginejournal.com/title-capitalization-in-the-english-language/4882/ http://ezinearticles.com/?Title-Capitalization-In-The-English-Language&id=658201 */ } return sqstrLowCase; } static const map<QString, QString>& getFixedCaseMap() { static map<QString, QString> mqstrFixedCase; static bool bInit (false); if (!bInit) { bInit = true; const char* aszList[] = { "I","MTV","L.A.", 0 }; for (const char** p = &aszList[0]; 0 != *p; ++p) { mqstrFixedCase[QString(*p).toLower()] = *p; } } return mqstrFixedCase; } static void dropPunct(const QString& s, int& i, int& j) { int n (s.size()); i = 0; j = n; for (; i < n && s[i].isPunct(); ++i) {} for (; i < n && s[n - 1].isPunct(); --n) {} } static QString singleWordFirstLast(const QString& s) { int i, j; dropPunct(s, i, j); if (i == j) { return s; } QString s1 (s.mid(i, j - i).toLower()); if (getFixedCaseMap().count(s1) > 0) { s1 = (*getFixedCaseMap().lower_bound(s1)).second; } else { s1 = s1.toLower(); s1[0] = s1[0].toUpper(); } QString s2 (s); s2.replace(i, j - i, s1); return s2; } static QString singleWordMiddleTitle(const QString& s) { int i, j; dropPunct(s, i, j); if (i == j) { return s; } QString s1 (s.mid(i, j - i).toLower()); if (getFixedCaseMap().count(s1) > 0) { s1 = (*getFixedCaseMap().lower_bound(s1)).second; } else if (getLowerCaseSet().count(s1) > 0) { // !!! nothing, keep lower } else { s1 = s1.toLower(); s1[0] = s1[0].toUpper(); } QString s2 (s); s2.replace(i, j - i, s1); return s2; } static QString singleWordMiddleSentence(const QString& s) { int i, j; dropPunct(s, i, j); if (i == j) { return s; } QString s1 (s.mid(i, j - i).toLower()); if (getFixedCaseMap().count(s1) > 0) { s1 = (*getFixedCaseMap().lower_bound(s1)).second; } QString s2 (s); s2.replace(i, j - i, s1); return s2; } QString getCaseConv(const QString& s, TextCaseOptions eCase) { /* lNames << "Lower case: first part. second part."; lNames << "Upper case: FIRST PART. SECOND PART."; lNames << "Title case: First Part. Second Part."; lNames << "Phrase case: First part. Second part."; */ switch(eCase) { //case TC_NONE: CB_ASSERT (false); case TC_LOWER: return s.toLower(); case TC_UPPER: return s.toUpper(); case TC_TITLE: { /*QString res; int n (s.size()); bool bWhitesp (true); for (int i = 0; i < n; ++i) { const QChar& qc (s[i]); if (bWhitesp) { res += qc.toUpper(); } else { res += qc.toLower(); } bWhitesp = qc.isSpace() || qc == '.'; }*/ QStringList l (s.split(" ", QString::SkipEmptyParts)); int n (l.size()); if (n > 0) { l[0] = singleWordFirstLast(l[0]); } if (n > 1) { l[n - 1] = singleWordFirstLast(l[n - 1]); } for (int i = 1; i < n - 1; ++i) { l[i] = singleWordMiddleTitle(l[i]); } return l.join(" "); } case TC_SENTENCE: { /*int n (s.size()); QString res; bool bPer (true); for (int i = 0; i < n; ++i) { const QChar& qc (s[i]); if (bPer) { res += qc.toUpper(); } else { res += qc.toLower(); } if (!qc.isSpace()) { bPer = (qc == '.'); } } return res;*/ QStringList l (s.split(" ", QString::SkipEmptyParts)); int n (l.size()); if (n > 0) { l[0] = singleWordFirstLast(l[0]); } for (int i = 1; i < n; ++i) { l[i] = singleWordMiddleSentence(l[i]); } return l.join(" "); } default: CB_ASSERT (false); } } const char* getCaseAsStr(TextCaseOptions e) { switch (e) { case TC_NONE: return "<no change>"; case TC_LOWER: return "lower case"; case TC_UPPER: return "UPPER CASE"; case TC_TITLE: return "Title Case"; case TC_SENTENCE: return "Sentence case"; default: CB_ASSERT (false); } } ������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/DoubleListWdg.ui������������������������������������������������������������0000644�0001750�0000144�00000024343�11200240555�016322� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>DoubleListWdg</class> <widget class="QWidget" name="DoubleListWdg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>641</width> <height>376</height> </rect> </property> <property name="windowTitle" > <string>Form</string> </property> <layout class="QGridLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <property name="horizontalSpacing" > <number>4</number> </property> <property name="verticalSpacing" > <number>0</number> </property> <item row="0" column="0" > <widget class="QLabel" name="m_pSelL" > <property name="font" > <font> <weight>50</weight> <bold>false</bold> </font> </property> <property name="text" > <string>Include elems:</string> </property> </widget> </item> <item row="0" column="2" > <widget class="QLabel" name="m_pAvailableL" > <property name="text" > <string>Available elems:</string> </property> </widget> </item> <item row="1" column="0" > <widget class="QTableView" name="m_pSelectedG" > <property name="tabKeyNavigation" > <bool>false</bool> </property> <property name="selectionBehavior" > <enum>QAbstractItemView::SelectRows</enum> </property> <property name="showGrid" > <bool>true</bool> </property> </widget> </item> <item row="1" column="1" > <widget class="QWidget" native="1" name="widget" > <property name="maximumSize" > <size> <width>32</width> <height>16777215</height> </size> </property> <layout class="QVBoxLayout" > <property name="spacing" > <number>0</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>32</width> <height>41</height> </size> </property> </spacer> </item> <item> <widget class="QToolButton" name="m_pAddB" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="maximumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string><</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/arrow-left.svg</iconset> </property> <property name="iconSize" > <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pDeleteB" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="maximumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>></string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/arrow-right.svg</iconset> </property> <property name="iconSize" > <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>32</width> <height>41</height> </size> </property> </spacer> </item> <item> <widget class="QToolButton" name="m_pAddAllB" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="maximumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/arrow-left-double.svg</iconset> </property> <property name="iconSize" > <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pDeleteAllB" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="maximumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>>></string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/arrow-right-double.svg</iconset> </property> <property name="iconSize" > <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>32</width> <height>41</height> </size> </property> </spacer> </item> <item> <widget class="QToolButton" name="m_pRestoreDefaultB" > <property name="minimumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="maximumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/reset_settings.svg</iconset> </property> <property name="iconSize" > <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pRestoreOpenB" > <property name="minimumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="maximumSize" > <size> <width>32</width> <height>32</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/undo_settings.svg</iconset> </property> <property name="iconSize" > <size> <width>28</width> <height>28</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>32</width> <height>41</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item row="1" column="2" > <widget class="QTableView" name="m_pAvailableG" > <property name="tabKeyNavigation" > <bool>false</bool> </property> <property name="selectionBehavior" > <enum>QAbstractItemView::SelectRows</enum> </property> <property name="showGrid" > <bool>true</bool> </property> </widget> </item> </layout> </widget> <resources> <include location="Mp3Diags.qrc" /> </resources> <connections/> </ui> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/MultiLineTvDelegate.cpp�����������������������������������������������������0000644�0001750�0000144�00000020610�11274256145�017634� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QTableView> #include <QHeaderView> #include <QApplication> #include <QScrollBar> #include <QMessageBox> #include "MultiLineTvDelegate.h" #include "Helpers.h" //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== MultiLineTvDelegate::MultiLineTvDelegate(QTableView* pTableView/*, QObject* pParent = 0*/) : QItemDelegate(pTableView), m_pTableView(pTableView), m_nLineHeight(0), m_nAddPerLine(0) { CB_CHECK1 (0 != pTableView, std::runtime_error("NULL QTableView not allowed")); connect(pTableView->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), pTableView, SLOT(resizeRowsToContents())); } QSize MultiLineTvDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { if (!index.isValid()) { return QSize(); } if (0 == m_nLineHeight) { calibrate(option.fontMetrics, option.font); } //cout << option.rect.width() << "x" << option.rect.height() << " "; int nMargin (QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1); //cout << "margin=" << nMargin << endl; int j (index.column()); int nColWidth (m_pTableView->horizontalHeader()->sectionSize(j)); /*if (4 == j) { qDebug("%s %d %d", m_pTableView->objectName().toUtf8().constData(), m_pTableView->verticalScrollBar()->maximum(), nColWidth); } QRect r (0, 0, nColWidth - 2*nMargin - 1, 10000); // !!! this "-1" is what's different from Qt's implementation (4.3); it is for the vertical line that delimitates the cells //ttt2 do a screen capture to be sure //ttt2 see if this is fixed in 4.4 2008.30.06 - apparently it's not fixed and the workaround no longer works */ // !!! 2009.04.17 - while working in most cases, the "1" above has this issue: Qt may toggle between showing a scrollbar and hiding it, doing this as many times per second as the CPU can handle; while the app is not frozen, what happens is quite annoying; so we'll just assume there's a scrollbar, until a proper solution is found; (it looks like Qt bug, though, because it can't make up its mind about showing a scrollbar; what Qt should do is try first to remove the scrollbar, see if it can fit everything and if not put back the scrollbar and don't try anything more); the downside is that in some cases more lines are requested than actually needed, but that happened before too (but to a lesser extent); //ttt2 perhaps at least don't do the same for all columns, normally only one is stretcheable int nSpace (1); //if (m_pTableView->verticalScrollBar()->isVisible()) if (1 == m_pTableView->verticalScrollBar()->maximum()) // the scrollbar gets 1 up for each line; the issues are around switching between no scrollbar and a scrollbar for 1 line, so hopefully this should take care of the issue; { nSpace += QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent); if (0 != QApplication::style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) { nSpace += 2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, m_pTableView); //ttt2 Qt 4.4 (and below) - specific; in 4.5 there's a QStyle::PM_ScrollView_ScrollBarSpacing // see also ColumnResizer } } QRect r (0, 0, nColWidth - 2*nMargin - nSpace, 10000);//*/ //QWidget* p (m_pTableView->viewport()); //qDebug("%d %d / %d %d", p->width(), p->height(), m_pTableView->width(), m_pTableView->height()); //QSize s (m_pTableView->maximumViewportSize()); //qDebug("%s %d %d / %d %d", m_pTableView->objectName().toUtf8().constData(), m_pTableView->verticalScrollBar()->maximum(), m_pTableView->verticalScrollBar()->minimum(), m_pTableView->width(), m_pTableView->height()); //QString s (index.data(Qt::DisplayRole).toString()); //const char* sz (index.data(Qt::DisplayRole).toString().toUtf8().constData()); //if (s.startsWith("No normal")) //qDebug("#%s", ""); QSize res (option.fontMetrics.boundingRect(r, Qt::AlignTop | Qt::TextWordWrap, index.data(Qt::DisplayRole).toString()).size()); //cout << "at (" << index.row() << "," << index.column() << "): " << res.width() << "x" << res.height(); //if (index.column() == 4) //qDebug("sz %d %d / spc %d", res.width(), res.height(), option.fontMetrics.lineSpacing()); //if (s.startsWith("No normal")) //qDebug("sz %s %d %d", "", res.width(), res.height()); res.setWidth(nColWidth); //res.setHeight(res.height() + 6); /*if (1 == m_nAddPerLine) { res.setHeight(res.height() + res.height()/m_nLineHeight - 1); //res.setHeight(res.height() + res.height()/m_nLineHeight); // ??m_nAddPerLine } else if (2 == m_nAddPerLine) { res.setHeight(res.height() + 2*res.height()/m_nLineHeight - 2); } else */if (m_nAddPerLine > 0) { res.setHeight(res.height() + m_nAddPerLine*(res.height()/m_nLineHeight - 1)); } //if (s.startsWith("No normal")) //qDebug("adj sz %s %d %d", "", res.width(), res.height()); //cout << " => " << res.width() << "x" << res.height() << endl; //QSize res (fontMetrics().size(0, text())); return res; }//*/ //ttt2 visible transf - empty lines sometimes, after resizing; seems related to scrollbar detection //s.toUtf8().constData() /*void MultiLineTvDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { //cout << "draw: " << option.rect.width() << "x" << option.rect.height() << endl; //QString s (index.data(Qt::DisplayRole).toString()); //if (s.startsWith("No normal")) //qDebug("draw: %d x %d - %s ", option.rect.width(), option.rect.height(), ""); //int nCol (index.column()); //if (0 == nCol) { return QItemDelegate::paint(pPainter, option, index); } }*/ void MultiLineTvDelegate::calibrate(const QFontMetrics& fm, const QFont& /*f*/) const// sets up m_nLine and m_nTotalAdd { //set snHeights; //QString s; QRect r (0, 0, 300, 10000);//*/ QSize res (fm.boundingRect(r, Qt::AlignTop | Qt::TextWordWrap, "a").size()); m_nAddPerLine = res.height() - fm.lineSpacing(); //qDebug("%d ww", m_nAddPerLine); //CB_ASSERT (0 <= m_nAddPerLine && m_nAddPerLine <= 1); //ttt2 triggered by "Microsoft Sans Serif 7pt"; see if it can be fixed /*if (m_nAddPerLine < 0 || m_nAddPerLine > 1) { QString s (QString("%1, %2pt").arg(f.family()).arg(f.pointSize())); static QString s_qstrLastErrFont; if (s != s_qstrLastErrFont) { s_qstrLastErrFont = s; QMessageBox::warning(m_pTableView, "Warning", "The font \"" + s + "\" cannot be displayed correctly. You should go to the Configuration Dialog and choose another general font"); } }*/ m_nLineHeight = fm.lineSpacing(); //qDebug("%d", m_nLine); } ������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/SessionEditorDlgImpl.h������������������������������������������������������0000644�0001750�0000144�00000007055�11230111215�017461� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef SessionEditorDlgImplH #define SessionEditorDlgImplH #include <string> #include <QDialog> #include "ui_SessionEditor.h" class CheckedDirModel; class QSettings; class SessionEditorDlgImpl : public QDialog, private Ui::SessionEditorDlg { Q_OBJECT CheckedDirModel* m_pDirModel; const std::string m_strDir; std::string m_strIniFile; bool m_bNew; bool m_bOpenLastSession; // meaningful only if bFirstTime was true on the constructor; void commonConstr(); // common code for both constructors public: // if bFirstTime is false it doesn't show the "Open last session" checkbox; // strDir is used as a start directory by on_m_pFileNameB_clicked; enum { NOT_FIRST_TIME, FIRST_TIME }; SessionEditorDlgImpl(QWidget* pParent, const std::string& strDir, bool bFirstTime); // used for creating a new session; SessionEditorDlgImpl(QWidget* pParent, const std::string& strIniFile); // used for editing an existing session; ~SessionEditorDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ //std::vector<std::string> m_vstrCheckedDirs; //std::vector<std::string> m_vstrUncheckedDirs; // !!! not needed; retrieved from the config file bool shouldOpenLastSession() const { return m_bOpenLastSession; } // meaningful only if bFirstTime was true on the constructor; // returns the name of an INI file for OK and an empty string for Cancel; returns "*" to just go to the sessions dialog; std::string run(); static std::string getDataFileName(const std::string& strIniName); static std::string getLogFileName(const std::string& strIniName); static void removeSession(const std::string& strIniName); // removes INI, DAT, and LOG public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pOkB_clicked(); void on_m_pCancelB_clicked(); void on_m_pBackupB_clicked(); void on_m_pFileNameB_clicked(); //void on_m_pLoadB_clicked(); void on_m_pOpenSessionsB_clicked(); void onShow(); void onHelp(); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/MpegStream.cpp��������������������������������������������������������������0000644�0001750�0000144�00000076075�11477525174�016057� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <sstream> #include <memory> #include "MpegStream.h" #include "Mp3Manip.h" using namespace std; /*namespace { // moves the read pointer to the end of the frame; throws if it cannot do so MpegFrame getMpegFrame(istream& in) { MpegFrame frame (in); } }*/ MpegStreamBase::MpegStreamBase(int nIndex, NoteColl& notes, istream& in) : DataStream(nIndex) { m_pRst = new StreamStateRestorer(in); auto_ptr<StreamStateRestorer> pRst (m_pRst); m_pos = in.tellg(); m_firstFrame = MpegFrame(notes, in); /*m_eVersion; m_eLayer; m_eChannelMode; m_nFrequency; m_nSize;*/ MP3_TRACE (m_pos, "MpegStreamBase built."); pRst.release(); } MpegStreamBase::~MpegStreamBase() { delete m_pRst; } /*override*/ void MpegStreamBase::copy(std::istream& in, std::ostream& out) { appendFilePart(in, out, m_pos, m_firstFrame.getSize()); } MpegStream::MpegStream(int nIndex, NoteColl& notes, istream& in) : MpegStreamBase(nIndex, notes, in), m_bVbr(false), m_nFrameCount(1), m_posLastFrame(-1), m_bRemoveLastFrameCalled(false) { MpegFrame frm; //int nFrameCount (1); streampos pos (m_pos); pos += m_firstFrame.getSize(); m_nTotalBps = m_firstFrame.getBitrate(); int nSecondFrameBitrate (-1); // to determine if the first frame has different bitrate from the others bool bVbr2 (false); for (;;) { try { frm = MpegFrame(notes, in); } catch (const EndOfFile&) { break; } catch (const MpegFrame::NotMpegFrame&) { break; } catch (const MpegFrame::PrematurelyEndedMpegFrame&) { if (m_nFrameCount >= MIN_FRAME_COUNT) { MP3_NOTE (pos, incompleteFrameInAudio); } //ttt2 perhaps include ver/layer/... in PrematurelyEndedMpegFrame and have different messages when the incomplete frame matches the stream and when it doesn't break; } if (m_firstFrame.getVersion() != frm.getVersion()) { // end; not part of the sequence if (m_nFrameCount >= MIN_FRAME_COUNT) { MP3_NOTE (pos, validFrameDiffVer); } break; } if (m_firstFrame.getLayer() != frm.getLayer()) { // end; not part of the sequence if (m_nFrameCount >= MIN_FRAME_COUNT) { MP3_NOTE (pos, validFrameDiffLayer); } break; } if (m_firstFrame.getChannelMode() != frm.getChannelMode()) { // end; not part of the sequence if (m_nFrameCount >= MIN_FRAME_COUNT) { MP3_NOTE (pos, validFrameDiffMode); } break; } if (m_firstFrame.getFrequency() != frm.getFrequency()) { // end; not part of the sequence if (m_nFrameCount >= MIN_FRAME_COUNT) { MP3_NOTE (pos, validFrameDiffFreq); } break; } if (m_firstFrame.getCrcUsage() != frm.getCrcUsage()) { // end; not part of the sequence if (m_nFrameCount >= MIN_FRAME_COUNT) { MP3_NOTE (pos, validFrameDiffCrc); } break; } m_posLastFrame = pos; m_lastFrame = frm; pos += frm.getSize(); m_nTotalBps += frm.getBitrate(); ++m_nFrameCount; if (frm.getBitrate() != m_firstFrame.getBitrate()) { m_bVbr = true; } if (-1 == nSecondFrameBitrate) { nSecondFrameBitrate = frm.getBitrate(); } else { if (nSecondFrameBitrate != frm.getBitrate()) { bVbr2 = true; } } } //MP3_CHECK (m_nFrameCount >= MIN_FRAME_COUNT, m_pos, "Invalid MPEG stream. Stream has fewer than 10 frames.", StreamTooShort(getInfo())); if (m_nFrameCount < MIN_FRAME_COUNT) { in.clear(); in.seekg(m_pos); char bfr [4]; string strInfo; if (4 == read(in, bfr, 4)) // normally this should work, because to get here at least a full frame needs to be read { strInfo = decodeMpegFrame(bfr, ", "); } MP3_THROW (m_pos, audioTooShort, StreamTooShort(strInfo, m_nFrameCount)); } MP3_CHECK (!m_bVbr || bVbr2, m_pos, diffBitrateInFirstFrame, UnknownHeader()); //ttt2 perhaps add test for "null": whatever is in the first bytes that allows Xing & Co to not generate audio in decoders that don't know about them m_nSize = pos - m_pos; in.seekg(pos); m_nBitrate = int(m_nTotalBps / m_nFrameCount); /*if (m_firstFrame.getCrcUsage()) { MP3_NOTE (m_pos, "Stream uses CRC."); }*/ if ( !(MpegFrame::MPEG1 == m_firstFrame.getVersion() && MpegFrame::LAYER3 == m_firstFrame.getLayer()) && !(MpegFrame::MPEG2 == m_firstFrame.getVersion() && MpegFrame::LAYER3 == m_firstFrame.getLayer())) { MP3_NOTE (m_pos, untestedEncoding); } MP3_TRACE (m_pos, "MpegStream built."); setRstOk(); } // this can only be called once; the second call will throw (it's harder and quite pointless to allow more than one call) void MpegStream::removeLastFrame() { STRM_ASSERT (!m_bRemoveLastFrameCalled); m_bRemoveLastFrameCalled = true; m_nSize -= m_lastFrame.getSize(); m_nTotalBps -= m_lastFrame.getBitrate(); STRM_ASSERT (m_nFrameCount >= 10); --m_nFrameCount; m_nBitrate = int(m_nTotalBps / m_nFrameCount); } /*override*/ void MpegStream::copy(std::istream& in, std::ostream& out) { appendFilePart(in, out, m_pos, m_nSize); } /*override*/ std::string MpegStream::getInfo() const { ostringstream out; out << getDuration() << ", " << m_firstFrame.getSzVersion() << " " << m_firstFrame.getSzLayer() << ", " << m_firstFrame.getSzChannelMode() << ", " << m_firstFrame.getFrequency() << "Hz, " << m_nBitrate << "bps " << (m_bVbr ? "VBR" : "CBR") << ", CRC=" << boolAsYesNo(m_firstFrame.getCrcUsage()) << ", frame count=" << m_nFrameCount; out << "; last frame" << (m_bRemoveLastFrameCalled ? " removed; it was" : "") << " located at 0x" << hex << m_posLastFrame << dec; return out.str(); } std::string MpegStream::getDuration() const { int nDur (int(m_nSize*8.0/m_nBitrate)); int nMin (nDur/60); int nSec (nDur - nMin*60); char a [15]; sprintf(a, "%d:%02d", nMin, nSec); return a; } bool MpegStream::isCompatible(const MpegFrameBase& frame) { if (getFirstFrame().getVersion() != frame.getVersion()) { return false; } if (getFirstFrame().getLayer() != frame.getLayer()) { return false; } if (getFirstFrame().getChannelMode() != frame.getChannelMode()) { return false; } if (getFirstFrame().getFrequency() != frame.getFrequency()) { return false; } if (getFirstFrame().getCrcUsage() != frame.getCrcUsage()) { return false; } return true; } // moves the read pointer to the first frame compatible with the stream; returns "false" if no such frame is found bool MpegStream::findNextCompatFrame(std::istream& in, std::streampos posMax) { streampos pos (in.tellg()); NoteColl notes (10); for (;;) { try { pos = getNextStream(in, pos); if (pos > posMax) { return false; } in.seekg(pos); try { MpegFrameBase frm (notes, in); if (isCompatible(frm)) { in.seekg(pos); return true; } } catch (const MpegFrameBase::NotMpegFrame&) { } } catch (const EndOfFile&) { return false; } } } #ifdef GENERATE_TOC // throws if it can't write to the disk void createXing(ostream& out, const MpegFrame& frame1, int nFrameCount, streamoff nStreamSize) { const MpegFrameBase& frame (frame1.getBigBps()); int nSize (frame.getSize()); out.write(frame.getHeader(), MpegFrame::MPEG_FRAME_HDR_SIZE); int nSideInfoSize (frame.getSideInfoSize()); writeZeros(out, nSideInfoSize); out.write("Xing\0\0\0\7", 8); char bfr [4]; put32BitBigEndian(nFrameCount, bfr); out.write(bfr, 4); put32BitBigEndian(nStreamSize, bfr); out.write(bfr, 4); for (int i = 0; i < 100; ++ i) { bfr[0] = i*255/(100 - 1); out.write(bfr, 1); } writeZeros(out, nSize - MpegFrame::MPEG_FRAME_HDR_SIZE - nSideInfoSize - 8 - 4 - 4 - 100); CB_CHECK1 (out, WriteError()); } #else void createXing(ostream& out, const MpegFrame& frame, int nFrameCount, streamoff nStreamSize) { int nSize (frame.getSize()); out.write(frame.getHeader(), MpegFrame::MPEG_FRAME_HDR_SIZE); int nSideInfoSize (frame.getSideInfoSize()); writeZeros(out, nSideInfoSize); out.write("Xing\0\0\0\3", 8); char bfr [4]; put32BitBigEndian(nFrameCount, bfr); out.write(bfr, 4); put32BitBigEndian(nStreamSize, bfr); out.write(bfr, 4); writeZeros(out, nSize - MpegFrame::MPEG_FRAME_HDR_SIZE - nSideInfoSize - 8 - 4 - 4); CB_CHECK1 (out, WriteError()); } #endif void MpegStream::createXing(ostream& out) { ::createXing(out, m_firstFrame, m_nFrameCount, getSize()); } //ttt2 perhaps make clear in messages that Xing is OK with CBR, which by convention should use "Info" instead of "Xing" but some tools don't follow this; don't delete Xing just because it's followed a CBR XingStreamBase::XingStreamBase(int nIndex, NoteColl& notes, istream& in) : MpegStreamBase(nIndex, notes, in), m_nFrameCount(-1), m_nByteCount(-1), m_nQuality(-1) { fill(&m_toc[0], &m_toc[100], 0); in.seekg(m_pos); const int XING_LABEL_SIZE (4); const int BFR_SIZE (MpegFrame::MPEG_FRAME_HDR_SIZE + 32 + XING_LABEL_SIZE); // MPEG header + side info + "Xing" size //ttt2 not sure if space for CRC16 should be added; then not sure if frame size should be increased by 2 when CRC is found char bfr [BFR_SIZE]; int nSideInfoSize (m_firstFrame.getSideInfoSize()); int nBfrSize (MpegFrame::MPEG_FRAME_HDR_SIZE + nSideInfoSize + XING_LABEL_SIZE); MP3_CHECK_T (nBfrSize <= m_firstFrame.getSize(), m_pos, "Not a Xing stream. This kind of MPEG audio doesn't support Xing.", NotXingStream()); // !!! some kinds of MPEG audio (e.g. "MPEG-1 Layer I, 44100Hz 32000bps" or "MPEG-2 Layer III, 22050Hz 8000bps") have very short frames, which can't accomodate a Xing header streamsize nRead (read(in, bfr, nBfrSize)); STRM_ASSERT (nBfrSize == nRead); // this was supposed to be a valid frame to begin with (otherwise the base class would have thrown) and nBfrSize is no bigger than the frame char* pLabel (bfr + MpegFrame::MPEG_FRAME_HDR_SIZE + nSideInfoSize); MP3_CHECK_T (0 == strncmp("Xing", pLabel, XING_LABEL_SIZE) || 0 == strncmp("Info", pLabel, XING_LABEL_SIZE), m_pos, "Not a Xing stream. Header not found.", NotXingStream()); MP3_CHECK_T (4 == read(in, bfr, 4) && 0 == bfr[0] && 0 == bfr[1] && 0 == bfr[2], m_pos, "Not a Xing stream. Header not found.", NotXingStream()); m_cFlags = bfr[3]; MP3_CHECK_T ((m_cFlags & 0x0f) == m_cFlags, m_pos, "Not a Xing stream. Invalid flags.", NotXingStream()); if (0x01 == (m_cFlags & 0x01)) { // has frames MP3_CHECK_T (4 == read(in, bfr, 4), m_pos, "Not a Xing stream. File too short.", NotXingStream()); m_nFrameCount = get32BitBigEndian(bfr); } if (0x02 == (m_cFlags & 0x02)) { // has bytes MP3_CHECK_T (4 == read(in, bfr, 4), m_pos, "Not a Xing stream. File too short.", NotXingStream()); m_nByteCount = get32BitBigEndian(bfr); } if (0x04 == (m_cFlags & 0x04)) { // has TOC MP3_CHECK_T (100 == read(in, m_toc, 100), m_pos, "Not a Xing stream. File too short.", NotXingStream()); } if (0x08 == (m_cFlags & 0x08)) { // has quality MP3_CHECK_T (4 == read(in, bfr, 4), m_pos, "Not a Xing stream. File too short.", NotXingStream()); m_nQuality = get32BitBigEndian(bfr); } streampos posEnd (m_pos); posEnd += m_firstFrame.getSize(); in.seekg(posEnd); //ttt2 2010.12.07 - A header claiming to have TOC but lacking one isn't detected. 1) Should check that values in TOC are ascending. 2) Should check that it actually fits: a 104 bytes-long 32kbps frame cannot hold a 100 bytes TOC along with the header and other things. } void XingStreamBase::getXingInfo(std::ostream& out) const { out << "[Xing header info:"; bool b (false); if (0x01 == (m_cFlags & 0x01)) { out << " frame count=" << m_nFrameCount; b = true; } if (0x02 == (m_cFlags & 0x02)) { out << (b ? "," : "") << " byte count=" << m_nByteCount; b = true; } //ttt2 see what to do with this: it's the size of the whole file, all headers&tags included (at least with c03 Valentin Moldovan - Marea Irlandei.mp3); ??? and anyway, what's the point of including the size of the whole file as a field? if (0x04 == (m_cFlags & 0x04)) { out << (b ? "," : "") << " TOC present"; b = true; } if (0x08 == (m_cFlags & 0x08)) { out << (b ? "," : "") << " quality=" << m_nQuality; b = true; } out << "]"; } std::string XingStreamBase::getInfoForXml() const { ostringstream out; if (0x01 == (m_cFlags & 0x01)) { out << " frameCount=\"" << m_nFrameCount << "\""; } if (0x02 == (m_cFlags & 0x02)) { out << " byteCount=\"" << m_nByteCount << "\""; } //ttt2 see what to do with this: it's the size of the whole file, all headers&tags included (at least with c03 Valentin Moldovan - Marea Irlandei.mp3); ??? and anyway, what's the point of including the size of the whole file as a field? if (0x04 == (m_cFlags & 0x04)) { out << " toc=\"yes\""; } if (0x08 == (m_cFlags & 0x08)) { out << " quality=\"" << m_nQuality << "\""; } return out.str(); } /*override*/ std::string XingStreamBase::getInfo() const { ostringstream out; out << m_firstFrame.getSzVersion() << " " << m_firstFrame.getSzLayer() << ", " << m_firstFrame.getSzChannelMode() << ", " << m_firstFrame.getFrequency() << "Hz" << ", " << m_firstFrame.getBitrate() << "bps, CRC=" << boolAsYesNo(m_firstFrame.getCrcUsage()) << "; "; getXingInfo(out); return out.str(); } bool XingStreamBase::matchesStructure(const MpegStream& mpeg) const { const MpegFrame& mpegFrm (mpeg.getFirstFrame()); return (m_firstFrame.getVersion() == mpegFrm.getVersion() && m_firstFrame.getLayer() == mpegFrm.getLayer() && //m_firstFrame.getChannelMode() == mpegFrm.getChannelMode() && m_firstFrame.getFrequency() == mpegFrm.getFrequency()); } // checks that there is a metch for version, layer, frequency and frame count bool XingStreamBase::matches(const MpegStream& mpeg) const { return matchesStructure(mpeg) && getFrameCount() == mpeg.getFrameCount(); } // checks that pNext is MpegStream* in addition to matches(const MpegStream&) bool XingStreamBase::matches(const DataStream* pNext) const { const MpegStream* q (dynamic_cast<const MpegStream*>(pNext)); return 0 != q && matches(*q); } bool XingStreamBase::isBrokenByMp3Fixer(const DataStream* pNext, const DataStream* pAfterNext) const { if (16 != pNext->getSize()) { return false; } const MpegStream* q (dynamic_cast<const MpegStream*>(pAfterNext)); return 0 != q && matchesStructure(*q) && getFrameCount() == q->getFrameCount() + 1; } XingStream::XingStream(int nIndex, NoteColl& notes, std::istream& in) : XingStreamBase(nIndex, notes, in) { MP3_TRACE (m_pos, "XingStream built."); setRstOk(); } LameStream::LameStream(int nIndex, NoteColl& notes, istream& in) : XingStreamBase(nIndex, notes, in) { in.seekg(m_pos); const int LAME_LABEL_SIZE (4); const int LAME_OFFS (156); const int BFR_SIZE (LAME_OFFS + LAME_LABEL_SIZE); // MPEG header + side info + "Xing" size //ttt2 not sure if space for CRC16 should be added; then not sure if frame size should be increased by 2 when CRC is found char bfr [BFR_SIZE]; MP3_CHECK_T (BFR_SIZE <= m_firstFrame.getSize(), m_pos, "Not a LAME stream. This kind of MPEG audio doesn't support LAME.", NotLameStream()); // !!! some kinds of MPEG audio have very short frames, which can't accomodate a VBRI header streamsize nRead (read(in, bfr, BFR_SIZE)); STRM_ASSERT (BFR_SIZE == nRead); // this was supposed to be a valid frame to begin with (otherwise the base class would have thrown) and BFR_SIZE is no bigger than the frame MP3_CHECK_T (0 == strncmp("LAME", bfr + LAME_OFFS, LAME_LABEL_SIZE), m_pos, "Not a LAME stream. Header not found.", NotLameStream()); streampos posEnd (m_pos); posEnd += m_firstFrame.getSize(); in.seekg(posEnd); MP3_TRACE (m_pos, "LameStream built."); setRstOk(); } /*override*/ std::string LameStream::getInfo() const { ostringstream out; out << m_firstFrame.getSzVersion() << " " << m_firstFrame.getSzLayer() << ", " << m_firstFrame.getSzChannelMode() << ", " << m_firstFrame.getFrequency() << "Hz" << ", " << m_firstFrame.getBitrate() << "bps, CRC=" << boolAsYesNo(m_firstFrame.getCrcUsage()) << "; "; getXingInfo(out); return out.str(); } //ttt2 see why after most VBRI headers comes an "unknown" stream; perhaps there's an error in how VbriStream works VbriStream::VbriStream(int nIndex, NoteColl& notes, istream& in) : MpegStreamBase(nIndex, notes, in) { in.seekg(m_pos); const int VBRI_LABEL_SIZE (4); const int BFR_SIZE (MpegFrame::MPEG_FRAME_HDR_SIZE + 32 + VBRI_LABEL_SIZE); // MPEG header + side info + "Xing" size //ttt2 not sure if space for CRC16 should be added; then not sure if frame size should be increased by 2 when CRC is found char bfr [BFR_SIZE]; MP3_CHECK_T (BFR_SIZE <= m_firstFrame.getSize(), m_pos, "Not a VBRI stream. This kind of MPEG audio doesn't support VBRI.", NotVbriStream()); // !!! some kinds of MPEG audio have very short frames, which can't accomodate a VBRI header streamsize nRead (read(in, bfr, BFR_SIZE)); STRM_ASSERT (BFR_SIZE == nRead); // this was supposed to be a valid frame to begin with (otherwise the base class would have thrown) and BFR_SIZE is no bigger than the frame char* pLabel (bfr + MpegFrame::MPEG_FRAME_HDR_SIZE + 32); MP3_CHECK_T (0 == strncmp("VBRI", pLabel, VBRI_LABEL_SIZE), m_pos, "Not a VBRI stream. Header not found.", NotVbriStream()); streampos posEnd (m_pos); posEnd += m_firstFrame.getSize(); in.seekg(posEnd); MP3_TRACE (m_pos, "VbriStream built."); setRstOk(); } /*override*/ std::string VbriStream::getInfo() const { ostringstream out; out << m_firstFrame.getSzVersion() << " " << m_firstFrame.getSzLayer() << ", " << m_firstFrame.getSzChannelMode() << ", " << m_firstFrame.getFrequency() << "Hz" << ", " << m_firstFrame.getBitrate() << "bps, CRC=" << boolAsYesNo(m_firstFrame.getCrcUsage()); return out.str(); } //=========================================================================================================================== //=========================================================================================================================== //=========================================================================================================================== Id3V1Stream::Id3V1Stream(int nIndex, NoteColl& notes, istream& in) : DataStream(nIndex), m_pos(in.tellg()) { StreamStateRestorer rst (in); const int BFR_SIZE (128); streamsize nRead (read(in, m_data, BFR_SIZE)); MP3_CHECK_T (BFR_SIZE == nRead, m_pos, "Invalid ID3V1 tag. File too short.", NotId3V1Stream()); MP3_CHECK_T (0 == strncmp("TAG", m_data, 3), m_pos, "Invalid ID3V1 tag. Invalid header.", NotId3V1Stream()); MP3_CHECK (BFR_SIZE == nRead, m_pos, id3v1TooShort, NotId3V1Stream()); // not 100% correct, but should generally work if (0 == m_data[125] && 0 != m_data[126]) { m_eVersion = V11b; } else { unsigned char c ((unsigned char)m_data[127]); m_eVersion = (' ' == m_data[125] && ' ' == m_data[126]) || (0 == m_data[125] && 0 == m_data[126]) || (c > 0 && c < ' ') ? V11 : V10; } // http://uweb.txstate.edu/~me02/tutorials/sound_file_formats/mpeg/tags.htm TestResult eTrack (checkId3V1String(m_data + 3, 30)); MP3_CHECK (BAD != eTrack, m_pos, id3v1InvalidName, NotId3V1Stream()); TestResult eArtist (checkId3V1String(m_data + 33, 30)); MP3_CHECK (BAD != eArtist, m_pos, id3v1InvalidArtist, NotId3V1Stream()); TestResult eAlbum (checkId3V1String(m_data + 63, 30)); MP3_CHECK (BAD != eAlbum, m_pos, id3v1InvalidAlbum, NotId3V1Stream()); TestResult eYear (checkId3V1String(m_data + 93, 4)); MP3_CHECK (BAD != eYear, m_pos, id3v1InvalidYear, NotId3V1Stream()); TestResult eComment (checkId3V1String(m_data + 97, 28)); MP3_CHECK (BAD != eComment, m_pos, id3v1InvalidComment, NotId3V1Stream()); // "28" is for ID3V1.1b (there's no reliable way to distinguish among versions 1.0 and 1.1 by design, and in practice among any of them because some tools use 0 instead of space and 0 seems to be a valid value for 1.1b's track and genre, for "undefined") //ttt2 use m_eVersion if (ZERO_PADDED == eTrack || ZERO_PADDED == eArtist || ZERO_PADDED == eAlbum || ZERO_PADDED == eYear || ZERO_PADDED == eComment) { // MP3_NOTE (m_pos, zeroInId3V1 /*"ID3V1 tag contains characters with the code 0, although this is not allowed by the standard (yet used by some tools)."*/); if (SPACE_PADDED == eTrack || SPACE_PADDED == eArtist || SPACE_PADDED == eAlbum || SPACE_PADDED == eYear || SPACE_PADDED == eComment) { MP3_NOTE (m_pos, mixedPaddingInId3V1); } } if (MIXED_PADDED == eTrack || MIXED_PADDED == eArtist || MIXED_PADDED == eAlbum || MIXED_PADDED == eYear || MIXED_PADDED == eComment) { MP3_NOTE (m_pos, mixedFieldPaddingInId3V1); } MP3_TRACE (m_pos, "Id3V1Stream built."); rst.setOk(); } /*static*/ bool Id3V1Stream::isLegal(char c) { unsigned char x (c); return x >= 32; } // makes sure that a valid string is stored at the address given, meaning no chars smaller than 32; well, except for 0: 0 isn't really valid, as the fields are supposed to be padded with spaces at the right, but some tools use 0 anyway /*static*/ Id3V1Stream::TestResult Id3V1Stream::checkId3V1String(const char* p, int nSize) { bool bZeroFound (false); int i (0); for (; i < nSize; ++i) { if (0 == p[i]) { bZeroFound = true; break; } if (!isLegal(p[i])) { return BAD; } } if (bZeroFound) { bool bMixed (false); for (; i < nSize; ++i) { if (' ' == p[i]) { bMixed = true; } if (0 != p[i] && ' ' != p[i]) { return BAD; } } return bMixed ? MIXED_PADDED : ZERO_PADDED; } if (' ' == p[nSize - 1] && ' ' == p[nSize - 2]) { return SPACE_PADDED; } return NOT_PADDED; } /*override*/ void Id3V1Stream::copy(std::istream&, std::ostream& out) { out.write(m_data, 128); CB_CHECK1 (out, WriteError()); } static string getSpacedStr(const string& s) { if (s.empty()) { return string(); } return ", " + s; } const char* Id3V1Stream::getVersion() const { switch (m_eVersion) { case V10: return "ID3V1.0"; case V11: return "ID3V1.1"; case V11b: return "ID3V1.1b"; default: STRM_ASSERT (false); } } /*override*/ std::string Id3V1Stream::getInfo() const { string strRes (getVersion()); strRes += getSpacedStr(getTitle(0)) + getSpacedStr(getArtist(0)) + getSpacedStr(getAlbumName(0)) + getSpacedStr(getGenre(0)); return strRes; } /*override*/ TagReader::SuportLevel Id3V1Stream::getSupport(Feature eFeature) const { switch (eFeature) { case TITLE: case ARTIST: case TRACK_NUMBER: case TIME: case GENRE: case ALBUM: return READ_ONLY; default: return NOT_SUPPORTED; } } // returns the string located at nAddr, removing trailing spaces; the result is in UTF8 format string Id3V1Stream::getStr(int nAddr, int nMaxSize) const { int nSize (0); for (; nSize < nMaxSize; ++nSize) { unsigned char c ((unsigned char)(m_data[nAddr + nSize])); if (c < ' ') { break; } // ASCII-specific, but probably OK for dealing with MP3 tags } for (; nSize > 0 && ' ' == m_data[nAddr + nSize - 1]; --nSize) {} return utf8FromLatin1(string(m_data + nAddr, m_data + nAddr + nSize)); } /*override*/ std::string Id3V1Stream::getTitle(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = true; } return getStr(3, 30); } /*override*/ std::string Id3V1Stream::getArtist(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = true; } return getStr(33, 30); } /*override*/ std::string Id3V1Stream::getTrackNumber(bool* pbFrameExists /*= 0*/) const { if (V11b != m_eVersion) { if (0 != pbFrameExists) { *pbFrameExists = false; } return ""; } if (0 != pbFrameExists) { *pbFrameExists = true; } char a [10]; sprintf(a, "%02d", (int)(unsigned char)(m_data[126])); return a; } /*override*/ std::string Id3V1Stream::getGenre(bool* pbFrameExists /*= 0*/) const { switch (m_eVersion) { case V11: case V11b: { int n (m_data[127]); if (0 != pbFrameExists) { *pbFrameExists = true; } return getId3V1Genre(n); } default: if (0 != pbFrameExists) { *pbFrameExists = false; } return ""; } } /*override*/ std::string Id3V1Stream::getAlbumName(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = true; } return getStr(63, 30); } /*override*/ TagTimestamp Id3V1Stream::getTime(bool* pbFrameExists /*= 0*/) const { if (0 != pbFrameExists) { *pbFrameExists = true; } string s (getStr(93, 4)); if (" " == s || string("\0\0\0\0") == s) { return TagTimestamp(""); } try { return TagTimestamp(s); } catch (const TagTimestamp::InvalidTime&) { return TagTimestamp(""); } } int Id3V1Stream::getCommSize() const { switch (m_eVersion) { case V10: return 31; case V11: return 30; case V11b: return 28; } return 0; } /*override*/ std::string Id3V1Stream::getOtherInfo() const { int nCommSize (getCommSize()); string strComm (getStr(97, nCommSize)); if (strComm.empty()) { return ""; } return "Comment: " + strComm; } const char* getId3V1Genre(int n) { if (n <= 0 || n > 147) { return ""; } static const char* aGenres [148] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Prank", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", //20 - 3F "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "Alternative Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", //40 - 5F "Native US", "Cabaret", "New Wave", "Psychedelic", // ??? "Psychadelic" in the specs "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebop", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", //60 - 7F "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhytmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", //80 - 93 "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Trash Meta", "Anime", "Jpop", "Synthpop" }; return aGenres[n]; } //=========================================================================================================================== //=========================================================================================================================== //=========================================================================================================================== //ttt1 GC - Stillness & Crafted Prayer 1.mp3 - audio present but not detected, because it's MPEG 2.5 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Sessions.ui�����������������������������������������������������������������0000644�0001750�0000144�00000011641�11227440313�015420� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>SessionsDlg</class> <widget class="QDialog" name="SessionsDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>788</width> <height>517</height> </rect> </property> <property name="windowTitle" > <string>MP3 Diags - Sessions</string> </property> <property name="sizeGripEnabled" > <bool>true</bool> </property> <layout class="QVBoxLayout" > <item> <layout class="QHBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_2" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QTableView" name="m_pSessionsG" > <property name="tabKeyNavigation" > <bool>false</bool> </property> </widget> </item> <item> <widget class="QWidget" native="1" name="widget" > <layout class="QVBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QTreeView" name="m_pDirectoriesT" /> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_3" > <layout class="QVBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QPushButton" name="m_pOpenB" > <property name="text" > <string>&Open</string> </property> <property name="default" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pNewB" > <property name="text" > <string>&New ...</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pEditB" > <property name="text" > <string>&Edit ...</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pSaveAsB" > <property name="text" > <string>Save &as ...</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pEraseB" > <property name="text" > <string>E&rase</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pLoadB" > <property name="text" > <string>&Load ...</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pHideB" > <property name="text" > <string>&Hide</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pCancelB" > <property name="text" > <string>Cancel</string> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> </layout> </widget> </item> </layout> </item> <item> <widget class="QCheckBox" name="m_pOpenLastCkB" > <property name="text" > <string>At s&tartup open the last session automatically</string> </property> </widget> </item> </layout> </widget> <tabstops> <tabstop>m_pSessionsG</tabstop> <tabstop>m_pDirectoriesT</tabstop> <tabstop>m_pOpenB</tabstop> <tabstop>m_pNewB</tabstop> <tabstop>m_pEditB</tabstop> <tabstop>m_pSaveAsB</tabstop> <tabstop>m_pEraseB</tabstop> <tabstop>m_pLoadB</tabstop> <tabstop>m_pHideB</tabstop> <tabstop>m_pCancelB</tabstop> <tabstop>m_pOpenLastCkB</tabstop> </tabstops> <resources/> <connections/> </ui> �����������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/RenamerPatternsDlgImpl.cpp��������������������������������������������������0000644�0001750�0000144�00000013120�11265321716�020343� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QMessageBox> #include "RenamerPatternsDlgImpl.h" #include "Helpers.h" #include "FileRenamerDlgImpl.h" #include "StoredSettings.h" using namespace std; RenamerPatternsDlgImpl::RenamerPatternsDlgImpl(QWidget* pParent, SessionSettings& settings) : QDialog(pParent, getDialogWndFlags()), Ui::PatternsDlg(), m_settings(settings), m_nCrtLine(-1), m_nCrtCol(-1) { setupUi(this); m_pAddPredefB->hide(); m_pSpacerW->hide(); QPalette grayPalette (m_infoM->palette()); grayPalette.setColor(QPalette::Base, grayPalette.color(QPalette::Disabled, QPalette::Window)); m_infoM->setPalette(grayPalette); m_infoM->setTabStopWidth(fontMetrics().width("%ww")); QString qsSep (getPathSep()); m_infoM->setText(QString("%n\ttrack number\n%a\tartist\n%t\ttitle\n%b\talbum\n%y\tyear\n%g\tgenre\n%r\trating (a lowercase letter)\n%c\tcomposer" "\n\nTo include the special characters \"%\", \"[\" and \"]\", precede them by a \"%\": \"%%\", \"%[\" and \"%]\"\n\nThe path should be either a full path, starting with a " #ifndef WIN32 "\"") + getPathSep() + "\", or it should contain no \"" + getPathSep() + "\", if what is wanted is for the renamed files to remain in their original directories" #else "drive letter followed by \":\\\", or it should contain no \"\\\", if what is wanted is for the renamed files to remain in their original directories") #endif ); int nWidth, nHeight; m_settings.loadRenamerPatternsSettings(nWidth, nHeight); if (nWidth > 400 && nHeight > 300) { resize(nWidth, nHeight); } connect(m_pTextM, SIGNAL(cursorPositionChanged()), this, SLOT(onCrtPosChanged())); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } RenamerPatternsDlgImpl::~RenamerPatternsDlgImpl() { } /*$SPECIALIZATION$*/ void RenamerPatternsDlgImpl::on_m_pCancelB_clicked() { reject(); } void RenamerPatternsDlgImpl::on_m_pOkB_clicked() { m_vstrPatterns.clear(); string s (convStr(m_pTextM->toPlainText())); const char* p (s.c_str()); if (0 == *p) { accept(); return; } const char* q (p); for (;;) { if ('\n' == *p || 0 == *p) { string s1 (q, p - q); s1 = fromNativeSeparators(s1); string strErr; try { Renamer r (s1, 0, false); } catch (const Renamer::InvalidPattern& ex) { strErr = ex.m_strErr; } if (!strErr.empty()) { QMessageBox::critical(this, "Error", convStr(strErr)); return; } m_vstrPatterns.push_back(s1); for (; '\n' == *p; ++p) {} if (0 == *p) { break; } q = p; } ++p; } m_settings.saveRenamerPatternsSettings(width(), height()); accept(); } bool RenamerPatternsDlgImpl::run(vector<string>& v) { string s; for (int i = 0, n = cSize(v); i < n; ++i) { if (!s.empty()) { s += "\n"; } s += toNativeSeparators(v[i]); } m_pTextM->setText(convStr(s)); if (QDialog::Accepted != exec()) { return false; } v = m_vstrPatterns; /* set<int> sPos; vector<pair<string, int> > v1; for (int i = 0, n = cSize(m_vPatterns); i < n; ++i) { int j (0); int m (cSize(v)); for (; j < m; ++j) { if (m_vPatterns[i] == v[j] && sPos.end() == sPos.find(j)) { sPos.insert(j); break; } } if (m == j) { j = -1; } v1.push_back(make_pair(m_vPatterns[i], j)); } //v.clear(); v.swap(v1);*/ return true; } void RenamerPatternsDlgImpl::onHelp() { openHelp("240_file_renamer.html"); } void RenamerPatternsDlgImpl::onCrtPosChanged() { QTextCursor crs (m_pTextM->textCursor()); m_nCrtLine = crs.blockNumber(); m_nCrtCol = crs.columnNumber(); m_pCrtPosL->setText(QString("Line %1, Col %2").arg(m_nCrtLine + 1).arg(m_nCrtCol + 1)); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/DiscogsDownloader.h���������������������������������������������������������0000444�0001750�0000144�00000007526�12040477675�017062� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DiscogsDownloaderH #define DiscogsDownloaderH #include "AlbumInfoDownloaderDlgImpl.h" namespace Discogs { struct SearchXmlHandler; struct DiscogsAlbumInfo : public WebAlbumInfoBase { enum StyleOption { GENRE_ONLY, GENRE_COMMA_STYLE, GENRE_PAR_STYLE, STYLE_ONLY }; const StyleOption* m_peStyleOption; // should be a reference, but that would make assignment fail DiscogsAlbumInfo(const StyleOption* peStyleOption) : m_peStyleOption(peStyleOption) {} std::string m_strComposer; std::string m_strGenre; std::string m_strStyle; std::string m_strNotes; std::string m_strId; /*override*/ void copyTo(AlbumInfo& dest); std::string getGenre() const; // combination of m_strGenre and m_strStyle }; }; class DiscogsDownloader : public AlbumInfoDownloaderDlgImpl { Q_OBJECT std::vector<Discogs::DiscogsAlbumInfo> m_vAlbums; Discogs::DiscogsAlbumInfo::StyleOption m_eStyleOption; friend struct Discogs::SearchXmlHandler; void clear(); /*override*/ bool initSearch(const std::string& strArtist, const std::string& strAlbum); /*override*/ std::string createQuery(); /*override*/ void loadNextPage(); /*override*/ void requestAlbum(int nAlbum); /*override*/ void requestImage(int nAlbum, int nImage); /*override*/ void reloadGui(); /*override*/ QHttp* getWaitingHttp(); /*override*/ WebAlbumInfoBase& album(int i); /*override*/ int getAlbumCount() const; /*override*/ QXmlDefaultHandler* getSearchXmlHandler(); /*override*/ QXmlDefaultHandler* getAlbumXmlHandler(int nAlbum); /*override*/ const WebAlbumInfoBase* getCrtAlbum() const; // returns 0 if there's no album /*override*/ int getColumnCount() const { return 4; } /*override*/ void saveSize(); /*override*/ char getReplacementChar() const { return '+'; } protected: int m_nPageSize; public: DiscogsDownloader(QWidget* pParent, SessionSettings& settings, bool bSaveResults); ~DiscogsDownloader(); /*$PUBLIC_FUNCTIONS$*/ static const char* SOURCE_NAME; public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pSearchB_clicked(); void on_m_pStyleCbB_currentIndexChanged(int); private: }; #endif // #ifndef DiscogsDownloaderH ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/RenamerPatternsDlgImpl.h����������������������������������������������������0000644�0001750�0000144�00000004244�11233524007�020010� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef RenamerPatternsDlgImplH #define RenamerPatternsDlgImplH #include <vector> #include <string> #include <QDialog> #include "ui_Patterns.h" class SessionSettings; class RenamerPatternsDlgImpl : public QDialog, private Ui::PatternsDlg { Q_OBJECT std::vector<std::string> m_vstrPatterns; SessionSettings& m_settings; int m_nCrtLine, m_nCrtCol; public: RenamerPatternsDlgImpl(QWidget* pParent, SessionSettings& settings); ~RenamerPatternsDlgImpl(); bool run(std::vector<std::string>&); protected slots: void on_m_pOkB_clicked(); void on_m_pCancelB_clicked(); void onHelp(); void onCrtPosChanged(); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Notes.cpp�������������������������������������������������������������������0000644�0001750�0000144�00000040623�11335446574�015070� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <sstream> #include <vector> #include <algorithm> #include "Notes.h" #include "Helpers.h" using namespace std; using namespace pearl; /*static*/ Notes::NoteSet Notes::s_spAllNotes; /*static*/ vector<vector<const Note*> > Notes::s_vpNotesByCateg (static_cast<int>(Note::CATEG_CNT)); /*static*/ vector<const Note*> Notes::s_vpAllNotes; static const char* s_szPlaceholderDescr ("<Placeholder for a note that can no longer be found, most likely as a result of a software upgrade. You should rescan the file.>"); // to be used by serialization: if a description is no longer found, the note gets replace with a default, "missing", one /*static*/ const Note* Notes::getMissingNote() { static Note::SharedData sd (Note::SUPPORT, Note::CUSTOM, s_szPlaceholderDescr, false); // !!! m_nLabelIndex is initialized to -1, which will result in an empty label; static Note note (sd, -1); return ¬e; } /*static*/ const Note* Notes::getMaster(const Note* p) { const Note* q (getNote(p->getDescription())); if (0 != q) { return q; } q = getMissingNote(); CB_ASSERT (p->m_pSharedData == q->m_pSharedData); return q; } // destoys the pointers added by addToDestroyList(); to be called after loading is complete; /*static*/void Notes::clearDestroyList() { clearPtrContainer(s_spDestroyList); } /*static*/ set<Note::SharedData*> Notes::s_spDestroyList; /*static*/ void Notes::addNote(Note* p) { CB_ASSERT (0 == s_spAllNotes.count(p)); int nCateg (p->getCategory()); CB_ASSERT (0 <= nCateg && nCateg < Note::CATEG_CNT); p->m_pSharedData->m_nLabelIndex = cSize(s_vpNotesByCateg[nCateg]); s_vpNotesByCateg[nCateg].push_back(p); p->m_pSharedData->m_nNoteId = cSize(s_vpAllNotes); s_vpAllNotes.push_back(p); s_spAllNotes.insert(p); } //ttt2 if one of the addNote() is missing, the program just crashes instead of showing an assertion; the reason seems to be that the UI will ask for the color of an invalid note; /*static*/ void Notes::initVec() { static bool s_bInit (false); if (s_bInit) { return; } s_bInit = true; // audio addNote(&Notes::twoAudio()); // e addNote(&Notes::lowQualAudio()); // w addNote(&Notes::noAudio()); // e addNote(&Notes::vbrUsedForNonMpg1L3()); // w addNote(&Notes::incompleteFrameInAudio()); // e addNote(&Notes::validFrameDiffVer()); // e addNote(&Notes::validFrameDiffLayer()); // e addNote(&Notes::validFrameDiffMode()); // e addNote(&Notes::validFrameDiffFreq()); // e addNote(&Notes::validFrameDiffCrc()); // e addNote(&Notes::audioTooShort()); // e addNote(&Notes::diffBitrateInFirstFrame()); // e addNote(&Notes::noMp3Gain()); // w addNote(&Notes::untestedEncoding()); // s // xing addNote(&Notes::twoLame()); // e addNote(&Notes::xingAddedByMp3Fixer()); // e addNote(&Notes::xingFrameCountMismatch()); // e addNote(&Notes::twoXing()); // e addNote(&Notes::xingNotBeforeAudio()); // e addNote(&Notes::incompatXing()); // e addNote(&Notes::missingXing()); // w // vbri addNote(&Notes::twoVbri()); addNote(&Notes::vbriFound()); addNote(&Notes::foundVbriAndXing()); // w // id3 v2 addNote(&Notes::id3v2FrameTooShort()); // e addNote(&Notes::id3v2InvalidName()); // e addNote(&Notes::id3v2IncorrectFlg1()); // w addNote(&Notes::id3v2IncorrectFlg2()); // w addNote(&Notes::id3v2TextError()); // e addNote(&Notes::id3v2HasLatin1NonAscii()); // w addNote(&Notes::id3v2EmptyTcon()); // w addNote(&Notes::id3v2MultipleFramesWithSameName()); // w addNote(&Notes::id3v2PaddingTooLarge()); // w addNote(&Notes::id3v2UnsuppVer()); // s addNote(&Notes::id3v2UnsuppFlag()); // s addNote(&Notes::id3v2UnsuppFlags1()); // s addNote(&Notes::id3v2UnsuppFlags2()); // s addNote(&Notes::id3v2DuplicatePopm()); //s addNote(&Notes::id3v2EmptyTag()); //w // ttt2 perhaps move up in a new release, so it isn't shown after support notes; better: assign ids to support notes at the end of the alphabet; addNote(&Notes::id3v2EmptyTextFrame()); //w // ttt2 perhaps move up in a new release, so it isn't shown after support notes; better: assign ids to support notes at the end of the alphabet; // apic addNote(&Notes::id3v2NoApic()); // w addNote(&Notes::id3v2CouldntLoadPic()); // w //addNote(&Notes::id3v2LinkNotSupported()); // s addNote(&Notes::id3v2NotCoverPicture()); // w addNote(&Notes::id3v2ErrorLoadingApic()); // w addNote(&Notes::id3v2ErrorLoadingApicTooShort()); // w addNote(&Notes::id3v2DuplicatePic()); // e addNote(&Notes::id3v2MultipleApic()); // w addNote(&Notes::id3v2UnsupApicTextEnc()); //s addNote(&Notes::id3v2LinkInApic()); //s addNote(&Notes::id3v2PictDescrIgnored()); //s // id3 v2.3.0 addNote(&Notes::noId3V230()); // w addNote(&Notes::twoId3V230()); // e addNote(&Notes::bothId3V230_V240()); // w addNote(&Notes::id3v230AfterAudio()); // e addNote(&Notes::id3v230UsesUtf8()); // w addNote(&Notes::id3v230UnsuppText()); // s addNote(&Notes::id3v230CantReadFrame()); // e // id3 v2.4.0 addNote(&Notes::twoId3V240()); // e addNote(&Notes::id3v240CantReadFrame()); // e addNote(&Notes::id3v240IncorrectSynch()); // w addNote(&Notes::id3v240DeprTyerAndTdrc()); // w addNote(&Notes::id3v240DeprTyer()); // w addNote(&Notes::id3v240DeprTdatAndTdrc()); // w addNote(&Notes::id3v240IncorrectDli()); // w addNote(&Notes::id3v240IncorrectFrameSynch()); // w addNote(&Notes::id3v240DeprTdat()); // w addNote(&Notes::id3v240UnsuppText()); // s // id3 v1 addNote(&Notes::onlyId3V1()); // w addNote(&Notes::id3v1BeforeAudio()); // w addNote(&Notes::id3v1TooShort()); // e addNote(&Notes::twoId3V1()); // e //addNote(&Notes::zeroInId3V1()); addNote(&Notes::mixedPaddingInId3V1()); // w addNote(&Notes::mixedFieldPaddingInId3V1()); // w addNote(&Notes::id3v1InvalidName()); // e addNote(&Notes::id3v1InvalidArtist()); // e addNote(&Notes::id3v1InvalidAlbum()); // e addNote(&Notes::id3v1InvalidYear()); // e addNote(&Notes::id3v1InvalidComment()); // e // broken addNote(&Notes::brokenAtTheEnd()); // e addNote(&Notes::brokenInTheMiddle()); // e // trunc addNote(&Notes::truncAudioWithWholeFile()); // e addNote(&Notes::truncAudio()); // e // unknown addNote(&Notes::unknTooShort()); // w addNote(&Notes::unknownAtTheEnd()); // e addNote(&Notes::unknownInTheMiddle()); // e addNote(&Notes::foundNull()); // w // lyrics addNote(&Notes::lyrTooShort()); // e addNote(&Notes::twoLyr()); // s addNote(&Notes::invalidLyr()); // e addNote(&Notes::duplicateFields()); // s //addNote(&Notes::imgInLyrics()); // s addNote(&Notes::infInLyrics()); // s // ape addNote(&Notes::apeItemTooShort()); // e addNote(&Notes::apeItemTooBig()); // e addNote(&Notes::apeMissingTerminator()); // e addNote(&Notes::apeFoundFooter()); // e addNote(&Notes::apeTooShort()); // e addNote(&Notes::apeFoundHeader()); // e addNote(&Notes::apeHdrFtMismatch()); // e addNote(&Notes::twoApe()); // s addNote(&Notes::apeFlagsNotSupported()); // s addNote(&Notes::apeUnsupported()); // s // misc addNote(&Notes::fileWasChanged()); // w addNote(&Notes::noInfoTag()); // w addNote(&Notes::tooManyTraceNotes()); // w addNote(&Notes::tooManyNotes()); // w addNote(&Notes::tooManyStreams()); // w addNote(&Notes::unsupportedFound()); // w addNote(&Notes::rescanningNeeded()); // w { CB_ASSERT (Note::CUSTOM == Note::CATEG_CNT - 1); for (int i = 1; i < cSize(s_vpAllNotes); ++i) { const Note* p1 (s_vpAllNotes[i - 1]); const Note* p2 (s_vpAllNotes[i]); CB_ASSERT (p1->getCategory() <= p2->getCategory()); CB_ASSERT (p1->getNoteId() <= p2->getNoteId()); } } // qDebug("%d errors, %d warnings, %d support notes", cSize(s_vpErrNotes), cSize(s_vpWarnNotes), cSize(s_vpSuppNotes)); } //ttt2 perhaps warn that file has multiple pictures, so will get deleted; probably like unsupportedFound; anyway after deciding on some standard way to tell the user about features and limitations; a class is probably a better answer than the current approach of "told/warned/..." settings scattered over the config file; should not show the messages too soon one after another, should get rid of all the static variables, ... /*static*/ const Note* Notes::getNote(const std::string& strDescr) { initVec(); Note::SharedData d (strDescr.c_str(), false); // !!! sev doesn't matter Note n (d); NoteSet::iterator it; it = (s_spAllNotes.find(&n)); if (s_spAllNotes.end() == it) { if (strDescr == s_szPlaceholderDescr) { return getMissingNote(); } return 0; } return *it; } /*static*/ const Note* Notes::getNote(int n) // returns 0 if n is out of range { initVec(); if (n < 0 || n >= cSize(s_vpAllNotes)) { return 0; } return s_vpAllNotes[n]; } /*static*/ const std::vector<const Note*>& Notes::getAllNotes() { initVec(); return s_vpAllNotes; } /*static*/ const vector<int>& Notes::getDefaultIgnoredNoteIds() { initVec(); static bool bInit (false); static vector<int> v; if (!bInit) { bInit = true; //v.push_back(zeroInId3V1().getNoteId()); v.push_back(mixedPaddingInId3V1().getNoteId()); v.push_back(mixedFieldPaddingInId3V1().getNoteId()); //v.push_back(lyricsNotSupported().getNoteId()); v.push_back(tooManyTraceNotes().getNoteId()); v.push_back(tooManyNotes().getNoteId()); } return v; } //============================================================================================================ //============================================================================================================ //============================================================================================================ //ttt2 maybe new type for Note::Severity: BROKEN, which is basically the same as ERR, but shown in UI with a different color //ttt2 maybe new type for Note::Severity: INFO, to be used for searches; normally they are "ignored", but can be used to search for, e.g., "CBR files" //====================================================================================================== //====================================================================================================== Note::Note(const Note& note, std::streampos pos, const std::string& strDetail /*= ""*/) : m_pSharedData(note.m_pSharedData), m_pos(pos), m_strDetail(strDetail) { //char a [30]; sprintf(a, "1 Note::Note() %p", this); TRACER(a); } Note::Note(SharedData& sharedData, std::streampos pos, const std::string& strDetail /*= ""*/) : m_pSharedData(&sharedData), m_pos(pos), m_strDetail(strDetail) { //char a [30]; sprintf(a, "2 Note::Note() %p", this); TRACER(a); } Note::Note(SharedData& sharedData) : m_pSharedData(&sharedData), m_pos(-1) { //char a [30]; sprintf(a, "3 Note::Note() %p", this); TRACER(a); } Note::Note() { //char a [30]; sprintf(a, "4 Note::Note() %p", this); TRACER(a); } Note::~Note() { //qDebug("destroyed note at %p", this); //char a [30]; sprintf(a, "Note::~Note() %p", this); TRACER(a); } //ttt2 maybe get rid of some/most ser-specific constructors, revert const changes, and call real constructors from the parent (adding serialization as member functions required switching from references to pointers and from const to non-const data members) bool Note::operator==(const Note& other) const { return m_pSharedData == other.m_pSharedData && m_pos == other.m_pos && m_strDetail == other.m_strDetail; } // returns an empty string for an invalid position (i.e. one initialized from -1) string Note::getPosHex() const { if (-1 == m_pos) { return ""; } ostringstream s; s << "0x" << hex << m_pos; return s.str(); } //====================================================================================================== //====================================================================================================== NoteColl::~NoteColl() { pearl::clearPtrContainer(m_vpNotes); } void NoteColl::add(Note* pNote) { if (Note::TRACE == pNote->getSeverity()) { if (m_nMaxTrace == m_nTraceCount) { m_vpNotes.push_back(new Note(Notes::tooManyTraceNotes(), -1)); ++m_nTraceCount; } if (m_nTraceCount > m_nMaxTrace) { delete pNote; return; } ++m_nTraceCount; } else { if (200 == m_nCount) { m_vpNotes.push_back(new Note(Notes::tooManyNotes(), -1)); ++m_nCount; } if (m_nCount > 200) { delete pNote; return; } ++m_nCount; } trace(pNote->getPosHex() + string(": ") + pNote->getDescription()); if (!pNote->getDetail().empty()) { trace(pNote->getDetail()); // ttt2 perhaps log the description only if the detail is empty (so strDetail would be expected to hold all the info in strDescription) } // try to avoid adding duplicates by comparing pNote to the last 10 notes for (int i = 10, n = cSize(m_vpNotes) - 1; i > 0 && n >= 0; --i, --n) { const Note* pLast (m_vpNotes[n]); if (*pLast == *pNote) { delete pNote; return; } } m_vpNotes.push_back(pNote); } void NoteColl::sort() { std::sort(m_vpNotes.begin(), m_vpNotes.end(), CmpNotePtrById()); // !!! needed when applying filters } void NoteColl::removeTraceNotes() { vector<Note*> v; for (int i = 0, n = cSize(m_vpNotes); i < n; ++i) { Note* p (m_vpNotes[i]); if (Note::TRACE == p->getSeverity()) { delete p; } else { v.push_back(p); } } m_vpNotes.swap(v); } bool NoteColl::hasFastSaveWarn() const { for (int i = cSize(m_vpNotes) - 1; i >= 0; --i) { Note* pNote (m_vpNotes[i]); if (*pNote == Notes::rescanningNeeded()) { return true; } } return false; } void NoteColl::addFastSaveWarn() { if (hasFastSaveWarn()) { return; } add(new Note(Notes::rescanningNeeded(), -1)); } void NoteColl::removeNotes(const std::streampos& posFrom, const std::streampos& posTo) // removes notes with addresses in the given range; posFrom is included, but posTo isn't { for (int i = cSize(m_vpNotes) - 1; i >= 0; --i) { Note* pNote (m_vpNotes[i]); if (pNote->getPos() >= posFrom && pNote->getPos() < posTo) { delete pNote; m_vpNotes.erase(m_vpNotes.begin() + i); } } } bool Notes::CompNoteByName::operator()(const Note* p1, const Note* p2) const { return strcmp(p1->getDescription(), p2->getDescription()) < 0; } �������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/SongInfoParser.cpp����������������������������������������������������������0000644�0001750�0000144�00000121152�11265066162�016665� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <stack> #include <sstream> #include "SongInfoParser.h" #include "Helpers.h" #include "DataStream.h" using namespace std; using namespace pearl; namespace SongInfoParser { //ttt2 perhaps null namespace (some classes are used in the header, though) // helper for TrackTextParser; // // base class for reading fields (artist, track#, ...) from a string containing the name of a file; // the string is passed in init(), which can be called repeatedly, without a need for new Reader objects to be created; // subclasses: BoundReader, UnboundReader, SequenceReader and OptionalReader struct Reader { enum Optional { OPT, NON_OPT }; enum Bound { BOUND, UNBOUND }; enum State { UNASSIGNED, ASSIGNED, FAILED }; enum { RIGHT, LEFT }; Optional m_eOptional; Bound getBound(bool bLeft) const { return bLeft ? m_eLeftBound : m_eRightBound; } Bound getLeftBound() const { return m_eLeftBound; } Bound getRightBound() const { return m_eRightBound; } State m_eState; const char* m_pcLeft; // set during the call to init() if it returns true const char* m_pcRight; // set during the call to init() if it returns true Reader(Optional eOptional, Bound eLeftBound, Bound eRightBound) : m_eOptional(eOptional), m_eState(UNASSIGNED), m_eLeftBound(eLeftBound), m_eRightBound(eRightBound) { } virtual ~Reader() {} enum { RIGHT_FIRST, LEFT_FIRST }; enum { MOBILE_LEFT, FIXED_LEFT }; enum { MOBILE_RIGHT, FIXED_RIGHT }; virtual bool init(const char* pcLeft, const char* pcRight, bool bLeftFirst, bool bFixedLeft, bool bFixedRight) = 0; // sets m_pcLeft and m_pcRight such that the field is matched; returns false if the assignment couldn't be made virtual void clearState() { m_eState = UNASSIGNED; } virtual void set(vector<string>&) {} protected: Bound m_eLeftBound, m_eRightBound; // rating, year, track - know when to stop bool failure() { m_eState = FAILED; return false; } bool success() { m_eState = ASSIGNED; return true; } private: Reader(const Reader&); Reader& operator=(const Reader&); }; struct BoundReader : public Reader { BoundReader(Optional eOptional) : Reader(eOptional, BOUND, BOUND) {} /*override*/ bool init(const char* pcLeft, const char* pcRight, bool bLeftFirst, bool bFixedLeft, bool bFixedRight); private: virtual int checkMatch(const char* pcLeft, const char* pcRight, const char* pcStart) = 0; // returns the size of the matching string, starting at pcStart; returns -1 if no match is found }; /*override*/ bool BoundReader::init(const char* pcLeft, const char* pcRight, bool bLeftFirst, bool bFixedLeft, bool bFixedRight) { const char* p (bLeftFirst ? pcLeft : pcRight - 1); int nInc (bLeftFirst ? 1 : -1); for (; p < pcRight && p >= pcLeft; p += nInc) { int nMatch (checkMatch(pcLeft, pcRight, p)); if (-1 != nMatch) { m_pcLeft = p; m_pcRight = p + nMatch; if ((bFixedLeft && m_pcLeft != pcLeft) || (bFixedRight && m_pcRight != pcRight)) { return failure(); } return success(); } //if (bFixedLeft && m_pcLeft != pcLeft) || (bFixedRight && m_pcRight != pcRight)) // ttt2 suboptimal; /*if (bFixedLeft || bFixedRight) { // if either end was supposed to be fixed and the first step wasn't a match, there's no point in going to another step return failure(); // !!! incorrect; the reason is the "-1" in the first line; for example a static reader "ab" fixed at right would fail on "xxab", because the first test would be for "b", and only the second test for "ab"; if we fail after first test there's no chance for the second; replacing "-1" with "-2" would fix the problem in this case, but that doesn't quite work, because static readers aren't the only bound readers, and the other ones may have variable length }*/ if (bLeftFirst && bFixedLeft) { // if the left end was supposed to be fixed and the first step wasn't a match, there's no point in going to another step; OTOH something similar cannot be done for the right side return failure(); } } return failure(); } struct StaticReader : public BoundReader { StaticReader() : BoundReader(NON_OPT) {} string m_str; private: /*override*/ int checkMatch(const char* /*pcLeft*/, const char* pcRight, const char* pcStart) { int nSize (cSize(m_str)); if (pcRight - pcStart < nSize) { return -1; } string s (pcStart, nSize); if (s == m_str) { return nSize; } return -1; } }; struct RatingReader : public BoundReader { RatingReader() : BoundReader(NON_OPT) {} /*override*/ void set(vector<string>& v) { v[TagReader::RATING].assign(m_pcLeft, 1); } private: /*override*/ int checkMatch(const char* pcLeft, const char* pcRight, const char* pcStart) { if (pcStart > pcLeft && isalnum(*(pcStart - 1))) { return -1; } if (pcStart < pcRight - 1 && !isdigit(*(pcStart + 1))) { return -1; } char c (*pcStart); if (c < 'a' || c > 'z') { return -1; } return 1; } }; struct TrackNoReader : public BoundReader { TrackNoReader() : BoundReader(NON_OPT) {} /*override*/ void set(vector<string>& v) { //v[TagReader::TRACK_NUMBER].assign(m_pcLeft, m_pcRight - m_pcLeft); string s; s.assign(m_pcLeft, m_pcRight - m_pcLeft); if ("00" == s) { s.clear(); } v[TagReader::TRACK_NUMBER] = s; } private: enum { DIGIT_LIMIT = 2 }; //ttt2 maybe make configurable /*override*/ int checkMatch(const char* pcLeft, const char* pcRight, const char* pcStart) { if (!isdigit(*(pcStart)) || (pcStart > pcLeft && isdigit(*(pcStart - 1)))) { return -1; } const char* p (pcStart); for (; p < pcRight && isdigit(*p); ++p) { } int nCnt (p - pcStart); if (nCnt > DIGIT_LIMIT) { return -1; } return nCnt; } }; struct YearReader : public BoundReader { YearReader() : BoundReader(NON_OPT) {} /*override*/ void set(vector<string>& v) { v[TagReader::TIME].assign(m_pcLeft, 4); } private: /*override*/ int checkMatch(const char* pcLeft, const char* pcRight, const char* pcStart) { if (!isdigit(*(pcStart)) || (pcStart > pcLeft && isdigit(*(pcStart - 1)))) { return -1; } const char* p (pcStart); for (; p < pcRight && isdigit(*p); ++p) { } int nCnt (p - pcStart); if (4 != nCnt) { return -1; } char q [5]; strncpy(q, pcStart, 4); q[4] = 0; int nYear (atoi(q)); if (nYear < 1900 || nYear > 2100) { return -1; } return nCnt; } }; struct UnboundReader : public Reader { UnboundReader(int nIndex) : Reader(NON_OPT, UNBOUND, UNBOUND), m_nIndex(nIndex) {} /*override*/ bool init(const char* pcLeft, const char* pcRight, bool /*bLeftFirst*/, bool /*bFixedLeft*/, bool /*bFixedRight*/) { m_pcLeft = pcLeft; m_pcRight = pcRight; m_eState = m_pcLeft != m_pcRight ? ASSIGNED : FAILED; //ttt2 see about the test; not sure if allowing an empty string is ok; //ttt2 perhaps at least %i should be allowed to be empty; maybe add constructor param to tell if empty is OK return ASSIGNED == m_eState; } /*override*/ void set(vector<string>& v) { v[m_nIndex].assign(m_pcLeft, m_pcRight - m_pcLeft); } private: int m_nIndex; }; // handles a sequence of other Readers struct SequenceReader : public Reader { struct ReaderInfo { Reader* m_pReader; bool m_bFromLeft; int m_nOrigPos; ReaderInfo(Reader* pReader, bool bFromLeft, int nOrigPos) : m_pReader(pReader), m_bFromLeft(bFromLeft), m_nOrigPos(nOrigPos) {} }; vector<Reader*> m_vpReaders; SequenceReader() : Reader(NON_OPT, BOUND, BOUND) {} bool setBounds() // to be called after all elems have been added; returns false if there's something wrong with the elements (e.g. touching unbounded) { int nCnt (cSize(m_vpReaders)); //CB_ASSERT (0 != nCnt); // empty sequence are not allowed; if (0 == nCnt) { return false; } /*m_eLeftBound = m_eRightBound = UNBOUND; if (NON_OPT == m_vpReaders[0]->m_eOptional && BOUND == m_vpReaders[0]->getLeftBound()) { m_eLeftBound = BOUND; } if (NON_OPT == m_vpReaders[nCnt - 1]->m_eOptional && BOUND == m_vpReaders[nCnt - 1]->getRightBound()) { m_eRightBound = BOUND; }*/ m_eLeftBound = m_eRightBound = BOUND; // skip all opt that are bound; if any unbound found, set unbound for (int i = 0; i < nCnt; ++i) { if (NON_OPT == m_vpReaders[i]->m_eOptional && BOUND == m_vpReaders[i]->getLeftBound()) { break; } if (UNBOUND == m_vpReaders[i]->getLeftBound()) { m_eLeftBound = UNBOUND; break; } } // skip all opt that are bound; if any unbound found, set unbound for (int i = nCnt - 1; i >= 0; --i) { if (NON_OPT == m_vpReaders[i]->m_eOptional && BOUND == m_vpReaders[i]->getRightBound()) { break; } if (UNBOUND == m_vpReaders[i]->getRightBound()) { m_eRightBound = UNBOUND; break; } } // don't allow unbound ends to touch one another; optionals make it more complicated: a bound optional is ignored, while an unbound optional is considered non-optional bool bPrevRightBound (true); for (int i = 0; i < nCnt; ++i) { Reader* p (m_vpReaders[i]); if (!bPrevRightBound && UNBOUND == p->getLeftBound()) { return false; } if (NON_OPT == p->m_eOptional) { // non-optional bPrevRightBound = BOUND == p->getRightBound(); } else { // optional bPrevRightBound = bPrevRightBound && (BOUND == p->getRightBound()); } } return true; } /*override*/ void clearState() { m_eState = UNASSIGNED; for (int i = 0, n = cSize(m_vpReaders); i < n; ++i) { m_vpReaders[i]->clearState(); } } /*override*/ bool init(const char* pcLeft, const char* pcRight, bool bLeftFirst, bool bFixedLeft, bool bFixedRight) { CB_ASSERT (UNASSIGNED == m_eState); if (m_vpReaders.empty()) { if (pcLeft == pcRight) { return success(); } else { return failure(); } } m_eState = FAILED; m_pcLeft = pcLeft; m_pcRight = pcRight; // needed to allow findLimits() to work const int nCnt (cSize(m_vpReaders)); vector<ReaderInfo> v; // ttt2 perhaps move this to setBounds(), to avoid building it every time; it seems that both a "left" and a "right" vector would be needed, since it's possible for bLeftFirst to come with either value, depending on other Readers failing or not (to be further analyzed) { int l (0); for (; l < nCnt; ++l) // bound at the beginning, on the left (or rather on the side indicated by bLeftFirst, but to understand the comments in this block it's easier to assume that bLeftFirst is true) { int f (bLeftFirst ? l : nCnt - 1 - l); Reader* p (m_vpReaders[f]); if (BOUND != p->getBound(!bLeftFirst)) { break; } // !!! keep adding from the left as long as there is a RIGHT bound v.push_back(ReaderInfo(p, bLeftFirst, f)); } int r (nCnt - 1); for (; r > l; --r) // bound at the end, on the right { int f (bLeftFirst ? r : nCnt - 1 - r); Reader* p (m_vpReaders[f]); if (BOUND != p->getBound(bLeftFirst)) { break; } v.push_back(ReaderInfo(p, !bLeftFirst, f)); } for (int k = l; k <= r; ++k) // all remaining statics, from the left { int f (bLeftFirst ? k : nCnt - 1 - k); Reader* p (m_vpReaders[f]); if (0 != dynamic_cast<StaticReader*>(p)) // !!! StaticReader is always bound at both sides { v.push_back(ReaderInfo(p, bLeftFirst, f)); } } for (int k = l; k <= r; ++k) // all remaining bound at both sides, from the left { int f (bLeftFirst ? k : nCnt - 1 - k); Reader* p (m_vpReaders[f]); if (BOUND == p->getBound(LEFT) && BOUND == p->getBound(RIGHT) && 0 == dynamic_cast<StaticReader*>(p)) { v.push_back(ReaderInfo(p, bLeftFirst, f)); } } // now what is left is sourrounded by bound readers at their unbounded side(s) (or are at a margin) for (int k = l; k <= r; ++k) // all remaining, from the left { int f (bLeftFirst ? k : nCnt - 1 - k); Reader* p (m_vpReaders[f]); if (UNBOUND == p->getBound(LEFT) || UNBOUND == p->getBound(RIGHT)) { v.push_back(ReaderInfo(p, bLeftFirst, f)); } } } CB_ASSERT (cSize(v) == cSize(m_vpReaders)); for (int i = 0; i < nCnt; ++i) { Reader* pCrt (v[i].m_pReader); bool bCrtDir (v[i].m_bFromLeft); const char* pcCrtLeft; const char* pcCrtRight; bool bCrtFixedLeft, bCrtFixedRight; findLimits(v[i].m_nOrigPos, pcCrtLeft, pcCrtRight, bFixedLeft, bFixedRight, bCrtFixedLeft, bCrtFixedRight); pCrt->init(pcCrtLeft, pcCrtRight, bCrtDir, bCrtFixedLeft, bCrtFixedRight); CB_ASSERT (pCrt->m_eState != UNASSIGNED); bool bFail (pCrt->m_eState != ASSIGNED); if (!bFail) { // make sure no unusable space is left to the left int k (v[i].m_nOrigPos - 1); for (; k >= 0 && m_vpReaders[k]->m_eState == FAILED; --k) {} if (k >= 0) { // found something if (ASSIGNED == m_vpReaders[k]->m_eState && m_vpReaders[k]->m_pcRight != pCrt->m_pcLeft) { bFail = true; } } } if (!bFail) { // make sure no unusable space is left to the right int k (v[i].m_nOrigPos + 1); for (; k < nCnt && m_vpReaders[k]->m_eState == FAILED; ++k) {} if (k < nCnt) { // found something if (ASSIGNED == m_vpReaders[k]->m_eState && m_vpReaders[k]->m_pcLeft != pCrt->m_pcRight) { bFail = true; } } } if (bFail) { if (OPT != pCrt->m_eOptional) { // failure on non-optional return false; } pCrt->m_eState = FAILED; } } m_pcLeft = 0; m_pcRight = 0; { // assign m_pcLeft and m_pcRight + assert there are no holes; const char* pLastRight (pcLeft); Reader* pLastRd (0); for (int i = 0; i < nCnt; ++i) { Reader* p (m_vpReaders[i]); CB_ASSERT (UNASSIGNED != p->m_eState); if (ASSIGNED == p->m_eState) { //CB_ASSERT (pLastRight == p->m_pcLeft || (!m_bTopLevel && 0 == pLastRd)); if (pLastRight != p->m_pcLeft && 0 != pLastRd) { // there is a gap between the previous and current reader return false; } //CB_ASSERT (0 == pLastRd || BOUND == pLastRd->m_eBound || BOUND == p->m_eBound); // 2 unbound can't be neighbors, because then there's no way to split something between them; tttx 2008.12.17 - this doesn't allow handling of "%t[ - %a]" but allowing it here is not enough: actually "[ - %a]" is "bound to the left", and should have priority vs "%t"; 2009.01.13 - seems no longer relevant pLastRd = p; pLastRight = p->m_pcRight; if (0 == m_pcLeft) { m_pcLeft = p->m_pcLeft; } m_pcRight = p->m_pcRight; } } if (0 == pLastRd && 0 == m_pcLeft && 0 == m_pcRight) { // sequence of optionals, all failed; return false; // !!! otherwise there would be issues matching it's left/right to the neighbours; also, the only place a seq with all failed is legal is inside an Optional } CB_ASSERT (0 != pLastRd); // must be true, because !m_vpReaders.empty() /*if (pLastRight != pcRight && m_bTopLevel) { // there is a match for the sequence, but some charachters remain to the left; that's invalid in the top level reader return false; }*/ //CB_ASSERT (pLastRight == pcRight || !m_bTopLevel); CB_ASSERT (0 != m_pcLeft); CB_ASSERT (0 != m_pcRight); } if ((bFixedLeft && m_pcLeft != pcLeft) || (bFixedRight && m_pcRight != pcRight)) { return failure(); } return success(); } /*override*/ void set(vector<string>& v) { if (ASSIGNED != m_eState) { return; } for (int i = 0, n = cSize(m_vpReaders); i < n; ++i) { Reader* p (m_vpReaders[i]); if (ASSIGNED == p->m_eState) { p->set(v); } } } private: void findLimits(int nPos, const char*& pcLeft, const char*& pcRight, bool bSeqFixedLeft, bool bSeqFixedRight, bool& bFixedLeft, bool& bFixedRight); // finds limits for m_vpReader[nPos], based on the status of the other elements //bool m_bTopLevel; }; void SequenceReader::findLimits(int nPos, const char*& pcLeft, const char*& pcRight, bool bSeqFixedLeft, bool bSeqFixedRight, bool& bFixedLeft, bool& bFixedRight) // finds limits for m_vpReader[nPos], based on the status of the other elements { pcLeft = m_pcLeft; for (int k = nPos - 1; k >= 0; --k) { Reader* p (m_vpReaders[k]); if (ASSIGNED == p->m_eState) { pcLeft = p->m_pcRight; break; } } int n (cSize(m_vpReaders)); pcRight = m_pcRight; for (int k = nPos + 1; k < n; ++k) { Reader* p (m_vpReaders[k]); if (ASSIGNED == p->m_eState) { pcRight = p->m_pcLeft; break; } } int nLeft (nPos - 1); // the reader to the left of that on nPos, skipping those that failed; -1 if there's no such thing for (; nLeft >= 0 && FAILED == m_vpReaders[nLeft]->m_eState; --nLeft) {} bFixedLeft = (-1 == nLeft && bSeqFixedLeft) || (-1 != nLeft && ASSIGNED == m_vpReaders.at(nLeft)->m_eState); //bFixedRight = (n - 1 == nPos && bSeqFixedRight) || (n - 1 != nPos && ASSIGNED == m_vpReaders[nPos + 1]->m_eState); int nRight (nPos + 1); // the reader to the right of that on nPos, skipping those that failed; n if there's no such thing for (; nRight <= n - 1 && FAILED == m_vpReaders[nRight]->m_eState; ++nRight) {} bFixedRight = (n == nRight && bSeqFixedRight) || (n != nRight && ASSIGNED == m_vpReaders.at(nRight)->m_eState); } struct OptionalReader : public Reader { SequenceReader* m_pSequenceReader; OptionalReader(SequenceReader* pSequenceReader) : Reader(OPT, pSequenceReader->getLeftBound(), pSequenceReader->getRightBound()), m_pSequenceReader(pSequenceReader) {} /*override*/ bool init(const char* pcLeft, const char* pcRight, bool bLeftFirst, bool bFixedLeft, bool bFixedRight) { m_pSequenceReader->init(pcLeft, pcRight, bLeftFirst, bFixedLeft, bFixedRight); m_eState = m_pSequenceReader->m_eState; m_pcLeft = m_pSequenceReader->m_pcLeft; m_pcRight = m_pSequenceReader->m_pcRight; return ASSIGNED == m_eState; } /*override*/ void clearState() { m_eState = UNASSIGNED; m_pSequenceReader->clearState(); } /*override*/ void set(vector<string>& v) { if (ASSIGNED == m_eState) { m_pSequenceReader->set(v); } } }; TrackTextParser::TrackTextParser(const string& strPattern) : m_strPattern(strPattern) { if (strPattern.empty()) { throw InvalidPattern(0); } string::size_type n (0); char cSep (getPathSep()); enum FoundSep { NO, ESC, FREE }; FoundSep e (NO); for (;;) { // don't allow mixing of free and escaped patterns n = strPattern.find(cSep, n); if (n == string::npos) { break; } if (0 == n || '%' != strPattern[n - 1]) { if (ESC == e) { throw InvalidPattern(n); } else { e = FREE; } } else { if (FREE == e) { throw InvalidPattern(n); } else { e = ESC; } } ++n; } m_bSplitAtPathSep = (FREE == e); construct(strPattern); // so we can debug } void TrackTextParser::construct(const std::string& strPattern) { const char* pBegin (strPattern.c_str()); char cSep (getPathSep()); if (cSep == *pBegin) { CB_ASSERT (m_bSplitAtPathSep); ++pBegin; } const char* p (pBegin); int nErrPos (-1); StaticReader* pCrtStatic (0); stack<SequenceReader*> stack; stack.push(new SequenceReader()); m_vpAllReaders.push_back(stack.top()); m_vpSeqReaders.push_back(stack.top()); for (;; ++p) { char c (*p); if (0 == c) { break; } bool bRegularChar (c != '[' && c != ']' && c != '%' && c != cSep); if ('%' == c) { char c1 (*(p + 1)); if ('%' == c1 || '[' == c1 || ']' == c1 || cSep == c1) { c = c1; ++p; bRegularChar = true; } } if (bRegularChar) { if (0 == pCrtStatic) { pCrtStatic = new StaticReader(); m_vpAllReaders.push_back(pCrtStatic); stack.top()->m_vpReaders.push_back(pCrtStatic); } pCrtStatic->m_str += c; } else { pCrtStatic = 0; if (cSep == c) { CB_ASSERT (m_bSplitAtPathSep); if (1 != cSize(stack)) { nErrPos = p - pBegin; goto err; } if (!stack.top()->setBounds()) { nErrPos = p - pBegin; goto err; } stack.pop(); stack.push(new SequenceReader()); m_vpAllReaders.push_back(stack.top()); m_vpSeqReaders.push_back(stack.top()); } else { switch (c) { case '[': { stack.push(new SequenceReader()); m_vpAllReaders.push_back(stack.top()); break; // !!! there's no point in creating an OptionalReader now; it will be created at the end of the optional sequence } case ']': { if (1 == cSize(stack)) { nErrPos = p - pBegin; goto err; } if (!stack.top()->setBounds()) { nErrPos = p - pBegin; goto err; } OptionalReader* o (new OptionalReader(stack.top())); m_vpAllReaders.push_back(o); stack.pop(); stack.top()->m_vpReaders.push_back(o); break; } case '%': { c = *++p; switch (c) { case 'n': { stack.top()->m_vpReaders.push_back(new TrackNoReader()); break; } case 'a': { stack.top()->m_vpReaders.push_back(new UnboundReader(TagReader::ARTIST)); break; } case 't': { stack.top()->m_vpReaders.push_back(new UnboundReader(TagReader::TITLE)); break; } case 'b': { stack.top()->m_vpReaders.push_back(new UnboundReader(TagReader::ALBUM)); break; } case 'y': { stack.top()->m_vpReaders.push_back(new YearReader()); break; } case 'g': { stack.top()->m_vpReaders.push_back(new UnboundReader(TagReader::GENRE)); break; } case 'r': { stack.top()->m_vpReaders.push_back(new RatingReader()); break; } case 'c': { stack.top()->m_vpReaders.push_back(new UnboundReader(TagReader::COMPOSER)); break; } //ttt2 perhaps add something for "various artists" case 'i': { stack.top()->m_vpReaders.push_back(new UnboundReader(TagReader::LIST_END)); break; } // !!! LIST_END for ignored items default: { nErrPos = p - pBegin; goto err; } } break; } default: CB_ASSERT(false); } } } } if (1 == cSize(stack) && stack.top()->setBounds()) { return; } nErrPos = p - pBegin; err: clearPtrContainer(m_vpAllReaders); throw InvalidPattern(nErrPos); } TrackTextParser::~TrackTextParser() { clearPtrContainer(m_vpAllReaders); } void TrackTextParser::assign(const string& s, vector<string>& v) { CB_ASSERT (TagReader::LIST_END + 1 == cSize(v)); // !!! "LIST_END + 1" instead of just "LIST_END", so the last entry can be used for "%i" (i.e. "ignored") for (int i = cSize(m_vpSeqReaders) - 1; i >= 0; --i) { m_vpSeqReaders[i]->clearState(); } string::size_type nPrev (s.size()); // last position to search (inclusive) if (m_bSplitAtPathSep) { if (nPrev <= 4) { return; } nPrev -= 5; // discard ".mp3" extension } else { --nPrev; // needed because a "1" will be added below } const char* szName (s.c_str()); int n (cSize(m_vpSeqReaders)); CB_ASSERT (1 == n || m_bSplitAtPathSep); for (int i = n - 1; i >= 0; --i) { string::size_type nCrt (m_bSplitAtPathSep ? s.rfind(getPathSep(), nPrev) : 0); if (string::npos == nCrt) { break; } if (!m_bSplitAtPathSep) { --nCrt; // now it's -1 (or rather npos), to get it ready for the addition of 1 } SequenceReader& rd (*m_vpSeqReaders[i]); rd.init(szName + nCrt + 1, szName + nPrev + 1, Reader::LEFT_FIRST, Reader::FIXED_LEFT, Reader::FIXED_RIGHT); if (SequenceReader::ASSIGNED == rd.m_eState) { CB_ASSERT(rd.m_pcRight - rd.m_pcLeft == (int)nPrev - (int)nCrt); rd.set(v); /*if (rd.m_pcRight - rd.m_pcLeft == (int)nPrev - (int)nCrt) // have to test this for top-level SeqReaders, which must cover the whole in this case { rd.set(v); }*/ } nPrev = nCrt; if (0 == nPrev) { break; } --nPrev; } for (int i = 0; i < TagReader::LIST_END; ++i) { trim(v[i]); } } // returns an empty string if the pattern is valid and an error message (including the column) if it's invalid string testPattern(const string& strPattern) { try { TrackTextParser rd (strPattern); return ""; } catch (const TrackTextParser::InvalidPattern& ex) { ostringstream s; s << "\"" << toNativeSeparators(strPattern) << "\" is not a valid pattern. Error in column " << ex.m_nPos << "."; //ttt2 perhaps more details return s.str(); } } } // namespace SongInfoParser #ifdef LPPPLPJOJAOIIIOJ #include <iostream> struct TestTrackTextParser { string f (string s) { for (;;) { string::size_type n (s.find(' ')); if (string::npos == n) { return " " + s + "\n"; } s[n] = '*'; } } TestTrackTextParser() { /* { cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/%n[%r]"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/b/q/12ab.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } } { cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/[%r]%n"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/b/q/ab12.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } } { cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/%a/%b/[%r]%n [-[ ]]%t"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/b/q/wa04 Snow Come Down.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } } */ /*{ cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/%a/%t/[%r]%n"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/e/q/ab12.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } } { cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/%a/%t/[%r]%n"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/e/q/b12.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } }*/ /*{ cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/[.%a.]%b"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/e/q/.aaaa.bbbb.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } }*/ /*{ cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/[.]%b"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/e/q/aaaa.bbbb.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } } { cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/[.]%b"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/e/q/aaaa,bbbb.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } } try { //SongInfoParser::TrackTextParser fr ("/%a%b"); //SongInfoParser::TrackTextParser fr ("/%a[%b]"); //%a/%b/[%r]%n [-[ ]]%t SongInfoParser::TrackTextParser fr ("/[-[ ]]%t"); } catch (...) { cout << "err\n"; }*/ /*{ //ttt2 make these work: SongInfoParser::TrackTextParser fr ("/[ [ ]][-[ [ ]]]%t"); //SongInfoParser::TrackTextParser fr ("/%t"); const char* s ("-------------------------------\n"); vector<string> v; vector<string> (TagReader::LIST_END + 1).swap(v); fr.init(".../ tst01.mp3", v); cout << "2 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } }//*/ /*{ //ttt2 make these work: SongInfoParser::TrackTextParser fr ("/[[%r]%n][[ ] ][-[[ ] ]]%t"); //SongInfoParser::TrackTextParser fr ("/%t"); const char* s ("-------------------------------\n"); vector<string> v; vector<string> (TagReader::LIST_END + 1).swap(v); fr.init(".../b06 -tst01.mp3", v); cout << "2 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } }*/ /*{ SongInfoParser::TrackTextParser fr ("/[[%r]%n][ [ ]][-[ [ ]]]%t"); const char* s ("-------------------------------\n"); vector<string> v; vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06tst01.mp3", v); cout << "1 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06 tst01.mp3", v); cout << "2 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06 tst01.mp3", v); cout << "3 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06-tst01.mp3", v); cout << "4 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06- tst01.mp3", v); cout << "5 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06 -tst01.mp3", v); cout << "6 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06 - tst01.mp3", v); cout << "7 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06 - tst01.mp3", v); cout << "8 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06 - tst01.mp3", v); cout << "9 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign(".../b06 - tst01.mp3", v); cout << "10 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } }//*/ /*{ SongInfoParser::TrackTextParser fr ("[[%r]%n][ [ ]][-[ [ ]]]%t"); const char* s ("-------------------------------\n"); vector<string> v; vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06tst01.mp3", v); cout << "1 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06 tst01.mp3", v); cout << "2 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06 tst01.mp3", v); cout << "3 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06-tst01.mp3", v); cout << "4 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06- tst01.mp3", v); cout << "5 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06 -tst01.mp3", v); cout << "6 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06 - tst01.mp3", v); cout << "7 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06 - tst01.mp3", v); cout << "8 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06 - tst01.mp3", v); cout << "9 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("b06 - tst01.mp3", v); cout << "10 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } }//*/ { SongInfoParser::TrackTextParser fr ("%t-%an"); const char* s ("-------------------------------\n"); vector<string> v; vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("HHHHHHHHHHHHHH - QQQQQQQ Listen", v); cout << "1 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("H-Listen", v); cout << "2 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } }//*/ { SongInfoParser::TrackTextParser fr ("%t-%aen"); const char* s ("-------------------------------\n"); vector<string> v; vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("HHHHHHHHHHHHHH - QQQQQQQ Listen", v); cout << "3 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } vector<string> (TagReader::LIST_END + 1).swap(v); fr.assign("H-Len", v); cout << "4 " << s; for (int i = 0; i < cSize(v); ++i) { cout << i << f(v[i]); } }//*/ /* patterns\value0000=%a/%b/[%r]%n [-[ ]]%t patterns\value0001=%t patterns\value0002=%i %t[go] patterns\value0003=[%a][%b] patterns\value0004=%a-%b patterns\value0005=%a[-%b] patterns\value0006=[%a-]%b patterns\value0007=[%a]%b { cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/%a/%b/[%r]%n [-[ ]]%t"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/b/q/wa04 Snow Come Down.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } } { cout << "-------------------------------\n"; SongInfoParser::TrackTextParser fr ("/%a/%b/[%r]%n [-[ ]]%t"); vector<string> v (TagReader::LIST_END + 1); fr.init("/r/temp/1/tmp2/c pic/b/q/a04 Snow Come Down.mp3", v); for (int i = 0; i < cSize(v); ++i) { cout << i << " " << v[i] << endl; } }*/ } }; /* --------------------- cp "tst01.mp3" "d1/b06tst01.mp3" cp "tst01.mp3" "d1/b06 tst01.mp3" cp "tst01.mp3" "d1/b06 tst01.mp3" cp "tst01.mp3" "d1/b06-tst01.mp3" cp "tst01.mp3" "d1/b06- tst01.mp3" cp "tst01.mp3" "d1/b06 -tst01.mp3" cp "tst01.mp3" "d1/b06 - tst01.mp3" cp "tst01.mp3" "d1/b06 - tst01.mp3" cp "tst01.mp3" "d1/b06 - tst01.mp3" cp "tst01.mp3" "d1/b06 - tst01.mp3" cp "tst01.mp3" "d1/06tst01.mp3" cp "tst01.mp3" "d1/06 tst01.mp3" cp "tst01.mp3" "d1/06 tst01.mp3" cp "tst01.mp3" "d1/06-tst01.mp3" cp "tst01.mp3" "d1/06- tst01.mp3" cp "tst01.mp3" "d1/06 -tst01.mp3" cp "tst01.mp3" "d1/06 - tst01.mp3" cp "tst01.mp3" "d1/06 - tst01.mp3" cp "tst01.mp3" "d1/06 - tst01.mp3" cp "tst01.mp3" "d1/06 - tst01.mp3" cp "tst01.mp3" "d1/btst01.mp3" cp "tst01.mp3" "d1/b tst01.mp3" cp "tst01.mp3" "d1/b tst01.mp3" cp "tst01.mp3" "d1/b-tst01.mp3" cp "tst01.mp3" "d1/b- tst01.mp3" cp "tst01.mp3" "d1/b -tst01.mp3" cp "tst01.mp3" "d1/b - tst01.mp3" cp "tst01.mp3" "d1/b - tst01.mp3" cp "tst01.mp3" "d1/b - tst01.mp3" cp "tst01.mp3" "d1/b - tst01.mp3" */ TestTrackTextParser qqwtrh; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/OsFile.cpp������������������������������������������������������������������0000644�0001750�0000144�00000037137�11340210606�015144� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <iostream> #include "fstream_unicode.h" #include <cerrno> #include <algorithm> #include <QFileInfo> #include <QDateTime> #include <QDir> #include <QTemporaryFile> #ifndef _MSC_VER #include <utime.h> #else #include <sys/utime.h> #endif #ifndef WIN32 #else #include <windows.h> #endif /* #include <sys/stat.h> //#include <sys/types.h> //#include <unistd.h> #include <dirent.h> */ #include "OsFile.h" #include "Helpers.h" //--------------------------------------------------------------------------- using namespace std; using namespace pearl; //namespace ciobi_utils { class FileSearcherImpl { CB_LIB_CALL FileSearcherImpl(const FileSearcherImpl&); FileSearcherImpl& CB_LIB_CALL operator=(const FileSearcherImpl&); public: //CB_LIB_CALL FileSearcherImpl() : m_hFind(INVALID_HANDLE_VALUE), m_findData() {} CB_LIB_CALL FileSearcherImpl() : m_nCrtEntry(0) {} int m_nCrtEntry; QFileInfoList m_vFileInfos; }; CB_LIB_CALL FileSearcher::FileSearcher() : m_pImpl(new FileSearcherImpl) { } CB_LIB_CALL FileSearcher::FileSearcher(const string& strDirName) : m_pImpl(new FileSearcherImpl) { findFirst(strDirName); } //TSearchRec sr; CB_LIB_CALL FileSearcher::~FileSearcher() { //FindClose(sr); close(); } CB_LIB_CALL FileSearcher::operator bool() const { return m_pImpl->m_nCrtEntry < m_pImpl->m_vFileInfos.size(); } bool CB_LIB_CALL FileSearcher::isFile() const { return QFileInfo(convStr(getName())).isFile(); } bool CB_LIB_CALL FileSearcher::isDir() const { return QFileInfo(convStr(getName())).isDir(); } bool CB_LIB_CALL FileSearcher::isSymLink() const { return QFileInfo(convStr(getName())).isSymLink(); } // it's easier to use the constructor, but sometimes may be more convenient to leave the object in an outer loop bool CB_LIB_CALL FileSearcher::findFirst(const string& strDirName) { close(); if (endsWith(strDirName, getPathSepAsStr())) { m_strDir = strDirName; } else { m_strDir = strDirName + getPathSepAsStr(); } m_pImpl->m_vFileInfos = QDir(convStr(m_strDir)).entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::AllDirs); m_pImpl->m_nCrtEntry = 0; return goToNextValidEntry(); } // skips "." and "..", as well as any invalid item (usually file that has been removed after entryInfoList() got called) bool CB_LIB_CALL FileSearcher::goToNextValidEntry() { for (;;) { if (!*this) { return false; } QString s (m_pImpl->m_vFileInfos[m_pImpl->m_nCrtEntry].fileName()); CB_ASSERT (s != "." && s != ".."); // it was QDir::NoDotAndDotDot if (!m_pImpl->m_vFileInfos[m_pImpl->m_nCrtEntry].exists()) { ++m_pImpl->m_nCrtEntry; continue; //ttt2 see if seeking the next is the best way to deal with this error } return true; } close(); return false; } bool CB_LIB_CALL FileSearcher::findNext() { CB_CHECK1 (*this, InvalidOperation()/*"findNext() may only be called on an open searcher"*/); ++m_pImpl->m_nCrtEntry; return goToNextValidEntry(); } void CB_LIB_CALL FileSearcher::close() { m_pImpl->m_vFileInfos.clear(); m_pImpl->m_nCrtEntry = 0; } string CB_LIB_CALL FileSearcher::getName() const { CB_CHECK1 (*this, InvalidOperation()/*"getName() may only be called on an open searcher"*/); return convStr(m_pImpl->m_vFileInfos[m_pImpl->m_nCrtEntry].absoluteFilePath()); } long long CB_LIB_CALL FileSearcher::getSize() const { CB_CHECK1 (*this, InvalidOperation()/*"getSize() may only be called on an open searcher"*/); return m_pImpl->m_vFileInfos[m_pImpl->m_nCrtEntry].size(); } long long CB_LIB_CALL FileSearcher::getChangeTime() const { CB_CHECK1 (*this, InvalidOperation()/*"getChangeTime() may only be called on an open searcher"*/); return m_pImpl->m_vFileInfos[m_pImpl->m_nCrtEntry].lastModified().toTime_t(); //ttt3 32bit } /*int CB_LIB_CALL FileSearcher::getAttribs() const { return m_pImpl->m_findData.dwFileAttributes; }*/ //void CB_LIB_CALL getFileInfo(const char* szFileName, long long & nCreationTime, long long & nChangeTime, long long& nSize) void CB_LIB_CALL getFileInfo(const string& strFileName, long long & nChangeTime, long long& nSize) { QFileInfo fi (convStr(strFileName)); if (!fi.exists()) { throw NameNotFound(); //throw CannotGetData(strFileName, getOsError(), LI); } nChangeTime = fi.lastModified().toTime_t(); //ttt3 32bit nSize = fi.size(); } #ifndef WIN32 #else static wstring wstrFromUtf8(const string& s) { vector<wchar_t> w (s.size() + 1); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, &w[0], w.size()); //inspect(&w[0], w.size()*2); return &w[0]; } #endif //void CB_LIB_CALL setFileDate(const char* szFileName, time_t nCreationTime, long long nChangeTime) void CB_LIB_CALL setFileDate(const string& strFileName, long long nChangeTime) { #ifndef WIN32 utimbuf t; t.actime = (time_t)nChangeTime; t.modtime = (time_t)nChangeTime; if (0 != utime(strFileName.c_str(), &t)) { //throw CannotSetDates(strFileName, getOsError(), LI); throw 1; //ttt2 } #else _utimbuf t; t.actime = (time_t)nChangeTime; t.modtime = (time_t)nChangeTime; if (0 != _wutime(wstrFromUtf8(strFileName).c_str(), &t)) { //throw CannotSetDates(strFileName, getOsError(), LI); throw 1; //ttt2 } #endif } // throws IncorrectDirName if the name ends with a path separator void CB_LIB_CALL checkDirName(const string& strDirName) { CB_CHECK1 (!endsWith(strDirName, getPathSepAsStr()), IncorrectDirName()); //ttt2 more checks } // returns true if there is a file with that name; // returns false if the name doesn't exist or it's a directory; doesn't throw bool CB_LIB_CALL fileExists(const std::string& strFileName) { QFileInfo fi (convStr(strFileName)); return fi.isFile(); // ttt2 not sure if this should allow symlinks } // returns true if there is a directory with that name; // returns false if the name doesn't exist or it's a file; //ttt2 throws IncorrectDirName bool CB_LIB_CALL dirExists(const std::string& strDirName) { if (strDirName.empty()) { return true; } checkDirName(strDirName); string strDir1 (strDirName); #ifndef WIN32 #else if (2 == cSize(strDir1)) { strDir1 += getPathSepAsStr(); } #endif QFileInfo fi (convStr(strDir1)); return fi.isDir(); // ttt2 not sure if this should allow symlinks } void CB_LIB_CALL createDir(const string& strDirName) { if (strDirName.empty()) { return; } // the root dir always exists checkDirName(strDirName); if (dirExists(strDirName)) { return; } string::size_type n (strDirName.rfind(getPathSep())); CB_CHECK1 (string::npos != n, CannotCreateDir(strDirName)); string strParent (strDirName.substr(0, n)); createDir(strParent); QFileInfo fi (convStr(strDirName)); CB_CHECK1 (fi.dir().mkdir(fi.fileName()), CannotCreateDir(strDirName)); CB_CHECK1 (dirExists(strDirName), CannotCreateDir(strDirName)); } void CB_LIB_CALL createDirForFile(const std::string& strFileName) { string::size_type n (strFileName.rfind(getPathSep())); CB_ASSERT (string::npos != n); createDir(strFileName.substr(0, n)); } // does nothing on Linux; replaces "D:" with "/D" on Windows, only when "D:" isn't at the beggining of the string; string replaceDriveLetter(const string& strFileName) { #ifndef WIN32 return strFileName; #else string s (strFileName); for (string::size_type n = 2;; ) { n = s.find(':', n); if (string::npos == n) { return s; } s[n] = s[n - 1]; s[n - 1] = '/'; } #endif } // adds a path separator at the end if none is present; throws IncorrectDirName on invalid file names string getSepTerminatedDir(const string& strDirName) { string strRes (strDirName); if (!endsWith(strDirName, getPathSepAsStr())) { strRes += getPathSep(); } checkDirName(strRes.substr(0, strRes.size() - 1)); return strRes; } // removes the path separator at the end if present; throws IncorrectDirName on invalid file names string getNonSepTerminatedDir(const string& strDirName) { string strRes (strDirName); if (endsWith(strDirName, getPathSepAsStr())) { strRes.erase(strRes.size() - 1); } checkDirName(strRes); return strRes; } // renames a file; // throws FoundDir, AlreadyExists, NameNotFound, CannotRenameFile, ?IncorrectDirName, void CB_LIB_CALL renameFile(const std::string& strOldName, const std::string& strNewName) { CB_CHECK1 (!dirExists(strNewName), FoundDir()); CB_CHECK1 (!dirExists(strOldName), FoundDir()); // ttt2 separate OldFoundDir / NewFoundDir CB_CHECK1 (!fileExists(strNewName), AlreadyExists()); CB_CHECK1 (fileExists(strOldName), NameNotFound()); createDirForFile(strNewName); //ttt3 undo on error /* int n (rename(strOldName.c_str(), strNewName.c_str())); int nErr (errno); if (0 != n && EXDEV != nErr) { qDebug("I/O Error %d: %s", strerror(nErr)); } if (0 != n && EXDEV == nErr)*/ if (!QDir().rename(convStr(strOldName), convStr(strNewName))) { // rename only works on a single drive, so work around this //ttt2 warn if this is called a lot try { copyFile2(strOldName, strNewName); } catch (const CannotCopyFile&) { throw CannotRenameFile(); } catch (...) //ttt2 not quite right //ttt2 perhaps also NameNotFound, AlreadyExists, ... { throw CannotRenameFile(); } deleteFile(strOldName); return; } //CB_CHECK1 (0 == n, CannotRenameFile()); } // creates a copy a file; // doesn't preserve any attributes; // ttt2 add option // throws WriteError or EndOfFile from Helpers //ttt2 switch to: throws FoundDir, AlreadyExists, NameNotFound, CannotCopyFile, ?IncorrectDirName, void CB_LIB_CALL copyFile(const std::string& strSourceName, const std::string& strDestName /*, OverwriteOption eOverwriteOption*/) { ifstream_utf8 in (strSourceName.c_str(), ios::binary); ofstream_utf8 out (strDestName.c_str(), ios::binary); streampos nSize (getSize(in)); appendFilePart(in, out, 0, nSize); CB_CHECK1 (out, WriteError()); streampos nOutSize (out.tellp()); CB_CHECK1 (nOutSize == nSize, WriteError()); } void CB_LIB_CALL copyFile2(const std::string& strSourceName, const std::string& strDestName /*, OverwriteOption eOverwriteOption*/) { CB_CHECK1 (!dirExists(strDestName), FoundDir()); CB_CHECK1 (!dirExists(strSourceName), FoundDir()); // ttt2 separate OldFoundDir / NewFoundDir CB_CHECK1 (!fileExists(strDestName), AlreadyExists()); CB_CHECK1 (fileExists(strSourceName), NameNotFound()); createDirForFile(strDestName); //ttt3 undo on error ifstream_utf8 in (strSourceName.c_str(), ios::binary); ofstream_utf8 out (strDestName.c_str(), ios::binary); CB_CHECK1 (in, CannotCopyFile()); CB_CHECK1 (out, CannotCopyFile()); streampos nSize (getSize(in)); try { appendFilePart(in, out, 0, nSize); } catch (const WriteError&) { throw CannotCopyFile(); } streampos nOutSize (out.tellp()); if (!out || nOutSize != nSize) { out.close(); deleteFile(strDestName); throw CannotCopyFile(); } long long nChangeTime; long long x; getFileInfo(strSourceName.c_str(), nChangeTime, x); setFileDate(strDestName.c_str(), nChangeTime); } // deletes a file; throws FoundDir, // CannotDeleteFile, ?IncorrectDirName; it is OK if the file didn't exist to begin with void CB_LIB_CALL deleteFile(const std::string& strFileName) { CB_CHECK1 (!dirExists(strFileName), FoundDir()); if (!fileExists(strFileName)) { return; } QFileInfo fi (convStr(strFileName)); CB_CHECK1 (fi.dir().remove(fi.fileName()), CannotDeleteFile()); } // just a name that doesn't exist; the file won't be deleted automatically; normally the name is obtained by appending something to strMasterFileName, but a more generic temp is used if the name is too long on wnd string getTempFile(const std::string& strMasterFileName) { QTemporaryFile tmp (convStr(strMasterFileName)); QString qs; if (tmp.open() #ifndef WIN32 #else && convStr(tmp.fileName()).size() < MAX_PATH //ttt3 not sure if MAX_PATH includes the terminator or not, so assume it does #endif ) { qs = tmp.fileName(); } else { QTemporaryFile tmp1; CB_ASSERT (tmp1.open()); //ttt2 if it gets to this on W7 (and perhaps others) the file attributes are wrong, probably allowing only the current user to see it; ttt2 perhaps only use the dir, instead of the full file name in such case; //ttt2 doc qs = tmp1.fileName(); } string s (convStr(qs)); //qDebug("patt: '%s', tmp: '%s'", strMasterFileName.c_str(), s.c_str()); return s; //ttt2 make sure it works OK if strMasterFileName is empty } // the name of a parent directory; returns an empty string if no parent exists; may throw IncorrectDirName string getParent(const string& strName) { checkDirName(strName); string::size_type n (strName.rfind(getPathSep())); //CB_ASSERT(string::npos != n); if (string::npos == n) { return ""; } return strName.substr(0, n); } bool isInsideDir(const std::string& strName, const std::string& strDirName) // if strName is in strDirName or in one of its subdirectories; may throw IncorrectDirName for either param { checkDirName(strName); checkDirName(strDirName); return beginsWith(strName, strDirName) && getPathSep() == strName[strDirName.size()]; } string getExistingDir(const std::string& strName) // if strName exists and is a dir, it is returned; otherwise it returns the closest ancestor that exists; accepts names ending with file separator { string s (strName); if (endsWith(s, getPathSepAsStr())) { s.erase(s.size() - 1); } try { while (!s.empty() && !dirExists(s)) { s = getParent(s); } } catch (const IncorrectDirName&) { s.clear(); } return s; } //ttt2 perhaps use strerror_r() to print file errors //} //namespace ciobi_utils ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/AlbumInfoDownloader.ui������������������������������������������������������0000644�0001750�0000144�00000050510�11267270051�017507� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>AlbumInfoDownloaderDlg</class> <widget class="QDialog" name="AlbumInfoDownloaderDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>964</width> <height>686</height> </rect> </property> <property name="windowTitle" > <string>WWW</string> </property> <property name="sizeGripEnabled" > <bool>true</bool> </property> <layout class="QVBoxLayout" > <item> <widget class="QGroupBox" name="groupBox" > <property name="title" > <string>Search</string> </property> <layout class="QHBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="m_pSrchArtistL" > <property name="text" > <string>Artist</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pSrchArtistE" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>4</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="readOnly" > <bool>false</bool> </property> </widget> </item> <item> <widget class="QLabel" name="m_pSrchAlbumL" > <property name="text" > <string>Album</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pSrchAlbumE" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>5</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="readOnly" > <bool>false</bool> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pMatchCountCkB" > <property name="text" > <string>Match count</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pSearchB" > <property name="text" > <string>Search</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_2" > <property name="title" > <string>Results</string> </property> <layout class="QVBoxLayout" > <property name="topMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_2" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="label" > <property name="text" > <string>Artist</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pResArtistE" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>4</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QLabel" name="label_2" > <property name="text" > <string>Album</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pResAlbumE" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>5</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QLabel" name="label_4" > <property name="text" > <string>Released</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pRealeasedE" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>2</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_10" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="m_pGenreL" > <property name="text" > <string>Genre</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pGenreE" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>3</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QLabel" name="m_pStyleL" > <property name="text" > <string>Use</string> </property> </widget> </item> <item> <widget class="QComboBox" name="m_pStyleCbB" /> </item> <item> <widget class="QLabel" name="label_5" > <property name="text" > <string>Format</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pFormatE" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > <horstretch>2</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QLabel" name="m_pSpacer01L" > <property name="text" > <string/> </property> </widget> </item> <item> <widget class="QLabel" name="m_pViewAtAmazonL" > <property name="text" > <string>Amazon</string> </property> <property name="margin" > <number>0</number> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_7" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > <horstretch>0</horstretch> <verstretch>4</verstretch> </sizepolicy> </property> <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QTableView" name="m_pTrackListG" /> </item> <item> <widget class="QWidget" native="1" name="m_pImgP" > <layout class="QVBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget_6" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="m_pImageL" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize" > <size> <width>300</width> <height>300</height> </size> </property> <property name="maximumSize" > <size> <width>300</width> <height>300</height> </size> </property> <property name="frameShape" > <enum>QFrame::Box</enum> </property> <property name="text" > <string>Image</string> </property> <property name="alignment" > <set>Qt::AlignCenter</set> </property> <property name="textInteractionFlags" > <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::NoTextInteraction</set> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_9" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="m_pImgSizeL" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize" > <size> <width>0</width> <height>10</height> </size> </property> <property name="text" > <string>Image size</string> </property> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>3</height> </size> </property> </spacer> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_3" > <property name="sizePolicy" > <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > <horstretch>0</horstretch> <verstretch>1</verstretch> </sizepolicy> </property> <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QTextBrowser" name="m_pAlbumNotesM" > <property name="sizePolicy" > <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > <horstretch>5</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> <item> <widget class="QTextBrowser" name="m_pDownloadsM" > <property name="sizePolicy" > <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > <horstretch>3</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_4" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="m_pResultNoL" > <property name="minimumSize" > <size> <width>170</width> <height>0</height> </size> </property> <property name="maximumSize" > <size> <width>170</width> <height>16777215</height> </size> </property> <property name="text" > <string>ResultNo</string> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pPrevAlbumB" > <property name="toolTip" > <string>Previous album</string> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/arrow-left-double.svg</iconset> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pPrevB" > <property name="toolTip" > <string>Previous image or album</string> </property> <property name="text" > <string>p</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/arrow-left.svg</iconset> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pNextB" > <property name="toolTip" > <string>Next image or album</string> </property> <property name="text" > <string>n</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/arrow-right.svg</iconset> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pNextAlbumB" > <property name="toolTip" > <string>Next album</string> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/arrow-right-double.svg</iconset> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QLabel" name="label_3" > <property name="text" > <string> Filter:</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pImageFltCkB" > <property name="text" > <string>Image</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pCdFltCkB" > <property name="text" > <string>CD</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pTrackCntFltCkB" > <property name="text" > <string>Track count</string> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_5" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QLabel" name="m_pVolumeL" > <property name="enabled" > <bool>false</bool> </property> <property name="text" > <string>Volume</string> </property> </widget> </item> <item> <widget class="QComboBox" name="m_pVolumeCbB" > <property name="enabled" > <bool>false</bool> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pSaveImageB" > <property name="text" > <string>Save image</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pSaveAllB" > <property name="text" > <string>Save all</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pCancelB" > <property name="text" > <string>Cancel</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> <resources> <include location="Mp3Diags.qrc" /> </resources> <connections/> </ui> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/main.cpp��������������������������������������������������������������������0000644�0001750�0000144�00000031103�11423062172�014677� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <algorithm> #include <cstdio> #include <iostream> #include <locale> #include <QApplication> #include <QSettings> #include <QFileInfo> #include <QMessageBox> #include "MainFormDlgImpl.h" #include "SessionEditorDlgImpl.h" #include "SessionsDlgImpl.h" #include "Helpers.h" #include "StoredSettings.h" #include "OsFile.h" //#include "Profiler.h" using namespace std; static const char* APP_NAME ("Mp3Diags"); static const char* ORGANIZATION ("Ciobi"); GlobalSettings::GlobalSettings() { m_pSettings = new QSettings (ORGANIZATION, APP_NAME); } GlobalSettings::~GlobalSettings() { delete m_pSettings; } void GlobalSettings::saveSessions(const vector<string>& vstrSess1, const string& strLast, bool bOpenLast) { vector<string> vstrSess (vstrSess1); { // add sessions that might have been added by another instance of the program vector<string> vstrSess2; string strLast2; bool bOpenLast2; loadSessions(vstrSess2, strLast2, bOpenLast2); for (int i = 0, n = cSize(vstrSess2); i < n; ++i) { if (vstrSess.end() == find(vstrSess.begin(), vstrSess.end(), vstrSess2[i])) { vstrSess.push_back(vstrSess2[i]); // ttt2 perhaps add a return value to the function, so the caller would know to update the UI; however, what is done here is more important, because it prevents data loss } } } int n (cSize(vstrSess)); m_pSettings->setValue("main/lastSession", convStr(strLast)); m_pSettings->setValue("main/openLast", bOpenLast); m_pSettings->remove("main/sessions"); m_pSettings->setValue("main/sessions/count", n); char a [50]; for (int i = 0; i < n; ++i) { sprintf(a, "main/sessions/val%04d", i); m_pSettings->setValue(a, convStr(vstrSess[i])); } } void GlobalSettings::loadSessions(vector<string>& vstrSess, string& strLast, bool& bOpenLast) const { vstrSess.clear(); int n (m_pSettings->value("main/sessions/count", 0).toInt()); strLast = convStr(m_pSettings->value("main/lastSession").toString()); bOpenLast = m_pSettings->value("main/openLast", true).toBool(); char a [50]; for (int i = 0; i < n; ++i) { sprintf(a, "main/sessions/val%04d", i); QString qs (m_pSettings->value(a, "").toString()); if (QFileInfo(qs).isFile()) { string s (convStr(qs)); vstrSess.push_back(s); } } if (!QFileInfo(convStr(strLast)).isFile() || vstrSess.end() == find(vstrSess.begin(), vstrSess.end(), strLast)) { strLast.clear(); } } const QFont& getDefaultFont() { static QFont s_font; return s_font; } //static char* s_pFreeMem (new char[1000000]); static char* s_pFreeMem (new char[10000]); // to test this use "ulimit -v 200000" and uncomment the allocations for char[1000000] below // //ttt2 if the GUI got started, this doesn't seem to get called, regardless of the size of s_pFreeMem void newHandler() { delete[] s_pFreeMem; //puts("inside new handler"); cerr << "inside new handler" << endl; cerr.flush(); throw bad_alloc(); return; } class QMp3DiagsApplication : public QApplication { public: /*override*/ bool notify(QObject* pReceiver, QEvent *pEvent) { try { return QApplication::notify(pReceiver, pEvent); } catch (...) { CB_ASSERT (false); } } QMp3DiagsApplication(int& argc, char** argv) : QApplication(argc, argv) {} }; #ifdef MSVC_QMAKE void visStudioMessageOutput(QtMsgType, const char* szMsg) { OutputDebugStringA(" "); // to stand out from the other messages that get printed OutputDebugStringA(szMsg); OutputDebugStringA("\r\n"); //cerr << szMsg << endl; //QMessageBox::information(0, "Debug message", szMsg, QMessageBox::Ok); } #endif #include <sstream> // http://stackoverflow.com/questions/760323/why-does-my-qt4-5-app-open-a-console-window-under-windows - The option under Visual Studio for setting the subsystem is under Project Settings->Linker->System->SubSystem int main(int argc, char *argv[]) { //DEFINE_PROF_ROOT("mp3diags"); //PROF("root"); /* //locale::global(locale("")); ostringstream o; o << 12345.78; cout << o.str() << endl; printf("%f\n", 12345.78);//*/ void (*nh)() = set_new_handler(newHandler); if (0 != nh) { cerr << "previous new handler: " << (void*)nh << endl; } //for (int i = 0; i < 200; ++i) { new char[1000000]; } Q_INIT_RESOURCE(Mp3Diags); // base name of the ".qrc" file QMp3DiagsApplication app(argc, argv); #ifdef MSVC_QMAKE qInstallMsgHandler(visStudioMessageOutput); // see http://lists.trolltech.com/qt-interest/2006-10/msg00829.html //OutputDebugStringA("\n\ntest output\n\n\n"); // !!! this only works if actually debugging (started with F5); #endif { // by default on Windows the selection is hard to see in the main window, because it's some gray; QPalette pal (QApplication::palette()); pal.setColor(QPalette::Highlight, pal.color(QPalette::Active, QPalette::Highlight)); pal.setColor(QPalette::HighlightedText, pal.color(QPalette::Active, QPalette::HighlightedText)); QApplication::setPalette(pal); } if (argc > 1) { if (2 == argc && (0 == strcmp("/u", argv[1]) || 0 == strcmp("-u", argv[1]))) { QSettings s (ORGANIZATION, APP_NAME); s.clear(); //ttt2 see if this can actually remove everything, including the ORGANIZATION dir if it's empty; return 0; } printf("\nUsage:\n%s [-u]\n\n", argv[0]); return 1; } getDefaultFont(); // !!! to initialize the static var string strStartSession; int nSessCnt; bool bOpenLast; { vector<string> vstrSess; //string strLast; GlobalSettings st; st.loadSessions(vstrSess, strStartSession, bOpenLast); nSessCnt = cSize(vstrSess); } if (0 == nSessCnt) { // first run; create a new session and run it SessionEditorDlgImpl dlg (0, "", SessionEditorDlgImpl::FIRST_TIME); dlg.setWindowIcon(QIcon(":/images/logo.svg")); strStartSession = dlg.run(); if (strStartSession.empty()) { return 0; } if ("*" == strStartSession) { strStartSession.clear(); } else { vector<string> vstrSess; vstrSess.push_back(strStartSession); GlobalSettings st; st.saveSessions(vstrSess, strStartSession, dlg.shouldOpenLastSession()); } } bool bOpenSelDlg (strStartSession.empty() || !bOpenLast); try { for (;;) { { QFont fnt; string strNewFont (convStr(fnt.family())); int nNewSize (fnt.pointSize()); fixAppFont(fnt, strNewFont, nNewSize); } if (bOpenSelDlg) { SessionsDlgImpl dlg (0); dlg.setWindowIcon(QIcon(":/images/logo.svg")); strStartSession = dlg.run(); if (strStartSession.empty()) { return 0; } } bOpenSelDlg = true; CB_ASSERT (!strStartSession.empty()); { vector<string> vstrSess; bool bOpenLast; string s; GlobalSettings st; st.loadSessions(vstrSess, s, bOpenLast); st.saveSessions(vstrSess, strStartSession, bOpenLast); nSessCnt = cSize(vstrSess); } MainFormDlgImpl mainDlg (strStartSession, 1 == nSessCnt); mainDlg.setWindowIcon(QIcon(":/images/logo.svg")); if (1 == nSessCnt) { mainDlg.setWindowTitle("MP3 Diags"); } else { string::size_type n (strStartSession.rfind(getPathSep())); string s (strStartSession.substr(n + 1, strStartSession.size() - n - 3 - 2)); mainDlg.setWindowTitle("MP3 Diags - " + convStr(s)); } if (MainFormDlgImpl::OPEN_SESS_DLG != mainDlg.run()) { return 0; } } } catch (...) // ttt2 for now it doesn't catch many exceptions; it seems that nothing can be done if an exception leaves a slot / event handler, but maybe there are ways around { /*QMessageBox dlg (QMessageBox::Critical, "Error", "Caught generic exception. Exiting ...", QMessageBox::Close, 0, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint); dlg.exec(); qDebug("out - err");*/ CB_ASSERT (false); } /*mainDlg.show(); return app.exec();*/ } //"undefined reference to `qInitResources_application()'" //ttt2 perhaps sign package /* rpmlint: MP3Diags.x86_64: W: no-changelogname-tag MP3Diags.src: W: no-changelogname-tag There is no %changelog tag in your spec file. To insert it, just insert a '%changelog' in your spec file and rebuild it. MP3Diags.src: W: source-or-patch-not-bzipped MP3Diags-0.99.0.1.tar.gz A source archive or patch in your package is not bzipped (doesn't have the .bz2 extension). Files bigger than 100k should be bzip2'ed in order to save space. To bzip2 a patch, use bzip2. To bzip2 a source tarball, use bznew MP3Diags.x86_64: E: summary-ended-with-dot (Badness: 89) Tool for finding and fixing problems in MP3 files. Includes a tagger. MP3Diags.src: E: summary-ended-with-dot (Badness: 89) Tool for finding and fixing problems in MP3 files. Includes a tagger. Summary ends with a dot. ---------------- ??? rpmlint -v ../RPMS/x86_64/MP3Diags-0.99.0.1-1.x86_64.rpm W: MP3Diags untranslated-desktop-file /usr/share/applications/MP3Diags.desktop W: MP3Diags summary-ended-with-dot Tool for finding and fixing problems in MP3 files. Includes a tagger. I: MP3Diags checking E: MP3Diags tag-not-utf8 Summary E: MP3Diags tag-not-utf8 %description E: MP3Diags no-packager-tag E: MP3Diags no-changelogname-tag E: MP3Diags invalid-desktopfile /usr/share/applications/MP3Diags.desktop value "Audio;AudioVideo;AudioVideoEditing" for string list key "Categories" in group "Desktop Entry" does not have a semicolon (';') as trailing character E: MP3Diags filename-not-utf8 /usr/share/icons/hicolor/48x48/apps/MP3Diags.png E: MP3Diags filename-not-utf8 /usr/share/icons/hicolor/40x40/apps/MP3Diags.png E: MP3Diags filename-not-utf8 /usr/share/icons/hicolor/36x36/apps/MP3Diags.png E: MP3Diags filename-not-utf8 /usr/share/icons/hicolor/32x32/apps/MP3Diags.png E: MP3Diags filename-not-utf8 /usr/share/icons/hicolor/24x24/apps/MP3Diags.png E: MP3Diags filename-not-utf8 /usr/share/icons/hicolor/22x22/apps/MP3Diags.png E: MP3Diags filename-not-utf8 /usr/share/icons/hicolor/16x16/apps/MP3Diags.png E: MP3Diags filename-not-utf8 /usr/share/applications/MP3Diags.desktop E: MP3Diags filename-not-utf8 /usr/bin/MP3Diags local build on 10.3: WARNING: Category "Audio" is unknown ! WARNING: it is ignored, until you registered a Category at adrian@suse.de . */ //ttt1 CLI-support: scan some files, create logs, apply some transforms, ... �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/StreamsModel.cpp������������������������������������������������������������0000644�0001750�0000144�00000020435�11265066162�016367� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <sstream> #include <QPainter> #include <QTableView> #include "StreamsModel.h" #include "NotesModel.h" #include "FilesModel.h" #include "CommonData.h" #include "DataStream.h" using namespace std; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== StreamsModel::StreamsModel(CommonData* pCommonData) : QAbstractTableModel(pCommonData->m_pStreamsG), m_pCommonData(pCommonData) { } /*override*/ int StreamsModel::rowCount(const QModelIndex&) const { return cSize(m_pCommonData->getCrtStreams()); } /*override*/ int StreamsModel::columnCount(const QModelIndex&) const { return 5; } /*override*/ QVariant StreamsModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("StreamsModel::data()"); /* //ttt2 Excessive calls to this from MultiLineTvDelegate::sizeHint() might make applying a filter pretty slow. To reproduce: 1) The first file that will get selected by the filter should be badly broken, having 1000 streams. 2) Apply a filter by a note of that file The issue is that StreamsModel::data() gets called way too many times from MultiLineTvDelegate::sizeHint(). So even if a single call is pretty quick (not leaving room to much improvement), the total time is noticeable. Since this is a pathologic case and even then it's only a matter of several seconds, the fix can wait. (One idea would be to report that all lines above 200 have a height of one line, but perhaps there's something better.) static int CRT (0); ++CRT; if (0 == CRT % 2000) { qDebug("StreamsModel::data() call %d", CRT); } */ int j (index.column()); //if (nRole == Qt::SizeHintRole && j > 0) { return QSize(CELL_WIDTH - 1, CELL_HEIGHT - 1); } // !!! "-1" so one pixel can be used to draw the grid //if (nRole == Qt::SizeHintRole) { return QSize(CELL_WIDTH - 10, CELL_HEIGHT - 10); } // !!! "-1" so one pixel can be used to draw the grid if (!index.isValid() || nRole != Qt::DisplayRole) { return QVariant(); } const DataStream* pDataStream (m_pCommonData->getCrtStreams()[index.row()]); switch (j) { case 0: { ostringstream out; //out << "0x" << hex << setw(8) << setfill('0') << pDataStream->getPos(); out << "0x" << hex << pDataStream->getPos(); return convStr(out.str()); } case 1: { ostringstream out; out << pDataStream->getSize(); return convStr(out.str()); } case 2: { ostringstream out; out << "0x" << hex << pDataStream->getSize(); return convStr(out.str()); } case 3: { return QString(pDataStream->getDisplayName()); } case 4: return convStr(pDataStream->getInfo()); default: CB_ASSERT(false); }//out << "Ape: " <<" offset=0x" << hex << m_pos << ", size=0x" << m_nSize << dec << " (" << m_nSize << ")"; } /*override*/ QVariant StreamsModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("StreamsModel::headerData"); if (nRole == Qt::SizeHintRole) { return getNumVertHdrSize(cSize(m_pCommonData->getCrtStreams()), eOrientation); } if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { //return section; switch (nSection) { case 0: return "Address"; case 1: return "Size (dec)"; case 2: return "Size (hex)"; case 3: return "Type"; case 4: return "Stream details"; default: CB_ASSERT (false); } } return nSection + 1; } static bool containsAnyOf(const DataStream* pStream, const set<streampos>& sSel) { streampos begPos (pStream->getPos()); streampos endPos (begPos); endPos += pStream->getSize(); for (set<streampos>::const_iterator it = sSel.begin(), end = sSel.end(); it != end; ++it) //ttt2 binary search { streampos pos (*it); if (begPos <= pos && pos < endPos) { return true; } } return false; } void StreamsModel::matchSelToNotes() { int nCrt (m_pCommonData->getFilesGCrtRow()); if (-1 == nCrt) { return; } set<streampos> sSel; QModelIndexList lSelNotes (m_pCommonData->m_pNotesG->selectionModel()->selection().indexes()); QItemSelectionModel* pStreamsSelModel (m_pCommonData->m_pStreamsG->selectionModel()); pStreamsSelModel->clearSelection(); for (QModelIndexList::iterator it = lSelNotes.begin(), end = lSelNotes.end(); it != end; ++it) { int nCol (it->column()); if (0 == nCol) // it's "whole row selection", so use only the first column { sSel.insert(m_pCommonData->getCrtNotes()[it->row()]->getPos()); } } const vector<DataStream*>& vCrtStreams (m_pCommonData->getViewHandlers()[nCrt]->getStreams()); bool bFirstFound (false); for (int i = 0, n = cSize(vCrtStreams); i < n; ++i) { const DataStream* pStream (vCrtStreams[i]); if (containsAnyOf(pStream, sSel)) { if (!bFirstFound) { bFirstFound = true; m_pCommonData->m_pStreamsG->setCurrentIndex(index(i, 0)); } pStreamsSelModel->select(index(i, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); } } } void StreamsModel::onStreamsGSelChanged() { NonblockingGuard g (m_pCommonData->m_bChangeGuard); if (!g) { return; } m_pCommonData->m_pNotesModel->matchSelToStreams(); m_pCommonData->m_pFilesModel->matchSelToNotes(); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== StreamsGDelegate::StreamsGDelegate(CommonData* pCommonData) : MultiLineTvDelegate(pCommonData->m_pStreamsG), m_pCommonData(pCommonData) { } /*override*/ void StreamsGDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { pPainter->save(); QStyleOptionViewItemV2 myOption (option); if (0 == index.column() || 1 == index.column() || 2 == index.column()) { myOption.displayAlignment |= Qt::AlignRight; myOption.font = m_pCommonData->getFixedFont(); } MultiLineTvDelegate::paint(pPainter, myOption, index); pPainter->restore(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/SessionEditorDlgImpl.cpp����������������������������������������������������0000644�0001750�0000144�00000030040�11304423516�020016� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QMessageBox> #include <QFileDialog> #include <QTimer> #include <QHeaderView> #include <QSettings> #include "SessionEditorDlgImpl.h" #include "CheckedDir.h" #include "Helpers.h" #include "Transformation.h" #include "StoredSettings.h" using namespace std; //using namespace pearl; void SessionEditorDlgImpl::commonConstr() // common code for both constructors { setupUi(this); m_pDirModel = new CheckedDirModel(this, CheckedDirModel::USER_CHECKABLE); m_pDirModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::Drives); m_pDirModel->setSorting(QDir::IgnoreCase); m_pDirectoriesT->setModel(m_pDirModel); m_pDirectoriesT->expand(m_pDirModel->index("/")); m_pDirectoriesT->header()->hide(); m_pDirectoriesT->header()->setStretchLastSection(false); m_pDirectoriesT->header()->setResizeMode(0, QHeaderView::ResizeToContents); m_bOpenLastSession = true; { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } QPalette grayPalette (m_pBackupE->palette()); grayPalette.setColor(QPalette::Base, grayPalette.color(QPalette::Disabled, QPalette::Window)); m_pBackupE->setPalette(grayPalette); m_pFileNameE->setPalette(grayPalette); } // used for creating a new session; SessionEditorDlgImpl::SessionEditorDlgImpl(QWidget* pParent, const string& strDir, bool bFirstTime) : QDialog(pParent, getDialogWndFlags()), Ui::SessionEditorDlg(), m_strDir(strDir), m_bNew(true) { commonConstr(); bool bAutoFileName (false); { #ifndef WIN32 QString qs (QDir::homePath() + "/Documents"); // OK on openSUSE, not sure how standardized it is #else QSettings settings (QSettings::UserScope, "Microsoft", "Windows"); settings.beginGroup("CurrentVersion/Explorer/Shell Folders"); QString qs (fromNativeSeparators(settings.value("Personal").toString())); #endif if (QFileInfo(qs).isDir()) { qs += "/MP3Diags.ini"; if (!QDir().exists(qs)) { m_pFileNameE->setText(toNativeSeparators(qs)); bAutoFileName = true; } } } //setWindowTitle("MP3 Diags - Create a new session or load an existing one"); setWindowTitle("MP3 Diags - Create new session"); m_pDontCreateBackupRB->setChecked(true); m_pScanAtStartupCkB->setChecked(true); m_pFileNameE->setToolTip(bAutoFileName ? "This is the name of the \"settings file\"\n\n" "It is supposed to be a file that doesn't already exist. You don't need to set it up. MP3 Diags\n" "will store its settings in this file.\n\n" "The name was generated automatically. If you want to choose a different name, simply click on\n" "the button at the right to change it." : "Here you need to specify the name of a \"settings file\"\n\n" "This is supposed to be a file that doesn't already exist. You don't need to set it up. MP3 Diags\n" "will store its settings in this file.\n\n" "To change it, simply click on the button at the right to choose the name of the settings file."); if (!bFirstTime) { m_pOpenLastCkB->hide(); m_pOpenSessionsB->hide(); } } // used for editing an existing session; SessionEditorDlgImpl::SessionEditorDlgImpl(QWidget* pParent, const string& strIniFile) : QDialog(pParent, getDialogWndFlags()), Ui::SessionEditorDlg(), m_bNew(false) { commonConstr(); setWindowTitle("MP3 Diags - Edit session"); m_pFileNameE->setReadOnly(true); m_pFileNameE->setText(toNativeSeparators(convStr(strIniFile))); m_pFileNameB->hide(); m_pOpenLastCkB->hide(); //m_pLoadB->hide(); m_pOpenSessionsB->hide(); m_strIniFile = strIniFile; CB_ASSERT (!m_strIniFile.empty()); SessionSettings st (m_strIniFile); vector<string> vstrCheckedDirs, vstrUncheckedDirs; st.loadDirs(vstrCheckedDirs, vstrUncheckedDirs); m_pScanAtStartupCkB->setChecked(st.loadScanAtStartup()); TransfConfig tc; st.loadTransfConfig(tc); if (TransfConfig::Options::PO_MOVE_OR_ERASE == tc.m_options.m_eProcOrigChange) { m_pCreateBackupRB->setChecked(true); } else { m_pDontCreateBackupRB->setChecked(true); } m_pBackupE->setText(toNativeSeparators(convStr(tc.getProcOrigDir()))); m_pDirModel->setDirs(vstrCheckedDirs, vstrUncheckedDirs, m_pDirectoriesT); QTimer::singleShot(1, this, SLOT(onShow())); } SessionEditorDlgImpl::~SessionEditorDlgImpl() { delete m_pDirModel; } void SessionEditorDlgImpl::onShow() { m_pDirModel->expandNodes(m_pDirectoriesT); } // returns the name of an INI file for OK and an empty string for Cancel; returns "*" to just go to the sessions dialog; string SessionEditorDlgImpl::run() { GlobalSettings gs; int nWidth, nHeight; gs.loadSessionEdtSize(nWidth, nHeight); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } if (QDialog::Accepted != exec()) { return ""; } gs.saveSessionEdtSize(width(), height()); return m_strIniFile; } void SessionEditorDlgImpl::on_m_pOkB_clicked() { m_bOpenLastSession = m_pOpenLastCkB->isChecked(); vector<string> vstrCheckedDirs; vector<string> vstrUncheckedDirs; if (m_bNew) { QString qstrFile (fromNativeSeparators(m_pFileNameE->text())); if (!qstrFile.isEmpty() && !qstrFile.endsWith(".ini")) { qstrFile += ".ini"; m_pFileNameE->setText(toNativeSeparators(qstrFile)); } //m_strIniFile = convStr(QFileInfo(qstrFile).canonicalFilePath()); m_strIniFile = convStr(qstrFile); if (m_strIniFile.empty()) { QMessageBox::critical(this, "Error", "You need to specify the name of the settings file.\n\nThis is supposed to be a file that doesn't already exist. You don't need to set it up, but just to pick a name for it. MP3 Diags will store its settings in this file."); on_m_pFileNameB_clicked(); return; } } vstrCheckedDirs = m_pDirModel->getCheckedDirs(); if (vstrCheckedDirs.empty()) { QMessageBox::critical(this, "Error", "You need to select at least a directory to be included in the session."); return; } if (m_pCreateBackupRB->isChecked()) { QString s (fromNativeSeparators(m_pBackupE->text())); if (s.isEmpty() || !QFileInfo(s).isDir()) { QMessageBox::critical(this, "Error", "If you want to create backups, you must select an existing directory to store them."); return; } } vstrUncheckedDirs = m_pDirModel->getUncheckedDirs(); { if (m_bNew) { removeSession(m_strIniFile); } SessionSettings st (m_strIniFile); TransfConfig tc; if (!m_bNew) { st.loadTransfConfig(tc); } if (m_pDontCreateBackupRB->isChecked()) { tc.m_options.m_eProcOrigChange = TransfConfig::Options::PO_ERASE; //ttt2 inconsistency with how config handles this; perhaps just hide the backup settings for existing sessions } else { tc.m_options.m_eProcOrigChange = TransfConfig::Options::PO_MOVE_OR_ERASE; tc.setProcOrigDir(fromNativeSeparators(convStr(m_pBackupE->text()))); } st.saveTransfConfig(tc); st.saveDirs(vstrCheckedDirs, vstrUncheckedDirs); st.saveScanAtStartup(m_pScanAtStartupCkB->isChecked()); if (!st.sync()) { QMessageBox::critical(this, "Error", "Failed to write to file " + m_pFileNameE->text()); if (m_bNew) { removeSession(m_strIniFile); } return; } } accept(); } void SessionEditorDlgImpl::on_m_pCancelB_clicked() { reject(); } void SessionEditorDlgImpl::on_m_pBackupB_clicked() { QString s (fromNativeSeparators(m_pBackupE->text())); if (s.isEmpty()) { s = QDir::homePath(); } QFileDialog dlg (this, "Select folder", s, "All files (*)"); //dlg.setAcceptMode(QFileDialog::AcceptSave); dlg.setFileMode(QFileDialog::Directory); if (QDialog::Accepted != dlg.exec()) { return; } QStringList fileNames (dlg.selectedFiles()); if (1 != fileNames.size()) { return; } s = fileNames.first(); QFileInfo f (s); if (!f.isDir()) { return; } m_pBackupE->setText(toNativeSeparators(s)); m_pCreateBackupRB->setChecked(true); } void SessionEditorDlgImpl::on_m_pFileNameB_clicked() { QString s (fromNativeSeparators(m_pFileNameE->text())); if (s.isEmpty()) { if (m_strDir.empty()) { s = QDir::homePath(); } else { s = convStr(m_strDir); } } QFileDialog dlg (this, "Enter configuration file", s, "INI files (*.ini)"); dlg.setAcceptMode(QFileDialog::AcceptSave); //dlg.setFileMode(QFileDialog::Directory); if (QDialog::Accepted != dlg.exec()) { return; } QStringList fileNames (dlg.selectedFiles()); if (1 != fileNames.size()) { return; } s = fileNames.first(); if (!s.endsWith(".ini")) { s += ".ini"; } m_pFileNameE->setText(toNativeSeparators(s)); } /*static*/ string SessionEditorDlgImpl::getDataFileName(const string& strIniName) { CB_ASSERT (endsWith(strIniName, ".ini")); return strIniName.substr(0, strIniName.size() - 4) + ".dat"; } /*static*/ string SessionEditorDlgImpl::getLogFileName(const string& strIniName) { CB_ASSERT (endsWith(strIniName, ".ini")); return strIniName.substr(0, strIniName.size() - 4) + ".transf_log.txt"; } /*static*/ void SessionEditorDlgImpl::removeSession(const string& strIniName) // removes INI, DAT, and LOG { QFile::remove(convStr(strIniName)); // ttt2 perhaps check ... QFile::remove(convStr(getDataFileName(strIniName))); QFile::remove(convStr(getLogFileName(strIniName))); } void SessionEditorDlgImpl::on_m_pOpenSessionsB_clicked() { m_strIniFile = "*"; accept(); } void SessionEditorDlgImpl::onHelp() { openHelp("110_first_run.html"); //ttt2 not quite right, since there are 2 "modes" } //================================================================================================================================================ //================================================================================================================================================ //================================================================================================================================================ //ttt2 see about dereferenced symlinks ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/LogModel.cpp����������������������������������������������������������������0000644�0001750�0000144�00000010652�11265052526�015471� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QTableView> #include <QHeaderView> #include "LogModel.h" #include "CommonData.h" using namespace std; LogModel::LogModel(CommonData* pCommonData, QTableView* pLogG) : QAbstractTableModel(pLogG), m_pCommonData(pCommonData), m_pLogG(pLogG) { } /*override*/ int LogModel::rowCount(const QModelIndex&) const { //qDebug("size %d", cSize(m_pCommonData->getLog())); return cSize(m_pCommonData->getLog()); } /*override*/ int LogModel::columnCount(const QModelIndex&) const { return 1; } /*override*/ QVariant LogModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("LogModel::data()"); if (!index.isValid()) { return QVariant(); } if (nRole == Qt::ToolTipRole) { QString s (convStr(m_pCommonData->getLog()[index.row()])); //QFontMetrics fm (QApplication::fontMetrics()); QFontMetrics fm (m_pLogG->fontMetrics()); // !!! no need to use "QApplication::fontMetrics()" int nWidth (fm.width(s)); if (nWidth + 10 < m_pLogG->horizontalHeader()->sectionSize(0)) // ttt2 "10" is hard-coded { //return QVariant(); return ""; // !!! with "return QVariant()" the previous tooltip remains until the cursor moves over another cell that has a tooltip }//*/ return s; } if (nRole != Qt::DisplayRole) { return QVariant(); } return convStr(m_pCommonData->getLog()[index.row()]); } /*override*/ QVariant LogModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("LogModel::headerData"); #if 0 if (nRole == Qt::SizeHintRole) { /*QVariant v (QAbstractTableModel::headerData(nSection, eOrientation, nRole)); // !!! doesn't work because QAbstractTableModel::headerData always returns an invalid value [...] */ if (eOrientation == Qt::Vertical) { /*QFontMetrics fm (m_pLogG->fontMetrics()); // ttt2 duplicate of FilesModel; move double d (1.01 + log10(double(m_pCommonData->getLog().size()))); int n (d); QString s (n, QChar('9')); //QSize size (fm.boundingRect(r, Qt::AlignTop | Qt::TextWordWrap, s).size()); int nWidth (fm.width(s)); return QSize(nWidth + 10, CELL_HEIGHT); //ttt2 replace CELL_HEIGHT; ttt2 "10" hard-coded*/ getNumVertHdrSize ... } return QVariant(); } #endif if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { switch (nSection) { case 0: return "Message"; default: CB_ASSERT (false); } } //return ""; return nSection + 1; } /* void LogModel::selectTopLeft() { QItemSelectionModel* pSelModel (m_pLogG->selectionModel()); pSelModel->clear(); emit layoutChanged(); if (!m_pCommonData->getLog().empty()) { m_pLogG->setCurrentIndex(index(0, 0)); } } */ ��������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Id3Transf.cpp���������������������������������������������������������������0000644�0001750�0000144�00000110160�11304154177�015556� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "fstream_unicode.h" #include <QTextCodec> #include "Id3Transf.h" #include "Id3V230Stream.h" #include "Id3V240Stream.h" #include "CommonData.h" #include "Mp3Manip.h" #include "Helpers.h" #include "MpegStream.h" #include "OsFile.h" //#include <iostream> using namespace std; //ttt2 remove id3v1; copy id3v2 to id3v1; copy id3v1 to id3v2; // ttt2 another option: before a group of transforms is executed on a group of files, a function is called on transforms to allow them to ask config info. most won't use this ... bool Id3V2Cleaner::processId3V2Stream(Id3V2StreamBase& strm, ofstream_utf8& out) { Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), 0, strm.getFileName()); //ttt2 unify code with Id3V2Rescuer vector<const Id3V2Frame*> v (strm.getKnownFrames()); for (int i = 0; i < cSize(v); ++i) { const Id3V2Frame* pFrm (v[i]); if ('T' == pFrm->m_szName[0]) { // text frame try { string s (pFrm->getRawUtf8String()); if (!s.empty()) { wrt.addTextFrame(pFrm->m_szName, s); } } catch (const Id3V2Frame::UnsupportedId3V2Frame&) { // add unchanged wrt.addNonOwnedFrame(pFrm); } } else if (0 == strcmp(KnownFrames::LBL_IMAGE(), pFrm->m_szName)) { CB_ASSERT (Id3V2Frame::NO_APIC != pFrm->m_eApicStatus); if (Id3V2Frame::COVER == pFrm->m_eApicStatus || Id3V2Frame::NON_COVER == pFrm->m_eApicStatus) // not sure about link; OTOH going to the tab editor will get rid of links, so we do it here as well { wrt.addNonOwnedFrame(pFrm); } } else if (pFrm->m_nMemDataSize > 0) { wrt.addNonOwnedFrame(pFrm); } } TagTimestamp time (strm.getTime()); wrt.setRecTime(time); // !!! needed to make sure the 2.3.0 format is used wrt.write(out); return !wrt.contentEqualTo(&strm); } /*override*/ Transformation::Result Id3V2Cleaner::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { ValueRestorer<string> rst (strTempName); const vector<DataStream*>& vpStreams (h.getStreams()); bool bFoundMatch (false); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { if (0 != dynamic_cast<Id3V2StreamBase*>(vpStreams[i])) { bFoundMatch = true; break; } } if (!bFoundMatch) { return NOT_CHANGED; } ifstream_utf8 in (h.getName().c_str(), ios::binary); bool bChanged (false); { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); Id3V2StreamBase* pId3V2 (dynamic_cast<Id3V2StreamBase*>(p)); if (0 != pId3V2) { bool b (processId3V2Stream(*pId3V2, out)); bChanged = bChanged || b; } else { p->copy(in, out); } } } if (bChanged) { rst.setOk(true); return CHANGED_NO_RECALL; } deleteFile(strTempName); return NOT_CHANGED; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== // APIC: if it can be loaded or is unsupported - keep; on error - dump // remove empty frames // rewrite text frames to discard null terminators bool Id3V2Rescuer::processId3V2Stream(Id3V2StreamBase& strm, ofstream_utf8* pOut) // nothing gets written if pOut is 0 { Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), 0, strm.getFileName()); const vector<Id3V2Frame*>& vpFrames (strm.getFrames()); for (int i = 0, n = cSize(vpFrames); i < n; ++i) { const Id3V2Frame* pFrm (vpFrames[i]); if ('T' == pFrm->m_szName[0]) { // text frame try { string s (pFrm->getRawUtf8String()); if (!s.empty()) { wrt.addTextFrame(pFrm->m_szName, s); } } catch (const Id3V2Frame::UnsupportedId3V2Frame&) { // add unchanged wrt.addNonOwnedFrame(pFrm); } } else if (0 == strcmp(KnownFrames::LBL_IMAGE(), pFrm->m_szName)) { CB_ASSERT (Id3V2Frame::NO_APIC != pFrm->m_eApicStatus); if (Id3V2Frame::COVER == pFrm->m_eApicStatus || Id3V2Frame::NON_COVER == pFrm->m_eApicStatus) // not sure about link; OTOH going to the tab editor will get rid of links, so we do it here as well { wrt.addNonOwnedFrame(pFrm); } } else if (pFrm->m_nMemDataSize > 0) { wrt.addNonOwnedFrame(pFrm); } } TagTimestamp time (strm.getTime()); wrt.setRecTime(time); if (0 != pOut) { wrt.write(*pOut); } return !wrt.contentEqualTo(&strm); } //ttt2 consider empty frames; or identifying valid id3v2 frames instead of stopping at first error, also looking in next unknown streams; /*override*/ Transformation::Result Id3V2Rescuer::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { ValueRestorer<string> rst (strTempName); const vector<DataStream*>& vpStreams (h.getStreams()); bool bFoundMatch (false); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { if (0 != dynamic_cast<Id3V2StreamBase*>(vpStreams[i]) || 0 != dynamic_cast<BrokenDataStream*>(vpStreams[i])) { bFoundMatch = true; break; } } if (!bFoundMatch) { return NOT_CHANGED; } ifstream_utf8 in (h.getName().c_str(), ios::binary); { for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); Id3V2StreamBase* pId3V2 (dynamic_cast<Id3V2StreamBase*>(p)); BrokenDataStream* pBrk (dynamic_cast<BrokenDataStream*>(p)); if (0 != pId3V2) { if (processId3V2Stream(*pId3V2, 0)) { goto e1; } } else if (0 != pBrk && (pBrk->getBaseName() == Id3V230Stream::getClassDisplayName() || pBrk->getBaseName() == Id3V240Stream::getClassDisplayName())) { goto e1; } } return NOT_CHANGED; } e1: bool bChanged (false); bool bRecall (false); { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); Id3V2StreamBase* pId3V2 (dynamic_cast<Id3V2StreamBase*>(p)); BrokenDataStream* pBrk (dynamic_cast<BrokenDataStream*>(p)); if (0 != pId3V2) { bool b (processId3V2Stream(*pId3V2, &out)); bChanged = bChanged || b; } else if (0 != pBrk && pBrk->getBaseName() == Id3V230Stream::getClassDisplayName()) { in.seekg(pBrk->getPos()); NoteColl notes (20); StringWrp fileName (h.getName()); Id3V230Stream strm (0, notes, in, &fileName, Id3V230Stream::ACCEPT_BROKEN); Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), &strm, h.getName()); wrt.write(out); bChanged = true; bRecall = true; // !!! now we read whatever frames are available from a broken stream, next time we check for empty or otherwise invalid frames } else if (0 != pBrk && pBrk->getBaseName() == Id3V240Stream::getClassDisplayName()) { in.seekg(pBrk->getPos()); NoteColl notes (20); StringWrp fileName (h.getName()); Id3V240Stream strm (0, notes, in, &fileName, Id3V240Stream::ACCEPT_BROKEN); Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), &strm, h.getName()); //ttt2 if useFastSave is true there should probably be an automatic reload; OTOH we may want to delay until more transforms are applied, so probably it's OK as is wrt.write(out); bChanged = true; bRecall = true; } else { p->copy(in, out); } } } if (bChanged) { rst.setOk(true); return bRecall ? CHANGED : CHANGED_NO_RECALL; } deleteFile(strTempName); return NOT_CHANGED; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== /*override*/ const char* Id3V2UnicodeTransformer::getVisibleActionName() const { string strActionName (string("Convert non-ASCII ID3V2 text frames to Unicode assuming codepage ") + m_pCommonData->m_pCodec->name().constData()); if (strActionName != m_strActionName) { m_strActionName = strActionName; // to make sure that pointer comparisons still work (though they should probably be replaced by string comparisons) //ttt2 replace ptr comparisons } return m_strActionName.c_str(); } void Id3V2UnicodeTransformer::processId3V2Stream(Id3V2StreamBase& strm, ofstream_utf8& out) { Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), 0, strm.getFileName()); const vector<Id3V2Frame*>& vpFrames (strm.getFrames()); for (int i = 0, n = cSize(vpFrames); i < n; ++i) { const Id3V2Frame* pFrm (vpFrames[i]); //Id3V2FrameDataLoader wrp (*pFrm); if ('T' == pFrm->m_szName[0] && pFrm->m_bHasLatin1NonAscii) { Id3V2FrameDataLoader wrp (*pFrm); const char* pData (wrp.getData()); CB_ASSERT (0 == pData[0]); // "Latin1" encoding QByteArray arr (pData + 1, pFrm->m_nMemDataSize - 1); QString qstrTxt (m_pCommonData->m_pCodec->toUnicode(arr)); wrt.addTextFrame(pFrm->m_szName, convStr(qstrTxt)); } else { wrt.addNonOwnedFrame(pFrm); //ttt2 removes duplicates of POPM/ratings; OTOH it removes duplicates of artist or tite; well, those were supposed to not have duplicates } } TagTimestamp time (strm.getTime()); wrt.setRecTime(time); wrt.write(out); } /*override*/ Transformation::Result Id3V2UnicodeTransformer::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { const vector<DataStream*>& vpStreams (h.getStreams()); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { Id3V2StreamBase* pId3V2 (dynamic_cast<Id3V2StreamBase*>(vpStreams[i])); if (0 != pId3V2) { const vector<Id3V2Frame*>& vpFrames (pId3V2->getFrames()); for (int i = 0, n = cSize(vpFrames); i < n; ++i) { const Id3V2Frame* pFrm (vpFrames[i]); if (pFrm->m_bHasLatin1NonAscii) { goto e1; } } } } return NOT_CHANGED; e1: ifstream_utf8 in (h.getName().c_str(), ios::binary); { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); Id3V2StreamBase* pId3V2 (dynamic_cast<Id3V2StreamBase*>(p)); if (0 != pId3V2) { processId3V2Stream(*pId3V2, out); } else { p->copy(in, out); } } } return CHANGED_NO_RECALL; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== /* struct PLPAS { PLPAS() { for (int i = 32; i < 512; ++i) { QChar c (i); QString q; q += c; cout << i << " " << q.toUtf8().constData() << " " << (int)c.category() << endl; } } }; PLPAS llpwwe; */ /*override*/ const char* Id3V2CaseTransformer::getVisibleActionName() const { string strActionName (string("Change case for ID3V2 text frames: Artists - ") + getCaseAsStr(m_pCommonData->m_eCaseForArtists) + "; Others - " + getCaseAsStr(m_pCommonData->m_eCaseForOthers)); if (strActionName != m_strActionName) { m_strActionName = strActionName; // to make sure that pointer comparisons still work (though they should probably be replaced by string comparisons) //ttt2 replace ptr comparisons } return m_strActionName.c_str(); } bool Id3V2CaseTransformer::processId3V2Stream(Id3V2StreamBase& strm, ofstream_utf8& out) { Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), &strm, strm.getFileName()); { const Id3V2Frame* pFrm (strm.getFrame(KnownFrames::LBL_ARTIST())); if (0 != pFrm) { QString s (convStr(pFrm->getUtf8String())); wrt.addTextFrame(KnownFrames::LBL_ARTIST(), convStr(getCaseConv(s, m_pCommonData->m_eCaseForArtists))); } } { const Id3V2Frame* pFrm (strm.getFrame(KnownFrames::LBL_ALBUM())); if (0 != pFrm) { QString s (convStr(pFrm->getUtf8String())); wrt.addTextFrame(KnownFrames::LBL_ALBUM(), convStr(getCaseConv(s, m_pCommonData->m_eCaseForOthers))); } } { const Id3V2Frame* pFrm (strm.getFrame(KnownFrames::LBL_COMPOSER())); if (0 != pFrm) { QString s (convStr(pFrm->getUtf8String())); wrt.addTextFrame(KnownFrames::LBL_COMPOSER(), convStr(getCaseConv(s, m_pCommonData->m_eCaseForArtists))); } } { const Id3V2Frame* pFrm (strm.getFrame(KnownFrames::LBL_TITLE())); if (0 != pFrm) { QString s (convStr(pFrm->getUtf8String())); wrt.addTextFrame(KnownFrames::LBL_TITLE(), convStr(getCaseConv(s, m_pCommonData->m_eCaseForOthers))); } } { const Id3V2Frame* pFrm (strm.getFrame(KnownFrames::LBL_GENRE())); if (0 != pFrm) { QString s (convStr(pFrm->getUtf8String())); wrt.addTextFrame(KnownFrames::LBL_GENRE(), convStr(getCaseConv(s, m_pCommonData->m_eCaseForOthers))); } } wrt.write(out); return !wrt.contentEqualTo(&strm); } /*override*/ Transformation::Result Id3V2CaseTransformer::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { //ttt2 identical / similar code to the other Id3V2 Transformers ValueRestorer<string> rst (strTempName); const vector<DataStream*>& vpStreams (h.getStreams()); bool bFoundMatch (false); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { if (0 != dynamic_cast<Id3V2StreamBase*>(vpStreams[i])) { bFoundMatch = true; break; } } if (!bFoundMatch) { return NOT_CHANGED; } ifstream_utf8 in (h.getName().c_str(), ios::binary); bool bChanged (false); { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); Id3V2StreamBase* pId3V2 (dynamic_cast<Id3V2StreamBase*>(p)); if (0 != pId3V2) { bool b (processId3V2Stream(*pId3V2, out)); bChanged = bChanged || b; } else { p->copy(in, out); } } } if (bChanged) { rst.setOk(true); return CHANGED_NO_RECALL; } deleteFile(strTempName); return NOT_CHANGED; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== bool Id3V1ToId3V2Copier::processId3V2Stream(Id3V2StreamBase& strm, ofstream_utf8& out, Id3V1Stream* pId3V1Stream) { Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), &strm, strm.getFileName()); if (strm.getTitle().empty()) { string s (pId3V1Stream->getTitle()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_TITLE(), s); } } if (strm.getArtist().empty()) { string s (pId3V1Stream->getArtist()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_ARTIST(), s); } } if (strm.getTrackNumber().empty()) { string s (pId3V1Stream->getTrackNumber()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_TRACK_NUMBER(), s); } } if (0 == strm.getTime().asString()[0]) { string s (pId3V1Stream->getTime().getYear()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_TIME_YEAR_230(), s); } } if (strm.getGenre().empty()) { string s (pId3V1Stream->getGenre()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_GENRE(), s); } } if (strm.getAlbumName().empty()) { string s (pId3V1Stream->getAlbumName()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_ALBUM(), s); } } wrt.write(out); return !wrt.contentEqualTo(&strm); } /*override*/ Transformation::Result Id3V1ToId3V2Copier::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { ValueRestorer<string> rst (strTempName); const vector<DataStream*>& vpStreams (h.getStreams()); bool bId3V2Found (false); Id3V1Stream* pId3V1Stream (0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { if (0 != dynamic_cast<Id3V2StreamBase*>(vpStreams[i])) { bId3V2Found = true; } else if (0 != dynamic_cast<Id3V1Stream*>(vpStreams[i])) { pId3V1Stream = dynamic_cast<Id3V1Stream*>(vpStreams[i]); } } if (0 == pId3V1Stream) { return NOT_CHANGED; } if (!bId3V2Found) { Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), 0, h.getName()); { string s (pId3V1Stream->getTitle()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_TITLE(), s); } } { string s (pId3V1Stream->getArtist()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_ARTIST(), s); } } { string s (pId3V1Stream->getTrackNumber()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_TRACK_NUMBER(), s); } } { string s (pId3V1Stream->getTime().getYear()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_TIME_YEAR_230(), s); } } { string s (pId3V1Stream->getGenre()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_GENRE(), s); } } { string s (pId3V1Stream->getAlbumName()); if (!s.empty()) { wrt.addTextFrame(KnownFrames::LBL_ALBUM(), s); } } if (wrt.isEmpty()) { return NOT_CHANGED; } ifstream_utf8 in (h.getName().c_str(), ios::binary); transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); wrt.write(out); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); p->copy(in, out); } rst.setOk(true); return CHANGED_NO_RECALL; } ifstream_utf8 in (h.getName().c_str(), ios::binary); bool bChanged (false); { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); // ttt2 doesn't seem needed; search for similar cases and perhaps remove them all for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); Id3V2StreamBase* pId3V2 (dynamic_cast<Id3V2StreamBase*>(p)); if (0 != pId3V2) { bool b (processId3V2Stream(*pId3V2, out, pId3V1Stream)); bChanged = bChanged || b; } else { p->copy(in, out); } } } if (bChanged) { rst.setOk(true); return CHANGED_NO_RECALL; } deleteFile(strTempName); return NOT_CHANGED; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== /*override*/ Transformation::Result Id3V2ComposerAdder::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { const vector<DataStream*>& vpStreams (h.getStreams()); Id3V2StreamBase* pId3V2 (0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); pId3V2 = dynamic_cast<Id3V2StreamBase*>(p); if (0 != pId3V2) { break; } } if (0 == pId3V2) { return NOT_CHANGED; } string strComp (pId3V2->getComposer()); if (strComp.empty()) { return NOT_CHANGED; } string strArtist (pId3V2->getArtist()); if (beginsWith(strArtist, strComp + " [") && endsWith(strArtist, "]")) { return NOT_CHANGED; } { // temp Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), pId3V2, h.getName()); wrt.addTextFrame(KnownFrames::LBL_ARTIST(), strComp + " [" + strArtist + "]"); ifstream_utf8 in (h.getName().c_str(), ios::binary); transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); wrt.write(out); // may throw, but it will be caught for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (p != pId3V2) { p->copy(in, out); } } } return CHANGED_NO_RECALL; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== /*override*/ Transformation::Result Id3V2ComposerRemover::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { const vector<DataStream*>& vpStreams (h.getStreams()); Id3V2StreamBase* pId3V2 (0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); pId3V2 = dynamic_cast<Id3V2StreamBase*>(p); if (0 != pId3V2) { break; } } if (0 == pId3V2) { return NOT_CHANGED; } string strComp (pId3V2->getComposer()); if (strComp.empty()) { return NOT_CHANGED; } string strArtist (pId3V2->getArtist()); if (!(beginsWith(strArtist, strComp + " [") && endsWith(strArtist, "]"))) { return NOT_CHANGED; } { // temp Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), pId3V2, h.getName()); //wrt.addTextFrame(KnownFrames::LBL_ARTIST(), strComp + " [" + strArtist + "]"); wrt.addTextFrame(KnownFrames::LBL_ARTIST(), strArtist.substr(strComp.size() + 2, strArtist.size() - strComp.size() - 3)); ifstream_utf8 in (h.getName().c_str(), ios::binary); transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); wrt.write(out); // may throw, but it will be caught for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (p != pId3V2) { p->copy(in, out); } } } return CHANGED_NO_RECALL; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== /*override*/ Transformation::Result Id3V2ComposerCopier::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { const vector<DataStream*>& vpStreams (h.getStreams()); Id3V2StreamBase* pId3V2 (0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); pId3V2 = dynamic_cast<Id3V2StreamBase*>(p); if (0 != pId3V2) { break; } } if (0 == pId3V2) { return NOT_CHANGED; } string strArtist (pId3V2->getArtist()); if (beginsWith(strArtist, "[") || !endsWith(strArtist, "]")) { return NOT_CHANGED; } string::size_type n (strArtist.find(" [")); if (string::npos == n) { return NOT_CHANGED; } string strComp (strArtist.substr(0, n)); string strExistingComp (pId3V2->getComposer()); if (strComp == strExistingComp) { return NOT_CHANGED; } { // temp Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), pId3V2, h.getName()); wrt.addTextFrame(KnownFrames::LBL_COMPOSER(), strComp); ifstream_utf8 in (h.getName().c_str(), ios::binary); transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); wrt.write(out); // may throw, but it will be caught for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (p != pId3V2) { p->copy(in, out); } } } return CHANGED_NO_RECALL; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== /*override*/ Transformation::Result SmallerImageRemover::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) //ttt1 recompress large images { LAST_STEP("SmallerImageRemover::apply() " + h.getName()); const vector<DataStream*>& vpStreams (h.getStreams()); Id3V2StreamBase* pId3V2 (0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); pId3V2 = dynamic_cast<Id3V2StreamBase*>(p); if (0 != pId3V2) { break; } } if (0 == pId3V2) { return NOT_CHANGED; } const vector<Id3V2Frame*>& vpFrames (pId3V2->getFrames()); const Id3V2Frame* pLargestPic (0); int nPicCnt (0); for (int i = 0; i < cSize(vpFrames); ++i) { const Id3V2Frame* p (vpFrames[i]); //if (0 == strcmp(p->m_szName, KnownFrames::LBL_IMAGE())) if (Id3V2Frame::COVER == p->m_eApicStatus || Id3V2Frame::NON_COVER == p->m_eApicStatus) { ++nPicCnt; if (0 == pLargestPic || pLargestPic->m_nImgSize < p->m_nImgSize) { pLargestPic = p; } } } if (0 == nPicCnt || (1 == nPicCnt && Id3V2Frame::PT_COVER == pLargestPic->m_nPictureType)) { return NOT_CHANGED; } { // temp Id3V230StreamWriter wrt (Id3V230StreamWriter::KEEP_ONE_VALID_IMG, m_pCommonData->useFastSave(), pId3V2, h.getName()); wrt.removeFrames(KnownFrames::LBL_IMAGE()); Id3V2FrameDataLoader ldr (*pLargestPic); vector<char> v; copy (ldr.getData(), ldr.getData() + pLargestPic->m_nMemDataSize, back_inserter(v)); //wrt.addBinaryFrame(KnownFrames::LBL_IMAGE(), v); wrt.addImg(v); ifstream_utf8 in (h.getName().c_str(), ios::binary); transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); wrt.write(out); // may throw, but it will be caught for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (p != pId3V2) { p->copy(in, out); } } } return CHANGED_NO_RECALL; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== /*static*/ const int Id3V2Expander::EXTRA_SPACE (4096); // frames other than APIC; title, artist, lyrics, ... /*override*/ Transformation::Result Id3V2Expander::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { const vector<DataStream*>& vpStreams (h.getStreams()); Id3V2StreamBase* pId3V2 (0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); pId3V2 = dynamic_cast<Id3V2StreamBase*>(p); if (0 != pId3V2) { break; } } //if (0 == pId3V2) { return NOT_CHANGED; } //(int(pId3V2->getSize()) int nOldPaddingSize (0), nOldSize (0); if (0 != pId3V2) { nOldPaddingSize = pId3V2->getPaddingSize(); nOldSize = int(pId3V2->getSize()); } int nExtraSize (ImageInfo::MAX_IMAGE_SIZE + EXTRA_SPACE); // it is possible for existing pictures with non-cover types to be kept, so we want additional space even if there is already a (big) image // !!! cannot just remove the size of whatever APIC is currently used, because it may be of a non-cover type if (nExtraSize <= nOldPaddingSize) { return NOT_CHANGED; } { // temp Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), pId3V2, h.getName()); ifstream_utf8 in (h.getName().c_str(), ios::binary); transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); wrt.write(out, nOldSize + nExtraSize - nOldPaddingSize); // may throw, but it will be caught for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (p != pId3V2) { p->copy(in, out); } } } return CHANGED_NO_RECALL; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== /*override*/ Transformation::Result Id3V2Compactor::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { const vector<DataStream*>& vpStreams (h.getStreams()); Id3V2StreamBase* pId3V2 (0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); pId3V2 = dynamic_cast<Id3V2StreamBase*>(p); if (0 != pId3V2) { break; } } if (0 == pId3V2) { return NOT_CHANGED; } if (pId3V2->getPaddingSize() < Id3V230StreamWriter::DEFAULT_EXTRA_SPACE + 512) { return NOT_CHANGED; } { // temp Id3V230StreamWriter wrt (m_pCommonData->m_bKeepOneValidImg, m_pCommonData->useFastSave(), pId3V2, h.getName()); ifstream_utf8 in (h.getName().c_str(), ios::binary); transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); wrt.write(out, 0); // may throw, but it will be caught for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (p != pId3V2) { p->copy(in, out); } } } return CHANGED_NO_RECALL; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== //ttt2 perhaps be able to extract composer even when the field is empty, if artist is "composer [artist]", but doesn't look too useful //ttt2 warn in config if user enables fast save and then hides Id3V2Compactor ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Mp3Manip.h������������������������������������������������������������������0000644�0001750�0000144�00000022047�11265061421�015053� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef Mp3HandlerH #define Mp3HandlerH #include "fstream_unicode.h" #include <vector> #include "SerSupport.h" #include <boost/serialization/split_free.hpp> #include "Notes.h" #include "ThreadRunnerDlgImpl.h" class Id3V2StreamBase; class Id3V230Stream; class Id3V240Stream; class Id3V1Stream; class LameStream; class XingStreamBase; class VbriStream; class MpegStream; class ApeStream; class LyricsStream; class NullDataStream; class UnknownDataStream; class BrokenDataStream; class UnsupportedDataStream; class TruncatedMpegDataStream; class DataStream; PausableThread* getSerThread(); //ttt2 global function struct QualThresholds { int m_nStereoCbr; // below this bitrate for stereo CBR a warning is generated; value is in bps int m_nJointStereoCbr; // below this bitrate for joint stereo CBR a warning is generated int m_nDoubleChannelCbr; // below this bitrate for dual channel CBR a warning is generated; half of this value is used for mono streams int m_nStereoVbr; // below this bitrate for stereo VBR a warning is generated int m_nJointStereoVbr; // below this bitrate for joint stereo VBR a warning is generated int m_nDoubleChannelVbr; // below this bitrate for dual channel VBR a warning is generated; half of this value is used for mono streams // ttt2 add Lame header info analysis, which might give a better idea about quality than simple bitrate }; // the details for an MP3 file class Mp3Handler { StringWrp* m_pFileName; // couldn't get Boost ser to allow an object, rather than a pointer; tried BOOST_CLASS_TRACKING; the reason seems to be that when using an object, it is also saved by the frames, as a pointer; so they all should be pointers; Id3V230Stream* m_pId3V230Stream; Id3V240Stream* m_pId3V240Stream; Id3V1Stream* m_pId3V1Stream; LameStream* m_pLameStream; XingStreamBase* m_pXingStream; VbriStream* m_pVbriStream; MpegStream* m_pMpegStream; ApeStream* m_pApeStream; LyricsStream* m_pLyricsStream; std::vector<NullDataStream*> m_vpNullStreams; std::vector<UnknownDataStream*> m_vpUnknownStreams; std::vector<BrokenDataStream*> m_vpBrokenStreams; std::vector<UnsupportedDataStream*> m_vpUnsupportedStreams; std::vector<TruncatedMpegDataStream*> m_vpTruncatedMpegStreams; std::vector<DataStream*> m_vpAllStreams; ifstream_utf8* m_pIn; // this isn't used after the constructor completes; however, many streams have a StreamStateRestorer member, which does this on its destructor: it restores the stream position if the stream's constructor fails and clears the errors otherwise, assuming that the stream pointer is non-0; m_pIn is set to 0 after Mp3Handler's constructor completes, so the restorers of the successfuly built streams don't do anything when the streams get destroyed, because they see a null pointer; //bool m_bHasId3V2; //MpegFrame m_firstFrame; //const char* szFileName; //bool m_bVbr; //int m_nBitrate; std::streampos m_posEnd; long long m_nSize, m_nTime; NoteColl m_notes; // owned pointers void parse(ifstream_utf8&); void analyze(const QualThresholds& qualThresholds); // checks the streams for issues (missing ID3V2, Unknown streams, inconsistencies, ...) //void checkMpegAudio(); //void checkEqualFrames(std::streampos pos); //void findFirstFrame(std::streampos& pos); void checkLastFrameInMpegStream(ifstream_utf8& in); // what looks like the last frame in an MPEG stream may actually be truncated and somewhere inside it an ID3V1 or Ape tag may actually begin; if that's the case, that "frame" is removed from the stream; then most likely an "Unknown" stream will be detected, followed by an ID3V1 or Ape stream void reloadId3V2Hlp(); public: Mp3Handler(const std::string& strFileName, bool bStoreTraceNotes, const QualThresholds& qualThresholds); ~Mp3Handler(); //void copyMpeg(std::istream& in, std::ostream& out); //void logStreamInfo() const; //void logStreamInfo(std::ostream& out) const; const NoteColl& getNotes() const { return m_notes; } const std::vector<DataStream*>& getStreams() const { return m_vpAllStreams; } const std::string& getName() const { return m_pFileName->s; } QString getUiName() const; // uses native separators long long getSize() const; std::string getShortName() const; std::string getDir() const; const Id3V2StreamBase* getId3V2Stream() const; // if the underlying file seems changed (or removed); looks at time and size, as well as FastSaveWarn and Notes::getMissingNote(); a difference in size always makes this return true; if bUseFastSave is true, both m_nFastSaveTime and m_nTime are tested, while m_notes.hasFastSaveWarn() and Notes::getMissingNote() are ignored; if it is false, m_nFastSaveTime is ignored, while m_nTime, m_notes.hasFastSaveWarn(), and Notes::getMissingNote() are tested bool needsReload(bool bUseFastSave) const; void sortNotes() { m_notes.sort(); } // this is needed when loading from the disk, if unknown (most likely obsolete) notes are found // removes the ID3V2 tag and the notes associated with it and scans the file again, but only the new ID3V2 tag; // asserts that there was an existing ID3V2 tag at the beginning and it had the same size as the new one; // this isn't really const, but it seems better to have a const_cast in the only place where it is needed rather than remove the const restriction from many places void reloadId3V2() const; mutable long long m_nFastSaveTime; enum { DONT_USE_FAST_SAVE, USE_FAST_SAVE }; struct FileNotFound {}; private: friend class boost::serialization::access; Mp3Handler() {} // serialization-only constructor template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & m_pFileName; ar & m_pId3V230Stream; ar & m_pId3V240Stream; ar & m_pId3V1Stream; ar & m_pLameStream; ar & m_pXingStream; ar & m_pVbriStream; ar & m_pMpegStream; ar & m_pApeStream; ar & m_pLyricsStream; ar & m_vpNullStreams; ar & m_vpUnknownStreams; ar & m_vpBrokenStreams; ar & m_vpUnsupportedStreams; ar & m_vpTruncatedMpegStreams; ar & m_vpAllStreams; ar & m_posEnd; ar & m_nSize; ar & m_nTime; ar & m_notes; PausableThread* pThread (getSerThread()); if (0 != pThread) { StrList l; l.push_back(QString::fromUtf8(m_pFileName->s.c_str())); pThread->emitStepChanged(l); } } }; struct CmpMp3HandlerPtrByName { /*bool operator()(const std::string& strName1, const std::string& strName2) const { return cmp(strName1, strName2); } bool operator()(const std::string& strName1, const Mp3Handler* p2) const { return cmp(strName1, p2->getName()); }*/ bool operator()(const Mp3Handler* p1, const std::string& strName2) const; bool operator()(const std::string& strName1, const Mp3Handler* p2) const; bool operator()(const Mp3Handler* p1, const Mp3Handler* p2) const; private: bool cmp(const std::string& strName1, const std::string& strName2) const; }; // finds the position where the next ID3V2, MPEG, Xing, Lame or Ape frame begins; "pos" is not considered; the search starts at pos+1; throws if no frame is found std::streampos getNextStream(std::istream& in, std::streampos pos); #endif // #ifndef Mp3HandlerH �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Mp3TransformThread.cpp������������������������������������������������������0000644�0001750�0000144�00000053762�11340212377�017457� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <memory> #include <QMessageBox> #include "Mp3TransformThread.h" #include "ThreadRunnerDlgImpl.h" #include "Helpers.h" #include "CommonData.h" #include "Transformation.h" #include "OsFile.h" using namespace std; //using namespace pearl; void logTransformation(const string& strLogFile, const char* szActionName, const string& strMp3File) { time_t t (time(0)); ofstream_utf8 out (strLogFile.c_str(), ios_base::app); out << "<" << strMp3File << "> <" << szActionName << "> - " << ctime(&t); // !!! ctime and a \n } //ttt2 perhaps make "fast-save aware" other transf that operate on id3v3 only (case transf, codepage, discards, ...); OTOH how likely is it to run 2 of these one ofer another? (otherwise you'd have to rescan anyway). still, perhaps allow proceeding in most cases without rescanning ID3V2 would be better, perhaps optional; then everything would be faster with ID3V2 namespace { struct Mp3TransformThread : public PausableThread { CommonData* m_pCommonData; const TransfConfig& m_transfConfig; //bool m_bAll; // if to use all handlers or only the selected ones const deque<const Mp3Handler*>& m_vpHndlr; vector<const Mp3Handler*>& m_vpDel; vector<const Mp3Handler*>& m_vpAdd; // for proc files that are in the same directory as the source and have a different name vector<Transformation*>& m_vpTransf; Mp3TransformThread( CommonData* pCommonData, const TransfConfig& transfConfig, const deque<const Mp3Handler*>& vpHndlr, vector<const Mp3Handler*>& vpDel, vector<const Mp3Handler*>& vpAdd, vector<Transformation*>& vpTransf) : m_pCommonData(pCommonData), m_transfConfig(transfConfig), m_vpHndlr(vpHndlr), m_vpDel(vpDel), m_vpAdd(vpAdd), m_vpTransf(vpTransf), m_bWriteError(true), m_bFileChanged(false) { } string m_strErrorFile; // normally this is empty; if it's not, writing to the specified file failed string m_strErrorDir; // normally this is empty; if it's not, creating the specified backup file failed bool m_bWriteError; bool m_bFileChanged; /*override*/ void run() { try { CompleteNotif notif(this); notif.setSuccess(transform()); } catch (...) { LAST_STEP("Mp3TransformThread::run()"); CB_ASSERT (false); } } bool transform(); }; // the idea is to mark a file for deletion but only rename it, so other things can be done as if the file got erased, but if something goes wrong the file can be restored; // the default behavior on the destructor is to restore the file, if the name isn't already used; to prevent the file from being restored, finalize() should be called after the things that could go wrong complete OK class FileEraser { string m_strOrigName; string m_strChangedName; public: void erase(const string& strOrigName) { CB_ASSERT(m_strOrigName.empty()); m_strOrigName = strOrigName; char a [20]; for (int i = 1; i < 1000; ++i) { sprintf(a, ".QQREN%03dREN", i); m_strChangedName = strOrigName + a; if (!fileExists(m_strChangedName)) { a[0] = 0; break; } } CB_ASSERT (0 == a[0]); // not really correct to assert, but quite likely try { renameFile(strOrigName, m_strChangedName); } catch (const CannotDeleteFile&) { revert(); throw; } catch (const CannotRenameFile&) { revert(); throw CannotDeleteFile(); } } ~FileEraser() { if (m_strOrigName.empty() || m_strChangedName.empty()) { return; } try { renameFile(m_strChangedName, m_strOrigName); } catch (...) { //ttt2 perhaps do something } } void finalize() { if (m_strChangedName.empty()) { return; } deleteFile(m_strChangedName); m_strOrigName.clear(); m_strChangedName.clear(); } private: void revert() // to be called on exceptions; assumes that the old file got copied but couldn't be deleted, so now the copy must be deleted { CB_ASSERT (!m_strChangedName.empty()); try { deleteFile(m_strChangedName); } catch (const CannotDeleteFile&) { // nothing } m_strChangedName.clear(); } }; // on destructor erases the file given on constructor, unless release() was called; doesn't throw class TempFileEraser { string m_strName; public: TempFileEraser(const string& strName) : m_strName(strName) { } ~TempFileEraser() { if (m_strName.empty()) { return; } try { deleteFile(m_strName); } catch (...) { //ttt2 perhaps do something } } void release() { m_strName.clear(); } }; void logTransformation(const string& strLogFile, const char* szActionName, const Mp3Handler* pHandler) { ::logTransformation(strLogFile, szActionName, pHandler->getName()); } bool Mp3TransformThread::transform() { bool bAborted (false); bool bUseFastSave (m_pCommonData->useFastSave()); for (int j = 0, m = cSize(m_vpTransf); j < m; ++j) { if (!m_vpTransf[j]->acceptsFastSave()) { bUseFastSave = false; break; } } try { for (int i = 0, n = cSize(m_vpHndlr); i < n; ++i) { if (isAborted()) { return false; } checkPause(); const Mp3Handler* pOrigHndl (m_vpHndlr[i]); string strOrigName (pOrigHndl->getName()); if (pOrigHndl->needsReload(bUseFastSave)) { m_strErrorFile = strOrigName; m_bWriteError = false; m_bFileChanged = true; return false; } string strTempName; string strPrevTempName; StrList l; l.push_back(toNativeSeparators(convStr(strOrigName))); l.push_back(""); //emit stepChanged(l); auto_ptr<const Mp3Handler> pNewHndl (pOrigHndl); try { long long nSize, nOrigTime; getFileInfo(strOrigName, nOrigTime, nSize); for (int j = 0, m = cSize(m_vpTransf); j < m; ++j) { Transformation& t (*m_vpTransf[j]); TRACER("Mp3TransformThread::transform()" + strOrigName + "/" + t.getActionName()); l[1] = t.getActionName(); emit stepChanged(l, i + 1); Transformation::Result eTransf; try { eTransf = t.apply(*pNewHndl, m_transfConfig, strOrigName, strTempName); } catch (const WriteError&) { //qDebug("disk err"); m_strErrorFile = strTempName; m_bWriteError = true; if (pNewHndl.get() == pOrigHndl) { pNewHndl.release(); } TempFileEraser er (strTempName); return false; //ttt2 review what happens to pNewHndl } catch (const EndOfFile&) //ttt2 catch other exceptions, perhaps in the outer loop { m_strErrorFile = strOrigName; m_bWriteError = false; if (pNewHndl.get() == pOrigHndl) { pNewHndl.release(); } TempFileEraser er (strTempName); return false; } if (eTransf != Transformation::NOT_CHANGED) { CB_ASSERT (!m_pCommonData->m_strTransfLog.empty()); //ttt0 triggered according to http://sourceforge.net/apps/mantisbt/mp3diags/view.php?id=45 ; however, the code is quite simple and it doesn't seem to be a valid reason for m_strTransfLog to be empty (aside from corrupted memory) if (m_pCommonData->m_bLogTransf) { logTransformation(m_pCommonData->m_strTransfLog, t.getActionName(), pNewHndl.get()); } if (pNewHndl.get() == pOrigHndl) { pNewHndl.release(); CB_ASSERT (strPrevTempName.empty()); } else { CB_ASSERT (!strPrevTempName.empty()); switch (m_transfConfig.getTempAction()) { case TransfConfig::TRANSF_DONT_CREATE: deleteFile(strPrevTempName); break; //ttt2 try ... // or perhaps a try-catch for file errors for the whole block case TransfConfig::TRANSF_CREATE: break; default: CB_ASSERT (false); } } strPrevTempName = strTempName; pNewHndl.reset(new Mp3Handler(strTempName, m_pCommonData->m_bUseAllNotes, m_pCommonData->getQualThresholds())); //ttt2 try..catch checkPause(); if (isAborted()) { bAborted = true; break; // needed because it is possible that a bug in a transformation to make it create "transformations" that are equal to the original, so the loop never exits; // not 100% right, but seems better anyway than just returning; // ttt3 fix: we should delete all the temp and comp files and return false, but for now it can stay as is; } if (Transformation::CHANGED_NO_RECALL != eTransf) { CB_ASSERT (Transformation::CHANGED == eTransf); j = -1; // !!! start again with the first transformation //ttt2 consider: 5 transforms, 1 and 2 are CHANGE_NO_RECALL, 3 is CHANGE, causing 1 and 2 to be called again; probably OK, but review } } } string strNewOrigName; // new name for the orig file; if this is empty, the original file wasn't changed; if it's "*", it was erased; if it's something else, it was renamed; string strProcName; // name for the proc file; if this is empty, a proc file doesn't exist; if it's something else, it's the file name; bool bErrorInTransform (false); FileEraser fileEraser; try { //bool bChanged (true); if (pNewHndl.get() == pOrigHndl) { // nothing changed pNewHndl.release(); switch (m_transfConfig.getUnprocOrigAction()) { case TransfConfig::ORIG_DONT_CHANGE: break; case TransfConfig::ORIG_ERASE: { strNewOrigName = "*"; fileEraser.erase(strOrigName); } break; //ttt2 try ... case TransfConfig::ORIG_MOVE: { m_transfConfig.getUnprocOrigName(strOrigName, strNewOrigName); renameFile(strOrigName, strNewOrigName); } break; default: CB_ASSERT (false); } } else { // at least a processed file exists CB_ASSERT (!strTempName.empty()); TempFileEraser tmpEraser (strTempName); // first we have to handle the original file; switch (m_transfConfig.getProcOrigAction()) { case TransfConfig::ORIG_DONT_CHANGE: break; case TransfConfig::ORIG_ERASE: { strNewOrigName = "*"; fileEraser.erase(strOrigName); } break; //ttt2 try ... case TransfConfig::ORIG_MOVE: { m_transfConfig.getProcOrigName(strOrigName, strNewOrigName); renameFile(strOrigName, strNewOrigName); } break; case TransfConfig::ORIG_MOVE_OR_ERASE: { m_transfConfig.getProcOrigName(strOrigName, strNewOrigName); if (fileExists(strNewOrigName)) { strNewOrigName = "*"; fileEraser.erase(strOrigName); } else { renameFile(strOrigName, strNewOrigName); } } break; default: CB_ASSERT (false); } // the last processed file exists (usualy in the same folder as the source), its name is in strTempName, and we have to see what to do with it (erase, rename, or copy); switch (m_transfConfig.getProcessedAction()) { case TransfConfig::TRANSF_DONT_CREATE: deleteFile(strTempName); break; case TransfConfig::TRANSF_CREATE: { m_transfConfig.getProcessedName(strOrigName, strProcName); switch (m_transfConfig.getTempAction()) { case TransfConfig::TRANSF_DONT_CREATE: renameFile(strTempName, strProcName); break; case TransfConfig::TRANSF_CREATE: copyFile(strTempName, strProcName); break; default: CB_ASSERT (false); } } break; default: CB_ASSERT (false); } tmpEraser.release(); } fileEraser.finalize(); } catch (const CannotDeleteFile&) { bErrorInTransform = true; } catch (const CannotRenameFile&) //ttt2 perhaps also NameNotFound, AlreadyExists, ... { bErrorInTransform = true; } catch (const CannotCreateDir& ex) { bErrorInTransform = true; m_strErrorDir = ex.m_strDir; } catch (const CannotCopyFile&) { CB_ASSERT(false); //bErrorInTransform = true; } if (bErrorInTransform) { if (!strProcName.empty()) { try { deleteFile(strProcName); } catch (...) { //ttt2 not sure what to do } } m_strErrorFile = strOrigName; m_bWriteError = false; return false; } //ttt2 perhaps do something similar to strNewOrigName //ttt2 review the whole thing if (!strNewOrigName.empty()) { m_vpDel.push_back(pOrigHndl); if ("*" != strNewOrigName && m_pCommonData->m_dirTreeEnum.isIncluded(strNewOrigName)) { m_vpAdd.push_back(new Mp3Handler(strNewOrigName, m_pCommonData->m_bUseAllNotes, m_pCommonData->getQualThresholds())); } } if (!strProcName.empty()) { if (m_transfConfig.m_options.m_bKeepOrigTime) { setFileDate(strProcName, nOrigTime); } if (m_pCommonData->m_dirTreeEnum.isIncluded(strProcName)) { m_vpAdd.push_back(new Mp3Handler(strProcName, m_pCommonData->m_bUseAllNotes, m_pCommonData->getQualThresholds())); // !!! a new Mp3Handler is needed, because pNewHndl has an incorrect file name (but otherwise they should be identical) } } } catch (...) { if (pNewHndl.get() == pOrigHndl) { pNewHndl.release(); } throw; } } } catch (...) { qDebug("Caught unknown exception in Mp3TransformThread::transform()"); traceToFile("Caught unknown exception in Mp3TransformThread::transform()", 0); throw; // !!! needed to restore "erased" files when errors occur, because when an exception is thrown the destructors only get called if that exception is caught; so catching and rethrowing is not a "no-op" } return !bAborted; } //ttt2 try to avoid rescanning the last file in a transform when intermediaries are removed; } // namespace // if there are errors the user is notified; // returns true iff there were no errors; bool transform(const deque<const Mp3Handler*>& vpHndlr, vector<Transformation*>& vpTransf, const string& strTitle, QWidget* pParent, CommonData* pCommonData, TransfConfig& transfConfig) { vector<const Mp3Handler*> vpDel; vector<const Mp3Handler*> vpAdd; string strErrorFile, strErrorDir; bool bWriteError; bool bFileChanged; { Mp3TransformThread* pThread (new Mp3TransformThread(pCommonData, transfConfig, vpHndlr, vpDel, vpAdd, vpTransf)); ThreadRunnerDlgImpl dlg (pParent, getNoResizeWndFlags(), pThread, ThreadRunnerDlgImpl::SHOW_COUNTER, ThreadRunnerDlgImpl::TRUNCATE_BEGIN); dlg.setWindowTitle(convStr(strTitle)); dlg.exec(); strErrorFile = pThread->m_strErrorFile; strErrorDir = pThread->m_strErrorDir; bWriteError = pThread->m_bWriteError; bFileChanged = pThread->m_bFileChanged; } //if (dlg.exec()) // !!! even if the dialog was aborted, some files might have been changed already, and this is not undoable { pCommonData->mergeHandlerChanges(vpAdd, vpDel, CommonData::SEL | CommonData::CURRENT); } if (!strErrorFile.empty()) { if (bWriteError) { QMessageBox::critical(pParent, "Error", "There was an error writing to the following file:\n\n" + toNativeSeparators(convStr(strErrorFile)) + "\n\nMake sure that you have write permissions and that there is enough space on the disk.\n\nProcessing aborted."); } else { if (bFileChanged) { QMessageBox::critical(pParent, "Error", "The file \"" + toNativeSeparators(convStr(strErrorFile)) + "\" seems to have been modified since the last scan. You need to rescan it before continuing.\n\nProcessing aborted."); } else { if (strErrorDir.empty()) { QMessageBox::critical(pParent, "Error", "There was an error processing the following file:\n\n" + toNativeSeparators(convStr(strErrorFile)) + "\n\nProbably the file was deleted or modified since the last scan, in which case you should reload / rescan your collection. Or it may be used by another program; if that's the case, you should stop the other program first.\n\nThis may also be caused by access restrictions or a full disk.\n\nProcessing aborted."); } else { QMessageBox::critical(pParent, "Error", "There was an error processing the following file:\n" + toNativeSeparators(convStr(strErrorFile)) + "\n\nThe following folder couldn't be created:\n" + toNativeSeparators(convStr(strErrorDir)) + "\n\nProcessing aborted."); } } } } return strErrorFile.empty(); } //ttt1 This is a new crash from when the destination folder was full while saving modifications, in particular adding an album image. ��������������MP3Diags-1.0.12.079/src/ExportDlgImpl.h�������������������������������������������������������������0000644�0001750�0000144�00000005026�11261057356�016167� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef EXPORTDLGIMPL_H #define EXPORTDLGIMPL_H #include <vector> #include <QDialog> #include "ui_Export.h" class Mp3Handler; class ExportDlgImpl : public QDialog, private Ui::ExportDlg { Q_OBJECT bool exportAsText(const std::string& strFileName); bool exportAsM3u(const std::string& strFileName); bool exportAsXml(const std::string& strFileName); void getHandlers(std::vector<const Mp3Handler*>& v); void setFormatBtn(); QString getFileName(); void setExt(const char* szExt); public: ExportDlgImpl(QWidget* pParent); ~ExportDlgImpl(); /*$PUBLIC_FUNCTIONS$*/ void run(); public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pCloseB_clicked() { accept(); } void on_m_pExportB_clicked(); void on_m_pChooseFileB_clicked(); void on_m_pXmlRB_clicked() { setExt("xml"); } void on_m_pM3uRB_clicked() { setExt("m3u"); } void on_m_pTextRB_clicked() { setExt("txt"); } }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/StructuralTransformation.cpp������������������������������������������������0000644�0001750�0000144�00000075055�11477523741�021105� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "StructuralTransformation.h" #include "Helpers.h" #include "Mp3Manip.h" #include "MpegStream.h" #include "Id3V230Stream.h" #include "Id3V240Stream.h" using namespace std; using namespace pearl; //=============================================================================================================== //=============================================================================================================== //=============================================================================================================== // locates a frame that starts about 2 seconds before pos and is compatible with pAudio; // if the stream is too short or such a frame can't be found, it returns pos; // doesn't change the pointer for "in"; static streampos findNearMpegFrameAtLeft(streampos pos, istream& in, MpegStream* pAudio) { StreamStateRestorer rst (in); streampos posRes (pos); in.seekg(pos); int nSize (pAudio->getBitrate()/8*2); // about 2 seconds if (posRes > nSize) { posRes -= nSize; } else { posRes = 0; } in.seekg(posRes); if (pAudio->findNextCompatFrame(in, pos)) { posRes = in.tellg(); return posRes; } return pos; } // locates a frame that starts about 2 seconds after pos and is compatible with pAudio; // if the stream is too short or such a frame can't be found, it returns pos; // doesn't change the pointer for "in"; static streampos findNearMpegFrameAtRight(streampos pos, istream& in, MpegStream* pAudio) { StreamStateRestorer rst (in); streampos posRes (pos); in.seekg(pos); int nSize (pAudio->getBitrate()/8*2); // about 2 seconds posRes += nSize; if (posRes > getSize(in)) { posRes = pos; // ttt3 perhaps should go a little farther } in.seekg(posRes); streampos posLimit (pos); posLimit += nSize*2; if (pAudio->findNextCompatFrame(in, posLimit)) { posRes = in.tellg(); return posRes; } return pos; } //=============================================================================================================== //=============================================================================================================== //=============================================================================================================== /*static*/ bool SingleBitRepairer::isUnknown(const DataStream* p) { // UnknownDataStreamBase covers UnknownDataStream, BrokenDataStream, UnsupportedDataStream and TruncatedMpegDataStream, which is probably OK; doesn't matter much if it returns true for types that it shouldn't - there's just a small performance penalty return 0 != dynamic_cast<const UnknownDataStreamBase*>(p); } /*override*/ Transformation::Result SingleBitRepairer::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const string& strOrigSrcName, string& strTempName) { //CB_ASSERT(UnknownDataStreamBase::BEGIN_SIZE >= x) //if (strOrigSrcName in tmp or proc) throw; //ttt2 const vector<DataStream*>& vpStreams (h.getStreams()); for (int i = 0, n = cSize(vpStreams); i < n - 2; ++i) { DataStream* pDataStream (vpStreams[i]); MpegStream* pAudio (dynamic_cast<MpegStream*>(pDataStream)); if (0 != pAudio) { UnknownDataStreamBase* pFrameToChange (dynamic_cast<UnknownDataStreamBase*>(vpStreams[i + 1])); if (0 != pFrameToChange) { for (int k = 0; k < 32; ++k) { try { NoteColl notes (100); char bfr [4]; const char* q (pFrameToChange->getBegin()); bfr[0] = q[0]; bfr[1] = q[1]; bfr[2] = q[2]; bfr[3] = q[3]; bfr[k / 8] ^= 1 << (k % 8); MpegFrameBase frame (notes, pFrameToChange->getPos(), bfr); if (pAudio->isCompatible(frame)) { streampos posNewFrameEnd (frame.getPos()); posNewFrameEnd += frame.getSize(); int j (i + 1); for (; j < n; ++j) { UnknownDataStreamBase* pLastReplacedFrame (dynamic_cast<UnknownDataStreamBase*>(vpStreams[j])); if (0 == pLastReplacedFrame) { break; } streampos posLastReplacedFrameEnd (pLastReplacedFrame->getPos()); posLastReplacedFrameEnd += pLastReplacedFrame->getSize(); if (posLastReplacedFrameEnd == posNewFrameEnd) { //qDebug("found"); ifstream_utf8 in (h.getName().c_str(), ios::binary); { // comp switch (transfConfig.getCompAction()) { case TransfConfig::TRANSF_DONT_CREATE: break; case TransfConfig::TRANSF_CREATE: { streampos posCompBeg (findNearMpegFrameAtLeft(pFrameToChange->getPos(), in, pAudio)); streampos posCompEnd (findNearMpegFrameAtRight(posLastReplacedFrameEnd, in, pAudio)); in.seekg(posCompBeg); string strCompBefore; string strCompAfter; transfConfig.getCompNames(strOrigSrcName, getActionName(), strCompBefore, strCompAfter); { // tmp before ofstream_utf8 out (strCompBefore.c_str(), ios::binary); //partialCopy(in, out, 10000); //appendFilePart(in, out, pos, 2*nHalfSize); appendFilePart(in, out, posCompBeg, posCompEnd - posCompBeg); } { // tmp after ofstream_utf8 out (strCompAfter.c_str(), ios::binary); appendFilePart(in, out, posCompBeg, posCompEnd - posCompBeg); out.seekp(pFrameToChange->getPos() - posCompBeg); out.write(bfr, 4); } } break; default: CB_ASSERT (false); } } { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); for (int i1 = 0; i1 < n; ++i1) { DataStream* q (vpStreams[i1]); q->copy(in, out); } out.seekp(pFrameToChange->getPos()); out.write(bfr, 4); CB_CHECK1 (out, WriteError()); } return CHANGED; } if (posLastReplacedFrameEnd > posNewFrameEnd) { break; } } } } catch (const MpegFrameBase::NotMpegFrame&) { } } } } /*BrokenMpegDataStream* pBroken (dynamic_cast<BrokenMpegDataStream*>(pDataStream)); UnknownDataStream* pUnknown (dynamic_cast<UnknownDataStream*>(pDataStream)); TruncatedMpegDataStream* pTruncated (dynamic_cast<TruncatedMpegDataStream*>(pDataStream));*/ } return NOT_CHANGED; } //================================================================================================================================ //================================================================================================================================ //================================================================================================================================ /*override*/ Transformation::Result InnerNonAudioRemover::apply(const Mp3Handler& h, const TransfConfig& cfg, const std::string& strOrigSrcName, std::string& strTempName) { setupDiscarded(h); Result eRes (GenericRemover::apply(h, cfg, strOrigSrcName, strTempName)); return NOT_CHANGED == eRes ? NOT_CHANGED : CHANGED_NO_RECALL; } void InnerNonAudioRemover::setupDiscarded(const Mp3Handler& h) { m_spStreamsToDiscard.clear(); const vector<DataStream*>& vpStreams (h.getStreams()); int nFirstAudioPos (-1); int nLastAudioPos (-1); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* pDataStream (vpStreams[i]); //qDebug("%s", pDataStream->getDisplayName()); //?? probably want to remove garbage between vbri and audio, but definitely not the 16 bytes between xing and audio if (0 != dynamic_cast<MpegStream*>(pDataStream) || 0 != dynamic_cast<VbriStream*>(pDataStream))// ttt2 should consider these? : || 0 != dynamic_cast<XingStreamBase*>(pDataStream) || 0 != dynamic_cast<VbriStream*>(pDataStream)) // with them, there's a risk of destroying Xing headers created by Mp3Fixer { if (-1 == nFirstAudioPos) { nFirstAudioPos = i; } nLastAudioPos = i; } } if (nFirstAudioPos == nLastAudioPos) { return; } for (int i = nFirstAudioPos + 1; i < nLastAudioPos; ++i) { if (0 == dynamic_cast<MpegStream*>(vpStreams[i]) && 0 == dynamic_cast<VbriStream*>(vpStreams[i])) { m_spStreamsToDiscard.insert(vpStreams[i]); } } } /* ttt2 see about unsynch audio (when some frames use data from other frames - bit reservoirs) diagram at http://www.hydrogenaudio.org/forums/index.php?showtopic=36445&pid=321867&mode=threaded&start=#entry321867 http://www.hydrogenaudio.org/forums/index.php?showtopic=35654&st=25&p=354991&#entry354991 http://www.hydrogenaudio.org/forums/lofiversion/index.php/t42194.html http://www.hydrogenaudio.org/forums/index.php?showtopic=38510&pid=347136&mode=threaded&start=0#entry347136 the issue is that this is stored in the "side info" area, which is poorly documented, the main way to figure out what's going on being to look at working code; so it's probably not worth the bother; something that could probably be done is to remove some/most of the "truncated audio" notes, where the last frame only uses the beginning of the area; still, padding with 0 is probably better, as most stand-alone taggers shoudln't care about side info, and probably just expect a full frame; note that inserting a blank frame before a cut duesn't really solve the warning in mplayer about being unable to rewind, because the side info needs to be modified in the affected frames */ /*override*/ bool InnerNonAudioRemover::matches(DataStream* p) const { bool b (m_spStreamsToDiscard.count(p) > 0); CB_ASSERT (!b || (0 == dynamic_cast<MpegStream*>(p) && 0 == dynamic_cast<VbriStream*>(p))); return b; } //================================================================================================================================ //================================================================================================================================ //================================================================================================================================ /*override*/ Transformation::Result GenericRemover::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { const vector<DataStream*>& vpStreams (h.getStreams()); bool bFoundMatch (false); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { if (matches(vpStreams[i])) { bFoundMatch = true; break; } } if (!bFoundMatch) { return NOT_CHANGED; } //ttt2 see InnerNonAudioRemover: Lambo has an error in mplayer, because of bit reservoir ifstream_utf8 in (h.getName().c_str(), ios::binary); { // comp switch (transfConfig.getCompAction()) { case TransfConfig::TRANSF_DONT_CREATE: break; case TransfConfig::TRANSF_CREATE: { in.seekg(0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (matches(p)) { MpegStream* pPrevAudio (i > 0 ? dynamic_cast<MpegStream*>(vpStreams[i - 1]) : 0); MpegStream* pNextAudio (i < n - 1 ? dynamic_cast<MpegStream*>(vpStreams[i + 1]) : 0); string strCompBefore; string strCompAfter; transfConfig.getCompNames(strOrigSrcName, getActionName(), strCompBefore, strCompAfter); streampos posCompBeg (0 != pPrevAudio ? findNearMpegFrameAtLeft(pPrevAudio->getEnd(), in, pPrevAudio) : p->getPos()); streampos posCompEnd (0 != pNextAudio ? findNearMpegFrameAtRight(pNextAudio->getPos(), in, pNextAudio) : p->getEnd()); { // comp before ofstream_utf8 out (strCompBefore.c_str(), ios::binary); appendFilePart(in, out, posCompBeg, posCompEnd - posCompBeg); } { // comp after if (0 != pPrevAudio || 0 != pNextAudio) { ofstream_utf8 out (strCompAfter.c_str(), ios::binary); appendFilePart(in, out, posCompBeg, p->getPos() - posCompBeg); appendFilePart(in, out, p->getEnd(), posCompEnd - p->getEnd()); } } } } } break; default: CB_ASSERT (false); } } { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* pDataStream (vpStreams[i]); if (!matches(pDataStream)) { //qDebug("copying %d for %s", (int)pDataStream->getSize(), pDataStream->getDisplayName()); pDataStream->copy(in, out); } /*else { qDebug("skipping %d for %s", (int)pDataStream->getSize(), pDataStream->getDisplayName()); }*/ } } return CHANGED; // CHANGED_NO_RECALL would be ok in some cases but it's hard to tell when } /*override*/ bool UnknownDataStreamRemover::matches(DataStream* p) const { return 0 != dynamic_cast<UnknownDataStream*>(p); } /*override*/ bool BrokenDataStreamRemover::matches(DataStream* p) const { return 0 != dynamic_cast<BrokenDataStream*>(p); } /*override*/ bool UnsupportedDataStreamRemover::matches(DataStream* p) const { return 0 != dynamic_cast<UnsupportedDataStream*>(p); } /*override*/ bool TruncatedMpegDataStreamRemover::matches(DataStream* p) const { return 0 != dynamic_cast<TruncatedMpegDataStream*>(p); } /*override*/ bool NullStreamRemover::matches(DataStream* p) const { return 0 != dynamic_cast<NullDataStream*>(p); } /*override*/ bool BrokenId3V2Remover::matches(DataStream* pDataStream) const { BrokenDataStream* p (dynamic_cast<BrokenDataStream*>(pDataStream)); if (0 == p) { return false; } string strBaseName (p->getBaseName()); return strBaseName == Id3V230Stream::getClassDisplayName() || strBaseName == Id3V240Stream::getClassDisplayName(); } /*override*/ bool UnsupportedId3V2Remover::matches(DataStream* pDataStream) const { UnsupportedDataStream* p (dynamic_cast<UnsupportedDataStream*>(pDataStream)); if (0 == p) { return false; } string strBaseName (p->getBaseName()); return strBaseName == Id3V2StreamBase::getClassDisplayName(); } /*override*/ bool MultipleId3StreamRemover::matches(DataStream* p) const { return m_spStreamsToDiscard.count(p) > 0; } void MultipleId3StreamRemover::setupDiscarded(const Mp3Handler& h) { m_spStreamsToDiscard.clear(); vector<DataStream*> v1, v2; const vector<DataStream*>& vpStreams (h.getStreams()); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { DataStream* p (vpStreams[i]); if (0 != dynamic_cast<Id3V2StreamBase*>(p)) { v2.push_back(p); } if (0 != dynamic_cast<Id3V1Stream*>(p)) { v1.push_back(p); } } if (cSize(v1) > 1) { m_spStreamsToDiscard.insert(v1.begin(), v1.end() - 1); } if (cSize(v2) > 1) { m_spStreamsToDiscard.insert(v2.begin() + 1, v2.end()); } } /*override*/ bool MismatchedXingRemover::matches(DataStream* p) const { return m_spStreamsToDiscard.count(p) > 0; } void MismatchedXingRemover::setupDiscarded(const Mp3Handler& h) { m_spStreamsToDiscard.clear(); const vector<DataStream*>& vpStreams (h.getStreams()); for (int i = 0, n = cSize(vpStreams); i < n - 1; ++i) { XingStreamBase* pXing (dynamic_cast<XingStreamBase*>(vpStreams[i])); if (0 != pXing) { MpegStream* pAudio (dynamic_cast<MpegStream*>(vpStreams[i + 1])); if (0 != pAudio && pXing->getFrameCount() != pAudio->getFrameCount()) { m_spStreamsToDiscard.insert(pXing); } } } } /*override*/ bool Id3V1Remover::matches(DataStream* pDataStream) const { Id3V1Stream* p (dynamic_cast<Id3V1Stream*>(pDataStream)); return 0 != p; } //================================================================================================================================ //================================================================================================================================ //================================================================================================================================ /*override*/ Transformation::Result TruncatedAudioPadder::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const string& strOrigSrcName, string& strTempName) { const vector<DataStream*>& vpStreams (h.getStreams()); ifstream_utf8 in (h.getName().c_str(), ios::binary); for (int i = 0, n = cSize(vpStreams); i < n; ++i) { TruncatedMpegDataStream* pTruncStream (dynamic_cast<TruncatedMpegDataStream*>(vpStreams[i])); if (0 != pTruncStream) { int nPaddingSize (pTruncStream->getExpectedSize() - pTruncStream->getSize()); { // comp CB_ASSERT (i > 0); // !!! a stream can be "truncated audio" only if it follows another audio; even if the user is allowed to erase streams at will, after removing an audio stream and rescanning what was "truncated audio" will become something else (perhaps "broken audio") MpegStream* pAudio (dynamic_cast<MpegStream*>(vpStreams[i - 1])); CB_ASSERT (0 != pAudio); switch (transfConfig.getCompAction()) { case TransfConfig::TRANSF_DONT_CREATE: break; case TransfConfig::TRANSF_CREATE: { streampos posCompBeg (findNearMpegFrameAtLeft(pTruncStream->getPos(), in, pAudio)); streampos posCompEnd (findNearMpegFrameAtRight(pTruncStream->getPos(), in, pAudio)); CB_ASSERT(posCompEnd >= pTruncStream->getPos()); in.seekg(posCompBeg); string strCompBefore; string strCompAfter; transfConfig.getCompNames(strOrigSrcName, getActionName(), strCompBefore, strCompAfter); { // tmp before ofstream_utf8 out (strCompBefore.c_str(), ios::binary); //partialCopy(in, out, 10000); //appendFilePart(in, out, pos, 2*nHalfSize); appendFilePart(in, out, posCompBeg, posCompEnd - posCompBeg); } { // tmp after ofstream_utf8 out (strCompAfter.c_str(), ios::binary); appendFilePart(in, out, posCompBeg, pTruncStream->getPos() - posCompBeg); writeZeros(out, nPaddingSize); appendFilePart(in, out, pTruncStream->getEnd(), posCompEnd - pTruncStream->getEnd()); } } break; default: CB_ASSERT (false); } } { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); for (int i1 = 0; i1 < n; ++i1) { DataStream* q (vpStreams[i1]); q->copy(in, out); if (q == pTruncStream) { writeZeros(out, nPaddingSize); } } } return CHANGED; } } return NOT_CHANGED; } //================================================================================================================================ //================================================================================================================================ //================================================================================================================================ //ttt2 see how adding a Xing header affects gapless playing. split a VBR file //ttt2 in a way this could take care of Xing headers for CBR streams as well, but it doesn't seem the best place to do it, especially as we ignore most of the data in the Lame header and "restoring a header" means just putting back byte count and frame count /*override*/ Transformation::Result VbrRepairerBase::repair(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName, bool bForceRebuild) { const vector<DataStream*>& vpStreams (h.getStreams()); ifstream_utf8 in (h.getName().c_str(), ios::binary); set<int> sVbriPos; int nAudioPos (-1); set<int> sXingPos; int n (cSize(vpStreams)); int nXingPos (-1); XingStreamBase* pXingStreamBase (0); for (int i = 0; i < n; ++i) { MpegStream* pAudio (dynamic_cast<MpegStream*>(vpStreams[i])); if (0 != pAudio) { nAudioPos = i; break; } VbriStream* pVbriStream (dynamic_cast<VbriStream*>(vpStreams[i])); if (0 != pVbriStream) { sVbriPos.insert(i); } XingStreamBase* q (dynamic_cast<XingStreamBase*>(vpStreams[i])); if (0 != q) { sXingPos.insert(i); nXingPos = i; pXingStreamBase = q; } } if (-1 == nAudioPos) { return NOT_CHANGED; } // no audio MpegStream* pAudio (dynamic_cast<MpegStream*>(vpStreams[nAudioPos])); if (!pAudio->isVbr()) { return NOT_CHANGED; } // CBR audio bool bXingOk (1 == cSize(sXingPos) && 1 == sXingPos.count(nAudioPos - 1) && pXingStreamBase->matches(pAudio)); if (!bForceRebuild && sVbriPos.empty() && bXingOk) { return NOT_CHANGED; } // exit if there's no VBRI and there's one matching Xing right before the audio bool bRepairMp3Fixer (false); bool bRemoveXing (true); // if true, existing headers are removed bool bAddXing (true); // if true, a header is added before the first Audio if (1 == cSize(sXingPos) && nXingPos < n - 2 && pXingStreamBase->isBrokenByMp3Fixer(vpStreams[nXingPos + 1], vpStreams[nXingPos + 2])) { // ttt2 see also http://www.kde-apps.org/content/show.php/Mp3Fixer?content=31539 for a bug that makes mp3fix.rb write its fix at a wrong address for mono files, but that's not going to be fixed now; at least don't try to fix this on mono files (or better: fix only stereo mpeg1 L III) bRemoveXing = bAddXing = false; bRepairMp3Fixer = true; } { // temp transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); ofstream_utf8 out (strTempName.c_str(), ios::binary); in.seekg(0); int i (0); for (; i < n; ++i) { DataStream* p (vpStreams[i]); if (0 != dynamic_cast<VbriStream*>(p)) { // nothing to do; this gets discarded } else if (0 != dynamic_cast<XingStreamBase*>(p)) { if (bRepairMp3Fixer) { XingStreamBase* pXing (dynamic_cast<XingStreamBase*>(p)); MpegStream* pAudio (dynamic_cast<MpegStream*>(vpStreams[i + 2])); CB_ASSERT(0 != pXing && 0 != pAudio); // that's what isBrokenByMp3Fixer() is about int nOffs (pXing->getFirstFrame().getSideInfoSize() + MpegFrame::MPEG_FRAME_HDR_SIZE); createXing(out, pXing->getFirstFrame(), pAudio->getFrameCount() + 1, pAudio->getSize() + pXing->getSize()); appendFilePart(in, out, p->getPos(), nOffs); streampos pos (p->getPos()); /*#ifdef GENERATE_TOC //!!! Doesn't matter whether GENERATE_TOC is defined or not. Mp3Fixer broke the first audio frame by adding length info and no TOC (although it claims to add TOC as well). What we do here is create a new Xing header (by calling createXing()) and remove the 16 bytes Mp3Fixer added, to restore the first frame to an audio frame, the way it was before Mp3Fixer messed it up. It's up to createXing() to add TOC or not. //const int nXingSize (16 + 100); #else const int nXingSize (16); #endif*/ const int nMp3FixXingSize (16); // Mp3Fix always adds 16 bytes, because it doesn't use a TOC pos += nMp3FixXingSize + nOffs; appendFilePart(in, out, pos, p->getSize() - nOffs - nMp3FixXingSize); } else if (!bRemoveXing) { p->copy(in, out); } } else if (0 != dynamic_cast<MpegStream*>(p)) { if (bAddXing) { dynamic_cast<MpegStream*>(p)->createXing(out); } break; } else { // any other stream p->copy(in, out); } } for (; i < n; ++i) { DataStream* p (vpStreams[i]); p->copy(in, out); } } return CHANGED_NO_RECALL; } //================================================================================================================================ //================================================================================================================================ //================================================================================================================================ /*override*/ Transformation::Result VbrRepairer::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { return repair(h, transfConfig, strOrigSrcName, strTempName, DONT_FORCE_REBUILD); } /*override*/ Transformation::Result VbrRebuilder::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { return repair(h, transfConfig, strOrigSrcName, strTempName, FORCE_REBUILD); } //================================================================================================================================ //================================================================================================================================ //================================================================================================================================ //ttt2 https://sourceforge.net/projects/mp3diags/forums/forum/947206/topic/3389395?message=8033754 - remove Ape, Lyrics, ... // email on Mon, 15 Mar 2010 - remove short audio streams �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/NotesModel.cpp��������������������������������������������������������������0000644�0001750�0000144�00000023165�11250015215�016027� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QPainter> #include <QTableView> #include "NotesModel.h" #include "FilesModel.h" #include "StreamsModel.h" #include "DataStream.h" #include "CommonData.h" using namespace std; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== NotesModel::NotesModel(CommonData* pCommonData) : QAbstractTableModel(pCommonData->m_pNotesG), m_pCommonData(pCommonData) {} /*override*/ int NotesModel::rowCount(const QModelIndex&) const { return cSize(m_pCommonData->getCrtNotes()); } /*override*/ int NotesModel::columnCount(const QModelIndex&) const { return 3; } /*override*/ QVariant NotesModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("NotesModel::data()"); int j (index.column()); //if (nRole == Qt::SizeHintRole && j > 0) { return QSize(CELL_WIDTH - 1, CELL_HEIGHT - 1); } // !!! "-1" so one pixel can be used to draw the grid //if (nRole == Qt::SizeHintRole) { return QSize(CELL_WIDTH - 10, CELL_HEIGHT - 10); } // !!! "-1" so one pixel can be used to draw the grid if (!index.isValid() || nRole != Qt::DisplayRole) { return QVariant(); } int nRow (index.row()); int nSize (cSize(m_pCommonData->getCrtNotes())); CB_ASSERT (nRow >= 0 || nRow < nSize); const Note* pNote (m_pCommonData->getCrtNotes()[nRow]); //printf("Note at %p\n", pNote); switch (j) { case 0: return getNoteLabel(pNote); case 1: { const string& s (pNote->getDetail()); if (s.empty()) { return pNote->getDescription(); } return convStr(s); } case 2: return convStr(pNote->getPosHex()); //return "mmmiiiWWWlll"; //return "ABCDEFGHIJKLM"; default: CB_ASSERT(false); } } /*override*/ QVariant NotesModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("NotesModel::headerData"); if (nRole == Qt::SizeHintRole) { /*QVariant v (QAbstractTableModel::headerData(nSection, eOrientation, nRole)); // !!! doesn't work because QAbstractTableModel::headerData always returns an invalid value [...] */ return getNumVertHdrSize(cSize(m_pCommonData->getCrtNotes()), eOrientation); } if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { switch (nSection) { case 0: return "L"; case 1: return "Note"; case 2: return "Address"; default: CB_ASSERT (false); } } return nSection + 1; } void NotesModel::matchSelToMain() { QModelIndexList lSelFiles (m_pCommonData->m_pFilesG->selectionModel()->selection().indexes()); set<int> sSel; for (QModelIndexList::iterator it = lSelFiles.begin(), end = lSelFiles.end(); it != end; ++it) { int nCol (it->column()); if (nCol > 0) // skip file name { sSel.insert(nCol - 1); } } QItemSelectionModel* pNotesSelModel (m_pCommonData->m_pNotesG->selectionModel()); pNotesSelModel->clearSelection(); bool bFirstFound (false); for (int i = 0, nNoteCnt = cSize(m_pCommonData->getCrtNotes()); i < nNoteCnt; ++i) { const Note* pNote (m_pCommonData->getCrtNotes()[i]); int nPos (m_pCommonData->findPos(pNote)); if (sSel.count(nPos) > 0) { if (!bFirstFound) { bFirstFound = true; m_pCommonData->m_pNotesG->setCurrentIndex(index(i, 0)); } pNotesSelModel->select(index(i, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); } } } void NotesModel::onNotesGSelChanged() { NonblockingGuard g (m_pCommonData->m_bChangeGuard); if (!g) { return; } m_pCommonData->m_pFilesModel->matchSelToNotes(); m_pCommonData->m_pStreamsModel->matchSelToNotes(); } static bool isInList(const Note* pNote, vector<const DataStream*>& vStreams) { if (-1 == pNote->getPos()) { return false; } for (int i = 0, n = cSize(vStreams); i < n; ++i) // ttt2 use a binary search; the streams are sorted; { if (pNote->getPos() >= vStreams[i]->getPos() && pNote->getPos() < vStreams[i]->getPos() + vStreams[i]->getSize()) { //cout << "accepted " << pNote->getPosHex() << " " << pNote->getDescription() << endl; return true; } } return false; } void NotesModel::matchSelToStreams() { QModelIndexList lSelStreams (m_pCommonData->m_pStreamsG->selectionModel()->selection().indexes()); const vector<DataStream*>& vCrtStreams (m_pCommonData->getViewHandlers()[m_pCommonData->getFilesGCrtRow()]->getStreams()); vector<const DataStream*> vSelStreams; for (QModelIndexList::iterator it = lSelStreams.begin(), end = lSelStreams.end(); it != end; ++it) { int nRow (it->row()); vSelStreams.push_back(vCrtStreams[nRow]); } QItemSelectionModel* pNotesSelModel (m_pCommonData->m_pNotesG->selectionModel()); pNotesSelModel->clearSelection(); bool bFirstFound (false); for (int i = 0, nNoteCnt = cSize(m_pCommonData->getCrtNotes()); i < nNoteCnt; ++i) { const Note* pNote (m_pCommonData->getCrtNotes()[i]); if (isInList(pNote, vSelStreams)) { if (!bFirstFound) { bFirstFound = true; m_pCommonData->m_pNotesG->setCurrentIndex(index(i, 0)); } pNotesSelModel->select(index(i, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); } } } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== NotesGDelegate::NotesGDelegate(CommonData* pCommonData) : MultiLineTvDelegate(pCommonData->m_pNotesG), m_pCommonData(pCommonData) { } /*override*/ void NotesGDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { int nRow (index.row()); //f1(); pPainter->save(); CB_ASSERT (nRow >= 0 && nRow < cSize(m_pCommonData->getCrtNotes())); const Note* pNote (m_pCommonData->getCrtNotes().at(nRow)); QStyleOptionViewItemV2 myOption (option); //myOption.palette.setColor(QPalette::Base, pal.color(QPalette::Disabled, QPalette::Window)); // !!! the palette doesn't matter; fillRect() should be called QColor col; double d1, d2; m_pCommonData->getNoteColor(*pNote, vector<const Note*>(), col, d1, d2); pPainter->fillRect(myOption.rect, QBrush(col)); if (0 == index.column()) { myOption.displayAlignment |= Qt::AlignHCenter; //myOption.font = m_pCommonData->getGeneralFont(); //myOption.font.setPixelSize(9); if (Note::ERR == pNote->getSeverity()) { myOption.palette.setColor(QPalette::Text, ERROR_PEN_COLOR()); } else if (Note::SUPPORT == pNote->getSeverity()) { myOption.palette.setColor(QPalette::Text, SUPPORT_PEN_COLOR()); } } if (2 == index.column()) { myOption.displayAlignment |= Qt::AlignRight; myOption.font = m_pCommonData->getFixedFont(); } //myOption.displayAlignment = Qt::AlignRight | Qt::AlignVCenter; #if 0 //myOption.palette.setColor(QPalette::Base, pal.color(QPalette::Disabled, QPalette::Window)); QString qstrText (index.model()->data(index, Qt::DisplayRole).toString()); //qstrText = "QQQ"; drawDisplay(pPainter, myOption, myOption.rect, qstrText); // ttt3 see why selecting cells in column 0 or 1 doesn't make column 2 selected unless there's an address for the note; drawFocus(pPainter, myOption, myOption.rect); #else MultiLineTvDelegate::paint(pPainter, myOption, index); #endif pPainter->restore(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/ImageInfoPanelWdgImpl.h�����������������������������������������������������0000644�0001750�0000144�00000004660�11232274740�017536� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef ImageInfoPanelWdgImplH #define ImageInfoPanelWdgImplH #include <QWidget> #include "ui_ImageInfoPanel.h" #include "TagWriter.h" #include "CommonTypes.h" class ImageInfoPanelWdgImpl : public QFrame, private Ui::ImageInfoPanelWdg { Q_OBJECT const TagWrtImageInfo m_tagWrtImageInfo; int m_nPos; public: ImageInfoPanelWdgImpl(QWidget* pParent, const TagWrtImageInfo& tagWrtImageInfo, int nPos); ~ImageInfoPanelWdgImpl(); /*$PUBLIC_FUNCTIONS$*/ void setNormalBackground(); void setHighlightBackground(); public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void on_m_pFullB_clicked(); void on_m_pAssignB_clicked() { emit assignImage(m_nPos); } void on_m_pEraseB_clicked() { emit eraseFile(m_nPos); } signals: void assignImage(int); void eraseFile(int); }; #endif // #ifndef ImageInfoPanelWdgImplH ��������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/ScanDlgImpl.cpp�������������������������������������������������������������0000644�0001750�0000144�00000006473�11265064011�016122� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QHeaderView> #include "ScanDlgImpl.h" #include "CommonData.h" #include "CheckedDir.h" using namespace std; using namespace pearl; ScanDlgImpl::ScanDlgImpl(QWidget* pParent, CommonData* pCommonData) : QDialog(pParent, getDialogWndFlags()), Ui::ScanDlg(), m_pCommonData(pCommonData) { setupUi(this); m_pDirModel = new CheckedDirModel(this, CheckedDirModel::USER_CHECKABLE); m_pDirModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::Drives); m_pDirModel->setSorting(QDir::IgnoreCase); m_pDirsT->setModel(m_pDirModel); m_pDirsT->expand(m_pDirModel->index("/")); m_pDirsT->header()->hide(); m_pDirsT->header()->setStretchLastSection(false); m_pDirsT->header()->setResizeMode(0, QHeaderView::ResizeToContents); //m_pDirModel->setDirs(pCommonData->getIncludeDirs(), pCommonData->getExcludeDirs(), m_pDirsT); //m_pDirModel->expandNodes(m_pDirsT); QTimer::singleShot(1, this, SLOT(onShow())); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } ScanDlgImpl::~ScanDlgImpl() { } void ScanDlgImpl::onShow() { m_pDirModel->setDirs(m_pCommonData->getIncludeDirs(), m_pCommonData->getExcludeDirs(), m_pDirsT); // !!! needed here because on the constructor the tree view doesn't have the right size; //ttt2 perhaps do the same in SessionEditorDlgImpl / see which approach is better } // if returning true, it also calls CommonData::setDirs() bool ScanDlgImpl::run(bool& bForce) { if (QDialog::Accepted != exec()) { return false; } bForce = m_pForceScanCkB->isChecked(); m_pCommonData->setDirectories(m_pDirModel->getCheckedDirs(), m_pDirModel->getUncheckedDirs()); return true; } void ScanDlgImpl::onHelp() { // openHelp("index.html"); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/FullSizeImgDlg.cpp����������������������������������������������������������0000644�0001750�0000144�00000006362�11310411453�016600� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QDialog> #include <QLabel> #include <QVBoxLayout> #include <QAction> #include <QClipboard> #include <QApplication> #include <QMimeData> #include "FullSizeImgDlg.h" #include "Helpers.h" FullSizeImgDlg::FullSizeImgDlg(QWidget* pParent, const ImageInfo& imageInfo) : QDialog(pParent, getNoResizeWndFlags()), m_imageInfo(imageInfo) { QVBoxLayout* pLayout (new QVBoxLayout(this)); //dlg.setLayout(pGridLayout); QLabel* p (new QLabel(this)); p->setPixmap(QPixmap::fromImage(imageInfo.getImage())); //ttt2 see if it should limit size (IIRC QLabel scaled down once a big image) pLayout->addWidget(p, 0, Qt::AlignHCenter); QString s; s.sprintf("%dx%d / %dkB\n%s", imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getSize()/1024, imageInfo.getImageType()); p = new QLabel(s, this); p->setAlignment(Qt::AlignHCenter); pLayout->addWidget(p, 0, Qt::AlignHCenter); { QAction* pAct (new QAction(this)); pAct->setShortcut(QKeySequence("Ctrl+C")); connect(pAct, SIGNAL(triggered()), this, SLOT(onCopy())); addAction(pAct); } } void FullSizeImgDlg::onCopy() { #ifndef WIN32 QByteArray ba (m_imageInfo.getComprData(), m_imageInfo.getSize()); QMimeData* pMimeData (new QMimeData()); const char* szFmt (0); switch (m_imageInfo.getCompr()) { case ImageInfo::JPG: szFmt = "image/jpeg"; break; case ImageInfo::PNG: szFmt = "image/png"; break; //ttt2 doesn't work for BMP, GIF, ... default: break; } if (0 != szFmt) { pMimeData->setData(szFmt, ba); QApplication::clipboard()->setMimeData(pMimeData); } else { delete pMimeData; } #else QApplication::clipboard()->setPixmap(QPixmap::fromImage(m_imageInfo.getImage())); #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Id3V2Stream.h���������������������������������������������������������������0000644�0001750�0000144�00000033407�11274225111�015432� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef Id3V2StreamH #define Id3V2StreamH #include <iosfwd> #include "DataStream.h" #include "SerSupport.h" // Frame of an ID3V2 tag struct Id3V2Frame { char m_szName[5]; int m_nMemDataSize; // size in memory, excluding header and unsynch int m_nDiskDataSize; // size including unsynchronization, excluding the header; if unsynch is used, m_nDiskDataSize>=m_nMemDataSize; if unsynch is not used, m_nDiskDataSize==m_nMemDataSize int m_nDiskHdrSize; // normally it's ID3_FRAME_HDR_SIZE but may be larger due to the unsynch scheme unsigned char m_cFlag1; unsigned char m_cFlag2; enum { ID3_FRAME_HDR_SIZE = 10 }; std::streampos m_pos; // position of the frame on the disk, including the header StringWrp* m_pFileName; // needed for serialization (it seems that the serialization cannot save pointers to strings, which makes some sense given that std::string is a "fundamental" type for the Boost serialization) // ttt2 make sure it's true bool m_bHasUnsynch; mutable bool m_bHasLatin1NonAscii; //ttt2 "mutable" doesn't look right virtual ~Id3V2Frame(); enum { SHORT_INFO, FULL_INFO }; void print(std::ostream& out, bool bFullInfo) const; // if bFullInfo is true some frames print more extensive details, e.g. lyrics // for display / export; for frames in KnownFrames::getKnownFrames only the data up to the first 0 is used (effectively removing comments in 2.3.0), while for the others, including TXXX, nulls and all other characters with codes below 32 are replaced with spaces (as a result, both description and value are shown for TXXX), so in either case the return value doesn't contain nulls; // whitespaces at the end of the string are removed; std::string getUtf8String() const; // for internal processing; similar to getUtf8String() but doesn't replace internal null characters with spaces; // removes trailing nulls and whitespaces, as well as 2.3.0 comments; std::string getRawUtf8String() const; bool isTxxx() const; std::string getReadableName() const; // normally returns m_szName, but if it has invalid characters (<=32 or >=127), returns a hex representation void writeUnsynch(std::ostream& out) const; // copies the frame to out, removing the unsynch bytes if they are present std::vector<char> m_vcData; // this is emptied when the constructor exits if it needs to much space; to reliably access a frame's data, Id3V2FrameDataLoader should be used virtual bool discardOnChange() const = 0; // ttt2 should distinguish between audio and ID3V2 change, should be called when audio is changed, ... struct NotId3V2Frame {}; struct UnsupportedId3V2Frame {}; enum ApicStatus { NO_APIC, ERR, USES_LINK, NON_COVER, COVER }; // !!! the reason "ERR" is used (and not "ERROR") is that "ERROR" is a macro in MSVC ApicStatus m_eApicStatus; enum PictureType { PT_COVER = 3 }; int m_nPictureType; // for APIC only (cover, back, ...) int m_nImgOffset; // for APIC only int m_nImgSize; // for APIC only ImageInfo::Compr m_eCompr; // for APIC only short m_nWidth; // for APIC only short m_nHeight; // for APIC only const char* getImageType() const; const char* getImageStatus() const; double getRating() const; // asserts it's POPM virtual int getOffset() const { return 0; } // to accomodate "Data length indicator" in Id3V240Stream private: Id3V2Frame(const Id3V2Frame&); Id3V2Frame& operator=(const Id3V2Frame&); protected: enum { NO_UNSYNCH, HAS_UNSYNCH }; Id3V2Frame(std::streampos pos, bool bHasUnsynch, StringWrp* pFileName); Id3V2Frame() : m_nWidth(-1), m_nHeight(-1) {} // serialization-only constructor static std::string utf8FromBomUtf16(const char* pData, int nSize); // returns a UTF8 string from a buffer containing a UTF16 sting starting with BOM; doesn't stop when finding a 0 terminator, but includes it in the result private: // may return multiple null characters; it's the job of getUtf8String() to deal with them; // chars after the first null are considered comments (or after the second null, for TXXX); virtual std::string getUtf8StringImpl() const = 0; friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 1) { throw std::runtime_error("invalid version of serialized file"); } ar & m_szName; ar & m_nMemDataSize; ar & m_nDiskDataSize; ar & m_nDiskHdrSize; ar & m_cFlag1; ar & m_cFlag2; ar & m_pos; ar & m_pFileName; ar & m_bHasUnsynch; ar & m_bHasLatin1NonAscii; ar & m_vcData; ar & m_eApicStatus; ar & m_nPictureType; ar & m_nImgOffset; ar & m_nImgSize; ar & m_eCompr; if (nVersion > 0) { ar & m_nWidth; ar & m_nHeight; } } }; BOOST_CLASS_VERSION(Id3V2Frame, 1); // Makes that frame data available, loading it from the file when necessary. This is needed for pictures or other large frames that would take too much space if they were stored in the memory, so they get discarded after the constructor completes. class Id3V2FrameDataLoader { Id3V2FrameDataLoader(const Id3V2FrameDataLoader&); Id3V2FrameDataLoader& operator=(const Id3V2FrameDataLoader&); const Id3V2Frame& m_frame; const char* m_pData; std::vector<char> m_vcOwnData; public: Id3V2FrameDataLoader(const Id3V2Frame& frame); ~Id3V2FrameDataLoader(); const char* getData() const { return m_pData; } struct LoadFailure {}; // thrown if the file is deleted / moved (and perhaps changed) after frames are identified }; // reads nCount bytes into pDest; // if bHasUnsynch is true, it actually reads more bytes, applying the unsynchronization algorithm, so pDest gets nCount bytes; // returns the number of bytes it could read; // posNext is the position where the next block begins (might be EOF); nothing starting at that position should be read; needed to take care of an ID3V2 tag whose last frame ends with 0xff and has no padding; // asserts that posNext is not before the current position in the stream std::streamsize readID3V2(bool bHasUnsynch, std::istream& in, char* pDest, std::streamsize nCount, std::streampos posNext, int& nBytesSkipped); // the total size, including the 10-byte header int getId3V2Size(char* pId3Header); //============================================================================================================ //============================================================================================================ //============================================================================================================ class Id3V2StreamBase : public DataStream, public TagReader { protected: std::vector<Id3V2Frame*> m_vpFrames; int m_nTotalSize; // including the header int m_nPaddingSize; unsigned char m_cFlags; std::streampos m_pos; StringWrp* m_pFileName; Id3V2Frame* findFrame(const char* szFrameName); //ttt2 finds the first frame, but doesn't care about duplicates const Id3V2Frame* findFrame(const char* szFrameName) const; //ttt2 finds the first frame, but doesn't care about duplicates void checkDuplicates(NoteColl& notes) const; void checkFrames(NoteColl& notes); // various checks to be called from derived class' constructor ImageInfo::Status m_eImageStatus; Id3V2Frame* m_pPicFrame; static const char* decodeApic(NoteColl& notes, int nDataSize, std::streampos pos, const char* pData, const char*& szMimeType, int& nPictureType, const char*& szDescription); void preparePictureHlp(NoteColl& notes, Id3V2Frame* pFrame, const char* pFrameData, const char* pImgData, const char* szMimeType); void preparePicture(NoteColl& notes); // initializes fields used by the APIC frame TagTimestamp get230TrackTime(bool* pbFrameExists) const; Id3V2StreamBase(int nIndex, std::istream& in, StringWrp* pFileName); Id3V2StreamBase() {} // serialization-only constructor struct NotSupTextEnc {}; struct ErrorDecodingApic {}; public: /*override*/ ~Id3V2StreamBase(); void printFrames(std::ostream& out) const; /*override*/ void copy(std::istream& in, std::ostream& out); /*override*/ std::string getInfo() const; /*override*/ std::streampos getPos() const { return m_pos; } /*override*/ std::streamoff getSize() const { return m_nTotalSize; } static const char* getClassDisplayName(); const std::vector<Id3V2Frame*>& getFrames() const { return m_vpFrames; } bool hasUnsynch() const; const Id3V2Frame* getFrame(const char* szName) const; // returns a frame with the given name; normally it returns the first such frame, but it may return another if there's a good reason (currently this is done for APIC only); returns 0 if no frame was found; bool hasReplayGain() const; enum { ID3_HDR_SIZE = 10 }; std::vector<const Id3V2Frame*> getKnownFrames() const; // to be used by Id3V2Cleaner; int getPaddingSize() const { return m_nPaddingSize; } struct NotId3V2 {}; // ================================ TagReader ========================================= /*override*/ std::string getTitle(bool* pbFrameExists = 0) const; /*override*/ std::string getArtist(bool* pbFrameExists = 0) const; /*override*/ std::string getTrackNumber(bool* pbFrameExists = 0) const; /*override*/ std::string getGenre(bool* pbFrameExists = 0) const; /*override*/ ImageInfo getImage(bool* pbFrameExists = 0) const; /*override*/ std::string getAlbumName(bool* pbFrameExists = 0) const; /*override*/ double getRating(bool* pbFrameExists = 0) const; /*override*/ std::string getComposer(bool* pbFrameExists = 0) const; /*override*/ int getVariousArtists(bool* pbFrameExists = 0) const; // combination of VariousArtists flags; since several frames might be involved, *pbFrameExists is set to "true" if at least a frame exists /*override*/ std::string getOtherInfo() const; /*override*/ std::vector<ImageInfo> getImages() const; /*override*/ std::string getImageData(bool* pbFrameExists = 0) const; const std::string& getFileName() const { return m_pFileName->s; } enum { DONT_ACCEPT_BROKEN, ACCEPT_BROKEN }; private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int nVersion) { if (nVersion > 0) { throw std::runtime_error("invalid version of serialized file"); } ar & boost::serialization::base_object<DataStream>(*this); ar & m_vpFrames; ar & m_nTotalSize; ar & m_nPaddingSize; ar & m_cFlags; ar & m_pos; ar & m_pFileName; //StringWrp wrp ("111222"); //ar & wrp; ar & m_eImageStatus; ar & m_pPicFrame; } }; //============================================================================================================ //============================================================================================================ //============================================================================================================ struct KnownFrames { static const char* LBL_TITLE(); static const char* LBL_ARTIST(); static const char* LBL_TRACK_NUMBER(); static const char* LBL_TIME_YEAR_230(); static const char* LBL_TIME_DATE_230(); static const char* LBL_TIME_240(); static const char* LBL_GENRE(); static const char* LBL_IMAGE(); static const char* LBL_ALBUM(); static const char* LBL_RATING(); static const char* LBL_COMPOSER(); static const char* LBL_WMP_VAR_ART(); static const char* LBL_ITUNES_VAR_ART(); static const char* LBL_TXXX(); struct InvalidIndex {}; static const char* getFrameName (int n); // throws InvalidIndex if n is out of bounds static const std::set<std::string>& getExcludeFromInfoFrames(); // frames that shouldn't be part of "other info"; doesn't include TXXX and "Various Artists" frames static const std::set<std::string>& getKnownFrames(); // includes "Various Artists" frames; doesn't include TXXX static bool canHaveDuplicates(const char* szName); // to be counted as duplicates, 2 frames must have the same name and picture type, so the value returned here is only part of the test }; #endif // ifndef Id3V2StreamH ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/ThreadRunner.ui�������������������������������������������������������������0000644�0001750�0000144�00000002533�11227440344�016217� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>ThreadRunnerDlg</class> <widget class="QDialog" name="ThreadRunnerDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>741</width> <height>99</height> </rect> </property> <property name="windowTitle" > <string>Thread Runner</string> </property> <property name="sizeGripEnabled" > <bool>true</bool> </property> <layout class="QVBoxLayout" > <item> <widget class="QLabel" name="m_pCurrentL" > <property name="text" > <string>TextLabel</string> </property> </widget> </item> <item> <layout class="QHBoxLayout" > <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QPushButton" name="m_pPauseResumeB" > <property name="text" > <string>&Pause</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pAbortB" > <property name="text" > <string>&Abort</string> </property> </widget> </item> </layout> </item> </layout> </widget> <resources/> <connections/> </ui> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/DoubleList.h����������������������������������������������������������������0000644�0001750�0000144�00000034744�11252461427�015512� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DoubleListH #define DoubleListH #include <set> #include <vector> #include <QWidget> #include "ui_DoubleListWdg.h" #include "MultiLineTvDelegate.h" class ListPainter; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== namespace DoubleListImpl { // TableModels and Delegates don't have to be public, but they must be in a header, for the Qt preprocessing to work. // ttt3 perhaps move to separate header class AvailableModel : public QAbstractTableModel { Q_OBJECT public: //std::vector<const Elem*> m_vpElems; // doesn't own the pointers const ListPainter& m_listPainter; public: AvailableModel(ListPainter& listPainter); /*override*/ int rowCount(const QModelIndex&) const { return rowCount(); } /*override*/ int columnCount(const QModelIndex&) const { return columnCount(); } /*override*/ QVariant data(const QModelIndex&, int nRole) const; int columnCount() const; int rowCount() const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; void emitLayoutChanged(); }; class SelectedModel : public QAbstractTableModel { Q_OBJECT public: //std::vector<const Elem*> m_vpElems; // doesn't own the pointers const ListPainter& m_listPainter; public: SelectedModel(ListPainter& listPainter); /*override*/ int rowCount(const QModelIndex&) const { return rowCount(); } /*override*/ int columnCount(const QModelIndex&) const { return columnCount(); } /*override*/ QVariant data(const QModelIndex&, int nRole) const; int columnCount() const; int rowCount() const; /*override*/ QVariant headerData(int nSection, Qt::Orientation eOrientation, int nRole = Qt::DisplayRole) const; QTableView* m_pTableView; // needed to retrieve column widths, which are needed for tooltips, which are no longer used but this is an example of how to do it void emitLayoutChanged(); }; //class AvailableModelDelegate : public QItemDelegate class AvailableModelDelegate : public MultiLineTvDelegate { Q_OBJECT const ListPainter& m_listPainter; public: //AvailableModelDelegate(AvailableModel* pAvailableModel, QObject* pParent) : QItemDelegate(pParent), m_pAvailableModel(pAvailableModel) {} //AvailableModelDelegate(AvailableModel* pAvailableModel, QTableView* pTableView) : MultiLineTvDelegate(pTableView), m_pAvailableModel(pAvailableModel) {} AvailableModelDelegate(ListPainter& listPainter, QTableView* pTableView) : MultiLineTvDelegate(pTableView), m_listPainter(listPainter) {} /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; //AvailableModel* m_pAvailableModel; }; class SelectedModelDelegate : public MultiLineTvDelegate { Q_OBJECT const ListPainter& m_listPainter; public: SelectedModelDelegate(ListPainter& listPainter, QTableView* pTableView) : MultiLineTvDelegate(pTableView), m_listPainter(listPainter) {} /*override*/ void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; }; } // namespace DoubleListImpl //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class ListElem { public: virtual ~ListElem() {} // virtual std::string getText(int nCol) const = 0; }; class DoubleList; //ttt2 perhaps have a "mirror" option, where available elems are on the left and selected on the right /* ListPainter has 2 related purposes: 1) it holds vectors and some other data used to describe the contents of the lists; 2) provides data needed by QAbstractTableModel and QItemDelegate to display the tables; to do this it uses the vectors described above, as well as abstract functions, which have to be implemented by derived classes; The basic idea is that there are 3 vectors: one with "elements", containing everything that is included in the lists, and two with integers, which are indexes in the vector with "elements". One of these two is used for "selected" items, while the other is for "available" ones. Depending on the settings, elements that are included in "selected" may be removed or not from "available" (this is DoubleList's business, though; ListPainter only provides the storage). Actually it's a bit more complex: 2 more vectors are used to support "restore open" and "restore default" functionality. "Restore default" is optional. To work, it needs reset() to be implemented and a param must be passed to DoubleList, telling it to show the corresponding button. If reset() is implemented, it should populate m_vpResetAll with pointers to elements and m_vSel with indices into m_vpResetAll. In most cases, reset() would only change m_vpResetAll if it is empty, because "there's only one default"; however, m_vSel should most likely be changed. Assuming DoubleList is used in a dialog window that gets closed, if reset() is implemented, the caller should check if m_vpResetAll contains elements regardless of the dialog being closed with OK or Cancel. Then it should probably transfer the information and delete the pointers in both vpOrigAll and vpResetAll (or perhaps only in one of them, based on the dialog result and m_bResultInReset). It's the caller's responsibility to provide reset() and to deal with m_vpResetAll in a compatible way. ListPainter and DoubleList don't delete any pointers from m_vpOrigAll or m_vpResetAll. It is the responsability of the class derived from ListPainter or of its users to release pointers. The reason for this is that no reasonable assumptions can be made about the lifetime of the pointers. They may have to be deleted after DoubleList is destroyed or they may have to live until the program is closed. Also, more things may have to be done besides deleting the pointers. Sometimes it makes sense to consider the fact that nothing is "selected" as meaning that everything is "selected". To make this convention obvious from a visual point of view, m_strNothingSel should be used. If its value is non-empty, when m_vSel is empty the "selected" list switches to using a single column (with no title) and a single row, containing a single data cell, whose text is m_strNothingSel (which should be something like "<<all elements>>". Of course, this is just visual. The user of the class must also make sure that the meaning of an empty m_vSel is the same as that of a m_vSel that contains all the available values. */ class ListPainter { public: typedef std::vector<const ListElem*> AllList; typedef std::vector<int> SubList; ListPainter(const std::string& strNothingSel) : m_pDoubleList(0), m_bResultInReset(false), m_strNothingSel(strNothingSel) {} virtual ~ListPainter() {} virtual int getColCount() const = 0; virtual std::string getColTitle(int nCol) const = 0; enum { ALL_LIST, SUB_LIST }; virtual void getColor(int nIndex, int nColumn, bool bSubList, QColor& bckgColor, QColor& penColor, double& dGradStart, double& dGradEnd) const = 0; // nIndex is an index in the "all" table; color is both input and output param; dGradStart and dGradEnd must be either -1 (in which case no gradient is used) or between 0 and 1, with dGradStart < dGradEnd; they are -1 when the call is made, so can be left alone virtual int getColWidth(int nCol) const = 0; // positive values are used for fixed widths, while negative ones are for "stretched" virtual int getHdrHeight() const = 0; enum TooltipKey { SELECTED_G, AVAILABLE_G, ADD_B, DELETE_B, ADD_ALL_B, DELETE_ALL_B, RESTORE_DEFAULT_B, RESTORE_OPEN_B }; virtual std::string getTooltip(TooltipKey eTooltipKey) const = 0; // !!! this must return an empty string for buttons that are removed, otherwise deallocated memory gets accessed virtual Qt::Alignment getAlignment(int nCol) const = 0; virtual void reset() = 0; // "restore default" functionality const std::string& getNothingSelStr() const { return m_strNothingSel; } const SubList& getSel() const { return m_vSel; } const SubList& getAvailable() const { return m_vAvailable; } const AllList& getAll() const { return m_bResultInReset ? m_vpResetAll : m_vpOrigAll; } protected: DoubleList* m_pDoubleList; // widget initialized with "this" as parent; deleted automatically by Qt; put here more as a convenience place to store the pointer, but it doesn't HAVE to be used (unlike the other member variables); AllList m_vpOrigAll; // the initial list with "all" elements; the derived class must initialize this; AllList m_vpResetAll; // the list with "all" elements after reset() got called; the derived class must initialize this when reset() is called; SubList m_vOrigSel; // used by on_m_pRestoreOpenB_clicked(); the derived class must initialize this; SubList m_vSel; // the "selected" elements; the derived class must initialize this; usually it's identical to m_vOrigSel at creation; // !!! note that both m_vOrigSel and m_vSel must be initialized (in a previous version m_vSel used to be copied from m_vOrigSel, but the current way is more flexible with cases when a DoubleList is created and deleted dynamically, multiple times, while its parent is alive and visible;) bool isResultInReset() const { return m_bResultInReset; } private: SubList m_vAvailable; // shouldn't be initialized in the derived class (well, it can't anyway, since it's private); DoubleList takes care of this, making it a sorted vector containing either all the numbers between 0 and "getAll().size() - 1", or only those numbers that aren't in m_vSel bool m_bResultInReset; // if m_vSel indexes m_vpResetAll or m_vpOrigAll std::string m_strNothingSel; friend class DoubleList; }; template<typename T, typename V> void getCastElem(T*& p, V& v, int i) { p = dynamic_cast<T*>(v[i]); CB_ASSERT(0 != p); } /* Widget handling a sublist of elements that are "selected" from a full list. It is quite configurable, but more options can be envisioned. Most of the data are stored in a ListPainter, which must be passed in the constructor (actually some class derived from ListPainter, which is abstract). This is mainly for convenience and clarity (some vectors could be moved to DoubleList, but some must stay in ListPainter and having them all in one place seems better). */ class DoubleList : public QWidget, private Ui::DoubleListWdg { Q_OBJECT typedef ListPainter::AllList AllList; typedef ListPainter::SubList SubList; public: enum SelectionMode { SINGLE_UNSORTABLE, SINGLE_SORTABLE, MULTIPLE }; // "SORTABLE" means "sortable by the user"; if the user can't sort the "sel" list, the elements are sorted to match the order they appear in the "all" list"; MULTIPLE is always "sortable" //ttt2 the word "Selection" is confusing in this context private: ListPainter& m_listPainter; SelectionMode m_eSelectionMode; // ttt2 perhaps add "Up" and "Down" buttons void setUpGrid(QTableView* pGrid); void resizeColumns(QTableView* pGrid); // this should be called after LayoutChanged was sent void clearSel(); void resizeRows(); void emitLayoutChanged(); void adjustOnDataChanged(); DoubleListImpl::AvailableModel m_availableModel; DoubleListImpl::SelectedModel m_selectedModel; friend class DoubleListImpl::AvailableModel; friend class DoubleListImpl::SelectedModel; friend class DoubleListImpl::AvailableModelDelegate; friend class DoubleListImpl::SelectedModelDelegate; /*override*/ void resizeEvent(QResizeEvent* pEvent); void initAvailable(); bool m_bSectionMovedLock; public: enum UsedButtons { NONE = 0x00, ADD_ALL = 0x01, DEL_ALL = 0x02, RESTORE_OPEN = 0x04, RESTORE_DEFAULT = 0x08 }; DoubleList( ListPainter& listPainter, int nButtons, // or/xor of UsedButtons SelectionMode eSelectionMode, const std::string& strAvailableLabel, const std::string& strSelLabel, QWidget* pParent, Qt::WFlags fl = 0); ~DoubleList(); void add(const std::set<int>&); // adds elements from the specified indexes void remove(const std::set<int>&); // removes elements from the specified indexes signals: void dataChanged(); void avlDoubleClicked(int nRow); protected slots: void on_m_pAddB_clicked(); void on_m_pDeleteB_clicked(); void on_m_pAddAllB_clicked(); void on_m_pDeleteAllB_clicked(); void on_m_pRestoreOpenB_clicked(); void on_m_pRestoreDefaultB_clicked(); void onSelSectionMoved(int nLogicalIndex, int nOldVisualIndex, int nNewVisualIndex); void onResizeTimer(); void onAvlDoubleClicked(const QModelIndex& index); }; #endif ����������������������������MP3Diags-1.0.12.079/src/TagReadPanel.h��������������������������������������������������������������0000644�0001750�0000144�00000004334�11260643304�015716� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <vector> #include <QFrame> #include "CommonTypes.h" struct TagReader; class QToolButton; class QLabel; class ImageInfoPanel : public QFrame { Q_OBJECT ImageInfo m_imageInfo; QToolButton* m_pBtn; QLabel* m_pInfoLabel; void createButton(int nSize); public: ImageInfoPanel(QWidget* pParent, const ImageInfo& imageInfo); void resize(int nSize); // removes the label and makes the button smaller protected slots: void onShowFull(); }; class TagReadPanel : public QFrame { Q_OBJECT QWidget* m_pImgWidget; std::vector<ImageInfoPanel*> m_vpImgPanels; public: TagReadPanel(QWidget* pParent, TagReader* pTagReader); protected slots: void onCheckSize(); }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/About.ui��������������������������������������������������������������������0000644�0001750�0000144�00000014470�11227440105�014666� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>AboutDlg</class> <widget class="QDialog" name="AboutDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>944</width> <height>563</height> </rect> </property> <property name="windowTitle" > <string>About MP3 Diags</string> </property> <property name="sizeGripEnabled" > <bool>true</bool> </property> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="widget" > <layout class="QHBoxLayout" > <item> <widget class="QLabel" name="label" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="maximumSize" > <size> <width>48</width> <height>48</height> </size> </property> <property name="text" > <string/> </property> <property name="pixmap" > <pixmap resource="Mp3Diags.qrc" >:/images/about.svg</pixmap> </property> <property name="scaledContents" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QLabel" name="m_pVersionL" > <property name="font" > <font> <pointsize>19</pointsize> <weight>75</weight> <italic>false</italic> <bold>true</bold> </font> </property> <property name="text" > <string>MP3 Diags x.y.z</string> </property> <property name="alignment" > <set>Qt::AlignCenter</set> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QTabWidget" name="tabWidget" > <property name="currentIndex" > <number>0</number> </property> <widget class="QWidget" name="tab" > <attribute name="title" > <string>About</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_2" > <layout class="QVBoxLayout" > <property name="leftMargin" > <number>10</number> </property> <property name="topMargin" > <number>20</number> </property> <property name="rightMargin" > <number>10</number> </property> <property name="bottomMargin" > <number>10</number> </property> <item> <widget class="QTextBrowser" name="m_pMainTextM" > <property name="frameShape" > <enum>QFrame::NoFrame</enum> </property> <property name="openExternalLinks" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> <widget class="QWidget" name="tab_8" > <attribute name="title" > <string>System info</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QTextBrowser" name="m_pSysInfoM" /> </item> </layout> </widget> <widget class="QWidget" name="tab_2" > <attribute name="title" > <string>GPL V2 (for the program)</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QTextBrowser" name="m_pGplV2M" /> </item> </layout> </widget> <widget class="QWidget" name="tab_4" > <attribute name="title" > <string>LGPL V3 (for the icons)</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QTextBrowser" name="m_pLgplV3M" /> </item> </layout> </widget> <widget class="QWidget" name="tab_3" > <attribute name="title" > <string>GPL V3 (for the icons)</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QTextBrowser" name="m_pGplV3M" /> </item> </layout> </widget> <widget class="QWidget" name="tab_5" > <attribute name="title" > <string>LGPL V2.1 (for Qt)</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QTextBrowser" name="m_pLgplV21M" /> </item> </layout> </widget> <widget class="QWidget" name="tab_6" > <attribute name="title" > <string>Boost license</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QTextBrowser" name="m_pBoostM" /> </item> </layout> </widget> <widget class="QWidget" name="tab_7" > <attribute name="title" > <string>zlib license</string> </attribute> <layout class="QHBoxLayout" > <item> <widget class="QTextBrowser" name="m_pZlibM" /> </item> </layout> </widget> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_3" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QPushButton" name="m_pOkB" > <property name="text" > <string>OK</string> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> </layout> </widget> <tabstops> <tabstop>m_pOkB</tabstop> </tabstops> <resources> <include location="Mp3Diags.qrc" /> </resources> <connections/> </ui> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Widgets.cpp�����������������������������������������������������������������0000644�0001750�0000144�00000030674�11265067367�015414� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <algorithm> #include <QMouseEvent> #include <QBoxLayout> #include <QPushButton> #include <QApplication> #include <QTextBrowser> #include <QCheckBox> #include <QPainter> #include "Widgets.h" #include "Helpers.h" #include "CommonData.h" using namespace std; using namespace pearl; /*override*/ void ModifInfoMenu::mousePressEvent(QMouseEvent *pEvent) { m_modif = pEvent->modifiers(); //int x (m_modif); qDebug("modif %d", x); if (pEvent->button() == Qt::RightButton) { m_modif |= Qt::ShiftModifier; } QMenu::mousePressEvent(pEvent); } ModifInfoToolButton::ModifInfoToolButton(QToolButton* pOldBtn) : QToolButton(pOldBtn->parentWidget()) { QWidget* pParent (pOldBtn->parentWidget()); QWidgetList lpSiblings (pParent->findChildren<QWidget*>()); setAutoRaise(pOldBtn->autoRaise()); setIcon(pOldBtn->icon()); setMinimumSize(pOldBtn->minimumSize()); setMaximumSize(pOldBtn->maximumSize()); setFocusPolicy(pOldBtn->focusPolicy()); setIconSize(pOldBtn->iconSize()); setToolTip(pOldBtn->toolTip()); //ttt2 set other properties QBoxLayout* pLayout (dynamic_cast<QBoxLayout*>(pParent->layout())); //ttt2 see about other layouts CB_ASSERT (0 != pLayout); int nPos (pLayout->indexOf(pOldBtn)); pLayout->insertWidget(nPos, this); //connect(this, SIGNAL(clicked()), that, SLOT(on_x_clicked())); //ttt2 would be nice to take over the signals, but doesn't seem possible delete pOldBtn; } /*override*/ void ModifInfoToolButton::mousePressEvent(QMouseEvent *pEvent) { m_modif = pEvent->modifiers(); //int x (m_modif); qDebug("modif %d", x); QToolButton::mousePressEvent(pEvent); } /*override*/ void ModifInfoToolButton::keyPressEvent(QKeyEvent* pEvent) { m_modif = pEvent->modifiers(); // ttt2 actually this never seems to get triggered; see if it's true (perhaps it matters if the button can get keyboard focus) //int x (m_modif); qDebug("modif %d", x); QToolButton::keyPressEvent(pEvent); } void ModifInfoToolButton::contextMenuEvent(QContextMenuEvent* /*pEvent*/) { //m_modif = pEvent->modifiers(); m_modif = m_modif | Qt::ShiftModifier; //emit clicked(); } int showMessage(QWidget* pParent, QMessageBox::Icon icon, int nDefault, int nEscape, const QString& qstrTitle, const QString& qstrMessage, const QString& qstrButton0, const QString& qstrButton1 /*= ""*/, const QString& qstrButton2 /*= ""*/, const QString& qstrButton3 /*= ""*/) { QStringList l; l << qstrButton0; if (!qstrButton1.isEmpty()) { l << qstrButton1; if (!qstrButton2.isEmpty()) { l << qstrButton2; if (!qstrButton3.isEmpty()) { l << qstrButton3; } } } QMessageBox msgBox (pParent); vector<QPushButton*> v; for (int i = 0; i < l.size(); ++i) { v.push_back(msgBox.addButton(l[i], QMessageBox::ActionRole)); // ActionRole is meaningless, but had to use something if (cSize(v) - 1 == nEscape) { msgBox.setEscapeButton(v.back()); } if (cSize(v) - 1 == nDefault) { msgBox.setDefaultButton(v.back()); } } msgBox.setText(qstrMessage); msgBox.setIcon(icon); msgBox.setTextFormat(Qt::PlainText); msgBox.setWindowTitle(qstrTitle); msgBox.exec(); return find(v.begin(), v.end(), msgBox.clickedButton()) - v.begin(); } CursorOverrider::CursorOverrider(Qt::CursorShape crs /*= Qt::BusyCursor*/) { QApplication::setOverrideCursor(QCursor(crs)); } CursorOverrider::~CursorOverrider() { QApplication::restoreOverrideCursor(); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== #if 0 struct ThreadLocalDlgList { virtual void addDlg(QDialog* pDlg) = 0; virtual void removeDlg(QDialog* pDlg) = 0; virtual QDialog* getDlg() = 0; }; ThreadLocalDlgList& getThreadLocalDlgList(); // a unique, global, object struct DlgRef { DlgRef(QDialog* pDlg) : m_pDlg(pDlg) { getThreadLocalDlgList().addDlg(pDlg); } ~DlgRef() { getThreadLocalDlgList().removeDlg(m_pDlg); } private: QDialog* m_pDlg; }; #endif #if 0 struct DlgList { void addDlg(QDialog* pDlg) { m_stpDlg.push(pDlg); } void removeDlg(QDialog* pDlg) { CB_ASSERT (!m_stpDlg.empty()); CB_ASSERT (m_stpDlg.top() == pDlg); m_stpDlg.pop(); } QDialog* getDlg() // may return 0 { if (m_stpDlg.empty()) { return 0; } return m_stpDlg.top(); } ~DlgList() { CB_ASSERT (m_stpDlg.empty()); //ttt 0 see if right, if called from ASSERT } private: stack<QDialog*> m_stpDlg; }; class ThreadLocalDlgListImpl : public ThreadLocalDlgList { QThreadStorage<DlgList*> m_storage; void addStorageIfNeeded() { if (!m_storage.hasLocalData()) { m_storage.setLocalData(new DlgList()); } } public: /*override*/ void addDlg(QDialog* pDlg) { addStorageIfNeeded(); m_storage.localData()->addDlg(pDlg); } /*override*/ void removeDlg(QDialog* pDlg) { addStorageIfNeeded(); m_storage.localData()->removeDlg(pDlg); } /*override*/ QDialog* getDlg() { addStorageIfNeeded(); return m_storage.localData()->getDlg(); } }; ThreadLocalDlgList& getThreadLocalDlgList() { static ThreadLocalDlgListImpl s_lst; return s_lst; } #endif /*static*/ int HtmlMsg::msg(QWidget* pParent, int nDefault, int nEscape, bool* pbGotTheMessage, int nFlags, const QString& qstrTitle, const QString& qstrMessage, int nWidth, int nHeight, const QString& qstrButton0, const QString& qstrButton1 /*= ""*/, const QString& qstrButton2 /*= ""*/, const QString& qstrButton3 /*= ""*/) { LAST_STEP("HtmlMsg::msg()"); //QDialog dlg (pParent, Qt::Dialog | getNoResizeWndFlags() | (bStayOnTop ? Qt::WindowStaysOnTopHint : Qt::WindowFlags(0))); QDialog dlg (pParent, getDialogWndFlags() | (nFlags & STAY_ON_TOP ? Qt::WindowStaysOnTopHint : Qt::WindowFlags(0))); dlg.setWindowTitle(qstrTitle); dlg.setWindowIcon(QIcon(":/images/logo.svg")); QVBoxLayout* pLayout (new QVBoxLayout(&dlg)); QTextBrowser* pContent (new QTextBrowser(&dlg)); if (nFlags & CRITICAL) { QPalette pal (pContent->palette()); pal.setColor(QPalette::Base, QColor(192, 0, 0)); pal.setColor(QPalette::Text, QColor(255, 255, 0)); pContent->setPalette(pal); QFont fnt (pContent->font()); fnt.setBold(true); pContent->setFont(fnt); } pContent->setOpenExternalLinks(true); pContent->setHtml(qstrMessage + (nFlags & SHOW_SYS_INFO ? "<hr/><p style=\"margin-bottom:1px; margin-top:8px; \">" + getSystemInfo() + "</p>" : "")); //ttt2 perhaps use CSS pLayout->addWidget(pContent); QHBoxLayout btnLayout; QCheckBox* pCheck (0); if (0 != pbGotTheMessage) { pCheck = new QCheckBox("I got the message; don't show this again", &dlg); btnLayout.addWidget(pCheck); } HtmlMsg msg (&dlg, nEscape); btnLayout.addStretch(0); QPushButton* pBtn0 (0); QPushButton* pBtn1 (0); QPushButton* pBtn2 (0); QPushButton* pBtn3 (0); pBtn0 = new QPushButton(qstrButton0, &dlg); (nFlags & VERT_BUTTONS ? (QLayout&)(*pLayout) : (QLayout&)btnLayout).addWidget(pBtn0); QObject::connect(pBtn0, SIGNAL(clicked()), &msg, SLOT(onClick0())); if (0 == nDefault) { pBtn0->setDefault(true); } if (!qstrButton1.isEmpty()) { pBtn1 = new QPushButton(qstrButton1, &dlg); (nFlags & VERT_BUTTONS ? (QLayout&)(*pLayout) : (QLayout&)btnLayout).addWidget(pBtn1); QObject::connect(pBtn1, SIGNAL(clicked()), &msg, SLOT(onClick1())); if (1 == nDefault) { pBtn1->setDefault(true); } if (!qstrButton2.isEmpty()) { pBtn2 = new QPushButton(qstrButton2, &dlg); (nFlags & VERT_BUTTONS ? (QLayout&)(*pLayout) : (QLayout&)btnLayout).addWidget(pBtn2); QObject::connect(pBtn2, SIGNAL(clicked()), &msg, SLOT(onClick2())); if (2 == nDefault) { pBtn2->setDefault(true); } if (!qstrButton3.isEmpty()) { pBtn3 = new QPushButton(qstrButton3, &dlg); (nFlags & VERT_BUTTONS ? (QLayout&)(*pLayout) : (QLayout&)btnLayout).addWidget(pBtn3); QObject::connect(pBtn3, SIGNAL(clicked()), &msg, SLOT(onClick3())); if (3 == nDefault) { pBtn3->setDefault(true); } } } } pLayout->addLayout(&btnLayout); dlg.resize(nWidth, nHeight); dlg.setSizeGripEnabled(true); dlg.exec(); LAST_STEP1("HtmlMsg::msg 2()", 1); if (0 != pbGotTheMessage) { *pbGotTheMessage = pCheck->isChecked(); } return msg.m_nBtn; } void HtmlMsg::onClick0() { m_nBtn = 0; m_pDlg->accept(); } void HtmlMsg::onClick1() { m_nBtn = 1; m_pDlg->accept(); } void HtmlMsg::onClick2() { m_nBtn = 2; m_pDlg->accept(); } void HtmlMsg::onClick3() { m_nBtn = 3; m_pDlg->accept(); } /*override*/ void NoCropHeaderView::paintSection(QPainter* pPainter, const QRect& r, int nLogicalIndex) const { /*{ QHeaderView::paintSection(pPainter, r, nLogicalIndex); return; return; }*/ pPainter->save(); // partial copy from Qt's implementation of QHeaderView (qheaderview.cpp) QStyleOptionHeader opt; initStyleOption(&opt); opt.rect = r; opt.section = nLogicalIndex; int nVisual (visualIndex(nLogicalIndex)); if (count() == 1) opt.position = QStyleOptionHeader::OnlyOneSection; else if (nVisual == 0) opt.position = QStyleOptionHeader::Beginning; else if (nVisual == count() - 1) opt.position = QStyleOptionHeader::End; else opt.position = QStyleOptionHeader::Middle; opt.selectedPosition = QStyleOptionHeader::NotAdjacent; style()->drawControl(QStyle::CE_Header, &opt, pPainter, this); pPainter->restore(); pPainter->save(); pPainter->setFont(getCommonData()->getLabelFont()); /*{ // bold for selected QModelIndexList l (getCommonData()->m_pFilesG->selectionModel()->selection().indexes()); for (QModelIndexList::iterator it = l.begin(); it != l.end(); ++it) { const QModelIndex& ndx (*it); if (ndx.column() == nLogicalIndex) { QFont f (pPainter->font()); f.setWeight(QFont::Bold); pPainter->setFont(f); break; } } }*/ QRect r1 (r); r1.adjust(0, -1, 0, -1); QString qs (model()->headerData(nLogicalIndex, Qt::Vertical).toString()); pPainter->drawText(r1, Qt::AlignCenter, qs); pPainter->restore(); } ��������������������������������������������������������������������MP3Diags-1.0.12.079/src/Debug.ui��������������������������������������������������������������������0000644�0001750�0000144�00000022100�11257651303�014636� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>DebugDlg</class> <widget class="QDialog" name="DebugDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>1005</width> <height>638</height> </rect> </property> <property name="windowTitle" > <string>Debug</string> </property> <property name="sizeGripEnabled" > <bool>true</bool> </property> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_14" > <property name="minimumSize" > <size> <width>0</width> <height>30</height> </size> </property> <layout class="QHBoxLayout" > <property name="spacing" > <number>10</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QFrame" name="frame_8" > <property name="frameShape" > <enum>QFrame::StyledPanel</enum> </property> <property name="frameShadow" > <enum>QFrame::Raised</enum> </property> <layout class="QHBoxLayout" > <property name="leftMargin" > <number>9</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QCheckBox" name="m_pEnableTracingCkB" > <property name="text" > <string>Enable tracing</string> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pSaveLogB" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="toolTip" > <string>Save trace messages</string> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/save_log.svg</iconset> </property> <property name="iconSize" > <size> <width>33</width> <height>36</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QFrame" name="frame_14" > <property name="frameShape" > <enum>QFrame::StyledPanel</enum> </property> <property name="frameShadow" > <enum>QFrame::Raised</enum> </property> <layout class="QHBoxLayout" > <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLineEdit" name="m_pFrameHdrE" > <property name="sizePolicy" > <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="maximumSize" > <size> <width>80</width> <height>16777215</height> </size> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pDecodeMpegFrameB" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="toolTip" > <string>Decode MPEG Audio frame header</string> </property> <property name="text" > <string>dec</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/decode.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QToolButton" name="m_pTst01B" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="toolTip" > <string>Test</string> </property> <property name="text" > <string>tst</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/test.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>10</width> <height>40</height> </size> </property> </spacer> </item> <item> <widget class="QWidget" native="1" name="widget" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QPushButton" name="m_pCloseB" > <property name="text" > <string>Close</string> </property> <property name="default" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> </item> <item> <widget class="QWidget" native="1" name="widget_2" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QCheckBox" name="m_pUseAllNotesCkB" > <property name="text" > <string>Use all notes</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pLogTransfCkB" > <property name="text" > <string>Log transformations</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pSaveDownloadedDataCkB" > <property name="text" > <string>Save downloaded data</string> </property> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> <item> <widget class="QLabel" name="label_6" > <property name="text" > <string>Trace messages:</string> </property> </widget> </item> <item> <widget class="QTableView" name="m_pLogG" /> </item> </layout> </widget> <resources> <include location="Mp3Diags.qrc" /> </resources> <connections/> </ui> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/FileEnum.cpp����������������������������������������������������������������0000644�0001750�0000144�00000032052�11265050316�015464� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ //#include <deque> #include <set> #include <algorithm> #include <QDir> #include "FileEnum.h" #include "OsFile.h" using namespace std; // All directory names in DirTreeEnumeratorImpl end with the path separator struct DirTreeEnumerator::DirTreeEnumeratorImpl { DirTreeEnumeratorImpl(const vector<string>& vstrIncludeDirs, const vector<string>& vstrExcludeDirs); void reset(); void reset(const vector<string>& vstrIncludeDirs, const vector<string>& vstrExcludeDirs); set<string> m_sstrIncludeDirs, m_sstrExcludeDirs; set<string> m_sstrProcDirs; // selected dirs (or their descendants) that have no ancestors in m_sstrProcDirs (for the first step they should have no ancestors in m_sstrIncludeDirs) set<string> m_sstrWaitingDirs; // selected dirs (or their descendants) that have ancestors in m_sstrProcDirs; //void getClosestAncestor(string strDir, string& strAncestor, bool& bIsChecked); enum ClosestAncestorState { NO_ANCESTOR, INCLUDED, EXCLUDED }; ClosestAncestorState getClosestAncestorState(const string& strDir) const; bool hasAncestorInProcDirs(const string& strDir) const; // "strict" ancestor, doesn't matter if the argument itself is in ProcDirs void addDirs(set<string>& s, const vector<string>& v) { for (int i = 0, n = cSize(v); i < n; ++i) { string str (v[i]); CB_ASSERT (string::npos == str.find("//")); // put to see if handling of "//" is needed; // ttt2 see also QFileInfo::absoluteFilePath(), for Windows meaning if (!endsWith(str, "/")) { str += "/"; } s.insert(str); } } vector<string> m_vstrCrtDirList; // contains files only string m_strCrtDir; // used because QFileInfo::absoluteFilePath() has a performance warning; not sure if it helps; see also QFileInfo::canonicalFilePath int m_nCrtDirNdx; // index in m_vstrCrtDirList string next(); // returns an empty string if there's nothing next bool isIncluded(const string& strFile); }; DirTreeEnumerator::~DirTreeEnumerator() { delete m_pImpl; } DirTreeEnumerator::DirTreeEnumerator(const vector<string>& vstrIncludeDirs, const vector<string>& vstrExcludeDirs) : m_pImpl(new DirTreeEnumeratorImpl(vstrIncludeDirs, vstrExcludeDirs)), m_noDefaults(0) { } DirTreeEnumerator::DirTreeEnumerator() : m_pImpl(new DirTreeEnumeratorImpl(vector<string>(), vector<string>())), m_noDefaults(0) { } void DirTreeEnumerator::reset(const vector<string>& vstrIncludeDirs, const vector<string>& vstrExcludeDirs) { m_pImpl->reset(vstrIncludeDirs, vstrExcludeDirs); } void DirTreeEnumerator::reset() { m_pImpl->reset(); } string DirTreeEnumerator::next() // returns an empty string if there's nothing next { return m_pImpl->next(); } bool DirTreeEnumerator::isIncluded(const std::string& strFile) { return m_pImpl->isIncluded(strFile); } DirTreeEnumerator::DirTreeEnumeratorImpl::DirTreeEnumeratorImpl(const vector<string>& vstrIncludeDirs, const vector<string>& vstrExcludeDirs) { reset(vstrIncludeDirs, vstrExcludeDirs); } void DirTreeEnumerator::DirTreeEnumeratorImpl::reset(const vector<string>& vstrIncludeDirs, const vector<string>& vstrExcludeDirs) { m_sstrIncludeDirs.clear(); m_sstrExcludeDirs.clear(); addDirs(m_sstrIncludeDirs, vstrIncludeDirs); addDirs(m_sstrExcludeDirs, vstrExcludeDirs); vector<string> v; set_intersection(m_sstrIncludeDirs.begin(), m_sstrIncludeDirs.end(), m_sstrExcludeDirs.begin(), m_sstrExcludeDirs.end(), back_inserter(v)); CB_CHECK1 (vstrIncludeDirs.size() + vstrExcludeDirs.size() == m_sstrIncludeDirs.size() + m_sstrExcludeDirs.size() && v.empty(), DirTreeEnumerator::InvalidDirs()); for (set<string>::iterator it = m_sstrIncludeDirs.begin(), end = m_sstrIncludeDirs.end(); it != end; ++it) { ClosestAncestorState e (getClosestAncestorState(*it)); CB_CHECK1 (NO_ANCESTOR == e || EXCLUDED == e, DirTreeEnumerator::InvalidDirs()); } for (set<string>::iterator it = m_sstrExcludeDirs.begin(), end = m_sstrExcludeDirs.end(); it != end; ++it) { ClosestAncestorState e (getClosestAncestorState(*it)); CB_CHECK1 (INCLUDED == e, DirTreeEnumerator::InvalidDirs()); } reset(); } void DirTreeEnumerator::DirTreeEnumeratorImpl::reset() { m_nCrtDirNdx = -1; } DirTreeEnumerator::DirTreeEnumeratorImpl::ClosestAncestorState DirTreeEnumerator::DirTreeEnumeratorImpl::getClosestAncestorState(const string& strDir) const { string s (strDir); //bIsChecked = false; strAncestor.clear(); if (endsWith(s, "/")) { s.erase(s.size() - 1); } // it's messier to work with an s that ends with '/', because then s=="/" is a special case for (;;) { string::size_type n (s.rfind("/")); if (string::npos == n) { return NO_ANCESTOR; } s.erase(n + 1); bool bI (m_sstrIncludeDirs.count(s) > 0); bool bE (m_sstrExcludeDirs.count(s) > 0); CB_ASSERT (!(bE && bI)); if (bI) { return INCLUDED; } if (bE) { return EXCLUDED; } s.erase(s.size() - 1); } } bool DirTreeEnumerator::DirTreeEnumeratorImpl::hasAncestorInProcDirs(const string& strDir) const // "strict" ancestor, doesn't matter if the argument itself is in ProcDirs { string s (strDir); if (endsWith(s, "/")) { s.erase(s.size() - 1); } // it's messier to work with an s that ends with '/', because then s=="/" is a special case for (;;) { string::size_type n (s.rfind("/")); if (string::npos == n) { return false; } s.erase(n + 1); if (m_sstrProcDirs.count(s) > 0) { return true; } s.erase(s.size() - 1); } } bool DirTreeEnumerator::DirTreeEnumeratorImpl::isIncluded(const string& strFile) { //return INCLUDED == getClosestAncestorState(getParent(strFile)); return INCLUDED == getClosestAncestorState(strFile); } /* Algorithm: - split m_sstrIncludeDirs in 2, putting those that have no ancestors in m_sstrProcDirs and the others in m_sstrWaitingDirs; - when next() is called: - go to the next file in the "current dir", putting all the found directories in m_sstrIncludeDirs (well, unless they are in m_sstrExcludeDirs); - if there are files left in the "current dir", return the next file; - if there are no files left in the "current dir", take the first entry from m_sstrIncludeDirs and turn it into the current dir, then move to m_sstrIncludeDirs all entries from m_sstrWaitingDirs that don't have an ancestor in m_sstrIncludeDirs - if m_sstrIncludeDirs is empty, just return ""; */ string DirTreeEnumerator::DirTreeEnumeratorImpl::next() // returns an empty string if there's nothing next { if (-1 == m_nCrtDirNdx) { m_nCrtDirNdx = 0; m_vstrCrtDirList.clear(); set<string> sstrNewProc; m_sstrWaitingDirs.clear(); m_sstrProcDirs = m_sstrIncludeDirs; // !!! needed for hasAncestorInProcDirs() for (set<string>::iterator it = m_sstrIncludeDirs.begin(), end = m_sstrIncludeDirs.end(); it != end; ++it) { if (!hasAncestorInProcDirs(*it)) { sstrNewProc.insert(*it); } else { m_sstrWaitingDirs.insert(*it); } } m_sstrProcDirs.swap(sstrNewProc); } for (;;) { if (m_nCrtDirNdx < cSize(m_vstrCrtDirList)) { return m_vstrCrtDirList[m_nCrtDirNdx++]; } if (m_sstrProcDirs.empty()) { if (m_sstrWaitingDirs.empty()) { return ""; } set<string> sstrNewProc, sstrNewWt; m_sstrProcDirs = m_sstrWaitingDirs; // !!! needed for hasAncestorInProcDirs() for (set<string>::iterator it = m_sstrWaitingDirs.begin(), end = m_sstrWaitingDirs.end(); it != end; ++it) { if (!hasAncestorInProcDirs(*it)) { sstrNewProc.insert(*it); } else { sstrNewWt.insert(*it); } } sstrNewWt.swap(m_sstrWaitingDirs); sstrNewProc.swap(m_sstrProcDirs); } m_vstrCrtDirList.clear(); m_nCrtDirNdx = 0; m_strCrtDir = *m_sstrProcDirs.begin(); m_sstrProcDirs.erase(m_sstrProcDirs.begin()); for (set<string>::iterator it = m_sstrWaitingDirs.begin(), end = m_sstrWaitingDirs.end(); it != end; ++it) { if (!hasAncestorInProcDirs(*it)) { m_sstrWaitingDirs.insert(*it); } } QDir dir (convStr(m_strCrtDir)); QFileInfoList lst (dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)); for (QFileInfoList::iterator it = lst.begin(), end = lst.end(); it != end; ++it) { const QFileInfo& inf (*it); string s (convStr(inf.fileName())); s = m_strCrtDir + s; // !!! note that inf.isSymLink() may return true in addition to isFile() or isDir() returning true, so no "special case" processing is needed unless we want to exclude symlinks if (inf.isFile()) { m_vstrCrtDirList.push_back(s); } else if (inf.isDir()) { if (!endsWith(s, "/")) { s += "/"; } if (0 == m_sstrExcludeDirs.count(s)) { m_sstrProcDirs.insert(s); } } } } } /* struct AAAlp { AAAlp() { vector<string> vIncl, vExcl; //vIncl.push_back("/r/temp/1/tmp2/a rep/a"); vIncl.push_back("/r/temp/1/tmp2/a rep/"); vExcl.push_back("/r/temp/1/tmp2/a rep/b"); DirTreeEnumerator en (vIncl, vExcl); for (;;) { string s (en.next()); if (s.empty()) { throw 1; } qDebug("%s", s.c_str()); } } }; AAAlp lprecerce; */ //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== ListEnumerator::ListEnumerator(const string& strDir) : m_noDefaults(0), m_nCrt(0) { QDir dir (convStr(strDir)); string s1 (strDir); if (!endsWith(s1, "/")) { s1 += "/"; } QFileInfoList lst (dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)); for (QFileInfoList::iterator it = lst.begin(), end = lst.end(); it != end; ++it) { const QFileInfo& inf (*it); string s (convStr(inf.fileName())); s = s1 + s; // !!! note that inf.isSymLink() may return true in addition to isFile() or isDir() returning true, so no "special case" processing is needed unless we want to exclude symlinks if (inf.isFile()) { m_vstrFiles.push_back(s); } } } ListEnumerator::ListEnumerator(const std::vector<std::string>& vstrFiles) : m_noDefaults(0), m_vstrFiles(vstrFiles), m_nCrt(0) { } // returns an empty string if there's nothing next /*override*/ std::string ListEnumerator::next() { if (m_nCrt >= cSize(m_vstrFiles)) { return ""; } return m_vstrFiles[m_nCrt++]; } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Transformation.h������������������������������������������������������������0000644�0001750�0000144�00000052062�11271362664�016447� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TransformationH #define TransformationH #include <string> /* Processing a file by MainFormDlgImpl: There is a list of Transformation instances. Their apply() functions get called, creating a new file from an existing one each time they return "true", until all of them return "false". There is a "source root folder", where all the original files come from. Not all the files inside that folder and its subdirectories are going to be processed; some filtering may be used. It may be "/", but care should be taken to not try to process files from m_strTempRootDir, m_strProcRootDir or m_strCompRootDir. Various Transformation instances get called. If they decide that they will modify the file, they call TransfConfig::getTempName() (which uses m_strTempRootDir) to get the name of the file where they should put their result. The next Transformation to get called will receive an Mp3Handler for this, just created file, along with the name of the original file. After a Transformation::apply() returns "true", the list with Transformation gets called from the beginning, until every element in the list return "false". After that, the last file that got created is moved to the "destination folder", determined by m_strProcRootDir. It may be the same as m_strSrcRootDir, in which case the original file is moved to the corresponding place in m_strTempRootDir. Based on settings, the original and/or all the intermediate files may be deleted. There may also be "comparison" files, which are meant for cases like this: Some bits are modified inside an audio stream, now the file "looks" ok, but we want to see the impact this had on the audio. So the affected frames and several frames before and after them are saved in 2 "comp" files, "before" and "after", so they can be listened to in a separate app. The get<...>Name() functions derive a name from the original name, the purpose of the folder, and a counter, such that it is located in the appropriate folder and there is no name conflict with an existing file. Example 1: source: /media/mp3/new/ dest: /tests/audio/ proc: /tests/proc/ comp: /tests/tmp/ orig. name: /media/mp3/new/pop/act_two.mp3 proc: /tests/proc/pop/act_two.proc.001.mp3 comp: /tests/tmp/pop/act_two.tmp.before.003.mp3 and /tests/tmp/pop/act_two.tmp.after.003.mp3 Example 2: source: /media/mp3/new/ dest: /media/mp3/new/ proc: /tests/proc/ comp: /tests/tmp/ orig. name: /media/mp3/new/pop/act_two.mp3 proc: /tests/proc/pop/act_two.proc.001.mp3 comp: /tests/tmp/pop/act_two.tmp.before.003.mp3 and /tests/tmp/pop/act_two.tmp.after.003.mp3 backup: /tests/proc/pop/act_two.mp3 (or /tests/proc/pop/act_two.orig.002.mp3) It's better for the directories to not overlap, but this is not enforced, as there may be valid reasons to use a folder for multiple purposes. One thing that should be avoided is to end up with comp or intermediate files in the same folder as source files. Folder names must not end with the path separator character ("/" or "\"), or an IncorrectDirName is thrown (defined in OsFile.h). Note: getTempName() and getCompNames() create the directories, if needed, so files can be created using the returned names. Note: all file names are absolute. //ttt2 more options to change what getBackupName() and getDestName() return and some other things: 1) the name can be the original one or changed; 2) the orig file may be left where it is, moved or deleted 3) the dest file may be left where it is (in temp), moved to src, moved to dest, or perhaps even deleted (so only the "comp" files are left, for comparison) 4) the comp and proc file may be left or removed; if they get deleted, it's probably better to not create a tree structure for directories 5) perhaps "flatten" file names: "/tests/tmp/pop/JoQ/act_two.tmp.before.003.mp3" -> /tests/tmp/pop - JoQ - act_two.tmp.before.003.mp3" */ class TransfConfig { //bool m_bRename std::string m_strSrcDir; // all scanned files are supposed to be here; // 2009.04.08 - for now it seems better to force this to be empty, by not allowing it to be edited // ttt2 perhaps put back, or calculate it from a session's folders in saveTransfConfig(), but seems likely to create confusion; can be edited manually in the config file to see what it does (or by commenting out "m_pSourceDirF->hide()") std::string m_strProcOrigDir; std::string m_strUnprocOrigDir; std::string m_strProcessedDir; std::string m_strTempDir; std::string m_strCompDir; // bit mapping: // //---------------------------- // // 0-2: 000 = don't change processed orig file // 001 = erase processed orig file // 010 = move processed orig file to m_strProcOrigDir; always rename // 011 = move processed orig file to m_strProcOrigDir; rename only if name is in use // 100 = rename in the same dir // 101 = move w/o renaming, if doesn't exist; discard if it exists; (so there's only 1 orig) // ??? move w/ renaming, if doesn't exist // 3: 0 = don't use identifying label when renaming proc orig // 1 = use identifying label when renaming proc orig // 4: 0 = use counter if name is in use when renaming proc orig // 1 = always use counter when renaming proc orig // //---------------------------- // // 5-7: 000 = don't change unprocessed orig file // 001 = erase unprocessed orig file // 010 = move unprocessed orig file to m_strUnprocOrigDir; always rename // 011 = move unprocessed orig file to m_strUnprocOrigDir; rename only if name is in use // 100 = rename in the same dir // 8: 0 = don't use identifying label when renaming unproc orig // 1 = use identifying label when renaming unproc orig // 9: 0 = use counter if name is in use when renaming unproc orig // 1 = always use counter when renaming unproc orig // //---------------------------- // // 10-11: 00 = don't create proc files // 01 = create proc files and always rename // 10 = create proc files and rename if the name is in use // 12: 0 = don't use identifying label when renaming proc // 1 = use identifying label when renaming proc // 13: 0 = use counter if name is in use when renaming proc // 1 = always use counter when renaming proc // 14: 0 = use the source dir as destination for proc files // 1 = use m_strProcessedDir as destination for proc files // //---------------------------- // // 15: 0 = don't create temp files // 1 = create temp files in m_strTempDir // //---------------------------- // // 16: 0 = don't create comp files // 1 = create comp files in m_strCompDir // //---------------------------- // // 17: 0 = keep orig time // 1 = don't keep orig time // /*int m_nOptions; int getOpt(int nStartBit, int nCount) const { return (m_nOptions >> nStartBit) & ((1 << nCount) - 1); }*/ void splitOrigName(const std::string& strOrigSrcName, std::string& strRelDir, std::string& strBaseName, std::string& strExt) const; // last '/' goes to dir; last '.' goes to ext (if extension present) enum { USE_COUNTER_IF_NEEDED, ALWAYS_USE_COUNTER }; enum { RENAME_IF_NEEDED, ALWAYS_RENAME }; enum { DONT_ALLOW_DUPLICATES, ALLOW_DUPLICATES }; static std::string addLabelAndCounter(const std::string& s1, const std::string& s2, const std::string& strLabel, bool bAlwaysUseCounter, bool bAlwaysRename); // adds a counter and/or a label, such that a file with the resulting name doesn't exist; // normally makes sure that the name returned doesn't exist, by applying any renaming specified in the params; there's an exception, though: is bAllowDup is true, duplicates are allowed std::string getRenamedName(const std::string& strOrigSrcName, const std::string& strNewRootDir, const std::string& strLabel, bool bAlwayUseCounter, bool bAlwaysRename, bool bAllowDup = false) const; public: TransfConfig( const std::string& strSrcDir, const std::string& strProcOrigDir, const std::string& strUnprocOrigDir, const std::string& strProcessedDir, const std::string& strTempDir, const std::string& strCompDir, int nOptions // may be -1 to indicate "default" values ); TransfConfig(); class Options { public: enum ProcOrig { PO_DONT_CHG, PO_ERASE, PO_MOVE_ALWAYS_RENAME, PO_MOVE_RENAME_IF_USED, PO_RENAME_SAME_DIR, PO_MOVE_OR_ERASE }; enum UnprocOrig { UPO_DONT_CHG, UPO_ERASE, UPO_MOVE_ALWAYS_RENAME, UPO_MOVE_RENAME_IF_USED, UPO_RENAME_SAME_DIR }; // !!! the values in UnprocOrig must match those in ProcOrig for getChangedOrigNameHlp() to work correctly enum Processed { PR_DONT_CREATE, PR_CREATE_ALWAYS_RENAME, PR_CREATE_RENAME_IF_USED }; private: static unsigned uns(bool b) { return b ? 1 : 0; } static unsigned uns(unsigned x) { return x; } static unsigned uns(ProcOrig x) { return x; } static unsigned uns(UnprocOrig x) { return x; } static unsigned uns(Processed x) { return x; } public: Options(); // initializes the fields to a "non-backup" state ProcOrig m_eProcOrigChange : 4; // !!! really "3", but declares more bits than used to avoid issues with signed/unsigned enums bool m_bProcOrigUseLabel : 1; bool m_bProcOrigAlwayUseCounter : 1; UnprocOrig m_eUnprocOrigChange : 4; // !!! really "3", but declares more bits than used to avoid issues with signed/unsigned enums bool m_bUnprocOrigUseLabel : 1; bool m_bUnprocOrigAlwayUseCounter : 1; Processed m_eProcessedCreate : 3; // !!! really "2", but declares more bits than used to avoid issues with signed/unsigned enums bool m_bProcessedUseLabel : 1; bool m_bProcessedAlwayUseCounter : 1; bool m_bProcessedUseSeparateDir : 1; bool m_bTempCreate : 1; bool m_bCompCreate : 1; bool m_bKeepOrigTime : 1; int getVal() const { unsigned x (0); unsigned s (0); x ^= (uns(m_eProcOrigChange) << s); s += 3; // unsigned m_nProcOrigChange : 3; x ^= (uns(m_bProcOrigUseLabel) << s); s += 1; // bool m_bProcOrigUseLabel : 1; x ^= (uns(m_bProcOrigAlwayUseCounter) << s); s += 1; // bool m_bProcOrigAlwayUseCounter : 1; x ^= (uns(m_eUnprocOrigChange) << s); s += 3; // unsigned m_nUnprocOrigChange : 3; x ^= (uns(m_bUnprocOrigUseLabel) << s); s += 1; // bool m_bUnprocOrigUseLabel : 1; x ^= (uns(m_bUnprocOrigAlwayUseCounter) << s); s += 1; // bool m_bUnprocOrigAlwayUseCounter : 1; x ^= (uns(m_eProcessedCreate) << s); s += 2; // unsigned m_nProcessedCreate : 2; x ^= (uns(m_bProcessedUseLabel) << s); s += 1; // bool m_bProcessedUseLabel : 1; x ^= (uns(m_bProcessedAlwayUseCounter) << s); s += 1; // bool m_bProcessedAlwayUseCounter : 1; x ^= (uns(m_bProcessedUseSeparateDir) << s); s += 1; // bool m_bProcessedUseSeparateDir : 1; x ^= (uns(m_bTempCreate) << s); s += 1; // bool m_bTempCreate : 1; x ^= (uns(m_bCompCreate) << s); s += 1; // bool m_bCompCreate : 1; x ^= (uns(m_bKeepOrigTime) << s); s += 1; // bool m_bKeepOrigTime : 1; return int(x); } void setVal(int x) { m_eProcOrigChange = ProcOrig(x & 0x07); x >>= 3; // unsigned m_nProcOrigChange : 3; m_bProcOrigUseLabel = x & 0x01; x >>= 1; // bool m_bProcOrigUseLabel : 1; m_bProcOrigAlwayUseCounter = x & 0x01; x >>= 1; // bool m_bProcOrigAlwayUseCounter : 1; m_eUnprocOrigChange = UnprocOrig(x & 0x07); x >>= 3; // unsigned m_nUnprocOrigChange : 3; m_bUnprocOrigUseLabel = x & 0x01; x >>= 1; // bool m_bUnprocOrigUseLabel : 1; m_bUnprocOrigAlwayUseCounter = x & 0x01; x >>= 1; // bool m_bUnprocOrigAlwayUseCounter : 1; m_eProcessedCreate = Processed(x & 0x03); x >>= 2; // unsigned m_nProcessedCreate : 2; m_bProcessedUseLabel = x & 0x01; x >>= 1; // bool m_bProcessedUseLabel : 1; m_bProcessedAlwayUseCounter = x & 0x01; x >>= 1; // bool m_bProcessedAlwayUseCounter : 1; m_bProcessedUseSeparateDir = x & 0x01; x >>= 1; // bool m_bProcessedUseSeparateDir : 1; m_bTempCreate = x & 0x01; x >>= 1; // bool m_bTempCreate : 1; m_bCompCreate = x & 0x01; x >>= 1; // bool m_bCompCreate : 1; m_bKeepOrigTime = x & 0x01; x >>= 1; // bool m_bKeepOrigTime : 1; } bool operator==(const Options& opt) const { return getVal() == opt.getVal(); } // backup is 3-state; based on various fields, options may be "backup", "non-backup", or neither of them Options asBackup() const; // returns *this, with some fields changed to match a "backup" configuration; touches many field, but ignores others (m_bProcOrigUseLabel, m_bProcOrigAlwayUseCounter, m_bUnprocOrigUseLabel, m_bUnprocOrigAlwayUseCounter, m_bKeepOrigTime) Options asNonBackup() const; // returns *this, with some fields changed to match a "non-backup" configuration; touches many field, but ignores others (m_bProcOrigUseLabel, m_bProcOrigAlwayUseCounter, m_bUnprocOrigUseLabel, m_bUnprocOrigAlwayUseCounter, m_bKeepOrigTime) }; Options m_options; /* // the name for an "intermediate" file; it's obtained from the "temp dir" and from the short name of the original file, with a ".temp.<NNN>" inserted before the extension, where <NNN> is a number chosen such that a file with this new name doesn't exist; std::string getTempName(const std::string& strOrigSrcName, const std::string& strOpName) const; // the names for a pair of "compare", "before and after", files; they are obtained from the "comp dir" and from the short name of the original file, with ".before.<NNN>" / ".after.<NNN>" inserted before the extension, where <NNN> is a number chosen such that files with the new names don't exist; void getCompNames(const std::string& strOrigSrcName, const std::string& strOpName, std::string& strBefore, std::string& strAfter) const; // to what an original file should be renamed, if it was "processed"; // if m_strSrcRootDir and m_strProcRootDir are different, it returns ""; (the original file doesn't get touched); // if m_strSrcRootDir and m_strProcRootDir are equal, it returns a name based on the original, with an ".orig.<NNN>" inserted before the extension, where <NNN> is a number chosen such that a file with this new name doesn't exist; std::string getBackupName(const std::string& strOrigSrcName) const; // to what the last "processed" file should be renamed; // if m_strSrcRootDir and m_strProcRootDir are different, it returns strOrigSrcName, moved to m_strProcRootDir; // if m_strSrcRootDir and m_strProcRootDir are equal, it returns strOrigSrcName; // if the name that it would return already exists, it inserts a ".Proc.<NNN>" such that a file with this new name doesn't exist; (so if m_strSrcRootDir and m_strProcRootDir are equal, the original file should be renamed before calling this) std::string getProcName(const std::string& strOrigSrcName) const; */ enum OrigFile { ORIG_DONT_CHANGE, ORIG_ERASE, ORIG_MOVE, ORIG_MOVE_OR_ERASE }; enum TransfFile { TRANSF_DONT_CREATE, TRANSF_CREATE }; OrigFile getProcOrigAction() const; OrigFile getUnprocOrigAction() const; TransfFile getProcessedAction() const; TransfFile getTempAction() const; TransfFile getCompAction() const; OrigFile getProcOrigName(std::string strOrigSrcName, std::string& strNewName) const; OrigFile getUnprocOrigName(std::string strOrigSrcName, std::string& strNewName) const; TransfFile getProcessedName(std::string strOrigSrcName, std::string& strName) const; TransfFile getTempName(std::string strOrigSrcName, const std::string& strOpName, std::string& strName) const; TransfFile getCompNames(std::string strOrigSrcName, const std::string& strOpName, std::string& strBefore, std::string& strAfter) const; //these are needed for saving the configuration const std::string& getSrcDir() const { return m_strSrcDir; } const std::string& getProcOrigDir() const { return m_strProcOrigDir; } const std::string& getUnprocOrigDir() const { return m_strUnprocOrigDir; } const std::string& getProcessedDir() const { return m_strProcessedDir; } const std::string& getTempDir() const { return m_strTempDir; } const std::string& getCompDir() const { return m_strCompDir; } void setProcOrigDir(const std::string& s) { m_strProcOrigDir = s; } // needed by the session dialog //ttt2 perhaps some checks int getOptions() const { return m_options.getVal(); } bool hadInitError() const { return m_bInitError; } //struct DirOverlap {}; //struct InvalidName {}; // something is wrong with the file name struct IncorrectPath {}; // thrown if a "source file" is outside of the "source folder" (takes care of this case too, where it's not enough to check for a substring: src="/tst/dir1", origName="/tst/dir10/file1.mp3") void testRemoveSuffix() const; private: OrigFile getChangedOrigNameHlp(const std::string& strOrigSrcName, const std::string& strDestDir, int nChange, bool bUseLabel, bool bAlwayUseCounter, std::string& strNewName) const; // !!! nChange will get initialized from either ProcOrig or UnprocOrig, so their values must match void removeSuffix(std::string& s) const; bool m_bInitError; }; class Mp3Handler; class Transformation { public: virtual ~Transformation() {} enum Result { NOT_CHANGED, CHANGED, CHANGED_NO_RECALL }; /*struct Result {}; static Result NOT_CHANGED; static Result CHANGED; static Result CHANGED_NO_RECALL;*/ virtual Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName) = 0; // this may throw virtual const char* getActionName() const = 0; // should return the same thing for all objects of a class, as this is used in string comparisons in several places (visible transformations, custom transformation lists, ...) virtual const char* getVisibleActionName() const { return getActionName(); } // to be used only by the UI, providing more details to the user virtual const char* getDescription() const = 0; virtual bool acceptsFastSave() const { return false; } // whether to consider Mp3Handler::m_nFastSaveTime as a match when deciding if a file was changed (so a transformation can't be applied) struct InvalidInputFile {}; // thrown if the input file was changed so it can no longer be processed }; class IdentityTransformation : public Transformation { public: /*override*/ Result apply(const Mp3Handler&, const TransfConfig&, const std::string& strOrigSrcName, std::string& strTempName); /*override*/ const char* getActionName() const { return getClassName(); } /*override*/ const char* getDescription() const { return "Doesn't actually change the file, but it creates a temporary copy and it reports that it does change it. This is not as meaningless as it might first seem: if the configuration settings indicate some action (i.e. rename, move or erase) to be taken for processed files, then that action will be performed for these files. While the same can be achieved by changing the settings for unprocessed files, this is easier to use when it is executed on a subset of all the files (filtered or selected)."; } static const char* getClassName() { return "No change"; } }; #endif // #ifndef TransformationH ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/DoubleList.cpp��������������������������������������������������������������0000644�0001750�0000144�00000060222�11252461427�016033� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <algorithm> #include <QPainter> #include <QTimer> #include <QHeaderView> #include "DoubleList.h" #include "Helpers.h" #include "CommonData.h" using namespace std; using namespace DoubleListImpl; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== AvailableModel::AvailableModel(ListPainter& listPainter) : m_listPainter(listPainter) { } int AvailableModel::rowCount() const { int n (cSize(m_listPainter.getAvailable())); return n; } int AvailableModel::columnCount() const { return m_listPainter.getColCount(); } /*override*/ QVariant AvailableModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("AvailableModel::data()"); if (!index.isValid()) { return QVariant(); } if (nRole != Qt::DisplayRole) { return QVariant(); } int nRow (index.row()); int nAllIndex (m_listPainter.getAvailable()[nRow]); return convStr(m_listPainter.getAll()[nAllIndex]->getText(index.column())); } /*override*/ QVariant AvailableModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("AvailableModel::headerData"); if (nRole == Qt::SizeHintRole) { return getNumVertHdrSize(cSize(m_listPainter.getAvailable()), eOrientation); } if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { return convStr(m_listPainter.getColTitle(nSection)); } return nSection + 1; } void AvailableModel::emitLayoutChanged() { emit layoutChanged(); } //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- /*override*/ void AvailableModelDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { pPainter->save(); //pPainter->fillRect(option.rect, QBrush(m_listPainter.getColor(m_listPainter.getAvailable()[index.row()], index.column(), pPainter->background().color()))); //ttt2 make sure background() is the option to use QColor bckgCol (pPainter->background().color()); QColor penCol (pPainter->pen().color()); double dGradStart (-1), dGradEnd (-1); m_listPainter.getColor(m_listPainter.getAvailable()[index.row()], index.column(), ListPainter::ALL_LIST, bckgCol, penCol, dGradStart, dGradEnd); QLinearGradient grad (0, option.rect.y(), 0, option.rect.y() + option.rect.height()); configureGradient(grad, bckgCol, dGradStart, dGradEnd); pPainter->fillRect(option.rect, grad); QStyleOptionViewItemV2 myOption (option); myOption.displayAlignment = m_listPainter.getAlignment(index.column()); myOption.palette.setColor(QPalette::Text, penCol); QItemDelegate::paint(pPainter, myOption, index); pPainter->restore(); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== SelectedModel::SelectedModel(ListPainter& listPainter) : m_listPainter(listPainter) { } int SelectedModel::rowCount() const { int n (cSize(m_listPainter.getSel())); if (0 == n && !m_listPainter.getNothingSelStr().empty()) { return 1; } return n; } int SelectedModel::columnCount() const { if (m_listPainter.getSel().empty() && !m_listPainter.getNothingSelStr().empty()) { return 1; } return m_listPainter.getColCount(); } /*override*/ QVariant SelectedModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("SelectedModel::data()"); if (!index.isValid()) { return QVariant(); } if (nRole != Qt::DisplayRole && nRole != Qt::ToolTipRole) { return QVariant(); } int nRow (index.row()); QString qstrRes; if (m_listPainter.getSel().empty()) { CB_ASSERT(0 == nRow); //qstrRes = 0 == index.column() ? "" : "<all notes>"; qstrRes = convStr(m_listPainter.getNothingSelStr()); // !!! in this case there's only 1 column } else { int nAllIndex (m_listPainter.getSel()[nRow]); qstrRes = convStr(m_listPainter.getAll()[nAllIndex]->getText(index.column())); } if (nRole == Qt::ToolTipRole) { #if 0 // works but tooltip is no longer needed here //QFontMetrics fm (QApplication::fontMetrics()); QFontMetrics fm (m_pTableView->fontMetrics()); // !!! no need to use "QApplication::fontMetrics()", because m_pTableView is needed anyway to get the column widths int nWidth (fm.width(qstrRes)); if (nWidth + 10 < m_pTableView->horizontalHeader()->sectionSize(index.column())) // ttt2 "10" is hard-coded { return QVariant(); }//*/ #else return QVariant(); #endif } return qstrRes; } /*override*/ QVariant SelectedModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("SelectedModel::headerData"); if (nRole == Qt::SizeHintRole) { return getNumVertHdrSize(cSize(m_listPainter.getSel()), eOrientation); } if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { if (m_listPainter.getSel().empty() && !m_listPainter.getNothingSelStr().empty()) { return ""; } return convStr(m_listPainter.getColTitle(nSection)); } if (m_listPainter.getSel().empty()) { return ""; } return nSection + 1; } void SelectedModel::emitLayoutChanged() { emit layoutChanged(); } //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- /*override*/ void SelectedModelDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (m_listPainter.getSel().empty()) { QItemDelegate::paint(pPainter, option, index); return; } pPainter->save(); //int nRow (index.row()); //int nCol (index.column()); //const Note* pNote (m_pSelectedModel->m_vpNotes[nRow]); /* // first approach; works, but it's more complicated QStyleOptionViewItemV2 myOption (option); if (0 == index.column()) { myOption.displayAlignment |= Qt::AlignHCenter; } pPainter->fillRect(myOption.rect, QBrush(noteColor(*pNote))); QString qstrText (index.model()->data(index, Qt::DisplayRole).toString()); drawDisplay(pPainter, myOption, myOption.rect, qstrText); drawFocus(pPainter, myOption, myOption.rect);*/ // second approach //pPainter->fillRect(option.rect, QBrush(m_listPainter.getColor(m_listPainter.getSel()[nRow], nCol, option.palette.color(QPalette::Active, QPalette::Base)))); //ttt3 " Active" not right if the window is inactive QColor bckgCol (option.palette.color(QPalette::Active, QPalette::Base)); //ttt3 compare to avl, where it's "QColor bckgCol (pPainter->background().color());" see why // 2009.07.15 - probably "option..." is better; the other one relies on the painter to be initialized to what's in option, but not sure that is required; so penCol is not quite right as well; however, the painter probably comes initialized correctly QColor penCol (pPainter->pen().color()); double dGradStart (-1), dGradEnd (-1); m_listPainter.getColor(m_listPainter.getSel()[index.row()], index.column(), ListPainter::SUB_LIST, bckgCol, penCol, dGradStart, dGradEnd); QLinearGradient grad (0, option.rect.y(), 0, option.rect.y() + option.rect.height()); configureGradient(grad, bckgCol, dGradStart, dGradEnd); pPainter->fillRect(option.rect, grad); QStyleOptionViewItemV2 myOption (option); myOption.displayAlignment = m_listPainter.getAlignment(index.column()); myOption.palette.setColor(QPalette::Text, penCol); QItemDelegate::paint(pPainter, myOption, index); pPainter->restore(); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== //#include <iostream> DoubleList::DoubleList( ListPainter& listPainter, int nButtons, //bool bAllowMultipleSel, //bool bUserSortSel, SelectionMode eSelectionMode, const std::string& strAvailableLabel, const std::string& strSelLabel, QWidget* pParent, Qt::WFlags fl /*=0*/) : QWidget(pParent, fl), Ui::DoubleListWdg(), m_listPainter(listPainter), //m_bAllowMultipleSel(bAllowMultipleSel), //m_bUserSortSel(bUserSortSel), m_eSelectionMode(eSelectionMode), m_availableModel(listPainter), m_selectedModel(listPainter), m_bSectionMovedLock(false) { setupUi(this); //printContainer(listPainter.m_vOrigSel, cout); if (SINGLE_UNSORTABLE == eSelectionMode) { for (int i = 0, n = cSize(listPainter.m_vOrigSel); i < n - 1; ++i) { CB_ASSERT(listPainter.m_vOrigSel[i] < listPainter.m_vOrigSel[i + 1]); } } m_pAvailableL->setText(convStr(strAvailableLabel)); m_pSelL->setText(convStr(strSelLabel)); if (0 == (nButtons & ADD_ALL)) { delete m_pAddAllB; } if (0 == (nButtons & DEL_ALL)) { delete m_pDeleteAllB; } if (0 == (nButtons & RESTORE_OPEN)) { delete m_pRestoreOpenB; } if (0 == (nButtons & RESTORE_DEFAULT)) { delete m_pRestoreDefaultB; } //m_listPainter.m_vSel = m_listPainter.m_vOrigSel; initAvailable(); m_pAvailableG->setModel(&m_availableModel); m_pSelectedG->setModel(&m_selectedModel); AvailableModelDelegate* pAvDel = new AvailableModelDelegate(m_listPainter, m_pAvailableG); m_pAvailableG->setItemDelegate(pAvDel); SelectedModelDelegate* pSelDel = new SelectedModelDelegate(m_listPainter, m_pSelectedG); m_pSelectedG->setItemDelegate(pSelDel); setUpGrid(m_pAvailableG); setUpGrid(m_pSelectedG); { string s; s = m_listPainter.getTooltip(ListPainter::SELECTED_G); if (!s.empty()) { m_pSelectedG->setToolTip(convStr(s)); } s = m_listPainter.getTooltip(ListPainter::AVAILABLE_G); if (!s.empty()) { m_pAvailableG->setToolTip(convStr(s)); } s = m_listPainter.getTooltip(ListPainter::ADD_B); if (!s.empty()) { m_pAddB->setToolTip(convStr(s)); } s = m_listPainter.getTooltip(ListPainter::DELETE_B); if (!s.empty()) { m_pDeleteB->setToolTip(convStr(s)); } s = m_listPainter.getTooltip(ListPainter::ADD_ALL_B); if (!s.empty()) { m_pAddAllB->setToolTip(convStr(s)); } s = m_listPainter.getTooltip(ListPainter::DELETE_ALL_B); if (!s.empty()) { m_pDeleteAllB->setToolTip(convStr(s)); } s = m_listPainter.getTooltip(ListPainter::RESTORE_DEFAULT_B); if (!s.empty()) { m_pRestoreDefaultB->setToolTip(convStr(s)); } s = m_listPainter.getTooltip(ListPainter::RESTORE_OPEN_B); if (!s.empty()) { m_pRestoreOpenB->setToolTip(convStr(s)); } } if (SINGLE_UNSORTABLE != m_eSelectionMode) { m_pSelectedG->verticalHeader()->setMovable(true); } connect(m_pSelectedG->verticalHeader(), SIGNAL(sectionMoved(int, int, int)), this, SLOT(onSelSectionMoved(int, int, int))); connect(m_pAvailableG, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onAvlDoubleClicked(const QModelIndex&))); //ttt2 perhaps use QAction::shortcutContext(Qt::WidgetShortcut) to set up shortcuts, if it works well enough } DoubleList::~DoubleList() { } void DoubleList::onSelSectionMoved(int /*nLogicalIndex*/, int nOldVisualIndex, int nNewVisualIndex) { CB_ASSERT(SINGLE_SORTABLE == m_eSelectionMode || MULTIPLE == m_eSelectionMode); NonblockingGuard sectionMovedGuard (m_bSectionMovedLock); if (!sectionMovedGuard) { return; } //m_pSelectedG->verticalHeader()->headerDataChanged(Qt::Vertical, 0, 4); m_pSelectedG->verticalHeader()->moveSection(nNewVisualIndex, nOldVisualIndex); SubList& vSel (m_listPainter.m_vSel); int x (vSel[nOldVisualIndex]); vSel.erase(vSel.begin() + nOldVisualIndex); vSel.insert(vSel.begin() + nNewVisualIndex, x); adjustOnDataChanged(); } void DoubleList::initAvailable() { m_listPainter.m_vAvailable.clear(); switch (m_eSelectionMode) { case MULTIPLE: for (int i = 0, n = cSize(m_listPainter.getAll()); i < n; ++i) { m_listPainter.m_vAvailable.push_back(i); // in a sense, m_listPainter.m_vAvailable shouldn't be used at all in this case, and it isn't in the DoubleList code; however, it makes AvailableModel easier, because while DoubleList always has to check the value of m_eSelectionMode anyway, AvailableModel doesn't have to do this, but an empty m_listPainter.m_vAvailable in the MULTIPLE case would force it to do so; } break; case SINGLE_UNSORTABLE: { int n (cSize(m_listPainter.getAll())); m_listPainter.m_vSel.push_back(n); for (int i = 0, j = 0; i < n; ++i) { if (i < m_listPainter.m_vSel[j]) { m_listPainter.m_vAvailable.push_back(i); } else { ++j; } } m_listPainter.m_vSel.pop_back(); } break; case SINGLE_SORTABLE: { SubList v (m_listPainter.m_vSel.begin(), m_listPainter.m_vSel.end()); sort(v.begin(), v.end()); int n (cSize(m_listPainter.getAll())); v.push_back(n); for (int i = 0, j = 0; i < n; ++i) { if (i < v[j]) { m_listPainter.m_vAvailable.push_back(i); } else { ++j; } } } break; } } void DoubleList::setUpGrid(QTableView* pGrid) { pGrid->verticalHeader()->setMinimumSectionSize(m_listPainter.getHdrHeight()); pGrid->verticalHeader()->setDefaultSectionSize(m_listPainter.getHdrHeight()); pGrid->verticalHeader()->setResizeMode(QHeaderView::Interactive); pGrid->verticalHeader()->setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter); resizeColumns(pGrid); } void DoubleList::resizeColumns(QTableView* pGrid) { if (1 == pGrid->horizontalHeader()->count()) { pGrid->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); } else { for (int i = 0, n = m_listPainter.getColCount(); i < n; ++i) { int w (m_listPainter.getColWidth(i)); if (w >= 0) { pGrid->horizontalHeader()->setResizeMode(i, QHeaderView::Interactive); pGrid->horizontalHeader()->resizeSection(i, w); } else { pGrid->horizontalHeader()->setResizeMode(i, QHeaderView::Stretch); } } } } void DoubleList::clearSel() { m_pSelectedG->selectionModel()->clear(); m_pAvailableG->selectionModel()->clear(); } void DoubleList::resizeRows() { m_pAvailableG->resizeRowsToContents(); m_pSelectedG->resizeRowsToContents(); } void DoubleList::emitLayoutChanged() { m_availableModel.emitLayoutChanged(); m_selectedModel.emitLayoutChanged(); } void DoubleList::adjustOnDataChanged() { emitLayoutChanged(); resizeColumns(m_pSelectedG); // ttt2 too much: this should only be done when switching between 1 and multiple columns; and even then, going from 1 to many, it should use the "previous" column widths, rather than the "default" ones resizeRows(); clearSel(); emit dataChanged(); } void DoubleList::on_m_pAddB_clicked() { QItemSelectionModel* pSelMdl (m_pAvailableG->selectionModel()); QModelIndexList lSel (pSelMdl->selection().indexes()); set<int> sSelPos; // the rows must be sorted for (QModelIndexList::iterator it = lSel.begin(), end = lSel.end(); it != end; ++it) { int nRow (it->row()); CB_ASSERT (nRow >= 0); sSelPos.insert(nRow); } add(sSelPos); } void DoubleList::add(const std::set<int>& sSelPos) // adds elements from the specified indexes { switch (m_eSelectionMode) { case SINGLE_UNSORTABLE: for (set<int>::const_reverse_iterator it = sSelPos.rbegin(), end = sSelPos.rend(); it != end; ++it) // the last must be processed first, so removal of elements doesn't change the row number for the remaining ones { int nRow (*it); int nIndex (m_listPainter.m_vAvailable[nRow]); vector<int>::iterator it1 (lower_bound(m_listPainter.m_vSel.begin(), m_listPainter.m_vSel.end(), nIndex)); m_listPainter.m_vSel.insert(it1, nIndex); m_listPainter.m_vAvailable.erase(m_listPainter.m_vAvailable.begin() + nRow); } break; case SINGLE_SORTABLE: for (set<int>::const_iterator it = sSelPos.begin(), end = sSelPos.end(); it != end; ++it) { int nRow (*it); int nIndex (m_listPainter.m_vAvailable[nRow]); m_listPainter.m_vSel.push_back(nIndex); } for (set<int>::const_reverse_iterator it = sSelPos.rbegin(), end = sSelPos.rend(); it != end; ++it) { int nRow (*it); m_listPainter.m_vAvailable.erase(m_listPainter.m_vAvailable.begin() + nRow); } break; case MULTIPLE: for (set<int>::const_iterator it = sSelPos.begin(), end = sSelPos.end(); it != end; ++it) { int nRow (*it); //int nIndex (m_listPainter.m_vAvailable[nRow]); //m_listPainter.getSel_().push_back(nIndex); m_listPainter.m_vSel.push_back(nRow); } break; default: CB_ASSERT(false); } adjustOnDataChanged(); } void DoubleList::on_m_pDeleteB_clicked() { if (m_listPainter.m_vSel.empty()) { return; } QItemSelectionModel* pSelMdl (m_pSelectedG->selectionModel()); QModelIndexList lSel (pSelMdl->selection().indexes()); set<int> sSelPos; // the rows must be sorted and the last must be processed first, so removal of elements doesn't change the row number for the remaining ones for (QModelIndexList::iterator it = lSel.begin(), end = lSel.end(); it != end; ++it) { int nRow (it->row()); CB_ASSERT (nRow >= 0); sSelPos.insert(nRow); } remove(sSelPos); } void DoubleList::remove(const std::set<int>& sSelPos) // removes elements from the specified indexes { for (set<int>::const_reverse_iterator it = sSelPos.rbegin(), end = sSelPos.rend(); it != end; ++it) { int nRow (*it); int nIndex (m_listPainter.m_vSel[nRow]); if (MULTIPLE != m_eSelectionMode) { vector<int>::iterator it1 (lower_bound(m_listPainter.m_vAvailable.begin(), m_listPainter.m_vAvailable.end(), nIndex)); m_listPainter.m_vAvailable.insert(it1, nIndex); } m_listPainter.m_vSel.erase(m_listPainter.m_vSel.begin() + nRow); } adjustOnDataChanged(); } void DoubleList::on_m_pAddAllB_clicked() { switch (m_eSelectionMode) { case SINGLE_UNSORTABLE: m_listPainter.m_vAvailable.clear(); m_listPainter.m_vSel.clear(); for (int i = 0, n = cSize(m_listPainter.getAll()); i < n; ++i) { m_listPainter.m_vSel.push_back(i); } break; case SINGLE_SORTABLE: m_listPainter.m_vSel.insert(m_listPainter.m_vSel.end(), m_listPainter.m_vAvailable.begin(), m_listPainter.m_vAvailable.end()); m_listPainter.m_vAvailable.clear(); break; case MULTIPLE: m_listPainter.m_vSel.insert(m_listPainter.m_vSel.end(), m_listPainter.m_vAvailable.begin(), m_listPainter.m_vAvailable.end()); break; default: CB_ASSERT(false); } adjustOnDataChanged(); } void DoubleList::on_m_pDeleteAllB_clicked() { m_listPainter.m_vSel.clear(); if (MULTIPLE != m_eSelectionMode) { m_listPainter.m_vAvailable.clear(); for (int i = 0, n = cSize(m_listPainter.getAll()); i < n; ++i) { m_listPainter.m_vAvailable.push_back(i); } } adjustOnDataChanged(); } void DoubleList::on_m_pRestoreDefaultB_clicked() { m_listPainter.reset(); m_listPainter.m_bResultInReset = true; initAvailable(); adjustOnDataChanged(); } void DoubleList::on_m_pRestoreOpenB_clicked() { m_listPainter.m_vSel = m_listPainter.m_vOrigSel; m_listPainter.m_bResultInReset = false; initAvailable(); adjustOnDataChanged(); } /*override*/ void DoubleList::resizeEvent(QResizeEvent*) { //return; //QDialog::resizeEvent(pEvent); /*cout << this << ": size: " << width() << "x" << height() << " m_pAvailableG: " << m_pAvailableG->width() << "x" << m_pAvailableG->height() << " m_pSelectedG: " << m_pSelectedG->width() << "x" << m_pSelectedG->height() << " sel hdr: " << m_pSelectedG->horizontalHeader()->sectionSize(0) << ", " << m_pSelectedG->horizontalHeader()->sectionSize(1) << endl; m_pAvailableG->resizeRowsToContents(); m_pSelectedG->resizeRowsToContents();*/ QTimer::singleShot(1, this, SLOT(onResizeTimer())); // !!! 2008.10.27 - this is a workaround for what appears to be a bug in Qt: resizeEvent() doesn't get called after applying a layout; as a result, resizeRowsToContents() uses incorrect sizes to figure line heights; perhaps there's no bug and there's some other way to achieve a QTableView that adjusts the row heights such that all rows fit on the screen (perhaps after Qt 4.3.1), but for now this approach seems good enough; (calling layout()->activate() might do something similar, but it's cumbersome to use) } void DoubleList::onResizeTimer() { //cout << this << ": size: " << width() << "x" << height() << " m_pAvailableG: " << m_pAvailableG->width() << "x" << m_pAvailableG->height() << " m_pSelectedG: " << m_pSelectedG->width() << "x" << m_pSelectedG->height() << " sel hdr: " << m_pSelectedG->horizontalHeader()->sectionSize(0) << ", " << m_pSelectedG->horizontalHeader()->sectionSize(1) << endl; resizeRows(); } void DoubleList::onAvlDoubleClicked(const QModelIndex& index) { emit avlDoubleClicked(index.row()); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Palette.ui������������������������������������������������������������������0000644�0001750�0000144�00000017635�11225430371�015222� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>PaletteDlg</class> <widget class="QDialog" name="PaletteDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>603</width> <height>472</height> </rect> </property> <property name="windowTitle" > <string>Background colors</string> </property> <layout class="QVBoxLayout" > <item> <widget class="QGroupBox" name="groupBox" > <property name="sizePolicy" > <sizepolicy vsizetype="Minimum" hsizetype="Preferred" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="title" > <string>Album</string> </property> <layout class="QGridLayout" > <item row="0" column="0" > <widget class="QToolButton" name="m_pCol0B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="0" column="1" > <widget class="QLabel" name="label" > <property name="text" > <string>Field equal to the ID3V2 field or missing</string> </property> </widget> </item> <item row="1" column="0" > <widget class="QToolButton" name="m_pCol1B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="1" column="1" > <widget class="QLabel" name="label_2" > <property name="text" > <string>Field is different from the corresponding ID3V2 value (or no ID3V2 field exists)</string> </property> </widget> </item> <item row="2" column="0" > <widget class="QToolButton" name="m_pCol2B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="2" column="1" > <widget class="QLabel" name="label_3" > <property name="text" > <string>Value marked as "assigned"</string> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="groupBox_2" > <property name="sizePolicy" > <sizepolicy vsizetype="Minimum" hsizetype="Preferred" > <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="title" > <string>Song</string> </property> <layout class="QGridLayout" > <item row="0" column="0" > <widget class="QToolButton" name="m_pCol3B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="0" column="1" > <widget class="QLabel" name="label_5" > <property name="text" > <string>Tag and field present</string> </property> </widget> </item> <item row="1" column="0" > <widget class="QToolButton" name="m_pCol4B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="1" column="1" > <widget class="QLabel" name="label_6" > <property name="text" > <string>Tag not present</string> </property> </widget> </item> <item row="2" column="0" > <widget class="QToolButton" name="m_pCol5B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="2" column="1" > <widget class="QLabel" name="label_7" > <property name="text" > <string>Tag present but field is not supported</string> </property> </widget> </item> <item row="3" column="0" > <widget class="QToolButton" name="m_pCol6B" > <property name="minimumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>60</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="text" > <string/> </property> </widget> </item> <item row="3" column="1" > <widget class="QLabel" name="label_8" > <property name="text" > <string>Tag present, field is supported but missing</string> </property> </widget> </item> </layout> </widget> </item> <item> <spacer> <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" > <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> <item> <widget class="QWidget" native="1" name="widget" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>391</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QPushButton" name="m_pOkB" > <property name="text" > <string>OK</string> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> <resources/> <connections/> </ui> ���������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/MusicBrainzDownloader.cpp���������������������������������������������������0000644�0001750�0000144�00000050016�11304154177�020231� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QHttp> #include <QDesktopServices> #ifndef WIN32 #include <sys/time.h> #else #include <windows.h> #endif #include <QDateTime> #include "MusicBrainzDownloader.h" #include "Helpers.h" #include "SimpleSaxHandler.h" #include "StoredSettings.h" using namespace std; using namespace pearl; #if 1 using namespace MusicBrainz; namespace MusicBrainz { /* metadata release-list release track-list */ struct SearchXmlHandler : public SimpleSaxHandler<SearchXmlHandler> { SearchXmlHandler(MusicBrainzDownloader& dlg) : SimpleSaxHandler<SearchXmlHandler>("metadata"), m_dlg(dlg) { Node& meta (getRoot()); meta.onStart = &SearchXmlHandler::onMetaStart; Node& relList (makeNode(meta, "release-list")); Node& rel (makeNode(relList, "release")); rel.onStart = &SearchXmlHandler::onRelStart; Node& trackList (makeNode(rel, "track-list")); trackList.onStart = &SearchXmlHandler::onTrackListStart; } private: MusicBrainzDownloader& m_dlg; void onMetaStart(const QXmlAttributes& /*attrs*/) { m_dlg.m_nLastLoadedPage = 0; } void onRelStart(const QXmlAttributes& attrs) { m_dlg.m_vAlbums.push_back(MusicBrainzAlbumInfo()); m_dlg.m_vAlbums.back().m_strId = convStr(attrs.value("id")); } void onTrackListStart(const QXmlAttributes& attrs) { m_dlg.m_vAlbums.back().m_nTrackCount = attrs.value("count").toInt(); } }; /* metadata release title asin artist name release-event-list event track-list track title artist name relation-list relation */ struct AlbumXmlHandler : public SimpleSaxHandler<AlbumXmlHandler> { AlbumXmlHandler(MusicBrainzAlbumInfo& albumInfo) : SimpleSaxHandler<AlbumXmlHandler>("metadata"), m_albumInfo(albumInfo) { Node& meta (getRoot()); meta.onEnd = &AlbumXmlHandler::onMetaEnd; Node& rel (makeNode(meta, "release")); rel.onStart = &AlbumXmlHandler::onRelStart; Node& albTitle (makeNode(rel, "title")); albTitle.onChar = &AlbumXmlHandler::onAlbTitleChar; Node& asin (makeNode(rel, "asin")); asin.onChar = &AlbumXmlHandler::onAsinChar; Node& albArtist (makeNode(rel, "artist")); Node& albArtistName (makeNode(albArtist, "name")); albArtistName.onChar = &AlbumXmlHandler::onAlbArtistNameChar; Node& albRelEvents (makeNode(rel, "release-event-list")); Node& albEvent (makeNode(albRelEvents, "event")); albEvent.onStart = &AlbumXmlHandler::onAlbEventStart; Node& albTrackList (makeNode(rel, "track-list")); Node& track (makeNode(albTrackList, "track")); track.onStart = &AlbumXmlHandler::onTrackStart; Node& trackTitle (makeNode(track, "title")); trackTitle.onChar = &AlbumXmlHandler::onTrackTitleChar; Node& trackArtist (makeNode(track, "artist")); Node& trackArtistName (makeNode(trackArtist, "name")); trackArtistName.onChar = &AlbumXmlHandler::onTrackArtistName; Node& relationList (makeNode(rel, "relation-list")); relationList.onStart = &AlbumXmlHandler::onRelationListStart; Node& relation (makeNode(relationList, "relation")); relation.onStart = &AlbumXmlHandler::onRelationStart; m_albumInfo.m_eVarArtists = AlbumInfo::VA_SINGLE; } private: MusicBrainzAlbumInfo& m_albumInfo; bool m_bTargetIsUrl; void onRelStart(const QXmlAttributes& attrs) { CB_ASSERT (m_albumInfo.m_strId == convStr(attrs.value("id"))); } void onAlbEventStart(const QXmlAttributes& attrs) { string strDate (convStr(attrs.value("date"))); if (!strDate.empty()) { m_albumInfo.m_strReleased = m_albumInfo.m_strReleased.empty() ? strDate : min(m_albumInfo.m_strReleased, strDate); } string strFormat (convStr(attrs.value("format"))); if (!strFormat.empty() && string::npos == m_albumInfo.m_strFormat.find(strFormat)) { addIfMissing(m_albumInfo.m_strFormat, strFormat); } } void onTrackStart(const QXmlAttributes&) { m_albumInfo.m_vTracks.push_back(TrackInfo()); char a [10]; sprintf(a, "%d", cSize(m_albumInfo.m_vTracks)); m_albumInfo.m_vTracks.back().m_strPos = a; } void onRelationListStart(const QXmlAttributes& attrs) { m_bTargetIsUrl = "Url" == attrs.value("target-type"); } void onRelationStart(const QXmlAttributes& attrs) { if (m_bTargetIsUrl) { QString qstrType (attrs.value("type")); if ("AmazonAsin" == qstrType) { m_albumInfo.m_strAmazonLink = convStr(attrs.value("target")); } else if ("CoverArtLink" == qstrType) { string strUrl (convStr(attrs.value("target"))); if (beginsWith(strUrl, "http://")) { m_albumInfo.m_vstrImageNames.push_back(strUrl); } else { //ttt2 perhaps tell the user qDebug("Unsupported image link"); } } } } void onMetaEnd() { m_albumInfo.m_vpImages.resize(m_albumInfo.m_vstrImageNames.size()); m_albumInfo.m_vstrImageInfo.resize(m_albumInfo.m_vstrImageNames.size()); if (m_albumInfo.m_strAmazonLink.empty() && !m_albumInfo.m_strAsin.empty()) { m_albumInfo.m_strAmazonLink = "http://www.amazon.com/gp/product/" + m_albumInfo.m_strAsin; } for (int i = 0, n = cSize(m_albumInfo.m_vTracks); i < n; ++i) { TrackInfo& t (m_albumInfo.m_vTracks[i]); addList(t.m_strArtist, m_albumInfo.m_strArtist); } } void onAlbTitleChar(const string& s) { m_albumInfo.m_strTitle = s; } void onAsinChar(const string& s) { m_albumInfo.m_strAsin = s; m_albumInfo.m_vstrImageNames.push_back("http://images.amazon.com/images/P/" + s + ".01.LZZZZZZZ.jpg"); // ttt2 "01" is country code for US, perhaps try others //ttt2 perhaps check for duplicates } void onAlbArtistNameChar(const string& s) { if (0 == convStr(s).compare("VaRiOuS Artists", Qt::CaseInsensitive)) { m_albumInfo.m_eVarArtists = AlbumInfo::VA_VARIOUS; } else { m_albumInfo.m_strArtist = s; } } void onTrackTitleChar(const string& s) { m_albumInfo.m_vTracks.back().m_strTitle = s; } void onTrackArtistName(const string& s) { m_albumInfo.m_vTracks.back().m_strArtist = s; } }; /*override*/ void MusicBrainzAlbumInfo::copyTo(AlbumInfo& dest) { dest.m_strTitle = m_strTitle; //dest.m_strArtist = m_strArtist; //dest.m_strComposer; // !!! missing //dest.m_strFormat = m_strFormat; // CD, tape, ... //dest.m_strGenre = m_strGenre; // !!! missing dest.m_strReleased = m_strReleased; //dest.m_strNotes; // !!! missing dest.m_vTracks = m_vTracks; dest.m_eVarArtists = m_eVarArtists; dest.m_strSourceName = MusicBrainzDownloader::SOURCE_NAME; // Discogs, MusicBrainz, ... ; needed by MainFormDlgImpl; //dest.m_imageInfo; // !!! not set } } // namespace MusicBrainz //============================================================================================================================= //============================================================================================================================= //============================================================================================================================= /*override*/ void MusicBrainzDownloader::saveSize() { m_settings.saveMusicBrainzSettings(width(), height()); } /*static*/ const char* MusicBrainzDownloader::SOURCE_NAME ("MusicBrainz"); MusicBrainzDownloader::MusicBrainzDownloader(QWidget* pParent, SessionSettings& settings, bool bSaveResults) : AlbumInfoDownloaderDlgImpl(pParent, settings, bSaveResults), m_nLastReqTime(0) { setWindowTitle("Download album data from MusicBrainz.org"); int nWidth, nHeight; m_settings.loadMusicBrainzSettings(nWidth, nHeight); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } m_pViewAtAmazonL->setText(getAmazonText()); m_pGenreE->hide(); m_pGenreL->hide(); m_pAlbumNotesM->hide(); m_pVolumeL->hide(); m_pVolumeCbB->hide(); m_pStyleL->hide(); m_pStyleCbB->hide(); m_pImgSizeL->setMinimumHeight(m_pImgSizeL->height()*2); m_pQHttp->setHost("musicbrainz.org"); m_pImageQHttp = new QHttp (this); m_pModel = new WebDwnldModel(*this, *m_pTrackListG); // !!! in a way these would make sense to be in the base constructor, but that would cause calls to pure virtual methods m_pTrackListG->setModel(m_pModel); connect(m_pImageQHttp, SIGNAL(requestFinished(int, bool)), this, SLOT(onRequestFinished(int, bool))); connect(m_pSearchB, SIGNAL(clicked()), this, SLOT(on_m_pSearchB_clicked())); connect(m_pViewAtAmazonL, SIGNAL(linkActivated(const QString&)), this, SLOT(onAmazonLinkActivated(const QString&))); } MusicBrainzDownloader::~MusicBrainzDownloader() { resetNavigation(); // !!! not in base class, because it calls virtual method resetNavigation() clear(); } void MusicBrainzDownloader::clear() { LAST_STEP("MusicBrainzDownloader::clear"); clearPtrContainer(m_vpImages); m_vAlbums.clear(); } /*override*/ bool MusicBrainzDownloader::initSearch(const std::string& strArtist, const std::string& strAlbum) { LAST_STEP("MusicBrainzDownloader::initSearch"); m_pSrchArtistE->setText(convStr((removeParentheses(strArtist)))); m_pSrchAlbumE->setText(convStr((removeParentheses(strAlbum)))); return !strArtist.empty() || !strAlbum.empty(); } /*override*/ std::string MusicBrainzDownloader::createQuery() { LAST_STEP("MusicBrainzDownloader::createQuery"); string s ("/ws/1/release/?type=xml&artist=" + replaceSymbols(convStr(m_pSrchArtistE->text())) + "&title=" + replaceSymbols(convStr(m_pSrchAlbumE->text()))); //qDebug("qry: %s", s.c_str()); if (m_pMatchCountCkB->isChecked()) { s += convStr(QString("&count=%1").arg(m_nExpectedTracks)); } /*for (string::size_type i = 0; i < s.size(); ++i) { if (' ' == s[i]) { s[i] = '+'; } }*/ //s = "/ws/1/release/?type=xml&artist=Beatles&title=Help"; return s; } void MusicBrainzDownloader::delay() { long long t (getTime()); long long nDiff (t - m_nLastReqTime); //qDebug("crt: %lld, prev: %lld, diff: %lld", t, m_nLastReqTime, t - m_nLastReqTime); if (nDiff < 1000) { if (nDiff < 0) { nDiff = 0; } int nWait (999 - (int)nDiff); //qDebug(" wait: %d", nWait); char a [15]; sprintf(a, "waiting %dms", nWait + 100); addNote(a); #ifndef WIN32 timespec ts; ts.tv_sec = 0; ts.tv_nsec = 100000000; // 0.1s, to be sure nanosleep(&ts, 0); ts.tv_nsec = nWait*1000000; nanosleep(&ts, 0); #else Sleep(nWait + 100); #endif //qDebug("waiting %d", nWait); } m_nLastReqTime = t; } long long MusicBrainzDownloader::getTime() // time in milliseconds { QDateTime t (QDateTime::currentDateTime()); long long nRes (t.toTime_t()); //ttt3 32bit nRes *= 1000; nRes += t.time().msec(); return nRes; #if 0 qDebug("t1 %lld", nRes); #ifndef WIN32 timeval tv; gettimeofday(&tv, 0); qDebug("t2 %lld", tv.tv_sec*1000LL + tv.tv_usec/1000); return tv.tv_sec*1000LL + tv.tv_usec/1000; #else QDateTime t (QDateTime::currentDateTime()); return t.toTime_t(); //ttt3 32bit #endif #endif } //========================================================================================================================== //========================================================================================================================== //========================================================================================================================== void MusicBrainzDownloader::on_m_pSearchB_clicked() { LAST_STEP("MusicBrainzDownloader::on_m_pSearchB_clicked"); clear(); search(); } //========================================================================================================================== //========================================================================================================================== //========================================================================================================================== void MusicBrainzDownloader::loadNextPage() { LAST_STEP("MusicBrainzDownloader::loadNextPage"); CB_ASSERT (!m_pQHttp->hasPendingRequests()); CB_ASSERT (!m_pImageQHttp->hasPendingRequests()); ++m_nLastLoadedPage; CB_ASSERT (m_nLastLoadedPage <= m_nTotalPages - 1); //m_eState = NEXT; setWaiting(SEARCH); //char a [20]; //sprintf(a, "&page=%d", m_nLastLoadedPage + 1); //string s (m_strQuery + a); QHttpRequestHeader header ("GET", convStr(m_strQuery)); //header.setValue("Host", "www.musicbrainz.org"); header.setValue("Host", "musicbrainz.org"); //header.setValue("Accept-Encoding", "gzip"); delay(); //qDebug("--------------\npath %s", header.path().toUtf8().constData()); //qDebug("qry %s", m_strQuery.c_str()); m_pQHttp->request(header); //cout << "sent search " << m_pQHttp->request(header) << " for page " << (m_nLastLoadedPage + 1) << endl; } //ttt2 see if it is possible for a track to have its own genre QString MusicBrainzDownloader::getAmazonText() const { LAST_STEP("MusicBrainzDownloader::getAmazonText"); if (m_nCrtAlbum < 0 || m_nCrtAlbum >= cSize(m_vAlbums)) { return NOT_FOUND_AT_AMAZON; } const MusicBrainzAlbumInfo& album (m_vAlbums[m_nCrtAlbum]); if (album.m_strAmazonLink.empty()) { return NOT_FOUND_AT_AMAZON; } else { return convStr("<a href=\"" + album.m_strAmazonLink + "\">view at amazon.com</a>"); } } void MusicBrainzDownloader::onAmazonLinkActivated(const QString& qstrLink) // !!! it's possible to set openExternalLinks on a QLabel to open links automatically, but this leaves an ugly frame around the text, with it right side missing; also, manual handling is needed to open a built-in browser; { LAST_STEP("MusicBrainzDownloader::onAmazonLinkActivated"); m_pViewAtAmazonL->setText("qq"); // !!! the text needs to CHANGE to make the frame disappear m_pViewAtAmazonL->setText(getAmazonText()); QDesktopServices::openUrl(qstrLink); } void MusicBrainzDownloader::reloadGui() { LAST_STEP("MusicBrainzDownloader::reloadGui"); AlbumInfoDownloaderDlgImpl::reloadGui(); m_pViewAtAmazonL->setText(getAmazonText()); } void MusicBrainzDownloader::requestAlbum(int nAlbum) { LAST_STEP("MusicBrainzDownloader::requestAlbum"); //CB_ASSERT (!m_pQHttp->hasPendingRequests() && !m_pImageQHttp->hasPendingRequests()); // ttt1 triggered: https://sourceforge.net/apps/mantisbt/mp3diags/view.php?id=36 ?? perhaps might happen when MB returns errors ; see also DiscogsDownloader::requestAlbum CB_ASSERT (!m_pQHttp->hasPendingRequests()); CB_ASSERT (!m_pImageQHttp->hasPendingRequests()); m_nLoadingAlbum = nAlbum; setWaiting(ALBUM); //string s ("/release/" + m_vAlbums[nAlbum].m_strId + "?f=xml&api_key=f51e9c8f6c"); string s ("/ws/1/release/" + m_vAlbums[nAlbum].m_strId + "?type=xml&inc=tracks+artist+release-events+url-rels"); QHttpRequestHeader header ("GET", convStr(s)); header.setValue("Host", "musicbrainz.org"); //header.setValue("Accept-Encoding", "gzip"); delay(); m_pQHttp->request(header); //cout << "sent album " << m_vAlbums[nAlbum].m_strId << " - " << m_pQHttp->request(header) << endl; addNote("getting album info ..."); } void MusicBrainzDownloader::requestImage(int nAlbum, int nImage) { LAST_STEP("MusicBrainzDownloader::requestImage"); CB_ASSERT (!m_pQHttp->hasPendingRequests()); CB_ASSERT (!m_pImageQHttp->hasPendingRequests()); m_nLoadingAlbum = nAlbum; m_nLoadingImage = nImage; setWaiting(IMAGE); const string& strUrl (m_vAlbums[nAlbum].m_vstrImageNames[nImage]); setImageType(strUrl); QUrl url (convStr(strUrl)); m_pImageQHttp->setHost(url.host()); delay(); // probably not needed, because doesn't seem that MusicBrainz would want to store images //connect(m_pImageQHttp, SIGNAL(requestFinished(int, bool)), this, SLOT(onRequestFinished(int, bool))); //qDebug("host: %s, path: %s", url.host().toLatin1().constData(), url.path().toLatin1().constData()); //qDebug("%s", strUrl.c_str()); m_pImageQHttp->get(url.path()); addNote("getting image ..."); } //========================================================================================================================== //========================================================================================================================== //========================================================================================================================== /*override*/ QHttp* MusicBrainzDownloader::getWaitingHttp() { LAST_STEP("MusicBrainzDownloader::getWaitingHttp"); return IMAGE == m_eWaiting ? m_pImageQHttp : m_pQHttp; } /*override*/ void MusicBrainzDownloader::resetNavigation() { LAST_STEP("MusicBrainzDownloader::resetNavigation"); m_pImageQHttp->clearPendingRequests(); AlbumInfoDownloaderDlgImpl::resetNavigation(); } /*override*/ WebAlbumInfoBase& MusicBrainzDownloader::album(int i) { return m_vAlbums.at(i); } /*override*/ int MusicBrainzDownloader::getAlbumCount() const { return cSize(m_vAlbums); } /*override*/ QXmlDefaultHandler* MusicBrainzDownloader::getSearchXmlHandler() { return new SearchXmlHandler(*this); } /*override*/ QXmlDefaultHandler* MusicBrainzDownloader::getAlbumXmlHandler(int nAlbum) { //return new AlbumXmlHandler(m_vAlbums.at(nAlbum)); return new AlbumXmlHandler(m_vAlbums.at(nAlbum)); } /*override*/ const WebAlbumInfoBase* MusicBrainzDownloader::getCrtAlbum() const // returns 0 if there's no album { if (m_nCrtAlbum < 0 || m_nCrtAlbum >= cSize(m_vAlbums)) { return 0; } return &m_vAlbums[m_nCrtAlbum]; } /* */ //ttt2 perhaps look at Last.fm for more pictures (see Cover Fetcher for AmaroK 1.4; a brief look at the API seems to indicate that a generic "search" is not possible) //ttt2 detect Qt 4.4 and use QWebView #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/DirFilterDlgImpl.cpp��������������������������������������������������������0000644�0001750�0000144�00000025271�11506600423�017120� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <algorithm> #include <map> #include "DirFilterDlgImpl.h" #include "CommonData.h" #include "Helpers.h" #include "StoredSettings.h" using namespace std; using namespace pearl; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== class DirListElem : public ListElem { /*override*/ string getText(int /*nCol*/) const { return m_strDir; } string m_strDir; // uses native separators //CommonData* m_pCommonData; public: DirListElem(const string& strDir) : m_strDir(strDir) {} const string& getDir() const { return m_strDir; } }; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== static string addSepToRoot(const string& s) { #ifndef WIN32 return s; #else //ttt2 if (s.size() != 2) { return s; } return s + "\\"; #endif } static string removeSepFromRoot(const string& s) { #ifndef WIN32 return s; #else //ttt2 if (s.size() != 3) { return s; } return s.substr(0, 2); #endif } #ifndef WIN32 static char getDrive(const string&) { return '.'; } #else //ttt2 static char getDrive(const string& s) { CB_ASSERT(s.size() >= 2); return s[0]; } #endif void DirFilterDlgImpl::populateLists() { TRACER("DirFilterDlgImpl::populateLists"); const set<string>& sDirs (m_pCommonData->getAllDirs()); if (sDirs.empty()) { return; } map<char, pair<string, int> > mCommonDirs; for (set<string>::const_iterator it = sDirs.begin(), begin = sDirs.begin(), end = sDirs.end(); it != end; ++it) { const string strDir (*it + getPathSepAsStr()); char d (getDrive(strDir)); if (0 == mCommonDirs.count(d)) { mCommonDirs[d] = make_pair(strDir, 0); } else { string s (mCommonDirs[d].first); int j (0); for (int n = min(cSize(s), cSize(strDir)); j < n; ++j) { if (strDir[j] != s[j]) { break; } } for (; j >= 0 && (getPathSep() != strDir[j] || getPathSep() != s[j]); --j) {} // a bug in this line was fixed by Mario Schwalbe on December 16 2010 s.erase(j + 1); // it's OK for j==-1 mCommonDirs[d] = make_pair(s, 0); // "0" doesn't matter //if (cSize(strCommonDir) <= 1) { break; } } } //ttt2 strCommonDir should be drive-specific on Wnd set<string> sDirsAndParents (sDirs); for (map<char, pair<string, int> >::iterator it = mCommonDirs.begin(), end = mCommonDirs.end(); it != end; ++it) { string s (it->second.first); string::size_type nCommonSize (s.size()); if (nCommonSize > 0) { CB_ASSERT (getPathSep() == s[nCommonSize - 1]); s.erase(nCommonSize - 1); --nCommonSize; mCommonDirs[getDrive(s)] = make_pair(s, nCommonSize); if (nCommonSize > 0) // this is always true on Windows { sDirsAndParents.insert(s); } } } for (set<string>::const_iterator it = sDirs.begin(), end = sDirs.end(); it != end; ++it) { const string& strDir(*it); CB_ASSERT(beginsWith(strDir, mCommonDirs[getDrive(strDir)].first)); int nCommonSize (mCommonDirs[getDrive(strDir)].second); string::size_type k (nCommonSize + 1); for (;;) { k = strDir.find(getPathSep(), k); if (string::npos == k) { break; } sDirsAndParents.insert(strDir.substr(0, k)); ++k; } } for (set<string>::iterator it = sDirsAndParents.begin(), end = sDirsAndParents.end(); it != end; ++it) { m_vpOrigAll.push_back(new DirListElem(addSepToRoot(toNativeSeparators(*it)))); } vector<string> vAll; vAll.insert(vAll.end(), sDirsAndParents.begin(), sDirsAndParents.end()); for (int i = 0, n = cSize(m_pCommonData->m_filter.getDirs()); i < n; ++i) { const string& s (m_pCommonData->m_filter.getDirs()[i]); int k (lower_bound(vAll.begin(), vAll.end(), s) - vAll.begin()); // CB_ASSERT (k < cSize(sDirsAndParents) && vAll[k] == s); // !!! wrong assert - m_pCommonData->m_filter is serialized, so it can keep old values, which don't get actualized as the scanned directories change if (k < cSize(sDirsAndParents) && vAll[k] == s) { m_vOrigSel.push_back(k); } // else - ignore; this old dir is no longer part of the scanned dirs } m_vSel = m_vOrigSel; } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== DirFilterDlgImpl::DirFilterDlgImpl(CommonData* pCommonData, QWidget* pParent /*=0*/) : QDialog(pParent, getDialogWndFlags()), ListPainter("<all folders>"), m_pCommonData(pCommonData) { TRACER("DirFilterDlgImpl constr"); setupUi(this); populateLists(); m_pListHldr->setLayout(new QHBoxLayout()); m_pDoubleList = new DoubleList( *this, DoubleList::RESTORE_OPEN, DoubleList::SINGLE_UNSORTABLE, "Available folders", "Include folders", this); m_pListHldr->layout()->addWidget(m_pDoubleList); m_pListHldr->layout()->setContentsMargins(0, 0, 0, 0); int nWidth, nHeight; m_pCommonData->m_settings.loadDirFilterSettings(nWidth, nHeight); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } else { defaultResize(*this); } connect(m_pDoubleList, SIGNAL(avlDoubleClicked(int)), this, SLOT(onAvlDoubleClicked(int))); { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } DirFilterDlgImpl::~DirFilterDlgImpl() { clearPtrContainer(m_vpOrigAll); } #if 0 void DirFilterDlgImpl::logState(const char* /*szPlace*/) const { cout << szPlace << /*": m_filter.m_vSelDirs=" << m_pCommonData->m_filter.m_vSelDirs.size() << " m_availableDirs.m_vstrDirs=" << m_availableDirs.m_vstrDirs.size() << " m_selectedDirs.m_vSelDirs=" << m_selectedDirs.m_vstrDirs.size() <<*/ endl; } #endif //--------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------- void DirFilterDlgImpl::on_m_pOkB_clicked() { vector<string> v; for (int i = 0, n = cSize(m_vSel); i < n; ++i) { v.push_back(fromNativeSeparators(removeSepFromRoot(dynamic_cast<const DirListElem*>(m_vpOrigAll[m_vSel[i]])->getDir()))); } m_pCommonData->m_filter.setDirs(v); m_pCommonData->m_settings.saveDirFilterSettings(width(), height()); accept(); } void DirFilterDlgImpl::on_m_pCancelB_clicked() { reject(); } void DirFilterDlgImpl::onAvlDoubleClicked(int nRow) { vector<string> v; const DirListElem* p (dynamic_cast<const DirListElem*>(m_vpOrigAll[getAvailable()[nRow]])); CB_ASSERT(0 != p); v.push_back(fromNativeSeparators(removeSepFromRoot(p->getDir()))); m_pCommonData->m_filter.setDirs(v); accept(); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== /*override*/ string DirFilterDlgImpl::getTooltip(TooltipKey eTooltipKey) const { switch (eTooltipKey) { case SELECTED_G: return "";//"Notes to be included"; case AVAILABLE_G: return "";//"Available notes"; case ADD_B: return "Add selected folders"; case DELETE_B: return "Remove selected folders"; case ADD_ALL_B: return "";//"Add all folders"; case DELETE_ALL_B: return "";//"Remove all folders"; case RESTORE_DEFAULT_B: return ""; case RESTORE_OPEN_B: return "Restore lists to the configuration they had when the window was open"; default: CB_ASSERT(false); } } /*override*/ Qt::Alignment DirFilterDlgImpl::getAlignment(int /*nCol*/) const { return Qt::AlignTop | Qt::AlignLeft; } /*override*/ void DirFilterDlgImpl::reset() { CB_ASSERT(false); } /*override*/ int DirFilterDlgImpl::getHdrHeight() const { return CELL_HEIGHT; } void DirFilterDlgImpl::onHelp() { openHelp("180_folder_filter.html"); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/Mp3TransformThread.h��������������������������������������������������������0000644�0001750�0000144�00000004001�11200236250�017071� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef Mp3TransformThreadH #define Mp3TransformThreadH #include <deque> #include <vector> #include <string> class Mp3Handler; class QWidget; class Transformation; class CommonData; class TransfConfig; // if there are errors the user is notified; // returns true iff there were no errors; bool transform(const std::deque<const Mp3Handler*>& vpHndlr, std::vector<Transformation*>& vpTransf, const std::string& strTitle, QWidget* pParent, CommonData* pCommonData, TransfConfig& transfConfig); #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/FileRenamerDlgImpl.cpp������������������������������������������������������0000644�0001750�0000144�00000116070�11310700562�017421� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <sstream> #include <QTimer> #include <QPainter> #include <QHeaderView> #include "FileRenamerDlgImpl.h" #include "Helpers.h" #include "ColumnResizer.h" #include "CommonData.h" #include "DataStream.h" #include "RenamerPatternsDlgImpl.h" #include "OsFile.h" #include "ThreadRunnerDlgImpl.h" #include "StoredSettings.h" #include "Id3V230Stream.h" #include "Widgets.h" using namespace std; using namespace pearl; using namespace FileRenamer; HndlrListModel::HndlrListModel(CommonData* pCommonData, FileRenamerDlgImpl* pFileRenamerDlgImpl, bool bUseCurrentView) : m_pFileRenamerDlgImpl(pFileRenamerDlgImpl), m_pCommonData(pCommonData), m_pRenamer(0), m_bUseCurrentView(bUseCurrentView) { } HndlrListModel::~HndlrListModel() { delete m_pRenamer; } void HndlrListModel::setRenamer(const Renamer* p) { delete m_pRenamer; m_pRenamer = p; emitLayoutChanged(); } void HndlrListModel::setUnratedAsDuplicates(bool bUnratedAsDuplicate) { if (0 == m_pRenamer) { return; } m_pRenamer->m_bUnratedAsDuplicate = bUnratedAsDuplicate; emitLayoutChanged(); } // returns either m_pCommonData->getCrtAlbum() or m_pCommonData->getViewHandlers(), based on m_bUseCurrentView const deque<const Mp3Handler*> HndlrListModel::getHandlerList() const { return m_bUseCurrentView ? m_pCommonData->getViewHandlers() : m_pCommonData->getCrtAlbum(); } /*override*/ int HndlrListModel::rowCount(const QModelIndex&) const { return cSize(getHandlerList()); } /*override*/ int HndlrListModel::columnCount(const QModelIndex&) const { return TagReader::LIST_END + 2 - 1; } /*override*/ Qt::ItemFlags HndlrListModel::flags(const QModelIndex& index) const { Qt::ItemFlags flg (QAbstractTableModel::flags(index)); if (1 == index.column() && 0 != m_pRenamer) { flg = flg | Qt::ItemIsEditable; } return flg; } /*override*/ QVariant HndlrListModel::data(const QModelIndex& index, int nRole) const { LAST_STEP("HndlrListModel::data()"); if (!index.isValid()) { return QVariant(); } int i (index.row()); int j (index.column()); if (Qt::DisplayRole != nRole && Qt::ToolTipRole != nRole && Qt::EditRole != nRole) { return QVariant(); } QString s; const Mp3Handler* p (getHandlerList().at(i)); const Id3V2StreamBase* pId3V2 (p->getId3V2Stream()); if (0 == j) { s = convStr(p->getShortName()); } else if (0 == pId3V2) { //s = "N/A"; s = "<< missing ID3V2 >>"; } else if (1 == j) { //s = convStr(p->getName()); if (0 == m_pRenamer) { //s = "N/A"; s = "<< no pattern defined >>"; } else { s = toNativeSeparators(convStr(m_pRenamer->getNewName(p))); if (s.isEmpty()) { //s = "N/A"; s = "<< missing fields >>"; } } } else { j -= 2; if (j >= TagReader::POS_OF_FEATURE[TagReader::IMAGE]) { j += 1; } s = convStr(pId3V2->getValue((TagReader::Feature)TagReader::FEATURE_ON_POS[j])); } if (Qt::DisplayRole == nRole || Qt::EditRole == nRole) { return s; } // so it's Qt::ToolTipRole QFontMetrics fm (m_pFileRenamerDlgImpl->m_pCurrentAlbumG->fontMetrics()); // !!! no need to use "QApplication::fontMetrics()" int nWidth (fm.width(s)); //qDebug("tooltip for %s, width %d int nMargin (QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1); // this "1" should probably be another "metric" constant if (nWidth + 2*nMargin + 1 <= m_pFileRenamerDlgImpl->m_pCurrentAlbumG->horizontalHeader()->sectionSize(index.column())) // ttt2 not sure this "nMargin" is correct { //return QVariant(); return ""; // !!! with "return QVariant()" the previous tooltip remains until the cursor moves over another cell that has a tooltip } return s; } /*override*/ bool HndlrListModel::setData(const QModelIndex& index, const QVariant& value, int nRole /*= Qt::EditRole*/) { if (Qt::EditRole != nRole) { return false; } CB_ASSERT (0 != m_pRenamer); m_pRenamer->m_mValues[getHandlerList().at(index.row())] = convStr(fromNativeSeparators(value.toString())); return true; } /*override*/ QVariant HndlrListModel::headerData(int nSection, Qt::Orientation eOrientation, int nRole /*= Qt::DisplayRole*/) const { LAST_STEP("HndlrListModel::headerData"); if (nRole != Qt::DisplayRole) { return QVariant(); } if (Qt::Horizontal == eOrientation) { if (0 == nSection) { return "File name"; } else if (1 == nSection) { return "New file name"; } else { nSection -= 2; if (nSection >= TagReader::POS_OF_FEATURE[TagReader::IMAGE]) { nSection += 1; } return TagReader::getLabel(TagReader::FEATURE_ON_POS[nSection]); } } return nSection + 1; } //====================================================================================================================== //====================================================================================================================== CurrentAlbumDelegate::CurrentAlbumDelegate(QWidget* pParent, HndlrListModel* pHndlrListModel) : QItemDelegate(pParent), m_pHndlrListModel(pHndlrListModel) { } /*override*/ void CurrentAlbumDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { pPainter->save(); const Mp3Handler* p (m_pHndlrListModel->getHandlerList().at(index.row())); const Id3V2StreamBase* pId3V2 (p->getId3V2Stream()); if (0 == pId3V2) { //pPainter->fillRect(option.rect, QColor(255, 226, 236)); //ttt2 perhaps put back, but should work for "missing fields" as well } QStyleOptionViewItemV2 myOption (option); if (0 != m_pHndlrListModel->getRenamer() && index.column() == 1) { string strNewName (m_pHndlrListModel->getRenamer()->getNewName(p)); if (fileExists(strNewName)) { pPainter->fillRect(option.rect, strNewName == p->getName() ? QColor(226, 236, 255) : QColor(255, 226, 236)); } if (m_pHndlrListModel->getRenamer()->m_mValues.count(p) > 0) { myOption.font.setItalic(true); } } QItemDelegate::paint(pPainter, myOption, index); pPainter->restore(); } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== FileRenamerDlgImpl::FileRenamerDlgImpl(QWidget* pParent, CommonData* pCommonData, bool bUseCurrentView) : QDialog(pParent, getDialogWndFlags()), Ui::FileRenamerDlg(), m_pCommonData(pCommonData), m_bUseCurrentView(bUseCurrentView), m_pEditor(0) { setupUi(this); resizeIcons(); m_pHndlrListModel = new HndlrListModel(m_pCommonData, this, bUseCurrentView); { m_pCurrentAlbumG->verticalHeader()->setResizeMode(QHeaderView::Interactive); m_pCurrentAlbumG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT + 1); m_pCurrentAlbumG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT + 1);//*/ m_pCurrentAlbumG->setModel(m_pHndlrListModel); CurrentAlbumDelegate* pDel (new CurrentAlbumDelegate(this, m_pHndlrListModel)); m_pCurrentAlbumG->setItemDelegate(pDel); m_pCurrentAlbumG->viewport()->installEventFilter(this); } m_pButtonGroup = new QButtonGroup(this); loadPatterns(); updateButtons(); { int nWidth, nHeight; bool bKeepOriginal, bUnratedAsDuplicate; m_pCommonData->m_settings.loadRenamerSettings(nWidth, nHeight, m_nSaButton, m_nVaButton, bKeepOriginal, bUnratedAsDuplicate); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } else { defaultResize(*this); } if (m_nVaButton >= cSize(m_vstrPatterns) || m_nVaButton <= 0) { m_nVaButton = 0; } if (m_nSaButton >= cSize(m_vstrPatterns) || m_nSaButton <= 0) { m_nSaButton = 0; } m_pKeepOriginalCkB->setChecked(bKeepOriginal); m_pMarkUnratedAsDuplicatesCkB->setChecked(bUnratedAsDuplicate); } { m_pModifRenameB = new ModifInfoToolButton(m_pRenameB); connect(m_pModifRenameB, SIGNAL(clicked()), this, SLOT(on_m_pRenameB_clicked())); m_pRenameB = m_pModifRenameB; } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } if (m_bUseCurrentView) { m_pCrtDirTagEdtE->setEnabled(false); m_pPrevB->setEnabled(false); m_pNextB->setEnabled(false); } QTimer::singleShot(1, this, SLOT(onShow())); // just calls reloadTable(); !!! needed to properly resize the table columns; album and file tables have very small widths until they are actually shown, so calling resizeTagEditor() earlier is pointless; calling update() on various layouts seems pointless as well; (see also DoubleList::resizeEvent() ) } FileRenamerDlgImpl::~FileRenamerDlgImpl() { m_pCommonData->m_settings.saveRenamerSettings(width(), height(), m_nSaButton, m_nVaButton, m_pKeepOriginalCkB->isChecked(), m_pMarkUnratedAsDuplicatesCkB->isChecked()); } string FileRenamerDlgImpl::run() { exec(); int k (m_pCurrentAlbumG->currentIndex().row()); const deque<const Mp3Handler*>& vpCrtAlbum (m_pHndlrListModel->getHandlerList()); if (k < 0 || k >= cSize(vpCrtAlbum)) { return ""; } return vpCrtAlbum[k]->getName(); } void FileRenamerDlgImpl::on_m_pNextB_clicked() { closeEditor(); if (m_pCommonData->nextAlbum()) { reloadTable(); } } void FileRenamerDlgImpl::on_m_pPrevB_clicked() { closeEditor(); if (m_pCommonData->prevAlbum()) { reloadTable(); } } void FileRenamerDlgImpl::on_m_pEditPatternsB_clicked() { RenamerPatternsDlgImpl dlg (this, m_pCommonData->m_settings); if (dlg.run(m_vstrPatterns)) { m_nVaButton = m_nSaButton = 0; savePatterns(); updateButtons(); selectPattern(); } } void FileRenamerDlgImpl::updateButtons() { m_nBtnId = 0; createButtons(); } void FileRenamerDlgImpl::createButtons() { QBoxLayout* pLayout (dynamic_cast<QBoxLayout*>(m_pButtonsW->layout())); CB_ASSERT (0 != pLayout); /*int nPos (pLayout->indexOf(pOldBtn)); pLayout->insertWidget(nPos, this);*/ QObjectList l (m_pButtonsW->children()); //qDebug("cnt: %d", l.size()); for (int i = 1, n = l.size(); i < n; ++i) // l[0] is m_pButtonsW's layout (note that m_pAlbumTypeL is in m_pBtnPanelW) { delete l[i]; } for (int i = 0, n = cSize(m_vstrPatterns); i < n; ++i) { QToolButton* p (new QToolButton(m_pButtonsW)); p->setText(toNativeSeparators(convStr(m_vstrPatterns[i]))); p->setCheckable(true); m_pButtonGroup->addButton(p, m_nBtnId++); //p->setAutoExclusive(true); connect(p, SIGNAL(clicked()), this, SLOT(onPatternClicked())); pLayout->insertWidget(i, p); } } void FileRenamerDlgImpl::onPatternClicked() { int nId (m_pButtonGroup->checkedId()); int n (cSize(m_vstrPatterns)); //qDebug("id=%d", nId); //CB_ASSERT (nId >= 0 && nId < 2*n); CB_ASSERT (nId >= 0 && nId < n); if (nId >= n) { nId -= n; } if (isSingleArtist()) { m_nSaButton = nId; } else { m_nVaButton = nId; } m_pHndlrListModel->setRenamer(new Renamer(m_vstrPatterns[nId], m_pCommonData, m_pMarkUnratedAsDuplicatesCkB->isChecked())); resizeUi(); } void FileRenamerDlgImpl::closeEditor() { if (0 != m_pEditor) { delete m_pEditor; } } /*override*/ bool FileRenamerDlgImpl::eventFilter(QObject* pObj, QEvent* pEvent) { //qDebug("ev %d", int(pEvent->type())); if (QEvent::ChildAdded == pEvent->type()) { //qDebug("add"); QObject* pChild (((QChildEvent*)pEvent)->child()); if (pChild->isWidgetType()) { CB_ASSERT (0 == m_pEditor); m_pEditor = pChild; } } else if (QEvent::ChildRemoved == pEvent->type()) { //qDebug("rm"); QObject* pChild (((QChildEvent*)pEvent)->child()); if (pChild->isWidgetType()) { CB_ASSERT (pChild == m_pEditor); m_pEditor = 0; } } return QDialog::eventFilter(pObj, pEvent); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== namespace { struct RenameThread : public PausableThread { const deque<const Mp3Handler*>& m_vpHndl; bool m_bKeepOrig; const Renamer* m_pRenamer; CommonData* m_pCommonData; vector<const Mp3Handler*>& m_vpDel; vector<const Mp3Handler*>& m_vpAdd; QString m_qstrErr; RenameThread(const deque<const Mp3Handler*>& vpHndl, bool bKeepOrig, const Renamer* pRenamer, CommonData* pCommonData, vector<const Mp3Handler*>& vpDel, vector<const Mp3Handler*>& vpAdd) : m_vpHndl(vpHndl), m_bKeepOrig(bKeepOrig), m_pRenamer(pRenamer), m_pCommonData(pCommonData), m_vpDel(vpDel), m_vpAdd(vpAdd) { } /*override*/ void run() { CompleteNotif notif(this); notif.setSuccess(proc()); } bool proc(); }; bool RenameThread::proc() { for (int i = 0, n = cSize(m_vpHndl); i < n; ++i) { if (isAborted()) { return false; } checkPause(); QString qstrName (m_vpHndl[i]->getUiName()); StrList l; l.push_back(qstrName); emit stepChanged(l, -1); string strDest (m_pRenamer->getNewName(m_vpHndl[i])); if (!strDest.empty()) { CB_ASSERT (string::npos == strDest.find("//")); try { bool bSkipped (false); //qDebug("ren %s", strDest.c_str()); if (m_bKeepOrig) { copyFile2(m_vpHndl[i]->getName(), strDest); } else { if (m_vpHndl[i]->getName() == strDest) // ttt2 doesn't work well on case-insensitive file systems { bSkipped = true; } else { renameFile(m_vpHndl[i]->getName(), strDest); m_vpDel.push_back(m_vpHndl[i]); } } if (!bSkipped && m_pCommonData->m_dirTreeEnum.isIncluded(strDest)) { try { m_vpAdd.push_back(new Mp3Handler(strDest, m_pCommonData->m_bUseAllNotes, m_pCommonData->getQualThresholds())); } catch (const Mp3Handler::FileNotFound&) { } } } catch (const FoundDir&) { m_qstrErr = "Source or destination is a directory"; } catch (const CannotCopyFile&) { m_qstrErr = "Error during copying"; } catch (const CannotRenameFile&) { m_qstrErr = "Error during renaming"; } catch (const AlreadyExists&) { m_qstrErr = "Destination already exists"; } catch (const NameNotFound&) { m_qstrErr = "Source not found"; } catch (const std::bad_alloc&) { throw; } catch (const IncorrectDirName&) { CB_ASSERT (false); } catch (...) { m_qstrErr = "Unknown error"; } if (!m_qstrErr.isEmpty()) { return false; } } } return true; } } // namespace //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== void FileRenamerDlgImpl::on_m_pRenameB_clicked() { if (m_vstrPatterns.empty()) { QMessageBox::critical(this, "No patterns exist", "You must create at least a pattern before you can start renaming files."); return; } const Renamer* pRenamer (m_pHndlrListModel->getRenamer()); CB_ASSERT (0 != pRenamer); bool bAll (0 == (Qt::ShiftModifier & m_pModifRenameB->getModifiers())); bool bKeepOrig (m_pKeepOriginalCkB->isChecked()); const deque<const Mp3Handler*>& vpAllHndl (m_pHndlrListModel->getHandlerList()); deque<const Mp3Handler*> vpHndl; if (bAll) { vpHndl = vpAllHndl; } else { QItemSelectionModel* pSelModel (m_pCurrentAlbumG->selectionModel()); QModelIndexList listSel (pSelModel->selectedIndexes()); set<int> snSongs; for (QModelIndexList::iterator it = listSel.begin(), end = listSel.end(); it != end; ++it) { QModelIndex ndx (*it); int nSong (ndx.row()); snSongs.insert(nSong); } for (set<int>::iterator it = snSongs.begin(), end = snSongs.end(); it != end; ++it) { vpHndl.push_back(vpAllHndl[*it]); } } if (QMessageBox::Yes != QMessageBox::question(this, "Confirmation", QString(bKeepOrig ? "Copy" : "Rename") + (bAll ? " all the" : " selected") + " files?", QMessageBox::Yes | QMessageBox::Cancel)) { return; } { set<string> s; for (int i = 0, n = cSize(vpHndl); i < n; ++i) { if (0 == vpHndl[i]->getId3V2Stream()) { QMessageBox::critical(this, "Error", "Operation aborted because file \"" + vpHndl[i]->getUiName() + "\" doesn't have an ID3V2 tag."); return; } string strDest (pRenamer->getNewName(vpHndl[i])); if (strDest.empty()) { QMessageBox::critical(this, "Error", "Operation aborted because file \"" + vpHndl[i]->getUiName() + "\" is missing some required fields in its ID3V2 tag."); return; } if (s.count(strDest) > 0) { QMessageBox::critical(this, "Error", "Operation aborted because it would create 2 copies of a file called \"" + toNativeSeparators(convStr(strDest)) + "\""); return; } if (fileExists(strDest) && (strDest != vpHndl[i]->getName() || bKeepOrig)) { QMessageBox::critical(this, "Error", "Operation aborted because a file called \"" + toNativeSeparators(convStr(strDest)) + "\" already exists."); return; } s.insert(strDest); } } vector<const Mp3Handler*> vpDel, vpAdd; { RenameThread* pThread (new RenameThread(vpHndl, bKeepOrig, pRenamer, m_pCommonData, vpDel, vpAdd)); ThreadRunnerDlgImpl dlg (this, getNoResizeWndFlags(), pThread, ThreadRunnerDlgImpl::SHOW_COUNTER, ThreadRunnerDlgImpl::TRUNCATE_BEGIN); dlg.setWindowTitle(QString(bKeepOrig ? "Copying" : "Renaming") + (bAll ? " all the" : " selected") + " files in the current album"); dlg.exec(); if (!pThread->m_qstrErr.isEmpty()) { QMessageBox::critical(this, "Error", pThread->m_qstrErr); } } m_pCommonData->mergeHandlerChanges(vpAdd, vpDel, CommonData::SEL | CommonData::CURRENT); if (!bKeepOrig || pRenamer->isSameDir()) { reloadTable(); } } void FileRenamerDlgImpl::reloadTable() { { bool bVa (false); bool bErr (false); // it's error if any file lacks ID3V2 const deque<const Mp3Handler*>& vpHndl (m_pHndlrListModel->getHandlerList()); if (vpHndl.empty()) { accept(); return; } int n (cSize(vpHndl)); CB_ASSERT (n > 0); string strArtist ("\1"); for (int i = 0; i < n; ++i) { const Mp3Handler* pHndl (vpHndl[i]); const Id3V2StreamBase* pId3V2 (pHndl->getId3V2Stream()); if (0 == pId3V2) { bErr = true; } else { if ("\1" == strArtist) { strArtist = pId3V2->getArtist(); } else { if (strArtist != pId3V2->getArtist()) { bVa = true; } } } } if (bErr) { m_eState = "\1" == strArtist ? ERR : bVa ? VARIOUS_ERR : SINGLE_ERR; } else { m_eState = bVa ? VARIOUS : SINGLE; } } selectPattern(); m_pHndlrListModel->emitLayoutChanged(); const Mp3Handler* p (m_pHndlrListModel->getHandlerList().at(0)); // !!! it was supposed to close the window if nothing remained if (!m_bUseCurrentView) { m_pCrtDirTagEdtE->setText(toNativeSeparators(convStr(p->getDir()))); } //m_pCrtDirTagEdtE->hide(); //setWindowTitle("MP3 Diags - " + convStr(p->getDir()) + " - File renamer"); QItemSelectionModel* pSelModel (m_pCurrentAlbumG->selectionModel()); pSelModel->clear(); pSelModel->setCurrentIndex(m_pHndlrListModel->index(0, 0), QItemSelectionModel::SelectCurrent); resizeUi(); } void FileRenamerDlgImpl::resizeUi() { SimpleQTableViewWidthInterface intf (*m_pCurrentAlbumG); ColumnResizer rsz (intf, 100, ColumnResizer::FILL, ColumnResizer::CONSISTENT_RESULTS); } /*override*/ void FileRenamerDlgImpl::resizeEvent(QResizeEvent* pEvent) { resizeUi(); QDialog::resizeEvent(pEvent); } // selects the appropriate pattern for a new album, based on whether it's VA or SA; sets m_nCrtPattern and checks the right button; assumes m_eState is properly set up; void FileRenamerDlgImpl::selectPattern() { if (!m_vstrPatterns.empty()) { if (isSingleArtist()) { m_pButtonGroup->button(m_nSaButton)->setChecked(true); m_pHndlrListModel->setRenamer(new Renamer(m_vstrPatterns[m_nSaButton], m_pCommonData, m_pMarkUnratedAsDuplicatesCkB->isChecked())); } else { m_pButtonGroup->button(m_nVaButton /*+ cSize(m_vstrPatterns)*/)->setChecked(true); m_pHndlrListModel->setRenamer(new Renamer(m_vstrPatterns[m_nVaButton], m_pCommonData, m_pMarkUnratedAsDuplicatesCkB->isChecked())); } } else { m_pHndlrListModel->setRenamer(0); } resizeUi(); m_pAlbumTypeL->setText(isSingleArtist() ? "Single artist" : "Various artists"); //ttt2 see if "single" is the best word } void FileRenamerDlgImpl::loadPatterns() { // pattern readers bool bErr (false); //vector<string> v (m_pCommonData->m_settings.loadRenamerPatterns(bErr)); vector<string> v (m_pCommonData->m_settings.loadVector("fileRenamer/patterns", bErr)); m_vstrPatterns.clear(); for (int i = 0, n = cSize(v); i < n; ++i) { string strPatt (v[i]); try { Renamer r (strPatt, m_pCommonData, m_pMarkUnratedAsDuplicatesCkB->isChecked()); m_vstrPatterns.push_back(strPatt); } catch (const Renamer::InvalidPattern&) { bErr = true; } } /*if (m_vstrPatterns.empty()) // ttt2 because there is no default, the user is forced to add a pattern first; see if a meaningful default can be used { // use default (only if the user didn't remove all patterns on purpose) string s ("/tmp/%a/%b[ %y]/%r%n %t"); //ttt2 change from tmp to root/out; //ttt2 perhaps ask the user //ttt2 OS specific Renamer r (s); // may throw after porting, but that's OK, because it signals a fix is needed m_vstrPatterns.push_back(s); }*/ if (bErr) { QMessageBox::warning(this, "Error setting up patterns", "An invalid value was found in the configuration file. You'll have to set up the patterns manually."); } } void FileRenamerDlgImpl::savePatterns() { //m_pCommonData->m_settings.saveRenamerPatterns(m_vstrPatterns); m_pCommonData->m_settings.saveVector("fileRenamer/patterns", m_vstrPatterns); } //ttt2 perhaps have a "reload" button void FileRenamerDlgImpl::resizeIcons() { vector<QToolButton*> v; v.push_back(m_pPrevB); v.push_back(m_pNextB); v.push_back(m_pEditPatternsB); v.push_back(m_pRenameB); int k (m_pCommonData->m_nMainWndIconSize); for (int i = 0, n = cSize(v); i < n; ++i) { QToolButton* p (v[i]); p->setMaximumSize(k, k); p->setMinimumSize(k, k); p->setIconSize(QSize(k - 4, k - 4)); } } void FileRenamerDlgImpl::onHelp() { openHelp("240_file_renamer.html"); } //void FileRenamerDlgImpl::on_m_pMarkUnratedAsDuplicatesCkB_stateChanged() void FileRenamerDlgImpl::on_m_pMarkUnratedAsDuplicatesCkB_clicked() { m_pHndlrListModel->setUnratedAsDuplicates(m_pMarkUnratedAsDuplicatesCkB->isChecked()); } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== namespace FileRenamer { class InvalidCharsReplacer { string m_strRenamerInvalidChars; string m_strRenamerReplacementString; public: std::string fixName(std::string s) const; InvalidCharsReplacer(const string& strRenamerInvalidChars, const string& strRenamerReplacementString) : m_strRenamerInvalidChars(strRenamerInvalidChars), m_strRenamerReplacementString(strRenamerReplacementString) {} }; string InvalidCharsReplacer::fixName(string s) const { CB_ASSERT (string::npos == m_strRenamerReplacementString.find_first_of(m_strRenamerInvalidChars)); if (m_strRenamerInvalidChars.empty()) { return s; } for (;;) { string::size_type n (s.find_first_of(m_strRenamerInvalidChars)); if (string::npos == n) { break; } s.replace(n, 1, m_strRenamerReplacementString); } return s; } struct PatternBase { const InvalidCharsReplacer* m_pInvalidCharsReplacer; PatternBase(const InvalidCharsReplacer* pInvalidCharsReplacer) : m_pInvalidCharsReplacer(pInvalidCharsReplacer) {} virtual ~PatternBase() {} virtual string getVal(const Mp3Handler*) const = 0; }; struct StaticPattern : public PatternBase { StaticPattern(string strVal, const InvalidCharsReplacer* pInvalidCharsReplacer) : PatternBase(pInvalidCharsReplacer), m_strVal(strVal) {} /*override*/ string getVal(const Mp3Handler*) const { return m_strVal; } private: string m_strVal; }; struct FieldPattern : public PatternBase { FieldPattern(TagReader::Feature eFeature, const InvalidCharsReplacer* pInvalidCharsReplacer) : PatternBase(pInvalidCharsReplacer), m_eFeature(eFeature) {} /*override*/ string getVal(const Mp3Handler* pHndl) const { const Id3V2StreamBase* p (pHndl->getId3V2Stream()); if (0 == p) { return ""; } return m_pInvalidCharsReplacer->fixName(p->getValue(m_eFeature)); } private: TagReader::Feature m_eFeature; }; struct YearPattern : public PatternBase { YearPattern(const InvalidCharsReplacer* pInvalidCharsReplacer) : PatternBase(pInvalidCharsReplacer) {} /*override*/ string getVal(const Mp3Handler* pHndl) const { const Id3V2StreamBase* p (pHndl->getId3V2Stream()); if (0 == p) { return ""; } return p->getTime().getYear(); } }; struct TrackNoPattern : public PatternBase { TrackNoPattern(const InvalidCharsReplacer* pInvalidCharsReplacer) : PatternBase(pInvalidCharsReplacer) {} /*override*/ string getVal(const Mp3Handler* pHndl) const { const Id3V2StreamBase* p (pHndl->getId3V2Stream()); if (0 == p) { return "00"; } string s (p->getTrackNumber()); int n (atoi(s.c_str())); if (n <= 0) { return "00"; } char a [20]; sprintf(a, "%02d", n); return a; } }; struct RatingPattern : public PatternBase { RatingPattern(const InvalidCharsReplacer* pInvalidCharsReplacer, const bool& bUnratedAsDuplicate) : PatternBase(pInvalidCharsReplacer), m_bUnratedAsDuplicate(bUnratedAsDuplicate) {} const bool& m_bUnratedAsDuplicate; /*override*/ string getVal(const Mp3Handler* pHndl) const { const Id3V2StreamBase* p (pHndl->getId3V2Stream()); if (0 == p) { return ""; } double r (p->getRating()); if (r < 0) { return m_bUnratedAsDuplicate ? "q" : ""; } // from TrackTextReader::TrackTextReader // a b c d e f g h i j k l m n o p q r s t u v w x y z //static double s_ratingMap [] = { 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 1.5, 1.0, 1.0, 1.0, -1, -1, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.0 }; // note that if this changes it should be synchronized with TrackTextReader if (r >= 4.9) { return "a"; } if (r >= 4.4) { return "b"; } if (r >= 3.9) { return "c"; } if (r >= 3.4) { return "d"; } if (r >= 2.9) { return "e"; } if (r >= 2.4) { return "f"; } if (r >= 1.9) { return "g"; } if (r >= 1.4) { return "m"; } if (r >= 0.9) { return "n"; } if (r >= 0.4) { return "x"; } return "z"; } }; struct SequencePattern : public PatternBase { SequencePattern(const InvalidCharsReplacer* pInvalidCharsReplacer) : PatternBase(pInvalidCharsReplacer) {} /*override*/ ~SequencePattern() { clearPtrContainer(m_vpPatterns); } /*override*/ string getVal(const Mp3Handler* pHndl) const { return getVal(pHndl, ACCEPT_EMPTY); } string getNonNullVal(const Mp3Handler* pHndl) const { return getVal(pHndl, DONT_ACCEPT_EMPTY); } // returns an empty string if any of its components are empty void addPattern(const PatternBase* p) { m_vpPatterns.push_back(p); } private: enum { DONT_ACCEPT_EMPTY, ACCEPT_EMPTY }; vector<const PatternBase*> m_vpPatterns; string getVal(const Mp3Handler* pHndl, bool bAcceptEmpty) const { string strRes; for (int i = 0, n = cSize(m_vpPatterns); i < n; ++i) { string s (m_vpPatterns[i]->getVal(pHndl)); if (s.empty() && !bAcceptEmpty) { return s; } strRes += s; } return strRes; } }; struct OptionalPattern : public PatternBase { /*override*/ ~OptionalPattern() { delete m_pSequencePattern; } OptionalPattern(SequencePattern* pSequencePattern, const InvalidCharsReplacer* pInvalidCharsReplacer) : PatternBase(pInvalidCharsReplacer), m_pSequencePattern(pSequencePattern) {} /*override*/ string getVal(const Mp3Handler* pHndl) const { return m_pSequencePattern->getNonNullVal(pHndl); } private: SequencePattern* m_pSequencePattern; }; } // namespace FileRenamer //using namespace RenamerPatterns; Renamer::Renamer(const std::string& strPattern, const CommonData* pCommonData, bool bUnratedAsDuplicate1) : m_strPattern(strPattern), m_bSameDir(string::npos == strPattern.find(getPathSep())), m_pCommonData(pCommonData), m_bUnratedAsDuplicate(bUnratedAsDuplicate1) { if (0 != pCommonData) { m_pInvalidCharsReplacer.reset(new InvalidCharsReplacer(pCommonData->m_strRenamerInvalidChars, pCommonData->m_strRenamerReplacementString)); } else { m_pInvalidCharsReplacer.reset(new InvalidCharsReplacer("", "")); } m_pRoot = new SequencePattern(m_pInvalidCharsReplacer.get()); auto_ptr<SequencePattern> ap (m_pRoot); const char* p (strPattern.c_str()); SequencePattern* pSeq (m_pRoot); // pSeq is either m_pRoot or a new sequence, for optional elements if (0 == *p) { throw InvalidPattern(strPattern, "A pattern cannot be empty"); } // add pattern str on constr, to always have access to the pattern if (!m_bSameDir) { #ifndef WIN32 if (getPathSep() != *p) { throw InvalidPattern(strPattern, "A pattern must either begin with '" + getPathSepAsStr() + "' or contain no '" + getPathSepAsStr() + "' at all"); } #else if (cSize(strPattern) < 3 || ((p[0] < 'a' || p[0] > 'z') && (p[0] < 'A' || p[0] > 'Z')) || p[1] != ':') // ttt2 allow network drives as well { throw InvalidPattern(strPattern, "A pattern must either begin with \"<drive>:\\\" or contain no '\\' at all"); } p += 2; m_pRoot->addPattern(new StaticPattern(strPattern.substr(0, 2), m_pInvalidCharsReplacer.get())); if (getPathSep() != *p) { throw InvalidPattern(strPattern, "A pattern must either begin with \"<drive>:\\\" or contain no '\\' at all"); } #endif } #ifndef WIN32 #else #endif auto_ptr<SequencePattern> optAp; string strStatic; bool bTitleFound (false); //const char* q (p); for (; *p != 0; ++p) { char c (*p); switch (c) { case '%': { ++p; char c1 (*p); switch (c1) { case 'n': case 'a': case 't': case 'b': case 'y': case 'g': case 'c': case 'r': if (!strStatic.empty()) { pSeq->addPattern(new StaticPattern(strStatic, m_pInvalidCharsReplacer.get())); strStatic.clear(); } } switch (c1) { case 'n': pSeq->addPattern(new TrackNoPattern(m_pInvalidCharsReplacer.get())); break; case 'a': pSeq->addPattern(new FieldPattern(TagReader::ARTIST, m_pInvalidCharsReplacer.get())); break; case 't': pSeq->addPattern(new FieldPattern(TagReader::TITLE, m_pInvalidCharsReplacer.get())); bTitleFound = true; break; case 'b': pSeq->addPattern(new FieldPattern(TagReader::ALBUM, m_pInvalidCharsReplacer.get())); break; case 'y': pSeq->addPattern(new YearPattern(m_pInvalidCharsReplacer.get())); break; case 'g': pSeq->addPattern(new FieldPattern(TagReader::GENRE, m_pInvalidCharsReplacer.get())); break; case 'c': pSeq->addPattern(new FieldPattern(TagReader::COMPOSER, m_pInvalidCharsReplacer.get())); break; //ttt2 perhaps add something for "various artists" case 'r': pSeq->addPattern(new RatingPattern(m_pInvalidCharsReplacer.get(), m_bUnratedAsDuplicate)); break; case '%': case '[': case ']': //case '/': // ttt linux-specific // actually there's no need for '/' to be a special character here strStatic += c; break; default: { ostringstream s; s << "Error in column " << p - strPattern.c_str() << "."; throw InvalidPattern(strPattern, s.str()); // ttt2 more details, perhaps make tag edt errors more similar to this } } } break; case '[': { if (!strStatic.empty()) { pSeq->addPattern(new StaticPattern(strStatic, m_pInvalidCharsReplacer.get())); strStatic.clear(); } if (pSeq != m_pRoot) { throw InvalidPattern(strPattern, "Nested optional elements are not allowed"); } //ttt2 column pSeq = new SequencePattern(m_pInvalidCharsReplacer.get()); optAp.reset(pSeq); break; } case ']': { if (!strStatic.empty()) { pSeq->addPattern(new StaticPattern(strStatic, m_pInvalidCharsReplacer.get())); strStatic.clear(); } if (pSeq == m_pRoot) { throw InvalidPattern(strPattern, "Trying to close and optional element although none is open"); } //ttt2 column m_pRoot->addPattern(new OptionalPattern(pSeq, m_pInvalidCharsReplacer.get())); pSeq = m_pRoot; optAp.release(); break; } default: strStatic += c; } } if (!strStatic.empty()) { pSeq->addPattern(new StaticPattern(strStatic, m_pInvalidCharsReplacer.get())); strStatic.clear(); } if (pSeq != m_pRoot) { throw InvalidPattern(strPattern, "Optional element must be closed"); } //ttt2 column if (!bTitleFound) { throw InvalidPattern(strPattern, "Title entry (%t) must be present"); } ap.release(); } Renamer::~Renamer() { delete m_pRoot; } string Renamer::getNewName(const Mp3Handler* pHndl) const { if (0 == pHndl->getId3V2Stream()) { return ""; } if (m_mValues.count(pHndl) > 0) { return m_mValues[pHndl]; } string s (m_pRoot->getVal(pHndl)); CB_ASSERT (!m_bSameDir ^ (string::npos == s.find(getPathSep()))); if (m_bSameDir) { s = getParent(pHndl->getName()) + getPathSepAsStr() + s; } if (string::npos != s.find("//")) { return ""; } if (!s.empty()) { s += ".mp3"; } return s; } //ttt2 should be possible to filter by var/single artists and do the renaming for all; or have a checkbox in the renamer, but that requires the renamer to have the concept of an album //ttt2 add "reload()" //ttt2 add palette ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/fstream_unicode.h�����������������������������������������������������������0000644�0001750�0000144�00000060600�11253616340�016576� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef FStreamUtf8H #define FStreamUtf8H /* Drop-in replacements for ifstream, ofstream, and fstream, which take Unicode strings for filenames (instead of the char* strings in the system codepage that MinGW uses.) (There are ifstream, ofstream, and fstream correspondents, but only fstream is mentioned, for brevity.) Provides the class fstream_unicode, which allows opening of a file with the name given as a UTF-8 or a UTF-16 string. Provides fstream_utf8, which on Windows is a typedef for fstream_unicode, while elsewhere it's a typedef for std::basic_fstream (currently the assumption is that outside Windows everything is UTF-8, although the older a Linux system is, the more likely it is to have non-UTF-8 file names.) Normally fstream_utf8 seems the best to use, because Linux users are shielded from bugs in fstream_unicode. However, the situation of a particular project may dictate otherwise. Currently using wchar_t* to open files on Linux throws an exception. It would be easy to implement, but there's no use for it right now. While the name reflects the intended use, fstream_unicode can do more than just open files with names given as Unicode strings: you can pass an existing file descriptor on its constructor, or you can add a specialization of unicodeOpenHlp that turns some custom objects into file descriptors or into UTF-8 or UTF-16 strings, and then pass those objects to fstream_unicode's constructor or to its open() function. For example you can easily make fstream_unicode accept a std::string, without the need of calling c_str(). */ #ifdef __GNUC__ #include <ext/stdio_filebuf.h> #include <istream> #include <ostream> #include <fstream> #include <fcntl.h> // for open() template<class T> int unicodeOpenHlp(const T& handler, std::ios_base::openmode __mode); // converts __mode to flags that can be used by the POSIX open() function int getOpenFlags(std::ios_base::openmode __mode); //******************************************************************************************** //******************************************************************************************** //***************** ***************** //***************** Adapted from fstream included in the GNU ISO C++ Library ***************** //***************** ***************** //***************** From the Free Software Foundation, Inc. ***************** //***************** ***************** //***************** http://gcc.gnu.org/libstdc++/ ***************** //***************** ***************** //******************************************************************************************** //******************************************************************************************** // needed because the base class doesn't have open() template<typename _CharT, typename _Traits = std::char_traits<_CharT> > class stdio_filebuf_open : public __gnu_cxx::stdio_filebuf<_CharT, _Traits> { public: stdio_filebuf_open() : __gnu_cxx::stdio_filebuf<_CharT, _Traits>() {} stdio_filebuf_open(int __fd, std::ios_base::openmode __mode, size_t __size = static_cast<size_t>(BUFSIZ)) : __gnu_cxx::stdio_filebuf<_CharT, _Traits>(__fd, __mode, __size) {} /*override*/ ~stdio_filebuf_open() {} /* typedef _Traits traits_type; typedef typename traits_type::off_type off_type; */ typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; typedef std::basic_streambuf<char_type, traits_type> __streambuf_type; typedef typename __gnu_cxx::stdio_filebuf<_CharT, _Traits>::__filebuf_type __filebuf_type; typedef typename __gnu_cxx::stdio_filebuf<_CharT, _Traits>::__file_type __file_type; typedef typename traits_type::state_type __state_type; typedef typename __gnu_cxx::stdio_filebuf<_CharT, _Traits>::__codecvt_type __codecvt_type; //using __gnu_cxx::stdio_filebuf<_CharT, _Traits>::open; __filebuf_type* open(int __fd, std::ios_base::openmode __mode) { //close(); __filebuf_type *__ret = NULL; if (!this->is_open()) { this->_M_file.sys_open(__fd, __mode); if (this->is_open()) { this->_M_allocate_internal_buffer(); this->_M_mode = __mode; // Setup initial buffer to 'uncommitted' mode. this->_M_reading = false; this->_M_writing = false; this->_M_set_buffer(-1); // Reset to initial state. this->_M_state_last = this->_M_state_cur = this->_M_state_beg; // 27.8.1.3,4 if ((__mode & std::ios_base::ate) && this->seekoff(0, std::ios_base::end, __mode) == pos_type(off_type(-1))) this->close(); else __ret = this; // this->_M_mode = __mode; //this->_M_buf_size = __size; // this->_M_allocate_internal_buffer(); // this->_M_reading = false; // this->_M_writing = false; // this->_M_set_buffer(-1); } } return __ret; } }; // [27.8.1.5] Template class basic_ifstream /** * @brief Controlling input for files. * * This class supports reading from named files, using the inherited * functions from std::basic_istream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. */ template<typename _CharT, typename _Traits = std::char_traits<_CharT> > class basic_ifstream_unicode : public std::basic_istream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef stdio_filebuf_open<char_type, traits_type> __filebuf_type; typedef std::basic_istream<char_type, traits_type> __istream_type; private: __filebuf_type _M_filebuf; public: // Constructors/Destructors: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_ifstream_unicode() : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an input file stream. * @param x Null terminated string specifying the filename, or a file descriptor, or anything for which a specialization of unicodeOpenHlp exists. * @param mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a mode. * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. */ template<class T> explicit basic_ifstream_unicode(T x, std::ios_base::openmode __mode = std::ios_base::in) : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(x, __mode); } /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_ifstream_unicode() { } // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param x Null terminated string specifying the filename, or a file descriptor, or anything for which a specialization of unicodeOpenHlp exists. * @param mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,mode|in). If that function * fails, @c failbit is set in the stream's error state. * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. */ template<class T> void open(const T& x, std::ios_base::openmode __mode = std::ios_base::in) { if (!_M_filebuf.open(unicodeOpenHlp(x, __mode | std::ios_base::in), __mode | std::ios_base::in)) this->setstate(std::ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(std::ios_base::failbit); } }; // [27.8.1.8] Template class basic_ofstream /** * @brief Controlling output for files. * * This class supports reading from named files, using the inherited * functions from std::basic_ostream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. */ template<typename _CharT, typename _Traits = std::char_traits<_CharT> > class basic_ofstream_unicode : public std::basic_ostream<_CharT,_Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef stdio_filebuf_open<char_type, traits_type> __filebuf_type; typedef std::basic_ostream<char_type, traits_type> __ostream_type; private: __filebuf_type _M_filebuf; public: // Constructors: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_ofstream_unicode(): __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an output file stream. * @param x Null terminated string specifying the filename, or a file descriptor, or anything for which a specialization of unicodeOpenHlp exists. * @param mode Open file in specified mode (see std::ios_base). * * @c ios_base::out|ios_base::trunc is automatically included in * @a mode. * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. */ template<class T> explicit basic_ofstream_unicode(T x, std::ios_base::openmode __mode = std::ios_base::out|std::ios_base::trunc) : __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(x, __mode); } /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_ofstream_unicode() { } // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param x Null terminated string specifying the filename, or a file descriptor, or anything for which a specialization of unicodeOpenHlp exists. * @param mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that * function fails, @c failbit is set in the stream's error state. * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. */ template<class T> void open(const T& x, std::ios_base::openmode __mode = std::ios_base::out | std::ios_base::trunc) { if (!_M_filebuf.open(unicodeOpenHlp(x, __mode | std::ios_base::out), __mode | std::ios_base::out)) this->setstate(std::ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(std::ios_base::failbit); } }; // [27.8.1.11] Template class basic_fstream /** * @brief Controlling input and output for files. * * This class supports reading from and writing to named files, using * the inherited functions from std::basic_iostream. To control the * associated sequence, an instance of std::basic_filebuf is used, which * this page refers to as @c sb. */ template<typename _CharT, typename _Traits = std::char_traits<_CharT> > class basic_fstream_unicode : public std::basic_iostream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef stdio_filebuf_open<char_type, traits_type> __filebuf_type; typedef std::basic_ios<char_type, traits_type> __ios_type; typedef std::basic_iostream<char_type, traits_type> __iostream_type; private: __filebuf_type _M_filebuf; public: // Constructors/destructor: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_fstream_unicode() : __iostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an input/output file stream. * @param x Null terminated string specifying the filename, or a file descriptor, or anything for which a specialization of unicodeOpenHlp exists. * @param mode Open file in specified mode (see std::ios_base). * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. */ template<class T> explicit basic_fstream_unicode(T x, std::ios_base::openmode __mode = std::ios_base::in | std::ios_base::out) : __iostream_type(NULL), _M_filebuf() { this->init(&_M_filebuf); this->open(x, __mode); } /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_fstream_unicode() { } // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param x Null terminated string specifying the filename, or a file descriptor, or anything for which a specialization of unicodeOpenHlp exists. * @param mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,mode). If that * function fails, @c failbit is set in the stream's error state. * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. */ template<class T> void open(const T& x, std::ios_base::openmode __mode = std::ios_base::in | std::ios_base::out) { if (!_M_filebuf.open(unicodeOpenHlp(x, __mode), __mode)) this->setstate(std::ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(std::ios_base::failbit); } }; #ifndef WIN32 //inline const char* unicodeOpenHlp(const char* szUtf8Name) { return szUtf8Name; } //int unicodeOpenHlp(const char* szUtf8Name, std::ios_base::openmode __mode); #include <fstream> typedef std::basic_ifstream<char> ifstream_utf8; typedef std::basic_ofstream<char> ofstream_utf8; typedef std::basic_fstream<char> fstream_utf8; #else typedef basic_ifstream_unicode<char> ifstream_utf8; typedef basic_ofstream_unicode<char> ofstream_utf8; typedef basic_fstream_unicode<char> fstream_utf8; #endif // #ifndef WIN32 / else typedef basic_ifstream_unicode<char> ifstream_unicode; typedef basic_ofstream_unicode<char> ofstream_unicode; typedef basic_fstream_unicode<char> fstream_unicode; #elif defined(_MSC_VER) && _MSC_VER>=1400 // #ifdef __GNUC__ // Visual Studio port by Sebastian Schuberth // As of Visual Studio 2005 (aka version 8.0), the supplied STL has extensions // that accept filenames of type wchar_t. #include <fstream> #define NOMINMAX 1 #define WIN32_LEAN_AND_MEAN 1 #include <windows.h> typedef std::ifstream ifstream_unicode; typedef std::ofstream ofstream_unicode; typedef std::fstream fstream_unicode; class ifstream_utf8:public std::ifstream { public: explicit ifstream_utf8(char const* _Filename,ios_base::openmode _Mode=ios_base::in,int _Prot=(int)ios_base::_Openprot) { open(_Filename,_Mode,_Prot); } void open(char const* _Filename,ios_base::openmode _Mode=ios_base::in,int _Prot=(int)ios_base::_Openprot) { int length=MultiByteToWideChar(CP_UTF8,0,_Filename,-1,NULL,0); if (length>0) { wchar_t* buffer=new wchar_t[length+1]; MultiByteToWideChar(CP_UTF8,0,_Filename,-1,buffer,length); std::ifstream::open(buffer,_Mode,_Prot); delete [] buffer; } else { setstate(ios_base::failbit); } } void open(char const* _Filename,ios_base::open_mode _Mode) { open(_Filename,_Mode); } }; class ofstream_utf8:public std::ofstream { public: explicit ofstream_utf8(char const* _Filename,ios_base::openmode _Mode=ios_base::out,int _Prot=(int)ios_base::_Openprot) { open(_Filename,_Mode,_Prot); } void open(char const* _Filename,ios_base::openmode _Mode=ios_base::out,int _Prot=(int)ios_base::_Openprot) { int length=MultiByteToWideChar(CP_UTF8,0,_Filename,-1,NULL,0); if (length>0) { wchar_t* buffer=new wchar_t[length+1]; MultiByteToWideChar(CP_UTF8,0,_Filename,-1,buffer,length); std::ofstream::open(buffer,_Mode,_Prot); delete [] buffer; } else { setstate(ios_base::failbit); } } void open(char const* _Filename,ios_base::open_mode _Mode) { open(_Filename,_Mode); } }; class fstream_utf8:public std::fstream { public: explicit fstream_utf8(char const* _Filename,ios_base::openmode _Mode=ios_base::in|ios_base::out,int _Prot=(int)ios_base::_Openprot) { open(_Filename,_Mode,_Prot); } void open(char const* _Filename,ios_base::openmode _Mode=ios_base::in|ios_base::out,int _Prot=(int)ios_base::_Openprot) { int length=MultiByteToWideChar(CP_UTF8,0,_Filename,-1,NULL,0); if (length>0) { wchar_t* buffer=new wchar_t[length+1]; MultiByteToWideChar(CP_UTF8,0,_Filename,-1,buffer,length); std::fstream::open(buffer,_Mode,_Prot); delete [] buffer; } else { setstate(ios_base::failbit); } } void open(char const* _Filename,ios_base::open_mode _Mode) { open(_Filename,_Mode); } }; #else // _MSC_VER / __GNUC__ //#error classes i/ofstream_utf8 need to be ported to this compiler #warning classes i/ofstream_utf8 need to be ported to your compiler #include <fstream> typedef std::basic_ifstream<char> ifstream_utf8; typedef std::basic_ofstream<char> ofstream_utf8; typedef std::basic_fstream<char> fstream_utf8; #endif // _MSC_VER / __GNUC__ #endif // FStreamUtf8H ��������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/FileRenamer.ui��������������������������������������������������������������0000644�0001750�0000144�00000021425�11265317206�016012� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>FileRenamerDlg</class> <widget class="QDialog" name="FileRenamerDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>1003</width> <height>579</height> </rect> </property> <property name="windowTitle" > <string>MP3 Diags - File renamer</string> </property> <property name="sizeGripEnabled" > <bool>true</bool> </property> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="widget_6" > <layout class="QHBoxLayout" > <property name="spacing" > <number>20</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QWidget" native="1" name="widget" > <layout class="QHBoxLayout" > <property name="spacing" > <number>3</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QToolButton" name="m_pPrevB" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="toolTip" > <string>Previous [Ctrl+P]</string> </property> <property name="text" > <string><</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/go-previous.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="shortcut" > <string>Ctrl+P</string> </property> <property name="autoRaise" > <bool>true</bool> </property> <property name="arrowType" > <enum>Qt::NoArrow</enum> </property> </widget> </item> <item> <widget class="QLineEdit" name="m_pCrtDirTagEdtE" > <property name="toolTip" > <string>Folder</string> </property> <property name="readOnly" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pNextB" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="toolTip" > <string>Next [Ctrl+N]</string> </property> <property name="text" > <string>></string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/go-next.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="shortcut" > <string>Ctrl+N</string> </property> <property name="autoRaise" > <bool>true</bool> </property> <property name="arrowType" > <enum>Qt::NoArrow</enum> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QCheckBox" name="m_pKeepOriginalCkB" > <property name="toolTip" > <string>If this is checked, a copy of the file is created, and both original and copy are kept</string> </property> <property name="text" > <string>Keep the original file</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="m_pMarkUnratedAsDuplicatesCkB" > <property name="toolTip" > <string/> </property> <property name="text" > <string>Mark unrated as duplicates</string> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pEditPatternsB" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="toolTip" > <string>Edit patterns</string> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/patterns.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> <item> <widget class="QToolButton" name="m_pRenameB" > <property name="minimumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="maximumSize" > <size> <width>40</width> <height>40</height> </size> </property> <property name="focusPolicy" > <enum>Qt::NoFocus</enum> </property> <property name="toolTip" > <string>Rename</string> </property> <property name="text" > <string>...</string> </property> <property name="icon" > <iconset resource="Mp3Diags.qrc" >:/images/rename.svg</iconset> </property> <property name="iconSize" > <size> <width>36</width> <height>36</height> </size> </property> <property name="autoRaise" > <bool>true</bool> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QTableView" name="m_pCurrentAlbumG" /> </item> <item> <widget class="QWidget" native="1" name="m_pBtnPanelW" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <widget class="QLabel" name="m_pAlbumTypeL" > <property name="text" > <string>alb type</string> </property> </widget> </item> <item> <widget class="QWidget" native="1" name="m_pButtonsW" > <layout class="QHBoxLayout" > <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> </layout> </widget> </item> </layout> </widget> </item> </layout> </widget> <resources> <include location="Mp3Diags.qrc" /> </resources> <connections/> </ui> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/TagEdtPatternsDlgImpl.h�����������������������������������������������������0000644�0001750�0000144�00000004733�11233524007�017572� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TagEdtPatternsDlgImplH #define TagEdtPatternsDlgImplH #include <QDialog> #include "ui_Patterns.h" #include <vector> #include <string> class SessionSettings; class TagEdtPatternsDlgImpl : public QDialog, private Ui::PatternsDlg { Q_OBJECT std::vector<std::string> m_vPatterns; SessionSettings& m_settings; const std::vector<std::string>& m_vstrPredef; int m_nCrtLine, m_nCrtCol; public: TagEdtPatternsDlgImpl(QWidget* pParent, SessionSettings& settings, const std::vector<std::string>& vstrPredef); ~TagEdtPatternsDlgImpl(); bool run(std::vector<std::pair<std::string, int> >&); // the int is ignored for input; for output, it tells which position a given pattern occupied in the input, or -1 if it's a new string protected slots: void on_m_pOkB_clicked(); void on_m_pCancelB_clicked(); void on_m_pAddPredefB_clicked(); void onHelp(); void onCrtPosChanged(); }; #endif // #ifndef TagEdtPatternsDlgImplH �������������������������������������MP3Diags-1.0.12.079/src/Transformation.cpp����������������������������������������������������������0000644�0001750�0000144�00000075664�11570757114�017017� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <sstream> #include <iomanip> #include <QDir> #include <QMessageBox> #include "Transformation.h" #include "Helpers.h" #include "OsFile.h" #include "Mp3Manip.h" #include "CommonData.h" using namespace std; using namespace pearl; /*static const string& getOsTempDir() { static string s; // ttt3 these static variables are not really thread safe, but in this case it doesn't matter, because they all get called from a single thread (the UI thread) if (s.empty()) { s = convStr(QDir::tempPath()); if (endsWith(s, getPathSepAsStr())) { s.erase(s.size() - 1, 1); } } return s; } */ //ttt2 review all defaults static string getDefaultSrc() { return ""; } //ttt2 see if src dir needs to be revived static string getDefaultUnprocOrig() { return convStr(getTempDir()) + "/mp3diags/unprocOrig"; } static string getDefaultProcessed() { return convStr(getTempDir()) + "/mp3diags/proc"; } static string getDefaultProcOrig() { return convStr(getTempDir() + "/mp3diags/procOrig"); } static string getDefaultTemp() { return convStr(getTempDir() + "/mp3diags/temp"); } static string getDefaultComp() { return convStr(getTempDir() + "/mp3diags/comp"); } /*static TransfConfig::OptionsWrp getDefaultOptions() { TransfConfig::OptionsWrp x; x.m_nVal = 0; x.m_opt.m_bTempCreate = true; x.m_opt.m_bCompCreate = true; x.m_opt.m_nProcessedCreate = 1; // create and always rename, since it is created in the same dir as the source x.m_opt.m_bProcessedUseLabel = true; x.m_opt.m_bProcessedAlwayUseCounter = false; x.m_opt.m_bProcessedUseSeparateDir = false; x.m_opt.m_nUnprocOrigChange = 0; x.m_opt.m_bUnprocOrigUseLabel = false; x.m_opt.m_bUnprocOrigAlwayUseCounter = false; x.m_opt.m_nProcOrigChange = 0; x.m_opt.m_bProcOrigUseLabel = false; x.m_opt.m_bProcOrigAlwayUseCounter = false; return x; }*/ TransfConfig::Options::Options() : //m_nProcOrigChange(5), // move w/o renaming, if doesn't exist; discard if it exists; m_eProcOrigChange(PO_ERASE), // erase m_bProcOrigUseLabel(false), m_bProcOrigAlwayUseCounter(false), m_eUnprocOrigChange(UPO_DONT_CHG), // don't change m_bUnprocOrigUseLabel(false), m_bUnprocOrigAlwayUseCounter(false), m_eProcessedCreate(PR_CREATE_RENAME_IF_USED), // create and rename if the name is in use m_bProcessedUseLabel(true), m_bProcessedAlwayUseCounter(true), m_bProcessedUseSeparateDir(false), m_bTempCreate(false), m_bCompCreate(false), m_bKeepOrigTime(false) { } // returns *this, with some fields changed to match a "backup" configuration; touches many field, but ignores others (m_bProcOrigUseLabel, m_bProcOrigAlwayUseCounter, m_bUnprocOrigUseLabel, m_bUnprocOrigAlwayUseCounter, m_bKeepOrigTime) TransfConfig::Options TransfConfig::Options::asBackup() const { Options opt (*this); opt.m_bTempCreate = false; opt.m_bCompCreate = false; opt.m_eProcOrigChange = PO_MOVE_OR_ERASE; //opt.m_bProcOrigUseLabel = false; //opt.m_bProcOrigAlwayUseCounter = false; opt.m_eUnprocOrigChange = UPO_DONT_CHG; // don't change //opt.m_bUnprocOrigUseLabel = false; //opt.m_bUnprocOrigAlwayUseCounter = false; opt.m_eProcessedCreate = PR_CREATE_RENAME_IF_USED; // create and rename if the name is in use opt.m_bProcessedUseLabel = true; opt.m_bProcessedAlwayUseCounter = true; opt.m_bProcessedUseSeparateDir = false; //opt.m_bKeepOrigTime = false; return opt; } // returns *this, with some fields changed to match a "non-backup" configuration; touches many field, but ignores others (m_bProcOrigUseLabel, m_bProcOrigAlwayUseCounter, m_bUnprocOrigUseLabel, m_bUnprocOrigAlwayUseCounter, m_bKeepOrigTime) TransfConfig::Options TransfConfig::Options::asNonBackup() const { Options opt (*this); opt.m_bTempCreate = false; opt.m_bCompCreate = false; opt.m_eProcOrigChange = PO_ERASE; // move w/o renaming, if doesn't exist; discard if it exists; //opt.m_bProcOrigUseLabel = false; //opt.m_bProcOrigAlwayUseCounter = false; opt.m_eUnprocOrigChange = UPO_DONT_CHG; // don't change //opt.m_bUnprocOrigUseLabel = false; //opt.m_bUnprocOrigAlwayUseCounter = false; opt.m_eProcessedCreate = PR_CREATE_RENAME_IF_USED; // create and rename if the name is in use opt.m_bProcessedUseLabel = true; opt.m_bProcessedAlwayUseCounter = true; opt.m_bProcessedUseSeparateDir = false; //opt.m_bKeepOrigTime = false; return opt; } // like getDefaultOptions() but does backups rather than erase the original file (if a backup exists, the file is deleted, though) /*static* / TransfConfig::Options TransfConfig::getBackupDefaultOptions() { Options opt (getDefaultOptions()); opt.m_nProcOrigChange = 5; // move w/o renaming, if doesn't exist; discard if it exists; return opt; } */ TransfConfig::TransfConfig( const std::string& strSrcDir, const std::string& strProcOrigDir, const std::string& strUnprocOrigDir, const std::string& strProcessedDir, const std::string& strTempDir, const std::string& strCompDir, int nOptions // may be -1 to indicate "default" values ) { m_bInitError = false; m_strSrcDir = "*" == strSrcDir ? getDefaultSrc() : strSrcDir; m_strProcOrigDir = "*" == strProcOrigDir ? getDefaultProcOrig() : strProcOrigDir; m_strUnprocOrigDir = "*" == strUnprocOrigDir ? getDefaultUnprocOrig() : strUnprocOrigDir; m_strProcessedDir = "*" == strProcessedDir ? getDefaultProcessed() : strProcessedDir; m_strTempDir = "*" == strTempDir ? getDefaultTemp() : strTempDir; m_strCompDir = "*" == strCompDir ? getDefaultComp() : strCompDir; if (nOptions >= 0x00040000) { // only the first 18 bits are supposed to be used; if more seem to be used, it is because of a manually entered wrong value or because a change in the bitfield representation; QMessageBox::critical(getMainForm(), "Error", "Invalid value found for file settings. Reverting to default settings."); nOptions = -1; m_bInitError = true; } if (-1 != nOptions) { m_options.setVal(nOptions); } checkDirName(m_strSrcDir); checkDirName(m_strProcOrigDir); // some of these dirs are allowed to be empty, just like src when comes from the config dialog, empty meaning "/", so that should work for all, probably checkDirName(m_strUnprocOrigDir); checkDirName(m_strProcessedDir); checkDirName(m_strTempDir); checkDirName(m_strCompDir); } TransfConfig::TransfConfig() { m_strSrcDir = getDefaultSrc(); m_strProcOrigDir = getDefaultProcOrig(); m_strUnprocOrigDir = getDefaultUnprocOrig(); m_strProcessedDir = getDefaultProcessed(); m_strTempDir = getDefaultTemp(); m_strCompDir = getDefaultComp(); } // last '/' goes to dir; last '.' goes to ext (if extension present) void TransfConfig::splitOrigName(const string& strOrigSrcName, std::string& strRelDir, std::string& strBaseName, std::string& strExt) const { //TRACER1A("splitOrigName ", 1); //Tracer t1 (strOrigName); CB_CHECK1 (beginsWith(strOrigSrcName, m_strSrcDir), IncorrectPath()); strRelDir = strOrigSrcName.substr(m_strSrcDir.size()); #if defined(WIN32) //CB_CHECK1 (beginsWith(strRelDir, getPathSepAsStr()), IncorrectPath()); //ttt2 see if it's OK to skip this test on Windows; it probably is, because it's more of an assert and the fact that it's not triggered on Linux should be enough #elif defined(OS2) || defined(__OS2__) //nothing #else CB_CHECK1 (beginsWith(strRelDir, getPathSepAsStr()), IncorrectPath()); #endif string::size_type nLastSep (strRelDir.rfind(getPathSep())); string::size_type nLastPer (strRelDir.rfind('.')); if (nLastPer > nLastSep) { // the file has an extension strExt = strRelDir.substr(nLastPer); strRelDir.erase(nLastPer, string::npos); } strBaseName = strRelDir.substr(nLastSep + 1); strRelDir.erase(nLastSep + 1, string::npos); } /* static int s_anPositions[] = { 0, 1, 2, 4, 5, 6, 7, 10, 11, 12, 14, 15, 16 }; int TransfConfig::getOptionValue(Option eOption) const { return getOpt(s_anPositions[eOption], s_anPositions[eOption + 1] - s_anPositions[eOption]); }*/ // adds a counter and/or a label, such that a file with the resulting name doesn't exist; /*static*/ string TransfConfig::addLabelAndCounter(const string& s1, const string& s2, const string& strLabel, bool bAlwaysUseCounter, bool bAlwaysRename) { string strRes; if (!bAlwaysRename) { strRes = replaceDriveLetter(s1 + s2); if (!fileExists(strRes)) { createDirForFile(strRes); return strRes; } } string strLabel2 (strLabel); if (!strLabel2.empty()) { strLabel2.insert(0, "."); } if (!bAlwaysUseCounter && !strLabel2.empty()) { strRes = replaceDriveLetter(s1 + strLabel2 + s2); if (!fileExists(strRes)) { createDirForFile(strRes); return strRes; } } for (int i = 1; ; ++i) { { ostringstream out; out << "." << setfill('0') << setw(3) << i; strRes = replaceDriveLetter(s1 + strLabel2 + out.str() + s2); } if (!fileExists(strRes)) { createDirForFile(strRes); return strRes; } } } // normally makes sure that the name returned doesn't exist, by applying any renaming specified in the params; there's an exception, though: is bAllowDup is true, duplicates are allowed string TransfConfig::getRenamedName(const std::string& strOrigSrcName, const std::string& strNewRootDir, const std::string& strLabel, bool bAlwayUseCounter, bool bAlwaysRename, bool bAllowDup /*= false*/) const // bAllowDup is needed only for the option 5 of m_nProcOrigChange, when ORIG_MOVE_OR_ERASE gets returned { /* steps 1. decide if it should rename, based on bAlwaysRename (merely changing the folder isn't considered renaming) 2. if it should rename: 2.1 add the label (if it's empty, there's nothing to add) 2.2 if bAlwayUseCounter is false and there's a label, try first with that label 2.2.1 if the name doesn't exist, return 2.3 increment the counter until a new name is found (note that addCounter() does all that's needed for 2 */ string strRelDir; string strBaseName; string strExt; //TRACER1A("getRenamedName ", 1); splitOrigName(strOrigSrcName, strRelDir, strBaseName, strExt); string strRes; if (!bAlwaysRename) { // aside from the new folder, no renaming takes places if this new name isn't in use strRes = replaceDriveLetter(strNewRootDir + strRelDir + strBaseName + strExt); if (!fileExists(strRes) || bAllowDup) { createDirForFile(strRes); return strRes; } } /*if (!bAlwayUseCounter && !strLabel.empty()) { // now try to use the label but not the counter strRes = strNewRootDir + strRelDir + strBaseName + strExt; if (!fileExists(strRes)) { createDirForFile(strRes); return strRes; } }*/ //out << strNewRootDir << strRelDir << strBaseName << (strLabel.empty() ? "" : ".") << strLabel; string s1 (strNewRootDir + strRelDir + strBaseName); //setfill('0') << setw(3) << i << strExt; return addLabelAndCounter(s1, strExt, strLabel, bAlwayUseCounter, bAlwaysRename); } TransfConfig::OrigFile TransfConfig::getChangedOrigNameHlp(const string& strOrigSrcName, const string& strDestDir, int nChange, bool bUseLabel, bool bAlwayUseCounter, string& strNewName) const { switch (nChange) // !!! nChange must match both ProcOrig and UnprocOrig, since getChangedOrigNameHlp() gets called in both cases { case Options::PO_DONT_CHG: // don't change unprocessed orig file strNewName = strOrigSrcName; return ORIG_DONT_CHANGE; case Options::PO_ERASE: // erase unprocessed orig file strNewName = strOrigSrcName; return ORIG_ERASE; case Options::PO_MOVE_ALWAYS_RENAME: // move unprocessed orig file to strDestDir; always rename strNewName = getRenamedName(strOrigSrcName, strDestDir, bUseLabel ? "orig" : "", bAlwayUseCounter, ALWAYS_RENAME); return ORIG_MOVE; case Options::PO_MOVE_RENAME_IF_USED: // move unprocessed orig file to strDestDir; rename only if name is in use strNewName = getRenamedName(strOrigSrcName, strDestDir, bUseLabel ? "orig" : "", bAlwayUseCounter, RENAME_IF_NEEDED); return ORIG_MOVE; case Options::PO_RENAME_SAME_DIR: // rename in the same dir strNewName = getRenamedName(strOrigSrcName, m_strSrcDir, bUseLabel ? "orig" : "", bAlwayUseCounter, ALWAYS_RENAME); return ORIG_MOVE; case Options::PO_MOVE_OR_ERASE: // move unprocessed orig file to strDestDir if it's not already there; erase if it exists; strNewName = getRenamedName(strOrigSrcName, strDestDir, "", USE_COUNTER_IF_NEEDED, RENAME_IF_NEEDED, ALLOW_DUPLICATES); return ORIG_MOVE_OR_ERASE; default: CB_ASSERT(false); } } TransfConfig::OrigFile TransfConfig::getProcOrigName(string strOrigSrcName, string& strNewName) const { removeSuffix(strOrigSrcName); return getChangedOrigNameHlp(strOrigSrcName, m_strProcOrigDir, m_options.m_eProcOrigChange, m_options.m_bProcOrigUseLabel, m_options.m_bProcOrigAlwayUseCounter, strNewName); } TransfConfig::OrigFile TransfConfig::getUnprocOrigName(string strOrigSrcName, string& strNewName) const { removeSuffix(strOrigSrcName); return getChangedOrigNameHlp(strOrigSrcName, m_strUnprocOrigDir, m_options.m_eUnprocOrigChange, m_options.m_bUnprocOrigUseLabel, m_options.m_bUnprocOrigAlwayUseCounter, strNewName); } void TransfConfig::removeSuffix(string& s) const { /* // !!! this seemed too aggressive; for (;;) { string::size_type nPos (s.rfind(".orig.")); if (string::npos == nPos) { break; } s.erase(nPos, 5); } for (;;) { string::size_type nPos (s.rfind(".proc.")); if (string::npos == nPos) { break; } s.erase(nPos, 5); } for (;;) { int n (cSize(s)); if (!endsWith(s, ".mp3") || n <= 4 + 4) { break; } if ('.' != s[n - 8] || !isdigit(s[n - 7]) || !isdigit(s[n - 6]) || !isdigit(s[n - 5])) { break; } s.erase(n - 8, 4); } */ string::size_type n (s.size()); string::size_type nPos (s.rfind(".orig.")); if (string::npos != nPos && nPos > 0 && nPos == n - 9) { s.erase(n - 9, 5); return; } if (string::npos != nPos && nPos > 0 && nPos == n - 13 && isdigit(s[n - 7]) && isdigit(s[n - 6]) && isdigit(s[n - 5]) && '.' == s[n - 4]) { s.erase(n - 13, 9); return; } nPos = s.rfind(".proc."); if (string::npos != nPos && nPos > 0 && nPos == n - 9) { s.erase(n - 9, 5); return; } if (string::npos != nPos && nPos > 0 && nPos == n - 13 && isdigit(s[n - 7]) && isdigit(s[n - 6]) && isdigit(s[n - 5]) && '.' == s[n - 4]) { s.erase(n - 13, 9); return; } //ttt2 this needs to be revisited if files with extensions other than ".mp3" are accepted } void TransfConfig::testRemoveSuffix() const { string s; const char* p; p = "abc.orig.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".orig.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".orig.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "ww trty.orig.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "abc.orig.003.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".orig.003.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".orig.003.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "ww trty.orig.003.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "abc.orig.03.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".orig.03.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".orig.03.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "ww trty.orig.03.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); qDebug("-------------------------------------"); p = "abc.proc.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".proc.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".proc.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "ww trty.proc.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "abc.proc.003.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".proc.003.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".proc.003.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "ww trty.proc.003.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "abc.proc.03.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".proc.03.mp3"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = ".proc.03.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); p = "ww trty.proc.03.mp"; s = p; removeSuffix(s); qDebug("pref: %s => %s", p, s.c_str()); qDebug("-------------------------------------"); } TransfConfig::TransfFile TransfConfig::getProcessedName(string strOrigSrcName, std::string& strName) const { //TRACER1A("getProcessedName ", 1); removeSuffix(strOrigSrcName); //TRACER1A("getProcessedName ", 2); switch (m_options.m_eProcessedCreate) { case Options::PR_DONT_CREATE: // don't create proc files { //TRACER1A("getProcessedName ", 3); strName.clear(); return TRANSF_DONT_CREATE; } case Options::PR_CREATE_ALWAYS_RENAME: // create proc files and always rename { //TRACER1A("getProcessedName ", 4); strName = getRenamedName(strOrigSrcName, m_options.m_bProcessedUseSeparateDir ? m_strProcessedDir : m_strSrcDir, m_options.m_bProcessedUseLabel ? "proc" : "", m_options.m_bProcessedAlwayUseCounter, ALWAYS_RENAME); return TRANSF_CREATE; } case Options::PR_CREATE_RENAME_IF_USED: // create proc files and rename if the name is in use { //TRACER1A("getProcessedName ", 5); strName = getRenamedName(strOrigSrcName, m_options.m_bProcessedUseSeparateDir ? m_strProcessedDir : m_strSrcDir, m_options.m_bProcessedUseLabel ? "proc" : "", m_options.m_bProcessedAlwayUseCounter, RENAME_IF_NEEDED); return TRANSF_CREATE; } default: CB_ASSERT(false); } } TransfConfig::TransfFile TransfConfig::getTempName(string strOrigSrcName, const std::string& strOpName, std::string& strName) const { removeSuffix(strOrigSrcName); if (!m_options.m_bTempCreate) { strName = getTempFile(strOrigSrcName); return TRANSF_DONT_CREATE; } string strRelDir; string strBaseName; string strExt; splitOrigName(strOrigSrcName, strRelDir, strBaseName, strExt); //string strRes; { ostringstream out; out << m_strTempDir << strRelDir << strBaseName << ".temp " << strOpName; strName = addLabelAndCounter(out.str(), strExt, "", ALWAYS_USE_COUNTER, ALWAYS_RENAME); return TRANSF_CREATE; } } TransfConfig::TransfFile TransfConfig::getCompNames(string strOrigSrcName, const std::string& strOpName, std::string& strBefore, std::string& strAfter) const { removeSuffix(strOrigSrcName); if (!m_options.m_bCompCreate) { strBefore = getTempFile(strOrigSrcName); strAfter = getTempFile(strOrigSrcName); return TRANSF_DONT_CREATE; } string strRelDir; string strBaseName; string strExt; splitOrigName(strOrigSrcName, strRelDir, strBaseName, strExt); /*{ ostringstream out; //out << m_strCompDir << strRelDir << strBaseName << ".1(before " << strOpName << ")" << strExt; strBefore = out.str(); } { ostringstream out; out << m_strCompDir << strRelDir << strBaseName << ".2(after " << strOpName << ")" << strExt; strAfter = out.str(); } if (!fileExists(strBefore) && !fileExists(strAfter)) { createDirForFile(strAfter); return TRANSF_CREATE; }*/ /*for (int i = 1; ; ++i) { { ostringstream out; //out << m_strCompDir << strRelDir << strBaseName << ".1(before " << strOpName << ")." << setfill('0') << setw(3) << i << strExt; out << m_strCompDir << strRelDir << strBaseName << "." << setfill('0') << setw(3) << i << "a (before " << strOpName << ")" << strExt; strBefore = out.str(); } { ostringstream out; //out << m_strCompDir << strRelDir << strBaseName << ".2(after " << strOpName << ")." << setfill('0') << setw(3) << i << strExt; out << m_strCompDir << strRelDir << strBaseName << "." << setfill('0') << setw(3) << i << "b (after " << strOpName << ")" << strExt; strAfter = out.str(); } if (!fileExists(strBefore) && !fileExists(strAfter)) { createDirForFile(strAfter); return TRANSF_CREATE; } }*/ int i (1); //File Searcher fs; for (;; ++i) { ostringstream out; string strDir (m_strCompDir + strRelDir); out << strBaseName << "." << setfill('0') << setw(3) << i << "*"; string strFile (out.str()); QDir d (convStr(strDir)); QStringList nameFlt; nameFlt << convStr(strFile); if (d.entryList(nameFlt).isEmpty()) { break; } } { ostringstream out; //out << m_strCompDir << strRelDir << strBaseName << ".1(before " << strOpName << ")." << setfill('0') << setw(3) << i << strExt; out << m_strCompDir << strRelDir << strBaseName << "." << setfill('0') << setw(3) << i << "a (before " << strOpName << ")" << strExt; strBefore = out.str(); } { ostringstream out; //out << m_strCompDir << strRelDir << strBaseName << ".2(after " << strOpName << ")." << setfill('0') << setw(3) << i << strExt; out << m_strCompDir << strRelDir << strBaseName << "." << setfill('0') << setw(3) << i << "b (after " << strOpName << ")" << strExt; strAfter = replaceDriveLetter(out.str()); } createDirForFile(strAfter); return TRANSF_CREATE; } TransfConfig::OrigFile TransfConfig::getProcOrigAction() const { switch (m_options.m_eProcOrigChange) { case Options::PO_DONT_CHG: // don't change unprocessed orig file return ORIG_DONT_CHANGE; case Options::PO_ERASE: // erase unprocessed orig file return ORIG_ERASE; case Options::PO_MOVE_ALWAYS_RENAME: // move unprocessed orig file to strDestDir; always rename case Options::PO_MOVE_RENAME_IF_USED: // move unprocessed orig file to strDestDir; rename only if name is in use case Options::PO_RENAME_SAME_DIR: // rename in the same dir return ORIG_MOVE; case Options::PO_MOVE_OR_ERASE: // move if dest doesn't exist; erase if it does; return ORIG_MOVE_OR_ERASE; default: CB_ASSERT(false); } } TransfConfig::OrigFile TransfConfig::getUnprocOrigAction() const { switch (m_options.m_eUnprocOrigChange) { case Options::UPO_DONT_CHG: // don't change unprocessed orig file return ORIG_DONT_CHANGE; case Options::UPO_ERASE: // erase unprocessed orig file return ORIG_ERASE; case Options::UPO_MOVE_ALWAYS_RENAME: // move unprocessed orig file to strDestDir; always rename case Options::UPO_MOVE_RENAME_IF_USED: // move unprocessed orig file to strDestDir; rename only if name is in use case Options::UPO_RENAME_SAME_DIR: // rename in the same dir return ORIG_MOVE; default: CB_ASSERT(false); } } TransfConfig::TransfFile TransfConfig::getProcessedAction() const { switch (m_options.m_eProcessedCreate) { case Options::PR_DONT_CREATE: // don't create proc files return TRANSF_DONT_CREATE; case Options::PR_CREATE_ALWAYS_RENAME: // create proc files and always rename case Options::PR_CREATE_RENAME_IF_USED: // create proc files and rename if the name is in use return TRANSF_CREATE; default: CB_ASSERT(false); } } TransfConfig::TransfFile TransfConfig::getTempAction() const { return m_options.m_bTempCreate ? TRANSF_CREATE : TRANSF_DONT_CREATE; } TransfConfig::TransfFile TransfConfig::getCompAction() const { return m_options.m_bCompCreate ? TRANSF_CREATE : TRANSF_DONT_CREATE; } #if 0 // to what an original file should be renamed, if it was "processed"; // if m_strSrcRootDir and m_strProcRootDir are different, it returns ""; (the original file doesn't get touched); // if m_strSrcRootDir and m_strProcRootDir are equal, it returns a name based on the original, with an ".orig.<NNN>" inserted before the extension, where <NNN> is a number chosen such that a file with this new name doesn't exist; string TransfConfig::getBackupName(const std::string& strOrigSrcName) const { if (m_strSrcRootDir != m_strProcRootDir) { return ""; } string strRelName; string strExt; splitOrigName(strOrigSrcName, strRelName, strExt); string strRes; for (int i = 1; ; ++i) { { ostringstream out; out << m_strSrcRootDir << strRelName << ".orig." << setfill('0') << setw(3) << i << strExt; strRes = out.str(); } if (!fileExists(strRes)) { createDirForFile(strRes); return strRes; } } } // to what the last "processed" file should be renamed; // if m_strSrcRootDir and m_strProcRootDir are different, it returns strOrigSrcName, moved to m_strProcRootDir; // if m_strSrcRootDir and m_strProcRootDir are equal, it returns strOrigSrcName; // if the name that it would return already exists, it inserts a ".proc.<NNN>" such that a file with this new name doesn't exist; (so if m_strSrcRootDir and m_strProcRootDir are equal, the original file should be renamed before calling this) std::string TransfConfig::getProcName(const std::string& strOrigSrcName) const { string strRelName; string strExt; splitOrigName(strOrigSrcName, strRelName, strExt); if (m_strSrcRootDir == m_strProcRootDir) { if (!fileExists(strOrigSrcName)) { return strOrigSrcName; } // not quite OK; by the time this gets called, strOrigSrcName should have been renamed; well ... } else { string s (m_strProcRootDir + strRelName + strExt); if (!fileExists(s)) { createDirForFile(s); return s; } } string strRes; for (int i = 1; ; ++i) { { ostringstream out; out << m_strProcRootDir << strRelName << ".proc." << setfill('0') << setw(3) << i << strExt; strRes = out.str(); } if (!fileExists(strRes)) { createDirForFile(strRes); return strRes; } } } #endif //=============================================================================================================== //=============================================================================================================== //=============================================================================================================== /*override*/ Transformation::Result IdentityTransformation::apply(const Mp3Handler& h, const TransfConfig& transfConfig, const std::string& strOrigSrcName, std::string& strTempName) { if (h.getName() != strOrigSrcName) { return NOT_CHANGED; } transfConfig.getTempName(strOrigSrcName, getActionName(), strTempName); copyFile(h.getName(), strTempName); return CHANGED_NO_RECALL; } //ttt2 test transformation (and perhaps the other threads) with this: wheat happens if something takes very long and the user presses both pause and resume before the UI checks /* ttt2 warnings + info ID3 V2.3 ID3 V2.4 ID3 V1 APE XING HDR LAME HDR no mp3gain more than 50000 in unknown streams more than 5% in unknown streams Xing TOC incorrect (probably hard to do) ttt2 When removing frames and Xing/Lame is present, adjust header for count and TOC (or remove TOC) */ //ttt2 indiv transformations should not generate duplicates of "original" and "temp" files; this should work only when the orig file is changed (there's no point if the modified file is elsewhere, because changes aren't visible) in the UI //ttt2 perhaps separate tab with actions: "check quality", ... ; or perhaps tab with settings, so the quality is checked the first time //ttt2 there are both "fixes" (pad truncated ...) and "actions" ("remove lyrics", "add picture", "check ID3"); perhaps distinguish between them //ttt2 "check tags" command - goes to musicbrainz and checks all known tags; 2009.03.19 - this doesn't seem to make much sense, given that there are many albums with the same name, ... ; perhaps we should search by track duration too; //ttt2 transform: convert to id3v2: assumes whatever reader order is currently in tag editor and writes to id3v2 if there are differences (including rating); maybe option to convert ID3V2.4.0 reagrdless; doing it manually isn't such a big pain, though; //ttt1 see why some files are read-only on W7 ����������������������������������������������������������������������������MP3Diags-1.0.12.079/src/SimpleSaxHandler.h����������������������������������������������������������0000644�0001750�0000144�00000012746�11747021437�016647� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef SimpleSaxHandlerH #define SimpleSaxHandlerH #include <list> #include <QXmlDefaultHandler> template<class T> struct SimpleSaxHandler : public QXmlDefaultHandler { typedef void (T::* Start)(const QXmlAttributes&); typedef void (T::* End)(); typedef void (T::* Char)(const std::string&); class Node { NoDefaults k; friend struct SimpleSaxHandler<T>; int m_nLevel; Node(const std::string& strName) : k(0), m_nLevel(0), m_pParent(0), m_strName(strName), onStart(0), onEnd(0), onChar(0) { } Node(Node& parent, const std::string& strName) : k(0), m_nLevel(parent.m_nLevel + 1), m_pParent(&parent), m_strName(strName), onStart(0), onEnd(0), onChar(0) { parent.add(this); } std::vector<Node*> m_vpChildren; Node* m_pParent; std::string m_strName; void add(Node* p) { if (0 != getChild(p->m_strName)) { throw 1; } // ttt2 throw something else m_vpChildren.push_back(p); } Node* getChild(const std::string& strName) { for (int i = 0, n = cSize(m_vpChildren); i < n; ++i) { if (strName == m_vpChildren[i]->m_strName) { return m_vpChildren[i]; } } return 0; } public: Start onStart; End onEnd; Char onChar; }; Node& getRoot() { //return *m_lpNodes.front(); typename std::list<Node*>::iterator it (m_lpNodes.begin()); ++it; return **it; } Node& makeNode(Node& node, const std::string& strName) { m_lpNodes.push_back(new Node(node, strName)); return *m_lpNodes.back(); } SimpleSaxHandler(const std::string& strName) { m_lpNodes.push_back(new Node("qqq")); // to avoid comparisons to 0 m_lpNodes.push_back(new Node(*m_lpNodes.back(), strName)); // the "root" node has a level of 1, because the artificial first elem has level 0 m_pCrtNode = m_lpNodes.front(); m_nCrtLevel = 0; // ttt2 reset these if an error occurs and then the object is used for another parsing; } /*override*/ ~SimpleSaxHandler() { pearl::clearPtrContainer(m_lpNodes); } private: std::list<Node*> m_lpNodes; Node* m_pCrtNode; int m_nCrtLevel; /*override*/ bool startElement(const QString& /*qstrNamespaceUri*/, const QString& qstrLocalName, const QString& /*qstrName*/, const QXmlAttributes& attrs) { ++m_nCrtLevel; if (m_nCrtLevel == m_pCrtNode->m_nLevel + 1) { std::string s (qstrLocalName.toUtf8()); Node* pChild (m_pCrtNode->getChild(s)); if (0 != pChild) { m_pCrtNode = pChild; if (0 != m_pCrtNode->onStart) { T* p (dynamic_cast<T*>(this)); (p->*(m_pCrtNode->onStart))(attrs); } } } return true; } /*override*/ bool endElement(const QString& /*qstrNamespaceUri*/, const QString& qstrLocalName, const QString& /*qstrName*/) { --m_nCrtLevel; if (m_nCrtLevel == m_pCrtNode->m_nLevel - 1) { std::string s (qstrLocalName.toUtf8()); CB_ASSERT (s == m_pCrtNode->m_strName); if (0 != m_pCrtNode->onEnd) { T* p (dynamic_cast<T*>(this)); (p->*(m_pCrtNode->onEnd))(); } m_pCrtNode = m_pCrtNode->m_pParent; } return true; } /*override*/ bool characters(const QString& qstrCh) { std::string s (qstrCh.toUtf8()); if (m_nCrtLevel == m_pCrtNode->m_nLevel) { if (0 != m_pCrtNode->onChar) { T* p (dynamic_cast<T*>(this)); (p->*(m_pCrtNode->onChar))(s); } } return true; } }; #endif // #ifndef SimpleSaxHandlerH ��������������������������MP3Diags-1.0.12.079/src/TagWriter.cpp���������������������������������������������������������������0000644�0001750�0000144�00000221534�11310373502�015671� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef MSVC_QMAKE #pragma warning (disable : 4100) #endif #include <algorithm> #include <QFile> #include <QClipboard> #include <QMimeData> #include "TagWriter.h" #include "Helpers.h" #include "OsFile.h" #include "ImageInfoPanelWdgImpl.h" #include "SongInfoParser.h" #include "Widgets.h" #include "DiscogsDownloader.h" // just for SOURCE_NAME #include "MusicBrainzDownloader.h" // just for SOURCE_NAME #include "Id3V230Stream.h" #include "Id3V240Stream.h" #include "Mp3Manip.h" #include "CommonData.h" #include "MpegStream.h" ////#include <iostream> //ttt remove using namespace std; using namespace pearl; //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== namespace { ostream& operator<<(ostream& out, const TagReaderInfo& inf) { out << "<" << inf.m_strName << ", " << inf.m_nPos << ", " << (inf.m_bAlone ? "true" : "false") << ">"; return out; } void printVec(ostream& out, const vector<TagReaderInfo>& v) { for (int i = 0, n = cSize(v); i < n; ++i) { out << v[i] << " "; } out << endl; } } ostream& operator<<(ostream& out, const TagWriter::OrigValue& val) { out << "song: " << val.m_nSong << ", field: " << val.m_nField << ", status: " << (int)val.m_eStatus << ", value: " << val.m_strVal; return out; } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== ImageColl::ImageColl() : m_nCurrent(-1) { } int ImageColl::addImage(const ImageInfo& img, const string& strFile /*= ""*/) // returns the index of the image; if it already exists it's not added again; if it's invalid returns -1 //ttt1 recompress large images AND mark field as changed { if (img.isNull()) { return -1; } int n (find(img)); if (-1 != n) { if (!strFile.empty()) { m_vTagWrtImageInfo[n].m_sstrFiles.insert(strFile); } return n; } m_vTagWrtImageInfo.push_back(TagWrtImageInfo(img, strFile)); return size() - 1; } void ImageColl::addWidget(ImageInfoPanelWdgImpl* p) // first addImage gets called by TagWriter and after it's done it tells MainFormDlgImpl to create widgets, which calls this; { m_vpWidgets.push_back(p); } void ImageColl::clear() { clearPtrContainer(m_vpWidgets); m_vTagWrtImageInfo.clear(); m_nCurrent = -1; } void ImageColl::select(int n) // -1 deselects all { CB_ASSERT (cSize(m_vpWidgets) == cSize(m_vTagWrtImageInfo)); if (m_nCurrent >= 0) { m_vpWidgets[m_nCurrent]->setNormalBackground(); } m_nCurrent = n; if (n >= 0) { CB_ASSERT (n < size()); m_vpWidgets[m_nCurrent]->setHighlightBackground(); } } int ImageColl::find(const ImageInfo& img) const { vector<TagWrtImageInfo>::const_iterator it (std::find(m_vTagWrtImageInfo.begin(), m_vTagWrtImageInfo.end(), img)); if (m_vTagWrtImageInfo.end() == it) { return -1; } return it - m_vTagWrtImageInfo.begin(); } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== TrackTextReader::TrackTextReader(SongInfoParser::TrackTextParser* pTrackTextParser, const std::string& s) : m_dRating(-1), m_bHasTitle(false), m_bHasArtist(false), m_bHasTrackNumber(false), m_bHasTimeStamp(false), m_bHasGenre(false), m_bHasAlbumName(false), m_bHasRating(false), m_bHasComposer(false), m_szType(pTrackTextParser->isFileNameBased() ? "(file)" : "(table)") { vector<string> v ((int)LIST_END + 1, "\1"); // !!! "LIST_END + 1" instead of just "LIST_END", so the last entry can be used for "%i" (i.e. "ignored") pTrackTextParser->assign(s, v); if ("\1" != v[TITLE]) { m_bHasTitle = true; m_strTitle = v[TITLE]; } if ("\1" != v[ARTIST]) { m_bHasArtist = true; m_strArtist = v[ARTIST]; } if ("\1" != v[TRACK_NUMBER]) { m_bHasTrackNumber = true; m_strTrackNumber = v[TRACK_NUMBER]; } if ("\1" != v[TIME]) { try { m_timeStamp = TagTimestamp(v[TIME]); m_bHasTimeStamp = true; } catch (const TagTimestamp::InvalidTime&) { // !!! nothing } } if ("\1" != v[GENRE]) { m_bHasGenre = true; m_strGenre = v[GENRE]; } //if ("\1" != v[IMAGE]) { q = true; m_str = v[IMAGE]; } if ("\1" != v[ALBUM]) { m_bHasAlbumName = true; m_strAlbumName = v[ALBUM]; } if ("\1" != v[RATING]) { const string& s (v[RATING]); if (1 == cSize(s)) { char c (s[0]); // a b c d e f g h i j k l m n o p q r s t u v w x y z static double s_ratingMap [] = { 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 1.5, 1.0, 1.0, 1.0, -1, -1, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.0 }; // note that if this changes it should be synchronized with RatingPattern // negative values are ignored if (c >= 'a' && c <= 'z') //ttt3 ASCII-specific { double d (s_ratingMap[c - 'a']); if (d >= 0) { m_bHasRating = true; //m_dRating = ('z' - c)*254/('z' - 'a' /*+ 1*/) + 1; //m_nRating = int(d*254/5 + 1.1); m_dRating = d; } } } } if ("\1" != v[COMPOSER]) { m_bHasComposer = true; m_strComposer = v[COMPOSER]; } } /*override*/ TrackTextReader::~TrackTextReader() { //qDebug("destr TrackTextReader %p", this); } /*override*/ TrackTextReader::SuportLevel TrackTextReader::getSupport(Feature eFeature) const { switch (eFeature) { case TITLE: case ARTIST: case TRACK_NUMBER: case TIME: case GENRE: //case IMAGE: case ALBUM: case RATING: case COMPOSER: //case VARIOUS_ARTISTS: return READ_ONLY; default: return NOT_SUPPORTED; } } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== WebReader::WebReader(const AlbumInfo& albumInfo, int nTrackNo) : m_strType(albumInfo.m_strSourceName) { //if (nTrackNo >= cSize(albumInfo.m_vTracks)) { return; } CB_ASSERT (0 <= nTrackNo && nTrackNo < cSize(albumInfo.m_vTracks)); const TrackInfo& ti (albumInfo.m_vTracks[nTrackNo]); m_strTitle = ti.m_strTitle; m_strArtist = ti.m_strArtist; //(ti.m_strArtist.empty() ? albumInfo.m_strArtist : ti.m_strArtist); m_strTrackNumber = ti.m_strPos; try { m_timeStamp = TagTimestamp(albumInfo.m_strReleased); } catch (const TagTimestamp::InvalidTime&) { //ttt2 perhaps log something ... } m_strGenre = albumInfo.m_strGenre; m_imageInfo = albumInfo.m_imageInfo; m_strAlbumName = albumInfo.m_strTitle; m_dRating = ti.m_dRating; m_strComposer = ti.m_strComposer; //(ti.m_strComposer.empty() ? albumInfo.m_strComposer : ti.m_strComposer); m_eVarArtists = albumInfo.m_eVarArtists; if (DiscogsDownloader::SOURCE_NAME == albumInfo.m_strSourceName) { m_bSuppGenre = true; m_bSuppComposer = true; m_bSuppVarArtists = false; } else if (MusicBrainzDownloader::SOURCE_NAME == albumInfo.m_strSourceName) { m_bSuppGenre = false; m_bSuppComposer = false; m_bSuppVarArtists = true; } else { CB_ASSERT (false); } } WebReader::~WebReader() { // qDebug("destr %p", this); } /*override*/ WebReader::SuportLevel WebReader::getSupport(Feature eFeature) const { switch (eFeature) { case TITLE: case ARTIST: case TRACK_NUMBER: case TIME: case IMAGE: case ALBUM: return READ_ONLY; case GENRE: return m_bSuppGenre ? READ_ONLY : NOT_SUPPORTED; case COMPOSER: return m_bSuppComposer ? READ_ONLY : NOT_SUPPORTED; case VARIOUS_ARTISTS: return m_bSuppVarArtists ? READ_ONLY : NOT_SUPPORTED; case RATING: default: return NOT_SUPPORTED; } } int WebReader::convVarArtists() const // converts m_eVarArtists to an int is either 0 or contains all VA-enabled values, based on configuration { switch (m_eVarArtists) { case AlbumInfo::VA_NOT_SUPP: case AlbumInfo::VA_SINGLE: return TagReader::VA_NONE; case AlbumInfo::VA_VARIOUS: { const CommonData* p (getCommonData()); int nRes (0); if (p->m_bItunesVarArtists) { nRes += TagReader::VA_ITUNES; } if (p->m_bWmpVarArtists) { nRes += TagReader::VA_WMP; } return nRes; } default: CB_ASSERT (false); } } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== Mp3HandlerTagData::Mp3HandlerTagData(TagWriter* pTagWriter, const Mp3Handler* pMp3Handler, int nCrtPos, int nOrigPos, const std::string& strPastedVal) : m_pTagWriter(pTagWriter), m_pMp3Handler(pMp3Handler), m_nCrtPos(nCrtPos), m_nOrigPos(nOrigPos), m_vValueInfo(TagReader::LIST_END), m_strPastedVal(strPastedVal) { TRACER("Mp3HandlerTagData constr"); refreshReaders(); setUp(); //qDebug("create %p", this); } Mp3HandlerTagData::~Mp3HandlerTagData() { //qDebug("destr %p", this); TRACER("Mp3HandlerTagData destr"); } static bool isId3V2(const TagReader* p) { return 0 == strcmp(p->getName(), Id3V230Stream::getClassDisplayName()) || 0 == strcmp(p->getName(), Id3V240Stream::getClassDisplayName()); } static const char* g_szImageFmt ("# %d"); extern const int PIC_FMT_HDR (2); void Mp3HandlerTagData::adjustVarArtists(bool b) // if VARIOUS_ARTISTS is not ASSIGNED, sets m_strValue and m_eStatus { ValueInfo& inf (m_vValueInfo[TagReader::VARIOUS_ARTISTS]); string strAll (TagReader::getVarArtistsValue()); if (ASSIGNED != inf.m_eStatus) { inf.m_strValue.clear(); string s (b ? strAll : ""); inf.m_strValue = s; inf.m_eStatus = s.empty() ? EMPTY : NON_ID3V2_VAL; for (int i = 0, n = cSize(m_vpTagReaders); i < n; ++i) { TagReader* p (m_vpTagReaders[i]); if (isId3V2(p)) { string strId3 (p->getValue(TagReader::VARIOUS_ARTISTS)); string s1; // those letters from strId3 that are also in strAll; needed because strId3 contains all known letters, regardless of their being enabled for (int i = 0; i < cSize(strId3); ++i) { if (string::npos != strAll.find(strId3[i])) { s1 += strId3[i]; } } inf.m_eStatus = s1 == s ? ID3V2_VAL : NON_ID3V2_VAL; break; } } } } // to be called initially and each time the priority of tag readers changes; (well, actually a new object will get constructed in the latter case, so only the first matters) void Mp3HandlerTagData::setUp() { //cout << "reload " << this; for (int i = 0, n = cSize(m_vpTagReaders); i < n; ++i) { cout << " " << m_vpTagReaders[i]; } cout << endl; //qDebug("%s", p->getName()); for (int f = 0; f < TagReader::LIST_END; ++f) { if (TagReader::IMAGE != f && TagReader::VARIOUS_ARTISTS != f) // special case needed because TagReader::getValue(TagReader::IMAGE) always returns an empty string; VARIOUS_ARTISTS is handled separately anyway { ValueInfo& inf (m_vValueInfo[f]); if (ASSIGNED != inf.m_eStatus) { inf.m_strValue.clear(); inf.m_eStatus = EMPTY; bool bId3V2Found (false); for (int i = 0, n = cSize(m_vpTagReaders); i < n; ++i) { TagReader* p (m_vpTagReaders[i]); bId3V2Found = bId3V2Found || isId3V2(p); string s (p->getValue((TagReader::Feature)f)); if (!s.empty()) { bool bId3V2Val (true); if ((TagReader::ARTIST == f || TagReader::COMPOSER == f) && TC_NONE != m_pTagWriter->m_eArtistCase) { string s1 (convStr(getCaseConv(convStr(s), m_pTagWriter->m_eArtistCase))); if (s1 != s) { s = s1; bId3V2Val = false; } } if ((TagReader::TITLE == f || TagReader::ALBUM == f) && TC_NONE != m_pTagWriter->m_eTitleCase) //ttt2 perhaps include genre as well { string s1 (convStr(getCaseConv(convStr(s), m_pTagWriter->m_eTitleCase))); if (s1 != s) { s = s1; bId3V2Val = false; } } inf.m_strValue = s; if (bId3V2Val) { bId3V2Val = false; // !!! if (isId3V2(p)) { bId3V2Val = true; } else if (bId3V2Found) { // !!! nothing: an ID3V2 was already found and, since it got here, the value was empty } else { // find the first ID3V2 and see if it has the same value for (; i < n; ++i) { TagReader* p1 (m_vpTagReaders[i]); if (isId3V2(p1)) { string s1 (p1->getValue((TagReader::Feature)f)); bId3V2Val = (s1 == s); break; } } } } inf.m_eStatus = bId3V2Val ? ID3V2_VAL : NON_ID3V2_VAL; break; } } } } } { ValueInfo& inf (m_vValueInfo[TagReader::IMAGE]); if (ASSIGNED != inf.m_eStatus) { inf.m_strValue.clear(); inf.m_eStatus = EMPTY; bool bId3V2Found (false); for (int i = 0, n = cSize(m_vpTagReaders); i < n; ++i) { TagReader* p (m_vpTagReaders[i]); bId3V2Found = bId3V2Found || isId3V2(p); if (TagReader::NOT_SUPPORTED != p->getSupport(TagReader::IMAGE)) { const ImageInfo& imageInfo (p->getImage()); int k (m_pTagWriter->getIndex(imageInfo)); if (-1 != k) { char a [10]; sprintf(a, g_szImageFmt, k + 1); inf.m_strValue = a; // most of the follwing code is pointless as long as the only image-holding tags are ID3V2, but would lead to hard-to-detect bugs if others are added; bool bId3V2Val (false); //if (isId3V2(p) && ImageInfo::OK == imageInfo.getStatus()) // !!! by comparing getStatus() we force the user to save the image with a "correct" type if (isId3V2(p) && (ImageInfo::OK == imageInfo.getStatus() || ImageInfo::LOADED_NOT_COVER == imageInfo.getStatus())) // ttt2 not sure about LOADED_NOT_COVER, but it seems to make more sense; probably most players don't care about the image type { bId3V2Val = true; } else if (bId3V2Found) { // !!! nothing: an ID3V2 was already found and, since it got here, the value was empty } else { // find the first ID3V2 and see if it has the same value for (; i < n; ++i) { TagReader* p1 (m_vpTagReaders[i]); if (isId3V2(p1)) { CB_ASSERT (TagReader::NOT_SUPPORTED != p1->getSupport(TagReader::IMAGE)); const ImageInfo& imageInfo (p1->getImage()); int k1 (m_pTagWriter->getIndex(imageInfo)); bId3V2Val = (k1 == k); break; } } } inf.m_eStatus = bId3V2Val ? ID3V2_VAL : NON_ID3V2_VAL; break; } } } } } /*for (int i = 0; i < TagReader::LIST_END; ++i) { cout << "(" << m_vValueInfo[i].m_strValue << ", " << (int)m_vValueInfo[i].m_eStatus << ") "; } cout << endl;*/ } // may throw InvalidValue void Mp3HandlerTagData::setData(int nField, const std::string& s) { if (s == m_vValueInfo[nField].m_strValue) { return; } if (TagReader::ARTIST == nField) { m_pTagWriter->delayedAdjVarArtists(); } if (TagReader::TIME == nField) { try { TagTimestamp t (s); } catch (const TagTimestamp::InvalidTime&) { throw InvalidValue(); } } if (TagReader::TRACK_NUMBER == nField && !s.empty()) // !!! note that an empty track# gets removed when writing to ID3V2 { if (!isdigit(s[0]) || !isdigit(s[s.size() - 1])) { throw InvalidValue(); } string::size_type n1 (s.find_first_not_of("0123456789")), n2 (s.find_last_not_of("0123456789")); if (string::npos != n1 && (n1 != n2 || s[n1] != '/')) { throw InvalidValue(); } } string s1 (s); if (TagReader::RATING == nField && !s.empty()) { bool bOk (isdigit(s[0])); if (bOk) { double d (atof(s.c_str())); if (d > 5) { bOk = false; } else { char a [15]; sprintf(a, "%0.1f", d); s1 = a; } } if (!bOk) { throw InvalidValue(); } } m_vValueInfo[nField].m_strValue = s1; m_vValueInfo[nField].m_eStatus = ASSIGNED; //ttt2 a check for track numbers would make some sense, but there are many formats for track numbers, e.g. "3", "03", "3/9", "03/09", "A03" (for cassettes), others for vinyl } void Mp3HandlerTagData::setStatus(int nField, Status eStatus) { m_vValueInfo[nField].m_eStatus = eStatus; } //ttt2 ??? ptr deallocated and then reallocated in the same place most of the time? // returns the data corresponding to the k-th element in m_pTagWriter->m_vTagReaderInfo; returns "\1" if it doesn't have a corresponding stream (e.g. 2nd ID3V1 tag), "\2" if the given feature is not supported (e.g. picture in ID3V1) and "\3" if this particular tag doesn't have the requested frame // nField is the "internal" row for which data is retrieved, so TagReader::FEATURE_ON_POS[] has to be used by the UI caller std::string Mp3HandlerTagData::getData(int nField, int k) const { if (k >= cSize(m_vpMatchingTagReaders)) // this may be true in transitory contexts (e.g. going to prev/next album) { return "\1"; } TagReader* p (m_vpMatchingTagReaders.at(k)); if (0 == p) { return "\1"; } if (m_pTagWriter->isFastSaving() && (m_pTagWriter->m_vTagReaderInfo.at(k).m_strName == Id3V230Stream::getClassDisplayName() || m_pTagWriter->m_vTagReaderInfo[k].m_strName == Id3V240Stream::getClassDisplayName())) { return "N/A"; } //qDebug("%s", p->getName()); //nField = TagReader::FEATURE_ON_POS[nField]; //qDebug("deref %p", p); bool bFrameExists; switch (nField) { case TagReader::TITLE: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::TITLE)) { return "\2"; } string s (p->getTitle(&bFrameExists)); return bFrameExists ? s : "\3"; } case TagReader::ARTIST: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::ARTIST)) { return "\2"; } string s (p->getArtist(&bFrameExists)); return bFrameExists ? s : "\3"; } case TagReader::TRACK_NUMBER: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::TRACK_NUMBER)) { return "\2"; } string s (p->getTrackNumber(&bFrameExists)); return bFrameExists ? s : "\3"; } case TagReader::TIME: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::TIME)) { return "\2"; } string s (p->getTime(&bFrameExists).asString()); return bFrameExists ? s : "\3"; } case TagReader::GENRE: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::GENRE)) { return "\2"; } string s (p->getGenre(&bFrameExists)); return bFrameExists ? s : "\3"; } case TagReader::IMAGE: { string qq ((m_vstrImgCache[k])); if (qq != "\7") { return qq; } if (m_vstrImgCache[k] != "\7") { return m_vstrImgCache[k]; } if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::IMAGE)) { m_vstrImgCache[k] = "\2"; return m_vstrImgCache[k]; } ImageInfo imageInfo (p->getImage(&bFrameExists)); if (!bFrameExists) { m_vstrImgCache[k] = "\3"; return m_vstrImgCache[k]; } if (!imageInfo.isNull()) { int j (m_pTagWriter->getIndex(imageInfo)); // CB_ASSERT (j >= 0); // !!! no need to assert; m_pTagWriter already does it char a [10]; sprintf(a, g_szImageFmt, j + 1); //cout << " " << a << endl; m_vstrImgCache[k] = a; return m_vstrImgCache[k]; } m_vstrImgCache[k] = ""; return m_vstrImgCache[k]; } case TagReader::ALBUM: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::ALBUM)) { return "\2"; } string s (p->getAlbumName(&bFrameExists)); return bFrameExists ? s : "\3"; } case TagReader::RATING: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::RATING)) { return "\2"; } char a [15]; double d (p->getRating(&bFrameExists)); if (!bFrameExists) { return "\3"; } //ttt2 perhaps use this: return p->getValue(TagReader::RATING); see why there's no test for "<0" in TagReader::getValue() sprintf(a, "%0.1f", d); if ('-' == a[0]) { a[0] = 0; } return a; } case TagReader::COMPOSER: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::COMPOSER)) { return "\2"; } string s (p->getComposer(&bFrameExists)); return bFrameExists ? s : "\3"; } case TagReader::VARIOUS_ARTISTS: { if (TagReader::NOT_SUPPORTED == p->getSupport(TagReader::VARIOUS_ARTISTS)) { return "\2"; } p->getVariousArtists(&bFrameExists); if (!bFrameExists) { return "\3"; } return p->getValue(TagReader::VARIOUS_ARTISTS); } } CB_ASSERT(false); // all cases have been covered and have "return" } int Mp3HandlerTagData::getImage() const // 0-based; -1 if there-s no image; { string s (getData(TagReader::IMAGE)); int nPic (s.empty() ? -1 : atoi(s.c_str() + PIC_FMT_HDR) - 1); // "-1" because on screen numbering starts from 1, not 0 return nPic; } double Mp3HandlerTagData::getRating() const { string s (getData(TagReader::RATING)); double d (s.empty() ? -1 : atof(s.c_str())); // !!! it's OK to use atof, regardless of the system's locale, because a program's locale is "C" unless changed explicitley ("locale::global(locale(""));" would switch to the system's locale) return d; } // updates m_vpTagReader to reflect m_pTagWriter->m_vTagReaderInfo, then updates unassigned values; // called on constructor void Mp3HandlerTagData::refreshReaders() { m_vTrackTextReaders.clear(); m_vpTagReaders.clear(); vector<TagReaderInfo>& vRdInfo (m_pTagWriter->m_vTagReaderInfo); m_vpMatchingTagReaders.clear(); m_vpMatchingTagReaders.resize(vRdInfo.size()); vector<std::string>(vRdInfo.size(), string("\7")).swap(m_vstrImgCache);//.clear(); m_vstrImgCache.resize(); m_vTrackTextReaders.reserve(m_pTagWriter->getTrackTextParsersCnt()); // !!! without this pointers would get invalidated m_vWebReaders.reserve(m_pTagWriter->getAlbumInfoCnt()); // !!! without this pointers would get invalidated for (int i = 0, n = cSize(vRdInfo); i < n; ++i) { const TagReaderInfo& inf (vRdInfo[i]); if (inf.m_strName == TrackTextReader::getClassDisplayName()) { SongInfoParser::TrackTextParser* pParser (m_pTagWriter->getTrackTextParser(inf.m_nPos)); m_vTrackTextReaders.push_back(TrackTextReader(pParser, pParser->isFileNameBased() ? m_pMp3Handler->getName() : m_strPastedVal)); m_vpTagReaders.push_back(&m_vTrackTextReaders.back()); m_vpMatchingTagReaders[i] = &m_vTrackTextReaders.back(); //qDebug("asgn %p", &m_vTrackTextReaders.back()); } else if (inf.m_strName == WebReader::getClassDisplayName()) { const AlbumInfo& albumInfo (m_pTagWriter->getAlbumInfo(inf.m_nPos)); if (m_nCrtPos < cSize(albumInfo.m_vTracks)) { m_vWebReaders.push_back(WebReader(albumInfo, m_nCrtPos)); m_vpTagReaders.push_back(&m_vWebReaders.back()); m_vpMatchingTagReaders[i] = &m_vWebReaders.back(); } } else { TagReader* pLast (0); int nCount (0); const vector<DataStream*>& vStreams (m_pMp3Handler->getStreams()); for (int j = 0, n = cSize(vStreams); j < n; ++j) { TagReader* pRd (dynamic_cast<TagReader*>(vStreams[j])); if (0 != pRd && pRd->getName() == inf.m_strName) { if (inf.m_nPos == nCount) { m_vpTagReaders.push_back(pRd); m_vpMatchingTagReaders[i] = pRd; goto e1; } ++nCount; pLast = pRd; } } if (0 != pLast) { m_vpTagReaders.push_back(pLast); // wasn't able to find the one on the specified position, so it uses a compatible one; // !!! this seems better than doing nothing: if TagWriter has the order "<ID3V2.3.0, 1>, <ID3V1, 0>, <ID3V2.3.0, 0>" and a file only has an ID3V2.3.0 and an ID3V1, doing nothing for the first (because there's no ID3V2.3.0 with a pos=1) would result in the order for that file being "<ID3V1, 0>, <ID3V2.3.0, 0>", making ID3V1 have priority; with the current implementation, the order is "<ID3V2.3.0, 0>, <ID3V1, 0>, <ID3V2.3.0, 0>", ID3V2 has priority; true, this introduces a needles duplicate but it's no big deal; //ttt3 remove duplicates } // !!! not an exact match, so don't touch m_vpMatchingTagReaders e1:; } } //qDebug("1 %p", this); for (int i = 0, n = cSize(m_vpTagReaders); i < n; ++i) { qDebug("%p", m_vpTagReaders[i]); } //qDebug("%s", p->getName()); //cout << "update " << this; for (int i = 0, n = cSize(m_vpTagReaders); i < n; ++i) { cout << " " << m_vpTagReaders[i]; } cout << endl; } void Mp3HandlerTagData::print(std::ostream& out) const { out << "==========================================\n"; for (int i = 0, n = cSize(m_vValueInfo); i < n; ++i) { out << m_vValueInfo[i].m_strValue << " <" << m_vValueInfo[i].m_eStatus << ">\n"; } } // returns 0 if i is out of range const TagReader* Mp3HandlerTagData::getMatchingReader(int i) const { if (i < 0 || i > cSize(m_vpMatchingTagReaders)) { return 0; } return m_vpMatchingTagReaders[i]; } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== TagWriter::TagWriter(CommonData* pCommonData, QWidget* pParentWnd, const bool& bIsFastSaving, const TextCaseOptions& eArtistCase, const TextCaseOptions& eTitleCase) : m_pCommonData(pCommonData), m_pParentWnd(pParentWnd), m_nCurrentFile(-1), m_bShowedNonSeqWarn(true), m_bIsFastSaving(bIsFastSaving), m_nFileToErase(-1), m_bVariousArtists(false), m_bAutoVarArtists(false), m_bDelayedAdjVarArtists(false), m_bWaitingChangeNotif(false), m_eArtistCase(eArtistCase), m_eTitleCase(eTitleCase) { } TagWriter::~TagWriter() { clearPtrContainer(m_vpTrackTextParsers); clearPtrContainer(m_vpMp3HandlerTagData); } // should be called on startup by MainFormDlgImpl, to get config data; asserts that m_vSortedKnownTagReaders is empty; void TagWriter::addKnownInf(const std::vector<TagReaderInfo>& v) { CB_ASSERT (m_vSortedKnownTagReaders.empty()); for (int i = 0, n = cSize(v); i < n; ++i) { vector<TagReaderInfo>::iterator it (std::find(m_vSortedKnownTagReaders.begin(), m_vSortedKnownTagReaders.end(), v[i])); if (m_vSortedKnownTagReaders.end() == it) { m_vSortedKnownTagReaders.insert(m_vSortedKnownTagReaders.end(), v[i]); } // else nothing (ignore duplicates) } } // sorts m_vTagReaderInfo so that it matches m_vSortedKnownTagReaders void TagWriter::sortTagReaders() { vector<TagReaderInfo> vSorted; //vector<TagReaderInfo> vSorted; for (int i = 0, n = cSize(m_vSortedKnownTagReaders); i < n; ++i) { vector<TagReaderInfo>::iterator it (std::find(m_vTagReaderInfo.begin(), m_vTagReaderInfo.end(), m_vSortedKnownTagReaders[i])); if (m_vTagReaderInfo.end() != it) { vSorted.push_back(*it); m_vTagReaderInfo.erase(it); } } m_vSortedKnownTagReaders.insert(m_vSortedKnownTagReaders.end(), m_vTagReaderInfo.begin(), m_vTagReaderInfo.end()); // by doing this we make sure m_vSortedKnownTagReaders has all the elements from m_vTagReaderInfo (and perhaps more) vSorted.insert(vSorted.end(), m_vTagReaderInfo.begin(), m_vTagReaderInfo.end()); vSorted.swap(m_vTagReaderInfo); } void TagWriter::addAlbumInfo(const AlbumInfo& albumInfo) { int nAlbInfCnt (getAlbumInfoCnt()); // excluding the new albumInfo to be added m_vAlbumInfo.push_back(albumInfo); int nKnownWebCnt (0); int n (cSize(m_vSortedKnownTagReaders)); for (int i = 0; i < n; ++i) { if (WebReader::getClassDisplayName() == m_vSortedKnownTagReaders[i].m_strName) { ++nKnownWebCnt; } } m_vSortedKnownTagReaders.insert(m_vSortedKnownTagReaders.begin(), TagReaderInfo(WebReader::getClassDisplayName(), nAlbInfCnt, TagReaderInfo::ALONE)); // last param doesn't matter for m_vSortedKnownTagReaders if (nAlbInfCnt < nKnownWebCnt) { // we have another TagReaderInfo with the same m_nPos as the one just added; it needs to be removed; for (int i = 1; i < n; ++i) // !!! start from 1 { if (WebReader::getClassDisplayName() == m_vSortedKnownTagReaders[i].m_strName && m_vSortedKnownTagReaders[i].m_nPos == nAlbInfCnt) { m_vSortedKnownTagReaders.erase(m_vSortedKnownTagReaders.begin() + i); break; } } } reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); } namespace { struct SortByTrack { enum { NO_TRACK = 999999 }; static double getTrack(const string& s) // returns -1 if it can't identify a track number { const char* p (s.c_str()); // requiring all chars to be digits isn't OK, because "5/12" should be handled as "5" for (; ' ' == *p; ++p) {} if (0 == *p || !isdigit(*p)) { return NO_TRACK; } char* pLast; double d (int(strtol(p, &pLast, 10))); for (; 0 != *pLast && !isdigit(*pLast); ++pLast) {} if (0 != *pLast) { d += atoi(pLast)/100000.0; // this sort of takes care of tracks in the format <total>/<track> } return d; } bool operator()(const Mp3HandlerTagData* p1, const Mp3HandlerTagData* p2) const { // !!! this defines a "strict partial order" (irreflexive and transitive) iff the codes for digits are grouped together (as is the case with ASCII) const string& s1 (p1->getData(TagReader::TRACK_NUMBER)); const string& s2 (p2->getData(TagReader::TRACK_NUMBER)); double d1 (getTrack(s1)); double d2 (getTrack(s2)); //if (d1 < NO_TRACK && d2 < NO_TRACK) { return d1 < d2; } if (d1 != d2) { return d1 < d2; } return s1 < s2; } }; } void TagWriter::sortSongs() // sorts by track number; shows a warning if issues are detected (should be exactly one track number, from 1 to the track count) { stable_sort(m_vpMp3HandlerTagData.begin(), m_vpMp3HandlerTagData.end(), SortByTrack()); int n (cSize(m_vpMp3HandlerTagData)); vector<pair<int, int> > v (n); for (int i = 0; i < n; ++i) { v[i] = make_pair(m_vpMp3HandlerTagData[i]->getOrigPos(), i); } std::sort(v.begin(), v.end()); m_vnMovedTo.resize(n); for (int i = 0; i < n; ++i) { m_vnMovedTo[i] = v[i].second; //cout << "## " << m_vnMovedTo[i] << endl; } m_bNonStandardTrackNo = false; for (int i = 0; i < n; ++i) { if (int(SortByTrack::getTrack(m_vpMp3HandlerTagData[i]->getData(TagReader::TRACK_NUMBER))) != i + 1) { m_bNonStandardTrackNo = true; if (m_pCommonData->m_bWarnOnNonSeqTracks && !m_bShowedNonSeqWarn) { m_bShowedNonSeqWarn = true; QTimer::singleShot(1, this, SLOT(onDelayedTrackSeqWarn())); } break; } } } void TagWriter::onDelayedTrackSeqWarn() { //CursorOverrider crs (Qt::ArrowCursor); QMessageBox::warning(m_pParentWnd, "Warning", "Track numbers are supposed to be consecutive numbers from 1 to the total number of tracks. This is not the case with the current album, which may lead to incorrect assignments when pasting information."); } // returns 0 if there's no current handler const Mp3Handler* TagWriter::getCurrentHndl() const { if (m_nCurrentFile < 0 || m_nCurrentFile >= cSize(m_vpMp3HandlerTagData)) { return 0; } return m_vpMp3HandlerTagData[m_nCurrentFile]->getMp3Handler(); } string TagWriter::getCurrentName() const { const Mp3Handler* p (getCurrentHndl()); return 0 != p ? p->getName() : ""; } const Mp3HandlerTagData* TagWriter::getCrtMp3HandlerTagData() const { if (m_nCurrentFile < 0 || m_nCurrentFile >= cSize(m_vpMp3HandlerTagData)) { return 0; } return m_vpMp3HandlerTagData[m_nCurrentFile]; } bool s_bToldAboutPatternsInCrtRun (false); // to limit to 1 per run the number of times the user is told about support void TagWriter::onDelayedChangeNotif() { m_bWaitingChangeNotif = false; QMessageBox::critical(m_pParentWnd, "Error", "Some files have been modified by an external tool after the last scan. You won't be able to save any changes to those files until you rescan them."); } //void TagWriter::reloadAll(string strCrt, ReloadOption eReloadOption/*, bool bKeepUnassgnImg*/) void TagWriter::reloadAll(string strCrt, bool bClearData, bool bClearAssgn) { TRACER("TagWriter::reloadAll()"); CursorOverrider crs; if (strCrt.empty() && !bClearData) { strCrt = getCurrentName(); } //ttt2 ??? q ? m_vpMp3HandlerTagData gets destroyed then prev values used?" x //ttt2 ??? ? push_back for m_vpMp3HandlerTagData ? vector<Mp3HandlerTagData*> v; v.swap(m_vpMp3HandlerTagData); const deque<const Mp3Handler*>& vpHndl (m_pCommonData->getCrtAlbum()); if (!v.empty() && cSize(v) != cSize(vpHndl)) { bClearData = true; // needed for the case when proc orig files are kept or when changed files are nor created } //qDebug("------------------------- dir %s -------------------------", vpHndl[0]->getDir().c_str()); if (bClearData) { //qDebug(">>>>>>>>>>>>>>>>>>>>>>>>> initial >>>>>>>>>>>>>>>>>>>>>>>>>"); clearPtrContainer(v); //qDebug("<<<<<<<<<<<<<<<<<<<<<<<<< initial <<<<<<<<<<<<<<<<<<<<<<<<<"); m_imageColl.clear(); m_vnMovedTo.clear(); m_vstrPastedValues.clear(); m_vAlbumInfo.clear(); m_snUnassignedImages.clear(); } if (bClearAssgn) { m_bAutoVarArtists = true; } m_vTagReaderInfo.clear(); set<pair<string, int> > sReaders; std::map<std::string, int> mReaderCount; if (vpHndl.empty()) { m_nCurrentFile = -1; //emit fileChanged(); // just to resize the rows emit albumChanged(); // this will cause the window to close return; // !!! don't add a column for which data doesn't make sense (without this, "pattern" readers would get added, because they exist independently of songs) } CB_ASSERT (v.empty() || cSize(v) == cSize(vpHndl)); int n (cSize(vpHndl)); bool bFullReaderNotFound (false); // ID3V1 is not full, while the others are for (int i = 0; i < n; ++i) { const Mp3Handler* p (vpHndl[i]); std::map<std::string, int> m; bool bTrackHasFullReader (false); const vector<DataStream*>& vStreams (p->getStreams()); for (int i = 0, n = cSize(vStreams); i < n; ++i) { TagReader* pRd (dynamic_cast<TagReader*>(vStreams[i])); if (0 != pRd) { sReaders.insert(make_pair(string(pRd->getName()), m[pRd->getName()])); ++m[pRd->getName()];// = m[pRd->getName()] + 1; if (pRd->getName() != Id3V1Stream::getClassDisplayName()) { bTrackHasFullReader = true; } mReaderCount[pRd->getName()] = max(mReaderCount[pRd->getName()], m[pRd->getName()]); if (bClearData) { // add images try { const vector<ImageInfo> vImg (pRd->getImages()); for (int i = 0; i < cSize(vImg); ++i) { m_imageColl.addImage(vImg[i]); // doesn't matter if it's null or already exists; m_imageColl handles it correctly } } catch (const NotSupportedOp&) { } } } } if (!bTrackHasFullReader) { bFullReaderNotFound = true; } } for (int i = 0, n = cSize(m_vpTrackTextParsers); i < n; ++i) { if (m_snActivePatterns.count(i) > 0) { sReaders.insert(make_pair(string(TrackTextReader::getClassDisplayName()), i)); } } mReaderCount[TrackTextReader::getClassDisplayName()] = cSize(m_vpTrackTextParsers); for (int i = 0, n = cSize(m_vAlbumInfo); i < n; ++i) { sReaders.insert(make_pair(string(WebReader::getClassDisplayName()), i)); } mReaderCount[WebReader::getClassDisplayName()] = cSize(m_vAlbumInfo); for (set<pair<string, int> >::iterator it = sReaders.begin(), end = sReaders.end(); it != end; ++it) { const pair<string, int>& rd (*it); m_vTagReaderInfo.push_back(TagReaderInfo(rd.first, rd.second, 1 == mReaderCount[rd.first])); } sortTagReaders(); if (m_vnMovedTo.empty()) { // needed both at the first run and after eReloadOption is CLEAR m_vnMovedTo.resize(vpHndl.size()); for (int i = 0; i < n; ++i) { m_vnMovedTo[i] = i; } } bool bRescanNeeded (false); { // process handlers in the order in which they appear in vpHndl; m_vpMp3HandlerTagData.resize(n); int nPastedSize (cSize(m_vstrPastedValues)); for (int i = 0; i < n; ++i) { int k (m_vnMovedTo[i]); const Mp3Handler* p (vpHndl[i]); bRescanNeeded = bRescanNeeded || p->needsReload(m_pCommonData->useFastSave()); m_vpMp3HandlerTagData[k] = new Mp3HandlerTagData(this, p, k, i, k < nPastedSize ? m_vstrPastedValues[k] : ""); //cout << "k=" << k << ", i=" << i << ", val=" << (k < nPastedSize ? m_vstrPastedValues[k] : "") << endl; if (!v.empty() && !bClearAssgn) { // copy existing value and status for "assigned" elements const Mp3HandlerTagData& src (*v[k]); Mp3HandlerTagData& dest (*m_vpMp3HandlerTagData[k]); //src.print(); //dest.print(); for (int j = 0; j < TagReader::LIST_END; ++j) { if (Mp3HandlerTagData::ASSIGNED == src.getStatus(j)) // !!! TagReader::FEATURE_ON_POS[] doesn't matter, because it's just a permutation, which is applied to both src and dest { dest.setData(j, src.getData(j)); dest.setStatus(j, Mp3HandlerTagData::ASSIGNED); } } } } adjustVarArtists(); } if (bRescanNeeded && !m_bWaitingChangeNotif) { m_bWaitingChangeNotif = true; QTimer::singleShot(1, this, SLOT(onDelayedChangeNotif())); } m_bShouldShowPatternsNote = false; if (!m_pCommonData->m_bToldAboutPatterns && !s_bToldAboutPatternsInCrtRun) { bool bIncompleteInfo (false); // turns true if a track is found that has empty artist, track number, or title; or if it only has ID3V1 if (!bFullReaderNotFound) { for (int i = 0; i < n; ++i) { if (m_vpMp3HandlerTagData[i]->getData(TagReader::TRACK_NUMBER).empty() || m_vpMp3HandlerTagData[i]->getData(TagReader::TITLE).empty() || m_vpMp3HandlerTagData[i]->getData(TagReader::ALBUM).empty() || m_vpMp3HandlerTagData[i]->getData(TagReader::ARTIST).empty()) { bIncompleteInfo = true; break; } } } if (bIncompleteInfo || bFullReaderNotFound) { m_bShouldShowPatternsNote = true; } } if (v.empty()) { sortSongs(); } //qDebug(">>>>>>>>>>>>>>>>>>>>>>>>> after merge >>>>>>>>>>>>>>>>>>>>>>>>>"); clearPtrContainer(v); //qDebug("<<<<<<<<<<<<<<<<<<<<<<<<< after merge <<<<<<<<<<<<<<<<<<<<<<<<<"); if (bClearData) { // add images from crt dir if (n > 0) { // scan crt dir for images //ttt2 this needs rewrite if an album means something else than a directory CursorOverrider crs; string strDir (vpHndl[0]->getDir()); FileSearcher fs (strDir); while (fs) { if (fs.isFile()) { string s (fs.getName()); QString qs (convStr(s)); if (qs.endsWith(".jpg", Qt::CaseInsensitive) || qs.endsWith(".jpeg", Qt::CaseInsensitive) || qs.endsWith(".png", Qt::CaseInsensitive)) { addImgFromFile(qs, CONSIDER_ASSIGNED); } } fs.findNext(); } } //emit tagWriterChanged(); // !!! needed here to avoid an assert that would be triggered by pSelModel->setCurrentIndex() when detecting a mismatch between the number of images in m_pCommonData->m_imageColl and the widgets that show them } //printVec(m_vTagReaderInfo); //printVec(m_vSortedKnownTagReaders); emit albumChanged(/*DONT_CLEAR == eReloadOption*/); emit imagesChanged(); setCrt(strCrt); emit varArtistsUpdated(m_bVariousArtists); } void TagWriter::adjustVarArtists() { if (!m_bAutoVarArtists) { return; } // !!! this gets called from reloadAll(); without the test it would lead to overriding whatever the user set bool bPrev (m_bVariousArtists); m_bVariousArtists = false; int n (cSize(m_vpMp3HandlerTagData)); if (n > 1) { string strArtist (m_vpMp3HandlerTagData[0]->getData(TagReader::ARTIST)); for (int i = 1; i < n; ++i) { if (strArtist != m_vpMp3HandlerTagData[i]->getData(TagReader::ARTIST)) { m_bVariousArtists = true; break; } } } for (int i = 0; i < n; ++i) { m_vpMp3HandlerTagData[i]->adjustVarArtists(m_bVariousArtists); } if (bPrev != m_bVariousArtists) { emit varArtistsUpdated(m_bVariousArtists); } } void TagWriter::toggleVarArtists() { m_bAutoVarArtists = false; m_bVariousArtists = !m_bVariousArtists; string s (m_bVariousArtists ? TagReader::getVarArtistsValue() : ""); set<int> snSelSongs; for (set<OrigValue>::iterator it = m_sSelOrigVal.begin(), end = m_sSelOrigVal.end(); it != end; ++it) { const OrigValue& o (*it); if (o.m_nField == (int)TagReader::VARIOUS_ARTISTS) { snSelSongs.insert(o.m_nSong); } } for (int i = 0; i < cSize(m_vpMp3HandlerTagData); ++i) { Mp3HandlerTagData* p (m_vpMp3HandlerTagData[i]); if (Mp3HandlerTagData::ASSIGNED != p->getStatus(TagReader::VARIOUS_ARTISTS) || m_nCurrentFile == i || snSelSongs.count(i) > 0) { p->setData(TagReader::VARIOUS_ARTISTS, s); } } emit albumChanged(); emit varArtistsUpdated(m_bVariousArtists); } void TagWriter::delayedAdjVarArtists() { if (m_bDelayedAdjVarArtists) { return; } m_bDelayedAdjVarArtists = true; QTimer::singleShot(1, this, SLOT(onDelayedAdjVarArtists())); } void TagWriter::onDelayedAdjVarArtists() { m_bDelayedAdjVarArtists = false; adjustVarArtists(); emit albumChanged(); } void TagWriter::setCrt(const std::string& strCrt) { m_nCurrentFile = 0; for (int i = 0, n = cSize(m_vpMp3HandlerTagData); i < n; ++i) { if (strCrt == m_vpMp3HandlerTagData[i]->getMp3Handler()->getName()) { m_nCurrentFile = i; break; } } emit fileChanged(); } void TagWriter::setCrt(int nCrt) { CB_ASSERT (0 <= nCrt && nCrt < cSize(m_vpMp3HandlerTagData)); m_nCurrentFile = nCrt; //qDebug("2 m_nCurrentFile=%d", m_nCurrentFile); emit fileChanged(); } /* 1) updatePatterns() is called, which updates m_vpTrackTextParsers and m_vSortedKnownTagReaders, then calls reloadAll() 2) reloadAll() gets all readers from current album and from m_vpTrackTextParsers and puts them in m_vTagReaderInfo 3) reloadAll() sorts m_vTagReaderInfo, so that it matches m_vSortedKnownTagReaders; 4) whatever elements remain in m_vTagReaderInfo without a corresponding element in m_vSortedKnownTagReaders will be at the right; they also get added to m_vSortedKnownTagReaders and at app exit they get saved in the conf file; */ // the int tells which position a given pattern occupied before; (it's -1 for new patterns); // doesn't throw, but invalid patterns are discarded; it returns false if at least one pattern was discarded; bool TagWriter::updatePatterns(const std::vector<std::pair<std::string, int> >& v) { set<string> sstrActive; { vector<string> v (getPatterns()); set<int> s (getActivePatterns()); for (set<int>::const_iterator it = s.begin(); it != s.end(); ++it) { sstrActive.insert(v[*it]); } } clearPtrContainer(m_vpTrackTextParsers); bool bRes (true); for (int i = 0, n = cSize(v); i < n; ++i) { //cout << v[i].first << " " << v[i].second << endl; ? ok, but try { m_vpTrackTextParsers.push_back(new SongInfoParser::TrackTextParser(v[i].first)); } catch (const SongInfoParser::TrackTextParser::InvalidPattern&) { // ignore the pattern and report that there was an error bRes = false; } } { // update m_vSortedKnownTagReaders based on v[i].second vector<TagReaderInfo> vNew; for (int i = 0, n = cSize(m_vSortedKnownTagReaders); i < n; ++i) { bool bAdd (true); TagReaderInfo inf (m_vSortedKnownTagReaders[i]); if (TrackTextReader::getClassDisplayName() == inf.m_strName) { int j (0); const int m (cSize(v)); for (; j < m; ++j) { if (v[j].second == inf.m_nPos) { inf.m_nPos = j; break; } } if (m == j) { bAdd = false; } } if (bAdd) { vNew.push_back(inf); } } // !!! elements from v with a pos of -1 don't get added to vNew (therefore m_vSortedKnownTagReaders), which is OK: they will be visible anyway (because they are added to m_vpTrackTextParsers), but they will be placed at the end of the list (as having no correspondence in m_vSortedKnownTagReaders when sortTagReaders() gets called); vNew.swap(m_vSortedKnownTagReaders); } { vector<string> v (getPatterns()); m_snActivePatterns.clear(); for (int i = 0; i < cSize(v); ++i) { if (sstrActive.count(v[i]) > 0) { m_snActivePatterns.insert(i); //ttt2 not quite right: for 2 identical patterns of which one was selected before, both will be selected now; } } } reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); return bRes; } vector<string> TagWriter::getPatterns() const { vector<string> v; for (int i = 0, n = cSize(m_vpTrackTextParsers); i < n; ++i) { v.push_back(m_vpTrackTextParsers[i]->getPattern()); // !!! may throw } return v; } void TagWriter::setActivePatterns(const std::set<int>& s) { m_snActivePatterns = s; reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); } int TagWriter::getIndex(const ImageInfo& img) const { //return 0; return m_imageColl.find(img); } void TagWriter::moveReader(int nOldVisualIndex, int nNewVisualIndex) { int n (cSize(m_vTagReaderInfo)); CB_ASSERT (nOldVisualIndex >=0 && nOldVisualIndex < n && nNewVisualIndex >=0 && nNewVisualIndex < n); TagReaderInfo inf (m_vTagReaderInfo[nOldVisualIndex]); m_vTagReaderInfo.erase(m_vTagReaderInfo.begin() + nOldVisualIndex); m_vTagReaderInfo.insert(m_vTagReaderInfo.begin() + nNewVisualIndex, inf); //printVec(m_vTagReaderInfo); //printVec(m_vSortedKnownTagReaders); vector<TagReaderInfo>::iterator it (find(m_vSortedKnownTagReaders.begin(), m_vSortedKnownTagReaders.end(), inf)); CB_ASSERT (m_vSortedKnownTagReaders.end() != it); m_vSortedKnownTagReaders.erase(it); if (0 == nNewVisualIndex) { m_vSortedKnownTagReaders.insert(m_vSortedKnownTagReaders.begin(), inf); } else { if (nNewVisualIndex < n - 1) { it = find(m_vSortedKnownTagReaders.begin(), m_vSortedKnownTagReaders.end(), m_vTagReaderInfo[nNewVisualIndex + 1]); CB_ASSERT (m_vSortedKnownTagReaders.end() != it); //assert when move col 0 over 1 } else { CB_ASSERT (nNewVisualIndex > 0); // well, it's n-1 it = find(m_vSortedKnownTagReaders.begin(), m_vSortedKnownTagReaders.end(), m_vTagReaderInfo[nNewVisualIndex - 1]); CB_ASSERT (m_vSortedKnownTagReaders.end() != it); ++it; } m_vSortedKnownTagReaders.insert(it, inf); } reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); } // should be called when the selection changes; updates m_sSelOrigVal and returns the new state of m_pAssignedB; AssgnBtnWrp::State TagWriter::updateAssigned(const vector<pair<int, int> >& vFields) { //cout << ">>> updateAssigned()\n"; printContainer(m_sSelOrigVal, cout, "\n"); set<OrigValue> s; int nAsgnCount (0); for (int i = 0, n = cSize(vFields); i < n; ++i) { int nSong (vFields[i].first); int nField (vFields[i].second); //cout << "look at " << nSong << ":" << nField << endl; //nField = TagReader::FEATURE_ON_POS[nField]; //const Mp3HandlerTagData& d (*m_pTagWriter->m_vpMp3HandlerTagData[nSong]); OrigValue val (OrigValue(nSong, nField, getData(nSong, nField), getStatus(nSong, nField))); set<OrigValue>::iterator it (m_sSelOrigVal.find(val)); const OrigValue& insVal (it == m_sSelOrigVal.end() ? val : *it); // !!! the test is needed because after toggling from assigned to unassigned the shown value changes to reflect the first tag; then when toggling back we need the old value, to restore //cout << " adding " << insVal.m_nSong << ":" << insVal.m_nField << " " << insVal.m_strVal << endl; s.insert(insVal); //if (insVal.m_eStatus nAsgnCount if (Mp3HandlerTagData::ASSIGNED == val.m_eStatus) // !!! val, not insVal { ++nAsgnCount; } } s.swap(m_sSelOrigVal); //Mp3HandlerTagData::Status eStatus (m_pTagWriter->getStatus(index.row(), index.column())); AssgnBtnWrp::State eRes (0 == nAsgnCount ? AssgnBtnWrp::NONE_ASSGN : (nAsgnCount < cSize(m_sSelOrigVal) ? AssgnBtnWrp::SOME_ASSGN : AssgnBtnWrp::ALL_ASSGN)); //cout << nAsgnCount << " assgn, " << cSize(m_sSelOrigVal) << " total, " << listSel.size() << "listSel" << endl; m_bSomeSel = AssgnBtnWrp::SOME_ASSGN == eRes; //cout << "<<< updateAssigned()\n"; printContainer(m_sSelOrigVal, cout, "\n"); return eRes; } void TagWriter::eraseFields(const std::vector<std::pair<int, int> >& vFields) { for (int i = 0, n = cSize(vFields); i < n; ++i) { int nSong (vFields[i].first); int nField (vFields[i].second); try { m_vpMp3HandlerTagData[nSong]->setData(nField, ""); } catch (const Mp3HandlerTagData::InvalidValue&) { // nothing } } } // artist and album for the current song; empty if they don't exist void TagWriter::getAlbumInfo(std::string& strArtist, std::string& strAlbum) { if (m_vpMp3HandlerTagData.empty()) { strArtist.clear(); strAlbum.clear(); return; } /*int nCrt (m_pCommonData->m_pCurrentAlbumG->currentIndex().row()); const Mp3HandlerTagData& d (*m_vpMp3HandlerTagData[nCrt]);*/ /*for (int i = 0; i < 9; ++i) { cout << d.getData(i) << endl; }*/ /*strArtist = d.getData2(TagReader::ARTIST); strAlbum = d.getData2(TagReader::ALBUM);*/ //s = convStr(d.getData(TagReader::FEATURE_ON_POS[j - 1])); CB_ASSERT (m_nCurrentFile >= 0); //const Mp3HandlerTagData& d (*m_vpMp3HandlerTagData[m_nCurrentFile]); strArtist = getData(m_nCurrentFile, TagReader::ARTIST); strAlbum = getData(m_nCurrentFile, TagReader::ALBUM); } void TagWriter::onAssignImage(int nPos) { char a [10]; sprintf(a, g_szImageFmt, nPos + 1); set<int> snSelSongs; for (set<OrigValue>::iterator it = m_sSelOrigVal.begin(), end = m_sSelOrigVal.end(); it != end; ++it) { const OrigValue& o (*it); if (o.m_nField == (int)TagReader::IMAGE) { snSelSongs.insert(o.m_nSong); } } for (int i = 0; i < cSize(m_vpMp3HandlerTagData); ++i) { Mp3HandlerTagData* p (m_vpMp3HandlerTagData[i]); if (Mp3HandlerTagData::ASSIGNED != p->getStatus(TagReader::IMAGE) || m_nCurrentFile == i || snSelSongs.count(i) > 0) { p->setData(TagReader::IMAGE, a); } } m_snUnassignedImages.erase(nPos); //m_pCommonData->m_pCurrentAlbumG->repaint(); reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); } void TagWriter::onEraseFile(int nPos) { m_nFileToErase = nPos; QTimer::singleShot(1, this, SLOT(onEraseFileDelayed())); } void TagWriter::onEraseFileDelayed() { const TagWrtImageInfo& inf (m_imageColl[m_nFileToErase]); CB_ASSERT (!inf.m_sstrFiles.empty()); QString s; if (inf.m_sstrFiles.size() > 1) { s = "these files?"; for (set<string>::const_iterator it = inf.m_sstrFiles.begin(); it != inf.m_sstrFiles.end(); ++it) { s += "\n" + convStr(toNativeSeparators(*it)); } } else { s = "\"" + convStr(toNativeSeparators(*inf.m_sstrFiles.begin())) + "\""; } if (0 != showMessage(m_pParentWnd, QMessageBox::Question, 1, 1, "Confirm", "Do you want to erase " + s, "Erase", "Cancel")) { return; } bool bAssigned, bNonId3V2; hasUnsaved(bAssigned, bNonId3V2); if (bAssigned) { if (0 != showMessage(m_pParentWnd, QMessageBox::Critical, 1, 1, "Error", "You cannot erase image files if there are unsaved values. Do you want to save?", "Save, then erase file", "Cancel")) { return; } emit requestSave(); hasUnsaved(bAssigned, bNonId3V2); if (bAssigned) { return; } } if (!m_vAlbumInfo.empty() || !m_vstrPastedValues.empty()) { if (0 != showMessage(m_pParentWnd, QMessageBox::Critical, 1, 1, "Warning", "Erasing image files triggers a full reload, which results in downloaded and pasted data being lost. Erase anyway?", "Erase", "Cancel")) { return; } } for (set<string>::const_iterator it = inf.m_sstrFiles.begin(); it != inf.m_sstrFiles.end(); ++it) { if (!QFile(convStr(*it)).remove()) { QMessageBox::critical(m_pParentWnd, "Error", QString("Couldn't erase file \"%1\"").arg(toNativeSeparators(convStr(*it)))); } } reloadAll(getCurrentName(), CLEAR_DATA, CLEAR_ASSGN); } // should be called when the user clicks on the assign button; changes status of selected cells and returns the new state of m_pAssignedB AssgnBtnWrp::State TagWriter::toggleAssigned(AssgnBtnWrp::State eCrtState) { if (m_sSelOrigVal.empty()) { return eCrtState; } // !!! covers the case when only fields in the "file name" column are selected //cout << " >>> toggleAssigned()\n"; printContainer(m_sSelOrigVal, cout, "\n"); AssgnBtnWrp::State eRes; //AssgnBtnWrp::State eState (m_pCommonData->m_assgnBtnWrp.getState()); switch (eCrtState) { case AssgnBtnWrp::ALL_ASSGN: // switch to "NONE" for (set<OrigValue>::iterator it = m_sSelOrigVal.begin(), end = m_sSelOrigVal.end(); it != end; ++it) { const OrigValue& val (*it); //setData(val.m_nSong, val.m_nField, val setStatus(val.m_nSong, val.m_nField, Mp3HandlerTagData::NON_ID3V2_VAL); } eRes = AssgnBtnWrp::NONE_ASSGN; break; case AssgnBtnWrp::NONE_ASSGN: // switch to "SOME" if it exists; otherwise switch to "ALL" if (m_bSomeSel) { for (set<OrigValue>::iterator it = m_sSelOrigVal.begin(), end = m_sSelOrigVal.end(); it != end; ++it) { const OrigValue& val (*it); setData(val.m_nSong, val.m_nField, val.m_strVal); setStatus(val.m_nSong, val.m_nField, val.m_eStatus); } eRes = AssgnBtnWrp::SOME_ASSGN; break; } // break; !!! don't "break" case AssgnBtnWrp::SOME_ASSGN: // switch to "ALL" for (set<OrigValue>::iterator it = m_sSelOrigVal.begin(), end = m_sSelOrigVal.end(); it != end; ++it) { const OrigValue& val (*it); setData(val.m_nSong, val.m_nField, val.m_strVal); setStatus(val.m_nSong, val.m_nField, Mp3HandlerTagData::ASSIGNED); } eRes = AssgnBtnWrp::ALL_ASSGN; break; default: CB_ASSERT(false); } reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); //cout << " <<< toggleAssigned()\n"; printContainer(m_sSelOrigVal, cout, "\n"); return eRes; } void TagWriter::copyFirst() { if (m_sSelOrigVal.empty()) { return; } set<int> sDupCols; for (set<OrigValue>::iterator it = m_sSelOrigVal.begin(), end = m_sSelOrigVal.end(); it != end; ++it) { sDupCols.insert(it->m_nField); } sDupCols.erase(TagReader::TITLE); sDupCols.erase(TagReader::RATING); sDupCols.erase(TagReader::TRACK_NUMBER); for (set<int>::iterator it = sDupCols.begin(), end = sDupCols.end(); it != end; ++it) { int nField (*it); string s (getData(0, nField)); for (int i = 1, n = cSize(m_vpMp3HandlerTagData); i < n; ++i) // !!! i starts at 1; { setData(i, nField, s); } } reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); } bool TagWriter::addImgFromFile(const QString& qs, bool bConsiderAssigned) { QFile f (qs); bool bRes (false); if (f.open(QIODevice::ReadOnly)) { CursorOverrider crsOv; int nSize ((int)f.size()); QByteArray comprImg (f.read(nSize)); QImage pic; if (pic.loadFromData(comprImg)) { bRes = true; ImageInfo::Compr eCompr; int nWidth, nHeight; if (nSize <= ImageInfo::MAX_IMAGE_SIZE) { nWidth = pic.width(); nHeight = pic.height(); eCompr = qs.endsWith(".png", Qt::CaseInsensitive) ? ImageInfo::PNG : ImageInfo::JPG; //ttt2 add more cases if supporting more image types } else { QImage scaledImg; ImageInfo::compress(pic, scaledImg, comprImg); nWidth = scaledImg.width(); nHeight = scaledImg.height(); eCompr = ImageInfo::JPG; } ImageInfo img (-1, ImageInfo::OK, eCompr, comprImg, nWidth, nHeight); //int nSize (m_imageColl.size()); int nPrevSize (m_imageColl.size()); int nPos (m_imageColl.addImage(img, convStr(qs))); CB_ASSERT (-1 != nPos); if (nPrevSize != m_imageColl.size()) { CB_ASSERT (m_imageColl.size() == nPos + 1); if (!bConsiderAssigned) { m_snUnassignedImages.insert(nPos); } } /*if (nSize == m_imageColl.size()) // !!! it seemed to make sense to warn the user about duplicates; however, this is also triggered when entering a directory that has contains images after one of those images is assigned to a file; { CursorOverrider crs (Qt::ArrowCursor); QMessageBox::warning(m_pParentWnd, "Warning", QString("Image in file \"%1\" was already added to the image collection, so it won't be added a second time").arg(qs)); }*/ } } return bRes; } void TagWriter::paste() { CursorOverrider crs; QClipboard* pClp (QApplication::clipboard()); QPixmap pic (pClp->pixmap()); //ttt2 this leads in many cases to recompression; see how to avoid it; (probably ask the clipboard for other formats) if (!pic.isNull()) { ImageInfo img (-1, ImageInfo::OK, pic.toImage()); //ttt2 only reason to change image widget is because images were loaded, so perhaps adjust signals; (keep in mind first time, though) //emit imagesChanged(); addImage(img, CONSIDER_UNASSIGNED); return; } //ttt2 text file name, including "http://", "ftp://", "file://" (see KIO::NetAccess::download() at http://developer.kde.org/documentation/books/kde-2.0-development/ch07lev1sec5.html ) QString qs (pClp->text()); if (qs.isEmpty()) { const QMimeData* p (pClp->mimeData()); QList<QUrl> lst (p->urls()); bool bWarned (false); for (int i = 0; i < lst.size(); ++i) { QString qs1 (lst[i].toString()); //qDebug("#%s#", qs1.toUtf8().constData()); if (!qs1.isEmpty()) { if (qs.isEmpty()) { qs = qs1; } else { if (!bWarned) { bWarned = true; QMessageBox::warning(m_pParentWnd, "Warning", "Currently pasting multiple file names is not supported, so only the first one is considered."); } } } else { } } if (lst.size() > 0) { qs = lst.front().toString(); } } if (!qs.isEmpty()) { if (-1 == qs.indexOf('\n')) { if (qs.startsWith("file://")) { qs.remove(0, 7); } #ifndef WIN32 #else // when copying paths from explorer we get something like "file:///E:/Multimedia/Images/img1.jpg". After removing first 7 chars we are left with "/E:/Multimedia/Images/img1.jpg", so one more has to be removed if (qs.size() > 8 && qs[0] == getPathSep() && qs[1].isLetter() && qs[2] == ':' && qs[3] == getPathSep()) { qs.remove(0, 1); } #endif #ifndef WIN32 if (qs.startsWith(getPathSep())) // ttt2 see if it makes sense to open files without full name #else qs = fromNativeSeparators(qs); //qDebug("qs=%s", qs.toUtf8().constData()); if (qs.size() > 7 && qs[0].isLetter() && qs[1] == ':' && qs[2] == getPathSep()) #endif { if (addImgFromFile(qs, CONSIDER_UNASSIGNED)) { emit imagesChanged(); return; } } { int nOk (0), nFail (0); for (set<OrigValue>::iterator it = m_sSelOrigVal.begin(); it != m_sSelOrigVal.end(); ++it) { const OrigValue& val (*it); //qDebug ("song %d, fld %d, val %s", val.m_nSong, val.m_nField, val.m_strVal.c_str()); if (TagReader::IMAGE != val.m_nField) // IMAGE is read-only from grid editing's point of view { Mp3HandlerTagData& dest (*m_vpMp3HandlerTagData[val.m_nSong]); try { dest.setData(val.m_nField, convStr(qs)); dest.setStatus(val.m_nField, Mp3HandlerTagData::ASSIGNED); ++nOk; } catch (const Mp3HandlerTagData::InvalidValue&) { ++nFail; } } } if (nFail > 0) { QMessageBox::critical(m_pParentWnd, "Error", nOk > 0 ? "The pasted value couldn't be assigned to some fields" : "The pasted value couldn't be assigned to any fields"); //ttt2 some/one/several ... } reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); return; } } else { QStringList lst (qs.split("\n", QString::SkipEmptyParts)); if (lst.size() != cSize(m_vpMp3HandlerTagData)) { if (0 != showMessage(m_pParentWnd, QMessageBox::Warning, 1, 1, "Warning", "The number of lines in the clipboard is different from the number of files. Paste anyway?", "Paste", "Cancel")) { return; } } if (m_bNonStandardTrackNo && m_pCommonData->m_bWarnPastingToNonSeqTracks) { if (0 != showMessage(m_pParentWnd, QMessageBox::Warning, 1, 1, "Warning", "The track numbers aren't consecutive numbers starting at 1, so the pasted track information might not match the tracks. Paste anyway?", "Paste", "Cancel")) { return; } } sort(); m_vstrPastedValues.clear(); //int n (min(lst.size(), cSize(m_vpMp3HandlerTagData))); int n (lst.size()); for (int i = 0; i < n; ++i) { //m_vpMp3HandlerTagData[i]->m_strPastedVal = string(lst[m_vnMovedTo[i]].toUtf8()); //m_vstrPastedValues.push_back(string(lst[m_vnMovedTo[i]].toUtf8())); m_vstrPastedValues.push_back(convStr(lst[i])); //cout << "paste " << m_vstrPastedValues[i] << endl; } /*m_pCurrentAlbumModel->emitLayoutChanged(); m_pCurrentFileModel->emitLayoutChanged();*/ reloadAll("", DONT_CLEAR_DATA, DONT_CLEAR_ASSGN); return; } } QMessageBox::critical(m_pParentWnd, "Error", "Unrecognized clipboard content"); } void TagWriter::sort() { sortSongs(); emit albumChanged(/*false*/); } int TagWriter::addImage(const ImageInfo& img, bool bConsiderAssigned) // returns the index of the image; if it already exists it's not added again; if it's invalid returns -1 { int nPrevSize (m_imageColl.size()); int nPos (m_imageColl.addImage(img)); if (nPrevSize != m_imageColl.size()) { CB_ASSERT (m_imageColl.size() == nPos + 1); if (!bConsiderAssigned) { m_snUnassignedImages.insert(nPos); } } emit imagesChanged(); return nPos; } void TagWriter::selectImg(int n) { m_imageColl.select(n); } void TagWriter::addImgWidget(ImageInfoPanelWdgImpl* p) { CB_ASSERT (0 != p); m_imageColl.addWidget(p); } void TagWriter::hasUnsaved(int nSong, bool& bAssigned, bool& bNonId3V2) // sets bAssigned and bNonId3V2 if at least one field has the corresponding status; { bAssigned = false; bNonId3V2 = false; const Mp3HandlerTagData* p (m_vpMp3HandlerTagData.at(nSong)); for (int i = 0; i < TagReader::LIST_END; ++i) { switch (p->getStatus(i)) { case Mp3HandlerTagData::NON_ID3V2_VAL: bNonId3V2 = true; break; case Mp3HandlerTagData::ASSIGNED: bAssigned = true; break; default:; // nothing } } } void TagWriter::hasUnsaved(bool& bAssigned, bool& bNonId3V2) // sets bAssigned and bNonId3V2 if at least one field in at least a song has the corresponding status; { bAssigned = false; bNonId3V2 = false; bool bAssignedSong, bNonId3V2Song; for (int i = 0; i < cSize(m_vpMp3HandlerTagData); ++i) { hasUnsaved(i, bAssignedSong, bNonId3V2Song); bAssigned |= bAssignedSong; bNonId3V2 |= bNonId3V2Song; } } // sets m_eState and changes the button icon accordingly void AssgnBtnWrp::setState(State eState) { static QPixmap picAll (":/images/assgn-all.svg"); static QPixmap picSome (":/images/assgn-some.svg"); static QPixmap picNone (":/images/assgn-none.svg"); m_eState = eState; //const char* szCap (ALL_ASSGN == eState ? "A" : (SOME_ASSGN == eState ? "S" : "N")); m_pButton->setText(szCap); const QPixmap& pic (ALL_ASSGN == eState ? picAll : (SOME_ASSGN == eState ? picSome : picNone)); m_pButton->setIcon(pic); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/StoredSettings.h������������������������������������������������������������0000644�0001750�0000144�00000014755�11267260512�016423� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef StoredSettingsH #define StoredSettingsH #include <string> #include <vector> //#include <QByteArray> #include <QStringList> // ttt2 what we really want is QByteArray; however, by including QByteArray directly, lots of warnings get displayed; perhaps some defines are needed but don't know which; so we just include QStringList to avoid the warnings (see also Helpers.h) class QSettings; class TransfConfig; class CommonData; class SessionSettings { QSettings* m_pSettings; public: SessionSettings(const std::string& strIniFile); ~SessionSettings(); void saveTransfConfig(const TransfConfig& transfConfig); bool loadTransfConfig(TransfConfig& transfConfig) const; // returns false if there was some error while loading (so the user can be told about defaults being used and those defaults could get saved) void saveDirs(const std::vector<std::string>& vstrIncludedDirs, const std::vector<std::string>& vstrExcludedDirs); bool loadDirs(std::vector<std::string>& vstrIncludedDirs, std::vector<std::string>& vstrExcludedDirs) const; // returns false if there were inconsistencies in the settings void saveScanAtStartup(bool b); bool loadScanAtStartup() const; void saveNoteFilterSettings(int nWidth, int nHeight); void loadNoteFilterSettings(int& nWidth, int& nHeight) const; void saveDirFilterSettings(int nWidth, int nHeight); void loadDirFilterSettings(int& nWidth, int& nHeight) const; void saveDiscogsSettings(int nWidth, int nHeight, int nStyleOption); void loadDiscogsSettings(int& nWidth, int& nHeight, int& nStyleOption) const; void saveMusicBrainzSettings(int nWidth, int nHeight); void loadMusicBrainzSettings(int& nWidth, int& nHeight) const; void saveConfigSize(int nWidth, int nHeight); void loadConfigSize(int& nWidth, int& nHeight) const; void saveDebugSettings(int nWidth, int nHeight); void loadDebugSettings(int& nWidth, int& nHeight) const; void saveExportSettings(int nWidth, int nHeight, bool bSortByShortNames, const std::string& strFile, bool bUseVisible, const std::string& strM3uRoot, const std::string& strM3uLocale); void loadExportSettings(int& nWidth, int& nHeight, bool& bSortByShortNames, std::string& strFile, bool& bUseVisible, std::string& strM3uRoot, std::string& strM3uLocale) const; void saveRenamerSettings(int nWidth, int nHeight, int nSaButton, int nVaButton, bool bKeepOrig, bool bUnratedAsDuplicate); void loadRenamerSettings(int& nWidth, int& nHeight, int& nSaButton, int& nVaButton, bool& bKeepOrig, bool& bUnratedAsDuplicate) const; void saveMainSettings(int nWidth, int nHeight, int nNotesGW0, int nNotesGW2, int nStrmsGW0, int nStrmsGW1, int nStrmsGW2, int nStrmsGW3, int nUnotesGW0, const QByteArray& stateMainSpl, const QByteArray& stateLwrSpl, int nIconSize, int nScanWidth); void loadMainSettings(int& nWidth, int& nHeight, int& nNotesGW0, int& nNotesGW2, int& nStrmsGW0, int& nStrmsGW1, int& nStrmsGW2, int& nStrmsGW3, int& nUnotesGW0, QByteArray& stateMainSpl, QByteArray& stateLwrSpl, int& nIconSize, int& nScanWidth) const; void saveNormalizeSettings(int nWidth, int nHeight); void loadNormalizeSettings(int& nWidth, int& nHeight) const; void saveTagEdtPatternsSettings(int nWidth, int nHeight); void loadTagEdtPatternsSettings(int& nWidth, int& nHeight) const; void saveRenamerPatternsSettings(int nWidth, int nHeight); void loadRenamerPatternsSettings(int& nWidth, int& nHeight) const; void saveTagEdtSettings(int nWidth, int nHeight, int nArtistCase, int nTitleCase); // Case params are really enum void loadTagEdtSettings(int& nWidth, int& nHeight, int& nArtistsCase, int& nOthersCase) const; void saveVector(const std::string& strPath, const std::vector<std::string>& v); std::vector<std::string> loadVector(const std::string& strPath, bool& bErr) const; // allows empty entries, but stops at the first missing entry, in which case sets bErr void saveMiscConfigSettings(const CommonData*); void loadMiscConfigSettings(CommonData*) const; void saveDbDirty(bool bDirty); void loadDbDirty(bool& bDirty); void saveCrashedAtStartup(bool bCrashedAtStartup); void loadCrashedAtStartup(bool& bCrashedAtStartup); void saveVersion(const std::string& strVersion); void loadVersion(std::string& strVersion); //ttt2 ??? see about ThreadRunner size; perhaps set width to its parent bool sync(); }; class GlobalSettings { QSettings* m_pSettings; //static QSettings* getGlobalSettings(); public: GlobalSettings(); ~GlobalSettings(); void saveSessions(const std::vector<std::string>& vstrSess, const std::string& strLastSess, bool bOpenLast); void loadSessions(std::vector<std::string>& vstrSess, std::string& strLastSess, bool& bOpenLast) const; void saveSessionsDlgSize(int nWidth, int nHeight); void loadSessionsDlgSize(int& nWidth, int& nHeight) const; void saveSessionEdtSize(int nWidth, int nHeight); void loadSessionEdtSize(int& nWidth, int& nHeight) const; }; #endif �������������������MP3Diags-1.0.12.079/src/AboutDlgImpl.cpp������������������������������������������������������������0000644�0001750�0000144�00000021700�11333606046�016304� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <QFile> #include "AboutDlgImpl.h" #include "Helpers.h" extern const char* APP_VER; AboutDlgImpl::AboutDlgImpl(QWidget* pParent /*= 0*/) : QDialog(pParent, getDialogWndFlags()), Ui::AboutDlg() { setupUi(this); QPalette pal (m_pMainTextM->palette()); pal.setColor(QPalette::Base, pal.color(QPalette::Disabled, QPalette::Window)); m_pMainTextM->setPalette(pal); /* <a href=\"DDDDDDDDDDDDD\">NNNNNNNNNNNNNN</a> */ m_pMainTextM->setHtml( "<p style=\"margin-bottom:8px; margin-top:1px; \">Written by <a href=\"mailto:ciobi@inbox.com?subject=000 MP3 Diags\">Marian Ciobanu (Ciobi)</a>, 2008 - 2009</p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Distributed under <a href=\"http://www.gnu.org/licenses/gpl-2.0.html#TOC1\">GPL V2</a></p>" //"Using <a href=\"http://doc.trolltech.com/4/opensourceedition.html\">Qt 4 Open Source Edition</a><p/>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Using <a href=\"http://www.qtsoftware.com/\">Qt Free Edition</a>, released under <a href=\"http://www.gnu.org/licenses/lgpl-2.1.html\">LGPL 2.1</a></p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Using <a href=\"http://www.zlib.net/\">zlib</a>, released under the <a href=\"http://www.zlib.net/zlib_license.html\">zlib License</a></p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Using <a href=\"http://www.boost.org/doc/libs/1_39_0/libs/serialization/doc/index.html\">Boost Serialization</a>, distributed under the <a href=\"http://www.boost.org/users/license.html\">Boost Software License</a></p>" //"Most icons are either copies or modified versions of icons from the <a href=\"http://www.oxygen-icons.org/\">Oxygen Project</a> for <a href=\"http://www.kde.org/\">KDE 4</a>. They are distributed under <a href=\"http://www.gnu.org/licenses/lgpl.html\">LGPL V3</a><p/>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Using original and modified icons from the <a href=\"http://www.oxygen-icons.org/\">Oxygen Project</a> for <a href=\"http://www.kde.org/\">KDE 4</a>, distributed under <a href=\"http://www.gnu.org/licenses/lgpl.html\">LGPL V3</a></p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Using web services provided by <a href=\"http://www.discogs.com/\">Discogs</a> to retrieve album data</p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Using web services provided by <a href=\"http://musicbrainz.org/\">MusicBrainz</a> to retrieve album data</p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Home page and documentation: <a href=\"http://mp3diags.sourceforge.net/\">http://mp3diags.sourceforge.net/</a></p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Feedback and support: <a href=\"http://sourceforge.net/forum/forum.php?forum_id=947206\">Open Discussion Forum</a> or <a href=\"http://sourceforge.net/forum/forum.php?forum_id=947207\">Help Forum</a> at SourceForge</p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Bug reports and feature requests: <a href=\"http://sourceforge.net/apps/mantisbt/mp3diags/\">MantisBT Issue Tracker</a> at SourceForge</p>" "<p style=\"margin-bottom:8px; margin-top:1px; \">Change log for the latest version: <a href=\"http://mp3diags.sourceforge.net/015_changelog.html\">http://mp3diags.sourceforge.net/015_changelog.html</a></p>" ); m_pVersionL->setText(QString("MP3 Diags ") + APP_VER); initText(m_pGplV2M, ":/licences/gplv2.txt"); initText(m_pGplV3M, ":/licences/gplv3.txt"); initText(m_pLgplV3M, ":/licences/lgplv3.txt"); initText(m_pLgplV21M, ":/licences/lgpl-2.1.txt"); initText(m_pBoostM, ":/licences/boost.txt"); initText(m_pZlibM, ":/licences/zlib.txt"); m_pSysInfoM->setText(getSystemInfo()); m_pMainTextM->setFocus(); //{ QAction* p (new QAction(this)); p->setShortcut(QKeySequence("Ctrl+N")); connect(p, SIGNAL(triggered()), this, SLOT(accept())); addAction(p); } { QAction* p (new QAction(this)); p->setShortcut(QKeySequence("F1")); connect(p, SIGNAL(triggered()), this, SLOT(onHelp())); addAction(p); } } void AboutDlgImpl::initText(QTextBrowser* p, const char* szFileName) { QFile f (szFileName); //QFile::FileError err (f.error()); //qDebug("file: %d", (int)err); //qDebug("size : %d", (int)f.size()); //QByteArray b (f.readAll()); f.open(QIODevice::ReadOnly); //qDebug("read size : %d", (int)b.size()); p->setText(QString::fromUtf8(f.readAll())); } AboutDlgImpl::~AboutDlgImpl() { } void AboutDlgImpl::onHelp() { openHelp("index.html"); } // exist: mp3 insight, mp3 doctor, mp3 butcher, mp3 toolbox, mp3 mechanic, mp3 workshop; //ttt melt ? ice ? ? sorcerer ? exorcist ? healer ? ? MP3 Spy //"mp3 workshop", "mp3 atelier" //workshop synonyms: foundry, laboratory, mill, plant, studio, works // deep understanding /* //bjam --toolset=gcc //PATH=D:\Qt\2009.02\mingw\bin;%PATH% bjam serialization toolset=gcc bjam toolset=gcc serialization threading=multi release http://stackoverflow.com/questions/718447/adding-external-library-into-qt-creator-project http://stackoverflow.com/questions/199092/compiling-a-qt-program-in-windows-xp-with-mingws-g */ /* Finds problems in MP3 files and helps the user to fix many of them using included tools. Looks at both the audio part (VBR info, quality, normalization) and the tags containing track information (ID3.) Also includes a tag editor and a file renamer. */ //PATH=D:\Qt\2009.02\qt\bin;%PATH% //ttt2 perhaps "Scan images in the current folder", checked by default //ttt2 perhaps something to remove image files after assigning them, or at least show them in a different color; it was suggested to add a "-" button to remove images, below the "v" for "assigning them", but not sure it's such great idea; perhaps some option to delete local images that were assigned (but perhaps the unassigned CD scan should go as well); // perhaps "-" works, though; should be enabled/visible only for local files //ttt2 some standard means to log only uncaught exceptions // backport jaunty 9.04 : https://bugs.launchpad.net/jaunty-backports/+bug/423560 /* //ttt2 w7 8.3 names C:\Windows\system32>fsutil behavior query disable8dot3 c: The volume state for Disable8dot3 is 0 (8dot3 name creation is enabled). The registry state of NtfsDisable8dot3NameCreation is 2, the default (Volume level setting). Based on the above two settings, 8dot3 name creation is enabled on c:. */ //ttt2 Perhaps linking Boost statically and Qt dynamically would solve most dependency issues - http://pages.cs.wisc.edu/~thomas/X/static-linking.html : "surround the libraries you wish to link statically with -static and -dynamic (in that order)"; OTOH "-dynamic" is not in man, and that page is from 1997; things have changed, and -static seems to be a global option, so it doesn't matter if you put it first or last; what should work is specifying the file name: -l:libboost_serialization.a rather than -lboost_serialization (!!! note the ":") //ttt2 mutt rips: https://sourceforge.net/projects/mp3diags/forums/forum/947206/topic/3441516 ; also, check for missing tracks and other album-related issues; //ttt0 might have to remove the program before switching packages; - in the fake mp3diags //ttt1 01 - The Privateer.mp3 - go to tag editor, change track, save; new image doesn't show, but there is the original "other" bmp and the new "cover" jpg //ttt2 maybe support for saving images to .directory files - point 7 at https://sourceforge.net/projects/mp3diags/forums/forum/947206/topic/3389395 ����������������������������������������������������������������MP3Diags-1.0.12.079/src/CommonData.cpp��������������������������������������������������������������0000644�0001750�0000144�00000255776�11304471417�016031� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef MSVC_QMAKE #pragma warning (disable : 4100) #endif #include <cmath> #include <algorithm> #include <sstream> #include <QApplication> #include <QToolButton> #include <QTableView> #include <QDesktopWidget> #include <QSettings> #include <QTextCodec> #include <QHeaderView> #include <QMessageBox> #include <QPainter> #include "CommonData.h" #include "Helpers.h" #include "StructuralTransformation.h" #include "Id3Transf.h" #include "OsFile.h" #include "StoredSettings.h" #include "FilesModel.h" // all files #include "NotesModel.h" // current notes #include "StreamsModel.h" // current streams #include "UniqueNotesModel.h" // all notes #include "CommonTypes.h" #include "Widgets.h" using namespace std; using namespace pearl; //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== UniqueNotes::UniqueNotes() : m_bAllDirty(true), m_bFltDirty(true) { } /*UniqueNotes::UniqueNotes(const UniqueNotes& other) { addColl(other.getAllVec()); setSel(other.getSelVec()); }*/ UniqueNotes::~UniqueNotes() { clear(); } void UniqueNotes::clear() { m_spFlt.clear(); //clearPtrContainer(m_spAll); m_spAll.clear(); m_bAllDirty = true; m_bFltDirty = true; } bool UniqueNotes::addNote(const Note* pNote) // if the note doesn't exist in m_spAll, it adds the corresponding note from Notes; returns true if the param really was added; { if (m_spAll.count(pNote) > 0) { return false; } const Note* p (Notes::getMaster(pNote)); CB_ASSERT (0 != p); m_spAll.insert(p); m_bAllDirty = true; return true; } void UniqueNotes::updateVAll() const { if (m_bAllDirty) { m_vpAll.clear(); m_vpAll.insert(m_vpAll.end(), m_spAll.begin(), m_spAll.end()); m_bAllDirty = false; } } void UniqueNotes::updateVFlt() const { if (m_bFltDirty) { m_vpFlt.clear(); m_vpFlt.insert(m_vpFlt.end(), m_spFlt.begin(), m_spFlt.end()); m_bFltDirty = false; } } int UniqueNotes::getPos(const Note* pNote) const // position in the "all" notes; -1 if the note wasn't found; { updateVAll(); vector<const Note*>::const_iterator it (lower_bound(m_vpAll.begin(), m_vpAll.end(), pNote, CmpNotePtrById())); // easier than equal_range() in this case if (it == m_vpAll.end() || !CmpNotePtrById::equals(*it, pNote)) { // trace or info return -1; } return it - m_vpAll.begin(); } int UniqueNotes::getFltPos(const Note* pNote) const // position in the "sel" notes; -1 if the note wasn't found; { updateVFlt(); vector<const Note*>::const_iterator it (lower_bound(m_vpFlt.begin(), m_vpFlt.end(), pNote, CmpNotePtrById())); if (it == m_vpFlt.end() || !CmpNotePtrById::equals(*it, pNote)) { // trace or info return -1; } return it - m_vpFlt.begin(); } const Note* UniqueNotes::getFlt(int n) const { updateVFlt(); return m_vpFlt.at(n); } const Note* UniqueNotes::get(int n) const { updateVAll(); return m_vpAll.at(n); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== void SessionSettings::saveMiscConfigSettings(const CommonData* p) { { // quality m_pSettings->setValue("quality/stereoCbrMinBitrate", p->getQualThresholds().m_nStereoCbr); m_pSettings->setValue("quality/jntStereoCbrMinBitrate", p->getQualThresholds().m_nJointStereoCbr); m_pSettings->setValue("quality/dualChnlCbrMinBitrate", p->getQualThresholds().m_nDoubleChannelCbr); m_pSettings->setValue("quality/stereoVbrMinBitrate", p->getQualThresholds().m_nStereoVbr); m_pSettings->setValue("quality/jntStereoVbrMinBitrate", p->getQualThresholds().m_nJointStereoVbr); m_pSettings->setValue("quality/dualChnlVbrMinBitrate", p->getQualThresholds().m_nDoubleChannelVbr); } { // ID3V2 transf m_pSettings->setValue("id3V2Transf/locale", p->m_locale); m_pSettings->setValue("id3V2Transf/caseForArtists", (int)p->m_eCaseForArtists); m_pSettings->setValue("id3V2Transf/caseForOthers", (int)p->m_eCaseForOthers); } { // tag editor m_pSettings->setValue("tagEditor/warnOnNonSeqTracks", p->m_bWarnOnNonSeqTracks); m_pSettings->setValue("tagEditor/warnOnPasteToNonSeqTracks", p->m_bWarnPastingToNonSeqTracks); m_pSettings->setValue("tagEditor/saveAssigned", (int)p->m_eAssignSave); m_pSettings->setValue("tagEditor/saveNonId3v2", (int)p->m_eNonId3v2Save); m_pSettings->setValue("tagEditor/maxImageSize", ImageInfo::MAX_IMAGE_SIZE); } { // misc m_pSettings->setValue("main/showExport", p->m_bShowExport); m_pSettings->setValue("main/showDebug", p->m_bShowDebug); m_pSettings->setValue("main/showSessions", p->m_bShowSessions); m_pSettings->setValue("normalizer/command", convStr(p->m_strNormalizeCmd)); m_pSettings->setValue("main/keepNormWndOpen", p->m_bKeepNormWndOpen); m_pSettings->setValue("debug/enableTracing", p->m_bTraceEnabled); m_pSettings->setValue("debug/useAllNotes", p->m_bUseAllNotes); m_pSettings->setValue("debug/logTransf", p->m_bLogTransf); m_pSettings->setValue("debug/saveDownloadedData", p->m_bSaveDownloadedData); m_pSettings->setValue("main/autoSizeIcons", p->m_bAutoSizeIcons); m_pSettings->setValue("main/keepOneValidImg", p->m_bKeepOneValidImg); m_pSettings->setValue("main/processWmpVarArtists", p->m_bWmpVarArtists); m_pSettings->setValue("main/processItunesVarArtists", p->m_bItunesVarArtists); m_pSettings->setValue("main/fastSave", p->useFastSave()); m_pSettings->setValue("debug/traceToFile", p->isTraceToFileEnabled()); QFont genFnt (p->getNewGeneralFont()); m_pSettings->setValue("main/generalFontName", genFnt.family()); m_pSettings->setValue("main/generalFontSize", genFnt.pointSize()); m_pSettings->setValue("main/labelFontSizeDecr", p->getLabelFontSizeDecr()); QFont fixedFnt (p->getNewFixedFont()); m_pSettings->setValue("main/fixedFontName", fixedFnt.family()); m_pSettings->setValue("main/fixedFontSize", fixedFnt.pointSize()); m_pSettings->setValue("main/warnedAboutSel", p->m_bWarnedAboutSel); m_pSettings->setValue("main/warnedAboutBackup", p->m_bWarnedAboutBackup); m_pSettings->setValue("tagEditor/toldAboutPatterns", p->m_bToldAboutPatterns); m_pSettings->setValue("main/toldAboutSupport", p->m_bToldAboutSupport); m_pSettings->setValue("fileRenamer/invalidChars", convStr(p->m_strRenamerInvalidChars)); m_pSettings->setValue("fileRenamer/replacementForInvalid", convStr(p->m_strRenamerReplacementString)); m_pSettings->setValue("main/checkForNewVersions", convStr(p->m_strCheckForNewVersions)); m_pSettings->setValue("main/timeLastNewVerCheck", p->m_timeLastNewVerCheck); m_pSettings->setValue("main/dontTellAboutVer", convStr(p->m_strDontTellAboutVer)); } { // note categ colors vector<string> v; for (int i = 0; i < Note::CATEG_CNT; ++i) { QColor c (p->m_vNoteCategColors[i]); char a [20]; sprintf(a, "%d %d %d", c.red(), c.green(), c.blue()); v.push_back(a); } p->m_settings.saveVector("categories/colors", v); } { // tag edt colors vector<string> v; for (int i = 0; i < CommonData::COLOR_COL_CNT; ++i) { QColor c (p->m_vTagEdtColors[i]); char a [20]; sprintf(a, "%d %d %d", c.red(), c.green(), c.blue()); v.push_back(a); } p->m_settings.saveVector("tagEditor/colors", v); } } static bool isWhite(const QColor& c) { //qDebug("%d %d %d", c.red(), c.green(), c.blue()); return c.red() >= 254 && c.green() >= 254 && c.blue() >= 254; } void SessionSettings::loadMiscConfigSettings(CommonData* p) const { { // quality QualThresholds q; q.m_nStereoCbr = m_pSettings->value("quality/stereoCbrMinBitrate", 192000).toInt(); q.m_nJointStereoCbr = m_pSettings->value("quality/jntStereoCbrMinBitrate", 192000).toInt(); q.m_nDoubleChannelCbr = m_pSettings->value("quality/dualChnlCbrMinBitrate", 192000).toInt(); q.m_nStereoVbr = m_pSettings->value("quality/stereoVbrMinBitrate", 170000).toInt(); q.m_nJointStereoVbr = m_pSettings->value("quality/jntStereoVbrMinBitrate", 160000).toInt(); q.m_nDoubleChannelVbr = m_pSettings->value("quality/dualChnlVbrMinBitrate", 180000).toInt(); p->setQualThresholds(q); } { // ID3V2 transf p->m_locale = m_pSettings->value("id3V2Transf/locale", "ISO 8859-1").toByteArray(); p->m_pCodec = (QTextCodec::codecForName(p->m_locale)); if (0 == p->m_pCodec) { /*QList<QByteArray> l (QTextCodec::availableCodecs()); CB_ASSERT (l.size() > 0); p->m_locale = l.front();*/ p->m_locale = "System"; // ttt2 2009.11.03 - actually this seems a bad idea; at least on 10.3 / 4.3.1 setting the locale to System shows no characters for codes > 128; doesn't happen in W7, though p->m_pCodec = (QTextCodec::codecForName(p->m_locale)); } else { p->m_locale = p->m_pCodec->name(); // !!! needed because the names may be different ("ISO 8859-1" vs. "ISO-8859-1") } CB_ASSERT (0 != p->m_pCodec); p->m_eCaseForArtists = (TextCaseOptions)m_pSettings->value("id3V2Transf/caseForArtists", 2).toInt(); p->m_eCaseForOthers = (TextCaseOptions)m_pSettings->value("id3V2Transf/caseForOthers", 3).toInt(); } { // tag editor p->m_bWarnOnNonSeqTracks = m_pSettings->value("tagEditor/warnOnNonSeqTracks", true).toBool(); p->m_bWarnPastingToNonSeqTracks = m_pSettings->value("tagEditor/warnOnPasteToNonSeqTracks", true).toBool(); { int k (m_pSettings->value("tagEditor/saveAssigned", 2).toInt()); if (k < 0 || k > 2) { k = 2; } p->m_eAssignSave = CommonData::Save(k); } { int k (m_pSettings->value("tagEditor/saveNonId3v2", 2).toInt()); if (k < 0 || k > 2) { k = 2; } p->m_eNonId3v2Save = CommonData::Save(k); } ImageInfo::MAX_IMAGE_SIZE = m_pSettings->value("tagEditor/maxImageSize", 102400).toInt(); } { // misc p->m_bShowExport = m_pSettings->value("main/showExport", false).toBool(); p->m_bShowDebug = m_pSettings->value("main/showDebug", false).toBool(); p->m_bShowSessions = m_pSettings->value("main/showSessions", !p->isUniqueSession()).toBool(); p->m_strNormalizeCmd = convStr(m_pSettings->value("normalizer/command", "mp3gain -a -k -p -t").toString()); p->m_bKeepNormWndOpen = m_pSettings->value("main/keepNormWndOpen", false).toBool(); p->m_bTraceEnabled = m_pSettings->value("debug/enableTracing", false).toBool(); p->m_bUseAllNotes = m_pSettings->value("debug/useAllNotes", false).toBool(); p->m_bLogTransf = m_pSettings->value("debug/logTransf", false).toBool(); p->m_bSaveDownloadedData = m_pSettings->value("debug/saveDownloadedData", false).toBool(); p->m_bAutoSizeIcons = m_pSettings->value("main/autoSizeIcons", true).toBool(); p->m_bKeepOneValidImg = m_pSettings->value("main/keepOneValidImg", false).toBool(); p->m_bWmpVarArtists = m_pSettings->value("main/processWmpVarArtists", false).toBool(); p->m_bItunesVarArtists = m_pSettings->value("main/processItunesVarArtists", false).toBool(); p->setFastSave(m_pSettings->value("main/fastSave", false).toBool(), CommonData::DONT_UPDATE_TRANSFORMS); p->setTraceToFile(m_pSettings->value("debug/traceToFile", false).toBool()); QFont fnt; //qDebug("%d ==========================", fnt.pointSize()); QFontInfo inf1 (QFont(m_pSettings->value("main/generalFontName", "SansSerif").toString(), m_pSettings->value("main/generalFontSize", fnt.pointSize()).toInt())); // ttt2 try and get the system defaults QFontInfo inf2 (QFont(m_pSettings->value("main/fixedFontName", "Courier").toString(), m_pSettings->value("main/fixedFontSize", fnt.pointSize()).toInt())); p->setFontInfo(convStr(inf1.family()), inf1.pointSize(), m_pSettings->value("main/labelFontSizeDecr", 0).toInt(), convStr(inf2.family()), inf2.pointSize()); p->m_bWarnedAboutSel = m_pSettings->value("main/warnedAboutSel", false).toBool(); p->m_bWarnedAboutBackup = m_pSettings->value("main/warnedAboutBackup", false).toBool(); p->m_bToldAboutPatterns = m_pSettings->value("tagEditor/toldAboutPatterns", false).toBool(); p->m_bToldAboutSupport = m_pSettings->value("main/toldAboutSupport", false).toBool(); #ifndef WIN32 const char* DEFAULT_INVALID ("/\"\\*?<>|"); //ttt2 even in Unix, it might be a good idea to not allow ":" as well in some cases, depending on the file system #else const char* DEFAULT_INVALID ("/\"\\*?<>|:"); //ttt2 perhaps have yellow background instead of underline, to be able to tell if there's a space or not; or have something like a progres bar below; or have each letter in its own rectangle; #endif p->m_strRenamerInvalidChars = convStr(m_pSettings->value("fileRenamer/invalidChars", DEFAULT_INVALID).toString()); p->m_strRenamerReplacementString = convStr(m_pSettings->value("fileRenamer/replacementForInvalid", "_").toString()); p->m_strCheckForNewVersions = convStr(m_pSettings->value("main/checkForNewVersions", "").toString()); p->m_timeLastNewVerCheck = m_pSettings->value("main/timeLastNewVerCheck").toDateTime(); if (p->m_timeLastNewVerCheck.isNull()) { QDateTime t1 (QDateTime::currentDateTime()); p->m_timeLastNewVerCheck = t1.addYears(-1); } p->m_strDontTellAboutVer = convStr(m_pSettings->value("main/dontTellAboutVer", "").toString()); } { // note categ colors //m_settings.saveVector("categories/colors", u); bool bErr; vector<string> v (loadVector("categories/colors", bErr)); int i (0); for (; i < Note::CATEG_CNT && i < cSize(v); ++i) { int r (230), g (230), b (230); istringstream in (v[i]); in >> r >> g >> b; p->m_vNoteCategColors.push_back(QColor(r, g, b)); } QColor c (getDefaultBkgCol()); for (; i < Note::CATEG_CNT; ++i) { //p->m_vNoteCategColors.push_back(QColor(240, 240 + i, 240 - i)); p->m_vNoteCategColors.push_back(c); } } { // tag edt colors bool bErr; vector<string> v (loadVector("tagEditor/colors", bErr)); for (int i = 0; i < CommonData::COLOR_COL_CNT && i < cSize(v); ++i) { int r (230), g (230), b (230); istringstream in (v[i]); in >> r >> g >> b; p->m_vTagEdtColors.push_back(QColor(r, g, b)); } QColor defNormal (QPalette().color(QPalette::Active, QPalette::Base)); if (cSize(p->m_vTagEdtColors) <= 0) { p->m_vTagEdtColors.push_back(defNormal); } // COLOR_ALB_NORM if (cSize(p->m_vTagEdtColors) <= 1) { p->m_vTagEdtColors.push_back(QColor(0xffffdd)); } // COLOR_ALB_NONID3V2 if (cSize(p->m_vTagEdtColors) <= 2) { p->m_vTagEdtColors.push_back(QColor(0xccccff)); } // COLOR_ALB_ASSIGNED if (cSize(p->m_vTagEdtColors) <= 3) { p->m_vTagEdtColors.push_back(QColor(defNormal)); } // COLOR_FILE_NORM if (cSize(p->m_vTagEdtColors) <= 4) { p->m_vTagEdtColors.push_back(QColor(0xdddddd)); } // COLOR_FILE_TAG_MISSING if (cSize(p->m_vTagEdtColors) <= 5) { p->m_vTagEdtColors.push_back(QColor(0xf0f0ff)); } // COLOR_FILE_NA if (cSize(p->m_vTagEdtColors) <= 6) { p->m_vTagEdtColors.push_back(QColor(0xffffdd)); } // COLOR_FILE_NO_DATA } } // adjusts the global font so it displays legible characters (on Windows it is possible under some unclear circumstances for all characters to be shown as small rectangles) void fixAppFont(QFont& font, string& strNewFont, int& nNewSize) { const char* aszFonts[] = { "Arial", "Helvetica", "Sans", "Courier", 0 }; for (int i = 0; ; ++i) { const int SIZE (50); QImage img1 (SIZE, SIZE, QImage::Format_RGB32); QImage img2 (SIZE, SIZE, QImage::Format_RGB32); { QPainter pntr (&img1); pntr.fillRect(0, 0, SIZE, SIZE, QColor(255, 255, 255)); pntr.drawText(5, SIZE/2 + 10, "ab"); } { QPainter pntr (&img2); pntr.fillRect(0, 0, SIZE, SIZE, QColor(255, 255, 255)); pntr.drawText(5, SIZE/2 + 10, "cd"); //pntr.drawText(5, SIZE/2 + 10, "ab"); } if (img1 != img2) { break; } qDebug("invalid font %s", strNewFont.c_str()); const char* szFont (aszFonts[i]); if (0 == szFont) { exit(1); // don't know what else to do } strNewFont = szFont; if (nNewSize < 5 || nNewSize > 20) { nNewSize = 9; }; font.setFamily(convStr(strNewFont)); font.setPointSize(nNewSize); QApplication::setFont(font); } } static int MIN_FILE_WIDTH; // minimum width of the "file" field void CommonData::setFontInfo(const std::string& strGenName, int nGenSize, int nLabelFontSizeDecr, const std::string& strFixedName, int nFixedSize) { if (nGenSize < 5 || nGenSize > 20) { nGenSize = 9; } if (nFixedSize < 5 || nFixedSize > 20) { nFixedSize = 9; } if (nLabelFontSizeDecr < 0 || nLabelFontSizeDecr > 5) { nLabelFontSizeDecr = 0; } if (m_strGenFontName == strGenName && m_nGenFontSize == nGenSize && m_nLabelFontSizeDecr == nLabelFontSizeDecr && m_strFixedFontName == strFixedName && m_nFixedFontSize == nFixedSize) { return; } // nothing changed bool bFirstTime (m_strGenFontName.empty()); m_strGenFontName = strGenName; m_nGenFontSize = nGenSize; m_nLabelFontSizeDecr = nLabelFontSizeDecr; m_strFixedFontName = strFixedName; m_nFixedFontSize = nFixedSize; if (!bFirstTime) { QMessageBox::warning(m_pFilesG, "Info", "The font changes will only be used after restarting the application."); //ttt2 try to get this work, probably needs to call QHeaderView::resizeSection(), as well as review all setMinimumSectionSize() and setDefaultSectionSize() calls; return; } m_generalFont.setFamily(convStr(strGenName)); m_generalFont.setPointSize(nGenSize); QApplication::setFont(m_generalFont); fixAppFont(m_generalFont, m_strGenFontName, m_nGenFontSize); m_labelFont = m_generalFont; m_labelFont.setPointSize(nGenSize - nLabelFontSizeDecr); m_fixedFont.setFamily(convStr(strFixedName)); //m_fixedFont.setFamily("B&H LucidaTypewriter"); //m_fixedFont.setFamily("B&H LucidaTypewriter12c"); //m_fixedFont.setFixedPitch(true); // !!! needed to select some fixed font in case there's no "B&H LucidaTypewriter" installed m_fixedFont.setFixedPitch(true); m_fixedFont.setStyleHint(QFont::Courier); //f.setPixelSize(12); //ttt2 hard-coded "12"; //ttt2 some back-up font instead of just letting the system decide m_fixedFont.setPointSize(nFixedSize); CELL_HEIGHT = QApplication::fontMetrics().height() + 3; { QPixmap img (100, 100); //ttt2 revisit the size; might need increase in the future QPainter pntr (&img); QFont f (m_labelFont); f.setWeight(QFont::Bold); pntr.setFont(f); int n (0); for (char c1 = 'a'; c1 <= 'z'; ++c1) //ttt3 ASCII-specific { for (char c2 = 'a'; c2 <= 'z'; ++c2) { if (c1 != 'm' && c1 != 'w' && c2 != 'm' && c2 != 'w') { QString s; s += c1; s += c2; QRect r (10, 10, 100, 100); r = pntr.boundingRect(r, Qt::AlignLeft | Qt::AlignTop, s); //CB_ASSERT (10 == r.x()); n = max(n, r.width()); } } //qDebug("%s - %d %d %2d %2d", s.toUtf8().constData(), r.x(), r.y(), r.width(), r.height()); } CELL_WIDTH = n + 4; //ttt2 hard-coded "4"; see how to get the correct value } MIN_FILE_WIDTH = QApplication::fontMetrics().width("ABCDEFGHIJKLMNopqrstuvwxyz12345"); /*m_pFilesG->horizontalHeader()->setMinimumSectionSize(CELL_WIDTH); m_pFilesG->verticalHeader()->setMinimumSectionSize(CELL_HEIGHT); m_pFilesG->verticalHeader()->setDefaultSectionSize(CELL_HEIGHT);*/ } QFont CommonData::getNewGeneralFont() const { QFont f; f.setFamily(convStr(m_strGenFontName)); f.setPointSize(m_nGenFontSize); QFontInfo info (f); return QFont (info.family(), info.pointSize()); } QFont CommonData::getNewFixedFont() const { QFont f; f.setFamily(convStr(m_strFixedFontName)); f.setPointSize(m_nFixedFontSize); f.setStyleHint(QFont::Courier); f.setFixedPitch(true); QFontInfo info (f); return QFont (info.family(), info.pointSize()); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== namespace { CommonData* g_pCommonData (0); } CommonData* getCommonData() // ttt2 get rid of all places passing CommonData* as a param { return g_pCommonData; } CommonData::CommonData( SessionSettings& settings, QTableView* pFilesG, QTableView* pNotesG, QTableView* pStreamsG, QTableView* pUniqueNotesG, QToolButton* pNoteFilterB, QToolButton* pDirFilterB, QToolButton* pModeAllB, QToolButton* pModeAlbumB, QToolButton* pModeSongB, bool bUniqueSession) : m_pFilesModel(0), m_pNotesModel(0), m_pStreamsModel(0), m_pUniqueNotesModel(0), m_pFilesG(pFilesG), m_pNotesG(pNotesG), m_pStreamsG(pStreamsG), m_pUniqueNotesG(pUniqueNotesG), m_bChangeGuard(false), m_pCodec(0), m_bUseAllNotes(false), m_bTraceEnabled(false), m_bAutoSizeIcons(true), m_nMainWndIconSize(40), m_settings(settings), m_bKeepOneValidImg(false), m_bWmpVarArtists(false), m_bItunesVarArtists(false), m_bLogTransf(false), m_bSaveDownloadedData(false), m_vvnCustomTransf(CUSTOM_TRANSF_CNT), //m_bDirty(false), m_nLabelFontSizeDecr(0), m_bUniqueSession(bUniqueSession), m_bFastSave(false), m_eViewMode(ALL), m_pNoteFilterB(pNoteFilterB), m_pDirFilterB(pDirFilterB), m_pModeAllB(pModeAllB), m_pModeAlbumB(pModeAlbumB), m_pModeSongB(pModeSongB) { g_pCommonData = this; m_vpAllTransf.push_back(new SingleBitRepairer()); m_vpAllTransf.push_back(new InnerNonAudioRemover()); m_vpAllTransf.push_back(new UnknownDataStreamRemover()); m_vpAllTransf.push_back(new BrokenDataStreamRemover()); m_vpAllTransf.push_back(new UnsupportedDataStreamRemover()); m_vpAllTransf.push_back(new TruncatedMpegDataStreamRemover()); m_vpAllTransf.push_back(new NullStreamRemover()); m_vpAllTransf.push_back(new BrokenId3V2Remover()); m_vpAllTransf.push_back(new UnsupportedId3V2Remover()); m_vpAllTransf.push_back(new IdentityTransformation()); m_vpAllTransf.push_back(new MultipleId3StreamRemover()); m_vpAllTransf.push_back(new MismatchedXingRemover()); m_vpAllTransf.push_back(new TruncatedAudioPadder()); m_vpAllTransf.push_back(new VbrRepairer()); m_vpAllTransf.push_back(new VbrRebuilder()); m_vpAllTransf.push_back(new Id3V2Cleaner(this)); m_vpAllTransf.push_back(new Id3V2Rescuer(this)); m_vpAllTransf.push_back(new Id3V2UnicodeTransformer(this)); m_vpAllTransf.push_back(new Id3V2CaseTransformer(this)); m_vpAllTransf.push_back(new Id3V2ComposerAdder(this)); m_vpAllTransf.push_back(new Id3V2ComposerRemover(this)); m_vpAllTransf.push_back(new Id3V2ComposerCopier(this)); m_vpAllTransf.push_back(new SmallerImageRemover(this)); m_vpAllTransf.push_back(new Id3V1ToId3V2Copier(this)); m_vpAllTransf.push_back(new Id3V1Remover()); m_vpAllTransf.push_back(new Id3V2Expander(this)); m_vpAllTransf.push_back(new Id3V2Compactor(this)); m_settings.loadDirs(m_vstrIncludeDirs, m_vstrExcludeDirs); try { m_dirTreeEnum.reset(m_vstrIncludeDirs, m_vstrExcludeDirs); } catch (const DirTreeEnumerator::InvalidDirs&) { QMessageBox::critical(m_pFilesG, "Error", "There was an error setting up the directories containing MP3 files. You will have to define them again."); m_vstrIncludeDirs.clear(); m_vstrExcludeDirs.clear(); } connect(&m_filter, SIGNAL(filterChanged()), this, SLOT(onFilterChanged())); } CommonData::~CommonData() { clearPtrContainer(m_vpAllHandlers); clearPtrContainer(m_vpAllTransf); g_pCommonData = 0; } // finds the position of a note in the global vector with notes sorted by severity and description; // the position can then be used to find the corresponding label; // returns -1 if the note is not found; (needed because trace and info notes aren't shown in the grid, so they are not found) int CommonData::findPos(const Note* pNote) const { return m_uniqueNotes.getFltPos(pNote); } // for debugging; prints what's current in m_pFilesG, using several methods void CommonData::printFilesCrt() const { QModelIndex x (m_pFilesG->selectionModel()->currentIndex()); QModelIndex y (m_pFilesG->currentIndex()); printf("SelModel: %dx%d View: %dx%d getFilesGCrtRow(): %d vector.size(): %d\n", x.row(), x.column(), y.row(), y.column(), getFilesGCrtRow(), cSize(m_vpAllHandlers));//*/ } const Mp3Handler* CommonData::getCrtMp3Handler() const // returns 0 if the list is empty { int n (getFilesGCrtRow()); return -1 == n ? 0 : m_vpViewHandlers[n]; } const string& CommonData::getCrtName() const { const Mp3Handler* p (getCrtMp3Handler()); if (0 != p) { return p->getName(); } static string strEmpty; return strEmpty; } const vector<DataStream*>& CommonData::getCrtStreams() const { int n (getFilesGCrtRow()); //static int yy; qDebug("row %d %d", n, yy++); static std::vector<DataStream*> s_vEmpty; if (-1 == n) { return s_vEmpty; } return m_vpViewHandlers.at(n)->getStreams(); } // copies to spUniqueNotes all the unique notes from commonData.m_vpFltHandlers, with comparison done by CmpNotePtrById; // ignored notes (given by m_vnIgnoredNotes) are not included; // not actual pointers from vpHandlers are stored, but the corresponding ones from given by Notes::getMaster(); so they must not be freed; void CommonData::getUniqueNotes(const std::deque<const Mp3Handler*>& vpHandlers, set<const Note*, CmpNotePtrById>& spUniqueNotes) { set<int> snIgnored (m_vnIgnoredNotes.begin(), m_vnIgnoredNotes.end()); for (int i = 0; i < cSize(vpHandlers); ++i) { const Mp3Handler* pHndl (vpHandlers[i]); const vector<Note*>& vpNotes (pHndl->getNotes().getList()); for (int j = 0, n = cSize(vpNotes); j < n; ++j) { const Note* pNote (vpNotes[j]); if (Note::ERR == pNote->getSeverity() || Note::WARNING == pNote->getSeverity() || Note::SUPPORT == pNote->getSeverity()) { if (0 == snIgnored.count(pNote->getNoteId())) { // not an ignored note, so it can be added; spUniqueNotes.insert(Notes::getMaster(pNote)); // most of the time the note already exists in spUniqueNotes, but that's OK: it doesn't take a lot of time and the pointers are not owned; } } } } } // although the current elem can be identified (so it "shouldn't" be passed) and most of the time pMp3Handler will be just that, sometimes it will deliberately be 0, so a param is actually needed; void CommonData::setViewMode(ViewMode eViewMode, const Mp3Handler* pMp3Handler /*= 0*/) { int nRes (setViewModeHlp(eViewMode, pMp3Handler)); m_pFilesModel->selectRow(nRes); switch (eViewMode) { case ALL: m_pModeAllB->setChecked(true); break; case FOLDER: m_pModeAlbumB->setChecked(true); break; case FILE: m_pModeSongB->setChecked(true); break; default: CB_ASSERT (false); } resizeFilesGCols(); } // returns the position of the "current" elem in m_vpViewHandlers (so it can be selected in the grid); if m_vpViewHandlers is empty, it returns -1; if pMp3Handler is 0, it returns 0 (unless m_vpViewHandlers is empty); int CommonData::setViewModeHlp(ViewMode eViewMode, const Mp3Handler* pMp3Handler) { m_eViewMode = eViewMode; if (m_vpFltHandlers.empty()) { m_vpViewHandlers.clear(); return -1; } switch (eViewMode) { case ALL: m_vpViewHandlers = m_vpFltHandlers; return 0 == pMp3Handler ? 0 : getPosInFlt(pMp3Handler); case FILE: { m_vpViewHandlers.clear(); m_vpViewHandlers.push_back(0 == pMp3Handler ? m_vpFltHandlers[0] : pMp3Handler); return 0; } case FOLDER: { m_vpViewHandlers.clear(); if (0 == pMp3Handler) { pMp3Handler = m_vpFltHandlers[0]; } string strDir (pMp3Handler->getDir()); int nRes (-1); for (int i = 0, n = cSize(m_vpFltHandlers); i < n; ++i) { const Mp3Handler* p (m_vpFltHandlers[i]); if (p->getDir() == strDir) { if (p == pMp3Handler) { nRes = cSize(m_vpViewHandlers); } m_vpViewHandlers.push_back(p); } } CB_ASSERT (nRes >= 0); return nRes; } } CB_ASSERT(false); } void CommonData::next() { int k (nextHlp()); m_pFilesModel->selectRow(k); resizeFilesGCols(); } // returns the position of the "current" elem in m_vpViewHandlers (see setViewMode() for details) int CommonData::nextHlp() { if (m_vpViewHandlers.empty()) { return -1; } switch (m_eViewMode) { case ALL: { // move to beginning of next folder int i (getFilesGCrtRow()); int n (cSize(m_vpViewHandlers)); string strDir (m_vpViewHandlers[i]->getDir()); for (; i < n - 1; ++i) { if (m_vpViewHandlers[i]->getDir() != strDir) { return i; } } return n - 1; } //ttt2 the layout doesn't change for ALL, but it does for FILE and FOLDER, so perhaps a means to tell if the layout changed or not is needed case FILE: { // next file CB_ASSERT(1 == cSize(m_vpViewHandlers)); int i (getPosInFlt(getCrtMp3Handler())); int n (cSize(m_vpFltHandlers)); if (n - 1 == i) { return 0; } ++i; m_vpViewHandlers[0] = m_vpFltHandlers[i]; return 0; } case FOLDER: { // next folder int i (getPosInFlt(getCrtMp3Handler())); int n (cSize(m_vpFltHandlers)); if (n - 1 == i) { return cSize(m_vpViewHandlers) - 1; } string strDir (m_vpFltHandlers[i]->getDir()); ++i; for (; i < n; ++i) { if (m_vpFltHandlers[i]->getDir() != strDir) { break; } } if (n == i) { return cSize(m_vpViewHandlers) - 1; } // it was the last dir; don't change m_vpViewHandlers, just move to the end // new folder found m_vpViewHandlers.clear(); strDir = m_vpFltHandlers[i]->getDir(); while (strDir == m_vpFltHandlers[i]->getDir()) { m_vpViewHandlers.push_back(m_vpFltHandlers[i]); ++i; if (i >= n) { break; } } return 0; } } CB_ASSERT(false); } void CommonData::previous() { int k (previousHlp()); m_pFilesModel->selectRow(k); resizeFilesGCols(); } // returns the position of the "current" elem in m_vpViewHandlers (see setViewMode() for details) int CommonData::previousHlp() { if (m_vpViewHandlers.empty()) { return -1; } switch (m_eViewMode) { case ALL: { // move to beginning of previous folder int i (getFilesGCrtRow()); string strDir (m_vpViewHandlers[i]->getDir()); for (; i > 0; --i) { if (m_vpViewHandlers[i]->getDir() != strDir) { return i; } } return 0; } case FILE: { // previous file CB_ASSERT(1 == cSize(m_vpViewHandlers)); int i (getPosInFlt(getCrtMp3Handler())); if (0 == i) { return 0; } --i; m_vpViewHandlers[0] = m_vpFltHandlers[i]; return 0; } case FOLDER: { // previous folder int i (getPosInFlt(getCrtMp3Handler())); if (0 == i) { return 0; } string strDir (m_vpFltHandlers[i]->getDir()); --i; for (; i >= 0; --i) { if (m_vpFltHandlers[i]->getDir() != strDir) { break; } } if (-1 == i) { return 0; } // it was the first dir; don't change m_vpViewHandlers, just move to the beginning // new folder found m_vpViewHandlers.clear(); strDir = m_vpFltHandlers[i]->getDir(); while (strDir == m_vpFltHandlers[i]->getDir()) { m_vpViewHandlers.push_front(m_vpFltHandlers[i]); // push_front() is OK for a deque --i; if (i < 0) { break; } } return 0; } } CB_ASSERT(false); } // finds the position in m_vpFltHandlers; returns -1 if not found; 0 is a valid argument, in which case -1 is returned; needed by next() and previous(), to help with navigation when going into "folder" mode int CommonData::getPosInFlt(const Mp3Handler* pMp3Handler) const { if (0 == pMp3Handler) { return -1; } /*deque<Mp3Handler*>::const_iterator it (find(m_vpFltHandlers.begin(), m_vpFltHandlers.end(), pMp3Handler)); if (m_vpFltHandlers.end() == it) { return -1; }*/ deque<const Mp3Handler*>::const_iterator it (lower_bound(m_vpFltHandlers.begin(), m_vpFltHandlers.end(), pMp3Handler, CmpMp3HandlerPtrByName())); if (m_vpFltHandlers.end() == it || *it != pMp3Handler) { return -1; } int n (it - m_vpFltHandlers.begin()); return n; } void CommonData::onCrtFileChanged() { CursorOverrider crs; updateCurrentNotes(); updateCurrentStreams(); } // updates m_vpCrtNotes, to hold the notes corresponding to the current file and resizes the rows to fit the data void CommonData::updateCurrentNotes() { int nRow (getFilesGCrtRow()); CB_ASSERT (nRow >= -1 && nRow < cSize(getViewHandlers())); m_vpCrtNotes.clear(); if (-1 == nRow) { // an empty file list m_pNotesModel->emitLayoutChanged(); return; } const vector<Note*> vNotes (getViewHandlers()[nRow]->getNotes().getList()); for (int i = 0, n = cSize(vNotes); i < n; ++i) { const Note* pNote (vNotes[i]); if (m_bUseAllNotes || findPos(pNote) >= 0) // findPos(pNote) is -1 for TRACE as well as for ignored notes { m_vpCrtNotes.push_back(pNote); } } std::sort(m_vpCrtNotes.begin(), m_vpCrtNotes.end(), CmpNotePtrByPosAndId()); // the list may come sorted by some other criteria, e.g. severity first, //reset(); //ttt2 see what is the difference between "emit layoutChanged()" and "reset()"; here, they are similar now, but in a prior version calling "reset()" didn't show the selection (this changed after implementing "NotesModel::matchSelToMain()" but as of 2008.06.30 even that seems unncecessary m_pNotesModel->emitLayoutChanged(); //m_pNotesG->resizeColumnsToContents(); //ttt2 see why uncommenting this results in column 0 (and perhaps 2) increasing their size each time NotesModel::updateCurrentNotes() gets called m_pNotesG->resizeRowsToContents(); } void CommonData::updateCurrentStreams() { int nRow (getFilesGCrtRow()); CB_ASSERT (nRow >= -1 && nRow < cSize(getViewHandlers())); m_pStreamsModel->emitLayoutChanged(); m_pStreamsG->resizeRowsToContents(); } int CommonData::getFilesGCrtRow() const // returns -1 if no current element exists (e.g. because the table is empty) { QModelIndex index (m_pFilesG->currentIndex()); // the documentation for QTableView isn't very clear, but in the code it just calls QItemSelectionModel::currentIndex(), for which the documentation says that it returns an ivalid index if there's no current element if (!index.isValid()) { return - 1; } // not sure if this is NECESSARY; for an empty table -1 is returned anyway as index.row(); but it doesn't hurt, anyway return index.row(); } int CommonData::getFilesGCrtCol() const // returns -1 if no current element exists (e.g. because the table is empty) { QModelIndex index (m_pFilesG->currentIndex()); if (!index.isValid()) { return - 1; } // not sure if this is NECESSARY; for an empty table -1 is returned anyway as index.column(); but it doesn't hurt, anyway return index.column(); } #if 0 struct AAA { int a; }; struct Cmp { /*bool operator()(int x1, int x2) const { return x1 < x2; }*/ bool operator()(AAA* a1, int x2) const // ttt2 review if the fact that this code compiles (without requiring any of the other operators) is due to the standard or to GCC's STL; probably it's standard, because we don't need an equality test for lower_bound { //return operator()(a1->a, x2); return true; } /*bool operator()(int x1, AAA* a2) const { return operator()(x1, a2->a); } bool operator()(AAA* a1, AAA* a2) const { return operator()(a1->a, a2->a); }*/ }; void opppo() { vector<AAA*> v; lower_bound(v.begin(), v.end(), 7, Cmp()); } #endif // if bExactMatch is false, it finds the nearest position in m_vpViewHandlers (so even if a file was deleted, it still finds something close); // returns -1 only if not found (either m_vpViewHandlers is empty or bExactMatch is true and the file is missing); int CommonData::getPosInView(const std::string& strName/*, bool bUsePrevIfNotFound = true*/, bool bExactMatch /*= false*/) const { /* if (strName.empty()) { return -1; } deque<Mp3Handler*>::const_iterator it (lower_bound(m_vpViewHandlers.begin(), m_vpViewHandlers.end(), strName, CmpMp3HandlerPtrByName())); if (m_vpViewHandlers.end() == it) { if (m_vpViewHandlers.empty()) { return -1; } --it; } else if (bUsePrevIfNotFound && m_vpViewHandlers.begin() != it && (*it)->getName() != strName) // position on previous elem if exact match wasn't found { --it; } int n (it - m_vpViewHandlers.begin()); return n;*/ deque<const Mp3Handler*>::const_iterator it (lower_bound(m_vpViewHandlers.begin(), m_vpViewHandlers.end(), strName, CmpMp3HandlerPtrByName())); if ((m_vpViewHandlers.end() == it || (*it)->getName() != strName) && (bExactMatch || m_vpViewHandlers.empty())) { return -1; } if (m_vpViewHandlers.end() == it) { --it; } int n (it - m_vpViewHandlers.begin()); return n; } void CommonData::updateSelList() { QModelIndexList lSelFiles (m_pFilesG->selectionModel()->selection().indexes()); set<int> sSel; for (QModelIndexList::iterator it = lSelFiles.begin(), end = lSelFiles.end(); it != end; ++it) { sSel.insert(it->row()); } m_vpSelHandlers.clear(); for (set<int>::iterator it = sSel.begin(), end = sSel.end(); it != end; ++it) { m_vpSelHandlers.push_back(m_vpViewHandlers[*it]); } sort(m_vpSelHandlers.begin(), m_vpSelHandlers.end(), CmpMp3HandlerPtrByName()); } vector<string> CommonData::getSelNames() // calls updateSelList() and returns the names ot the selected files; { updateSelList(); vector<string> v; for (int i = 0, n = cSize(m_vpSelHandlers); i < n; ++i) { v.push_back(m_vpSelHandlers[i]->getName()); } return v; } const deque<const Mp3Handler*>& CommonData::getSelHandlers() { updateSelList(); return m_vpSelHandlers; } // the index in m_vpAllTransf for a transformation with a given name; throws if the name doesn't exist; int CommonData::getTransfPos(const char* szTransfName) const { for (int i = 0, n = cSize(m_vpAllTransf); i < n; ++i) { //if (m_vpAllTransf[i]->getName() == szTransfName) // this works as of 2008.11.07, but it doesn't provide any performance advantage, so better without it if (0 == strcmp(m_vpAllTransf[i]->getActionName(), szTransfName)) { return i; } } CB_ASSERT (false); } set<string> CommonData::getAllDirs() const { set<string> sDirs; for (int i = 0, n = cSize(m_vpAllHandlers); i < n; ++i) { const Mp3Handler* p (m_vpAllHandlers[i]); const string& s (p->getName()); string::size_type k (s.rfind(getPathSep())); CB_ASSERT(string::npos != k); string strDir (s.substr(0, k)); sDirs.insert(strDir); } return sDirs; } // keeps existing handlers as long as they are still "included" void CommonData::setDirectories(const std::vector<std::string>& vstrIncludeDirs, const std::vector<std::string>& vstrExcludeDirs) { //const vector<string>& vstrSel (getSelNames()); //string strCrtName (getCrtName()); m_vstrIncludeDirs = vstrIncludeDirs; m_vstrExcludeDirs = vstrExcludeDirs; m_dirTreeEnum.reset(vstrIncludeDirs, vstrExcludeDirs); m_settings.saveDirs(vstrIncludeDirs, vstrExcludeDirs); vector<const Mp3Handler*> vpDel; for (int i = 0, n = cSize(m_vpAllHandlers); i < n; ++i) { const Mp3Handler* p (m_vpAllHandlers[i]); if (!m_dirTreeEnum.isIncluded(p->getName())) { vpDel.push_back(p); } } deque<const Mp3Handler*> vpAll, vpFlt, vpView; set_difference(m_vpAllHandlers.begin(), m_vpAllHandlers.end(), vpDel.begin(), vpDel.end(), back_inserter(vpAll), CmpMp3HandlerPtrByName()); set_difference(m_vpFltHandlers.begin(), m_vpFltHandlers.end(), vpDel.begin(), vpDel.end(), back_inserter(vpFlt), CmpMp3HandlerPtrByName()); set_difference(m_vpViewHandlers.begin(), m_vpViewHandlers.end(), vpDel.begin(), vpDel.end(), back_inserter(vpView), CmpMp3HandlerPtrByName()); vpAll.swap(m_vpAllHandlers); vpFlt.swap(m_vpFltHandlers); vpView.swap(m_vpViewHandlers); //updateWidgets(strCrtName, vstrSel); // !!! no point in keeping crt/sel; this is only called by scan(), and after that the first file gets selected anyway updateWidgets(); } /*QString CommonData::getNoteLabel(int nPosInFlt) // gets the label of a note based on its position in m_uniqueNotes.m_vpFlt { return ::getNoteLabel(m_uniqueNotes.getFltVec()[nPosInFlt]); }*/ //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== // For the vertical header of a QTableView whose labels are the current row number, it determines the width necessary to accomodate any of those labels. // Currently it uses a hard-coded value to add to the width. //ttt2 fix // It makes 2 assumptions: // - the TableView uses the same FontMetrics as the ones returned by QApplication::fontMetrics() (this is intended to be called from a TableModel's headerData(), for which finding the table is not easy; and anyway, a model can be connected to several tables) // - digits in the font have the same size, or at least there is no digit with a size larger than that of '9'; (in many fonts all the digits do have the same size, so it should be OK most of the time) // Only the width is calculated; the height is returned as "1". This allows the content of a cell to determine the width of a row. Returning the height actually needed to draw the label would cause the rows to be to large, because significant spacing is added to the result. This is the opposite of what happens to the width, where a big number of pixels must be added by getNumVertHdrSize() just to have everything displayed. // ttt3 is this a Qt bug? (adds spacing where it's not needed and doesn't add it where it should) // // If nRowCount<=0 it behaves as if nRowCount==1 // // Returns QVariant() for horizontal headers. // // The real reason this is needed: Qt can easily resize the header to accomodate all the header labels, and that's enough for fixed-height rows, whose height is set with verticalHeader()->setDefaultSectionSize(). However, if resizeRowsToContents() gets called (and it seems that it must be called to get variable-height working, and some flag to enable this doesn't seem to exist) the height of each row's header becomes too big. Using getNumVertHdrSize() we force the height to be 1, thus allowing the data cells to tell the height (the final height is the maximum between data cells and the header cell for each row). //ttt2 At some point it seemed that rows would get larger even without calling getNumVertHdrSize(). This should be looked at again. QVariant getNumVertHdrSize(int nRowCount, Qt::Orientation eOrientation) // ttt2 add optional param QTableView to take the metrics from { if (eOrientation == Qt::Vertical) { QFontMetrics fm (QApplication::fontMetrics()); if (nRowCount <= 0) { nRowCount = 1; } double d (1.01 + log10(double(nRowCount))); QString s (int(d), QChar('9')); int nWidth (fm.width(s)); return QSize(nWidth + 10, 1); //ttt2 hard-coded "10" } return QVariant(); } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== #if 0 static QString getNoteLabel(int nPos) { if (-1 == nPos) { return ""; } //ttt2 perhaps have a vector where each string is added manually; then it's possible to skip "trouble" letters, like 'l' and 'I' (look the same in many fonts) or 'm' (too wide) //ttt2 perhaps use underline, strikeout, ... to have more single-letter labels QString s; { // currently accepts codes from 0 to 103 #if 1 if (nPos >= 52) { s = "'"; nPos -= 52; } if (nPos < 26) { //nPos = 0x03B1 + nPos; // greek alpha nPos += 'a'; } else if (nPos < 52) { nPos = 'A' + nPos - 26; } else { CB_ASSERT (false); } //ttt2 add more when needed #else if (nPos < 26) { //nPos = 0x03B1 + nPos; // greek alpha nPos += 'a'; } else if (nPos < 52) { nPos = 'A' + nPos - 26; } else if (nPos < 77) { nPos = 0x03B1 + nPos - 52; // greek alpha } //ttt2 add more when needed else { CB_ASSERT (false); } //return QString::number(nPos); #endif /*int n1 (nPos % 52); int n2 (nPos / 52); return getNoteLabel(n2) + getNoteLabel(n1);*/ } nPos %= 26; { //nPos = 0x03B1 + nPos; // greek alpha nPos += 'a'; } if ('m' == nPos || 'w' == nPos) { nPos = 'i'; } QChar c (nPos); s = c + s; //s += "\n"; s = c + s; return s; } #endif static QString getNoteLabel(int nCateg, int nPos) { if (nCateg < 0 || nCateg >= Note::CUSTOM || nPos < 0 || nPos > 'z' - 'a' - 2) { return ""; } if (nPos >= 'm' - 'a') { ++nPos; } if (nPos >= 'w' - 'a') { ++nPos; } if (nCateg >= 'm' - 'a') { ++nCateg; } if (nCateg >= 'w' - 'a') { ++nCateg; } char cp ('a' + nPos); char cc ('a' + nCateg); QString s; s += cc; s += cp; return s; } // returns a label for a note in a given position; first 26 notes get labels "a" .. " z", next 26 get "A" .. "Z", then "aa" .. "az", "aA" .. "aZ", "ba", ... QString getNoteLabel(const Note* pNote) { /*if (0 == nPos) return "l"; if (1 == nPos) return "m"; if (2 == nPos) return "wwwwww";//*/ //CB_ASSERT (nPos >= 0); return getNoteLabel(pNote->getCategory(), pNote->getLabelIndex()); } #if 0 struct TestLabel { TestLabel() { for (int i = 0; i < 104; ++i) { qDebug("%d %s", i, getNoteLabel(i).toUtf8().constData()); } } }; static TestLabel ppppppppp; #endif //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== const QColor& ERROR_PEN_COLOR() { static QColor col (112, 48, 0); return col; } const QColor& SUPPORT_PEN_COLOR() { static QColor col (24, 64, 190); return col; } //ttt2 inconsistency: note is ref while vpNoteSet has vectors; OTOH comparison is not done by address; perhaps just document this; // color is normally the category color, but for support notes it's a "support" color; if the note isn't found in vpNoteSet, dGradStart and dGradEnd are set to -1, but normally they get a segment obtained by dividing [0, 1] in equal parts; void CommonData::getNoteColor(const Note& note, const vector<const Note*>& vpNoteSet, QColor& color, double& dGradStart, double& dGradEnd) const { LAST_STEP("CommonData::getNoteColor()"); dGradStart = -1; dGradEnd = -1; if (Note::TRACE == note.getSeverity()) { color = QColor(255, 255, 255); return; } //ttt2 use a system color /*if (Note::SUPPORT == note.getSeverity()) { color = QColor(235, 235, 255); } else*/ { color = m_vNoteCategColors[note.getCategory()]; } vector<const Note*>::const_iterator it (lower_bound(vpNoteSet.begin(), vpNoteSet.end(), ¬e, CmpNotePtrById())); if (vpNoteSet.end() == it) { CB_ASSERT (vpNoteSet.empty()); return; } int nPos (it - vpNoteSet.begin()); int nFirstInGroup (nPos), nLastInGroup (nPos); for (; nFirstInGroup > 0 && vpNoteSet[nFirstInGroup - 1]->getCategory() == note.getCategory(); --nFirstInGroup) {} for (; nLastInGroup < cSize(vpNoteSet) - 1 && vpNoteSet[nLastInGroup + 1]->getCategory() == note.getCategory(); ++nLastInGroup) {} nLastInGroup -= nFirstInGroup; nPos -= nFirstInGroup; //nFirstInGroup = 0; dGradStart = double(nPos)/(nLastInGroup + 1); dGradEnd = double(nPos + 1)/(nLastInGroup + 1); } QColor getDefaultBkgCol() { QColor c (QPalette().color(QPalette::Active, QPalette::Light)); if (isWhite(c)) { c = QPalette().color(QPalette::Active, QPalette::Window).lighter(110); } if (isWhite(c)) { c = QPalette().color(QPalette::Active, QPalette::Window).lighter(103); } if (isWhite(c)) { c = QPalette().color(QPalette::Active, QPalette::Window); } if (isWhite(c)) { c = QColor(253, 250, 240); } return c; } //===================================================================================================================== //===================================================================================================================== //===================================================================================================================== /*void printFontInfo(const char* szLabel, const QFont& font) { QFontInfo info (font); cout << szLabel << ": " << info.family().toStdString() << ", exactMatch:" << info.exactMatch() << ", fixedPitch:" << info.fixedPitch() << ", italic:" << info.italic() << ", pixelSize:" << info.pixelSize() << ", pointSize:" << info.pointSize() << ", real pointSize on 100dpi screen:" << info.pixelSize()*72.0/100 << endl; } */ #if 0 const QFont& getFixedFont() { static QFont s_font; // ttt3 not multithreaded, but doesn't matter static bool s_bInit (false); if (!s_bInit) { s_bInit = true; //myOption.font = QFont("Courier", myOption.font.pointSize()); //myOption.font = QFont("B&H LucidaTypewritter", myOption.font.pointSize()); //myOption.font = QFont("LucidaTypewritter", myOption.font.pointSize()); //myOption.font = QFont("B&H LucidaTypewritter", 9); //myOption.font = QFont("Lucidatypewriter"); //myOption.font = QFont("LucidaTypewriter"); //myOption.font = QFont(); //myOption.font.setPixelSize(12); //myOption.font.setRawName("B&H LucidaTypewritter"); //myOption.font.setRawName("LucidaTypewritter"); //myOption.font.setRawName("Typewritter"); //myOption.font.setRawName("-b&h-lucidatypewritter-*-*-*-*-*-*-*-*-*-*-*-*"); //myOption.font.setRawName("-b&h-lucidatypewriter-medium-r-normal-sans-26-190-100-100-m-159-iso8859-1"); //myOption.font.setRawName("-b&h-lucidatypewriter-medium-r-normal-sans-12-120-75-75-m-70-iso8859-1"); //myOption.font.setStyleHint(QFont::TypeWriter); //myOption.font.fromString("B&H LucidaTypewriter,11,-1,5,50,0,0,0,0,0"); // myOption.font.setSize... // myOption.font.setFixedPitch(true); // ttt2 is there a difference between setFixedPitch(true) and setStyleHint(QFont::TypeWriter) ? /*myOption.font.setFamily("B&H LucidaTypewriter"); myOption.font.setPixelSize(12);*/ //printFontInfo("orig font: ", s_font); //s_font = QFont("B&H LucidaTypewriter"); s_font.setFamily("B&H LucidaTypewriter"); //s_font.setFamily("B&H LucidaTypewriter12c"); s_font.setFixedPitch(true); // !!! needed to select some fixed font in case there's no "B&H LucidaTypewriter" installed s_font.setPixelSize(12); //ttt2 hard-coded "12"; //s_font.setPointSize(9); //ttt2 hard-coded "9"; //QFont f; qDebug("default font: pix %d, point: %d, fam: %s", f.pixelSize(), f.pointSize(), f.family().toLatin1().constData()); //myOption.font.setPointSize(12); // printFontInfo("new font: ", s_font); //font: B&H LucidaTypewriter,11,-1,5,50,0,0,0,0,0 //print map // xfontsel // "mmmiiiWWWlll"; } return s_font; } #endif #ifdef OKPOJOIJWOUIh void tstFont() { /* bool b; QFont f (QFontDialog::getFont(&b, this)); //cout << "font: " << QFontInfo(myOption.font).family().toStdString() << endl; //cout << "font from dlg: " << f.toString().toStdString() << endl; printFontInfo("font from dlg", f); */ for (int i = 6; i < 18; ++i) { QFont f ("B&H LucidaTypewriter", i); char a [20]; sprintf(a, "point size %d", i); printFontInfo(a, f); } cout << endl; for (int i = 6; i < 18; ++i) { QFont f ("B&H LucidaTypewriter"); f.setPixelSize(i); char a [20]; sprintf(a, "pixel size %d", i); printFontInfo(a, f); } cout << endl; { bool b; QFont f (QFontDialog::getFont(&b)); printFontInfo("font from QFontDialog" , f); /* QFont f; if (QDialog::Accepted == KFontDialog::getFont(f, true)) { printFontInfo("font from QFontDialog" , f); }*/ } cout << endl; for (int i = 6; i < 18; ++i) { QFont f ("B&H LucidaTypewriter12c", i); char a [50]; sprintf(a, "B&H LucidaTypewriter12c point size %d", i); printFontInfo(a, f); } } #endif /*extern*/ const int CUSTOM_TRANSF_CNT (4); void Filter::setNotes(const std::vector<const Note*>& v) { m_vpNotes.clear(); for (int i = 0; i < cSize(v); ++i) { const Note* p (Notes::getMaster(v[i])); // 2009.03.23 currently v comes with pointers from Notes, so this is pointless; CB_ASSERT (0 != p); m_vpNotes.push_back(p); } //qDebug("set v sz %d", cSize(m_vpNotes)); m_bNoteFilter = !m_vpNotes.empty(); emit filterChanged(); } void Filter::setDirs(const std::vector<string>& v) { //if (v == m_vstrDirs) { return; } m_vstrDirs = v; m_bDirFilter = !m_vstrDirs.empty(); emit filterChanged(); } // !!! needed because we need m_vstrDirs next time we press the filter button, so we don't want to delete it with a "setDirs(vector<string>())", but just ignore it void Filter::disableDir() { if (!m_bDirFilter) { return; } m_bDirFilter = false; emit filterChanged(); } void Filter::disableNote() { if (!m_bNoteFilter) { return; } m_bNoteFilter = false; emit filterChanged(); } void Filter::disableAll() // saves m_bNoteFilter to m_bSavedNoteFilter and m_bDirFilter to m_bSavedDirFilter, then disables the filters { m_bSavedNoteFilter = m_bNoteFilter; m_bSavedDirFilter = m_bDirFilter; if (m_bNoteFilter || m_bDirFilter) { m_bNoteFilter = m_bDirFilter = false; emit filterChanged(); } } void Filter::restoreAll() // loads m_bNoteFilter from m_bSavedNoteFilter and m_bDirFilter from m_bSavedDirFilter, then enables the filters, if they are true { if (m_bNoteFilter != m_bSavedNoteFilter || m_bDirFilter != m_bSavedDirFilter) { m_bNoteFilter = m_bSavedNoteFilter; m_bDirFilter = m_bSavedDirFilter; emit filterChanged(); } } //======================================================================================================================== //======================================================================================================================== //======================================================================================================================== // called after config change or filter change or mergeHandlerChanges(), mainly to update unique notes (which is reflected in columns in the file grid and in lines in the unique notes list); also makes sure that something is displayed if there are any files in m_vpFltHandlers (e.g. if a transform was applied that removed all the files in an album, the next album gets loaded); // this is needed after transforms/normalization/tag editing, but there's no need for an explicit call, because all these call mergeHandlerChanges() (directly or through MainFormDlgImpl::scan()) void CommonData::updateWidgets(const std::string& strCrtName /*= ""*/, const std::vector<std::string>& vstrSel /*= std::vector<std::string>()*/) { CursorOverrider crs; //if (m_vpViewHandlers.empty() && !m_vpFltHandlers.empty()) // 2009.09.25 - not sure why the test was here, but its presence prevented the right song to be selected when returning from tag editing, if in album mode; see if this takes a long time; if so, perhaps the idea was to run this only if needed, but the test was too restrictive { CommonData::ViewMode eViewMode (getViewMode()); setViewMode(CommonData::ALL); int nPos (getPosInView(strCrtName)); // doesn't matter if it's empty const Mp3Handler* pMp3Handler (nPos >= 0 ? m_vpViewHandlers.at(nPos) : 0); setViewMode(eViewMode, pMp3Handler); } int nRow (-1); if (!strCrtName.empty()) { nRow = getPosInView(strCrtName); } if (-1 == nRow) { nRow = 0; } vector<int> v; for (int i = 0, n = cSize(vstrSel); i < n; ++i) { int k (getPosInView(vstrSel[i], EXACT_MATCH)); if (-1 != k) { v.push_back(k); } } updateUniqueNotes(); m_pFilesModel->selectRow(nRow, v); m_pUniqueNotesModel->selectTopLeft(); resizeFilesGCols(); m_pFilesG->setFocus(); } // updates m_uniqueNotes to reflect the current m_vpAllHandlers and m_vpFltHandlers; void CommonData::updateUniqueNotes() { set<const Note*, CmpNotePtrById> spAllNotes; getUniqueNotes(m_vpAllHandlers, spAllNotes); set<const Note*, CmpNotePtrById> spFltNotes; getUniqueNotes(m_vpFltHandlers, spFltNotes); // ttt2 not sure if it makes more sense for m_uniqueNotes to show notes for what is filtered or for what is "current"; it feels like the list would change too often if it is going to reflect "current"; anyway, if the change is made, the code must be moved; m_uniqueNotes.clear(); // if there's no filtering (and sometimes even if there is a filter applied), spAllNotes and spFltNotes have the same elements; it's probably not worth the trouble to try and figure out if they should be equal or not m_uniqueNotes.addColl(spAllNotes); m_uniqueNotes.setFlt(spFltNotes); } // updates m_vpFltHandlers and m_vpViewHandlers; also updates the state of the filter buttons (deselecting them if the user chose empty filters) void CommonData::onFilterChanged() { const vector<string>& vstrSel (getSelNames()); string strCrtName (getCrtName()); m_vpFltHandlers.clear(); const vector<string>& vSelDirs (m_filter.getDirs()); const vector<const Note*>& vpSelNotes (m_filter.getNotes()); int nSelNotesSize (cSize(vpSelNotes)); CmpNotePtrById cmp; // !!! same comparator used by NoteColl::sort() bool bDirFilter (m_filter.isDirEnabled()); bool bNoteFilter (m_filter.isNoteEnabled()); for (int i = 0, n = cSize(m_vpAllHandlers); i < n; ++i) { const Mp3Handler* pHandler (m_vpAllHandlers[i]); if (bDirFilter) { vector<string>::const_iterator it (lower_bound(vSelDirs.begin(), vSelDirs.end(), pHandler->getName())); if (vSelDirs.begin() == it) { goto e1; } --it; //cout << *it << " " << pHandler->getName() << endl; if (!isInsideDir(pHandler->getName(), *it)) { goto e1; } } if (bNoteFilter) { const NoteColl& coll (pHandler->getNotes()); const vector<Note*>& vpCrtNotes (coll.getList()); int i (0); int j (0); int nCrtNotesSize (cSize(vpCrtNotes)); for (;;) { for (; i < nSelNotesSize && j < nCrtNotesSize && cmp(vpSelNotes[i], vpCrtNotes[j]); ++i) {} for (; i < nSelNotesSize && j < nCrtNotesSize && cmp(vpCrtNotes[j], vpSelNotes[i]); ++j) {} if (i >= nSelNotesSize || j >= nCrtNotesSize) { goto e1; } if (CmpNotePtrById::equals(vpSelNotes[i], vpCrtNotes[j])) { break; } } } m_vpFltHandlers.push_back(pHandler); e1:; } m_pNoteFilterB->setChecked(bNoteFilter); // !!! no guard needed, because the event that calls the filter is "clicked", not "checked" m_pDirFilterB->setChecked(bDirFilter); m_vpViewHandlers.clear(); updateWidgets(strCrtName, vstrSel); if (m_vpViewHandlers.empty() && (bNoteFilter || bDirFilter)) { m_filter.disableAll(); // it makse some sense to not disable the filter, e.g. after reload } } void CommonData::setCustomTransf(const std::vector<std::vector<int> >& vv) { CB_ASSERT (cSize(vv) == CUSTOM_TRANSF_CNT); //ttt2 assert elements are withing range m_vvnCustomTransf = vv; } void CommonData::setCustomTransf(int nTransf, const std::vector<int>& v) { CB_ASSERT (nTransf >= 0 && nTransf < CUSTOM_TRANSF_CNT); //ttt2 assert elements are withing range m_vvnCustomTransf[nTransf] = v; } void CommonData::setVisibleTransf(const std::vector<int>& v) { //ttt2 assert elements are withing range m_vnVisibleTransf = v; } void CommonData::setIgnoredNotes(const std::vector<int>& v) { const int NOTE_CNT (cSize(Notes::getAllNotes())); for (int i = 0, n = cSize(v); i < n; ++i) { CB_ASSERT (v[i] >= 0 && v[i] < NOTE_CNT); } set<int> s (v.begin(), v.end()); CB_ASSERT (cSize(s) == cSize(v)); m_vnIgnoredNotes.clear(); m_vnIgnoredNotes.insert(m_vnIgnoredNotes.end(), s.begin(), s.end()); } void CommonData::setQualThresholds(const QualThresholds& q) { // ttt2 some checks m_qualThresholds = q; } // looks in m_vpAllHandlers; returns 0 if there's no such handler const Mp3Handler* CommonData::getHandler(const std::string& strName) const { deque<const Mp3Handler*>::const_iterator it (lower_bound(m_vpViewHandlers.begin(), m_vpViewHandlers.end(), strName, CmpMp3HandlerPtrByName())); if (m_vpViewHandlers.end() == it || (*it)->getName() != strName) { return 0; } return *it; } // elements from vpAdd that are not "included" are discarded; when a new version of a handler is in vpAdd, the old version may be in vpDel, but this is optional; takes ownership of elements from vpAdd; deletes the pointers from vpDel; void CommonData::mergeHandlerChanges(const vector<const Mp3Handler*>& vpAdd1, const vector<const Mp3Handler*>& vpDel1, int nKeepWhenUpdate) { //m_bDirty = m_bDirty || !vpAdd1.empty() || !vpDel1.empty(); string strSongInCrtAlbum (m_nSongInCrtAlbum >= 0 && m_nSongInCrtAlbum < cSize(m_vpAllHandlers) ? m_vpAllHandlers[m_nSongInCrtAlbum]->getName() : ""); const string& strCrtName (nKeepWhenUpdate & CURRENT ? getCrtName() : ""); const vector<string>& vstrSel (nKeepWhenUpdate & SEL ? getSelNames() : vector<string>()); vector<const Mp3Handler*> vpAdd; for (int i = 0, n = cSize(vpAdd1); i < n; ++i) { if (m_dirTreeEnum.isIncluded(vpAdd1[i]->getName())) { vpAdd.push_back(vpAdd1[i]); } else { delete vpAdd1[i]; } } sort(vpAdd.begin(), vpAdd.end(), CmpMp3HandlerPtrByName()); // !!! the vector is probably sorted, but file renaming might have an impact on the order (and if it doesn't have now, it might in the future) vector<const Mp3Handler*> vpDel; { // we want in vpDel elements from vpDel1, as well as elements from m_vpAllHandlers for which there is a newer version in vpAdd vector<const Mp3Handler*> vpDel2 (vpDel1); sort(vpDel2.begin(), vpDel2.end(), CmpMp3HandlerPtrByName()); vector<const Mp3Handler*> vpNewVer; // existing handlers for which there is a new version set_intersection(m_vpAllHandlers.begin(), m_vpAllHandlers.end(), vpAdd.begin(), vpAdd.end(), back_inserter(vpNewVer), CmpMp3HandlerPtrByName()); // !!! according to the standard (25.3.5.3) copying is made from the first range (i.e. from m_vpAllHandlers) set_union(vpNewVer.begin(), vpNewVer.end(), vpDel2.begin(), vpDel2.end(), back_inserter(vpDel), CmpMp3HandlerPtrByName()); } deque<const Mp3Handler*> vpAll, vpFlt, vpView; /*qDebug("1a %d %d %d", cSize(m_vpAllHandlers), cSize(m_vpFltHandlers), cSize(m_vpViewHandlers)); qDebug("1b %d %d", cSize(vpDel), cSize(vpAdd)); qDebug("1c %d %d %d", cSize(vpAll), cSize(vpFlt), cSize(vpView));*/ set_difference(m_vpAllHandlers.begin(), m_vpAllHandlers.end(), vpDel.begin(), vpDel.end(), back_inserter(vpAll), CmpMp3HandlerPtrByName()); set_difference(m_vpFltHandlers.begin(), m_vpFltHandlers.end(), vpDel.begin(), vpDel.end(), back_inserter(vpFlt), CmpMp3HandlerPtrByName()); set_difference(m_vpViewHandlers.begin(), m_vpViewHandlers.end(), vpDel.begin(), vpDel.end(), back_inserter(vpView), CmpMp3HandlerPtrByName()); //qDebug("m_vpAllHandlers.z()=%d, m_vpFltHandlers.size()=%d, m_nSongInCrtAlbum=%d, vpDel.sz=%d, vpDel1.sz=%d, vpAdd1.sz=%d", cSize(m_vpAllHandlers), cSize(m_vpFltHandlers), m_nSongInCrtAlbum, cSize(vpDel), cSize(vpDel1), cSize(vpAdd1)); clearPtrContainer(vpDel); m_vpAllHandlers.clear(); m_vpFltHandlers.clear(); m_vpViewHandlers.clear(); set_union(vpAll.begin(), vpAll.end(), vpAdd.begin(), vpAdd.end(), back_inserter(m_vpAllHandlers), CmpMp3HandlerPtrByName()); set_union(vpFlt.begin(), vpFlt.end(), vpAdd.begin(), vpAdd.end(), back_inserter(m_vpFltHandlers), CmpMp3HandlerPtrByName()); // !!! perhaps for view and flt we should check the directory/filter, but it seems more important that the new handlers are seen, so they can be compared to the old ones //ttt2 review set_union(vpView.begin(), vpView.end(), vpAdd.begin(), vpAdd.end(), back_inserter(m_vpViewHandlers), CmpMp3HandlerPtrByName()); updateWidgets(strCrtName, vstrSel); if (!strSongInCrtAlbum.empty() && !m_vpFltHandlers.empty()) { deque<const Mp3Handler*>::const_iterator it (lower_bound(m_vpFltHandlers.begin(), m_vpFltHandlers.end(), strSongInCrtAlbum, CmpMp3HandlerPtrByName())); if (m_vpFltHandlers.end() == it) { --it; } it = lower_bound(m_vpAllHandlers.begin(), m_vpAllHandlers.end(), *it, CmpMp3HandlerPtrByName()); m_nSongInCrtAlbum = it - m_vpAllHandlers.begin(); } } void CommonData::setSongInCrtAlbum() { m_nSongInCrtAlbum = 0; if (m_vpAllHandlers.empty()) { return; } const Mp3Handler* p (getCrtMp3Handler()); CB_ASSERT (0 != p); deque<const Mp3Handler*>::iterator it (lower_bound(m_vpAllHandlers.begin(), m_vpAllHandlers.end(), p, CmpMp3HandlerPtrByName())); CB_ASSERT (m_vpAllHandlers.end() != it && (*it) == p); m_nSongInCrtAlbum = it - m_vpAllHandlers.begin(); } deque<const Mp3Handler*> CommonData::getCrtAlbum() const //ttt2 perhaps sort by track, if there's an ID3V2; anyway, this is only used by TagWriter and FileRenamer, and TagWriter does its own sorting (there might be an issue if calling getCrtAlbum() multiple times for the same album returns songs in different order because tracks changed between the calls) { deque<const Mp3Handler*> v; if (m_vpFltHandlers.empty()) { return v; } //CB_ASSERT (m_nSongInCrtAlbum >= 0 && m_nSongInCrtAlbum < cSize(m_vpAllHandlers)); // !!! incorrect assert; files migth have been deleted without updating m_nSongInCrtAlbum (well, one of the purposes of this function is to update m_nSongInCrtAlbum) CB_ASSERT (m_nSongInCrtAlbum >= 0); m_nSongInCrtAlbum = min(m_nSongInCrtAlbum, cSize(m_vpAllHandlers) - 1); string s (m_vpAllHandlers[m_nSongInCrtAlbum]->getDir()); int nFirst (m_nSongInCrtAlbum), nLast (m_nSongInCrtAlbum); for (; nFirst >= 0 && m_vpAllHandlers[nFirst]->getDir() == s; --nFirst) {} ++nFirst; for (int n = cSize(m_vpAllHandlers); nLast < n && m_vpAllHandlers[nLast]->getDir() == s; ++nLast) {} --nLast; m_nSongInCrtAlbum = nFirst; v.insert(v.end(), m_vpAllHandlers.begin() + nFirst, m_vpAllHandlers.begin() + nLast + 1); return v; } // used for album navigation in tag editor and file renamer bool CommonData::nextAlbum() const { if (m_vpFltHandlers.empty()) { return false; } CB_ASSERT (m_nSongInCrtAlbum >= 0 && m_nSongInCrtAlbum < cSize(m_vpAllHandlers)); string s (m_vpAllHandlers[m_nSongInCrtAlbum]->getDir()); //qDebug("m_vpAllHandlers.z()=%d, m_vpFltHandlers.size()=%d, m_nSongInCrtAlbum=%d", cSize(m_vpAllHandlers), cSize(m_vpFltHandlers), m_nSongInCrtAlbum); deque<const Mp3Handler*>::const_iterator it (lower_bound(m_vpFltHandlers.begin(), m_vpFltHandlers.end(), m_vpAllHandlers[m_nSongInCrtAlbum], CmpMp3HandlerPtrByName())); //CB_ASSERT (m_vpAllHandlers[m_nSongInCrtAlbum] == *it); // !!! wrong - getCrtAlbum() moves m_nSongInCrtAlbum to the first song in album regardless of filter CB_ASSERT (m_vpFltHandlers.end() != it); int n (cSize(m_vpFltHandlers)); int nFltPos (it - m_vpFltHandlers.begin()); for (; nFltPos < n && m_vpFltHandlers[nFltPos]->getDir() == s; ++nFltPos) {} if (n == nFltPos) { return false; } it = lower_bound(m_vpAllHandlers.begin(), m_vpAllHandlers.end(), m_vpFltHandlers[nFltPos], CmpMp3HandlerPtrByName()); CB_ASSERT (m_vpFltHandlers[nFltPos] == *it); m_nSongInCrtAlbum = it - m_vpAllHandlers.begin(); return true; } bool CommonData::prevAlbum() const { if (m_vpFltHandlers.empty()) { return false; } CB_ASSERT (m_nSongInCrtAlbum >= 0 && m_nSongInCrtAlbum < cSize(m_vpAllHandlers)); string s (m_vpAllHandlers[m_nSongInCrtAlbum]->getDir()); deque<const Mp3Handler*>::const_iterator it (lower_bound(m_vpFltHandlers.begin(), m_vpFltHandlers.end(), m_vpAllHandlers[m_nSongInCrtAlbum], CmpMp3HandlerPtrByName())); //CB_ASSERT (m_vpAllHandlers[m_nSongInCrtAlbum] == *it); // !!! wrong - getCrtAlbum() moves m_nSongInCrtAlbum to the first song in album regardless of filter CB_ASSERT (m_vpFltHandlers.end() != it); int nFltPos (it - m_vpFltHandlers.begin()); for (; nFltPos >= 0 && m_vpFltHandlers[nFltPos]->getDir() == s; --nFltPos) {} if (nFltPos < 0) { return false; } it = lower_bound(m_vpAllHandlers.begin(), m_vpAllHandlers.end(), m_vpFltHandlers[nFltPos], CmpMp3HandlerPtrByName()); CB_ASSERT (m_vpFltHandlers[nFltPos] == *it); m_nSongInCrtAlbum = it - m_vpAllHandlers.begin(); return true; } // resizes the first column to use all the available space; doesn't shrink it to less than 400px, though void CommonData::resizeFilesGCols() { QHeaderView* p (m_pFilesG->horizontalHeader()); p->setResizeMode(0, QHeaderView::Stretch); int n (p->sectionSize(0)); if (n < MIN_FILE_WIDTH) { //n = 600; n = MIN_FILE_WIDTH; //n = m_pFilesG->width() } p->setResizeMode(0, QHeaderView::Interactive); p->resizeSection(0, n); /*if (nSection >= 1 + 26*2) // ttt3 this is needed to handle more than 52 notes // ttt3 keep in mind that bold fonts need more space { for ... QFontMetrics fm (m_pCommonData->m_pFilesG->fontMetrics()); int nWidth (fm.width(getNoteLabel(nSection - 1))); //return QSize(50, CELL_HEIGHT); resizeSection(i, nWidth); }*/ } void CommonData::trace(const std::string& s) { if (m_bTraceEnabled) { m_vLogs.push_back(s); } } void CommonData::clearLog() { m_vLogs.clear(); } void setupTraceToFile(bool bEnable); void CommonData::setTraceToFile(bool bTraceToFile) // also removes the file { m_bTraceToFile = bTraceToFile; setupTraceToFile(bTraceToFile); } void CommonData::setFastSave(bool bFastSave, bool bUpdateTransforms) { if (m_bFastSave == bFastSave) { return; } m_bFastSave = bFastSave; if (!bUpdateTransforms) { return; } } /* KDE 3.5.7 / Qt 3.3.8 point size 6: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:8, pointSize:6, real pointSize on 100dpi screen:5.76 point size 7: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:10, pointSize:7, real pointSize on 100dpi screen:7.2 point size 8: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:11, pointSize:8, real pointSize on 100dpi screen:7.92 point size 9: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 point size 10: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 point size 11: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 point size 12: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 point size 13: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:18, pointSize:13, real pointSize on 100dpi screen:12.96 point size 14: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:20, pointSize:14, real pointSize on 100dpi screen:14.4 point size 15: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:20, pointSize:14, real pointSize on 100dpi screen:14.4 point size 16: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:24, pointSize:17, real pointSize on 100dpi screen:17.28 point size 17: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:24, pointSize:17, real pointSize on 100dpi screen:17.28 pixel size 6: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:6, real pointSize on 100dpi screen:5.76 pixel size 7: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:6, real pointSize on 100dpi screen:5.76 pixel size 8: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:8, pointSize:6, real pointSize on 100dpi screen:5.76 pixel size 9: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:6, real pointSize on 100dpi screen:5.76 pixel size 10: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:10, pointSize:7, real pointSize on 100dpi screen:7.2 pixel size 11: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:11, pointSize:8, real pointSize on 100dpi screen:7.92 pixel size 12: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:12, pointSize:9, real pointSize on 100dpi screen:8.64 pixel size 13: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 pixel size 14: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 pixel size 15: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 pixel size 16: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 pixel size 17: B&H LucidaTypewriter [B&H], exactMatch:1, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 font from QFontDialog: B&H LucidaTypewriter [B&H], exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 issues: 1) when building by point size, the 14px (10.08 points) is selected over the 12px (8.64 points) to approximate the "9 points" font 2) the 12px font can be selected in QFontDialog as "12 points" (as shown in the preview) but when the call returns the 14px font is passed */ /* Qt 4.3.1 point size 6: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 point size 7: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:10, pointSize:10, real pointSize on 100dpi screen:7.2 point size 8: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:11, pointSize:8, real pointSize on 100dpi screen:7.92 point size 9: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:12, pointSize:12, real pointSize on 100dpi screen:8.64 point size 10: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:14, real pointSize on 100dpi screen:10.08 point size 11: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:14, real pointSize on 100dpi screen:10.08 point size 12: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 point size 13: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:18, pointSize:18, real pointSize on 100dpi screen:12.96 point size 14: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:20, pointSize:14, real pointSize on 100dpi screen:14.4 point size 15: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:20, pointSize:14, real pointSize on 100dpi screen:14.4 point size 16: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:24, pointSize:24, real pointSize on 100dpi screen:17.28 point size 17: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:24, pointSize:24, real pointSize on 100dpi screen:17.28 pixel size 6: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 pixel size 7: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 pixel size 8: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 pixel size 9: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 pixel size 10: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:10, pointSize:10, real pointSize on 100dpi screen:7.2 pixel size 11: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:11, pointSize:8, real pointSize on 100dpi screen:7.92 pixel size 12: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:12, pointSize:12, real pointSize on 100dpi screen:8.64 pixel size 13: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:12, pointSize:12, real pointSize on 100dpi screen:8.64 pixel size 14: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:14, pointSize:14, real pointSize on 100dpi screen:10.08 pixel size 15: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:14, real pointSize on 100dpi screen:10.08 pixel size 16: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 pixel size 17: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 font from QFontDialog: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:14, real pointSize on 100dpi screen:10.08 issues: 1) while building a font with a particular point size works OK, the value returned by pointSize() is wrong for fonts with 75dpi resolution 2) the smallest "B&H LucidaTypewriter" font that can be selected in the dialog is 14px */ /* Qt 4.4.0 (KDE 4.1): point size 6: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 point size 7: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:10, pointSize:10, real pointSize on 100dpi screen:7.2 point size 8: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:11, pointSize:8, real pointSize on 100dpi screen:7.92 point size 9: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 point size 10: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 point size 11: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 point size 12: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 point size 13: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:18, pointSize:18, real pointSize on 100dpi screen:12.96 point size 14: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:20, pointSize:14, real pointSize on 100dpi screen:14.4 point size 15: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:20, pointSize:14, real pointSize on 100dpi screen:14.4 point size 16: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:20, pointSize:14, real pointSize on 100dpi screen:14.4 point size 17: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:24, pointSize:24, real pointSize on 100dpi screen:17.28 pixel size 6: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 pixel size 7: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 pixel size 8: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 pixel size 9: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:8, pointSize:8, real pointSize on 100dpi screen:5.76 pixel size 10: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:10, pointSize:10, real pointSize on 100dpi screen:7.2 pixel size 11: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:11, pointSize:8, real pointSize on 100dpi screen:7.92 pixel size 12: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:12, pointSize:12, real pointSize on 100dpi screen:8.64 pixel size 13: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 pixel size 14: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 pixel size 15: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 pixel size 16: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 pixel size 17: B&H LucidaTypewriter, exactMatch:1, fixedPitch:1, italic:0, pixelSize:17, pointSize:12, real pointSize on 100dpi screen:12.24 font from QFontDialog: B&H LucidaTypewriter, exactMatch:0, fixedPitch:1, italic:0, pixelSize:14, pointSize:10, real pointSize on 100dpi screen:10.08 issues: 1) when building by point size, the 14px (10.08 points) is selected over the 12px (8.64 points) to approximate the "9 points" font; this used to work in 4.3.1 2) the 12px font can't be selected at all in QFontDialog 3) in the dialog both smaller and larger fonts can be selected, but the 12px never shows up */ ��MP3Diags-1.0.12.079/src/NoteFilter.ui���������������������������������������������������������������0000644�0001750�0000144�00000003163�11227440217�015670� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>NoteFilterDlg</class> <widget class="QDialog" name="NoteFilterDlg" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>616</width> <height>424</height> </rect> </property> <property name="windowTitle" > <string>Note filter</string> </property> <property name="sizeGripEnabled" > <bool>true</bool> </property> <layout class="QVBoxLayout" > <item> <widget class="QWidget" native="1" name="m_pListHldr" /> </item> <item> <layout class="QHBoxLayout" > <property name="spacing" > <number>6</number> </property> <property name="leftMargin" > <number>0</number> </property> <property name="topMargin" > <number>0</number> </property> <property name="rightMargin" > <number>0</number> </property> <property name="bottomMargin" > <number>0</number> </property> <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" > <size> <width>131</width> <height>10</height> </size> </property> </spacer> </item> <item> <widget class="QPushButton" name="m_pOkB" > <property name="text" > <string>OK</string> </property> </widget> </item> <item> <widget class="QPushButton" name="m_pCancelB" > <property name="text" > <string>Cancel</string> </property> </widget> </item> </layout> </item> </layout> </widget> <resources/> <connections/> </ui> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/NormalizeDlgImpl.h����������������������������������������������������������0000644�0001750�0000144�00000005507�11230111215�016627� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef NormalizeDlgImplH #define NormalizeDlgImplH #include <QDialog> #include "ui_Normalize.h" class QProcess; class SessionSettings; class CommonData; class NormalizeDlgImpl : public QDialog, private Ui::NormalizeDlg { Q_OBJECT QProcess* m_pProc; bool m_bFinished; void addText(QString); int m_nLastKey; //QString m_qstrLastLine; QString m_qstrText; SessionSettings& m_settings; const CommonData* m_pCommonData; // for logging /*override*/ void closeEvent(QCloseEvent* pEvent); // /*override*/ void keyPressEvent(QKeyEvent* pEvent); // /*override*/ void keyReleaseEvent(QKeyEvent* pEvent); public: NormalizeDlgImpl(QWidget* pParent, bool bKeepOpen, SessionSettings& settings, const CommonData* pCommonData); ~NormalizeDlgImpl(); void normalize(const QString& qstrProg, const QStringList& lFiles); // it would make sense to return true if something was changed (or even exactly what changed), but that's not easy to do, so the caller should just assume that something changed public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ void onFinished(); void onOutputTxt(); void onErrorTxt(); void on_m_pCloseB_clicked(); void on_m_pAbortB_clicked(); void onHelp(); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/MultiLineTvDelegate.h�������������������������������������������������������0000644�0001750�0000144�00000006425�11265062600�017300� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MultiLineTvDelegateH #define MultiLineTvDelegateH #include <QItemDelegate> class QTableView; // This helps fix an issue with the default delegate, namely the fact that there is a shight discrepancy between the estimated size returned by sizeHint() and the actual size used when drawing; when a column gets resized, it is quite likely that close to the limit when the number of lines changes the last letters in a word will be changed to "...", because sizeHint() detects that 1 line is enough while paint() wants 2 lines. class MultiLineTvDelegate : public QItemDelegate { Q_OBJECT protected: QTableView* m_pTableView; mutable int m_nLineHeight, m_nAddPerLine; // needed because of Qt bugs in QFontMetrics::boundingRect() that cause incorrect heights to be returned when the text wraps across several lines (e.g. with some fonts an additional pixel must be added for each line to get the correct value) void calibrate(const QFontMetrics&, const QFont&) const; // sets up m_nLine and m_nTotalAdd public: MultiLineTvDelegate(QTableView* pTableView/*, QObject* pParent = 0*/); /*~MultiLineTvDelegate() { printf("destr MultiLineTvDelegate: %p\n", this); }*/ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; //void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const; /*void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index) const { //cout << "draw: " << option.rect.width() << "x" << option.rect.height() << endl; int nCol (index.column()); if (0 == nCol) { return QItemDelegate::paint(pPainter, option, index); } }*/ }; #endif // #ifndef MultiLineTvDelegateH �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������MP3Diags-1.0.12.079/src/DiscogsDownloader.cpp�������������������������������������������������������0000444�0001750�0000144�00000070235�12040500033�017361� 0����������������������������������������������������������������������������������������������������ustar �ciobi���������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * MP3 Diags - diagnosis, repairs and tag editing for MP3 files * * * * Copyright (C) 2009 by Marian Ciobanu * * ciobi@inbox.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <map> #include <QHttp> #include "DiscogsDownloader.h" #include "Helpers.h" #include "SimpleSaxHandler.h" #include "StoredSettings.h" ////#include <iostream> //ttt remove using namespace std; using namespace pearl; using namespace Discogs; ostream& operator<<(ostream& out, const DiscogsAlbumInfo& inf) { out << "id: \"" << inf.m_strId << "\", artist: \"" << inf.m_strArtist << "\", title: \"" << inf.m_strTitle << "\", composer: \"" << inf.m_strComposer << "\", format: \"" << inf.m_strFormat << "\", genre: \"" << inf.m_strGenre << "\", style: \"" << inf.m_strStyle << "\", released: \"" << inf.m_strReleased << "\"\n\nnotes: " << inf.m_strNotes << "\n\nimages:\n"; for (int i = 0, n = cSize(inf.m_vstrImageNames); i < n; ++i) { out << inf.m_vstrImageNames[i] << endl; } out << "\ntracks:" << endl; for (int i = 0, n = cSize(inf.m_vTracks); i < n; ++i) { out << "pos: \"" << inf.m_vTracks[i].m_strPos << "\", artist: \"" << inf.m_vTracks[i].m_strArtist << "\", title: \"" << inf.m_vTracks[i].m_strTitle << "\", composer: \"" << inf.m_vTracks[i].m_strComposer << "\"" << endl; } return out; } namespace Discogs { /* resp exactresults result uri searchresults result uri */ struct SearchXmlHandler : public SimpleSaxHandler<SearchXmlHandler> { SearchXmlHandler(DiscogsDownloader& dlg) : SimpleSaxHandler<SearchXmlHandler>("resp"), m_dlg(dlg), m_bIsRelease(false) { Node& resp (getRoot()); Node& exactResults (makeNode(resp, "exactresults")); Node& excResult (makeNode(exactResults, "result")); excResult.onStart = &SearchXmlHandler::onResultStart; Node& excUri (makeNode(excResult, "uri")); excUri.onChar = &SearchXmlHandler::onUriChar; Node& searchResults (makeNode(resp, "searchresults")); searchResults.onStart = &SearchXmlHandler::onSearchResultsStart; Node& srchResult (makeNode(searchResults, "result")); srchResult.onStart = &SearchXmlHandler::onResultStart; Node& srchUri (makeNode(srchResult, "uri")); srchUri.onChar = &SearchXmlHandler::onUriChar; } private: DiscogsDownloader& m_dlg; bool m_bIsRelease; void onSearchResultsStart(const QXmlAttributes& attrs) { int nStart (attrs.value("start").toInt()); int nEnd (attrs.value("end").toInt()); int nCount (attrs.value("numResults").toInt()); if (nStart == 1) { m_dlg.m_nPageSize = nEnd; } CB_ASSERT (m_dlg.m_nPageSize > 0); CB_ASSERT (0 == nEnd % m_dlg.m_nPageSize || nEnd == nCount); //ttt2 see if this needs to be more flexible int nPageCnt ((nCount + m_dlg.m_nPageSize - 1) / m_dlg.m_nPageSize); int nCrtPage ((nStart - 1)/m_dlg.m_nPageSize); if (0 == nPageCnt) { nCrtPage = -1; } // !!! needed for consistency m_dlg.m_nTotalPages = nPageCnt; m_dlg.m_nLastLoadedPage = nCrtPage; //cout << "total pages: " << nPageCnt << ", crt: " << nCrtPage << endl; } void onResultStart(const QXmlAttributes& attrs) { m_bIsRelease = "release" == attrs.value("type"); if (m_bIsRelease) { m_dlg.m_vAlbums.push_back(DiscogsAlbumInfo(&m_dlg.m_eStyleOption)); } } void onUriChar(const string& s) { if (m_bIsRelease) { string::size_type n (s.rfind("/")); CB_ASSERT (string::npos != n); //string s1 (convStr(qstrCh.right(qstrCh.size() - n - 1))); string s1 (s.substr(n + 1)); m_dlg.m_vAlbums.back().m_strId = s1; //cout << s << endl; } } }; /* resp release images image artists artist name title extraartists artist name role tracks formats format genres genre styles style released notes tracklist track position artists artist name title extraartists artist name role */ struct AlbumXmlHandler : public SimpleSaxHandler<AlbumXmlHandler> { AlbumXmlHandler(DiscogsAlbumInfo& albumInfo) : SimpleSaxHandler<AlbumXmlHandler>("resp"), m_albumInfo(albumInfo) { Node& resp (getRoot()); resp.onEnd = &AlbumXmlHandler::onRespEnd; Node& rel (makeNode(resp, "release")); rel.onStart = &AlbumXmlHandler::onReleaseStart; Node& images (makeNode(rel, "images")); Node& image (makeNode(images, "image")); image.onStart = &AlbumXmlHandler::onImageStart; Node& albArtists (makeNode(rel, "artists")); Node& albArtist (makeNode(albArtists, "artist")); Node& albArtistName (makeNode(albArtist, "name")); albArtistName.onChar = &AlbumXmlHandler::onAlbArtistNameChar; Node& albTitle (makeNode(rel, "title")); albTitle.onChar = &AlbumXmlHandler::onAlbTitleChar; Node& albExtraArtists (makeNode(rel, "extraartists")); Node& albExtraArtist (makeNode(albExtraArtists, "artist")); albExtraArtist.onStart = &AlbumXmlHandler::onAlbExtraArtistStart; albExtraArtist.onEnd = &AlbumXmlHandler::onAlbExtraArtistEnd; Node& albExtraArtistName (makeNode(albExtraArtist, "name")); albExtraArtistName.onChar = &AlbumXmlHandler::onExtraArtistNameChar; Node& albExtraArtistRole (makeNode(albExtraArtist, "role")); albExtraArtistRole.onChar = &AlbumXmlHandler::onExtraArtistRoleChar; Node& albExtraArtistTracks (makeNode(albExtraArtist, "tracks")); albExtraArtistTracks.onChar = &AlbumXmlHandler::onExtraArtistTracksChar; Node& formats (makeNode(rel, "formats")); Node& format (makeNode(formats, "format")); format.onStart = &AlbumXmlHandler::onFormatStart; Node& genres (makeNode(rel, "genres")); Node& genre (makeNode(genres, "genre")); genre.onChar = &AlbumXmlHandler::onGenreChar; Node& styles (makeNode(rel, "styles")); Node& style (makeNode(styles, "style")); style.onChar = &AlbumXmlHandler::onStyleChar; Node& released (makeNode(rel, "released")); released.onChar = &AlbumXmlHandler::onReleasedChar; Node& notes (makeNode(rel, "notes")); notes.onChar = &AlbumXmlHandler::onNotesChar; Node& tracklist (makeNode(rel, "tracklist")); Node& track (makeNode(tracklist, "track")); track.onStart = &AlbumXmlHandler::onTrackStart; Node& position (makeNode(track, "position")); position.onChar = &AlbumXmlHandler::onPositionChar; Node& trkArtists (makeNode(track, "artists")); Node& trkArtist (makeNode(trkArtists, "artist")); Node& trkArtistName (makeNode(trkArtist, "name")); trkArtistName.onChar = &AlbumXmlHandler::onTrkArtistNameChar; Node& trackTitle (makeNode(track, "title")); trackTitle.onChar = &AlbumXmlHandler::onTrackTitleChar; Node& trkExtraArtists (makeNode(track, "extraartists")); Node& trkExtraArtist (makeNode(trkExtraArtists, "artist")); trkExtraArtist.onEnd = &AlbumXmlHandler::onTrkExtraArtistEnd; Node& trkExtraArtistName (makeNode(trkExtraArtist, "name")); trkExtraArtistName.onChar = &AlbumXmlHandler::onExtraArtistNameChar; Node& trkExtraArtistRole (makeNode(trkExtraArtist, "role")); trkExtraArtistRole.onChar = &AlbumXmlHandler::onExtraArtistRoleChar; } private: DiscogsAlbumInfo& m_albumInfo; map<string, string> m_mComposers; // track-composer string m_strExtraArtistName; string m_strExtraArtistRole; string m_strExtraArtistTracks; static bool isNumber (const string& s) { int n (cSize(s)); if (0 == n) { return false; } for (int i = 0; i < n; ++i) { if (!isdigit(s[i])) { return false; } } return true; } // since roles of "Composed By" and "Written-By" were found, it seems that these don't follow a strict syntax; so probably non-letters are best ignored; case might be better ignored too; static string transfRole(const string& s) { string res; for (int i = 0, n = cSize(s); i < n; ++i) { char c (s[i]); if (isalnum(c)) { res += tolower(c); } } return res; } static bool isComposerRole(string s) { //qDebug(" orig role %s", s.c_str()); s = transfRole(s); //qDebug(" transf role %s", s.c_str()); return "composedby" == s || "writtenby" == s || "musicby" == s || "lyricsby" == s; // ttt2 review whether all these should be added to "composer"; see if some others should be put here } void onReleaseStart(const QXmlAttributes& attrs) { CB_ASSERT (m_albumInfo.m_strId == convStr(attrs.value("id"))); m_mComposers.clear(); } void onImageStart(const QXmlAttributes& attrs) { string strUri (convStr(attrs.value("uri"))); string::size_type n (strUri.rfind('/')); CB_ASSERT (string::npos != n); strUri.erase(0, n + 1); m_albumInfo.m_vstrImageNames.push_back(strUri); //cout << strUri << endl; } void onAlbExtraArtistStart(const QXmlAttributes& /*attrs*/) { m_strExtraArtistName.clear(); m_strExtraArtistRole.clear(); m_strExtraArtistTracks.clear(); } void onFormatStart(const QXmlAttributes& attrs) { string strFmt (convStr(attrs.value("name"))); //cout << strFmt << endl; addIfMissing(m_albumInfo.m_strFormat, strFmt); } void onTrackStart(const QXmlAttributes& /*attrs*/) { m_albumInfo.m_vTracks.push_back(TrackInfo()); } // called by onRespEnd(); assigns composers to tracks based on the content of m_mComposers void onRespEnd() { for (int i = 0, n = cSize(m_albumInfo.m_vTracks); i < n; ++i) { TrackInfo& t (m_albumInfo.m_vTracks[i]); addList(t.m_strComposer, m_mComposers[t.m_strPos]); addList(t.m_strComposer, m_albumInfo.m_strComposer); addList(t.m_strArtist, m_albumInfo.m_strArtist); } m_albumInfo.m_vpImages.resize(m_albumInfo.m_vstrImageNames.size()); m_albumInfo.m_vstrImageInfo.resize(m_albumInfo.m_vstrImageNames.size()); } // takes data from m_strExtraArtistName, m_strExtraArtistRole and m_strExtraArtistTracks and either adds it to m_mComposers (if some tracks were specified) or to m_albumInfo.m_strComposer (if no tracks are given) void onAlbExtraArtistEnd() { if (isComposerRole(m_strExtraArtistRole)) { vector<string> v; if (m_strExtraArtistTracks.empty()) { addIfMissing(m_albumInfo.m_strComposer, m_strExtraArtistName); } else { split(m_strExtraArtistTracks, ",", v); for (int i = 0, n = cSize(v); i < n; ++i) { string t (v[i]); string::size_type p (t.find("to")); if (string::npos != p) { addIfMissing(m_mComposers[t], m_strExtraArtistName); } else { string s1 (t.substr(0, p)); trim(s1); string s2 (t.substr(p + 2)); trim(s2); if (isNumber(s1) && isNumber(s2)) { int n1 (atoi(s1.c_str())); int n2 (atoi(s2.c_str())); char a [10]; const char* szFmt ('0' == s1[0] ? "%02d" : "%d"); for (int i = n1; i <= n2; ++i) { sprintf(a, szFmt, i); addIfMissing(m_mComposers[a], m_strExtraArtistName); } } else { qDebug("track range not supported for non-numeric positions"); // ttt2 maybe support } } } } } } void onTrkExtraArtistEnd() { if (isComposerRole(m_strExtraArtistRole)) // ttt2 see if "Music By" should be compared too { addIfMissing(m_albumInfo.m_vTracks.back().m_strComposer, m_strExtraArtistName); //inspect(m_strExtraArtistName); } } void onAlbArtistNameChar(const string& s) { addIfMissing(m_albumInfo.m_strArtist, s); } void onExtraArtistNameChar(const string& s) { m_strExtraArtistName = s; //addIfMissing(m_strExtraArtistName, s); // ttt2 review if this makes sense, given that for artists there is the option to join, but not sure about extraartists: /* <track> <position>5</position> <artists> <artist> <name>Chloë Agnew</name> <join>&</join> </artist> <artist> <name>Lisa Kelly</name> <join>&</join> </artist> <artist> <name>Órla Fallon</name> <join>&</join> </artist> <artist> <name>Méav Ní Mhaolchatha</name> </artist> </artists> <title>One World 3:49 */ } void onExtraArtistRoleChar(const string& s) { //addIfMissing(m_strExtraArtistRole, s); m_strExtraArtistRole = s; } void onExtraArtistTracksChar(const string& s) { //addIfMissing(m_albumInfo.m_strArtist, s); m_strExtraArtistTracks = s; } void onAlbTitleChar(const string& s) { m_albumInfo.m_strTitle = s; } void onGenreChar(const string& s) { addIfMissing(m_albumInfo.m_strGenre, s); } void onStyleChar(const string& s) { addIfMissing(m_albumInfo.m_strStyle, s); } void onReleasedChar(const string& s) { m_albumInfo.m_strReleased = s; } void onNotesChar(const string& s) { m_albumInfo.m_strNotes = s; } void onPositionChar(const string& s1) { string s (s1); //m_albumInfo.m_vTracks.back().m_nPos = qstrCh.toInt(); if (endsWith(s, ".")) { s.erase(s.size() - 1, 1); } m_albumInfo.m_vTracks.back().m_strPos = s; } void onTrkArtistNameChar(const string& s) { addIfMissing(m_albumInfo.m_vTracks.back().m_strArtist, s); } void onTrackTitleChar(const string& s) { m_albumInfo.m_vTracks.back().m_strTitle = s; } }; /*override*/ void DiscogsAlbumInfo::copyTo(AlbumInfo& dest) { //cout << *this; dest.m_strTitle = m_strTitle; //dest.m_strArtist = m_strArtist; //dest.m_strComposer = m_strComposer; //dest.m_strFormat = m_strFormat; // CD, tape, ... dest.m_strGenre = getGenre(); dest.m_strReleased = m_strReleased; dest.m_strNotes = m_strNotes; dest.m_vTracks = m_vTracks; //dest.m_eVarArtists // !!! missing dest.m_strSourceName = DiscogsDownloader::SOURCE_NAME; // Discogs, MusicBrainz, ... ; needed by MainFormDlgImpl; //dest.m_imageInfo; // !!! not set } std::string DiscogsAlbumInfo::getGenre() const // combination of m_strGenre and m_strStyle { switch (*m_peStyleOption) { case GENRE_ONLY: return m_strGenre; case GENRE_COMMA_STYLE: return m_strGenre.empty() || m_strStyle.empty() ? m_strGenre + m_strStyle : m_strGenre + ", " + m_strStyle; case GENRE_PAR_STYLE: { if (m_strStyle.empty()) { return m_strGenre; } if (m_strGenre.empty()) { return "(" + m_strStyle + ")"; } // ttt2 perhaps without "(/)" return m_strGenre + " (" + m_strStyle + ")"; } case STYLE_ONLY: return m_strStyle; } CB_ASSERT (false); } }; // namespace Discogs //============================================================================================================================= //============================================================================================================================= //============================================================================================================================= /*override*/ void DiscogsDownloader::saveSize() { m_settings.saveDiscogsSettings(width(), height(), m_pStyleCbB->currentIndex()); } /*static*/ const char* DiscogsDownloader::SOURCE_NAME ("Discogs"); DiscogsDownloader::DiscogsDownloader(QWidget* pParent, SessionSettings& settings, bool bSaveResults) : AlbumInfoDownloaderDlgImpl(pParent, settings, bSaveResults), m_nPageSize(200) //ttt0 review "200" - really should be initialized in SearchXmlHandler::onSearchResultsStart() and here just get an invalid value { setWindowTitle("Download album data from Discogs.com"); int nWidth, nHeight, nStyleOption; m_settings.loadDiscogsSettings(nWidth, nHeight, nStyleOption); if (nStyleOption < 0 || nStyleOption > Discogs::DiscogsAlbumInfo::STYLE_ONLY) { nStyleOption = Discogs::DiscogsAlbumInfo::GENRE_ONLY; } m_eStyleOption = Discogs::DiscogsAlbumInfo::StyleOption(nStyleOption); if (nWidth > 400 && nHeight > 400) { resize(nWidth, nHeight); } delete m_pSrchArtistL; delete m_pSrchAlbumL; delete m_pSrchAlbumE; delete m_pSpacer01L; //delete m_pViewAtAmazonE; delete m_pMatchCountCkB; m_pViewAtAmazonL->hide(); { QStringList l; //l << "< don't use >" << "Genre1, Genre2, ... , Style1, Style2, ..." << "Genre1, Genre2, ... (Style1, Style2, ...)" << "Style1, Style2, ..."; l << "Genres" << "Genres, Styles" << "Genres (Styles)" << "Styles"; m_pStyleCbB->addItems(l); m_pStyleCbB->setCurrentIndex(nStyleOption); } m_pQHttp->setHost("api.discogs.com"); m_pModel = new WebDwnldModel(*this, *m_pTrackListG); // !!! in a way these would make sense to be in the base constructor, but that would cause calls to pure virtual methods m_pTrackListG->setModel(m_pModel); connect(m_pSearchB, SIGNAL(clicked()), this, SLOT(on_m_pSearchB_clicked())); connect(m_pStyleCbB, SIGNAL(currentIndexChanged(int)), this, SLOT(on_m_pStyleCbB_currentIndexChanged(int))); } DiscogsDownloader::~DiscogsDownloader() { resetNavigation(); // !!! not in base class, because it calls virtual method resetNavigation() clear(); } void DiscogsDownloader::clear() { LAST_STEP("DiscogsDownloader::clear"); clearPtrContainer(m_vpImages); m_vAlbums.clear(); } /*override*/ bool DiscogsDownloader::initSearch(const std::string& strArtist, const std::string& strAlbum) { LAST_STEP("DiscogsDownloader::initSearch"); string s (!strArtist.empty() && !strAlbum.empty() ? strArtist + " " + strAlbum : strArtist + strAlbum); s = removeParentheses(s); m_pSrchArtistE->setText(convStr(s)); return !s.empty(); } // "/search?type=all&q=Beatles+Abbey+Road&f=xml&api_key=f51e9c8f6c" /*override*/ std::string DiscogsDownloader::createQuery() { LAST_STEP("DiscogsDownloader::createQuery"); //string s (strArtist + "+" + strAlbum); string s ("/search?q=" + replaceSymbols(convStr(m_pSrchArtistE->text())) + "&f=xml"); for (string::size_type i = 0; i < s.size(); ++i) { if (' ' == s[i]) { s[i] = '+'; } } return s; } //========================================================================================================================== //========================================================================================================================== //========================================================================================================================== void DiscogsDownloader::on_m_pSearchB_clicked() { LAST_STEP("DiscogsDownloader::on_m_pSearchB_clicked"); clear(); search(); } //========================================================================================================================== //========================================================================================================================== //========================================================================================================================== void DiscogsDownloader::loadNextPage() { LAST_STEP("DiscogsDownloader::loadNextPage"); CB_ASSERT (!m_pQHttp->hasPendingRequests()); //ttt0 2010/05/08 - reported again in 0.99.05.033 for Ubuntu 9.10 ++m_nLastLoadedPage; CB_ASSERT (m_nLastLoadedPage <= m_nTotalPages - 1); //m_eState = NEXT; setWaiting(SEARCH); char a [20]; sprintf(a, "&page=%d", m_nLastLoadedPage + 1); string s (m_strQuery + a); QHttpRequestHeader header ("GET", convStr(s)); // ttt1 QHttpRequestHeader and QHttp are deprecated, to be replaced by QNetworkAccessManager header.setValue("Host", "api.discogs.com"); // ttt1 Discogs API v1 is deprecated; switch to v2: http://api.discogs.com/search?q=abba&f=xml vs http://www.discogs.com/search?type=all&q=abba&f=xml&api_key=f51e9c8f6c // see http://www.discogs.com/help/forums/topic/234138 //header.setValue("Host", "api.discogs.com"); header.setValue("Accept-Encoding", "gzip"); //header.setValue("User-Agent" , "Mozilla Firefox"); header.setValue("User-Agent" , "Mp3Diags"); m_pQHttp->request(header); //cout << "sent search " << m_pQHttp->request(header) << " for page " << (m_nLastLoadedPage + 1) << endl; } /* http://www.discogs.com/help/api http://www.discogs.com/developers/ http://www.discogs.com/developers/accessing.html http://www.discogs.com/developers/resources/database/index.html http://www.discogs.com/developers/resources/database/artist.html http://api.discogs.com/release/1 http://www.discogs.com/developers/resources/database/image.html http://www.discogs.com/developers/resources/database/search-endpoint.html http://api.discogs.com/database/search?artist=coldplay http://qtwiki.org/Parsing_JSON_with_QT_using_standard_QT_library http://nilier.blogspot.com/2010/08/json-parser-class-for-qt.html?spref=tw http://ereilin.tumblr.com/post/6857765046/lightweight-json-parser-serializer-class-for-qt https://github.com/ereilin/qt-json */ void DiscogsDownloader::reloadGui() { LAST_STEP("DiscogsDownloader::reloadGui"); AlbumInfoDownloaderDlgImpl::reloadGui(); const DiscogsAlbumInfo& album (m_vAlbums[m_nCrtAlbum]); m_pAlbumNotesM->setText(convStr(album.m_strNotes)); m_pGenreE->setText(convStr(album.getGenre())); } //http://api.discogs.com/release/1565272?f=xml vs http://www.discogs.com/release/1565272?f=xml&api_key=f51e9c8f6c void DiscogsDownloader::requestAlbum(int nAlbum) { LAST_STEP("DiscogsDownloader::requestAlbum"); CB_ASSERT (!m_pQHttp->hasPendingRequests()); //ttt1 triggered according to mail (Nov 2, 2009, 2:31 PM - Qt 4.5.2; there is something in the 4.5.3 change log at http://qt.nokia.com/developer/changes/changes-4.5.3 about duplicate HTTP requests, but according to http://www.qtcentre.org/forum/f-qt-programming-2/t-qhttp-response-content-25255-post121265.html it only affected QNetworkAccessManager, which is a replacement for QHttp, so this is probably not related) m_nLoadingAlbum = nAlbum; setWaiting(ALBUM); string s ("/release/" + m_vAlbums[nAlbum].m_strId + "?f=xml"); QHttpRequestHeader header ("GET", convStr(s)); header.setValue("Host", "api.discogs.com"); header.setValue("Accept-Encoding", "gzip"); header.setValue("User-Agent" , "Mp3Diags"); m_pQHttp->request(header); //cout << "sent album " << m_vAlbums[nAlbum].m_strId << " - " << m_pQHttp->request(header) << endl; addNote("getting album info ..."); } //http://api.discogs.com/image/R-1565272-1228883740.jpeg vs http://www.discogs.com/image/R-1565272-1228883740.jpeg?api_key=f51e9c8f6c void DiscogsDownloader::requestImage(int nAlbum, int nImage) { LAST_STEP("DiscogsDownloader::requestImage"); CB_ASSERT (!m_pQHttp->hasPendingRequests()); m_nLoadingAlbum = nAlbum; m_nLoadingImage = nImage; setWaiting(IMAGE); const string& strName (m_vAlbums[nAlbum].m_vstrImageNames[nImage]); setImageType(strName); string s ("/image/" + strName); //cout << " get img " << s << endl; QHttpRequestHeader header ("GET", convStr(s)); header.setValue("Host", "api.discogs.com"); //header.setValue("Accept-Encoding", "gzip"); header.setValue("User-Agent" , "Mp3Diags"); m_pQHttp->request(header); //cout << "sent img " << m_vAlbums[nAlbum].m_vstrImageNames[nImage] << " - " << m_pQHttp->request(header) << endl; addNote("getting image ..."); } void DiscogsDownloader::on_m_pStyleCbB_currentIndexChanged(int k) { LAST_STEP("DiscogsDownloader::on_m_pStyleCbB_currentIndexChanged"); if (m_nCrtAlbum < 0 || m_nCrtAlbum >= cSize(m_vAlbums)) { return; } DiscogsAlbumInfo& album (m_vAlbums[m_nCrtAlbum]); m_eStyleOption = Discogs::DiscogsAlbumInfo::StyleOption(k); m_pGenreE->setText(convStr(album.getGenre())); } //========================================================================================================================== //========================================================================================================================== //========================================================================================================================== /*override*/ QHttp* DiscogsDownloader::getWaitingHttp() { LAST_STEP("DiscogsDownloader::getWaitingHttp"); return m_pQHttp; } /*override*/ WebAlbumInfoBase& DiscogsDownloader::album(int i) { return m_vAlbums.at(i); } /*override*/ int DiscogsDownloader::getAlbumCount() const { return cSize(m_vAlbums); } /*override*/ QXmlDefaultHandler* DiscogsDownloader::getSearchXmlHandler() { return new SearchXmlHandler(*this); } /*override*/ QXmlDefaultHandler* DiscogsDownloader::getAlbumXmlHandler(int nAlbum) { return new AlbumXmlHandler(m_vAlbums.at(nAlbum)); } /*override*/ const WebAlbumInfoBase* DiscogsDownloader::getCrtAlbum() const // returns 0 if there's no album { if (m_nCrtAlbum < 0 || m_nCrtAlbum >= cSize(m_vAlbums)) { return 0; } return &m_vAlbums[m_nCrtAlbum]; } MP3Diags-1.0.12.079/src/licences/0000755000175000001440000000000012036514073015041 5ustar ciobiusersMP3Diags-1.0.12.079/src/licences/gplv3.txt0000644000175000001440000010360611107241715016641 0ustar ciobiusersGNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright © 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 .MP3Diags-1.0.12.079/src/licences/boost.txt0000644000175000001440000000247211203001725016723 0ustar ciobiusersBoost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. MP3Diags-1.0.12.079/src/licences/lgplv3.txt0000644000175000001440000001645411107241731017017 0ustar ciobiusersGNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, “this License” refers to version 3 of the GNU Lesser General Public License, and the “GNU GPL” refers to version 3 of the GNU General Public License. “The Library” refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An “Application” is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A “Combined Work” is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the “Linked Version”. The “Minimal Corresponding Source” for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The “Corresponding Application Code” for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: * a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or * b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: * a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. * b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: * a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. * b) Accompany the Combined Work with a copy of the GNU GPL and this license document. * c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. * d) Do one of the following: o 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. o 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. * e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: * a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. * b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.MP3Diags-1.0.12.079/src/licences/gplv2.txt0000644000175000001440000004235211107241710016633 0ustar ciobiusersGNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. MP3Diags-1.0.12.079/src/licences/lgpl-2.1.txt0000644000175000001440000005664411203001247017042 0ustar ciobiusersGNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: * a) The modified work must itself be a software library. * b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. * c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. * d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: * a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) * b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. * c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. * d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. * e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: * a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. * b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. MP3Diags-1.0.12.079/src/licences/zlib.txt0000644000175000001440000000207511203001660016532 0ustar ciobiusers zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.3, July 18th, 2005 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly jloup@gzip.org Mark Adler madler@alumni.caltech.edu MP3Diags-1.0.12.079/mp3diags.kdevelop0000644000175000001440000001767612040502151015735 0ustar ciobiusers Marian Ciobanu ciobi@inbox.com 0.99 KDevTrollProject C++ Qt MP3Diags false false false *.o,*.lo,CVS true 4 4 ExternalDesigner /usr/bin/qmake /usr/bin/designer /usr/lib/qt4 false true true 250 400 250 false 0 true true false std=_GLIBCXX_STD;__gnu_cxx=std true false false false false true true false .; bash bash_bugs clanlib fortran_bugs_gcc gnome1 gnustep gtk gtk_bugs haskell haskell_bugs_ghc java_bugs_gcc java_bugs_sun kde2book opengl pascal_bugs_fp php php_bugs perl perl_bugs python python_bugs qt-kdev3 ruby ruby_bugs sdl stl sw w3c-dom-level2-html w3c-svg w3c-uaag10 wxwidgets_bugs KDE Libraries (Doxygen) /usr/bin/gdb true false false false true ./bin/MP3Diags executable src true Doxygen Documentation Collection MP3Diags.tag MP3Diags mp3diags MP3Diags MP3DIAGS Marian Ciobanu /usr/bin/designer ciobi@inbox.com GPL COPYING /usr/bin/qmake 0.99 2009 MP3Diags-1.0.12.079/BuildMp3Diags.hta0000644000175000001440000006203512040502151015545 0ustar ciobiusers MP3 Diags build configuration
Boost Serialization .lib file - release
Toolchain / IDECompiler binary folderQt root folderBoost root folderBoost Serialization .lib file - releaseZlib include folderZlib .lib file
Maximum number of folders remembered:


Notes:
  1. The purpose of this utility is to allow builds to be made easily for various combinations of compiler and libraries, as well as generate project files that can be used from IDEs.
  2. First you need to choose your compiler / IDE and configure the folders and libraries. For a given folder there is a toolchain and a set of libraries that can be configured. Others should be set up in another folder.
  3. Folders are populated with invalid values by default. Usually it should be easy to correct them, provided that you have installed the required libraries (Qt, Boost Serialization, and zlib.) If you already configured a folder for the same toolchain, you can copy the settings to the current folder.
  4. Note that the Qt root folder is for the Qt library, not for Qt Creator..
  5. After configuring the folders you need to "set up" the project. Then you can either build it, by clicking on the corresponding button, or open it in an IDE.
  6. To open MP3 Diags with Qt Creator: set up the project, start Qt Creator and open mp3diags.pro. If it offers to import existing build settings, you should decline; otherwise you'll only be able to build the debug version.
  7. To open MP3 Diags with Visual C++ (Express): first set up the project. Then, if you have a 2008 version, you can double-click on mp3diags.sln in Windows Explorer. If you have something else, double-clicking on src\MP3DiagsWindows.vcproj will probably work, as well as opening either src\MP3DiagsWindows.vcproj or mp3diags.sln from the IDE; however, these haven't been tested.
  8. MinGW uses the "release" Boost serialization in both debug and and release version, while the Visual C++ debug version uses the "debug" serialization. There is little reason to debug the serialization code, but by design that's how Boost works under Visual C++. (Note that you should specify the release library in "Boost .lib file" regardless of what you want to build. The generated .vcproj file will have correct settings for both "debug" and "release" configurations.)
  9. The settings are stored in the file Up to 10 folders are remembered by default (the maximum is 100.) You can use them to keep several versions of the project, perhaps including some local changes or different libraries.
  10. The settings are saved automatically only if you set up or build the project. Otherwise you need to save them explicitely.
MP3Diags-1.0.12.079/branch.txt0000644000175000001440000000000011570452726014461 0ustar ciobiusersMP3Diags-1.0.12.079/changelog.txt0000644000175000001440000004453412040500603015154 0ustar ciobiusers--------------------------------------------------------------------------- 20.10.2012 - 1.0.12.079 - Discogs fix --------------------------------------------------------------------------- 11.05.2012 - 1.0.11.076 - made program compilable with GCC 4.7 --------------------------------------------------------------------------- 31.12.2011 - 1.0.10.065 - updated Discogs API calls to current version --------------------------------------------------------------------------- 10.09.2011 - 1.0.09.063 - made Discogs queries work again, after a Discogs API change - added close button for windows on Gnome 3 --------------------------------------------------------------------------- 28.05.2011 - 1.0.08.053 - fixed crash when trying to save after error at startup - added branch support to build process --------------------------------------------------------------------------- 29.12.2010 - 1.0.07.052 - fixed crash in folder filter dialog - made project compilable on Fedora 13 and 14 --------------------------------------------------------------------------- 04.07.2010 - 1.0.06.051 - fixed crash caused by invalid Lyrics tag - fixed assertion failure when opening the folder filter in Windows --------------------------------------------------------------------------- 17.03.2010 - 1.0.05.050 - fixed issue #23 (assertion failure) --------------------------------------------------------------------------- 07.03.2010 - 1.0.04.049 - fixed crash triggered by invalid frame lengths in ID3V2 - fixed crash that occured when the backup directory couldn't be created --------------------------------------------------------------------------- 29.01.2010 - 1.0.03.048 - fixed crash triggered by GEOB frames containing UTF-16 text --------------------------------------------------------------------------- 12.01.2010 - 1.0.02.047 - fixed crash triggered by trying to repair broken ID3V2 tags that contain images - fixed crash that occurred when changing file names manually in the file renamer, without defining a pattern - fixed crash caused by unsynchronized ID3V2.4.0 frames that end with 0xff --------------------------------------------------------------------------- 11.12.2009 - 1.0.01.046 - fixed crash that occurred when running on Qt 4.6 - fixed crash that occurred when changing song info in the tag editor if songs had images stored as BMP or anything else besides JPG or PNG --------------------------------------------------------------------------- 29.11.2009 - 1.0.00.045 - wording changes to reflect non-beta status - pressing CTRL+C when viewing full-size images in the tag editor or in "Tag details" in the main window copies the image to the clipboard - added "Rating" and changed field order in "Tag details" to match the Tag editor --------------------------------------------------------------------------- 04.11.2009 - 0.99.06.044 - fixed a crash in folder filter - fixed bug causing non-normalized files having any TXXX frame to appear normalized - case is ignored for file extension, so .Mp3 or .mP3 files are recognized - better support and more consistent handling for TXXX and text frames in ID3V2 - reduced number of locales by eliminating redundant ones - disabled CTRL+A selection in the main window - static link for serialization - added trace details for web downloads --------------------------------------------------------------------------- 27.10.2009 - 0.99.06.043 - "Simple view" in file configuration - fixed crash on empty text frames in ID3V2 - generic binaries for Linux - BuildMp3Diags.hta detects VS version - documentation updates --------------------------------------------------------------------------- 20.10.2009 - 0.99.06.042 - better support for binary frames in ID2V2.4.0 - fixed bug resulting in crash when files were modified in external tools - fixed bug resulting in crash when renaming files if a filter is applied - fixed bug resulting in crash when going to "Tag details" for files using Unicode in USLT (issue 40) - added option to include styles in Discogs info - added case-change option to the tag editor - better detection and notification for changed files before applying transformations or saving from the tag editor - file renamer allows file names to be changed manually - file renamer can use "duplicate" label for unrated songs - images shown for Lyrics tags - improved case-change transformation - removing images from the tag editor now works even for non-cover images --------------------------------------------------------------------------- 09.10.2009 - 0.99.06.041 - brought documentation up to date - added test for ReplayGain info stored inside Id3V2 - failing to read text frames from files no longer causes crashes - fixed bug resulting in crash when 2 ID3V2 tags are present and "Discard invalid ID3V2 data" gets called - XML export now works when names contain double quotes - locale in export dialog - locale lists are now sorted - long text frames are now truncated when shown in the "File info" area - changed names and order for tabs under Config/Files - made transformation options work correctly in MSVC --------------------------------------------------------------------------- 30.09.2009 - 0.99.06.040 - "Various Artists" support - all pictures are shown and can be viewed in full size in "Tag details" - all pictures from a file are shown in the tag editor - patterns in the tag editor may now be disabled - export as M3U or XML - better handling of text frames containing null characters - auto-size for the tag editor's "current file" area - better column widths in the tag editor - improved HTA for Windows build --------------------------------------------------------------------------- 23.09.2009 - 0.99.05.038 - fixed bug introduced in 0.99.05.037 causing crashes when finding empty ID3V2 frames - new build process for Windows - 4th custom transf list now defaults to a "fix-all" approach --------------------------------------------------------------------------- 17.09.2009 - 0.99.05.037 - fixes on right-click - UTF-8 strings recognized in ID3V2.3.0 - fixed bug 35 (assertion failure) - faster tracer - code compilable with VS 2008 (port by Sebastian Schuberth) --------------------------------------------------------------------------- 07.09.2009 - 0.99.05.034 - drive labels shown in Windows - mp3gain can be started now if it's in a directory containing spaces - configurable invalid characters and replacement for file renamer - automatic check for new versions - text inside square, curly, and angle brackets removed from web queries - improved tracing code - no longer rescan the files if exiting tag editor without changes - replace non-alphanumeric chars with spaces in web queries (issue 2) - better sorting in the tag editor for albums with unusual track numbers - a default .ini name is generated in most cases - (probably) fixed an assert (not sure because couldn't reproduce it) - tracks without a track number are put at the end in the tag editor - let the user know about reporting support notes and about patterns - better detection of exceptions in threads - exceptions that propagate from slots are now caught - default "actions to be taken" no longer shown when applying transforms - file info for StreamWriter --------------------------------------------------------------------------- 02.09.2009 - 0.99.05.033 - fixed crash in Windows when checking a whole drive - fixed crash when saving data from the tag editor - improved trace speed on Windows - fixed potential crash at startup - fixed crash when changing a file that is being used by other program - more details and better formatting in assert messages and trace files - MPEG2 Layer3 streams no longer show Support note - improved temporary file generation, which can result in faster transforms - F1 help now works for the first session dialog - smaller TABs in the "Tag details" area make "Other info" more readable - better HTML paragraph formatting --------------------------------------------------------------------------- 23.08.2009 - 0.99.05.032 - new Qt (4.5.2) and MinGW (3.4.5) for the Windows version - restructured crash detector - fixed Windows issue with rectangles being shown instead of letters - Lyrics partial support - warning that may corrupt data - note about how to change selected files - HTML clean up --------------------------------------------------------------------------- 18.08.2009 - 0.99.05.031 - crash detection - fixed small memory leak in config dialog - fixed small memory leak in the tag editor - content is shown for GEOB frames - .ID3 files are now loaded in addition to .MP3 - made the counter shown when applying transforms increment on new file (until now it was incremented for each transform) - "Various artists" no longer set as "artist" when downloading track info from MusicBrainz - fixed "current cell" in the tag editor (until now, when dragging the mouse to select several cells, the current cell was wrong, leading to setting values incorrectly - fixed a bug that didn't allow removal of the track number - slightly improved the normalizer, so a "busy" cursor is shown when the connection to the underlying process is lost (the program seems frozen, but it resumes after about 30 seconds) --------------------------------------------------------------------------- 28.07.2009 - 0.99.05.030 - fixed a bug that caused the tag editor to reserve more space than needed even if the "fast save" option was turned off - fixed a bug that prevented removal of elements from lists - fixed a bug in the ID3V2 tag writer that prevented "Discard invalid ID3V2 data" and other transformations to properly work with ID3V2.4.0 tags that contain UTF8-encoded strings, resulting in a broken ID3V2.3.0 tag - file renamer now accepts patterns with no directory separators, in which case the renamed files are placed in the source directory - pattern dialogs now show the current line and column - fixed an assertion in the code that determines the file list - added tooltips for all the notes in the main file table - improved speed for "Discard invalid ID3V2 data" when no changes are done - transformation name included in the dialog that shows which file is currently processed - broken ID3V2 streams get removed when saving from the tag editor - the tag editor no longer triggers an assertion failure if non-default settings in the file section of the configuration dialog; (e.g. until now saving from the tag editor while original files weren't deleted resulted in this assertion failure) - fixed a bug in the "Change case for ID3V2 text frames" that resulted in a program crash if some fields were missing from the ID3V2 tag --------------------------------------------------------------------------- 26.07.2009 - 0.99.05.029 - improved paste in tag editor (it is possible to paste to multiple cells or to paste file names copied from file browsers) - configurable max image size - button to remove image files - fixed loading images from current dir - fixed a bug in tag editor patterns that prevented patterns ending with a static text from working - Windows only: fixed pasting image file that was copied from Windows Explorer --------------------------------------------------------------------------- 23.07.2009 - 0.99.05.028 - fast save in the tag editor --------------------------------------------------------------------------- 21.07.2009 - 0.99.04.027 - file renamer can work with the list of visible files instead of the current album if the user holds CTRL down when pressing the button - new transform for keeping a single image, as front cover - new transform for removing ID3V1 - configurable visible transformations - tooltips for the transformations menu - use of backslash for path separator on Windows - fixed some bugs in the directory filter - made F1 work on Windows - fixed normalization status on Windows - directory filter no longer shows some directories that don't make sense - more checks + fixed error reporting in file renamer - "sessions" button visible by default for second and later sessions --------------------------------------------------------------------------- 17.07.2009 - 0.99.04.026 - size grip on most dialogs - F1 help --------------------------------------------------------------------------- 15.07.2009 - 0.99.03.025 - restructured Unicode stream classes - Lyrics inside ID3V2 are now shown --------------------------------------------------------------------------- 15.07.2009 - 0.99.03.024 - switched to fstream_utf8 --------------------------------------------------------------------------- 13.07.2009 - 0.99.03.023 - tag editor now looks at filter - files changed in the tag editor no longer show up in the main window if a filter is applied and they don't match the filter - better alignment for text in note column header on Ubuntu - replaced C / POSIX calls with Qt calls --------------------------------------------------------------------------- 09.07.2009 - 0.99.03.022 - configurable colors --------------------------------------------------------------------------- 09.07.2009 - 0.99.03.021 - 2-letter labels - gradient grouping of notes - more consistent font handling - detecting files changed by external tools - tooltips are shown for the column headers in the file table --------------------------------------------------------------------------- 05.07.2009 - 0.99.02.020 - added sysinfo to "about" dialog - more details in sysinfo - made file renamer work on Windows - file renamer now replaces invalid characters in file names - made logger work on Windows 7 (and probably Vista) --------------------------------------------------------------------------- 29.06.2009 - 0.99.02.019 - downloaded images are no longer lost when saving in the tag editor - duration is now shown for audio streams - fixed assertion caused by files with too many streams - assertion instructs reports to be made on forum instead of email - number of files that might get changed is shown before processing multiple files - assert message includes more info about the OS - multiple ID3 stream remover no longer included by default in second list - some changes to .spec file in the hope it will work on Mandriva --------------------------------------------------------------------------- 24.06.2009 - 0.99.02.018 - made -mt suffix default for Boost Serialization --------------------------------------------------------------------------- 24.06.2009 - 0.99.02.017 - always use multithreaded libraries - improved assert dialog; now it has more data, which can be copied and even emailed directly - the tag editor shows a warning in some cases when a user action would result in discarded images --------------------------------------------------------------------------- 21.06.2009 - 0.99.02.016 - fixed an assertion failure that was triggered by an unsupported text encoding in APIC - added support for UTF8 text encoding in APIC - made the documentation look slightly better on IE6 --------------------------------------------------------------------------- 20.06.2009 - 0.99.02.015 - made compilable on Fedora 11 and added Fedora 11 build - copying missing ID3V1 fields to ID3V2 no longer part of the default custom transformation list 2 --------------------------------------------------------------------------- 18.06.2009 - 0.99.02.014 - the tag editor loads albums much faster than before; this is most visible when navigating to the next / previous album --------------------------------------------------------------------------- 16.06.2009 - 0.99.02.013 - Windows-only: new Boost Serialization library, compiled with multithreading support - Windows-only: new install script, so now the setup has a more modern look and allows the user to run the program when the install completes --------------------------------------------------------------------------- 14.06.2009 - 0.99.02.012 - added support for UTF8 in ID3V240 - added maximize button to most windows in Windows (but could not get this to work with Gnome) - removed "What's this" button from most windows - now the main window shows the session name if more than 1 session was defined - now the main window shows up maximized in Gnome and Windows if it was maximized when it was closed - changed documentation links to point to new site, at SourceForge - minor documentation improvements --------------------------------------------------------------------------- 06.06.2009 - 0.99.02.011 - added dependency to guarantee that SVG icons can be displayed on non-KDE desktops - fixed an assertion in "Sessions / Save as" - doc comment changes to prepare for moving to SourceForge --------------------------------------------------------------------------- 04.06.2009 - 0.99.02.010 - fixed a bug that could result in removal of audio data when using the "Remove inner non-audio" transformation - first Windows version - fixed incorrect handling of the option to keep a single image in an ID3V2 tag --------------------------------------------------------------------------- 03.06.2009 - 0.99.01.009 - added scripts for Ubuntu builds - made compilable on Windows - added some Windows-specific icons, to replace those that are displayed incorrectly - improved ColumnResizer - switched text in SVGs to "path", to avoid issues related to missing fonts - fixed Config / Files so it's no longer possible to only to uncheck all radio buttons - better handling of light background colors in the Notes table - fixed a bug that could result in erased files when the disk becomes full - change header / footer layout in the documentation --------------------------------------------------------------------------- 25.05.2009 - 0.99.0.008 - increased cell width for notes, to look OK with more fonts - added an #include so gcc 4.4 can compile the project - now using black instead of "selection" color for notes if the contrast with the background is too low - improved the workaround that is needed for multiline text, so now it can handle all fonts (previously a message used to show up telling the user to change the font) - added horizontal scrollbar to directory trees - install.sh now exits errors --------------------------------------------------------------------------- 22.05.2009 - 0.99.0.007 - first public version; most of the 1.0 features implemented and functional (what's left is an option to write ID3V2 tags "in place", to be used if the tag editor seems too slow; this may lead to data loss in cases of program / computer crash)MP3Diags-1.0.12.079/doc/0000755000175000001440000000000012040502153013221 5ustar ciobiusersMP3Diags-1.0.12.079/doc/arrow_right_small.png0000644000175000001440000000162011201741042017445 0ustar ciobiusersPNG  IHDRw=bKGD pHYs B(xtIME  6xPIDATHŖ]hg$7 .4}]qi7 F} +hЛ1 DAs3I/Um{N2ib&$cBSEXM!c&4i pyH)9onMO3 X;VH&S,, `,VCpr:B!/@Q6CJI"&`v*pG `0eZ@QMmj~%% *~B(TkB(Ѵz%}Ks`n=A L~GI*bPULM=8m%x-Jn>^D,2eKV`B[;򢪢$[]7x- TU y|fQuQ10< ?\7UufQ=檞ocӷ1*v .Gkk۱?30t#K1Mv-9+x`)冻"Eͼ˖r+ ,j:'1ՙKs| N&E`s6{%5d&b1L`ݶ=|=dֳb&(jDfmfK=>!O~?"Y2~֥iJK_ݻ?R%C=]Ur5U Q ~D__D 0\NfX,ei-%A"b]ߖp!A6kIENDB`MP3Diags-1.0.12.079/doc/004_screenshot01.html0000644000175000001440000000440212040502152017007 0ustar ciobiusers MP3 Diags - Screenshot 1
MP3 Diags
MP3Diags-1.0.12.079/doc/email.png0000444000175000001440000000317211677564071015045 0ustar ciobiusersPNG  IHDRa}sRGBbKGD pHYs  tIME  %.@z!iTXtCommentCreated with The GIMPmIDAThilTUVBŪ-4*XPT* Qj!j(D_1F SLQqJ-(E1Pp) ty~t޼addN2yn{(E)JQR(EQ0XLa;jiI(`&=,ʁ^%fIBzg6ͻXV<jg%~YL6ymL% )tC\ @& "|1ԾXJ㱵ߞ6^:0 ~K97+d.LKDʓB> rP7`EQr jCQBmH00Zj?hxfK*\;Z[Së{z-o4RSųsz9ӥW<[҃ZJj(?osP;G}3eOxL/ھX{l1_v"r`,OF(QXަĺ TIEJKMUJ'}vY_4\H`+2q~ z>gAiBv@GoV:K_ ɀ8ӗ縔%[ {ۭSUˀ* `d^X}ɯTx[!/2\ɏ~{ 2xBtOT'2se*}^yygK6yA~v]? gzM2Վru߂RRzפ;*"xDOU'&gX}'[S5IENDB`MP3Diags-1.0.12.079/doc/220_tag_editor_patterns.png0000644000175000001440000031251411477260241020375 0ustar ciobiusersPNG  IHDR8sRGBbKGD pHYsȥtIME 1 IDATxwx?[IS/lI.7l0F'S!@B$`ZB$ZBbƘbmؒ-Ke;,˒|瞻2|gyG"K~d @ sgI͗D>$rK @ 〰R|F\8c@ @ tc\.7nE-;v{-@ @ #NΈl6l6+&rI 389t:|TTQ[[EuU%"#I(@ 8ˏ: RR6@ /{x,󨪊l!9%dI%+'=z鬣%_Ȳ,2P @ fQ^^჏:-['##ngt1m^} 9%lRH'RSSKmm=e躁a$'з ̀ATVV@ uZ})(؋ÑPC1#/IqqqXHB`׋Fuq' k@ bb2)Lf4M# RSSM]}>Fìil$z@ nat 숈zGMn@zlr᭮!Ѐ$X,v)h z߿ݻٸqC0BV !|I WUqTWW7^e>+ ,z@ g=Obדbx*+u=H2skm~=mDVK8W1ӊ?zҏu oVZ?4K{ᇴm~=g:KVEQh^F8aoƜ3bXk&Loaɤ@ @#M~ O>Lp'C&; )PW %_C9v3p,_ cǎc/v 6+t)|n|nja_UUbA?];wPRRMe|;L:T*0 @ E磌ΌZ-;bumnw%, χ`й`MW+!}(;^;/F}S54HB=%%#n}k鷶φ #/W0l b6JL4m&MǪU[lמ4ˤI㨯wRW9JLLhbt[6:7|aup#NkXnc6[ M!Ia$/( ffgO}Afw@ @ auב^|qW^yFq8nѬ1{Q zOw@|ѝ|X|\~mh'##5׏aE5_~[i6I#D5afժ[li'#bp4͗r8M݇GkIP|k-k{240Iuo7e@ zCEEzf~6$()*o.f@  \M?W\q:f2bDN8Pbδ+No"(o"dǎ|jjm ( 'JVZc d@p:b2lؠ9啭]s?ZjnW7,S^SNL}z'^A ܠms[ V! m}^@\ UImN]]yy/l?Mkt:jޘ~V2i8_t}jb1ێ#E_;a#2uMc! 9V? D;="WZOIz 4.,H[khVE[vvg9F#M9o[vĄ m$,b OFϞ4ŋ>٧@e4MGӂ(Lv^ 1 ߇a#@ :_'&̌n3gϾm"- $&ڻP쯀!oa3!%ԫ?rg@sw8a-gw5ѽ1;[6,6=}?JfdYݻZ-dg!9%I%v(Qc ,"@ @~[cz~kY\ CA׭+Fcxcz&7#~{߽!ɆgABuhf'-? K%,3ơG+~úv4針/?OѶl}m.:rsHC%P4o85ذNx PxVkhkMk-珤"B5a6-`kj>daoFv*V=*b\iވ6ЍXyֵjO0Zmd&55ĤdOH@QBUUUY"L&cn@ LEEUL4'yXF֞:jGAVRX#]י?Ï |݆YOjb2x<\Hҍjߡ $C0ޡmx%"eG|>N,Zsekv*VyxhX7p:]=:G@K(@ A7ւY,fff`X0MlnOli#}u]̏='i;m{mۚ-;y\4 #h3h^eW:1Zk 4I.3$2@ q&RjβnOhMtvD싋lƏĭBn剉vl6Kǫݝȍ=@ ~b#tT+;zjBX,&9r(n@ @ h=Z:Wcԭ=ǘ<:E_-@ !IP_pi9 ٺ '@ /㈏C}@ @ ~d4MO>"W@ @ 8(**GE@ @B}@ @ @ @ ľ@ @ !@ @ /@ @}@ @ @ @ ľ@ @ !@ @ /@ @}@ @ ~֭;_N0Dev;$!IR˛fr՗3/v{ի'[@pLXf=Zx!!?Ɵ'NjGϞ=ٳgqcz;jβekpfN?dQh!2廷PVTBme :7~_EUqII:!; S__Sϙ3Yf`XX,fTUEQx^t]o{E׿>DG'<|Pf5>ɀnFBXP @?<_e"3~dx^^o3<ܹsINN[ɩb;.ϨQc=:I4)"(]ǀl[o*j3o`f1$;&@MiQ֭a邅:qg]Bz1헂,˭vZw0ӱPd¤,wM'Δ߇ L'ZG7oҚ֜lݺɓ'\/JPt7@ 3%腯{ bSj0 ]A8ֻi[{ρ?C%Q nSQQ'O> ."yU>SPY+^zvz4sq=0xN=ν޽{y'Mi0襲ˏk.8qbw2w\F)UTTKo:@u!*(…C>C 3VNNܗ_r }3@1lV s-+çM`D1:?X&d@/da$$$(j4$ܮ }~KKop-~Fu,Xݻ1 QF5)kHT}gPVJ~#Po83 &%]">Dup)拋0z4w`N:. ~3+U')#9Pgc9,zsȒȘ:.rl6Ǐ_TTqA>c,l6qf,3cǎffjQ Ky'_0o< rL /l2.IGaĈ!ˇBĤI"Ʊ>@޽ط?7驢!BV0%̘Im 6yCtZy3`V rz\t2Ej SBFLhpλ8'иYiN&>!Ɍ(hFAA>~k׮;nb?< ~Yg{e֭HD޽# mۃ; +6PH5ߡo#^I>jd~`= [~B[> Q{L8 Ti.؃,sAH15t|m >Mb Vm.rjsv/by;[n W^y&GO￿ZU;bf-E}:,(dZQDž_r%O?4ƍ;fbw[شiqqqMľNCQZ?D&{^֭.;4!˾a黟sI=bDLV A7/:kvQ-n:^|*矕P:ÇH|j ح/Lvo~ vJ% pz* YVL*gKa6͋`ۍ$'n_w iBJJ<$8x^rs;n7|'/<$Ok۶ 0q؇$I~.,rrzwivv{\E }]כ%%@HAMl͗K?$k9*0:ruX%^x1_~?Hvi],_M׀>5NSf: ăL t9a„^ܵO9Y< 䦹q:;F0 kV g.ehC5rrz__KC{UxdFah-<#\|TUUu)**bop=Lft Q"rY3:k=ry꩝x`22;ol}%c~Fjʯ;$mZ^k$$$0tR{q5!oVfGLɓ&`qhWy43dp   jx<.*[ -£G˲*d7t-I!?e *P05ˏБb50օ)'=~5')yt/mehD`ty" vП>}x .gٲO:M}^n>?,93n>>X/^]18'^d~7fr dҤ(ʡ'|=+8 9ںX- z^sOl;e^f՛Ⓒ[:uRJ\sgu:yqfV^bAm(*%l۶C?KXϐUa۶Z{lGO?=_,n u_M}}=@8Xzj6.Zm=|Mdg}z/$E"RԗJ_%u:TI$rd+1$ Uh~6nz<}rOݲGR<Ng/-b1'wĴK/5cOp2>˟/ԒBYyII$$$`PV^GJrbwEgE1\½b> \hZp0&#I`%Vh-Ļ rp= [rz"[\@ nb赻sXnU9o,-31x<9~(BҤI&A34{p{xC @sOb"xv#S3EM۠j!^_W Jkp{eZ1xN0 tGkJ8׍lSW=t~~|)/`oJt X,V^]7ߡ?_ƙg6H/첯:5ɓ;QbAD{46 s}XDs`9˖}dYrr#GkaS~C i> ۥ>͖9гifoRmoMTQhNC?W]f86q$ţMFE IDAT:y4%[7'gL>^9iȒ=wÃ{kM/&@$ TWW*Jd*'5]שqr{tO߼o͏ϰgϞա:MzkqT I $# YG|4#@"PߘaAYs[%mADCCf2ѣ6_3Vx}x t 4}w) ݘ$@ LJS<{p۵x+w7p9M" {(A31lFcAb҉sqDt~q\ZVo"=]TBU$n8'7WlgE#죩_?P}v&%fC.2` L5SWkXc.|A ?8my2efsp q˿$7wa|r[#- nW (KϚ53gvQcւ}>Vk\Ɨo'=S#0 l'0alO(}UR#Y:C\npo0lDrZrh[I<6}d_^ɲe_YgqmyiaE!992|$%%cU2{A3'=f>1D0l"b_un^˅" 8F^ 1@^&t3H`ȡ$"P@,5X 62(oJ? Ν i0$Uɧ;bI5;VM$LVOFV*&BBW1%+X٭1}V^Szo5_=/"s/:M \AjZ:%}v>s.{1yyhF\\<spYu?߼P&WX{aiZĽ! ͂sxz 2<%HqA?Yiqɬ9$ DeV^[+W〚Ԭ8j(t,Uu2cz?so}"POr{?97)v\H$!Ir(;0Ђ=LłZ0Ȫ(R2jP_G2b|+6Gj|lyuo[έ^μ7`X=Rdt]# x |^J;KKPeoi{^6۹fvOLs問Ud+'`Μq :+7f2gN-ljjjB "1uxc7Hx<^.]}ywo1j,0 {3r,@Kfz?-yƱc ~B&)nƒ8J/J*4ݿ㜉o@&Ȗ-xqݍݷGo75/0_Qe˛wÀ,GN` G^^.{}/y1ˣGyYz:VW8ٜ{`[[ru6.Rm=޽{y~T"k&*?RQQE]% {^,\0LQ^ꗶľx#b-q<ӏ5l^ϊCs著Xuf6lJ/_%_e!ޮoUkظ{g:Z08Eޘ*'t"> KX7?a!<^|>?w~?z+UՑ+RnL^^N.Z>I~ZkYk=f_##5i߅׵rN@~ =I2I=3b&^VƗȒ-;8}$P_A=e<߸QsZ]rYêsi}T/$H,KH}Ĉ Uu A t=kHJJwaxp/AGn yי:fM㇣2$nu MCkI$Z}17#L?sn9o;.Gc`SZdwc}]g])(TFӧ/j E S8psϽI&ҧOQU>Y~ʘgP͢%SS[ 7.m~㨪.!-7Ng[ k9kbOL࿿9wɯXc׍ᶋs׋yᥗЯ':[>{8,˭Xc-3T~gkc%\ o˵^uDJV YY-=w))fǑqwJ^!aÒxxZfsMyLd25 @8w06hhֻHz[kj~{tvzGwgۏW~:>Y}Δ9ͥ͜׫ !;hU@Q$sV|A pt-ځ tƌbf;x3z\. _m'77L)͘qy{TWWS\\B]]SQQ nbo8oߞJV&>`0E 7@B@HJH+3՞ɜ,`˫WQpp#'ds5i!HIKo{1)@g8{ hȚP2eIkh'aIHlto5- jhZ`0H*KcTpݍy֙"IiieEUCIY E'%dPl@@ksbgc〮 M#3wZfM=QO;m{2+VaC|8ƍ [|RPtznnӦWF `&ЫW*']pٳCAMjiMo5}A|T=1y%5&V} gCCMqo6p*qqITV@g'E7 ^XRݦ3x}Y1ܿ%LFˇqbIdd4ؽ={ 9o[tn7ntB)/tz].\ƍM߾}ػ={qFn{Hd07b#ύd~7Nwʔ 8#{sϝ )<8ni=_|q},\x2l2^y.9o 7%\rĺ%ڕ?ƛ)jD~gϟs=ܹsyꩧT]w|C~{1f͚+$ITVVrW_Esرcn_mlRU<:3+a8/GMcxgTIQAQ8Ş) C=: V /mܨ:tW_englM]{Ljj*L0OEcG!iifUWE]{ ?HDZZ?}piӨ? $AzPWW C8x\ ܋Y2cd=j#ʃqϏg$%f7g${62{Qs6~DBF**靇" j;7<9sn݋ӧvzwCb?y^diȲťyfh& /,hd="=,Z2c mСCygk\44sEj*&O /W7?.P@Ƌm&=RRP75O5GG#wmy6kEun~k~k P\Ra{Yf#Æ'Ԙu I327]!*: JR oSKhZ7 4u@@C5i횵׭yhGܡ;H83E/o:c<GX]`3&٬+7NooszC?4v撕`f3DyP[q\}Ӡ}-}7 4߆+pT瑓ӛyW\ή]4EE 8GNW=qx `TTӫW&'4AHHH{K;HNNnRHm}1" Lzz gCICL7v8)a}0zeʞsKew&4O$qg|f?3!fh:L2!cHdD*) P'K:2aA3}k:?1&#?e]#㛏dkW<`w:ľzN0G_n"up~hܾ(tMGBE:aPW[OMU-wQ rilcPv?jXUUʕ諯ϠA9_Êk8^rr2x晫ӟަ>Z#Fzi|:y= YHKCs%dffpFa7ٳp(+eӦV~zz-4 9{ֲh#g\jYJVT̖K >TLJr6 蓓 'pʨLY0'ZANF<=R,+YLLiK_$P|躁ngѢ%[&ک;e޼"22$/_ICC}si=cFFC O&ϩt*+صv$:ȂSӭT,)ᇷQYwK '8bN}<;ڻߞ򗐐 LrHHH`…wy-O:iӦC b*DŽT $$$dN>dlCexniuȲFQQոݵ|AJK ʊ &O>o-l1`o &㮻$ II mWm }}$gc1ѿXlV;EȲʔ.%3 >U% ׽~MnτHm TmspMfF `6hl!...~?z`{={F^x˗4% uu]W_ʕ<cX sdL^zi7ͦ a {`Տ5~w;N`޽$3gruבʭڡ6 㭯"m>%kZo>ZԷ&Jv괴Tn.h.o6m dž 8I &D//((NE߱ YLNNNߞJg34he}]^0t u\5A k"]1 H`;d4A 7t@h/IH lзLb`@ƥuXz']6AC ޕcw:n 1qqPR{Eo$ dI;<]fY%ɖ;c1$^R RBBH%j1`1&&[ջZ$jvt%ig)yidy䥝dXd8'}`k Zsϋ)5kKv3yDRR#';糮 2^y TUw (TWj y#e˖a;we˖-A}l>֌{?]vQSSsd.rѣ=-% FG5j<w?)--UU;:Ͱ1>nGO[lAUU=PT|/9)0rW3fkKńIhU/h$p{\ .˅pb;pUZZV=O:'4K2BY{]x^a " F>fO_jRFUHOYAբy}NiX IWA*ŃF#2E%4 k9gTj1kz#neNVIS}$ ^M3su:)),&رYEk@Bhٶm?#N}H]6CGe~WQ]w i:μ1 A򜵋|E_2cĥ .2 C7Y&pdT sܨT^<&,ѡW=5ƻխ8d URP$02:VBU]rx `K3C̳C ?ԴȃTU&;$%1uAt z2 yQy1z@P6e4Z-int>%F5KiF=n <|t,ޝtiF :]g?|0x` ^ye.K/m;/'')D,  _63{z# hhhhF`0G& _oaڴ1̛7+4cZyq=dĈaܳ7v_֬{%{fs-ʅ$P[~U)[3ml .3"AUq5 C,;~oy ;ozf0,X0fJJN%CRRÆ eڴ$''E4>˖Izjqݜ8q-[3mٝw}x< O>87p-,s usoAAAAa;Oַp57{'8~8/P1.mk)aיm4k׿ŭފ$IXV, fV.]ʒ%Kh4l6f3SxQIqy+gFy#dxKt=TC֐1ѣX#Lf#e([I8t`;%+f2 c Ȼ?Ė<(w^ј=Y]+T?maçc{H6U2n^6gk{vI^bQ/PQw./r!&ike}W{_:FшN]jд53ߓΌVm7!N-ˏ/8پ QdPR:oijkKݳ{]{gYY)}@Gn&"IN5'osϝd"!!Q`g^?^5S;#(/ECPVVƃ]wDeV7:?ILL[nw#zʢ"9i<\6V3GoCQ3(ƚ絥ó20,1yblYE؝Pu܈h3OjwƬ˲W_9_v{Xr.(B?sgvq:]x뭳VW Gk䦛9HN51tc 1QoZH ǃp`ٰv\.J/qM'ǎ˖-[غu+~vGII@^zcǎel߾EVBBK.eժUo:Il9]5o~pkKNR{ӮQN(Ѱ}v>Z!&r2 eѢKٳg'w+V2, uhk_Wl<*oٲ&gXU׸tf28s:] fJ҈Y fNuí>Yǻ/›ƒ:֣y $f  9lN^E1 Y!qJ:RYj4:US'v+˭…[mQ)r*Z FQTvॗqp矟˜99"cZDjF +JƆã6uh52@T34_x#yP9=_VOEhejVRg,)i{ʔ< N)/7V{/kg{Z]3rd:GTQSӊ(G^vK09/Mt,|yg- /$c2şaV45W3op<!>{FE3y<^ : _ˣ7aӁ:=6LɎ'-)>_䒋((ڵ먯o$ITUUx,_9s駟fΜbg?l>3Br*vDϞ9$0d,t:@ѡ|'i@u-,˅vp8pݨFd kuA O?ɓ'}cqϊ+klߎbA رcÆ cȐ!wŋt,_o~8p'OF%*yv^Gi&***Κou<55KqR~l52{ * oaG̊Kި ˛K|Z8~H~~O8|_ v,tqkظq7|ۨ#>> ND$n:%C*ꪟSVvf-V+S[ke׮STT|oEӒÎli`udgyG As%i__0&76tHl?n擝U"X@r_ԃ A}},8p±7.]?&%%p|V\jeժ3g8p!Cc"o-[jO Kj?ȀG˅(Egj7ko~u)m8N'Mbp\ޥ( Iq..'OÇ;裏vjkk&Mt|رc9p@{yW"FE1$#:BVJŇHĨcn/gثw˯hgsxٷii2hd-sunzrr3|0&O.:Ç璓͔)TTT*fYљLFy&岣՚;vIII\wb϶mؾ}?K69e1gά5IIIgF_yey:̒% )*IEE%tz~O3g6|ʨ?zf/-KUq+HZ \vilDN8{K MV Ke3(sSienCE3o`1ieeewrx۠˕3cƴNRQ;7W_=o{}]b2E%Ntt.=dyVjm6X\{߽{7|k_JN;Z<ơH:=P\hp!*ܽ_~Elg7{ArrFBEE9z26')++cԨa{#vV˥̦0ҊVy˹gDE8;~)/mFGۄwO|(b?r]G7Pr. (NWyrؖ@}K|<&*X-,]Ͼ2EW\M~É9JލzC>;FO>d[O14̟Mr2k 2rdnh4ȧ~ۦMY$T7p5sXr>M E&'sh,EE},sT:BK~@q 3in; ɓGPXOaa~ v'ꫯ^w")qZǾqv_m͙ؼ86Zlnn06bՖS\>=gd۟ųˊg7ۻ.:fstWUUiVN* ^ks~YZkشi IIfڴs~vSS3˗_Huq„|EOؙ?~.GJJ /r{[! rs-\|'}V…YQzJ}}%ii$$$b ۯnٲ>3y,XSXKSh:n\.---444`Z>mY9v֬YŸqcMAyhvۆf!$V'FTdFd%%,,2xh8EbKH/<94٫*vd|7ԡ(+-ʷm:ԩaj_1~BS'!* ‹p`OQ\-X oARrd|T_f O\\3fn Cc% cstYc.{th_>iG'^:&LC]Eeұ h{P!Cc#|1PY)ϧ"cb#s;EBkd -lNyn25jkeN#ǣFp0q9a=Aܩ[Fθן5u$%ɚEs/m?vS/rE:*,VN]Zj&f.f˧V ?pd3?MQ)>` ';vS͗ e,-[s. X`:]N,[_^})Veuѣyͷؾ}Gg+WQd޼c0X IDAT̜9/ɓ̝FC|W<Y*.\лBǬ婧ƨ RT5so㭷⭷o? 5U ȽP viii>8֭(7͸\0^f8 ="Nzu@Uנn:v`zw7y饗hhjPbߗSrX[X| A=a 55v-b3uXqF{k %*9TcG&fpKKɜ:C(~W> hx?h{y;o105 =/}9W*)Թ>!uU^T#*E=)UW]b `{#4N{(vG2@$RvNŸR8Fs<_`yXx,D@Jk֔SS0cFFq{<ؚٰs='>\ufN)lrsr\l!{L:GQ$'VRURO|̑)y=8}ESu+i98\v aynȎSOn7i?Ռެǒ`_uL;<Я>@BlFGU+ۏ͍jjjYm_w=fzzkYsA={th߄2R( [n=Z^^6lQԡYW^?=ygf`]߻f{Ԟl?λF_Uݫ_zxȜ>Qj(GY6Wy^[WoݿV~GwF6 pLZ9UUeU Ylr*iəLFK7Q IH/$%5?>/5&)ڄ ?Ճwd]&ȍx^q{֬K/_͛;o4ٰa}Opq^~娉ٚ_r%7p$裏_AFߗh'C=c梪*-<#&w7pd+UUm%6I7QRF^~ 44sa{.$kjIM5nTjkX&܆'WU¢Ee E$%˚5rWߵwYtJ^BƔl'̘trJWQ-v __ î RRIG'30McH+WBx3} XJsC HgC`ONdҤLIEE `Jm>u/??!cAXqb { \lݷI1SS]{oС 4٨wl 9nNUYvɆt7Żɠ`)Yyo뼷0if^4͌Nͷ xO>_2jX]x-NZ9[naqUNoĉa1Bm)ZZYlz+o/IUU%%ٽ{7{aϞ=w^illy:eٻFN#kPY쭈-N5$%c~Y;BcS_t H Ǖ5$-iZu62dPq):Oʌfzfdh|+8".eWS9+hkC+GeM^3ŝ:|0Ym/km2:wCh`0 oC9Βh2aCjmi^*HÉIW M);k/՗jsgLJ ]q8@BBBDC Q.מ;{쨆_XXm? С\ۍtpߺ^[G΁!+Dj߼hsG;cPYI防%g"bޗtb&>^}v?S>#$j~ZwI<&thM1*TM\֭IHgʔI QNZɓQ(a??O8NyhA@TUV֮=EK /dҤT!>?J$QB\RRE&".B]G%)I?g*TWCs]ʎ/x~s\CR l6_|QEqqYYf,JZ8B Ap(ؑ$HK3! TUf>ye0~|2Zp@ vdY"=(N/5n>>…f,F@ -MM.22Lb'~@(M|Inʼy,S@ }46:ijrahIK3@}@ fWrh3 \xPt"c@ )NZ[iIHcB A7* ][̝;1ceѐ @ [nZ.Bbx1!b_ I+\pĉ@ Sۭ҆fb}Agzl_}cJDN ðj*V}+F A6%XQ(e0rd.3fL;&nj!n6l# 0|^@TTPjzyy&Ӊ~@==mB_$vM4 A_ټY,Kdd4PUUK}qa] u_**$DC))EE9 2_"VZwb;vswElKUU%+}JK[vpdΜL~%7] +j0@߁\MUU6n㏿`P\pИNȑ=+b8H( <* A_æMUlRMrE6̌*|-w@خ(j~r6[Jk!CL$%#W3b-DnKoV>Z; f3cF:8'E lW0˪@߁\ryw$'뉏t _}18/*ٴT#%# 'E lW ľ_Ptz(*&,@  ΉZUJc3ҙ:5 ^#2G ALpxn`و}A@rs }~^Ru 2\۳|y% ffa)9N!yv$'|l趺]yJY v⫬CWP+/$vs,ڌ4zЖVZEEwDDʎe&+!QݖKH8bDQC=UU9v>*juseLF#mѨ+my[xVwoǼ &N]'|f_ucy*3vP@/`u(>'mYח %b! 1 J[Szz4L[4]&ľ ˱cB {|E50t .$9Yf(ayǎn4Ol\ՃOBόQޯ ַgnˢm Pbw/{3mRScމ٬%9Y(=N[,XeohkB߀,5G6/<aw$טO[ r*:@j%_y 羬ϡ_ d<Z;=񺨧_E[/Hooٳ,8rdw5G9]ѣw^ / zp>v,( 7cp:9$qȮle>ȞC#cS֢ uWC^ohU4='|>;*޵ֱ_W ' iؓd$r);QUd=FT|c­GlpL%ܺnۧb_k>G _ qJ˛{0?AJ.֯21" kţcm'ZSX[ ?8l7/}ū1>8[ӛ7!gbGHr %N5#6Me Ed=zL:ڮPo=)`#R|%P:thgDϟ^O:=8?5n] ax$ɿmM8N:]paחu!~pn@/Xp۫`vzS$m.jjh4Ft:gtm Mwb?P7~>R(@}Am3 wD$HlK]&֭s3Ӣ*cLTۻ߶Wx ?b{B]나?p~ǿ}n@? &OcA[ɓ@ݳõHb?D3mN 2Fd9ܾPd뿯0-'_zR_>+pB#~!u̘IBWx?Al!)(XgUJ|r g@oFSւcl}OgǂO $mऱх٬%5UF#o\_ Mf4?65<#kݖCo,2 'tO8p`Y m=o`d஻D$}qvW nY X*PzO۲P9L<]H![IlI<ط=ddILu`ۇ`m-QʧplmEZoD!8 ;wUBNO}q"_v] uP]=v/!A٬Lama,@!jkk__IES93 AS?#|]~ETr)1}}RP0BP/ۭcG=_~YC\36O@ ev>@FQ8۷_i}1/bTUY*;3gqrD ~Y}H⢺ځV+n@mzb_@ pvc˖:u,X0LcLD +oltˤe!B AhWVXz'\ԩ)11/|]~EMWc7&D_+|e?Xe6@ D8 }VɦM$$h=;xVH(w@خ ʪ@߁\;&]1<*WO1!'MoDN4 A$}@Mڵ:e =TTl>Q]AlU`a6 :ll9 -,K#W/KƳdɬc?|.F_MK}I+w/a(zLolk_.\~|Ag?BFInj߱c7WĎRUI@ 1G4{'\}.3f@ CUؽL&8E] b@$EHXeedAiiqjU972|+FjAd@ ~꡶{^FN ^zIC(Ig:W\:]=I[0'm`/dZXk(㞥mtyAUUmd8 e4ߤWz+obx8 IDAT.PN$'Lؓ8Z\{ke>%5:k]448FGŸD*"鳢yf?Qh5있p,P݈|86+ĪU9̄ \z~?߽@P͸nn9pYeݳI@f<#a?=t}YocU,bzfc$-.n># 6^~k7HׅXv,UTXH`4٬뺮5k==+]>=[w.޽)dı n$m3 >GГ DCc]$S2Z,٩>MMNV7YY&m{Y[] /ľ/!3"uOOѓmR@o5Ҷ N9q:RR kCQBGM߿MQ'seØ7/Q#2F Aj;NBRG$b_ O &+ٸ4#W_="cb4D }˥PYBQTRS b@C ľ@0km;{z'K2{vzh@ ۾xY)v С'lTKV&3$2F CU{N'Lد,1W >g3cFh@  TUCMYCF1cIoE4b&g墄Aջ^֬cJ5 f% r YV˅] @AQľ8 GG '%\%JH K.zqq/X W^˽'+܏ҷ f$E lW_@,z?.DQN3bǎ]HRdFTU_bQlZZ\|a9[֒kal22"c@  0P_THO7/$ EQ"VYY(@UUٿw-jpᅙLV+ @ Xnjk]*deXo]gtKw /h{Vǿc-Oрdl/&5pZG{=ڛi}UˢEm]_PGeѸ6ۅ@K:g ZIb?'ӵ'@Yw 7k y tl<|U ?Vmd˖w4".!9Gb+}7aSXi'>%\?Ƶ. &ḩ-k]Vi1;agVWbf&~?Aao }X#⪗#6laN/O f~^xl, }vׯlDXk8FJ7(E~`aN؅}"v6\/zK O8O6"Oؑ\,8wQU0-1(72r?]xB_j*5+~ΐkEٳ "x.ȯ6a{,n]]~x<.+ FGGp%B|'Zzs:5k«z[/Y vWb0[կ1<܁^x饯;ĕkչ^תJJ%ZQZy4Z%gS5a:AOcj/'dJzJH<Az{p9E>o#‚bn J.2}xԼ0PzE %aAl/<N܍k Fd;zm~5|%qɅagXٰq6%eGvb\f5,ʺ,w""VWH& a5|@b؟Tx| ~{}N܃   "VW3fKص˃6'rgƱ]±cÝd  O,`}=RGk--^2 Ab ')ҥ4.\H`߾~Ҩ>AAاISP( hiq#>Az5_z lO<1j-AAdJXYIv >@H$d3ѤRE4nah'NFG CADӰZ~^x4A4H쏍Ƌ/4acc111N"&BDLMeWFG\er:مK4WT.X~DQW_e03 ypWwO~"LFq)A4[[y|鯱4~?~1|;ݎiܪ;UG&]*DC|uʤmQ.P~b*8n Ab;v?=MUOy!D_tO?c!E/3<9 A197ߜ(x(/HOA! dz(x z}b8 LZ\\"D__NCǞ:WD3yz"J^x< CFgf)XFM5\\5甆e^.ci4@6sY_̙)${SÈDh~TgQ\Nteaz6RzwUzGV>f{OFAV[[tvr)WZfKz0 ZUDRAmX-ح/yc)|"~&aN< N ~כ+w:njaTd=v:&LBVx/T)|YRͪO~n OCm,"ZZ!&CC_5tkMB%zFkJgLay9/xbA|G˚Y5Jv'Ik }[֌KoWrXb,3ĭ4RvnA[[ gC4؟|Mr_mš<oukTGwo è3ֈld*b;z@X>b$Cce%RI@OOX d‚b_y qӯ'{J?,XXƙ3Sx챽TnI_ّ˕tuk;CFGGp%lr;6-畞{Un'ҍ;m> xիH&Glu~70uήZݑWZXkBW{^zasF|R+xψt֮]k]chU[9A$ת+śvmM*UD"Fww^KS9sR؟ѱ;MM]d&`*.IВ-ySfQl$C>_;̡3c7S圝:zm~~Z7kj*.MX3LOy&:EkxYie][}x< B!/zz"p]}@ma $77˓H&߻?^ CAD}`}=ZZ VAd%3e B__ CADVWfKnGGG"H[ n||zSfK^|8e? V)eP(ho"QAXt^?_`+ߏ  @Pc'`KF!!2,a$DQĕ+8{*J%Gr4  r\.}}Qa?6v/ӄ8y @&c||/c.?zzo]61qvqz.]ºrkw0;e/67P(&~T W9Ӓ?fڶll[[lTbgX-3'R* XYIT=5>K#}&b` `nn_X Fٞh>DH[ K@[ 1BϦmq&aN4Ӌw%aY(\[fĹfkL>_6ea>}"د;'gAK܂BHQ*HtP F,%a|:u[Lkkx<.݂@C到<\ǚF v%3*:r:s\.>J&RDC*C2GGk,9ns;33,w9;ȥE~agXXkyY',3HX}2 r2-=z0m>{5FN:+WY}ԤYZZ' ?M]+%F:Zr*2);Tv5?yer̲>12=':* 3ۥz;ľn?4tn CC1< ~-]˄:WY-{hnC*Նvx<%tt"șhUshoTkwYT( J[G}f<XһJN""Z[) EQ{:M,[q-Z_8(F lFD<ރrه5&hE0˸CO*CZmMSXfO|if[[]p 4A&S@+ۃ}$g.GF_ZBW5%kQ=R/7M^}xshx9 Apak1x˛9^mFvUo T6¿Zmmvl*QI$`i)BGgg--~2 C6##>72r?Gb^iܔVJ^BԺO]=xIKW:h>e H$^&Ғ%fwXyJ\F;KMmղ/A()FC=uZb e,-z{#J>hn ٿzccݯR%⚥خ^h'GrV,x)llOAp!@* /5|C;N,UHvszRqɥ V4mGD zSF_K]chUl8A$K}Y@|圕)d&+cc# COO~GWzڠ>SZ]JW{^I|6Sfو8|p3g>_QQ#S ra$=7bDIp8NYsWZW\z%rVaM\]lldewAb_؟T8~n7bяRQк}) IDATBF2ىt:@ 5xE2 AAD67s"' :M>>P(Q(pwBH&;!.bDT4U B b}=bpEoZNxC(nhhsߎym)aD>AՋQVVdػ7ft ?Aχ ntB3r$ݷGAA(\Ax{ѨBXO' d2Y&a!򌁸\8NDϻH,`sl`kxh>AA "B0%cc/1Ma| h"{/?ٹ?ɣ,:Aĕ+_,#gE$neG#Tv jʅ˯~eF/.H!p;~Ző#C "BYB'f )w ~OŬMLȑÎNمKXWLmʯ~eWǏu;OdW?o'6/DK.m&!"^xgx9rpvjK+MT{8"x^ xp9;6C:AA g+>"`V8 L3Į]Q]) ۨt>douN|&f[++æ`C);;nԦ QikWnvnTbvit[',2L݄b`]&MPǴ #Y ύ={Z󹱾A2GTeIYϯVFWϋ =iZ^N'1;}o??݁>F 2,6+ }Y9N[IzX)J{!feiz5K`WJ%KK) <ۃD|ˑ_$u+YRXjfx 1bơCΚ#="?/9V?N<}b/7_@(XR>" B2Y]J 2VVEQba ov5a) V)HTR󿽾"<ΰ7z{#z]>#+q+KWRU^'u "Wj]x7lAE$͖ yuM̚oToC5(vf&)lld綐] V{޵Rsa}Ӛ"~wyw_ gH04ƴ,XsΨZ""~u;w \ >{<^D;}r떍NXIi3-a;tSxqh'?ͪHVe͖gO+::1v֢wZ%"uq5 jrq?V?׳X^NAĆK hg2Ο?_ž=8yzz–47"-rSq7NJۈQ~=v4J4s]kWFJu }jFghm bWAsc^$y^O;u\riөW _z\ӯ/V0;rYн:Nk\j﫵{>JˆTWq2._ǃkʴn^Ȫ[v9v׵*9SJJ%Эz6W9ۙQX(`jߠ^5N0zhƳ\>ɿvmrJ3P(cy9 A8lZHEqnj"NdrakHNziI4ȅY/ig-af&\tכgfm'k4i-{rloq:Q6NNhOj+֩ jg5KRiMZ;<QFIoZ5nZG#ˣֺ@m),ˆ]yVYie]\,\.==af1'Hѱ`h`C8PnIREUӈ""j z岀GG06 ֓AAa{,^7ª>M =ucq1d2ݻ[ rZ9am<Ν+W6p`'ߏX^Ӡ)A泹F==a4B'X QL汱ռʈs.ׯqGqp!O-Rbzz"" q L汸 '4;D]&G a  tVWfK >GD"L&$p8D1 v-7(xH5+ /V7pFG;" `@,`u5BG{{ xŗ&ll0&&C&Nv'P,_`ub2LL* !7DOL\v? AeƩ\8E;e| 25Wo4 i<}8ry2ff>o =80M xi\& ~GnC8OLȑÎNمKXWLmʯ~R Sַ 5EN~jؼa"/]ӧg6'"^xgx9rl yg'4)kkUm;O#a  ]J^ }}xn2 acqIXKq9ՂX,x<A]ArY.wfq Z}  FD"D"p؇<)VZTM\pӛw5a2A.,$J%~GդU~:zkI@62zl~ x!<>ކxl9aSPm?+QIXKMϕRYm'}qՋ_KʍZ]*uX#lovif[fvhvbdzH hi+ =*J|-_I8777iЗtrԈF=bQ.mmՂ?^L|Yد"Nkն-jQ,xY,Z[8qb;je;VKxLsuV{ z9ѮGvOϭVAcu*mZ]+ bc#L(ZZj<>3:8xW870pcwC!/07Tրf!-b&[8sf YZ69΋ߟïo_"o=N)=[>3QgE{պN9%aVC*MZӪTX{2^%JX*Qf<*gX',l*>kh@>_6e}}_<2{aO oԈn^vݻҴ1RMgW:]}{-an~ƾAz|5jH]kYJjt81W޽vm^[QV[aj]Dj 7j걗t* St[-ieQ\'k:*݈1>z\Oa|Xl48w'z9Fb7b֗ jA&=FޝoFgg33IZF ʗJ^+?WGw8p`7J-dƕi]]+%ڭO9QmD|z9a˭CVzUmof|Ja">3L3JA__>^ӗ%;U0v~/o9EbzJX5L]~SSw|^l˟}:v5".%Sݬ>Aح>Q,4s"AȞd2~7:;Cp]C~b/Q}OԎF]`+nz!f <[o/Vl?Ϩn_pZ֌ҨfZB_MN75jV$H- ̬HV@D$9ED~tt@[Fb}ݠώ_yqVx.Qlmţts;j%:?>N$2"ſ8G(6^*qYnF:MJ)pNߙLꙭc>ȯ NDGG1u>Q-YAngq"GkMqV2YT;Z>\Q<pCm޵+M)gQfVwGط O?=_r㕻FfJ;kTp~GZXk'mkl&ZŤiF[zy+#4-+kj/'d/ TndkdLTB>_=5HEqnjnUoYүDOM.ePAz ?G{{Dgμ'F~>қw-`aOV0>|?7 }5GYڜ]VK7J1tk+y 4  =ϣRM:3fzU;`VZYfP(ce% Q?~#H5 &x8Cwwa,-03DqV~W{pb2 AAreeq@WW؄f_8Z[ص"7d 8&t /V+WGС.ų7 _fAؒtx< ׍_@"#0ld'mx\IbkVuJdzT>؇#GFȱAب&OړD"x`|0 } [mtW3oeJ}+; ׷eneQu'̨sNl(H$rH$r}qVގk4M:楅{@knmmo!y^l^/#668u}t~=GkuvI'vNz4(ZPuĩ]2#9]W lnJz{zV?k99q-ȷ;`vZsjҦFvIJeO&/o⣏ƩSkW C8ńU;jFfBirD!"2ZZhmTZ]Я'8pIGuZv~Kx{ɶa;?BǍ&Zײw3=$R|~xwSsxJtTizv<.v0m{Bo>Fy *>?khJcy9| "y1|}0rkͭ|i [Z42;32$O?/17={ZUWIkDIXɕf#)⭷nϗgO+N:xyQT_kĈTZk:̘y5MWߩggz~e<hȇP౴ϋ0J0bOľKzbY r}~e>+Iƾ}mH"H$ržڴɗְ|1b7DQիq93|'7KF0vt4uwhwN6zZK6YN:B-gfq*L++i\vjaU$/rio#ØHeg+vs"ce%xQƒNq |*ӣaYB\at;=TM|J~A<¬25n;./ؐJov' M>$/"̘o̲Ie]]!ttqW4:LlE78{*x^c#x>K~I;MF֔IҨ?F }#`AP=g2O$vtu_FX6׮}jc>59 .'Xl2RS >:;Cؽss[(i3/R%WU b2Lui(ku>|j3グ߅.ٕ[;g]@4GGGzF##Gt+KEªK6#!LZD''r@Vw:FޝC_i.<(9$ӎ`Fnsz?ͥd}T\ri޵r%Scy2 {jFW'ֺѪuH@f:TNy++iREF=XUr$-+T᜚t(Vi:Xl@%Mj>_`+|>7z9ؿnJӡVV]*b x뭛qct੧w\W9OjëZ.^M[tjϔcgZMSz2`DgNe]nYټrYr"j͋a''/hdf)^ {R ED|}* IDAT*^{ر8t9Dz7AƑϗ AٽpGF!LÔOvw]鉠ŏx<4D h=,Μ?ZZd[/w Xan2 AbɂNtv6Q*=d7 .\XƛoNuGq=]4O*?AAuE$9xntw'ðizG"$r2bgk1?>=:hAA4x<,Azzpi00fCDLIXpAADYlm@ww1_I"H쏍Ƌ/4acc111Nj04"\쥦_HLő#C FEB8{U<c P,ϯڵ%xq9rѢ#Tv kIq٣-sB5ӯJJ⋏!ٍcǎbϞ֦YOV[F_tO?L^{h8CggXׯ'B,"`qqr9;?1B  <[˜dT) #DXw`rrss[(x &/wgshoAAP(X_B |>?6G8N2Yɝ̼{ֲŽF}ػ703D&SD$c7+ܼ_ ~Cx=MрT~VYVtήy53z>e2+u'W!F)vxvefvhN&SDYDN@__Ր;Gç-qҦ4Tvb$=,%IS'ej.؁[x\)$Hk0;{s:f',) DžVD~Lh Qx啫(x<0~x- JTv\I4KfVAEeg{M\R"f Z#jU8P& !]+ʗrq鉠=4"^Wͼ(9toϗgO N؏.btd:R;uIQ^ic'SFɤdƋQ-~4L+ S:Em|\X}jEgɔ00Њ0Y)yE/ IJdĚҥz)ͣJ=neբ_Xr(brrgNX5}p]d 6]+a븩MYS֩eR|kgz~ee}bd{OrYj|A-B^-o {ǹ7b"ԆwM8!fk gֺ. ``S˪Pzfk^˗װNEGKu SeͬkD{RkR/u̚ymD\z5ju,/'_VKeIJ<3(ttVvh_#LaLO_}wG,=ZGYg)C!/kann T_}sAE=:Eks77UЌNm%Rh¾4:I4c}aSf.ϗ==a! /%piVH1gO D67s8w.;6X,@N_)fQ:Zs8AX\O/٤RE,/veg`WۢsrǤ-k7@wvsؽmm9,/pmT xqvsxQ{o7b=:X+<5VmifV7#gqWi#? Ŵ9F> }m§e>%Mկ7_jWz^PhOS?5ucwhȧs8Ϋ=3KK7/>|KK)Yqȩ>t@03hGΈkpi͟ԆWj62]iF}fuQ~ٯֽ93esFVeE]6znfnflތu H$rd" w$5 $F8@+`aal΢ĝepU,,l?"AAXrYJ|mmAD~2  Y&~wua~~ y2 g-f3j#AAXbr pS.$H7طzo_ ,-6+z]r >؇Glg[2} .vr"R a rq닢#"<5_j;N<{cd  Js{~B[' d2l3- _O`aaEab ?,,l?cQ}  ["zzW&-_bØ'Yd QLP(/a߾D$BYR, x$|s0͛PLL\5!d.aƩ\8ZA;/Lcy9@͛ӺwwRBfb(9El 7n|>@`pdz:qxك?|)m<11#G;Z89d.am_2).{eN(fUL~ _E__O=_/9?^@>{Q2 AA (Q(F{{B4 f#A&a-..g,a׮(sXYICD\I^DQ H&8rd.x AA(x,.|v/H>G8@38vճ *"w:l 33I 冈}+HM9zv_Oܹk(x=:o}k7ZsLح6Om`5F)J{9hQm]^Zlx< Dž!34|Fb<+w8x1>Bǿak+V\SfKFM.tHxi\v<(:;AwXn N?$ye2dۂ'=;;&WOP'FQE Dž_Fo^4WMWM8▊Ciz>7xի(yC#oLGQQ^Wۨ4ݩW:\igXj˜0YU|$~>YQgU@K}}\CGb4z䵊_5j`Z[m:Ԇ>aUh<.ӂx|Mo _j][kʖ:RELLL5 έ,:NʏtzS}Ub7aW6z*T:NWnN?eEMZWkYf>,}Է,#@أ}jF ؽ!C)}긔<<)OIYيՋ#[š/:4R/wHkIsJ^+W11q<(~whT_ojgaZzJv;@o^AkZy3?KoT elYfg2:;C=re5"TLMO_-w~nfjfR/7Hc{{!| 3XvVx啫oq=]8qb uYB\jGƝf)7:,,8DctK3m BuJ66y!>!<ׯyqnoɍ.ZJ-"o=Pmg2.^\srq8~|? ZS&J4aN ˩,784f_$ 3JXZJA~45X ٠Oj=UN-יF 65][kCa/Mx<.,,l0Yr!̙)\8ztѨj%&DYgߪFIM6 SS֕ī4m4o.j}mOTЧvEei]mn իnWdW PW޴vyg\xr^zƅ Wv/ O|ȕZ?_oD$Ï~tvҨoZr%#Jݫ@ZXk'm3|ĺ\ jɓP}= U`gӊu۲,zE,eM.sJY6󿹙zQC>r0$u}|j!ӴNO h݀N:#6k nQ<x^PG=6QU&2L |rj$sNϟԔp5iKiFN!˲fS3%.ϴu;=gEYC=of=Җox9D">tw 잚@>s!>9yA& q`׮\$J%ްJN\_/⭷n"ط CAaSAfl Qi&pL[揰XQE?wߝA{{N` A hZ'ATǰX䱼B$'L.F n sci)d2OF6ΜFA|Y  ;˕G ^LDa6H$d36ucp0?hOP( gF%AA؜y;ݣ!bl0^|% ;qř-bm_%٘;ڙ<\zN++xmF+e jʅo#Í9ܼI >x6Fq)9th oq7XlO8|'}8nӎˣ.Ӗ~\Fa3UZ}n7?4깵Ck8ĺj 3Qg}*JOuR 8Qc9->ČgCi|$>YAzz"x\ٞ>!a#7o!_O+묧׫44r6*WUg9NbJ \_R~I$"r~n7g9Q}Ic^T_kĈTZk:̚$=գ,FKMo\Rhچyee Yy >5EQFx#.k,a!Y]@0׳fE\wo i~q*YJ(Wbf&ñc#F}Tt2uwhoD^zYYeThɌk#[Gyn(vVLeƎ4R"2^56k^ӂp؋4HS>l ~ Ǐh'AkD\Z6 2HB [(M̶X#1YrYZBa' f p"z{#ai)O|pاnB:lzr[wS4ߠ_{ƉkW   S,X^NT!OXfCDLIXpc1?ط(G"Ar]kbхc7*E_~kϻqQE00j9hQ]*}uʤі9.]Z}Ѩ6'ؿt2N~E/3<9N\"bvv y3~:]oL/Vwo 'O@ww AAEd[[i'~r08 0 kqqgKoerȶWJϳ6OS[gCKOssA[%| NOb˖V>_勤p$ kj#y|ձlRyc1R}'JY ~*TKjNZ}!-^x|]kυ|_L^O3+jn/=M}ɕ@q:wo#K4{G7bLBU1_y])μ.5l\huYLy>xZJS|:}:mTZ|2Bבoֳ|z1iȜV̼iMMz,^y"z%Wa6kwfVU)3o^|{5:-SLyjuJJ%X u~enwOf햪,TObx'<)٬vTƼ}T?XeJ$$\a\dywkآ[ݓȧoB,.{٦U /i{ӟ(h)x<.׿{0a!4AnJksm+_=PBTaVc LW\S\# d2ˠiTOG4| 8{;c_~)l:+5^sBYLg|ǯ1z%gׯqe\a<ntj=V"}R_ȶ*Y.vzWR_g%OqLs'js7+mĦDDn{f찙B#auj4*[k0?Fs]]$cp$سgVj872 DD<Mdx<BqttXlL`J@W--F,.F13(JP룙,˸|كW^/'}uCS}"""Je,,hn6IL=B"2M,:':;-XΊ>Dpo}'OΠ <._C """""Ea2اw؊_EcV=z%TǼ$dًp8?Gw2.2FG#O04dF0xo}ZeG܉Xweuo5MϦL&ĉ7r}HxuWcc ձp8P[q}EO~ _| &''18c7R}j<ֆ y/ĺK]V-k[rzuOh _߉'z`ԩxSs YK?ϳNFooF-p5K3gp0DQo¶m 􉈈@ nwZmmfG5MP @$E555͒i*N+V\0Ce{,8r .]raV< v he^o@f&Gk#OM[ґ\ldW3*췷p06t(C*JϜѣWөofqG Axː>1˿,цJo/q1fy^+ۦ-eՏ:ñw$I|~ mmfް{'W45PۻnnR-4^̀ZZ…yK͝*X\Q\7ax \?̊=s:-(|&V7 IBrzn+uZ.T[2)av6H$VZZ5k$Z׷`|-w+݀k,!d\HSfqh4*<5Zj"ZK~< j ˯RKՎ  QSG Y`l-ߏ]s:/OU;Oo3s۹T+׺sm7z-[:KM^_@SG?%zj@pxzcG{l,yT[B?ZS:o[HZK]uU<]'1\\)uMQ1ߧJh4 DQB{Fvu Q'׮)/f|*{:3gk~_LVZW>P}>5bF"I,.FzԫE+5O7 jMfJ|)bӚ.o+ܭ2V|B8th~ՇĢtJygyskM&JG9^Wc[# F2סW (+]gjB:.btl^9O[ yRm.WH]wZL/u묘 u?~{,?ıc`33/nka[+_JK]`}Iv1x9qx"0hoڈM,`ӦmrLQ~Һv M)D^Ts)1tuY16Uڕej*/af&'ᙁNulM&b[6Z(q1TʺY,c9C~պͧ'=^0GgN3SͫX}:Kmڴ /ιL!~y_LZy:?[][`XJU\j¾}CiYNu-%;׼:dc)fy0_տJiú߫Tɤ ZZ WydppFFNi>_{:Sb΋rY޻"~oO_K9]ǽ8p`Q<<@ߪvBsg52ksm+_O̎],JPN/\SغAr߫|C˖:i]"!C%8Ui2{eA5 \ >Y6m M{BԺ/_ V:W,݂Mz󡜣TK4;ᣏÂgٌ.+ut܈?Ztޖb|*ɻR֕'.[캋\h~NcVu::>zwVZ .Kba! ho7kn0دX7}%Tp8Lav6QѬ^3W%13[=Q 㘝 Bi^>URiA8hr$p5| mسgmmfelzf>$" )]/o$"Zz._WG&p]Py&"""RoEbmmfO SѨņ jU J:8|s_|1&3V T %Ԥa>(A(Vd]f3h֭l ``ie.>|G݈;S}""""Meχ&a`)v;EфرG` 5YqZ*U>6<&ջ+ 8p`=ol ;z,NĺK( X+U>G$$yg5-˧?5ƍn)8Cx衻6l$'pP4߸ Wbdcmm蠠BTeJ۪߲F,ׅz "s3zj &ޯk&?u,^| :^'M-rBq+YњpΕ\C@Ukn%),W-]%5BH +@ VSM WJimR ,7/ۻy s݀VOA p:Mhi1aj*Q qT ~}wyfG~\j.CAWXʿP {UI 33ADI8f47X~_] Ȝg1[dP-?3M7>\])}>gi֗m;v džX, t:cr-'Sx <>կskM6.:-9rLG_)em:engy^d7>ROsm'W}.%ϩ6rlOJ9:(Q}ojELMp:MZuW><>֮5vM|1 "-_o,j5̣b^%79J,chju7&&|+nr ˘G7b׮UVb.5]oy_tT)rtd6ui*iv9eO},+IuZJSa,&b~>A05\+}^=Wt Wlbߟ_WB_ȍtzcmzZ >FrHrKK$D|u8V}tc1wf7WоZrXK*d=losƶ=Gs\{l:]Uve'rojN/`ٛ$--Wl֗ysZMM+t\t<ҏ]TbR:$}/?6j)NWP!yphk3ݰ{,C2O- W |2K^nB$CV.q$>:x-XΣ/[jadQB{W'-0h㵑}J],.Faaa > V|y /ԖBןw9|'VB461׾փo|z=7EJftXHBTr:F 0 r-Swi5H |( p85;,]U?8## ^6W[hl)Պ`۩Ql|V~Ec_`b|,ܢ$}w ~8v BgG0 |M V\_k[Ҙ'JJdvԻbޗZ/k+ W;Jթrb_$Y`yG)NzZeLJXXvτfc]\d됶q+uFWnGz:+s)qNVZFKɳ`p?G7*ի8p`~ ? _jOMuB]#Wu~U Vu[6+m'RC2+*1?1]J+b%֩9߁WwZiU.j??B"!EW `_`ҥ/nҥ/~l`ѨkA__ԇBqU|mػwf8-Mbn.Yt31اd6[_Kj`03c\:ۿȈ #IGq=T"Zr65%""qѨeeO yׯLJ7+M o97cϞ!8&V4"* /-.F17^AgT7RtvZ%16E,&.Iq<^}uɤ߄;;VLDDDD5OX,:9Ş{<BaEe6lkj2`Ӧ5LN Kׯ… 9jT""""? Cp8L im;vl/ ۱c+=jPPIJ8t0zz %Ϟ ?F"曧 ѳ?;.U^4`U\ Ǐ{*vX>uv1WΝ۱svKAI YDB{oa!c~n?,?""""Zۂ8>yvz<2cj⃲iUT:;p:Mb@!gxQtj< 6oneODDDDeF 0Y@ӌp8I? C8thcc^yg'͍%ODDDD 13FBgz=#D6 IDAT!phe |ǎ]Ţ޽CشJDDDDecpjhk3s=bOT IPLL ^vf&13}u㡇6yMe|Q1O өcԔ.WaC7"N{و}~JDDDDe$ aq8FK(bOTZ@w  or҇Dpx>GEDDDDH&%LO ln``  (ǽH&w&;cKO~z6f&)"0;(촠L!Djj24#Kbrҏx\;ի8xp@ w׾N͌$""""EDI̤hd RbOT4E&)?DϦm3lFWHDDDDDp#P`BWcz;t:5X\w|܋#G c׮.BDDDD zhm5zBUM Bo/N୷㏧acmif|#p8P2}+J@W&|1 7,e7F0Cm=]V""""R$x"Zp8Lvӄh4-=B ;v Oϡ<|ODDDDTO`}RY,:ttXLJ#>Y1<¡C#ŒxM.6"""""%Fp:ͰbOT*YMZѨ06[kq6nloBKFDDDDŒ B.+,3JKug0h05zg9:4Q}{;T*6"""""E"Iχ i^a}R֭; $Iő#W0:֭xAfUD0Vif` Âv 8&'Œ8yr~*;A UɤEgj5=>QY MELM#zu۷w;SDDDDT1$c~>7 MG>QL&-m >poy{apDDDDT1(an.p8VZZ81'*A3  ǽ8th>yg'~xf>'"""I&%χp8vڨzzl0abY@33**1?(Jp8L0*Q}}JugDDp=0 """"p8j0S}Z7nʜUwPꏔ'23h? Z:;-jk|ODDDDDk,KKf::,h*Q}?f5Af-qvĖcGTx4IvG %``91'"""""gTOG ],&u? fX,:f 1'"""""gPAT:;?1'"""""k@|iؽv3t:Ƃ}A[PWG^)9={~n^u|~ ~ Nj5R3sz(>A˧!󋈈VW'0V=#ݣXqyue~-˜73\J˶!߲'̅G1i(\ |_i73a!i*vՑr\1<#"""򈢄 8::,hi1r=b+H_)  o:󥧐@esJQHb5zV?[sl̕/JCu:Wl:J3""""*N2)af&x\D{vB sٞp*bJw!SbYYqPN Joi/TPj*wr[<#"""Z$$v r5.fPK햓夡o(&j+DDDD\r!@[Qèx7b߱.u;_jUNZzZ[:%[r[*Q(`0'V63Z*d?wg 픲l![dJ{!izV#?~ Ϳb[;CmTGs֛rODDDDr#XXhԠ Qc{Uou?wƍ[ lVW-2d"""Z$Ik]f^z)/{Uȑ *xqX,??̓}b4\""""jJ %@Z|I !bIa'~j*fE+ p:0bODDDDDTB z6|&DDDDDDu-a~>V.+t:G ,x"pðXt@axD Z˺Ws,4ny)oJ]Tzz![ȼDDDDTk>rFa6kj;'ED?f.RJu:Xlj$b" vJQ=Pi7zzZ溳m?ײ˿\GB/ 7vٯ\Μ/?ɛlymyuR72Z)XiŤC/nH r=b+8( Vw&bB/f[ֹҶJYg|[ʢزU>)fJ7 QMBꙒe_M """,1=(baOk<)%rKty oYly Vڏbʻtb˨JMG@-;Q=☝ Bn ݣ5gJTJVtsLI>QTժn{po{.s!KMG%WRSoOMov]""""jd~ ~ Nj5ݣR֓ruV:^6sg_>Oe ]g1Qj֗ IKm?leKَ򘈈h-Hap95رW^?>lܸuv,ƼDDDf%fldaP8r-lЇeb8 EC'"""*~k >#\|Qlͪ T}/-fY~Vc95BADDDDDkJ,&aq1ANt:E` xQJ C ŢáQ1'"""""_(ca!p8&t>'DDDDDDu{Ѩ+l=Ԙ>=˜ 8uʃq,Ҵ!~{14Č""""" 1h*'`I 33 ~ \G4*.MWJ@2)3Hq,AW{`,@'Oq$>p񛦫TV$H$$fU |8B$V Z[91'*I2)aj*cfp$\dҠY;('FZ ɤx\,%I2DD8XZ^s}b <8qbᰈ 5.\A --z$DQF"fDDDDdRB]1'*$*0Ł U]:R xH ˻&LOHH7JDDDDJE,,D!2 0}q|q۶5'!2"JfCWAi O ^o8'"""""fg#6#zG E33a ի:b+SgkX"mX-H$Tp8"?D[15egٜ@$^̌~?+{F%""""E\ w!U㭷bx8WG&ر >ot$@}(!N`6ttVz}þh4 Q!IˈeT4E($ p: 0?1/.2Oxc Vy>~i~zޑ~8y҅&on@ 矻`icG >pj-[ٴDDh$IF8D2)J~52""jL!s=bϋ5?Pg.q4"$ow`Ϟ^ձ4?oaW3hk3;و^ .ba!o|mmLOa00`NB4\z`eDDDJ xP4781اI%Dp4^ye##>:<^NsϭǮ]| --z ?kJ%@ժ $ɼ&""""E x18r׷%+P(s8yg`CCMx>݅MO{;_8g}o= +G]͛( 6ۻ.F(O ϗb.dPW(BӺ|j՛z>T<̼Ϝв̜^嚯^&IG ժAk*>' W+.d}oiϹN33a;612ŢO`߾^lֲn}I&%<0qa`;ٴxv0:NPv cc$Xݻ?ߴnlByuF)Vp%-i\z`dVזO_iӋGXF|hzIDDQBp458z 1gzkBד9_B$Ο_ġC8vl~7۱woROjp:$I?UX,h /l Qpbؽ;v`x؇0N6m!2R$ HHEmJFլ7Jٰv\v6^R:gIKf];oõkqerYKGXFiM%"R6wE:X,|3د`_z6lW l ^}u/z ;Ǐ~t[իa7mHu_gtowq @xN:\q# 3zdY;܍`ЏhԁQ\~>2دT5XZ.y3A!e^,YӼ|;ժ7 +wS勩GtLDD$<8$ hn``O`jXf`d pL?Z[10`ɓ?/u\|}8ÇCVgCغuݰX]w9pݭC~;KNbEK$PTzSJU4uSq/1:ND_4*ba! ɾ7mtz?6rME LСI\Ӎ={z7-H$ߟ/9@ ={hiҥxiߜv S3g16ͦP:AJ% NPܗSW9sݙ R)TZi)ٛŔ[>_iS\ &0?J%C`*ϕ+gV\ǦMۊ $.^:`,# *<~va|m\n`~>gvLaǎfk1a,4"6lܸdRB<.AVT*!p%r_R~)~|Ӯ\9ʕ3شi\90~̬-ޮTlj5ϗɤA[ ' W1V``;._>}B8~|O؆f{۶Ee}+~8sf6|;10` S%x9@kNvF hEB]Ϊls`z`]({|Tlj58ߟ٬á{`~mܑ:I_#8~|>_~2ȩ,cz:`NX@[}عZxxi\1<@N! V jdhOw wܔliE`C<:w~뷞_U|i| ;x^Aϥs=dֵ吭.V>~YljV&2\ v엄O˟?<|ri˗9}3\K/ `6``{{kW;:;8k2=<|H|0'`;]x._[rE37ߜoCr/[1ARܱF$"њ {z{hhg|SllCoP~-7}8p"z㘞ڵ DQ ^ Y&-ԫztvjX0505ThPnY}?[9\j3MfzV5ժ?W:3ɵ+W=g1cv1їb1 C>1g_sy^bOuBd,,Dq ^^ j/L8>`F|q-g^X TFS`i֖z-@p5x\B(\bb%@@ S`2n8ҭvҍtk@<V$f v#x;QvG.`6.lnŢ %m7{sxIb"~zgxn45/kldժəFNB2e3~YꦌT*@ժa4ԤEWQ7kėz㘟"!I24Z:47n[[_ h<ˈh 1Iax=D yRw>_dž fUSLNS#MC&-V zs _2)ca!x\DK6B vG˘LFEGdx0صˁo`XX۸v-|.10`=T!rSO,  VP( % /덣τ6HqBv?@ IUu0jRf N7 $a@ M/;;/?8\ @R TkUsTNgߦ&퍿԰_k\CYF@DV"磐$>1/ʎ[#o?0?/5FF82lbz?fg0?_~z^|sj 2zz011[wbnN~ >ƗOB!q-A5!?ŋZ$j\t 6~ʨZd9gF# bQ  Rᰀp8LO F#`L&V 9Œ`HMeh4q?js 5v@DVbS0CS'D l?K_>ȑ+ LCWc߾Mڎժ̻GG+?N8[M&%eƛp:?ݍ`J;7??|N<7H&哸?ߍ?:z{l_YeT+$)~<."K"Iaq10悘 u?pcR}ݩj &MMz8f6ӌv3-hn6fl`@QAJ@Օ[_eflWI?fg `v6;'I?._wǖ: 4 hi14a:֭ ÄfV=L&-zҍ'Z<\0L&-::,vBH LMM+6<Ћ͛[կvf+4%>:^zSyC𻿻M9)8fxb-FI??/[{aCUUKODI::f&1l`zԍ@ (\0<ba! +"`z:DB\ZѨ]j tӄu谠 =ujhBK`'DDDTO!,.F`t엪ޅ{zrNV,m==CEo2,//$海@dŞO.~'g}{;۶<_Ԕ?܏]TH5ɿxIys+TzRH^_l3Anbf^$#ZlssALNq|1\aLNP6RAaBgtwiiaZ `0hժn3ޛuwF HXed[DYf쩒lvTgRNM+U74+VQۣdL4%3eَڒB @@.o U(t,9}9BJB$ĩSvLA()WWg3O>}ET9eSIh4jw}s3^?g#* v|rЬzժx'f Zx*3c|WiWLnTDpV~lm%x"X\ds -nWH6cE[C4B![]$̰ 4 دEH{`޽]uHG{ߛ3\SOŢ/xnW.a{;XpV?Lcfƍ5N…YT*qf_Q#Jg)4Bn@@O$7f\AǰD,v-@f0]\ )鱢ϞZp!rS #n5D~VVf2cұ N;;B \84j#"r2Ia u1|/\Y}E'8ׯ?Jƍmq;׆~T^;Fif%[@WxNr H&ӈŒen;;!`+{׋TJ\Mi`4jptbBO5Wt hi1n7d`4B!'H$ j&?b/ iX^>t@siK+_Zٯ~"¿:^< y NvA;u?{l>:Ksg'7Z5&&teKBR!I"Ozv ź==6;'@q SW섰D-x1;+ƇNU݀vsO 겢roEFnB1D &шb_S(b;2dz_'u `xxQ MiɃ/͸t+a_NM&qU"1|hS N#Nr Fjpf-qhftZ@L͌3:;-z{mn7p hT6Bi"A~$V ׄPW)cgL%ʇK^t}륥n5x=G(O7G>2?&15;gδ^2R^v b$$ʓn00Ű'pBpۢ.pD: J+zzvs5nBH}`?@ ]iׄbٳx{b_̙i^Gn~ѕDm,4^3\O+$Lw6_4A#﵁@ oL1:ڎ2 jiFl#BnjT@@(ͬbcÏ`f+0VW};`4jami0@Zba٬NGB!(I iao2ot~dٯGF.caFszKlV.pW.F~3ԋvcc#~p> n77QXzEő=}kFz_ }4uhi1u bV$+7 7\~-4M.׆6݌t BjK2fhNQ3)!G '3"~~]ɜ>''ڥ'.-KXL$R^_;{ׇ~,>``)W[of'GF]X`uՇn+:BQT1' z z9nR;g Łu?\!VW}xL&--LP@iv3Lhk30d@!TXLğN 'bCi:&{^:[|*obN70=7._ƥK]xYbgGc ՏFuk@ }o/g.e(D_ԳHc hn?Kd[^{{all2nww#OAQCWlaA_-hm54fj`-BQ@8Vk{b>>R@7\F_N)y^n.]B[Yqyz?:c@VAu dQq aw72p}ݟY A0m`*%dTZoi1ÌS8uʎ zzDi9[V/!E NAOd0jB()0oww&>{,y>KnwW.  w}XX؃iDL&K"J#IOG6P @ ~ O$3Fnw{{x<lmn?zvNftw[q=$pq1}8zXZL-BIhԢbb'뿾H$Oze϶Ko EoϠ^x<7\[0<F^0I!N#d L$ @r ZFT8`0hR~ttcB==&twfݮͦŢnBR$~/EV >@ W.|x≳g(]^>x51>4*09h4*Nɤ'SSؒm$HߣRn8F `u;cXZ `zڋtZvͦ.uw⿷ׄ>30405j[!;;!q 9foدǃP(Lfagv@m\ҍ/|AqV\[o47s΢_nwa,S'g 9)Hnj:>Ef[@< ~բ oF YO~*KxIm"J֭\ UFԂAEszDZf)I|IxI&$&ǰE,F:-(hT00԰4p:hiѡE SvŢɤPAgNJpk!DIllJ j(bԆ'd] S݌?>(*~2/`iimm|ǧ>up8kFçQ]Ǹvm ]]xJ@ЯWR~ ߏbw71as3 \|(<67cHĕ7vVtwkCO(PAX0@j#.?,!wwVnG(+arr ?gt0xc~<% (nt!Lc|ш{*$i.'B10p- J#H#Idfwwp`k+0vvBpqÕq 00t촠̈́63,鱡NJLw !j ƱNF{ZF!>PiZ4ͺ$#Vgyg?]Xz|#8}t~,,x`60> YWv=j 1@_$@*EOH- jգC- KevvBppE῱V0{H&T0u hm5ˊnkf@W80!5B2#p0PjPX[}|خ݌F->!X,z|p=|fA(ycxLŅ{"nllkùsmhDaR&3ۋ6R_?_d{%}(wӈ3-]?Xi`њY׋o8FiA_mE{ftt3 M&H !"naDWe ~#ӧcuuX]uꬬrl Z<~`2銎`泇JiV% ~}p/vZ P\a6ѨN~6RQ4 [i?cg?7q~?K_*<q_h00A^ہ.+N6!bk+@ g[ot<-G )^Yu ^{mw5>h-*DW)~<⧔&8::,R4>Fx" cs3q dfe\ VVH&U>:v--Ftw[gGGX! p80ut O2F,B{恞 د 2.`ee%ɽ( ٳ9iW:ć^2,zOH( ?"VW}hi1_}_<>Rk2F4nj[¼Xt HRP# g8&&~ v ?9~Tm4{Xq=̈́vf!v Œ"bƢah"!188C_:}}ns-/O(=X:Wb"V| |?QBdh&ӣhm-wUe=$GF(; 'K7r?nk3gJn&.`3|_W^{{6iZ:4ń^z{mwvZp.@N[!4piQ~|澿sV^q}R5ʦ&i\3 IDAT}l7۲c:pBzzlSܭirfmTJr\q[x%gqD"{L|u?66 aw7 ?VW}݂ h԰Xt ZhmNۚq hmWLz=w F$+pq%bb̙ XZ= _Z:Vv j@)F_`{ۋ|`Fh^ux&Wtfz/&6|/ i~Rө3tZ\ [- `}ݏ <q5̶nmm&18D_=sLr 00@!G~nw&==VnG(UCΞ${&?}vzgLx_SvUIk$i&~;gWr/vd|+^FF,D4<#\/(mTn^VS ~RZ,Zho[@@@$D ɸln: NN H+V8FYD"T*́B{a|1lttXoD?2r 7򦹰pg^ Eb_Jе"~-<F"$n>KwT\ϾNF,B,lZ(yQih4*h4bD̀NˡX,P(-`g'+qX[ r Hh4*X,zXz8eE_ ^utubݮɤ7ȩC)!T,#D4rpP7ؗ^!ϑ˘B q5m(#$ii | vGF;;Qư^ w@"]ѨөGgJn#z{3 B@.W:==6nG()Or*Z  ZFN ItZD'6 FN=N( & ;;QlnN{{1ry2tjl:8:cBgxnˊsƧdHBH3"mj4jeF2BOpC>08_tZ;X^0blKZq 48nE9 w  l6ہk[X,H$@ 'K\ ͬ pxD7wCHGXthm5݌^z{m鱡ӂ6hi1b`]8R? jPb17TyR4_~v6O>9ӧ҈Fy'࠳Z ;>!nѨtw[@(`s3vRD>R)-@hj2Ђn+zzl[naiŢ p B9bʕ +f\jCI>.]BY~( ;7D,ORݙ<b8&'om ڦQڈFSuKX,ࠀSԈOʕco/ +uf@+/@ }LO@ Zp:OdN#l6fԾ}_!Y>)O|ːJ.bi݄gyeEKAoo"ZZR |dg'_7?}}XjOի6D~|h.]H$҈Œbߏbk+5? b{;)4t: zM-Մn+--FXb|N nBHË)_ ++^"R540up8 촠ߞmE[ --&X,:L:ZB!G!EP-xnmmX[+xosG UVΕ~.W?| >zZ>q ҥ.jbF|hH#_6bB~L?TZ-FZ~҈ScN⊀@ERdbѣň NJ8W@!4_]ͼ>} `uu6wZ敐L&gZjۻwX^އiŋ0jAipdط!Ǥ`0hammӈDۋ`_tVllDFw#HC- ^,{A0:nB(U+'|3<0ⳟ}O=u0b)ܺ+ q\4DWU0PĭES  }BN pADBb bg'+Mq0`o/`0e/fgw31]F-l6=V=ZZLho7Gc;mժlx\E._zjӪFr('j(ڸVmZiVˮ>Jl/t.qkC&cXY``VVf^/]5{,Zz8>>z.PARgM&>%qB.]IT* Z* cFm|$'ُQlY6s>_O.b|@Xhj8FnFG{+m#,->@#<`W ۾wۨY]j}b&i ]kҹlQޗAûX1?I?G4PhZd5OpB4Cu : 'F^@b}ݏERtf hn7̈́q+::,dn b Wxd(6}]{ UHH RiYy*˧rɽPY$_رrZj\jѿئX.'Ǧ>ڼP(u-W$ {(feb(t=gxi|+Wa55 Ӊ.DHk6R‰z{mqq e tBp gJ.-czڍtZ0- ==V%n! O;JsrWi(KpSZbe/%|KMMQ҆\oP]ѿM-)izcs%}PL7/6x"@7(.\hGjeG"I$)Q9^B`& p(>~nwAll%`g'I -@Ub/;bP/BrK|JSR^9^ժg%e(tOP"x+ij|6SjRj wtKգ(DNSz-د_\b?G^7 &ܺA06ց>OV!K"KںhjZ`h[@4D0Jnnw@aܽ;  4ˊ^Vtv[ a-R߁R& ͣWwIxVbZ֣T3Qb_~=2r 7恼fݤ2?K_zv> ^oid)8ۨx+a?&0n٤`0_ Fnw[ښ{74N Y݀VSfi0Քq 0t5Us d"kRrëUJf- 'g5L-RzT3;D+@3.o?2rObdrdCf?fGuY9AƆN?AHɸx x&6*\Z9>R(~3>_ ss{A:-@w14p:谠z/P8 eEKvAP(p^l87^kRV,^8X-PvC9Sھr]+IBτzͫ"'P]?Oʒ{tJ$'8UYJ\V[v$12҆X9/XZz\[gZ_%i(.UrR)-kOJCZiz (ɩk*irE(ɑb͛.h4*\X\z z x&0'!4@@r m ♭ `{;™m/~v bND8im)w+BB(IC>*| ttXpR m]0H6现,t У͜ n7+1xQEV++^|m ^'] b4H$o|mxQ==rBɤC:-d|NF؏ 9~HZlttX2q16@}B!cq#Lctk`4jN DM!)>ѨA!_{<BaZ4 `f I+WaꖷFVF:- } !B!Q_2_~,`W_mrR~s/w`hƛom<7"8&''q:zuk6"hF BH}R'dӕ9mG{ucÏ^!`x>k|Wa?n682pePB^|!z%eȾ8DGJ}p'LNN矫۬o ^xE{[3} !rT4lg# `B0Ni,666 Rݻ^,-yp0>Y@ZO!b"BJil}sEO|J[+$ފԱXr)6ELN[*mZձT] AI(4Þ^J]N(ԫT?W&uKXK"bmmB4"[ex 33nlo1:ڎ3gZѨVw9}`ܹ6Xmx˿Jl^i{FG[h#6g5~R _JsT>Wt8}劊B_Mjag9u--ϗ4[:gr]N?*[AkE],]%mTIO>N>Ybuuh^'*APnb)V|s3u>Ndҕ_3ȱ jQ#c! %ԹWO1^ԷPSz_i4r*Mkr_jIn]NKANJ_N}sEN* ؗ^tO)B] fgwժqBl6}V08Dh6|?y8ڬ^mrrmʝ%W:PP6yʩ_mQJS_u'Lǽ]NUL|_ \{/ν/_:A܇ܼr+x\Ν}tvZ01 A(jŖKz'5韾|gϊY:ԻJr妝˲׺}细\/O!Ww.54 %vcB)< 7nJSI+VAN>Syhr~)Ν[+X:qd|(ffܰxS֖{J_JȖY+w)_FA#jc!cJ*d闪rZz96/~rQRe(v}+o2UʩstOn}]'.J9R&bp`xxq,-M);z `m͏۷wa206YW𡹖Y^Yby*s~6bB'0rIig RBbo:v쥲fOدd2]lneH+Zumo)m3س.W)!߈3X&}1d94Xa ۙPΞy-,8 ֹBkO}V^pSS;yM>(@*%Faܺw !BH!nf_cu##3'3'˽gs m}> 4ϿVSYiV* 󓳕UEH=W\r| Ux;mtۈB!iiH糯^ U}TCKK4?z@εhVf%}jb=Wn+:n\۞~6j6"B9bx n0:ڎ6h4jB!B?n̈́6b&&:qꔝB!I+su)vM_{uFo=(gf3.z &&`iB!4$R4u[)~ڏ{txF'bT i 54 !djg*xcX}/=|B/Bu)&J@ɵŮ)vkReJmU-GI_;ӯe%؋}ǃP(LfapzrNnCE!4 Q)uMt -4\/GDʵM%哛%R YʵA-!V_2_~,`W_m2HX O~!ǥhRBbJO/uJ7\Lrg Z!rlU,/9kj4 IDAT^u$>)k^՚>oC=9]{ۈcQ5@8H![Z»6i4Y͕r6V>9brr ?~/">-c".\ 8s  ۑB9T[Ts}=\jZɵDfu+ ()YB~dTbr[u$ľUHӴh _p8۷w$0:ځ>;m!c(s;+P|*M%/r]ҝ(RرVZbG귄+/vDڜ?17Nŋ]p84 !d W/-/vLiy4rl W^I)'Me)WSJ\ȱi-m%$b_a^ӧcuuX]egN X^`yy.t``B!LgmsG9ab8}<޽}ܽ{@Yhb$fgz#|-PB!$Sot!RϏŭ[.$ivBB!B1 Pi 8688]_Fg{;]L:wbA!B!ǀϗ'd2}\Aqlt:5 C!B!G+0<<)93LΜ G$0;F(Ǖ+=sp=B!B?zon7]{% -ǻf槁B!B(C/,ٳp# ]Rkk>,-y`06 [B!B~By*IݏSwcw73g0< BH/9!r,y/uI#-:c'B!B(Keloqz-&&ahB! !}T*U/hm56B!B()h4۷wF-!B!bbu˅TJx,4 !B!P  ӢYX,wwlal E!B!re/ Y6׮eI&>vڪC,6w]a# F!BF!B?~b~~##3'v7oCQE'vnGIA{\_9B!B_ss},a5ݻ!p 9 ^+vsB!bԁX,cxv ۠Vs=B!BاoZ㘚BKZeQ!B!bbYa`4j06٬a!B!bbYI&A_h\O!B! x<´hDuˋ`0g;o>EB!B~A\/BkիSuw{;l>wY4#(ڈWi|E#p(!4'y≉X'6no9vh2(-["[n_=ۏ !yhܹU0w:^jץ^$i;_.+> Tr{>"B(+Lkii*̙r|b4 PSS^D");gG_=/L\g0᥼3كg_l*7bJU,rꚯ +vI!{k_}kJ٬T-!oVEKYpBSZt_BP#rϕJ /V%TYukbPҞrl](]9W֩b_Iy !Ppg^GF.caFA./GKHܹJmm;a0h !>m^曹TN!AT)V2,PXJV)ݔO6;K[nW'BI\>t,;krinKʕ ZVs=BHBsW_jVWt&Yr\M1\r6rp3ǩ~B/]?WKT>cr҃xYi?$BOH&XXcc#N##BGι|+{MGkvSv[ܼ˱k*yeAy!P"{@<ҁ!k޽ !'\_AB!D!OSS^pmmrB۳B1Pb1GUݻ!ܹáÅ rB!B(+ʕ +f\:U4~=q;;.G~^!l#B׏_!BH>)fi!|{?F:CO|mmf]׮Z6"B!4؟?Ǡp9^xppCXX؃^ ZO!B!'ϦRNQKXY֖fA>!z6JҩgժII]JE!a=6w'h4#xlZBŞBȱ:w@::++ӧMEq sJ_}BQ"=xcDY:ܼ].lה{-mR,-bc| f=BdTT劰R")߽r-v_bXJzDNyڤԽlP/;ȱ}1JD| !PLXt\:60prMH&X\܃D_'* i[ u2->.6˵C1]Ӧȗ&^‰kK.byy_^t\`F("ΞmCO\B9ܲv FH;BؗCܹUPg.v]JmvwCvAQclvB@(PMNJmJmjKۇ}GS_Z*f1Q.R 7Oya0BHZ`* >߱b}>˹^n&V&Vv׎,!_x~<.<Ο#rT!T\t b˷eS|K]/^JWj9u*d/9쏃rPW['kr?{Rsޗ6;rT L06։.+{2!B! M;???˙ɼTVn ZLLtf3'B!Bi fw77hm5(B!ǘBVB>v.^٬a!BN .Jm; +O9i`T;r,rK$_a%W|u$R@(D";wWAWN+Ev~`TV2rUZb+Y%*f9m[Nɹ@rTɃBbʕ +f\jUZ]WZG:?Wj!L!͂b/W`Sf%VZjLʉ;~v΃b'>Yq鴀__@ ^~w>xj5#WիV9~DŽr)Gx)H˙VZf%iT_I\_BZR j oyTs~&'q A / $iLMoW_? |Cяַ&/>!X#d?{qfc/`uu6hw<ӧnuuJ:T|(FҬDIW7իp8xx+8}ځNX,:yM$)| ܹ6n)K B" #7F^c6"r xe|/>;>8z{E3gZ/<o;ߙB0Ͽ.uA'B* TW(2::4s﫤.Pj6=l#BkƵkm>{%#>a+oD"EcB!Ҕ3CC<9>88i,/OgeZ6uvcUO!(nJ| ۈBAvww`yy}o/_G>2 ͐spЉ?_C[ o7H/?G9;B!J ]A( I%Kʉ+d\yZnǠ_j+-#56Ni|A{zL76ָGfM6z~ꐪӟI\(A$#"ۻ{9W*FӐYk…i7b1bϞfqv/<'&0'$hQ]",~ھH+W}雿c*DY}mj,3G`,YYSL∈ܸ~x e?+ـٳՄ*tu_LՖ~w"xP;_Ɠ|r*kh8o'"" M.>ņ pMyddI_}QoGfρw߭[o7pZK. J˨xm;U8%uTpV__1BDD+Éxl^~}ebOl{ =rrॗ !!~x۶Foo?֬)i#U?Q$'^:+?}{N_D\~,\kQImm{n Gt7s "" i7ntϾÛoV9s֭+NᖐȑV\9vG^Dwwv/NG\JDDLp8Q˗g(9N\|-l9+Wn,օ䉉,_86m:+xգbذ01ANJʴ/62DDDA,ĺu%(.OH%0 ظNW^9>,_#b9DDdߟIYpAp߁زdZWV >v5k^~ f غfODDl𷿝v,^g,1_!-->[ň߯6ӎf6 'l6D!"i;NMM7h]FFN,.msWVؖzO~Q;t[[O^̝;I aX/XMȑ BDD)`=[̙=mWʾ.a=rmxqZ_uuW{ؽfVa[((uWt?>Wτjkc,Z{@cclY퍍5N@]v6qDDDӇKx8tx|Z5//KJʕ3kQYy ==}wbtřy}o@aMDDѨӎCZ'pEL0 O>Yg`x\Ÿ>܂ňM*^y:;L nDDDLn|u3l9*daĈXH !!ݗ9WV^Ÿt]]vތlzNvczƈ$˗?= ""{իqhlLFڑq&>tw3FZ$'5--QWg­[ݘ:{Q@ AI] """yoqضoBVV<}4w=II}m~'6TT㏱1#+Vd ;;f33~"" }F(϶^s۷ŋNOLycoךNÄ VZ8#oo__Agg?V }"""2ѿr ;w^6\ލQXz JJF!6q&cbٲɰX ؾG>d`Μь?1'"""u'lcG+v>,Z4?>99#V92K !?u߉sj1'"""8{'|Q ^e&GҐ1 . 3cѢ 0غnw΢CB?JADDLHFOO?n/i? >ބLʕHI^D?Xpbbغgδ7ч{D3DDDԜFmm#I$YfC`09`!7wy&F}}֊=k#Q$DDD޵kع*kv`޼X|zԶ%'ߵ]\}/7qZ9P}ܹoV:Wj5'$%`^sx˹C8h}rNw` E]lۇclѐJV[\ GXV!ߵ]\}/7qZnwqfy*;sIO$ԯXi[N))pwn-{77u/:Ks}n%}sy3Z 9=Z EYAcs,±c_{Y7SM߽9x\'}6fVy_!a4) .|̤IY#UF\p…<8VEnobꆗ<'\9sGxCk F@OXNӡt!*+K/-]8]9q}jvqW.wiKM\YcrǩxWa}jL9r:9s=ǔ6[Efkw0䱻޴%We:vwmhWO";}~˵羼v}g)Ξ-W{~[ q쾅ұuC'./ qkruɜe.#_RU:~D&ɾ?%% p/ǮevZs2dVs F-Zxe?XcCDQ+;yuRe-WxN<;k*'Uq'ulRqTsɾ?ӢJgB=Z%3EJ99st4py?=C@]22-;wf:5uedܹ3Cֻ[oKI"9sGu-t'"R"(_ S ,: ZTA:ݭOq˾PҾu=%StmMMꇚJmT^n"9sr0h;<c(.ODdK55GTײ>Om{'}GZƒ~5ɜ@DH|?Q+DAW/(@@D~~~.K.a$Db7se?[bŃ o^s2y3wpBsl(fiϚ5sJDCoX\OEN"8'!2ƆB;߱cFJ.wMʜ!M}""""""0O}""""""K}""""""K}""""""OyEX3F fèQI,&7Q%"""""" so2DDDDDDDa$͈y_TT=mTQIENDB`MP3Diags-1.0.12.079/doc/160_main_window_tag_details.html0000644000175000001440000001022512040502152021347 0ustar ciobiusers MP3 Diags - Main window - Tag details
MP3 Diags
Here you can see more details about the tags in the current file. Some of the fields / frames / items are shown in the tag editor, but for the others this is the only place where you can see them. The fields / frames / items that are used by the tag editor are shown in the upper part (as "Track#", "Artist", "Title", ...) while the rest are listed in the lower part. (In this example, the TLEN frame in the ID3V2.3.0 tag and various normalization-related items in the APE tag are ignored by the tag editor, and therefore they are shown in the lower part.)
MP3Diags-1.0.12.079/doc/250_config_files_full.png0000644000175000001440000005750211271057106020007 0ustar ciobiusersPNG  IHDRq5YbKGD pHYsȥtIME -_tEXtCommentCreated with The GIMPd%n IDATx{pO26`Yla '˱5EM-VT*-vRqU65{vvgv+5!`b;!!1Ei &HzܢzW~~׏2/DkfU>F- f{…i54,e駟Ϯi||\v}s&MMMjllp3ۉU_9}A_ʓWĄ>}˟|cz/%vOƍə*lccR3֪.Z{ScS/[_wI^>o3fD55I%I:Е+Y}Z8SΪmn9vիj׮o޺SmmXl.pZZZYWil,?@ӆ mZu}ʎ]Vmm-+@D>c\yǯkʻu¯Դ(vuOGn' -\PtLFv?43ioёݸqCוJ`A,Ԕ&''ue44t^'&tMSUWUY "_HRc&ZZr.5եOu5=1!%IQ[5h?o~;ͬ 0nDmmɛۄkkktOG޴E/E_C7|AY뿎>P*UNJ,PAJetί~?vUX5kG.;ʾҫoݺYt*ufL?u|G$ITjΥcMMjjjȢEzxSF{?~T^O^g/뗇is0 jybVJ7L|ᇺڿ*}vI^jZWJi_jLZzuaۿwD>xJՅ)֭$555*٨[}RSm:~RuJ&hbb"ul^?wF#KWK/X=_m'0Ҭ%bWמ6}k fe륱/gK/'{vIm unӓ)-Y+EϽ6Ijk[,%3JRse2u9ys3l&WWa :߮o=8|:78ب>m D"FuuJקu}{Cgnz(y~^_忙yOS Ҳ4]$e[.I 5mRnY%]ΙM>\&&y,0MX>7{֩VtfML{Z]J$TNݵl>Sta iE}=@nf$_1co hn-[B7n\^Y_[}ftJ$|}e b PKK.]2Gy¬a?r&ͫ+`۔NשITzxΥR"y3}w\ yAZC7(cuT*{mř,Ms1t9g?/ǜYY~֧<êpH$F[uw5+??ɤ555.]>!Ø}*F-]jU6dvC&| 9>+MRZtgX7;_& ]:OwBtc[z<e)i)4fy)+p{S}~%I{Ϭ>vfLhd䢆Nt+t[k,ՍOuaA-_~$}e;1P ~?[/3キMCC7o[J]3z%v_JWsdLKiƧǤ;K}:˖40$鳳-_~JUKgxTld7zU[<于aG}B6s7D" jU[[ 499Д cZ!i͚&dߏL&US&bt?|v~mʕKNzaI/~qB_o)N*1MjklhHɺI%n|Gz󧮩NuvvBONRڸ~;vrK.Q*U7zh.Ki%,|6:wdjtq;٫-L_❪K~>YU]V *Vm555e+~CO(|{10Yf]O=l*U%KnW*җ|8yS]]-%^e翧d|lÆZr-P?˺~7DB TԤka)uy;OL\W.wU;޼QUtiǤ[7D*~0(J0r˗ߩų˧`YeՎy͛[ML\9^|^am P:]/|N~b5ܦ԰hjjnJ'|OUGhҥy`!OdGG;뫄l>([ ~=+>)_1S=k7{:qdR N`I駿(cВNH$JfJW&NKJJ[5t~Y]t:m{fX ua5===^*܎`&9[ZiMTW@uuu'V,iU*R]jl\1zx9==Wsz5 P:~:]-[[NwSݟ}XI$7ש)CDR컝% &USSWAŭ椹D/\XL}}J=t͍OUU$?_aenqbߔ+Dfn~ITzV{sn]7/1-Z8WL+.^jJNyHHԴH Ǿ7v9]USX@Řuwo|ZbK.IP)bb  @ A,*Q4Gŋ*WhӦ 0߃|䓏Ul$|blKKKvU+uXA|{:!fWTVuy w`i|ikb%-X@_ڟ0 ?p?+sͮ_kxr]wwZR2¾٭~Ƨ bӿ__®[{Z]nǥ+V ޥjr6_n$6(.,>jnsi_予u0[y7;0]nQrͱ(bnE.Ncw,A`nlquzӳ{jo_;]1/Ǽ*\.E~^A ka~ KٽW9AǗr*0t\E}[9c&x n?(^"uu3 _/>nv^11Uns=f.<7uw:ϸX…9{V}fxa9鵝^Ns#1r^oG8aGC^?盥]\^qwn枛~?Yyn>/rwsf%VJAɟj:$if˿Vxypfϋ᳛߹_ =xm ;^4a(Jӿޅus|(9s|ֱ3gUXz;;>fzi[*|At~)缶kÈ}K#.Ϝ95k6̙%7v..m]~9#gJaw/afbNߓ5PVG}|U} YaNڨ융k7*߮vvc/w|۲vFm[?R qs1/׼kc:E/u Ҏi΅=o~p]D]wڵgMݽ]澟q Sc-ϱno/1vI*D~p0h;_='o1˗|zGUfixӧߜSڵuaWoMe|5m ]Fmv1?›VAo{K ;K1o9h>}M9F_c|~ cR?8k-vWwbVbo'y=zҢJu;<j:y{kT{6s ;iC?>_YYʿt钾uNl3:qFy`^/h3O{:͍7(F_Hok̬Ad\ kC4s y|}ڴ?3OرCXuءy7.50}}V̠/n s `ށ% Ѝ7wO}6}u`^50ޘ 6F6mzHkYhc5\?퍁3gi=io_1ĆvvKG@'|,|m&" A%[UV $Xb@  jKY؉';<@֯Gbm^?Je/}j7mA|H$<~bغm۞K/  0 zG 7vT Vb9Vb@r;]wS|<2ح.[֩sas膕gTJl&չtb*Mԁ|v7/P{9HSܝxdWy|9>Kk&.]NyYk<@m:s؀ ðt̬,Ma>ҥ3-|n,4QM^VZ=7+UH88?s:͞ ĿfXfk׿}cz׿Ҋk_Jwv\pmYϏ=`bӦ/*]^ 6r5ؕwA,ƺJuIx|+M4Mkؐ9.ŋ:emu]^fې6N+Ǭo%2o>.\AlA]0zӞu){gWVy b+>^UVzs3{u=L_;A3/alHo'顇ꭷ\S\愱\Al0nVdžOٞ7<|jyc7 Ømܸ2k-c\ A|.l'~COq~tRTJIVb 2jD `>a;1b;ϱ և?g^ /Dz饟XK?|!]#~Y NXbޝѷt%zP{ m0'|^"kD lKK Dhժ:A,bTݻ <޾p+ P,X}$IaXyȰ)ͭ]E4M4Bcv:r ۮ4x9~L݌r3x/7¹k_f9+>K'WuSzoU}{qڵ˩=/۵Ǯ0}7ǪnP @2 Cq %zN] ޯ??"b㥣kSxI$ºӅQnz,X)~5==;0O)gnܸj ز~xw@~E WX3Kg;.Huϧ 0)%:=(3nAga>S׹~/~:blMOO`'` B{Z]%ůx]WMSY_O)9&7m-VWм\<fq%SyX^X':g%C#[v_x´fyS'yN1;Vvz^{^p;w榗qj( IDAT O{Z9io?v:O +WT啪/qٵ\|Wj?}W,GKǼlNAqZﰺYvZ6o9Ul?}dl~psY6Wܬ~[>]08y+W޼F1Dži _7;fV|{YgZsʯ0/uʧ⾳znUo<ڞ?n5~ǩ~ЊZ6yHιpapX%SyTfڟf}mZϸMma׹0ȵTp ֢(8O B;ʕ3j:#Q0cVu<yuYvU>v}nk8ll> ^)2ܜWwvyz0g7TZ?}G>Z\/oks{~mz  ):˙wu񉲌}_};عs'f=7{| uvLgGV;c/EQsNhժgy\/C7_/81y׳s*¾~uS)<ڽ'E16vm+  IQ3LQ0F])Ϩm|%ʟ1tklpײ:;jsTu.`=ly,<>xzyosa^vv:zi{n26i'?YMu=]Q]觰(#>2_k7kؘ1;AllY/ܬKv9K :{۶c9'mXe|wo<:5 =.nYۊ\S݋l̜nVGqCm8 kn9ظ0g7YuڷcX[Խqc;1P}S*Uo|Zbwޣ'|L--- S w;<>?ɓd2`^)޳\tDZٟqiC?>_oN@8~?A;w>K.;ML\׮]ߜ7v}t!3:q@%+.\\uX޼;1S@5ͿoX\v֯z^a^z?^:=`wvbX @E+/cͪ 0k^WrDZߏ;T:3cI 'A,3j/*Ԇ ƍڻ'ھ}Ts>p1^bTM$:p-Z̙sڽ{I{ϟy'2ڿϟ)e@YjΟP 6I*A, XA,b  @ A,*96ȨU__˗չ]s^>J::Bk>2]rUWQ[rY@Mںuc>]S~0σkڷd[䭝Ͻ400_|E۷?*-j ,;}}dGDBa$Ihn R^GGO͂tfw*y DƲ|9L&3+x-ٲe>xLl.p;<|j,p:_͵Z5;T^؈sd2>qv\\/G -q566&}8# U 7vW.ais2Pb|2={F:w-S|@JlKK/nzzz,:tHmmjnn}0ߊ+Lab##ڻeL&cSSSojǎ^|zNwKTs&Ob(Ngzu`9U:Ԭ\.ZvѫT*(Al<'xTlN##>RCBmbAlY477k-U.Ib @ A, XbJm%Trl,Q^˗/SKKs;:, bAl8ǯo@W\kֶD\VPkknݢt:*FSe2[ݭdmЋ/۟v*_l7Lfzzz /hÆ jllԆ K/G7wo pY-Dž[;:f~9&+ccY]S&ў={sΙc'OԳ>{ꩧfsjnnr Rn3y^8cyĎsw~Z522 $ x < Rʃq!0444dٳ2 CMr`z[x8e1TY[__\.+0٩'NIf\.ۂY@tbyc˗3Ԯ]O$ַI;wV˖Y]X/+@bҬŋ[400m۶iϞ=zuYYFկ~UT[[MIU-fۇ;m5 Vy[{,0멧96557xCǏ;zmzS'mPAl:3~9rXVuY\VCCtڱWTQxO<ٜFFF}ڶq-زhnn;ꐤ b  @ A,Xbjp}K56u}nGGWq㷾Jkhzzږ0vm"PPDD 9ݷd[xw⋯hNI]P&U===J$2 c'LG7wo1SsV::4<|jNڎ׊إb6*SAfvSݭSWhs.+ccY]S&al٢Ç*)msA歷oP|o]$Hu Zr%vddT$IuvȨc^ 4v/GJ_Xm&0!+jmv6IW_zBQ-oPAl}}r 6˪aavli(efVi҉v˗3N<99sjٲ\Aoe(U0ƪ,XĶ4k 2ݡCM a/Lkv0Z(.nqojsTPA$=H}Ya(ɨfԔuڱ1D9=vz&L~r U:3~9rXVuY\VCCtڱWTQ, آ@'U6ȨrаP۶=bVZ&յъi b  @ A,Xbjp}K56u}nGGWa)U9.(>5i՗9b#2>~M?/MO/P[rF?W_}]׮M0W M>DGcxԬ>>55Y8TVuww+on^|m# U +}}dGDBa$Ihn 85<|tJ~vc^lz^@^,WbƲ|9L�,mٲE+ͩ)pŁUFzw:XyN0`Uwv~|]o?4wkzm~)muVgs\Ug9+?dR522CLA-'jeX&.u{ hs9+mq()kl\./nr%v||\wخ566ʕVJEݣꏰ[>aS ֕zrYWAl.UC²~x_#|ls7a|Ӡ[wXn'^|Ξ=Iē:w-SJ~?5I)qs^Weì[)=-Uէ6v8QJ,Wb[ZxqcСCjkk N *ݓϳN폅9>;lWat'-a|zrYWAl.UCB_AIacU4̺J r;tMNNn'Թsgl]wR~( ;(0r%Yh``@===:VǛ:^sb?Ou XIzn P&QMM̱)7cG@1V~M?/MO/P[rF?W_}]׮MWwçf;<|jkfCؗWz}_(NPjSe2[ݭdVۻMzW}JS$Tخ (٪% 1L&ӣ͛7)m{V+[εKo&vi妾vu[RY]]=ʋ/ԭpnCN *~?A狟wa/xIW Pj\2 ðLe>ܯl6VAՖAcY=v*<:fvөveDA//h{~Ӫvw󜮿 \5]97@)r%vddT$IuvȨc+^^>97 a$?VɷTu ZNVv=XEZ5r%v||\wخ566ʕVro ||bR$37ۏ5Gݬ,ݷ^wU+˺ bs0VNAD0Jj))>M}f;q}vcWJ 5v˗3N<99sjٲ\@wm^vnmRSuv1גGٷ~0Vsr%Yh``@===:PnTy|xt Ӛgm^mW<("S#nKy^ʷɓqw{C\3QGu~%/?=Ru7+V>y=zjZIvmB{7+ɨfԔuڱW'(8n)e+@?Ο; 5mޥK&&k׮os%V锞yWȑZSMM:Ko'*Sʥ)=ģfsU.j۶CB ­q*,Al,477k-(%A,Xb @ A, Xb@ .OǹyAlE>E UZZza?V)/ew[U]˧ZoeխKb+YV4ynX=6{Le9xUK[Ww'v zG$-k]sE@uJѣoKv|2[ C){Ehe߹xlwU }6mz kk ': aKݢ|Ú#n/1v ӝ\zUo] zmbss;cm^ޝl j{7Vyy^buwb/u+G*>u{"9`(M-̺ۺ;ȩ}`~KnTZ`~`-XT\ < *l'@ vwyvtt9Sz]6wF@;›$uttix㍓b+1-fnYs2-Vms jUwb{JV ˳;浞VmnR`;5hjnR ͋أGŋL<٨B{, fWhӦb VImaIc bS85dê_vqs'JR7v*^jc^R?yV'@3znw,<}^'O2@pw v^ը.(_dbQa ۉb  @ A,e58xZG˺>kOX+.E{t3FGeǹةF_S_߀\իרGmIDATmr?&mݺEt1Ssׂ@aWNQ A< `2V2yk1w⋯h]A| < nn;q_߀2 / 6Q6lK/mܭPʳnnv, 6Z/۠M]ZY_f՟fi[^:{gU;69e2ٳG;w9vI=ڻwz)>ܯl6@ݶfaz)ˮ mpS7kyv}fW(惗滪ZUgj% }5M|GdR522i}J-鼠mz~hKTJZ[a2MsY&]~Ŷ0X3 |2]Xee:;;uĉ9i֬Y#0eаkVR{~UZপN|2={FڵkלDBַ499sjٲ)N[EaE+UJlKK/nmۦ={ٳgf}WUq:/bG޽/0 =zꩧfMMM7ojǎ^ǀmu;?1v['y+:}wL:3~9rXVuY\VCCtڱWTS Oܯl6@ScA˯j)oxevǼqs!9CUĎsd2 RQ}W9vi W^ mK=UJZ[]kllҕ+ؘӪNuO=pbC岮\.˴ۮY+df[PݶK>Q+AUZTN|2={Fۉ'''uY-[v7߻# 8olX .VeP j%Yh``@===:VǛ:9m;uײݜg9K#ʺwX'NE5xn P&QMM̱)7cGn^dLGUn]Z?=6nw~ 6&锞yWȑZSMM:Ko׎JR @'U6ȨrаP۶=VFO ܤUn)cKXbF}vHݻ}EŷNiC30޾b&~"A ;`b @ A, XbKm56k)fT[𩙟€A3 S[T, 6ŁmGGOV+|K0W-]9AdaPkzmNy) +! +$sb%ѷt%c;w>:{.{f*@WhӦb V˱}Kyq TXKkv'8|8ΝY`$Uwc@Ox e:b]vǭvp w'@  XA,b  ֫Oѷ48xZccY_tttyz@54=@mmeuڿ^}u]6)>EZ!'VcoOlUww[q|o6 _O+N1C Fn%o@V(H0d2mܭ,^{55*eOW2X⣪VbƲ|9L�,mٲE+ͩ6>%I3[y^RFXi,1@yUJȨ:;WY-I&\P-lwha/yإ ޥRCBmxɷU=bPss6FSLxKT5Y >_mb\1yh D<$NtQVy*@rQ^DX ҦMHs8<$ru`c@mțJ_T#|3̢ľ tbXb@@!XXbb{Ǯ]cncɒLKsZ_jyI_@vÃxoxɝkeF4ff?EΎ+8㌅={Ըe=!v`$ǯ/<,x3k;wƏ~ǯI Ղѣ,O>3ǯk֭[cqYgիkƥ^O>3핆 n\>eӆ739eK{]n߯g{|y׻VOz{n:^^꒵&Է@7_?:155s֭m۶G?x8眳s VҖ}kzRJ=ֳDDC׳~^!}zjg:@W^M,+.o|#,X##W~v|,@6N3gmRͫVױӎZTZ~Zy^imճfoĢEIÇ+.sH$:xcŻҗzpNk^vZy= w]13s<$xN[ftt4$qLBpn 7yl;zy޺%0=46PÉ⭷ފ76hh([o/|0?Ob]A* y~߿g5oqؓکv_Ky_T/j@Ğ{9qyΝ;뮋شiSzx_ 7\ .l 1\hVd1:%ӱy1;flx`FDq''x*~˧cґ8sbfx>|(?X g,8~|&^y713qH. ۈ@=9+V\"Զ@ b@@!BLNN9)&'X,qӉ̝*+ sI 't@!!Xbb@> b!&'bЕ6܍;56fpWXeBlA[@g'!XXb@@!XX.ý~K8Gl[y݊6U_=R# 6[&6 vK+]y0 ;ڼRonpj4f~ t2j˶*\ ڞ]vDZcMLjCp+({䔫EX5BlZMZ8Mh-o0Jddr8q6˽ UGvZ_<ةo 5mVjmjh3@5eN\+ gl=5@?tbXbb@!A3 {+WU.b]رi+[)~K7e뾈=bKO ш [ CCCm٧u뮏[b;`}R022sg؈$I@`'+Ğbhh-E)m]F =P*k@#5b6lW@%I۾S|b+R4oRePV;ZVZZL[/+C4A.^c3+Ķ䢨5R*ͫmZ #m[mx9, Y v,!|~#WVNJ޶e?Zq_j++?^tB,e!QC{!V[mxr=$=֪6Nf Ͳzϫ.YimnےpSi=YN=Ֆ:/fMZY&Ýb{ӂA$9-4Hy;Jשu\Jv Y2/kMjT /^^~5hh [zSZo?(bO\WC,Bl\TX~/}XEbT,g sgbO76f"ba.Ԣ'vBl)f@ʕ+⮻uon}(V\!PU. ͥm 4d!X%@!!Xbb@ b!&'bЕ6܍;56fpWXeBlA[@g'!XXb@@!XXb@@!XXb@@!XXb@@!XXbb!Xp6T,bb TO:t$Bر5s@( syBl)ȶ/@!!Xbb@ 7rXK/PIR:t$BBؚ4ba.Gv$Ėl;Y'!XXb@@!XX.J;߹?yfBTqecagZg׮qشUQ,bll 4`nbTng""2RoR*{#" B, gbTqwpK{t|s)>?|XPID$9 *MIЎ$6}3.|gz-Q(|t};N8'?ߢ(Tl|{g&'bÆ'N(be˶Xyؼ}36npbT5LbǎC/Jh'V-,É`CŇ?e:SYzb`CcMp姼6,RG%ɳkβ/Cb`l$q啟m%+}*ҺoףÉkUNflA %>m鉽#G#Gƒ%+ȑURu[TfVk!pb@$I\ug?~Cy‹=m\G#˳'R;u‹OW^֫5|]X }m إKWơC/R=:Rmj^6'Ӊ`CWmO2ҥ+SiTGoV_H[yi5v\M$I'?nĎ?v(գӿeVW]|y󍌬jhIRC5}U!^8\,[:x-XGbR;aߥy:b0$~ɤK/=%Kνb*գўV*N򺼆ioyLzboN[^Zan>]>ةVu?ݱ|L=iڦ߉:b|}~UIR=:=V-OڔשWG ' I>?h'/7CO, xݶmMsŗfZnϞ_lJ& $In+xP|>X u뽂),^<<~q7ѣ iv"@ G|$9 WerHk-;yh{V./?m7}l4Nϯd_zR MN+o[.w[ϩwFˮ8> U?EAQK  iNq/<֯eҋӏcY`H @ tI&im"в&Z|ுh\ UWClس ?OzvOołiv^ziM;;v[Tgӧ+XN<OO R/FҮ\ _6U'q`^{GW_s)цe9D@ @ D3" p?ݡؾL?[ש;U?A=zJÔw=̽g@Օs)@Mz=/))@4˟h[:k֬`)ѯlB4M뵎<˖-d-'76.^vX,IU̜9%]s?U3gN%Zd"3r/Zb-'͓gL]/$;uҤ16s~󟮏}qG,KbYHilۺ)7~j IX &bL @ x 94ӵ ɥ̞]y `Zoݡؾ|^B㭽ɓKٻA㌊3tOL+s`b1cCkk3sS?rimތٳ.q8SFhF^^m_Q!p AbISE8Sv^Hv컽3gNIG_̍}#7 h eҤ*bz-sD<ΖXzѥ hj<#?>Otp6CQd:;;(S D@ ="deϗ7>bq]c/+[r /Mg$Կ<bڜSb̞@g`-{gNFwyfLt"`竭=kZ_q!OTuҼ9癤ЌV;Mʰ{~,}Fp8~v'.].$I;W_fE2fX&MƋ/<#?,c&(2c2s\8e[@ @ xo.>SgR>.\3u[/E4JK( @y鳰7i#SQ.s:wuO'F4Ya Vp1sv?>HýSuQ.T;jƂQ,I)} ԯLd@I}˙,c-Ǩa//X YQUEQ@0+@ ۢ˩"Y2GBt\heѢC3CVth$6xf+]ءDYr"I'KHmKD^ϛus#;֯…sz9xD"9`3$_\}u>Ho;Z[ۙ9sj/Q 3`9j44d{f|z!25=י~>v I|>/6sN$v;pkq84**Sc$:H̙ Ȳ,F/@ r~4T߯MZO5~ҤjkSl\UWCb|iБ.)?y~{5x@C:Mˠiv|TݐĺuزegvzeeiG|8깔nFm~e}γz~~4M;ah` 7~ =m2_3rNh4H$l6UU t]СZZ2,L6ܳ@ee.@ ΍ <Ԫ.w Ku>AUT"P;8ph,XP֭x\yt6{r.^Ly^b/fz9&/Bʗ-Cu˗/:L4 P~dD7w=!Kd%]\yw:-lAR=vvLΆQNgC;ݣTVV9 _NB?'VsW<.`Gca4͞N7@ fN7 @Fgmג25M:˙OՏ;r7w=q}ogdo+3?9•=iOeTs;FPW?gbf6r,EΊ-E @ xpS fnX{TT6զ4 ݆eY6^v{J9~qi9u!w YȟNigl ͎lM3j`ls.Lj$Ii$%$HR8IPUEQPUE-@ ]zjw(4OJq?r"]A589)K_9!;^|bzz|y蕑[q< @ ыѲ}}ɉtp9IaQQ_a ߎL]@ `Tzqs[P89" [eCDG;l{1v< @ @0zpHsn+/σvGi @ @ xovp]LBt@ @ z^ @ @ !, @ @  =Bt@ @ "@ @0 E @ `@ @ 0 D@ @ a@.@ @ À]@ @ !@ @  Bt@ @ Ta`ؾ}';vU};w;G @ F!CDFpGU^{m-^@ `9iZDQ $zp:ȲtA'# H&u,n)++-$Hrx3mmb L0 $IBRNjeYȲv(++UC>#QeHt1,ai#_(,"!Q ޓ$:P=aut@B´LzD"F<c4. &aBQT,DףȲӦgرGٷo؉)8Kwwv"2D/cyGGMNqq UU3g~˅(XE2$NCC6Mwwee,Z4mA8!u#+fhrr9eymsnB 1klƏiH,C$EF%d9^$d95-Α#躎$I0eʤ N~,,Lfې鎨A:E< \N7E~ƌiL]jSPk#f@ ijjf9@4EUm|> SQάN"I2-躎f( pn$D9m!6QVVr'u471iR N0),,x$H8eEϻ}ۂ:o).eYU(wIGy.]]=ٿר;Y6mڎ$ٸxz)eaINeYW"$ˌ3&B֭nX`lG(f۶1 2LJUU5 HH$q:]btȉ(Y$%F1TUM`ƌi,Ysg ~ y7\tP9Fm @O= Vo'ư,KEBƢ%g]yUyKq:-̼ ]˦I99' -9LĖ\njnȴúnKpqAOF#;쨷X>K Q.F˘0a<+RXfw0n\%{y/Ҳoŋ1}:ob#nAROL$x]ۊ7t Iw'xHDf/n&\MKLTڟ@g\{=u0Zf1z2‡zvqC9j[6= Ip4 ݆;vmC|L<^5zN[}_tɍ929[OBvvVW V Eܐ Dl~o;kSxDM8}Oy}^S=ncwͣ} Scao(eZ6z(/ &F"  F>Iݿ p.#&d|@ [@8$/c(J6>P؎TA ~B0c:yc'SG֚CڈtwپW>!%FU; PWFKg~ 3f,nib> ]],]yں|uIEbMQ]ħR2G8nHPaG} !66t2 d&$I|s wAn76tk^}gƌ?|I0 aٸ瞏S[[;m{SN}ﻞ~6^h yN7zhCD"Q/^‘#Ghjj" 8\UxSO5k2,|>E=h6;,^զR{[젦߻L~DhfҥKe;7nu]kޖJK|2 0)[_Ǩܓ|+p:}I$s9~|3vT`?/Ɵz/!^>|O^XI,X Uَ={S]=EMҐ$D"rynZ|/fC6Eڹ\3|-{oHq(;(wp?]a`;.>N> [`͚?n4M>7f IDAT,YB}}=,dɥDRpN'gf9r3]u Xn+^hX߮&NfˎcYVN}+G' Wtu 4M4M|`3l4yDi <ƦMFSxg~Q,GcQ믡ϬYg/\NSNaʔI$СA8ɤN2$ Ųdž'1 Ӊ롨TWWtjlݺyu4~,μ4MCӴҷ>Ps;4lJ4%LiuJ2PIKkG#a% J r& 3 YQ&.UUp9ݨ6ԴuAVx3u_/k""q>.K[=p€A0& ٺ6nSϒ%dC,CD94O%4Hr3e Ҳq ?SvM̛1J=c)G# $ %-%52l9M$iQK_l +新:joE0[P Kq-eÌs4a„wĉqƥ` t]' q:]/Ya]TT)i$dFʑq]2磩Ȱ.>, 4AM7ػw?zzD"0X,+ (\NN^| )--a8i0a‰%/CWWE!IphL:GyN'6 ]I$b1b(pP(;?).."/;lŋ=dYFSǯfD $EVR9-$9PXiIJ9WbI0kYT_~&d]OLSI K'K ˒1cn6 MfOEd^RPSU]qV6bmeS|ҟF䲷!v73&gp4{M'ؐ+#\~yWDx1"8 gF&宙Lt_6[~3\| `mmm\4 GQMeu_-|.VZO^ŋ Y?>{tׯݖPQ8ir%5V.hIݿL_~޽7{_Z[[zfS#)gmTaBLXEiisͶ#'{M^|%|Ct/`i$ )%\|1X*Јe< F84BqXXl\tǍM2ݗNYnqwkL=V9?m2,ͦ(JVHȤ}jN0vSPPK}Du@ @ ֓&HmdH&97^t+ֆI}p؉Ǔ.ϟ˜90M 8lEIX#L 9+fdFjl<ʔ)xCOI EQl@1c*PU3iqBHG%Ii]70Rbb1n7akq0I )AL+7== ,AcР-B޷-D DMZ:/& =evB LKHxՖplTjeg۵T-Ů٥+ZL`HJl*_g\F e뭬\}q SgT5,H,s_K$H\-[&n{)SxHDd"J$#KPt-o#;еvIɈ*~|{q7Ekk;v`͚47ncŊ9r3eyQqco8,FaEKK+_ ֓L#.a|{'eH$hmmLU%B8m8ۻܹsdTܰv)_VkJ'Y4=y#RiYMkj! \}@ᬬU9Y s .R_g<'sݺ_|Kʕ3{)t|ƔWQZR,I|+_|{>AL DUc&]AkPQQ>,ݼy(΢?*"J48߼}I޶vbz,`+g8aLTɶmۘ;w.Rr U[U;ƕy un؅*pz :]4/杝'Emdjodo$?)#H}B#2!IJU"SV6CCUSCEvN'X`PJi)H<;j wLSGODd2F$'HfG*'|8 U^XC+oڴ [omaڴjn^ڂ/=EKK+W^y%#S#\R d ƏO0y:Ə`Ԛ߅ݿk;(kiӦ!2k׮Wpq\7OxB9Bww,x"Ms[^ɫ[`+[lCxlfPԃ=KJZZ4u !t#AvZXH$igUЃ#ᝲWu 'Q6F xk\sOFmN~>W]γ+WxfVVV{R[{k/}G5럟}P4FsK qٻw/-\w躝P\DR'9ux=v[pH$Bkk %%TU 3P`0UC$3RL"Ȧ8uuuݝ*d_`0l0n"H䶙پLpS\'p%xQDv^]שodhZjĠEm3H?# hL}NZD&d;aM4FX ^%f`$h+^O9!!)!Y)QE&UER.Q^T.#UM}R!Kv୙:۱|bg.e䩭 _Wx)--o3f BaV~F<yy/_8"bfSxnEs3rL,3eXV2>IJI Rn0+X|q_=M)_ 3adW"eWe݆7=ݻC>Vܼy%FTp/rq>OxssvFcQּoifar4' MMMQVV2&|vKIX&E8ax%M:Gw2'Gpƿ1̡gHFUeH$̋PYA];0- 0M D7 0MJ E ký"]*+ GxRYQQQN`S:Ny]JGI(vvr<[ZZe I۱S_WWر*>_ްOxcfV7cSIÇ0vlf %IXFLtPʮfZ԰,34Y WL10P[O|H$D&Hr⴮&ɩd,,LR}s8 P..s(O;i^m@$ }(//.6n{;w_|7|OIOO~^2fֽ.%K$$9BsГl{{ϰljdU2Mz- ;l@{[_yK=u g2p~F#seǁ65xu;$cz<'$1ox\ D{+.b,&L(CEn~z1ћnؾ}7W_v5>-Ǐ#Y[p8ԌL!ƍ`c BXV wx]vqWPVV6bp+Hf[ooΖV+Q~JKK{=̼O(?_6q :RbKNJX F$ocgKS0vH ٳ~Mv4$u!u-:3~C rU~_-=>qǹooٕ+Y2^/h1o?׿5>XhwTjh,s=D'|/| tvvblǎc4i°/DX<чaI'%'%#@se3T:biϓOO[dfVC& mlʰ.[ͭޞueY6/HDcbZVJ|1L 9"I8o SpIk|÷-!݌?@ @~~~|! 3륡U99Teimnװ,D"aNW2e,R[pݸ\aW拋47#I*vxҵ2Shii uVCqia!7Q11̙̐"De傅aI4R,eS1*x""'X%%Hg f$eI"˘*Xwhg'V2ƍ,+r%=ͦb&{y}~UmΎJhii4M~ e.HzKmbsh 62;Binns"49LnjHIls{.gϠjX$rk"Ӵ0M4LuϋPf?BVPEǞ̵/aY%Ia-t2RLӤd8It13if&-Tmq>|U+F7oIUDfϟEcJˋNn_ݻr9u ihhcm84 ggiq__СC\wyˈQ_FpٱcWw8Ybv0\r 6tDFH79mG"?u g|q,SD " 7!9RiG;j4!(/gkӼk/7m=yu͇wpK< o򆆣<3|rG?³O=]2.ks4;pG#|lbFDw#Y<6ƏϚ5kBiEIGR?F]muuuEVxgW- nd2I$vs`~*++O .v11ݴwֽHDyy9,^^Gl/7h1Ēa!g ,dYA̴&GǼiٿn`)!Fڏ ~//3' SF~Qv9'+Jj$:YYBNzK&"N*9R~U]Ws݂Q5}]|ۈF"bQwjfΜ:"Fcl۶w32tgʋG$T_Fpٶm'$iwq7xcVp)K,#̙hՖz0;pJR,nIT#Mc&"mHDʩhsxK3OQ׼oizzL_ULXp෿}8z) -TM̘1Ow<xh-8pIRXXHgg'K,ᗿ|ŋ/zD=H{[_?s֐F%NՏ{c5h|O X7𸜠o1~Wx,AgCX1cȎy=rmWGw a )L{n'G9b̙ȲL<GUUǠ/੢1t]G4^/v"Byy9cƔt:((0 (*]]] ]׳"eYXNzҵ$#,^:;;ffHdV BFP_4ӒD`ROJtI:L8:988Eb̖Egg's7ʥbKxl٢w E ~ǣ<%sq:IT5%(e9u$Ruu2.e932,+=4z2#hg|wA֔o}M :\5.u6tP2M; h,3DQ-TL$9%HLY e(ނi~4Uy*8SQ4]ͻi;sU9l;HQ<FJT&Lh#S_}\u%#VKa<پ=U/nswr7iZHS3kΜ9O~?90w3ᆲIP6iH_"VXqx鑘VW IDAT %}/0\$]Xrip?xK#o PUf\A & ѦcJOj'GV7֣',>+ ̿hNHMM5'G?ʓO$e䂜)lc΢>UER[gnWL+T74 /_"fl8e <*X˗$Sf!]n]g\jҿ^b[6vR.R]7D"mH$p{<=.]!n~׼^/Ѩ#ttY%m&ǟ`hmON&TԴb#Q%ضSfY6)1MӰ0 Mw] |%{.}퓝/?2V}-Ci?^.E$n%]sQU(FU3 }e`M2H-լ0*H'F1a\ p#޾ybV?H(` pi9MhmYgC}M í>Yr5^z5̜9}j>^{[rK9c;޾ko˯S]]CFF3gN笳N_x ׯDztnbw wRRSSCSS#Cs!!c%`\(=%^chDI!( &qOQ_@X,IQݴ)Fӻ@)zeYqxp4NN!''χTYI4u~Dۂ99D4pimmvSRRBAA@!^˱$vhFHQhii@ f^ Xa..5 RhLJr _H67DG;\ҶvˊLC/Ȓ-xB@D8&TС%l/#vFw!L!BÂPFMxp)p\!D\$,#~-}$ l)-!10tM ?{qS||c0QGYbeR n @cSs_?lFQդegpB1ݒX+YR:@wX6<^-//al1dxu²A)g܅Lͩ+#l2K|̄aa&#t]ۗEgo}~s _ PS9׾fxDo^RQQ~m\st$N)!xѱ, lot`GM|+yCPLM|)B!qk9"RɆWpl1SOeP;f.*m&YW_~aÆ`ےŋ6w,+~k;FyqzY!O8 7w},n/ )%sE1|3OTjP# Xy)//?!wui˥Z^`͚5\s5'?NH{q)0n8^ZֈtHtWJGRh>/jBE%J&/L|}ZP#~$$FGm -җ-aŊu +4540utr7ĠA%xÕy֙|JJKGE8"38pB**3k5Al5I 2t)Pv+ Rr9gWܿ. I{#mQpJ]a[QI{0PtXJw***Gg~Eج\C, ### >ncR---=tM40;Skk+---4PRp *,,$??˲@Lj 4*\t[cǮLu!0]ΥhHTjk95$S`P1b͍c[X&VYY{WHVUSeJiExn4M#??)%@XœJHVSN"+YޓtI LGVt)/>y]y $'Hg Y>?Y%%XR4m6obƘ ۝OH[WaİB0p>p$܎vL4E,Htz\F&W_qooo';;Ǔ. B!h[T@:@lEJ  O1ƶ %1-IN`i[>i@pmm)Mo[|WLY^$" B(JҝSvjc)$Eô44HIc1d,F{f anJXɬɅ9ttcw@7f?e|Ph tݴi3)۶U0{≿˯3z(zU8l /^7&MଳNo^{y(..BJɳϾ 7eFT|Bɽ8ln,\%izD=9Rڈ*p\uŜ|ʩ}^g.aTB.; ]8aJ8מ_~]$USz xQtj#L׺F˲0- 65 0- ǃa;.mcVۭiZTVVRVV]0tӢx]IF lFilذǓF+ܾ7bP:X1PPEiQ4˜F&-cnŽfa(*H!l탞V1*vLMV׹ d{LXꔊX Uk\OKr,k vJӥ0\@&A}H$)m]NdquM!az4,i 1oesQe éJ?rDG ބwD!Ctp pq.ni(--%*iT0IG(+ؤqlq4!]i@t3YxnS >7M8|p\~}ނ<+lK|w-5dgxpA@UlPÖ=fؘiX$xP8i8D#GQHIG P tˊi"ğm#DO=0,~zV1lgΏq+:z% |i>!%wI&9\O?7@K'6׿L !8yŗYx -fΜCK%kv甖j^.})i7i;aY[P3Ab7s:gfΜٽ/illZmƬY;n~a|MxǸظq#>L2>?|G-o :^n׭=|kۉf8欉,gn39UoriV{=g Ua&'O2\Beea`rG0b˖:Ni;h}/_α%K88Eͷ_(-qI{B.UAmw9l73jHENc&-1."I*-j-uѥimNHlŃvZX3v{hJbQP0ZOեkaAHwڴiضMMM ˖-cݺudeeގi;,6Ck׮%BzjhZHwA~Ѷr"%ZgJ96%JVAC@l%܌b@vB wt߶W퍈DRAA-GaĀ-QphwKP)gٗjn yHU[H/f>()p$;HizRvޝFdz#,:'`D<pAtьh *.b۴V NqSP2'FP6r$˗-KDNMM\2P6ONKKKۛy qQr%3+,P\I pI(KSTUUP#0L ڪ6[ۈF"D#aQͥ+eoց2zs: TN_'e_ JJH"NcH4x^\n8 I$CMux-FU-,EA(,>hYx3#9}޸ [A' 2ц%6|8vf"l& %β\v^y |޾^\\Ą ;**b9?۶yL9hc9ֶ6]_W455>'Yie\M|'(BAAz+sM3\DB4nلDk Fm駟Ob:c4>)Nn% >h0>,gE1sLs9vi\wu!Xn厱G|/K7Fv-m WhFXθ66M4ĊƱ݁-dlA]m mͨl^ߖ/ܣtys- x٧).)kz*d"ږDU.bT!2"TDcHn}[Epeg{wO7)vkY]K`-f!5$aX΅#4M456 0~Ԡ@o lqLg<;1v 鶷3vX|qbax(e%b̘1n0UUU= ?@[9ަ4Y*IH% ƤjRƑZBq0ѝ*mRx/0"N ¶zz[Rln8wZzWl VV{lICZ'z0wttpF.\n7녢8uUEz#"!nbhZ׻y\!(,*b-0l.#҂J" ɻ/ a>I ''}m6 )++$r ߑ9#Q۶MYYэ;Ǎdzy6m)ZiCx}x}~222ƟuA!iI0 b8qSizZ[UUM"㽧H;;N_t^vՖޖ9//m{gws{Vz/ g;SD~qlK,BU$$+Pja!n77p G+9.A~~!nOm0ìے52T=dd  iǓ1:s?#;;W^yh_VV&~N͛&yE{^!-)S&Mſ*6_|Spky76l7tsI6ueJ (ȢIO?{w`0ٳgp՗YGu֭[MEE<˙8q"'OFuK '7Yr!JG.xKߤ@G-pCO24P\FAXdd wk %o`y u4e^Pi+j#()F6#Lzq #7/V ng|+m\1]̥=c3R|Ցک&UƤo,:.iXvSJ E1AHac p+ fJ@roPPU- )Kdoվ#{I3ֽ7}}9ފ}ގo:J N6MCU|O.t],JTERd9Q0uóꌙ:&$_s2ZF & & QPNN;'p s;8^vEtv}'8#k_444lrr1|x~m_uu-7t&M?p<\JKK{;wn79Ԙl᭚Ȧ ֍`(GLM&|'vmD"z,{$O.'t+l^~=K.oŋ{/^̱梋.?.ۘaulሱ6~]n~K?gdn~,e:Ae{{X*boфM_V&]XTVnP[SǸqL: 떰ٌ_'oͷI9wΡ P.Ι)cjInĂ M<䠃&t*¬X1{*G*O`Y%\<|~$EĤXĴ$q  vhGJLLfXEUUx<N!tmFUսBAIIɀ#DI a;A(IS˩8;o]'8$( q@BvX/N%%a;a)]ڈ3t$zʓYQh%* ~s՜2ф IDAT,OH._Bh"6l@IIIz'4lv@K$0 zqF**+))ajEee#D"a"Hfsٔ *B(*PPЅB܊r !P ^z$e#BFwUXPGliqk_4RDʺt4Ex-b[D7OI-Im4蹯J6[.M`E.jus*PeoYi<̪Xbc&M妷Kh{4v{&j%KO?RSSˠ{q,Zs bW ODr.fwA7/ DR簷` =IbN@E!@ˎ: ~-r5rU$b)4TuJbfcͭm47XGscgu\LӤg`NܴiSZHw˖-*;|plN ,f|Lj[P$֠6⸥(3Ha"I$)8tgTqdi)d frwЖ+zS*('*vLUDI|ױND=xe)H%єDu;N~~شi~!Hd'vp10f-ӌu[lƖz*MeC())&G{]lCC :%l 4coƜ,9aIKIt>'dɐf.tz)ݤ?5/N!+{ ds-7`ے7|>SO=ΈK} +~=z^z@Qi@y %k k =TĈCz|W]u7o=of333裏GA&ԩSY|y7[^*>lN].RJ,X# 7Jc8PeG}11򃑴Uc7`ƭ9[|K|~55d393ӏ9G169̀RȒ (ɳPE3.oE1 pSL4M<͗BscXPb|L uHSC-`24ԩ|r۶|TTT`Y,[kגg!qơ(BĽߥ!V"h" 4%$X'UG;%FB.F]]#,^{ V/t=Xhr +.ŬR;8dp@P}loH)ϱ,6lcƌN) ˗3yn ΀!D[jDu' ={5s>aE=P ^%E^|^4 `)"+&d) L@C{~zٓԉm<(id?e7ݏ-Ӡ mm$gpa&<Ǽt5#&MŗTN9۶yGz=<}̚u&M`$~晧q㍿g~SO=۷b*8ٜyx1M p'f&;oYQv%2wFI??sn~w^."QUUҥK1hĉ^N:)쨯WǞ>}:_|zj<YYYrsu| t$ߢDAWE2X!W~G3d\2 &0CI~dX \alc,%5*8Uwq1 J*eAfHtb.{*֬DAA /<׮vZTE//rĥ8CxxN'sh3g (=1]/g @uP4@ۂ07/@`G8X4t\ Ç̎t<: z%F&J].WtM;aQt!lRRNs.Iх4 Igy$MNKf% ]-+AS1$Ua66MՐ/o 3v eYi`40 t]NJ u=Ht}]u&Z7[?ʏ?#a Է@4|J2K{[feo_Ϥ rsJ….Z=3){u\so6y<؃L|`̌}ھn˲(-i |w;]#+.aJ}w*%%%x$u%Eīa֬u9<b=}#*Ŝ]vŘC9Gs!mD"=1 H$ Aiiih4ϗAVVntSMEҵ,\t]'REQ0 rD;B.HimEHG7B:;)bPsK:I^` a;l1W^BILF”x B,;%n(\x\y4GW7/CJ~_qwA(q\)\E$I4e|iApvج'{)ilFNNn݇/w`(D_)E  TRA+9O hICP0jf 'W2I1 *n"2Y6>H(N*8Mu0X tF І"//b7P><"_TofߠT1T%N2-"T80C(Uua, [ʤ3+,d;$/mm\@T̬lF&IÄ"& 4FT}@OM?#`X$HsЃ6%ry?aɒe3{CK$lܸX,δiSw{^c { i[xvN?݂.ws%W xxX,ߏaX.G2 O$m<xm]שSJI[[6[vD$FNQI [v]9>b;KYh~pٺ>tNp477ގs yyyԗamuQD"X-;={k y0[ak2HicXG ߦL? c],rXw3sH6X7wgs6bmM,|l &tr}N1/~2oY $faM &)!.nL&h13^f!f3LƟO[G39z-97Fcwޅ,Yٳg#1p1O%''  RH(Jwu6x/p}w9}FUn˃>\wud\,V#S~Tz}pB.r/_>` )SKYlǎˆ ҺUUU}]^/eee\)SA3|D7[]n?Iv*JYAu6`ʀ=@sr2TVV2x`f̘uvHaa!cǎM6Caaހ. \.fJ=R$Y.HQ(R$I tZN2DG Q)]Lz [s}dʋC&ݒ9ȥ[x\ $JiضM<OvFxpI0zсCQ H$\m;iFhksw/)J-yF(TQS&0^Ta՟Ås zq6wz#>>|8#Fap@.SVHj|N8~_ Mr,fLŕ71o, oLCdnӕͻ){F r G 8ú.HtM"h !:;щ;Ѐ墾'͛Ytit׬YC" XlЀ3LOhH-%L 8״H`ٹ"z" 2G}vO=A6mzC nc[xdo,5PWғƯs rTlܸ P?*PXPxeq+/$[L G徹m #y@2 K稣?K/Uʕ=z,;ձq +'?`R(RB:%f)dr9pG`X.Ѩ-l[ĉ7^cޣ}"Sc=tjIJmTkM8PCS5`Z /_kfq}pmǔef@#̆m1P<y<ȵQ;8wn@SlGb֭SdeG:o1a =6 L>m 3I}ɷNyfj#!ELj0{Ӿ_w8Wsm_/C ocu̚5[o%%{92%H-iLx;m .-Zu]G}3gW_1o<֬Y÷>}#zYzu7w=o3BU[p%#ăر.rc177"]snl*R2dH) ^x6asc8X]<>pCWbG~&\'ijÉ5SVрS<x4 rW?wcol JtI޻Gq_-~˶$ES R-+JUPNsrڵNJlTqeɲ[u|<ܸI4J&HzH eǒQ=`83=`|?ka3{oc{]Sp E,wܱ/3,]Zr|sw߽?3C]X|٭^{oΜŧ>TUfƥH&;JLOOʕ+x"jkkxB/NQ.`\xSSS|2`X>ŋo]|HүRP&26kmd @B6^Y}׏Xp-…X6kYTUPSi/_݆M$Ƈ7n"S2f9V u(2}ȟ crrV5fff;])_Qn,DeeňQou]U¥Kbq]9" >(vIf/lEf5jeM!Za;9Em?or޷U7roRU߀_R vuj=Qwŵ ~Q[{ .M2.M]BUleeex>^z ciӕ(Píފon~5UŁq$˘*7|?wuv]2TTl\UU*++xRϬvwSߏkC TTTuesNoÆǎٳoatte}$[YYr~~eKxٹs'lj'0>>y3Uy93|1 Ö-[o@mchƏw,57^;һI _JN >$oR=.&;c୷Ρz|L{gg+Fۿ'm=~¿ /|sILMǕZ,mR ]ćcxWWs9IWG555g>=޿ vլ\o.]j\rxw꫖"\!syYR) `˖YOW>Z|}ן?]ոk++Cl K8{WWRDdWq9j ;?]o^/߿RI4_uS'B?8뽨xy,FJYYjjQSS  ըJ2ZnƂџeU^pF.vZzYv⡇w܁|[rN7vOq>|=}.]Bbxײ Tp-a+3?)c1DbvPI]SSޘp$pv%~ ħsnJoŏ?9SsΡ o G?R\zz=a \uB=S;T‡sc&>p~UƛZhKP Rr{b[٢ZZ.#?eDLL~ʫ|#;78j@&cp[P"KܸoƫqһH&.wN!4N{[e(++W|/K8g̾Qͫ_+O&YZaVUwĥL%n.=;$f|]>yمwg~>7#o3OX_'٧^)w*Xgs={K2VXgF{{#ZTAi[2,+{#2c<d(2Xt1^(:H.MС>l޼]#"O`USCٜ̽qv2)AXE[#|]j09] 2|5/iMߵ+gfg\Ao&S166[niWYF|#B<>Hd?OQ^^wf15uGŋplOeu%xOv333gH$C~Y9 V-:Wdt Pn 8r_S};NJH$gC7|Or=[ҀTʇƢk^B<>nEy%᚛n4pmuKj$~bev: v\uU::ڊb0W.Wxlއ?nj.fH*Q^OH w*sAUU***P__UVۃ/ū-}u`۝+IΞ=g?[o]([_"㊬ҬCeCK۰/X{:7}H$p) $.;W wr5(988.'֖Xd yO஻REP}10j. ,0},}x]8x#7;2 ffDb36xx=+HTJμS TVV|_plb^.߄ ccgp|kں xAE˖l33 LOOW(Guu5*++<:tE;{X8w߽`jhouλBm{=UcmI ]}W>.$Su)TfkJQYY- pF!.PwS?MxpUHTӳXߛŪ;`:&nJ&IYYjkkӯcȋ'61}ݮ]{Rd̕g2%&O\ ۘöqIZˀ4֕׏ 䯈MGQ/T~b [N/0]UWWg$ObH$dUWly욖s;0Q^#!_E&w>T*g,OB!Ppw((((Cxv٬)A>$0Ds'!R(8;IyGyGyGyW\s4 Ѥ\< !BIʣ<ʣ<ʣ<ʣBL&,Ơ !R!(((J]^]!B!BV曛q).sRX*r

~*͏:]~)ӿV+NO) U~UOy>oCE3'.Z7~KKE?=yF>`;NY"KsZ"ӿv_ɤtEL:n,_/"9}d;&ufd+GsBv.kfijjMi_8꿥 J17׌=#&KsZNo._rKcʌK[pqמt!Yo.?`E95f{A׉R/s*hPA[/AlKl%hLol\#<1BH Nֽ^FF}<=F#bͧK43VVeysFTiyFeP_'ӌ Ul}q6nڋ?Y7겫Ͷ-k3]>oޔq?|+})p_˓YOQ*N*ml=W|Ǯrfbt-lZʁrpn٬uyfY/b&ТƬӌd\߼|/[Df|GFr2$P'2##C~cw͗!|[: דg|2|;Cc'O{>(#yah'"t:ݿ8o 0B  d t--2}DG.|3ҲS"驭/͔ODs"@oV7n sP<>"ϊD٭7+?z5{1ۮ^ Z7$frQ>>ݎ9d/ 0BgYVnOpD]iyN>ȋ s2'o _\CI&ЗMlyeͅt^E/[ۋʳ?yv+f}e~+.}lgԧ񏖖ά,z-  [xŊ ĉ#>6[>Bd~>J&OEҌi٩~Ϸ}:U>{j˻2W-r^+Ye;?f("|{1ҟp=SyI}wcA::;%HrQ>rg?ȕ22::g1.KIsD+V34y||;~`R~ϖߕ?5-/;УSu]2ZёhhfjS;MVi=O[^{0[>msu*.NSRNanȳ극SSv~!۴vcŎ@0؁8x5o]8Ӆrx_ӵϙ1+w|L9~iz>zx<5feKS_ek7in{3+ YY'G^i/ukE#[{L.O>/w}fU-/["ߋџU5瘭yvgVf9[.8m/n/fjjZ[?ˑ_]8"Br;Iyjj;BgK[?#迹 ,\).BHÇ4sZѣ}Xjs P^1س-Sɷ8εOyx Bط9e.B!DGB{&fŔC3] 4OB!P((((TL]!o4ʣ<ʣ<ʣ<+UyRyB!((((TLwy/_qᱶvA$B ')((( Uf1{ߋ@ `ځÇ`^C9{ ; yB!ӿGyGyGyGy(iKOϗ09y?5b'SA[?ϧjB!D^z7o75w0:V^` yKWaY1{CXn6G:8tk׆TRr:;7w?N6LRO#ں $HIJH23K͛iz2b1LM]YWɺP*W^e3l}}aBAdRy$!L&13@"Hp#^!=s&A*,y9G8Lp܎ `dd(܎T*.FFL] NF3irbofw.Nυl $D*H4Kz$򈷈FپXPI.QԻɴtbxx0usP'XIҳ:%ʼnr(]ra/4Y*x~?!O[LN<9`ڑZ."k93lv:1ϵv*rzkؕDqˆz?6:& AgG[[k^oե; hooH _kj Jr^e.8DYK7NӒF?ӌv]YRolr.%GyΊ^DiT՝6ЛMeWF.)ѵi/x'lZyiN Fҏ~nD&!Ķm ~|yGg/=%%۷~㼀˶m?\ 3]\yhnqxT*5/M>o6_sv5"f;Y'bgT+m`>2Df־e/UpN!5MM<06v hooCyyiy{S{188n( lY}0::1ܣr% a߾t9vut)h|B!P7VgJyě uY Xf5֬YbJٽ!cB!BHPD6RJN!BHÙ.B!B!(.ΝåK]W…B!B!⅙._Lp"v#ؾP vD!B!M-jx&'ᇿf:Q$b8z{{Pm Z!K/͛7il-:V^3_>7)bÆCXnG:8tk׆TRr:;7w?N6|:ȑchm]I4_Ŗ$ $Jeg~055͛7d3bɳȓul -{UO+o8gdɤ$$IB2)!Lbf&D"{…yw|IZ"Z+ҟC\Jz6]xE/lX Za>IH$L&H$ #%Y_w녙.]!}\LRxo`V>TB!B!D>ˁP(}]f|>H"(-B!B!p"v/lyl?tqNL\_moٝK,SC=!d'fIU(ۗ*%z"N f:[*XIҳZv8Qn7?W>LB,yGECRtkz\-~KKK'N0nQL7vf;ͮ\/ LEeS[Ů|$Rv3v䲼vbԽ[zlB`0mmyGEWW2𣽽J"%Kww7~)v*%zM˻pDXh\A'mvz^^uz}#9fՒ]RKiQtq ;0#Gu$I|[$HWB*y]6oޔNӓit aj&'Ϻ"Oօ-U?ﯼ֯-㜑gK # ^''Γ$ ɤd2D o65%-V'j ZhH>jr)vh ҆x>wEcвa/hS$IB"D2@"D<>xG!Bڽ|?_66vT^[X|t߽\Nm)纜ZDd;Y'c!B!KѬDbthF߿ G d[-5 )Pd 9=&7 v ۲S./0} Kt p,YTTTxFX bQHK.AWWnRTk(lO>bۀ:My}SS+N>V[^+Tk J^glfӻϩ:(W'$wY݉ۃ93D[|m?ksp\ZlL"/l֭>Rdxxv=ht"}==!]##{F'45 R#}\Gh:U2m6hDztZՍ2ٷء[li^R(Lbpp^ːn9 DJ#EtinnPaX>?.n m >*Bn{ߌ}%v.|(}:d""/߻\97w"D",鑼#"eb?C%DQ^$҉4޽^]~cL&KFNDb!7#9m_-CilϒޘWy[44,5LfaG 5]ܢgtɁ3X̞{HwsggQusVvQqzkؕ]_Dnf}\z?fJT^;m_fh3S aNϠɇRA466 hkkͫ<-tmT)YkMMttSI.Qk,_ޅ'–,"A'mu+jQr 8El fNٕKDbtm @[1V}(͍v6q"[ 6i7@BĶm ~|yGg/=%%۷~㼀˶m?\ 3]\yhnqxy;"f W:U'bgT+m`>2Df־e/;_8/;3W b~I;̒_9-x^zj/%!-k³~FG7{YB!7.ǎ.edǎN#I)*++ uc`z$IGi/P75kVc͚y((݋A$=<B!$E9=QMo }B!(Lt!B!B Lsҥˮ+mZZ!B!B L/v~U{LC;plދpx(g ;PWWG "B!B&5 | g_3(}X=(۶l-Bॗ^͛4NS+-/ƍ Wam~![`+#s:ԇkC*y)M9jΝ;DwwPf^y|1$IbKIJH23K͛iz2b1LM]YWɺPі+o8gdɤ$$IB2)!Lbf&D"{…yw|IZ"Z+ҟC\Jz6]xE/lX Za>IH$L&H$ #%Y_w녙.]!}\LRxo`V>TB!B!D>ˁP(}]f|>H"(-B!B!p"v/lylW__.xSؽ Ds T)GE$2lEJjMuEd 5]2E},*>ͬ:-RleՋ 6кƌD퀋[V~kRl^?p,N 9ԛBDilϒޘWy[44,5LfaG 5]ܢgtׅig4~ͮ\/ 6EeS[Ů|$Rv3k䲼VYw+YeN7!d# AgG[[k^oե; hooH _kj Jr^e.8`Qӻ׋^P?!"]WKuՋ|ޚ.ve]+jfB=wVDBnf^v|jH&BFUU%m{p^$˨ȫ<={l/)yؾ\m{"^E+WvVf?ޏ5ϧR)kt"f]VZ'buaPm`>2Df־%RgwX[d!8MSSO?$AccP^^fqZ<^ ۷JB,[քg:oL?x Bط9o]{](}B!$TVV YI<#x^Bn>k֬ƚ5QLQ29!$_ B!B)Jb"✞&O{a!B)8Ӆ3]!B!E5ܹstJ[C!B!C0ŷݻ@uu^7?>|۷"ʙт!B!ɢE /==_Y?pUlpcۣ_?cWyt^ze4:g05u g,Vֻ*W^e3l}}aBAdRy$!L&13@"Hpwc?;7ށ; % ,^B{v[H͋r!B?|9/S*BgE.^_Y˲)ufS_#IvQQ/WzQO҅6tG!۝KH tƍwPB~6D32r w?ht2}_ASS "%yQD" hm?\hv/21 Ύ\3'm+]׻Ot@7Ll ̖Ū^gkoug`jj+Ќ vlL2DLaS5gtA/;y&d7@BFkKMM5oK,8Ѐğ133f{t ;w>ɌH{޽OQb1<w|<ۃHI2=Î21]O?IpڽH?˖N:?LfXNL3b+햯$f}#ꏝvV 'x)bsl?[2CH1{Q05/"؈yv/  Q fC0n9 DJ˜#Etݴ5lix/jIfݲ3 EFGef@!۵v;s1!L466Wu9.HP^$ ޾k֬HI?kn.9yhxx0:-FX^䃾V0[, O>w{,NI?)6*A~1C)tFH.Ze|ތ›oƎ13'hKUU%m{;w>3g3==_FeeEg7TUUw׾=\$lU\ۄb.23338teL BX:~}\$6B o(xB4c͚Xfuy3LBm` ?{]}!vћ"J.BH.)݋R.#'^'uIf`f !+z">B!YB!x/^XܹsgZZ!B/~2'/fO5~#3]!._Lp"v#ؾP vD!B!M-jx&'ᇿf:Q$b8z{{Pm Z!K/͛7{-w0:V^` yKWaY1{CXnkșS:8tk׆TRr:;7w?N6|:ȑchm]I4_Ŗ$ $Jeg~055͛7d3bɳȓul -{UO+o8gdɤ$$IB2)!Lbf&D"{…yw|IZ"Z+ҟC\Jz6]xE/lX Za>IH$L&H$ #%Y_w[4C/ J3֭|&B!B6E{$I+-r!B!bw/ra\̶W.˦3O}\N'ujVV>EG9YӕҕݲRi|בB!92(H;f*M߿J7 x} kϗ.m?R\S+?Q|[Lfn!B!V(5]@VHWata@VO!Jl 4)~{ ےcz:p8htK,Fgg***<#xX,w NTUUQ1(H$K 7)5]ۧO1m@wxrZ>clwS_uPDN3pK~iofl Z7~*ԏLq:6[>+[! `׮Nף>#bdv~d\CC=z{DJ?}GL(۶=@pZEt1457мIEeg:#RuEFeՋ`6кƌD1l`DB+xꄭXտڻ*NؕV9̦];l-M!xv|,#@H{E"ȫ<-b}43<̰}Ii;v8vz"^X%oAe`zpwlי)d򹶃L+7a5b,&_Zj۸3еjWZ_l+>'֕RxLbpp^ːn9 DJ#EtinnP]>?ڙT q*Bn{_,SE}Tv0 w "8M$͒ɫ<-Q/!V3TKE2--HS|7G`F r]n&KFD+>T8aӥ7BHhlϒޘWy[44,5LfaG 5]ܢgtWεt (glٕArTt9fؕDgCeCV`gȵ^gsʙ6` :?Z*x.݁e G{{DJn_SSTK.˗wĉnE܉y2u.K" G-rMq#!Z'QXj譽aWF.)ѵi/ԃk'lZr,V;Sǭبv$ZnBHĶm ~|yGg/=%%۷~㼀˶m?\ 3]\yhnqxy;[FY"f&Ȧ:[*܉:}MͪNnf۪_i[V‰ŢПkGfȊ=]\mx'`l ކ2K<={yꩽJoggX >uߘg9 os ;P;: W8SRTVV YI<#x^Bn~k֬ƚ5QLQ3])7P"'B!0w{GKqoa'lB1!B:x>K>_;R]!B!R$I#XܹstZC!B!SsoSw?*o~8|or!B!Ɂ̌}ɳxᯙwtt{>X,m[|D!hK/`M~V` yl9~ذvǶ%?x֭[kzƑ9ڵ!NS ]-f?GCk*Hnn' IJH23K͛iz2b1LM]YWɺP*W^e3l}}aBAdRy$!L&13@"HpHDB!B!"kE>/g+eS1SOQ{ԛn{z3 N晏2غ^;/j]!Bvµ߿*#ml옥4u:lA NI=vS߹/)x^q2j`%v˦7фB!@~h nь4FGɨ>\z?|H6  qҧiTBJ0 ,Yb)g*W.O1m@ __QdP~:*̖l~n2x:׉hEVc5?uX\^Y|lEFOvu.H fh_ޫzVh֍mg-bf^Y+BvzD\}}=zzC ূt˜}AOSS+|rD\XT}f+Y9"uPjJ9 )>v1o&?-9aFꏕrgU[gvOZ`A~ANS>"ڏ8QML6m[Gw([hN!pa2.Dg^$ *bvBʇS/[֖q2@\5!pxiQ FwwEH'8aKyYՉB5wwX ^8]~;6AU BH$%=  !6(ttbxx0#M},߫u Bc>+ reuZB-3Vܰw1[~;v>A B!$46gIo)g\Wtiiɓkd;A"Nu"`k=Bt`]d[|lĩ5USK{q$"RA466h~RIz>NZe.86`-_e)ԃl= -rMq(YыH9EIZl-@+nPafp&l;av}{֎>\6sZQhǶ鼴d!⡪۶=8/eTVrhBUB+WvVf?ޏ5ϧR)4psc3ifd8!W48d[ZEw+";+vl;+rlΉEvEvłNunUB}B}x'`l ކ2b[رׅҕQ!O8ӄBTVV %IbI^D!}`vB! /t)~ !CU ~ !B|~ߌ1]!B!RŚ.ΝåK]/…B!B!"D|ڽ TWWE 0}CG}{/ᡜ:@]]-B!B!8*>O[翋˘<FGGwAne'hAB/6oޤMuXy_~6n` nwlaݺyg霟С>]RKiQtq ;P޵dy|1$Iv:$T*8󻄩)l޼)'8A,%LNuE e[m.kXsF-/P(udRy$!L&13@"Hp&R&=M+B!{,\N:P(H\2_66vv>/]FwQ]Vʭm}gz)_E*QyEz[-K.}j{B! 3]\ bthF߿ G-5]xuM>-rOw6!B`z:p8htK,Fgg***B,g9 osJ# ӔYÕ3)ZZf3[6 R=CNubp+ZFUd%?uX\^Y|lEFOvu.H fl_Q+ϊڒhmdžD|RB! #صqDs "%:bt5]k ^W6rD꠮r:pSF#}h]OK}сcl>٬+ӻV/_)ݺ=--&vU#;ʖVB!ZLOǰscD"سg/DzMlNθF/Mt؍:j]glN/+zrk}^07֗qCN}ȲF>MҚctJ = Ҷfx! LLLjG18x]T!Lv \cܞ5LT;Y>W粮V+B5etwvrDն3[.w"R D",* LN fBg>INSaEh%[Y Xqf؅ NgeB!hlϒH%b҉'ۢ|ζ΋[iA)ey\쾒6^,Wpܪ"Nۄ^L`l:C!`0ʹ@V* xakA˻pDb947_/2z@mgvEEn/Ǝ>}"I]6"3HJC+ZR ^9>d\XUy#LhX X9Q>X^(2`)1WV8P?$2iAt QHzzﯪ`@U]U۴ۇVO\\6=7yuu7Sε|4]fھD=&r㻯Y,1c0mR>g$UI'TYjonрFDhÆJ)gL?q:q`H;fBPpMz]KG2.Ә *Vb޺2'6o0ېWKNvoyK:YMYnB?fgVkܪ6oޤ>Oow=ܣt9~MJD7 V{٪őz"?^rq" vHAF\tI}уvM7RrV#]hWWR>M511a_UGU=G% u7S@|֠ݻo;謹bͅO+W={v־F ‹/>|Wg/8WxԗCMv8ڱ>W{t IDATj{5_O{)oTrL?V[唇Ko^;PVpC5-Cue,N[իQW\Q/y(Ǣu/ޖ^/ےt47f=7|8p8Tׯo~sM]vm_ˎ_ӱ;_>_KPuOʟ5]r;7ڼX?O߽Oꋪ2\>+rP]v]]~M]v]]uUuU_K~䳿9ttSv=A h}ZE5vu!u"i2 C…u!5;;i}йm㻭i+n3vm7g_̸l/Uy܇66HKY'Ӻbr,ƪɺ:|:\R?S칵t)v]{ǒi7N+_lNr`0XLcDZVt@*Nb۴qi˱4Ne*MuĨlǵTtqEbsvNjaؒikޡik{هHbkF #G]Q_VwݵE\:rQ-]\OsUsUzlMꖓjDG~J4n]RnCٶW7o]^pIt!ڦ1Z>}닐]\cZgᣏ~ot(ԅ ڵk t.喩Ŏe_X?.UϾ:Mڤ?ޮ2ˍ,eHb=UFy_B$\rh.cQwLsFyk)Ӵ&;͙=~w*Gr}s[d>~t[tLMmVs㿩͵tڧ6QB}Wml϶٦1S,ɲyF"F9ֳtzRpaZfC5k6,3vD{{wӧ/V\lNCS1eS5)僖uτ(Gm([#Vb }rQIԶumGF-nf $ 3gVNPWLƴMlMvcH㾫 7Tەd=vmE^3b,Ti*333j͚[obٴjӦ; ɷEV'OZ=]ط醶zA{ȭi=ǭZsLLiqI=5LPapsie"ȍꎓqp9^%ʛ`{ H+}fUR@VA};֬uYR7kN?IQFlذU)̒'NT'N>䡔6id:kE|_`HHvSِ|@k߷\}gueNb_mߧ>(M7Rǀo$6*Ct֭POC՚5͛7O}j @ӥ)Q:]iz9~M*s +=lU_HpH`@MG ЄnNƉ@~٢y˾kit\#u\tI}уvM7Rrџٟz-hWWR>M511a_UGU=Gu7Sz@^tYX8y꣏>T˿/.'|J]rUٳ[=5J^|9Tzy"?=m>WԎbW_W۷߫y O5P{Oi}cw|>xں.<㿥=5K}pPFK?/P]|Y=֩|oԕ+Wwy7Ʊ(k-NWMxcVsόׯc~] CuP]~]7Եk5c5 U_*?\U,sso͛=ފe<*cb~.7յkԵkիQW^UW\UկzG>;WFΩ]Q zGڻis'@.J)5 …`er-S(ۋAtn+eڊL769jtTyYɸl/W7m!&Rɶٰ֬sۏtLLlT ǖL[p{Z[mL[nJc.uS\|5;;.^mu][ʕ+ h8\کpTMLܩ.&-J˹sGo(O+oۋ5U۔ Ub;ml떡_u亿[4z|W2/Zwk<4V4 y暿ot$k*+uS7q%6NWWS/rj?Uk ֡3gDhtK_E7;BulKz\߾>ݐI.gin5^z\ˇM >6o gr^^ݼu xS~}-a8r]SY +\y4)}tE}E).\oT׮]#H@Pu?II[lMMm^4wrrӲ'_Mcc|6ixH+ֳByb[nʐzl-'RCucZ*^n$n.m$/i()@!_S9>n@.MIrm[j~~nqx򼩕m˅xa~NNlQʚ>vFv\<]z0vE t:~]K?zKj"S;e'ϭS! }+CQʖhenOc?\Yy5 0vg_:us[tttٰm<P*^qJ\GtnzIno<:"e9mK-$O `ffFYsk崉jӦ; ulmQ9/3?T33[Dm:yr&GiފP zl߾QFH ۸|ڠyȫĈĴ}׆6s绯2{on90ur>aժwۿX{ 7xߖ3?tٺnꫯ_O|_^J=7Ą_pYnv$YA uOh#}xMW1}Ƽ-f.{Qt>zFHz{mHoY~ yvj;RJ?|wklX2ռ6R%\]q;+oߴ~@%}{nۿ^}u۷eytl{ᆵ,δ~鎄jaFjaZpv=u-| ǖl_7iZXUkqFvtJů./cЬ#]J)k\mʟuiپ+{^Kw$}ܹ֭vR& U=wZNvt&ObЬty3Ь`ۓXu\os6V )v5F6 W@ln/*O/۶S4|elF+=ֲ&'7YXmwK9MiY~#]&'7-I.v!7=) hVVҭH)^^i)onn>|SSՙ3G*9s戚ܤΜ9mtNXv?6[մSW@^d|ϽzXlW̙#EFn^z޷M]KL9^q^mF+YM/Χ[ӥOh7SZ<N:DaK$ V~%:߂:]ff^:co?V33[1ojH+ A.[ޭ#/ff,.&>/\Ī|{֭w$& @..Aۋ^{uu199m7hA.茓'O+TPKP˸e09lQJui䊶1x /N9k#j08/;޽O+:|4]rE[LNNkT]p1x>.4VJ&l4e6m\VC   Z;ebbRJc٤ԟ >os7]tzIuܹu\<H'V4_Wtt,Cb;9s4gϾ&'7uTgϾ^:]"Nerr:sH9wjjy/._7?gJyt=P5Z2 ]bxU*.W5 x:ol 5uHEv M;۶(SHϩnۢ6eO;V=3??zǾӅ 6^>}X_EpҜ}I#K5Ac<õF l$P :up<\:t]wԡcӅ 6_<9gD/;yr@\^;OOϨo{ɴhL4.mŴ_&#Z{QNiKh+ӅmVytix䊶r:](HVN #tyԇr7[vm1%23E=WJM W?AU=WnWԎ%.q $tΩ]Qyh})b#]]p\Bre/77|˒毚^5ovLO9=}9ӐSU }-]q{|ؖ%Ť Nې8v"Td.klhEK.+W6|WO0MWzA+wiSF]9GدbէYzjCs#~ڦi=]s}h:F:2\]GNk精8Ct'S]q.WxM5>}N%zFu>էa[|smX#j}5!Ut u.c_q-Ŏ#S%mw6\~J 9~mMH$˟ߎNk[oJ֍9M/m+D:O|cRr>^߅uhMeOXqr3]|MU(gϾ}Ȗ/Rݴ=hm/~%ex؞DꖕyݼU l?$!yﳼKuΘU15[HJW\믐#$ξuo3u:߹="n̵h|g Ry+U^߅]so^ǨcCBΉ&dt3)3S^0ׂ`;|uH'E~Ĉ]uM#cA1iʗ|v7,unn1 CܧXyFM9/uTyDj:R6w9,ŵfP* )GLm5]zs!u|baîiW793!i`^8tb9]$,G/s:ߤ|!qՕ7qV'вc鎗utRiz~~HwM ۔#?w|wQ*Uu!~Rm0ϗM ($~uqRyTo ~dKo/j>2X*SBϒy{ i 6#$ceS*de-OMh{̥:vڴzZ`F4WGx4]s4u,~;R֧wcr;7\>?1(|jKBuT52]hgچ\~}uy\ SM-e5.oC|qJҔKlBA5/״_JK=-ys7|XqϭHu ɇc~|17uoqSʡb;?OS=lFO<}z*T 5=^:tD}y7lتN8_ڳ[3WԎ Ri+~3}-Kme|V/r 'RW\U{Nw{o&}{\ Si4)EH[a VOו[rT:EK/per 7^tt@ҥK>t^n$@tlQ=4 @h+XKBxrU $tΩ]Qyh}Z=W)3F 5p":gF󟔛o%:oʿ6ܟ1A(n+3;}߲[NOԭ#fY\ @צu&)+׮cw\ne0%F4]e @".צuNebbZX8仵kX]4VǦK^tۉBn/2 J1<(u&e۠ʷZb[igafUݲq zB1ud޾D9-7!ut1^WuMʹjU擡6C. CH .֒ͫ$Yb7/cضQzIxL %/Cg8]kKCJqD9<&siJ˗]g0]4vXn~iߪ_W~mQVb9V\Q7OHCӐ}e6ZbRݡyqlO.K[Njum$rm[[bgvy %[&lsMt޴45]NoIu1b {m8ƋFv\ @t )Ywӧg1@=4z{Tb:r4rK[ż0.Xu6vm(c.r.F.^~]ԩCdL[:IbP>R2Io9OmX˦ڧ,IOM"r,/99_cC8}Qcj4s)m5>t^n$@tlQ=4 @h+XKBv츯BvmeN'N9k#j08/;޽O*%tH`ár.\$@笐\h4rs؎[oqw>Kغng_[UXVے׶qڟ&҇.>F]9LQ&s̳[aud]g^!;bWŌou^WF]{ǒe~\.i L[ҞC,s϶.S:϶c!ڛotB>un.C.Ǎo$Etب-n;}IA2]).*˹z{ѹsG+o'򽽨|c;nY] rPͰҺ.i2m;}Хϔ^>^J)6|״62fO״M\nݏXevT=Z;ϥ ؞S}$ǨOY(ıZ~Mѐ<0yk[>sͧ]CKcmKn 9#u;d.YGۋB3u<~]1{ln11-'1&Mm m]eu7| I:]6/̙#"#\L*1;\l2Iwb -|u1V*/mY5Eⓢʽ58s9.i=&Rġn۶s/>b;V=2OcweIjRPc=u=뀜UWHm{>:ֹ?VAX.uo1˲e~~nILOKOj9fJoo:h4-+uBn1s}Ǚrnc=ކcx]Αʳ^:Cg;jbէ9]CL{bt;1˶w*,oʵ-Ft KŐ:Ϛ(']+c9܊:@bOXq=\SRF1n'l7= kirűܹ1E}n_yX|GT k:˅.JV6Onކ>%2K>K۱}M?_$x>TwMwuiپ2pޔJsN#IX:ޚʧ6_CH{m﮵I*W^gu-'-Huq>xwhЌ+~}bI9<ִ-}6 *.,Sm'n_2{7$JS9ee6>'lC"}MrU!e%[L\#uͩbRR~S^xLm˧^CǺFmnƫZOq$mmwy>n 2O|_^J=7Ą@MOWQƟ<6l]ĉK>Z=՞=Jv츏 [M`h>n(@[|V/r 'RW\U{L4xky.n`P4lhG>@\th&n @X˥K|M7H.t٢{6h^i$Mm\V2<_'c}+@H?zVRO)SF\zU^yUV sVHl08^?SKmuR'nzHjXc9>qI:v;!爘RW6Q^R[X۾?.S:>xI/7y^/.ΉI.>*_˶|ۗd@sV MZ{?MqOMsu~ۗV!爘K7~+!G%_};FW+dW7̓&+qݻՍ jgBGl%~y|3DwLUIӭ;>æmc>7nUVywyW Ǵo>q-KM&ybls6o"})>21S'&kSޔc7Ru.MR_}IIWmʂϹBwleuVJ?4TKݲq IkՅi~[ڤS'm'm)YLu1SRnC>_ؔ1XRy3Cطy"V|$!V \ئ5Z.Uz=T}s. 9o٤t H˾Q,Ǹf\8.15LeAew۷E~}Wj*gX^X˦Q욮_zboiXONFK)V:b+>s).ǑMFݿiB UtKr(eNeu(.hq|ԵKSzD\r=uTy1CKOYIF钳6t&+/y0GӾF.@y*CHsE[5ǜv[ln:7m0!*ź⦭]mPv]-oijubeSoj%r!FK58~I[u}}%1155GnZr1ՆiuӨc˧T{# q˶m, }Mps(495`"xMT~H!l>eG1'9"V"[t/>yՆ8H1|[gNJM28H]s>QRMc.bKwg|,$eQ\gymuۋ:Q?]~iwJ)54UAj`vj4Pĺtc34lew}IږC|t}-3$ʆos9bط5%ꇜ2p\pV8 /D}l‚zɧԕ+W՞=^T{㍟7Y-HRH_pʮO@ \cH#+SV^@u 8.u\pЩN\u|3VW\u^nUN-?x.h;k$=mJʼntlzںuLMm&7@|@:VFytD@ @tD@ @tD@ @tD@ @tD@ @tD@ @tD@ @tD@ @tD@ @tD@ @tD@ @tD@ @tD2d ui55.8!oyYxᅟɉuulvbBbrrbDlvop"gD@ t.t:`-jjj3ehWWR>M511ATCg;;㻌t‚zɧԕ+W՞=tPt ~{kΞ] 3eezz=:J)2p jvv{=33[R*h}F^/?~\ڵ5 FjާR{}F_/ON?vT]p1x}FĹ^R2a(u#~:]h<?  :7ebbY[7izlWQURKmn)v1+~Mʷ<#F*yk?o0ӷٮ4_$[wRJs.nbbb8 KljBkbmK:~M*Yw:l|k[s?tܤRٷ&nݝٷ٥N1WٳoEt̟[bl+fh TW>OXڦue8WNt5H6+:sHW%ys]y.#u뒎_NPr,|ܦX@]vlצJlrmyz!"ب.sa~]K>}y0^145bi4Re.}]tNp=o\Uuޘװ@KK:]'ԝ.Ng߽S~:~NZLϯ<80?eKb7N "SFtf]>sH'.[V\nzvWC42W޶..ۤĉjÆ1Y)#5rM)6EW_|#~ď|\/t٢yA+gď?orl^sv$c}sꡇF]/KtSv=H4SF 5p"2 j[O2-ENC>.[D,hS>~FDkv]yi[Ӕv򫋹M)Mԉ2er]/uRC |꘲rHy J9 )w"E텅47$Bc؛GؔkXtµTc躏ty$Y_t6Unv>2/ֹ%mIg8iZBrlr__5-]pҥYЗri\wĨu 3eGS\KohSx լsS")"4`]ui6Y,/ӹI&q hI ݕŤ)=mLhbMh\L\vz;@)GUEq%SK5fSmJ#RnrfHq>iI]}H\kMSSnm{-Tі1۪bS2&12B.}R}Q:c^T7zzz6]܇X!!NL_E|{ЩM]uZ[LqŋvQU˹̕$; BVm*Mn;4 !i$Iɲ )M>c)Uz$hrr:{-3Z1 y=_zxCf([;l`s|݃l`@muO/_ii]'>b6b N9ض%ʆKtbt:9l2s+MelSWGy>vn4eB.|(ј^b?}픷SO{V[WFΦbyllOyn].#\W^{;OL-ϒ&QwHK\tH.].^H]l鈑y"Q:Sl1:]v!И]]6ѷ,2nJżŭnUl.Ccbئ zC%ІDcKg^XC;sS/~6v.N%@O6.]F~.҉X6] eV߹Vՙ֥ \ґ.qpma١#Wr~W9^>ݎGFzMٖnI~鼳kJ8mˈ&t˒kWCݱWQj{[e t Q㥯|3>Sa3J˷:Սvi*|5VyWh:|FU!ss|D` !"З8uuLxǞmC]і)ۖKkHsx #]! /]ll|a厷ysԀK>~IM*%cH7bQ'iT.~-HlS#I\:$jLJEj}#Rq"UR^1d`zFҕ;>.wC]Fbh 5ԕOSr-6iХm䈗]9,E:X |9 ]XԽ*ٔhkz{iиX bŸkHt)cMH>C7~72tx,L] #Mm>sB N8#E~I1"n#8J.ƮB֫e}Mf!H8eLM#6e.tyԇr7[N-g~/>Gn ~ď|E=5r#D]/KtSv=;HڹL!6e0p܅ 92FqԎ~ etUS|'Uyzȸ|S=ݱ(]bew.yc{(kK78V_^lsys9vue4-E Ӛ*7%S: NkX㭻t HЭwZ^w9~kl<:M`nJmԦ3|1>Q[bocL|fSpuFplY'L4zM#mgm8Xw0\:tMՋu,>$@LQ;]Ν;Z{1ݷ?d.҈u] e\걺|OMաj+|WHcݒ+Our5-m+r~ľ}W*f #;,:]9Q(u9/"9Q-]@-V.ՠ i4s_y 7?q^<6SlAn{513kz/rl(}:@Km {7b[6}st!uIB48^]:LZb4wJ<:NB"͹!d>GI*Tz SNnۢ::N˓\.s,.ol.C`}xHO s]rGpNJ17wy$tY.uNR<.xp1ͮ!1f>5rPHQ%}>uQ5-Ǧln.x> $.~:uPkN~1~ѭwZ.lXu!ؕpHykyQbdۆzm.W`6>8Rcю:1sRVwLOϨ'g[LLs']Cge^3ө4ǰ̓tSѷܤKc6!?lʎD2QӪ2Kcy,M N .v8q=Y沬OKGn[bv&̫<}x<uiNwIsmc7$K~&;e@GNl]@B# wa9O\76=.pN8N:].]>CnFrtHo߳A˿sFG7 /+sIC}h8?G@rD:]fgԮ],h4R{>v$S@wt j8:/wEr20 c Ix{ux ;VbHUSuM3ERX5_Hz6۔:m3tY)uyS'ו|گ&кDYkq}  6csP\%FRv<_i. #G8iD4SzcYS铖"vL7}XMO1x<ۘuv:R~Q56,6\HOSitTNOUGD\czHyY7ouemg"q߱vu;QMqjL_& /mR.2| 繴j9zT#LjS7lH<;4Β?~mcrNzmܛb3z]L@.S5x>i꡺tpA$Dr]TYm-)SŧuP tdqB3֛AbāBܿ1X~VCݖ|Y.ml˄jl5uu FNrmeR.[+`\_41>8c=9f3x\_S-_9eSE׮xLDtܴٳo3m}V/])e]ʖK9-Ӓ1,qDqzZ~md,}g|/|ϭ԰-)Ԩm QUJ]| D zQ"Ŋi6 :\:lӄusԕ9TtʺgI{m[??? rLzhr4"6嶩<n9N&_2*r!9 : IF-۶,kcηa >7m|i;uij4KULh+Z3߷/T5tF$&^+^h3:]O&8h1W~w2(O>:Aڞn94}z])j:U|Q.uӪ㳍ymO*N'|:e/'OζS.ϛ-nqշx[m:9BgdNJ_GBfKl#dޔ.>D!@{EɓD)Di!t]y;JQua"4L@o~6lޒK ]i%!Tн^uߺvTӧCBj=rJ d0`|ވk@4u<9H 1:[\h53]ڏۋ~%}.l:l/$:^gx Y /T]g`MWyz\cuk6۱Y vdñcT8x2틩/=547]KcT\uO|c x!3z$RKj { MWfrM5ma6JQKloE Mkc;L=Cꇪ ʦD9ȍTM瑎ow9MuQH|]o[oCĈX+в$uON4J$( wIGUc¦n;봶1uNO(S#5]ʁMy jB".v:B7Ħޔ(?:C>q5Wr,?eI\i<=3.&uB mdpyFKc0i4凞6\Hd|&.Bm$rC!¶E#b58MUvSm'EwzhK}cMROtKmh}Rh5 &OP9}SWS]+ɹ1&ul͇o8>P~8q]ۋI.Jwo2O\F;iU]6#>Ǿqh*~Mf&9L zېFaFJXe6ūZ~\ӝ[DE@>$?i@U#(vrX5~hAZnZ 8 ;WxRs!~6]Wrb]ͪXO$rA)/UȾo(ȖHK To yhWn;< )ËmiSa(#.ꅔC/(JW7Ս>`4mO67]6۔1Wr+et[Dc)>c[M{N9* ̓Ĭ{bglH }듐I=3ŧ~7lˇKG,:LCO|_^J=7Ą@MOWQQyӥ*~.a3 J^M'FԶN/yľ}*I+zzᅟ[XXPO>rڳgE?Hw߸åzU um~Ec?.!HWVLl/.rEB$etb{;EgΆ&ǥS 79wI#i6R/;A$f;ʪ x떾=I^QW GWFoeorcj.DpdK.t?K]jeZˑ-hզ![So_Q^mۗks3҅wöaݓ@B~mۗ~iZgB٧r( M$D˾SJ(FsT#?n{=sc'ͺb(*ؼZ"]ԊyKV]T^2-Z@?H<(ؾ/Wk }ˑ P6ҭ~(4rsB4 +eZ2ZhD&]idӐvilKQ%u>+^N ڨ.e@\la:rtiFKo:[:Vt+hJB;Dߎx@G0JV'΍clh#]V\n/ VȮn Ɏu1MAԍf)v).kLi)O3]4n/(씧>W;i.răt"XA1 N|ʕ˭^\#23E-c}F6A ~l^C_#73m*zڵw,4I5tQխAK V}^NZBm@%鲰p,NScb#vJoTWnQtkV [8v{ s(q6.ߔ{]err:{,L[ʍNV5mc|5mʴ..'ZTN[<]- @?E29i3gdHk#Fx;\ltrYwt]e~~n穩˾kJݨ]$xytecG.Ol` ]x1cKe8wHh$m1U~K4>%ή1A֝.?ݱR>b<{rBAX}W/E#j[6iixjcr{C]^V3Ӵ.Tl:mc+/apVQG8qPMO,]>;>E7iHi.]G FP_::]"tt9".33[Ծ}-ϑ#~ %!=5r#D]/KtSv=HڹL!6e0p܅ 9{QqdU)ΣKK4:*j||U:~|)yYnϷ7u#4(K}(>ջ1 CC-vzطھ_v]{ǒo.yzKnMNr9B?FtdFtXr˷Xyd3ƨDR1;r.ۢeFplY'L'ш^Cȟ8彉 qt(Χ'yO>þ,P!VH_;wyr=\ſT}(7Q[uoy}us_uR޶n~DYt۬+w1ӥ׶WXW׼q)ǒ%c5n~{Q/ 4놢:ol~ !]li+9t|0;c.|3ұbs,،4s}l::X#lcfM6U織[S]W$ŮǮD}E25y3Gl^Ǻ1=<1"O-W9[vmo}:$b{KV*&]&/\~t֭. ejjC#.t&I4ڜzw[Ny1ʗmzm9tr+ÍajK]DFj$}@l[:!>4~qn?PFT9@j#^IDAT5L>7g59y,cLhn ]$G(!u>p.:]:ۖig}1o|S'Uޥ{32B%JvHzȧ$4u?NH ۴Փ613ſ<7c%@e&661"tDH6\xbh~oy)G10p- 1~tC.ǏDu ;]hR&ӭ$1[{+O5׫@x[[څN:].]>CnFrtHo߳A˿sFG7 /".[ޭn;hSS 7<@.......ʐv舽R$=,G D.( =( H$'+}Rڸ\19^ .Ji.]7{/JiSM]7 @tH $]. D @ y?V*Dzc#_МN爈}f>_DDt:J}rAC9ŠIENDB`MP3Diags-1.0.12.079/doc/110_first_run.png0000644000175000001440000010561411274334417016350 0ustar ciobiusersPNG  IHDRUckbKGD pHYsȥtIME #%P, IDATx{t&[d&xfvɌg؝Vf8!ZL bc}xパ Ҿ=~uCr<ovb n1 @ZU՗[Wj=stZu_]WUx7dQ}kk8_pg^-""""if̰.dNܳg/͛j\sM QMNNaj*p8ޞ Bf@_poMI\: .üyH$D%"q_ abbh~z1z^A""FG]t?][*7o^5DjاVkk(2Q6χ*x8w j|z>[j \"~s,Ο?HD4]ŋP_q[$IµRپٳo!|]uU\$I,˸pwbEjܹd).]_qe|>v"9KX6m-YrN5,_vKe2xw\A@MM J$D" IP2ߜ3gPUU /***!"Fqu*Nb(]Հ/`ՌZvKeR!]~ォdq-UDdt >oU*jkQ}uxx ϟGıcAD[Yg^x/s)|^ GΝO/u""tԌZvKetC^_p K,-욛ou˗?x +8їQ]]*?me?}F[{*%@R7Ǟ9?k{LM}y\7𳟾/}s TT12+x< S/o?.k-0z[\9}OVǿ>y#,m̿Ăěo$k,5}0 Y~D}t/]*c;¯>9~qucjVӉmQdv'?_oYFӌrY돟. ,ks `շn?:P^@UUeygYÅ oThϞ=zt ~ ?ɻ+b=WCUUU2yӟ36 6]xIw{viQUg|ےV'wyNz,jF{f˴֢.),Cd҇yՈEcS;qwCeU'"#IrIw?[K/V RF'_`?~xƫAX}uuXp$]wݎ+igoKN*Qpy2ڦ6תYxQζXY/Σwf]=he}]]y|vW4+8/H4??!x<$ C_%K{O?W{:+p'; I ED4(2c.l śr9?pIuuc6lx0+xN8+VkgwspӽP;ɓ`ŊyZ֪Lu '/Buua  0pVp^@$˩gV.!k2P]]iصǎFm%Ϭv]#QYUxm_b)?ڮ Ԯ磮~kW5[fo^~M~F@_*-@UUO;ޏx*?WgB ހZ,XP (j?ޟ}={޴2 V;yqP=g|'Fik2>=M/9ۗ3]uM*m׮Xk0zf.[_Pha80:˴x>2^Q7nT)WOGH _]/IC*[ԧ+ sV']p ]: YaI Ԣ.] ?{sX\weme+nwmGu%X,+TWWŕ+J_3g UWL~/XPZggcŊexwRA fqV:gY AjQ]]ey3v>|]QS:@QouuJqm}[o]dzG 5eMJ{ԮVW]]>#+7kCzՊyjO"**|P:'!!d$"*w6[{/%ܮ:^ӘQv˥-Yr#߉`#Q|k]^=Mk BnW}tϼ2uq7^77:1z]wݑ mWL|jh;1P歴YYYevSEQU=$+*|7w܉_޲ +Wq'Lv!"rfv=W\E8}wW^y o} VD"т֧[DWe_꽖OKx7={> >,YEܼFlQ&& SQ PuH\Spu~{w8uW8zD*B[HJ_h45Of^Fch*UyԾOo}3T%HMW+Ϸ޺ ހ jȷBhv 2z~˷UUFcj$>3|oFc9uTí)_vAm}Q߼_>w->Ww-?^RU˗/c 9.Μ> @yҨS.DDeO/jtzj6HmϬݳgf̻YYBԩ_|"_{$駷I?z4GaǃkjTTT0&'?KUͧj`u :Ҟ-O_UU /zU~or1]|-vۣl~mWA lou?_&uݭO۶N~m3׫tW8u%HdIQIsˀND4G*znUU%*++uwQfanuBeedYFeejk磲Rvߞ%IULL\uCw˽|f]ڼzXwBDDDD4 BzPIb1Ltb|yxʲvZa[i߬|]_l_6o}vJS>EC|Å7ͬ}vni}2]7^򉈈hq`4@@)t9Nύmc@'"""|1c-_313~.DDDDa"m/yއX|L[%jw |zgQ;n3+ۅvMq|""""=~C޳g/*m[ /pMӧOh O?3"""""*5 DDDDD DDDDDĐNDDDDĐNDDDDD DDDDD DDDDDĐNDDDDĐNDDDDD紁A;$UV⡇zBЇQ'AQHWѣiW_}7, Y%<:f?ѣıc2UX^ڇc>>J%7l;w.$(=iCy"j@ɭֶߵu!Jz0D0<;mu 7܃XrDW֞DC Y!u&dYtOa|?!Jz0DSSuC:&⹣e fHWIR{*<\%Q rC#aÚ:? jhmqmX[7-3-+0 R-,IC6.1Zwp<-4CmάkOHOW/^Ϟ!]$<ԷS۷+WܶHEZԐb,Ώ/A- $QWQ|: """*/|/^ӧPYҟ~`ǎ'Ru5k_%WX2'CxV<3&ራ6O'""".b[!!r{wN)|Tũ)[hwXofӈҳ46u 鲘018x{0|"""Ɯݽň(a}{H. TxӧgmH/$(x5&DDDDedժz|?(?0*DDDDDFnm㏇q+l^Jݿ#bpDDDD/8AWցt;{׌iCy"`+/ݐ^h@p{0KHZړhĕkG!@>Ե"""JV҃ ,߯Dƍc$֙XoQ *JgW_}QHc؎h W2_w4/Ɖ"o0]GAR|%""""s`VJ$*t\nuaMD5'XtfW5hggnv^$]atŵ.1Zwp<-4^Of'"""rG)I]ob/к%X1_LH~n 87K'Q~J+dV^t7ȒQ@ Gpa JHyf417.Dt1G065Լ.N1"V(>Q ]78xMom_Q""""XIw* SSh4""""2JQIOrGJ@ov] HP.!eOX#ha%݁B+`3þ:›{D,9"YDWk+kO!WrjP߇:QJz A455HߊQt~ M&⹣e +Wka9Fa V-:v,]vNz{$! ٳJs=Y81&xꫬn~f;cÚv>lضEk+Upm|Ù'(v#"""KXIA$R'?DUUnێ$*t\n~d"lXSQͿ6o: VY;Qc%}B:X_OƥKpBz뭸qwt1(к{>Ԁ·si9XɄް#"""*7 O=w{Ѿл~!.]x"nf,_RHQE1QEu ETVD4:-- 79Vmߗw<ۋU/ʲP(*p OqM7! *Xq5 .%Sx2gUυ7)b82mXc%fHwP(snVr-|eO,˦A]cpc:]3JBC9<UPHǓnqq9srH8&@<<㻬/{p -.-Fb[jU=m8nU/ x00`k~=#?ek{ EbX2Rz h 3~J+mycd"""2R tly2 """"r]0,(t7̹J8{~Jy YH1w 5DDDDb^BOW{jv] HP!eOXoQOnB Θį{0KHZړhĕkQ!@>Եm/hW"""JRIhjj~R惒*1LsG x*Pj `cAŬ+ IDAT}_5&;$<8cB9?iÑ $aƍx< q Ov1=I=93(""""Jc!ڥg'f8p@ĦMR^/Chgy16zkǁæy`T6iڮ*ODDD4XIwiW @V@طoyC |8wH_IAmXow^d@NDDDtܨ?ԷS۷oh_fGG>f)ʉ("(:ܢy*@"umeY;47MDDD4]Q>qT$<>k%a w) %OiC!"""*"IwTA[QՁs&bkE=@\vdȩC]+Mm.3*EDDDD@T҃ {iDa";ZܶV2Ve ~KᛈJ8v,;}ժz46ܞ,ː$ 7nAoo/AH}}}OД1=H=93(""""Jc!ڥgNÎf8p@ĦMR^/Chgy16zkǁ>yrʒyaDDD4>j7xےe9KOO:̟8*J%]v>Yaa@T3lm[ DDD4W>!=߰ >g8ƣ@!QIycՐ} $aYtB4pTq5 .A۹ ]=l&9M Gy;F"""kXIwJo؎D"&RQ}}}>-1LĀD8I`3`lπ ext"=87;f~w>555-[[nE:uw㘌$ﲾ#hz+ly~BRVӉ.8˪Uػwt:::(_lmmM㨩A[[3ªԔi67{ –Jzcz[A70ՕZW0ZD$o XIw}jc``zF^@İ=ed]9* T""""r+Н]@Fo ]pzwbGDDDD@Tҋr ';.᷆Y} W*}ְٻCʞ6Ա"""":xpǎ zo!w ,^*`0hɨ@od]=@\vdȩC]+s.C};;“On-mmvH/Jz0DSS[;E8p+*ىM6y^twwt1dW/Q} cGblXS׎;ڇ V+zC2O ffimгW+޲Fb?M|IWu93СCIhT`suaMD5 8v¥mw9f˵>nO[v 'ODDDTv!i̐on(Coo/d@ }}1(к{>Ԁ·si9XPd9!,\HwSN o߮\ڞs"} c8|pV@G[[&'b4@@r橬.hplU`&ќ nTҟ^nD̊ھ5_H$ 7o  i~$j\KdϪg6&#U_~XL"""'nI7lG"@ss3R )wo|LYa"$Mt(5Smf`(wNDDDs.'OzMMMjx˖-hmm֭[olL㘌$ﲾ#hz+,ͻh/ԶmezkOݨ}; nG"""bHuUwnvuttPnښQSS6 g Uũ)lgyp˲MN Xma0'""*R'9AwҞ|]]]B" \HGlC"qHw'ݭ~V_t+yQ,[). Tf)iHw'ݭ~akMe1iH/J:'I/@Tҋ#bp~[Vҋ^;{׌iCy1RAAa_=`",'+׎B 95}kkw`!"""f2`0&$ywrvdDE477J\@gg'6mڔzmF]]DUV^7?3͋aM]^;h6]|'W嫦=I>jQ9`w8퓮vC{rY]\zzzp!wgQIT*ȺEذ-<qz[&"""1!.}3Cza;A@ww7|>z{{ +۷0C |8wH_IA]>s}DDDDT!ݍJSO};5}V@kk{VW`сÇgzY r" Fc8? 4>sTVD4:mެo=ѐF%O~W+jW.I6oޜ  !QI( #0LU=l&9M Gm߳ZNDDDsLFli㐮#H /Rj\}}}>-1LĀD8I`3`lπ ext"=8ρUu"""*n=OzMMMjx˖-hmm֭[ߟq6frd'q|A[a3AY,6XcOUػwt:::(_lmmM㨩A[[3ªԔmeav""""t*鍍mjmoo ]]]iGLrGԵd>wq{$i&+ hjj~@Ǔ߯D<"عm2 eXV?3deg"""1!.';OPfظY IqFx<B8Aחμ$b7z{rXgbGDDDDebNVҏ a.'>wl=HE477J\@gg'6mڔzmF]]DUV^7?3͋aM]^;h6l[juE<Ȝf>2Ϭ[i%"""bHFNP rV:t###?qTJ|.7t?n6ÀfU9T+6 Bu1[Ot"""rit7C Coo/d@ }bQu|r+I3BOB qsЉEDW ~* vQIoomm9о}:::pᬀ^__6K_<9X1_L{ $ђJaLCߗwD@/K͛7gtB4pTq5 .%SzY=4'xRLwUw!rf -wBȐn[)IO$hnn@j\}}=B!2}}}b 1 `lR'kFy]XG$303QbtbMMMjx˖-hmm֭[ߟq6frd'q|A[a g/o=^ ׎~FbII@_{6nWGGqx555hkkp`*%NMY; m!2Yw:މS?/k, ظ>>NSa{{{N@\I.x$#! [DDDD"5}W'R͆tHw'ݭ~V_t+yQ,[) ]As L DDDDnLǗ|?^c6n ]#ol*ҙ<#O{ #զv˰,;Rh[bR^ltٰ|;fOl Y^;{RLʞ6Ա<"\PaVU4HU*v0zo]Eo|mkim`V>,пh|]Qc-اY!pʕ9KOAA_=`"@N?ieI4ʵ CNMZi5Oo~8{=5v&փ tubVkv`r+[b)mxoNf߭`':L 9knN>3*gn٬X{`MMM\xҽ/\c9$@;M#*j] Jp̷eiXxi,4.f3񙑻~kgi-^ɲ QԄfH5nƍq$b J,{mm˖aeZ19Ya;iJDYԬO 6fF;U f}[n=N+L)g99- lOE477vvvbӦMq^Ƈhgy16zkǁ`hü޴|{f҆vK:#om:oN??*LnYϺ=fKq;v0NnVs3PѺks8fO֭Y9˵O2СCIp>y%]1 ; ݏ[ k0 Y'U+X/Md&uXfuh+֍NP;OFߍu:llv̧,`u?u2hV/vڷr 3gn٬`{ >g~`qGCxt>;OA$ 3e2c%͓NN$2۴l޼izOv)Qix=4I/r{fFa˖-˚V__6ȲlOzc@p~h|1|#1ܨz~,=FgB꧘W}揓uqoILZ s̖J٫^$ 7oΪ@(B @ggyD\b8 cP*Y=4Ǣ7W~}]Xoqʖ ͽK0::g6VKD"&KqҒ%0&π (O$?F'щsVK=APSS޲e Z[[uVgOd'q|A[a g?̦OO]ژ޳nb4gJdh.bnex·r G/qԠͼ)*85e92"|2 2p6g}f`NDDs[hj\IWQ{{{NPtp.x$#! {IDDDs;ˀ߿/ZI5Ų="1oyO)g+Ge4Wԙ@| VK=oyc,?K rǕM3deGDDDDe{?nb%})@Nvp7H]oќi""*E>K+TöxgR@w){Pr~ Q`0`0hy~>!LĒ#Et$qQ!u4\O9i{:z.m2S""*m3+%^0DSS(/Ў׿Ta"pܶ6u jݣ ~,/_jʋ>3; {+vh4ێp DDT}{b%ۓe$aƍx< q r"q 'u&V \DDDDs8stQ܌(qشiSjEwwqhcMvuWYy0v4/Ɔ5uY{8}>W֎ dS2նz[o]37~>w׶m%""6*Jzf:t###3$*t\n~d"lXSQ(h=Ũ. kzZz'v6.'l R4+ےmmXwce^ n|>@V@طo%1Zwp<-4@]yJm1;mJt[Ӧa8IT!b@'"h>h6Tꅊ,[,kZ}}=RT#w IDATpb,Ώ/&o$?7U^Ϗh?CAR?vÛ^1{_2mvǭe{ ̆'5_E7oΪ@(B $I\b8 cυqXG;bSö A+jnXHnODDsl=^% 477c`` 5Pؿa%0&35MQjt'}߰Vuw A'""":W}kjjR[lAkk+n݊Pc㘌$ﲾ#hz+l;lzP;OĬB m/QNl }fuH/J:G/qԠͼ)85e%ݼ EzzgJf}WH'GV"""{3UΕt5`.w70ZD$%.k%gE2Ų="1oyO)g^(N$"""bH\+~0x5&DDDD ӣLctʹOOrbp~":J5 NK ʣiC $"""*1X{``F}WBxs=%G$j-}eI4ʵ CNMZiy2]j1zcw|!pFlO1[J#"ل]l+Jz0DSS@IM׎׿Ta"pܶ6u jݣ ~,/ؿÎugCsDy:׃e^ɲ IqFx<B8Agx{9øs`ݓ:+ʹ9Y ќ']E477J\@gg'6mڔzm"F]]DUV^7?3͋aM]^;h.hu}>|)Ø 1bu.O*Lu:ͭEV;8dw;֍h΅rgvqC022|>'JRIG-†5urІvm f.h=$Jv_7Ao:gΫ#nc'm/'DDa&-g%|o>Kc< ƒ5yZ"}%i1/mt[ר ZPo]쮣ɬںO1e1ֹuyiyf늿˳=W;::lٲihkkKUz CC" Fc8? 4pnTy=?NDs Bb]Zَm(~(ㄈJ+EnU/K͛7gU  !QI( #0b$ot<411 *T54<^e/Pn YdƖJz H$Ԅ^z)5>{__ZZZRc=&b@"$006g2<:G|-Nץh|iFͺ6-DDTf]&VK=APSS޲e Z[[uVgd'q|A[aPju=fمڻrhw;hӍb5,kj[V}\*BDDsRuttPnښQSS6FªԔi1ov_ kvsQx;_;lLLjќ \IWoooe1a  cpuHDv[0Vtߏ[yQ,[)z%@\A*Sg%1DDD4-}+%֞7 v 0 DDDTxwYM7{XI%9~ \ ҃{GDDDžr[;{Hӆ:HDDDTbXI/ {0KHZړhĕkG!@>Եpfݣ= Y""""tZIhjjE=q1LP m1z_7.*Q:} Cz!ʽťH̟8*J%]v>Yaa@T3[Z!}gz}hAXo^+'¹[iVAϏ8^VK=A χ^ @3bQu|r+I3xAġ0YMw3TZi:-fnc@'""vmظ<;XaՍ>kf4*^BSGG-[5mmme<'b4@ɟ~ύFcD4j)eG)=AR?$(?_p@s ባj7{DQ͛*  I.Wpq%^"@ss3R }}}11G06DNQj\"%Ūb,sXCDDTNXIw`6Tҝ-[`ևkԇ}u 7܃XrDZQE+kO!WrjPJe˼\^s~B ]17>""=xwʵ S-${%iYEa"'Hvn[ CV2Տqi(*vѶ?Lk1Nfry gP'""=;PI$ 7nAoo/AH}}}O1=H=93b?|!1~~'"tʹO(hnnƁ\QNlڴ)58X1&xꫬn~f;cÚv>JV^Y  ϜWovY|W+>zB͍ƻ-FSF<=;P..===8tFFFgQIT*ȺEذ'\zaW'+ڦ6.2~B۳~fے9Mo{XMhc%݁r n|>@V@طoyHC |8wH_IA钹,+Au%m+21QGDD;0[nj:::lٲihkk,4X1_LH~n 87K'Ѣ}v ~fKn׎͖aw=F[?s>ߺ̦㐈l!Iy :B!tvv_8*pƠT́\g6&#Eb6ͭVmc)W؋WXbhvo!"XIwH$Ԅ^JgOׇuCD H#>&> PG'SiV+\Ч+|nf;ŬNg5Uy9dXM'"]XIw\wQVg(yɀr DLWoyme6vƖŲqW%yjԐ.V߼ (DFfԑZI0egYk9{y9wy>cƌ)ܾi&ڶm۠ptG:{ZD+Yo8oKTu;L}~,蛉8Ω}Nx]BH]jhh4pM6Ә1cyfBrgϟb J(>HԎ8IL 8KLo0Ww a8_{!/Oo޼>p Im/# # Ww a8_D/)'v sWӍ_}N .-gϞ770ٽEc-TVTuu׭{X&y_O|;}JmCpH҃O>詜 vJe@ٰQ-#I2eVׇv544Wk֬.9Q={NgϞ嗏}S=>O?j zeYn;tkWWPb\%={NiSЋH[7h!iݣdaH_@mH'@ pu57 СKKZ=_{.//l gm[凑tHFC3ܢ]nݟ Ql^I6~oޮ;! #evZ@It`$=S]r\׷DpuJH_Uicu ;)Ils6vsX VDtHFC;'8[.EHOwG5ku¡< . @It`$=(Fҿn^}$iӦdž0-gtW룳#_0AQs-+4Rdv凑tHq46< #@nmҽ8t#~)ӧg9 }t\ΈP~x@: o-(F?V*+ׯ>)۫*}.);G Bs~xcjwIz{OV4}Vs|c$ҁ9! uuڲ/R!]Q>Hc.6tz)s I!H Qt#UgѾ}6;8{ ta$ҁI嗏U]]L8oU_>}dΌ4p r12R& s!K^@a$ҁI2;o&pMrIg F 0>b2ܭ]o~<~0H4gv~ظq.ժU+U]]yuVk;:x%{w~q W!IFCjr-g9@ 3>e,^]?Z~&ls~<<,tI!׷Dp7ˡ/J_qYǪAv|p'Hznu$!=ۧ=ҦG苷UCYC?IZ$n8@,Iҿn^}$iӦ$]ڋw!GlOciw Lfy!ROb$gH߰QIڵZ;?߱\V=R['O]HBLF]<Rt!鶯pGJ]:u&p!`$=`H፩~G:{nZ.6]żܼ#j˖G"+/)بxZN8t.uГ F_uI}]ڹsmx#!8]ŭӷok};m?f,yR^ݹ;3ҠYFFʘ>AjHOH!FC)x=;SZⓆrg"(Gң0FcyI22شZr2ÜIUjϖRN ^va&g:@aNzAzSSw8NsԷhucώ*#CFa'fH!FC:Ԥ˗{^۶ms:7n#'e*V-vCҜ5(HF=ڱc[I_ft非ˋ::=F,G@ 1Qss֯uחEeFTQ{UkWLWn0h-}ձL�dxYzV 1C.w6=r@_}I"޾P tg W_ic&5-T},-N~ 4/duCB 6<*IZO wl!=UgSR>hs~_wwq7[ ͛۷ZNKTWw|cΌ4h2Oe'M'I7oc{b?: '?ym!X(N :x O>QOq#qI22شZn2 Z.iuN<>rC87ook};m?f,yR^ݹ;3ҠYFFʘ>AjHOs:L'!_$CS{8eH8'?yO'Ot;0i==&ioGΐe\}ča_`$\bӖk9ʔT[c2,Bz9Q]2]i4 (ː]| Лy}9s[k:{ hn}gG!d2ҌL&PA #MMMZ|mfAlY霔ZdnG Is֤vU%S+TȮ߫Nc`K8R,7܇5"brWW(#u +&ݿ5ggELuvej}oj#i#!HzFz/O+7N/K|^pyKmeA R7A9sn(n~ΜomqUU]UV/S͇OLh>f6jhhTOO֬Yn$=_qs! VBOw U!!  ttHeRMZkyc-E9 v tle[L )Nw S]S_o;-3gSnO@j~;.rٲe_]^i'qLWy9CKMM,_A¸]6Oi*)+QF@oꃣQtfyT~,[%ۙ&^ꃣǎ)zܝN ^9{)m= H  ` !!  tt% OwСVj:vOT,؏&cW|tΪr*[WNь3u5WCvrn]ZBND.\>{;nH< 'wW-\x-ZKܦ{?onL Nwy啽ZV-^X;vܹs5n8͝;Wŋ릛WFRme_^ֵ[fS*^;h#:[{3?弌Kl$}q.\^˖-+,{뭷tR ^ۣNM0>T@wP|ۼ˨|,jm6m9vۚ9?­lcTCb#'NDӧP&ц ,+UTTh:q''b.kq%E@k? zLtK}Fһt啟a:r:mmm2 CƍשS2#l9Q'G$m!}.L2 CӧO3sL;fXu](AOV3]"O.P>8Ymm謹_k֬<{m<ӡgҢ ;&?ig}]{@yIl$+&h+w^vmzqFi̙z衇kkzu5W~h,an2z6ݧ uzaFILs|JYvкK/7nQUեZj=okٲ/y^G/>pB5,jϞ=:pǺ% L#ߜޮFj͚~U%z=ڷ5M6]OPgg9I"`īLѣ/:::uO3;F롮C0ajkLu.!!  ttN%]rt[jnnIZ͙s!@zĢZ 'Ҧ[IRbA P@6Z:ÇJcPL&H.MCB:ts @,Lvh$1,)H:#;}Cj7tPN]ԩ4]Ika / pI$-n^:uF3f5\[4ztsX(RY9s@)es![;w.U-REŁ%Kn޽{~1[cZFdɘW^٫ oŋd B/M7-+ TyTwoNNS:ܦ~XS~ͮ n r>y\< Rtpt>S .t[nEG0a|:G֝-;Ʈ q*;l_f*H؅T-ۭ u=~^>I?q'>}ƐtOEEO'~NA&cW:q[VӒ8i+;s0ZWWvrܸ:ueGrjO$Ih?hCpXH#;;;4v@)-$pN }V꺒 (_Mw_w~^&Ocб`~[Nez>M︯w@]B 8 ݻW/]W_5\QS/^oAZÌVm?uٗ>%z~^xE jԨQelV{с?w,,~ÕUzz~?ui?CM2KǏz="CU%z=ڷ5M6]OPgg9Iw,QUUg\;2h#2+ԉ?Qg4vvۯ.:Ae*0ajkJS$@ItSSSÇjʔX#T> e'PPSS]xqH:uOġV[nҥH};vPuu}{8!egΜ 97: CPO28' B:B:@H@H)Tg }yT*#7.X0\a"ttB:B:@H&tRssK"ujΜg7t({55Z`<6mݺMBuB Ӧ]KgwQIr diҥ;~HHw>wnޔ)Ѯ]?rM$0f(2`D`$ekAҞ븭g/?#^ܪYttnID!tcǢԩdu&Vyp9^[cw IQeIm Rwo`˨9~;t9V).[X(_xl+Tt7I9)UĹBz!iIxjVN) ՗e@3PbKX/QqR S wqԟD#՚^i%)Z~C# AF4=4_x(?$TG ?x]m6HveYVcbX9_˲8鉅t5Xy1 ›&m݇5mOܯ( {o[xb]:2?,6O2KǏz8 }/no.EqP0 Vԇt^x r0lB:/<_@H%H:@H'Ûj>|TS|Zzui]K?I%6>6_so{ӧOZ]?RMM{$0 /eHS^}Ӹ3GMMu!߸?vIGʃדo$X20zYoׂ6aWuP鴽۱r:vߩy gU۹e̪|òe_Jy7.BUU֭۴to&R?T]]/+$ʊ]x 5DÜzV幅]vi_} mq'~;VNk[9VFs˛rf>:|SW[?9sn($$U$#^j;`_[8ھ:oH˶^-jsb:qc~˰jOR{)r:;t\סgumMԘ139It@zԡ@a.L=~U}QoT=V#ix؇(tt{S{LgI&œ/~J]RGH&{:5{ QQReeF՗kuWk *]rI!8Xt{)~ܶs0׶z?FW^3%jzXK ?߯.57={Nc}qƌTmZxϟq7)ݻ_46nܢKjJUWLc e0}#|6k̙>O\Gѹs}7R^E&iܫ4yX3JLyv544Wk֬f$Б.}}9:գwkTo?*3O\~n͞ '.SUըat):7zzrOtЩB8?yK[nni&+.-tZ.gܹ~}yGڻjm=^]vYԢE])SWTd}lPGGo?gt|ƏT:IMҜ9Wӟ.+tZooN}ԭS55\dҧ>5F_§`՚5 ]}a9ߜ7ÁK(I:tJ'OvBӦ7_ &+.UeeňP!yY>Y>˙ +ӗv]ݒ{soV&Jgg?oVGG.RO-\'3\cV扄kIr$}6w k sm͠(Ei5ujm?6 }f./j$ícQP^ vif$};GgӓUWUWhѢI_'?9F]HC b(VEEz)e2}LFO?D t и3t+XZEvj[ͣ搒_S-A(^,K}uj9<2̩Fmo>nVAi2S&#UW_''ĉu<ҳ٬VXgyFt%QsOQFi֭657ᶞ\R2)~˔ ?e sᶎ~>{ /yM7]oZSj( 4'K/TV0@GƜV-ˏMc/7Op+?vuzvi4\vY_\]_)ۋONzcwmr;aCa/1oǮseFO~/djo=NcWv1sꏠ/H; {q$G塇fӟ|Cz&֭[UYYzJz=裞¸[@d]s ve ~C]8b!ɩ+z鴮cgݛ}̣x ݿQRuE%o~ qMy2̘1aD]<*O͘1cвZm޼YaxIϿP_T l/Qi7:7D q }vs,kQ%?җ濽8/5=OǪ֕-) Zbo^V--/O?$w}!345F(^W0)q^GNw چ8Ayu%lnY}Xmp;>~ni_ީ5>HҗL)]2ƌS}}i߾}Z|7^ͣ\ڗct(GU62T=I\|]A?! }i$ǬDrI_ܴiSι>3F7ov-/ֱ[fW_~-TQ83LN]~sZs[X׺˨NAt'!ݻ_46nܢKjJUWW{gʕ/ƅwkr9e2}[lٗ(8dž2/g֛v544Wk֬7>kgظ w#]]7HLZ(}۞rVH˳v:!QT_WmJtͣ{母7L6ڭc ^iU׶S{N~Y}Cv^lv=~-^Kn=>!0S(muUVmD-J?*ynu)lyY߭./cz9As no r{gÔӋ9aNWiy[D0G ;u?*~icZK i ùQzmRK8 HUH5;Tc]4\&0+} z7 ?Fei4rL:wk;Z9Ve ^o ^ǩn?m ?~+9e{cxqUU]UV^fذ|&`_ U{{ӫ5kVIom}Gx^֬j֬r 4yt`d ׮]'Irmذ5GXJkao8 'rBp0 eY-_\+VP.tw]k,1r it@ -Bp4jŊzg$I\ru=5jn)[KF@H0AS\|IKjkkXIet/=?bj#ܶsӪLe\-72s[ IDATn[5okUyYs !=h֭SO=%Iz}}}Hmœۺ^Z Yn?[mqb[D2']4cƌAjkkyfH|3v~ ا)@f?JqdK.ӽ;h]ZZZT__Fe2Dv(ڕif7{u0IBZbo^V--駟$=Pin>%:]7&GYt^.LFcƌ)ܾo>-_|zn].h޼Ü.hPdRik *(A7mTOcƌ͛=cԝ.h^ts]ݦص!贕(DON}fۺm}$qUU]UV>V\-Hy\.L&Sq-RsDs E{{ӫ5kVI5jlk}Bt7d55n@HO9\iUAttB:B:@H@H@HDeCNO@ TktFg{~:7/]w>/eϽBz}kws4 %wNgXNI< ߮?̙s H;OtX_CVq䓍瞕C:/] Ða8Ba q@Vy>2-  +}B;)" qc! 4^F }C>eʬAo-yM2+۞v}DݧvM^K۹DҼa,}5(]tAN$˂vM}ZW~ئLZcZY#Mk 6j_0t_l}q1*LZGB7s&q>y@@/ 9)C%Nw1U)b)I:zА=Sku衒vpUp۷r0!=m5L#)}oX𓃼f4MmR(-]I95.nБ#on$9֠mgkgZ0 uZmՆg (vw:NdY>9nvok>ϼ~ӱr;sAvj`sxp*êO<Ǩ7I</ (HdZO[KۧaKl'$էtzr^w :|yӦ6/sڮͅrE|~6/ntYmԖˊ!qN'(í.c>i{Arcmݶz΅鋴>J1z=9[=o QE\!ھ:MSqέ-A43cW~:]Oj}n-q7wPӧ },gUNjsK[ 98 ΀MuCzף(HCz.n?iÆi?ȩ0Θ17t0@a;c[ہAˊqZ$;s~ѭqz\}[ہGcuOcTHk@OkH/~6^ L]z= HKǾnS!ݩΠΜ9oP3g΋% f̘;Ӳ(SQEC}t/rι|=VwHHcj6 (VTm\[KۧVy= ڔ9Qtl.7̙?s<.mw~[eN˜n;U3gγ]g>n/e_w}X8=8Acz ?1a$*qA^'Hz\}O~^dIeIib#魭o?7>/7ooNonVgQ>Κ5?t>ӯAèiߝ8zN}aUƬYoNcs.hOU0zVU~rz}\z݇>!%I2kIĽS>u{ zsp}Z,{ƍ[TUuVZj?_3*Q--?e|s^8\dY˿Ҳe_ cD?UFl6XDHSϽjhhTOO֬YGk:thyy= ܼ>͞`|yyx,n\־%!=;9(Kͯ$q, 4L)-~)}f$=Ͻ%IN}s/!&>MVb} }s/#0 }UyO} kj/^zTSSMG`ĺZ>[ΰ~|_ {LB OMMu AodDKwʔYzi+  HsPBAKJ>[{y4)Sf4t)/t E83'HY@gN:Μt 83'HY@^ijooĉWr1744ҫ@U#I7{&UΚYIR7\!SRrIENDB`MP3Diags-1.0.12.079/doc/200_discogs_query.png0000644000175000001440000062624411267273073017226 0ustar ciobiusersPNG  IHDRbKGD pHYsȥtIME #5 IDATxya&/דּ Mh q<"mju0vmbWz'*1h=xmӖmI,ɴlqFFzGv5 uWuwu2˗YU̒Po|ChxOH贈l-""""""2y08K@ @0h" ňhKHd2x/,f0,GD"!m9D xb94/wL8V"-/cX\\@"aff sȐ$ EDDDd~~M38؏ζG `¶Rr$ahSUnvŷ׈D;;18 C۞$1Lc= /KvR6VV( EA~0S/?cIF?}xƩ? i*a0۶]r4|~{ g`G#?ǭoJrO?h4u_@4Y'?Z{5 CohYe:F`J۵K6K/"-}Vv^e#bw.> =~__({0?7!L^e&""-oVJh^TR4R=j4 H??:WN 8@| xsW|^80`ҋK>>[o]bcWաj‰)g,K_ x*WrZno UGa8th?._>[rيۢZ5.ն2:(VԫᕖTԻ4RVy^$@$!y$W( t]0a,ܼy;w$t{*5fybMk~p=L5,+?w l?#+'٥֊?Yr2Y)_<8er4~a{ʹWela(NNiZzzR,ʵj|nV ?8aH ޹w{~<}ffO?/qclܻs ;wyu"""Rg<̏c߾9?1<|8bV3BÇӏ}cXX\u_轡g@. ?kכ[ a }}w6k!;_+rxǏ_E,[!k'ؾ}R^zǏ޽#%,WF%ʬ\=b(~}mZ0D.qۣvaavK|޽#+ڻmp*ZQn;h^j<+3oCGܩcm {_'Og?9|s+bE$ sϋ;;[?-5]+!܏--0MQ:??<(xџp5 /?պRa vutZ?Q7 cc[\f2I2g=LS/zԲl::"km.2JRWkfڥm,g[B٬q~;ZZ=V^jsI01oߡ'O}O@??W~?PO |,=/=&c%ɟN$|[ox?ozzx=?΋/ěo)OTO>9 4`Ncϳ:<~RFqۣZůVj]K^[hRGiգRZ[.nצiĉwy<,濈xœ5o{Smz5GewLtuwCTضt:cqq%4Gwwo?9s?0%\\|5_ay+ԣq"ۀ;Jȟt[~VrF(u%xycc7*ʬMKճTJ=Zm|œ GqmxKYu/.7KeeUG>IђzJ D&^~*$I4@\87ƒ8xi8y  Y(/""":ݎybF*VV^i8~|7Νߟ/[][zgvwcY肬GE"8Vx뿧E"ݏ `%10З0 8q8ߛ x|LZPv>e~727W q,׆ֳ۫ԲV[+i4v9wjyX"TQg:VuZRVdƓO0<s `"vƿ_<;??Ľ`Rm"""=̯=V@6[~eЗۃ^:Zp^G&o|C|KY.}هAs9r $ AFa 1 <č8{ݚ:O Kxp cWr9kyx8[7wrb x4Y@'TC0G[2+JUn o^yOjz֣x.u/i|J-apr9Deƅu]XjvR]jSVid,^=?<%'XG.k禕m^5Ӌ.tvt!CQ077T2ӧ;w.iMDDD[zwo-yln|ܬZyƍe/KRyW_B{ϟ?-ePiB48d2HWi[ilƊi@$|Rrʇ|zoiiƩ\RË0qVoR..zZjKOz\O.:6jZRraJOSYEe_?7lbL7FqcR7"-߇vPy9(+°LDDD[J+e:t]~3u0 !t]C$z,_aVkb "._!5yRhsEQ 2mIӳjYyss ˷϶[=\-   V pahMsqH o* /ƀLDDDDDDO>[+bK]-ҰVy׹Ump##;p \)Z`݌Z[bh3dU.4W^tеZ~_nrʕUK9DDDDDDDmk >Q-d633333њSDDDDDD_Ci6D)|?LDDDDD_1`B}qEe""""";O}5ۧHxeͿa\DDDDDecUhf9ϟĵLDDDDDpb]y=B!A`&"""""ar001#$iT_+#IҺJu/7T] HΛjaNܹQ;]xkvjKhʚzgu\iDDDD9r疻wJܚy}hBf2:z~«υTlTx-_VTa.c-{meZ۽hkYṾx.+^X^<6c{a ۻ(_Z9B[]m FI&x!+ͫ sͶC-=mZy^[]>m܌ +ٷc{tua5[jz͆ ̍4L.]4y?o+Srhl%""""ڊ_?X8.~Rƺ~|U<ҰJ6:[+0vi-~BO+Tk]Nnm֎너6NXnykfBϖVz]/6T`.:*ݣ:U^|ݙWCƫDDDDZv8a>Q|v:tJ>M g+_zBL[4Zz^k}Z._يuҪe'""""Z .[q BҥwZ9㖚Yu+DDDDDDmyfuLҁ7 6 ܸhf-LDDDDDC3k33f=cG_s-Ѧwr'20Wl?O.\uLDDDDDޱcGsPʵoMdSlh!""""">SkIy'yH]`PYU_ڜJgv96%ضT*x`" O?݉'z˃D463y4.]Z3tix@O^‡?܏Gm[ Ex DDDD݇Dmn|Һ׶ɷn%3xYőHTųĉ8Ё^.o}10 'N;x0Wq,!08hqx/O iLDDDy _DmF~ae-'p Ξ͛ $6LS޽Q<\/{F٩0$f"""""'5yr2Wc8}z.cb" ԩ^8_M~a ̫ DDDDDDPI7nqΞ]xNic,::fpۺ##;3|hnDDDD_b% ]vʺrbs7Z[zU=l &_0ޛō&*^:Ջ={yor=DDDD@;!2&?xŋ 8{v.-L}8| AB*tLDDDDlaVl+ )7m=ׯ|[ny]z\jRRk]M_iRzQk۶ڠROVmjmSmOM~ƑJ59҅B!Of`&""" ;'ܕ+yUOVA-ҪvKj!UufPjFgmUG#C# 򰰐hO…yܺ\7y(Nɓػ7.W]Bs02Z\zeuZ>msv= .^\D$ap^=څ'M_sm"g re2Fmʩ̫(}N>zc-[zE Gtsۃ_cSzv"7^a&"""ڀRWZFU_妭j󩷮uZk VmzinԹvjfZ~Uպg}N=zu0ȫɛr_o0t|;vU݇nbS|w&o6woo!_f"""""eG>2[!"""bdbX2 s{QK>՞107Tp]@LDDDDDDbl""""""w>Wj +5nVO.2]ҰZ_ZlѺRWq le3uNa鲁JO.֊p[^{[ I6QbNFFvԩa8VCj ݧ+r5~l6ǜ1h&47 ˵ts'"""j<7!"jW^4^{ ̭8 J]VkH^nDDDDDD9Y`.FHaH&"""""Rd633333њSŸ>}nV@D-12N䱃ڌu?яs#ćG"";x!~fx`_xnuDW #<?3>LDDDDDDLDD IDATDDDDyk:]#$IZ66ըj/c׺}MYkϫY.ZFko+?QNjRxu)?_aDw>K5}`&;I h2;u?^Wv#Գu(>hsoCZqN^W%hE`&"""""_8s7e]M*uO,-tTTQ{Tz]jPjR;JHjVn*-G#uDTyXjWu}irZe?Ⱦ]ݗz(^~v#8VTWo5mDz|ݪ]IYWjx _+|k{׫mX0 |jy4rB'9.Dg-O4)47rݙWD'zDԪHZσݱҗa˚=Rm{FO0+}B\OwFiwi+ZFɼ^ume"uifjlE ˴_$!ca/U\Fk.GDO0h!d;RJӬUr"2zb QeKs~r{FnZp-W֮'jYZz^SFk.ԙh+Իuj`ur@߷pHDD[mό?AqHDD<{V&x3uҎ? c5 -AgcQ]@1~iCWUCo^[mk<#~e`^A l ""|mB̭[w}D+ eنO/7e`1hB@hu )b`&""ġs0010{^_j$iX9oI.'?M3*o=uXh*JʽߊPy^a##O?֭+ GF^k24MsF8\J'ND20:1XVtWj W<8u[6R]+_{&_o!De(^r4DKyrmmsfǥϥB4DsDDD-,KصPk/w[j-] v7.)u9W~rê;_rՆgfH֫-*uA'"Z [0qc U~rêSmXx+q VuqyƍUjOXbշr^l "fC6WzVJ݄oy}@\U|CZ=ɮܟzؾ}G1:={}]n牊TGz={<NW쥆5[ZڷܺiuH̘zεJmղ7!107xbPnG^IV+7sj&! 7Z[fiBxۿdž]~촅_?Z4]e)}GWW}ؿlΕT<^(^Ěl?V{aDD[60Y)L**\z6Z=umAD W.|sL+wl{׮}lXqtopaʹvdž֥cq~yJ_ismǦڵp%m^DD uv(M|-ۂU܅cZ] ]zZ6RN]1nzxq+եJLkjyd_zO=u!Tc65}W7vj'%-h}pTjz`ԕ+gSWSqٲ*xXJÊ)G:Rn-u)\e6]=u wYXQ7VwzZ=hͯ0:a(u_L.ik6Aa^Y4j*WjGڂRJ._>>q)^kJTGe) x|LMRKjsǼJUjVVZ$jEm\NևITSDKk僵98`ڊW d,' Қ31U,`KNUpK˾.VjÊ;tc/Cz+T=JM[O>Ur]75u=תu3s.c5mLTAs c` Dt CHeݬ4E}yV]j-w~V7E0(\˫+0::3J0T /ۣ.i?Hwt 2 ͫDя/iv8zy\vC;rZ.ǎ}rh"3[E{w~gNav6}{BQ$@ 0<p۶EBoo&a<)!"o5LϿjmRD53my$aN/?x@@aAIFaL010o(##;gcl {`iX,4ӘJ$Ҙ`a!7q4<Ͽ"i2a߽ۿ2=4` -=pLi>i"/cddG[O \9m(!N74~V[mk<#~e`^r@Pp};d2@*$@<$ɤ<0:Oh_F(@$tt@0u@Ui$ e`ddqi?[\9m0Mmk<#~e`.Qoփ= wd\b,f1=MNf07B33Ra2" ]]u 00@>]]:::tB* CK?4"nDiKe5MF ض-+srJ9H&bTSS07E"]sA0*Q }}&z{M @ON?H]f&""""b`&j i*FuɤE 9LMazf9b6܅_b`&""f"*d'<'Nmbx0n+׮ {҆!#٩@uvk0MׅAZmn.wߝE6b0a^sN>[ՉJ @w7s'N?X ffK DE{3X+X \DTƀ3g}I&31( ۦU9ݻhCs>,۷k '?tL $. .fg;]b.q鴇EJd zzTtv**2LS|UL8{vtx^ l65:z*{Yp!dXa  @d!XX\@6nTD@QH.\ׅ,PTV΂i!$@I 24M 4U[z_z4\\pl6#KJ|.C&i;yTUp`vnC4M"PU( 6D*:0 0Ma{)n?iUOULQTH\ֆ?)WM7Mع,\ׅ:x03T2!LD8F0,(*) $##\x@udJlB#p81XƒIkA%155 ]3K[݈-."BQ";x̻SF8F(,7;HxqH^tvD' $ h!!Ljqgh 2Džu4r,o!I# appp]?p!NCUUd~ah 0 I&''ۋh4EE.tC_ϓ KE% Bd  u/W X BQeH8=σeea:d(X *ǃ³pnBXdUmaYHHPd P#8.8$ᇹt*701;.<$ M $@"ݹ E! B3tx1p- T#\$itvu"݉vׅ0tnF:6dY3EۇɩI|@&ƮC䲘_\@:صw/: "Qe!L-Q039.BT}w :ߏp$=`0 H EQej&29)YYHe$7v%?슕;--MTI>i˹HlᅥtZ /,&'Ә`f&,b1 yw*Akbh( wG:"}2cïY+WqvA8ы`}7:ljCW]MA#MQ\L`$ON#hX% 4 `&FWW'ԎaX]]bHh4~!+sӸ?; ﮂ@8 YYصk,$ۋ{ p {" 0=3 +ffzLӄؽg7 < BN# ö,iHsHLOA7t8X|P;v>(Raj2]$pN;w,˸?͛t@ m;x01ٙRqc18  " 4M!Axҙ ۋiLLL Hb۶!cppO?4l+Wdx'@QTȲneX Ä"u`e\ܹs;t:u Ivك'F__LD*,axx::,<' U`ASIQ$YG&@uȊwn/c8L#p$ǏH;\+/˗`jrCCqLOMa$Ο{ea4'7u\9?_~ C1uoׯ_Ů=EM^ǕW:zi "똛=zD'.ʦ݅#w`d,0~p cWG1<2 lˆ*$P#;wbvvw4}}H`tvum1oPعkE,}'х'08h+{5 HHH=F4\p+g  / @(ߛ@7w`-d+.=pA2icaZiLN~_:x \!EˈD4D"z{M  ,i~Th MS1r faٳþΝa~7p%Y<ٶpU{ f`: lAv骏i0 bϞ=8uyܾ|c7p} p\m]~.uٵ,  cy$IFm ۰,@c#J4Mq-LOO# @WUׁ8Hf*,dE0! !+ 2i*&&<-Ip]f#ؾc; SH%HSX! ecfvsmm#ݯ{{pad\ btt 33 IV0;;UpWܼvP#L"Jq]_ocxx/AUdݻ_{LiUaYjYF:w+ f075\.w¿y$΍;D<Pe7n², +8|d/‘0dC d-ȲEѠ~wIlsݻ]%.]oF:n⟿ᆵ(2rVӄ(ؾ};>pr$o᧏B̈y_}ׯq\hW^GX\0 ضw:SN"ǽ[$$ĕ3#A.dIo=plLa5? EHp> s9OO}b;}?]Bg;5Τ.LYd  xh[{62s 3$˲!2ހ$I*t\,C"6= q sP5HG:{cRCpr6&B5~Oo uɅc)pؒ@"},NOahx0?X2 >޻ѮNp("l8?0w| IDATHj P.zK=dI903zw33oK09;I$0Unct D"::tc'OuFGctiE4{77e#yp5 @+h±mdIh UV.uu pB@YT yǎ(\ݻ\pHvΆ$KUX 0<ہiBOoAAx.TU@aڵ1<|8 ۲o"JCtdYGC@R}RlT8E'~%k7] w'{ qhoH8H'lDup= I<ɑ4L؎+TjҿOqu*L={4)-"¡2v"Ia,|#q`>u]8I əsI莊r3P4 ] OöL3boW._`i /=aVE4.2 s%ؖS_9'AxyHx)+sqxPd@tؖu5f\d'`"lAw_/+!t!<cq!DO܁wEr,t:L۪,Kua!8yH&m6<3ŃidczvֿRmY.dYHTDQ k,w2٩#Pa2TҲ,muBi; ]u jA݄%el–ap=qB$HKtqrH-d8 Âip] T)kCH O< ?{okI;tsk՜ڄa%4$Hz0 ' a0Ƞ Q– C sn*U]U5tM]gؓ֎qOʬʚ2N=S=Dķַ/%f xD)F c-֖Ѐ  JAt$(B!bn{Lh;Ml[7oc( |$daPV#6$Y,O̳s`^E[~kP%8}iw~-v0#9c߱>Ww1ab0 }DɥK}?2Y{Q'hik&-RϬqh)H")l՝1بI9hf ,GX]}bj֢RkH$ۘIb")QVy(EUN"uJ}-㘒)1EB$)JUE@+tDe7Y *Hģ=: ÅґDh)#*!$RLnD:F䗬I1d׊1*C8'T^ 9C_WJfi|9`&7EB-e)BlGHZw~R3&(7ag{h MU<^>HIwA[1Es$.X?3/ӧ{Ъ g؆(M)iJ E'H@Ņ<猬.+P!B4< R;Wxwfos p0iId{ǎ̏~vh~csәJ1 c ĉe!lm>OysʍLnޮau!$hd9qY^[pмO*Y]-_ELQlw\[E_͹~op€3 !4^y4F7sh[R%nIIXD!̩ӧQ.{1!)yN%QJSeYP5$Icr$\kD`Xw!O1>d4D6]ܹ8yEQJF;]WjVlER"JD!l<Z,K"AaQ{d6|W 6T$@X~)M.*B $qуQEQ r r_ R0+( h>LfrЃ1iZiʲhݝb,$m4h 뛛2&;;{X[I ^2yG)VQ [r837$,՞?/yZLGS -ւRf0 ޣ"iRCrLѠ@Ղw(UMfX}#bzUEO,Ė-klݼIiBR0 ( X5ZJ&GF,td_B(A$.1 6_|I/^whx:esɞfyi.XCU-ϰ.x*_~o =0<`x[ǏДO< ET m;{;4aPYj0m&r@2Aꌓ–jT-U|G$LR(TRA(0Dנ:D,oԠu"!vH⣜JQjCH(e( H tB+08>CPZ&g1bKEVqC)bɁH e7MMA((4`47 Z)lQ0(P\ I}Ja'-@5auׯ( |)4hj !MOib.Xr6U2!jH ဨqIQHdgw[FC: 6Y3k-J[\A^1(-@A45x w?`Ű`̭Mm$"5aP!b+ "FjxH>LvhK$e )EP&4BN1*5`tBY ecʔ  &xL !enݼ {Rs.A)́zVC 6QbI,-]Aw(u 4ZEi@E,+oͅ yE6(ަPq(aiyNyAɴ~o0w>__w;:iiF_ox[5W֭[5߿Rؘqʘ^")㖥%˩S/ SEWvX]-X^nBF~Oo#}?oC?/x?ƩS  \xmʤmPT;nmmP)@!+Kc{o*K#UZIx/ Q%x#䞍lS"j"(tSDf[jt2^D/!QdX @CAJQ2(fJy]㒂s$Uc\~JJdJ\k@: %AiBQ6Z@=ƀD !jy aXE'R":ɘ9PZxjEUVB# 8F!js[;e4jFc'H!v+ŘI zPFzJa)tfikMt Jbeup󞪪T,jMh8d6|ìnV+/ I/~'z#{ |_Izϟx'ݎ٢};P@%O<Ȉ੧K/W@ y?'o+~WۮvWͧ62*vw7_[WʯCEj- HO*[/Z_{ُz}[OM&ƍ)_ TՂ 5dǂ˗ؼr[F@XA22xE(gb$ (n͵)F#-@ t"6Rs6SԷ}U%KKb=G#m2I0:N4>xb {-7&NhI+]7 GMT =BWhla)C"SD؀Q!H( O&*W zPIjN僩_+P3Bϕn z!erF4d-TuR5;t/-y-2m?b:aQ4yɂV|M>3w}pXw bPX3$E@="PK ; z 8'J ֲ/1E27o>^ %1BFRdZ4ϙO..5(-A 4GX+EV)57EC.㭭!cnd;zO2oF tiFUM<'fEu4X]0n5H7 \lmoK4~L3bg: r3´{/?+mN->Fx1. @+_yȺ|͗:?_ǿ2+w]_b}}kڣɟ7\0Y VW ΜpI=+8!PpLCpp8͹Þcem3^xag~f/|ai)"hvaɥx>%꺆(Ni!bA+3%ӔbDr \|\awwm M "vI!;nxMu 6wۈ .$…F@>uΊ((އ\qt9֌be`8`f ӧEKkN}K"d1-$IKث: vٶ\#AVkŃ9EQtRBglT}ڏzm1eodrV\,wb"^%|2.?mkߢ]E$HsAIf0!91G[@K彣VA^Z}'Kk6$%}YheM*%Atp/}at'P|'l1~sTum D=d64%Ҩz8'ag(/ܝIӃڎ3.쬿?Ϗ[{m48~~.}i")w̕+-d{{+Wo/8 .g/8sܹA>qBph:/'iܩN;aϱoI+9Sf4Zn0VsJIDǂY-)hu-Ij-VCڡoj6y0ҹLjǬn1Q;>ȹe?\s]g۬r1}R}Q^{}-Coe{vXkrf*Gڐ2%[]ʄ# ")ABm 9fu^ |` b-1fRRcHGu ۹Fu7|2`biih4booʲyij|03QJquz'>sC[|{|?= <2$%klHN֖)׮Mڪ:V{7bZRd!NU\0…%KKx;j' ~kGt:_Oy[T~,kkE.5jdEE߹s5KKR3P!vjciif[[[ CB.g0?̳w '7N/"O?n\}К="&F#ɓpP 㡟t88plnlo7Y{(yolwllx t IDAT /-.+&Bckk"oYZJ\r@J v}~ove?8~#-]|b_hfT%He~ {[&EAtʍ7:FlׯSo!R4RUU{0p Qg8vT;mMβwϟS*+ǂ#*; &ąx}L۷UUwO?'}R$sN'TUAQZ1өetkY^Yauu0kf8q͇0V믿3<{ݼh1[ܸܸZp'L]6#YUӰYsڄYnٙxP@p>m3{sCN/Qnջۺj3~ "_ܪb2sbt6E?3<Y__{;{x W n):6CjmA5Ϳ(خVZu섷RJ(jMYV# gK$͡_5.`0ċf?CuC R" ʪ"p0%{ԍϴTV8WO{?qגNf3zY `~\D悻,yb:\F4`P4nZC=1'L*jAt/B)@S.hq;Rnіcׯк^uύs4($b:0Z%t**>t 7nx8'a~wn_wzpƦZcso7:7QH4U<(c\'L< n )WNnys•+5?f['RpIH({cwRrXyüwE-꫻Oayy!65h>7׹|2|;˗N"rGp+8*AWW 3[]+x/VNFU{sBbQG6Sp>#Z`x9s2H#ikIw_ދ}"%l:c2\.a!f5(A)&)9FeLf3|bD[n.mPR&(V>?>܋̓ҏ2yAX>_54+ȆYiZrŃ L )`e V'tPVj2FJ ]=o;w=4enAu[PlpfY7Z} cV8},lib4[#UY u-J:|\w9 6 Hx)YE[O)ENN.|N9HfWw?1+gy]nݪY_++W&|;R']%Ғ)Q>{gT<)uң鏦ܽSֶ}ǟ3~/ZurUBK_ϞO~?s^[c{{Z+R8Z<.Zpځ@mJִ(+T[ ۚ˖W6p{ߧ7RxC>Z(i?t$]5\ʹ!P F.#] R8tW@cz+JqrqRǀZ_q~H,X.~}=!h1MT ,6jbN=<狫W'|{0Fs?E<{X=uyʕMWc8y^ЪR ]S$s9Ę>ZEgaԪǼO!wGUn?Fdc1VQV锽=UU1L4Ljx2i0Bm(9nQW14}n{7@֟ZޫƵ,HVQ(r!T*%A$U!>UE(l%T c$hsXSZ@3ibXƭW;'Za}]wRH MTEbmRπvJ(8{mm@ZɲޡX]Gn {s)X֭^{m/_(zyYϞLŋCΞ8ududy2Baݷkb04^G?s∯LYY!nd)$MR[ت@8eiR 41EbBcB\S,(k OQ,B@e#}.`c1}'>J$%GOLmJ`k2 IA`$)`*2ָOEsLkG>&BL֐TQM˙M֒hҪUJGZK*w P.7K)I#y{:lV$bt1lG&y"Ik@B+֊D](B ` OgZOx Iʐ"RU1A2 >B1xO!DFU(Q&q!b a(ՊµAIID͊P`6qΡIhɼT`<4 {є{;`^dmXE#ٳO<~Xꤷ 367Eploqڄw9hrE|yY[jٳX[rƺ`00ؽE{0Vsm0z}"O>x+l!`yo3XtaDŹ $ÌhmEe}Fe%hԪrsU,n3^?}ޖB|cilsh 8_2@kJSL EY <#ڨ`|t:G4dSv ,'`4G^ `{F|͊ UlvQԎ*f V ^4ʠđN2h4K.Ce7nE F Yh2Ge eIHI:QEBVsEL9nZ}Ruh;& 0hhfY:N#ɄΚeckQ<)30S:4]#F BkF&(k(0/-b.vأ 9x|HjX_q4`뛛3^}BkQ'm9~ښJ_ `}Ө^Ox]^~yՂo|c'EX4͑~9EX=J=a="ffSMMҊ\|K_Z`^E[Ř D+8&SA'8sh^_q[lհpW^#ƄHUL'Z1Hubh6x~)?Sg8IQ,ľ6Oyx+5OL#!CQ!fÄ|}P[%׾߂>(Ϸyor 5}ìdc˺'4T>&Ӛ="DL)H cPJjcd2YZ^]]P[ۻdU)@XsS='*Μ)9}Zj,"3IɢIvm‹/B)ųϞ^}=Di wm Rq]lh2%̪c:Vy^On`/\td1>fZ(lE- C3sL&3ڑVR  F#|޶3"% ̡QXI(Rxr5l[,YLO"CpYgԖ?{~| ̇ "P( UBȎT5kr)E"0, NXPnN 9!Cm:v- 'J*wPoNsG-G2gڵ~9kjk @UřkUI@'"EY=؀g¿7}&p߷YE[\]IGQp44b2QL&ppߗx,]P{L 0%VV䱴$//{U( aeaX>Mݎɢ/\4gvh04u:FQNPxdg.= b8-e.-`N^viy mo|) Nj!%4* 89(>b*ˬمeQ"H<l! aήy* hj31yں]끏GAw|}xn{lv]%CR%#*{Ju i=cXX.ĴHlk,VxJWJ-Rlo c9 # z-]ݕX>N;{~VUo,#G ѓ4Y8,Į]Í A9B[Q~~T~{m1Wci7 !QמԳ_=\{>f}}Ƙر؈hVRqԀ/p2/r2-6bub4* ,Ea2L}"c/brׯk0'kgxqe1 τ1x<QN ;%1ߌbQ.stض д3}l9rsޞZj[8td:D!\i!$lQ}+Klųp 4\%*F2k{fiw.K$([k%G+Ma[a]sш3}KS}`v |vYyc(m^oom/K]Y 1QW \B0F2!m%&+k10`4DǨZf4R;;Rag0+s!Dz2Uctg1CZ)-F?B4 AN}˪g6Q+ZKi  **[Rڂ,F,`]X>8y/Rw `mclrTeiXY8wn!437̸ys$]ns[[Ǽ!(4KK%gώ8~x\ˬ8qbyd8,r^I -+lsWX^._xӧt쇥5Mè888`2fl;AbRJJF <0bx߹Ou:DY]ƪ?= fuScrsE)sD> hc// B$U5(E"ր'} (Oa EUG%-o)IiB:ɞD!>&~kŽ|}\>|o] GV?Hӧ_eQte ZmAxa f"t Z0ex_uym(56ovvywD/ vb$HpʹjZkaLdi]vwwֲ@XQGQ1 X1ZT'X_`Gzʶhh)i°T6t(Y38vwgllLqk~}+Wys̭[Svvf\׉1QVX[q .ҧN YY ]&I/Ի?lL=wkW?{Zбf'VOl;0 GwCJ)Rg A~RqF< w Kk@ 5uijh.HR$-@{ϴ )-)E"ZE񅶆<>0ʒX[}xm mkw0{,>*`#]4?'ҕk2Y:gbc$Q̓&Sb hC+1=._䗞|^| BCQZt:ƍ8w7ץ6^IPFȔjzArUU1TUuEQQunuZPf޵֔H9sUpe9`0h5(R,go0¹7s=|}0'泷G=v?}Ё'ٟ:4N0yFmf8,8}z#ң W[=1ׯs>Wwtݚp}fRr痹paKVxUΝ[ܹ%~?b4**Q.mm۷kO=bL|c'(H.%f"֐ 2Xs7=:Ʃgf.ޢ(:g?>\t r՗穥-=n}[&MQb (=$k`02 1**bRHY1y8(,cmD[zܱ*!S[˩#Iݽ}+qx#svw#혨VN{56>S* C&_k8(5llocF%78vҐ7op զ,`__|s <lopMBً<' EZfeu%UqlTeVE BJL\z?لg 0?yWBE1<`Y{L@j._^:iKz2qܺ5eccキo{Ue4*8uj|c}XaggFUNz /\祗9~o~QVVUK>b6 -3LζK|Ӭ:tQxw?0 ۝潽{-wuyae]hTIb7焞JEI&TSO44ޣ&\߬55T!xUѴ|h) W9bT45΢s.;&t:6kn{~> z/j e̜C{}>͵Wr>gaiXXp\IB-WbSk}fQ $"])g1 M$УG c 5'B kl |}nM7 ZRtAJ8WSUܘ, \'epQsmd:y˒QL놙 T{G5KÂF5X[A(*I @YKg=QZ{+D1E0sQI͕ [fD>:3l Qlnn(fQno7?:(N!ޝc?lc"jhhoh!Dr/i%klmI#ׯs%kkV,-,/h=?p{VꤗKFN:osW ,棜;8>t}M\~d V\Ԑa6Lf_h].;:'u'pґu@r\š}T緖jA7]% Եûyˣե%L6J(P*1CN, MpuMa,DVHI1k&L~9fГrEm6sXj5UqK߅1Nlb0HRyߏ=z>o/%Ԗ+@@?,ؔb-$yOj"Qb]M#^u t m1&|^GOnٲ^coemc(%D-?Ą֊&xFeޛ4Kdי^U537ŐYYd@[ Rhi&#)WX'p ,a$"$@ (Ԉ)27NPUssb )=T=m'`/c=Iϲ }<~88yev_v=8W crs ǿʝ; O8?,8vnPl6pxp[x ؛oplj[1US~neV?(_NZRʵMےˋBMѬĊ ݀)xZ5#4NYm!i1<)>8mCI((ean眝?dE bPѣEq|8/kX=ծ:H|1MOqrr RJƇH7uD|^cLwͶQq7T%[>߮9`y]MA#ٰA\j)pKxܮئonQf܌bwW̠b xPX_EN3R*SM<U-W0ڐ$ʴ =մZ;޻7E)[6Ʃk*a, D>~uQ[gAp;_˪ٯ`םdrOu}cpՅ/W._*k2ys%3E?ˌQڵk:GcbpzYƍo{|9wdw}ȏ|i4 ׯϊZt+_9歷qcI7IW *J9?s?wַnK^Gٜ#0893jm^ݵXFդnvu|`Uk\vkS *7Y r"r0D(i7,YV,YG CZdąTcJ F&>ZZKV6) >n\>OT,jϧ*5~gEc"6]+nY(}P8ͻ {zjɾ^cvQ9ØE1ĐEަ]1FnIa#<e*6Ҳy-Wޏ5c}ݘ 1=xT+cVÇ?o|cq~{Y(g_P*-_d[cb2/}pN?q~>p;w. {>|p^T/~H7nx휉W2Xׯw4tyeC_xc?q|D$zOJ 1"T]ڑ})mfܦY5d5T앴!ʴ=O7=4k]+1%!ϲpaɷ|rŇH3 PhwŵcR ÒlF84MC c hǓ}rCXSUs GaX"ZE+DV (ҚXUc,y=`OTߢV䄨uuC[ClPIk!|®PǧsZFi5ܖT mm n~"< ݻ->;ϸY/R@z>f/}pwom]8:jG1c^>=O|ɂ?YzMC&D7ɶ.YMvMWo=.m%=c7l4i&,}u*t{x{?>z:q֛a;?ݻ|G$M;{|В7 m #m;Cb*}3;<<X./2FhDg@J cU㘐.`+ӺKic*+gr5 0V2p% djљO0Kk 69ƽΗi{G5ZhRxiwXtѥys@Y-@\l71r&[%ڴ~)T0\ߛUIl5 &6S٘j*=S $Xnx"f{`AA=}}fO)x4{>%ZU]%("zj>~sR0 X|p',O~r#BHX뤏nޜs֜>_~7ޘs朣IկmV|K4bJ pt|owQqEId,?ya.5a5 T2U\H X[Kfסtvqm(dmЉG65*buVg^3S25zuV>fS&Vtf ʐמ9S~|{nRx$m;朤Vϼ s a? s*X:Zu8geMm5*kWLi6lu:xR\YEHs!h)jEGRnMjV3hш[[y_UɮwZq} ?+ʹT6|)^k_ug13)Q\4Zzee^ۓe,c=W=ڃͷu|_v?<{{u?&ޘ<-u]~-lUAty߿u)%rVrG#~Cnޜqܹ/◜m{8VC_zX2EY[!I=ӊԔ9]|JG`yܼXy4=W/?%ˋ{+~}hCcX>k5\ 6rEJ_Ns}~m >ahN47]>yG7#JsXmDA:v )lhی!dXE-QuI:۟gTU줲@$Q#cl.c9v&U5=ME~R-"[G%j7U?JTx16ӯ-fCu[2B4MvoYOt#n>YC(RZ QBRmm~dмzrZrv~έnRG?=>}|!c Ƿno\!~R'}>J߾}_pNJ9}G3ܼ9筷 ;:97nd?Z'-W!''~7f{Ch~W+茬r2UiM@xE5b^OAp^hϤ&rWlϬ͚Y4pɊKr۷>Z.Koɝsn .V||o Y耣Aa58.K:۬}bj:00b 9!xNNNMb $aGP `RbxĮ=VJ*{ R5 5ƍ_*u}x|X~x_pzQ)@(`Ujw:ܾ}wڽnX%­$ `La@چf~ ޶ti(r rJE:f*Ft1jffzZ r=1srg Lb_xhZk)q䘮V1-+Y-Vh|pXi_8={juќ_\chΰ\ehSV9qaO*DUtm.dV* f{'ȑPxw)Vk㉹S*BVL*ohFe[^I X8"ӢA)D9bVVJLN` {Z|"Jxq2XLDtI%($ђEB2,XgCdMF1 ʌ̪PܫZxިQBw5"l/֚C( :Rwdkb¯mNcD0`D5.xB D:F1 'ͯ5dcޏy>wolQn Jb(F k:xKFI *%|hUhZD4XRrYZ,>85\?AkMf3`XlXVU}#ps"%xGfd?8$ICr1xlLtJtx1  m4TIJ\@懀0 Z i!889!gEr|;+J #B3x OgHS5KdS 0"P䭐2D tX HV)E@\[;)FhDi:&0ҲIԤ}+:ElfaWȤOnjD@:b#JqqqrWQ6FZKEmZ̶$mYvZh35ߺgz{Y@/8*V͒cˆ!EH ~Hc#*h~4&J"==`>}cnt*j*+V0܆:u۶Uk=M/EE+%[4Ha:_Ww>?xư\.Y,V zjtJ @:g1D>l ֠V@Xئbb3 s\,qa5Y9G"19×b΢!F|z$7nGq=whQ8>1h1}6 zDe7=@DkԱm2Ua.6vRTjuB!aRŠəQ1Xcq1 ŘFuohmX-Q+U8QިNL7F@]PoMaZ1׮CQ@?!u~jcZ]|ڙ:\B#J9Z&0Uͮڴ^qnDT xez>ejߦ,#CFYs=J$d*vג'ň)w7޽{\\,˱o}cK}|ԟc(9\ҩ%yfn >Cc}T:Hg@,ea!J$SX$.C~?b\r~VYJ{Վ,N|%:<-XE_{\…Z,=6\}c)a`[_Z0g!LP~.*X/YWz/Fۜ !ȔFug ;3}X#udY ꛦ 6F:9 4.ƒeXk1+DCVtſd|Fh[ Dږv{BMCL%E 1uaņa@iMpY((ЍA"*<ńJLUTA^)#" fZMgZ0FM~5y3!"l&}\i> eZ)&B c;>=XgY'^ CY'*h!&p!И\},vx1Fh&![Ui!k"("H_DKQ.[)<땗ը -zWWhz.F*[k/3 v̀']үb{v>}/s|ߋ:ߋhϋ}}uoΙ"c яYl4|^STe1ŹPaն )s[٭]LfՊtPe1FuޣT(d1j  fn @Q&)_[LŒqnhMcX'2@Ӳ= }``TM4\nLVV[.җȺMޚ!%IE""F,ꥄ1x6-wVa hA7" @g[18C"$OJUBkiPzVTz+ɀYX;45@VLW^)eSX6$ zBpAպ(OJv͈U*~|<ʥ1leпR1B(Q#*s! ϣyOOO{~w}G}Fik$^v~ڰUv?&x۟m~JUJe5MkݴِXr*QS(-.+-"Mb{ibȠB$U8]\X#9Mc1#Ɔw?2`5&g66|LJvJ(MbBf[5(L hE*4l hB>̾=t]KHgs5>O;ƈhY.6 LozHM7UWhY k 1D_6zʫt5Ojeoo&MpG@]fu!FRb\_.l*˽ћ"Y kHJq4|',?{ 0n<;cO }cx9kA\gP b9..aReq,zǺy*kzwHRkLYLY*#Q3O !YJ3fv5Z` ;e!Dֶe>a*ߢF $Dd_12.Bl-|a^bD3?qrtYKk݇,zҖ=]1u̚YgY-3s,ц"*Nk5^ק*Qk0Z$C:Q9;*Zc"HLhVkZi[ǒP: iI(`qpD7i]KBq(f1Rznr! Ū6(YZ2 %[ULXzyVO@Ȯ%'}k@(S,J--o34Zk>saX|D)1f3)?uٜzKl})k[8тw~p%팮qr|^z_;?|x]ۊv \#")24~2̜s5}Rv2zc tU8L6~/{] Yp럂m8m{z>9w2}2cXpxءMAVƹ Tb"\Cu>לZi9r,S BOҦUna:ZxnBnLGh5mYň*up͊H .cDes4HCL! BB#O,{R"6%p&fՊGĝ{<8_!dUhA`DZ-g43JXKr$5T\gkTcFMV)ZYEA0Fi)aFik]pd$<^A @H͗k^UAǬsI31:|2SvIިfZ9v[5FAWI=g51/Ih@a.;LThT$:Rl*欮WJxGKq>2D .:LN"!1kB.:THT|V4C.V+܀:9ĭ<|`~I׫.r}Wi<Ǯ>>.?Ώ9xM̳gO:~L>c|l7(zǧ베kOӆǁs<*ǼJ_\^v~1kIRdP ( XlgHݰ*jeDpUVޢBfR޶M "Ԕ~%gtUUS@ʵ1R§1%(ʿ5)Ť1&gY(\?d!%%=E;\LRb#Z$m9-V"гpO.H)Wy:6ӝwخ> U/bkYZ+2zjK6?&јsR@icu@IBDLs9j4ƀFZg*n*(e$ŜkwIE: A1x*,rԒg.THgIMt^qZQ)aր[)¸_JQѨR|P *Oìks4 )д"]=Z,0y%oP7z ;7"6G:p֭B7;21ODp/v _54my?+>v͍ͅm/̡˼yhʐ>qvSh?&_1snc>}6?)6|6\o?~վ.sr8>9!_҇.[!DPOnF"VO)-yh(z[;NbXkGEX+hϙRV-1BC:Z1J:Әc~mk,m#hQXI!}OtCV܎JW,1w4EKL,C?dZotp|xJY#McpCI hY2 ү d'gC-?WXBD"S|F%RZZCc 5ʵ66k&5Rr%xLĤbby,&<:k1]+ 8F7O%;`.m-6.n- C"QOSDRߢF@fby3mln !HǘMaYWDս(InvQA0FS`XOOV0>ei4Wx1ÿͫ4'^d[cx8hW=^eŇT%j.7fBj Ө@aԘ,|zT}>? XF%Pl ÀYyyG"R6S-ʒQʙrkH!{ǐ !%1cF;Pa>bᰍ\?c 7߼ŗz36Dbn\fpS҂i,  nMւLɣu;lkW`fYcMk[롵V9K=QMS6;5 e?CC7MƦFQ% ex~wQ8o3B%#mȗRuWRV͔1B6au2^+" x ֔vRیll$P)) fh$4:EM~|7_gg }~=,꣫fa}2~_ۖ] tW6uu9Uy\%:umydzڟO{Χ"k3B4 mn)ИSJ0FYmp ʧV4"x4_@&gdئ6 MѴ-mk&צMݎיMA3h>E")gh5&1m2^9bX,/|r!Z'`Xa z(*h&)jFiۖicP*,ӄZg`Ejü1[˼t1#]E8*cC$zO!;0utPzI++%<ەmsrچ6#'w(Wz>kcf/)=0*gZ6&[ADD'& ]UT E|jZ.) ڔZv}TdZ9|"VhVKܿR?_ owOkY~Y={OzH=U^WkL\ 6|{cOS{~ʱn,,+B R\v=gς?B~t+s6ݨ^VVmAu>70׬`xY1+*88<"n=\pUb)Wo".EVȎq]MJJY9 ;O(uݾ(4 I=hEO2Ţ'a*׮`bq# q,J%bdp9McI <(OvX*'2Yjv#2-Dh@JcFEJkˤ ?K(/Q}jKTЧѥ"V5*L_{ g/==8&dmPXT˔z4ڢHѢͣsfsqxr,n4"[Ipa3;uM:YCSKTԯsAmof>sp8#jm'-69 !E^ ۿ{'{`y׍y]2%ص0Jq]qimy1&OS}}я?ǵuR,?=vW5|Z1w;lfX|wS9{LUcV$ʲ\3ƻ>OP7Y)iZh>l25%\˩5>fT/b"~r1=1,g[zb 4}ep.Riu;u9s9RK[@es3ŢǚgHtiFC# **mr=jq'R|DJ!{Ǭ Y hLjkJb"F?(͵7[ǬO7~K~h ﱩW^ؠn UkZCz<׫]ZK[mrM.+8;;'׿M[?_;}16wd*!]Q۟)fc-10F38bdr_nc9q 1[πjŝO>i,J%%lstycʻ\/=ULk[..?z~4>}}?}yp}N>@ 6(8Oi4d6=4#7}|yM?EhςL*Ѡ._X1U,h5[L@8@ J$&D? CHڢE5 CrH7җ nҰk}iff̳(H^Z)d?m7'Ptf(|Gp|'!Dcb5n(>[ujѽHk5zL1Z t]sca۹H#z %Ô ŀ0ZcP 0cSc?&>^poҟ IDAT1lךٝfӦvRSUCk){Z\Uh*]OMκ qzqmhLJ,6\*YAڲc:A@D>ezJ`$i8:<3X %!Z#vãGArE,+D M3 I#4mscNOOY,.P:B:BL;וBʞ)4N4ӒYʣ`:Sd|80P.B-Bc,.Zy\J z1&S's,ƘĴ&ż<f/[35sܜ.vWd\LZVZw:׮5ٳEV+`r1n׉&lhTrn~kmmƭhD,Zgv\[M4=؎U\6-Ve%ap(-Xcs2*+{}sz?&>>a%i g&hZ?\(_U'mR<S`\UA6{ ^"FDLLj.vP9a%"8XB*9T V_VB))YʇRQBdJwyMqə٬%Y0,(H([+d8<<!Zk 8XжCbPV}(m'5V3"BYxtF8#hE+R"S"TWRyL}]@Y*f(bG4fhcy/ D퓶mZe;P Kkɤ62ו*ZfB $ExʮѺj':li. (-L; I1b Nƴ1FPX{vb+ M`~V6>pxt@ `Nef(Y^\p1(D".:tf/9;=%( ېbX.z$%f`MN#;59hࠉQ$-(J&JQ&Ml2)0apЦAHHh5CEGL"I%TFD#yΆ9l=l\HkʐH ʕb=֊K-'E+}Q@p64ڠ%uږjwy>(i; 1WK[e6cmZZxTm݀В'TRh2k# c/# 5]=GEO FR?b&w_\|=.`f>}cxN{b"m)eE瘊R 9Ɋɶ0JF[a5#bxD~wʕ&(]EKX'F)Xi;Y 66{&J klUYBEJFO = !X,XU?KfGd64M7C m4Gܻwq`mUkONNH1q.M$ujfYU} . AD8K.. .=p8 .ygefD,3*]]U]*YGQ=zka XvAC`RT~LJ|crp+#GNl"PuHg~]7e8Pʑ[ ln0&*Q\R`q %zmS>/XB;am4fbP)ZpZ+Rp(Uӥoǩ{kxcջlwõ)6[,?svyRp[;00]  1x?Ʒg˻9q199^6^Fy|;=|O__O ~௩l6ZkF|mg/?Ot&2UTosqRƖlN#f# .d.FCZl00L+%OX ~`߳/eF>Sno4VR\k| ^#&DJD4M-q Lܐt]=B68ub A w YkVm'*͇<\O)C8DJ TG"߼9q199*X;= ~R\+鄉+@{Bm4F'qbNrrZku{@79* dQn+\EĨ 82 #}w,f%b*[e>Ē:g*͡ aV){hͭF1bPÁapY+..v͎n.xpMŗǏn6==puyE;I)aLi@(pM\\$b^YN .Gt21Q)gDR, ӹ؎%?K퉾u3f4M0a?=e'ɿvsx`YVܷg=2ǻ}<}iv_Eu1lZqmR(ĤT 8.fAsivJ=qa^h?Vk`!1kZP GrzuիRp4r+ D)53٨-q3.af躎?jKGogq)F.U(^ZTdW^'bwgK00;uzdRBK(hk ZO 9;ߴUӔ9O0K>Ho"~ӟWj89q 4? = ׳^>REOa?O;=nnoxm|}Q\ **ZaYHO9/=Z9^UŚJY+?W[eo k{ <5F;3>4R !:+R\q. a)կ4cnt*̅")F7=9=fp"ooߴ@*빹awsC .6bT8xㄕ] Fc\l;.bG#CY! 93YqswQ(m 1<6{)DVv"<5WV* V)Y~ T<Uv0ۍϭ=.V+d Xm4R+Sƌ1x>D穒:*0Us/ܪK\)Fa躎K ݎq\\U|R ŠҪY4GLjKXv+H.mV^~&~*٧̷鋼}?޷}x;mϻ=Ǿs|_e1yk5{YަxjW9W9ާU_5*!%Oߐfլ6+u,b\\..`j0_TNf!;cUb'蠧>pS{!DjqZYG֛\7*"0R0J{Ofyy&\麞Z*A#8`5a{4*]ױ0S~?w0pZ\C'Dju ULG0gkuIbbUEm'*u('9Z mV TjB;V}bw<~+k˥%I$Oj Ϳs)`#PlUkAFx"]a2 R &Cs\ImcIl}kQy.3="Rjj%mRQU]0N@;jAw~}]?O:]c0w繟/m/<׋û/{gaڧUY}u.!0蚀Vյk-" ](Mm bṈZuKu0YW7 8rssÇbzA['~fa2yj-SP-9g.l=8,Z΅ͶGD4A4 h_eĺc}_ ~t7~y?'{]ws8OۋVFe~6ޅP{_w߯ޏ\ Ar1da؃{N~rdG w* ׋̎ʔ˽ 50raܧ4PuP n-s;/[(^9-PW5Rg'kQ! &i^EC&HaGMa8_>gq,t86=|mοnB]RR& n(JDu]٤U] V`r;2s`0f}3ˡQ@(Sޯ61B*l 2 G#'h٫IZ|i7nO 9wՕDXPTTSkQ0ɯnc|>vLSasϠ^Y\nhN藈">sIU 8M\@ˡslR|tnVv:V>5=^4ɽ{qz^d/Ӌc]gy?g_rx}{x7wgf_u=xE훺cW휂ǿK"|x{_gܾqa?~}sRfRr@!W5kV?f -;xYCӾ} Bݨ3(tiymoΝ*/ZuJ:ϙ:&4h~{#ALPiUhWS_48NyJ Rx6.eRjD0.7}]T_(JNmĆ7y;=&(jmfxh{-fܒk1)N}FmN| kmm(E3<,kWX?c+V2j*(F5u6Cmjz[@Jaϗ_~ŧt FUm<,ɫך䉖mZVpU6ٯBqlw)ٯ }t15%u4@,{>~jٲV`eW cBo,T#ZdT * Rl~̈́Z Z\Wٺ & Aӄ`ޮ l~is ըVJL[_n>! l6=-_~U{U@E4 Ps* V+`z@ ]8%8>S<ƙ_[IE=FjK4Á2:$HBX+8b"%`я~o޻c-9׾>*O\x y~{ļplUߛh1yտ/GĞgau+: 7׏ٰ:{X'(FC j;O*GHz<"n 5"us[Ε+,N$TseRLT\Zk-VUM ю5KU/WW6,$[ں핻.^J50f59{*)0ԄZ%֊ \]myҋR5dmGtl"ڥ *_8{J:KVuDŽlbF֊0남ryqI"ᆃCvab5`Rjpn%(VgU@RP K".OE\rncv!{ox^CQ)W@,$EXwy,1>K>xߟzŗ|WM$+cG䧌2u60r)CfMW}d~nVϞڼnURJD diD5c"6g4NIaQE̚:k2j~kxo)F-BW7b_%by0$xOu%lItAH1C N%H~+^yEP.m^X=3@&KhՄqrZB{vU@juPyLg|iEсʐ+1OH&)tA10no})Ow? ɇ}Q=)Xrfw{f m݂kp[ݓNW>qEO" |g\n`O~F.1p';3& P&NW0o}m<oY}ⱜ{,8LJjcnonI.~O1V'S ZIں~ׯ9}oJ .R6M55W^lEL)ֳ5 @]IŰ5^c.BHPjve\%yZ ؍2Uh%Ӓ7MT'qs*U]mfrnŌRrFCjD.~r&[ $(Qsnu t]Bc@Rds?~wШd+Տ%RzbqN2 BHh ;+SFP_zo[Wo0?}Z?uo]#{yse*;yLq-<`2_ E 3P􅁃aO{{vw*VFɞL# !ܵc-bH^ɔV#:͵V鑾>r9W]\3Fl{F3@(NUyxŠL( M@D..zMšrz+Fq.Fnr(SnU=+g0Eh`L㘩%S,IٖJfV!opwK@\r ܜU5J&U %Evޛ7wӿޥG=FGYP1b1 ]BJ 'ʬi*4 [f '[T0/~oG!_×|c~O1qI53.oib|hc3(VW.}pqwkw ^WMmigmyzbaxt*suUe<&ߏ199>Ƙ|_2 Jv`"MjM]LPݪ v5]{8yr{0 X"B@CBR:-۴^jy]餺}ǛR€=riЂ[r8că>1QƁOVIذ\\lI F.&TZmfQOf]]ZX*L.BЄj O%#d +4m )S #&$h)krv; cLXRe. +^Ϲ>MIQJ^z >7ُ?*8NP/D89qs~0 t]Zoˢ镧ySa<6 x=-8&=QmbV1UBTXu+(~af`7V!4pm_j^QTJi8PK-+]`\&I($tɫW]t!Z/cD>ҪQfŅnhN!f6Wh %–ĘU]19aijTMqsߏjO`٫XlNҮUؓݺ\a.S#z_O{^YU|er(D)Kudƚ)kW=Vj4W T2b%5庽~B ޫ̛(h>.%%u6;!&-M)!"xnmu:n1TB` fҜsz_Tng0Hǝ--QaGfEtW .VR1&?ImYuʝkP!A݇F7*JUYgTS. J. 1gqfGN^ͯ%e~"d#FMyjWJuz%)᏿~38 T/t`0DZ {eBP#瑛cٰPZ"CB7_A/7q89qc$""ネ3upR @+;j g຦g{DXbJ)eUBԲ((_=z [ZR@sJ1;]\lQc '%Fq]H)x/s}iu}B.N^3Ʌ>qNwym%kV[s-cVnWyvOqs.p(*)R4Bq0]t@z]|u2XvTVW/*nN:ْb$~Bzc2aTk'?L%Āff:M<|DXv5H!WM]Gn㗿%)E} ?я}p\lzrug?9˷x89qsXb_7QQӈ T+XO{ƚyEahGq$®ϧ۵j[9MPUvf4&"&^ A &UOSm(V͚2zVl!0zN(^5{6}B(^p2 }OߧZ被Jof^5Twy""!Kr:_ۅoJn 9gj)SJmQM5YU~{VKg T? H@MU|*TSsysXEqzs7sK&U׷P1扨NB*,Dz-7kO~v]V0 'dT ]oJג* ӈ6ywt]0y%~G~_ߐR?'ۛovRm毾89V=n_rTFG(eҤk*ռ(M~_9WsNmx%H}9ԼKM<ڪkJ+uqihQ;_ߒ4եy2hd1.@YTreQd.hA QtOh钑-:s 5`eXDB XQLR+)[;pV-ŢCrJ)WJ5ɭ yʋ'UC[>xeLWƖO25?q&XPj1 (dPam`Mp.cڒw5a-v|,6Q(aKsn2ݛ(t1TWƮT+V>(1Tfl:v*U&Z".F:o@daB-㯿e\9]#Q1[- \ a/AUl<|*j6q_3"Č~O?mٟw.}syLqsMx3OݎL%&,!QSS^j*RE vJU+͋UNEī&]YOԫkq̨DD*Ӵ'rݢrJUiFԀQU0S}jV=1suX0/ttu"H167)"i躀:Boh,ѶIUFtxOtT3J-:*/p*ט%Iq8bT&ѫ^Y Cf&r.̈!uqurB_7=8=;)\D(Q)Vȥ"b˷3554x/s$q<6WFɋ*j8ϬF9ϵҧyԓ:%DN/ e;pu3~a*;[쾫}zs8Ǜ~Ǘ_|1C֊{J9/ >_&̭sNOˣbw?ѪZR퓕d Sq` 2虨ӮiX>S .T"s}W))1EM&#uC%DH\;FVZE;#`6-9TQ-,sA`)nIdԩRK |cLEk 㘗+FL^]G}R_犭,7!UCsAiҭOtb—4[kq=_ooiyɓ8I8QKE)X ydV7Q铢R(IDc@v9u^5`*L5cjLn^- DŽa{im?~>{mŹd?qs89j;ݘB@^(ҕR3Ҽ[gpVvp6O\k%SiL%[ w,Sq[^bq'$J. N-b5s8 ёk+kXJ !R*\_,ʿXn!k?A4nDMlHERb*.Tp>d E BRIj[Qȁ_\ct d+wwO,<&N A͟96ו*pHUEQ_iejfAeBKOj.o3D=@2ӔGV 8 8urk t8ؽE;nBUt\tJ! @uJ7覔WUg,XZ_Ҏ/z[n7pF #qW 1u]^^]F`Z0u`?뉎nPC;Cp{r,ks63%.W蓲B.ܷfb<y􈯿1$̤ya%,f)%BSV|vE; '?7Xzv{ T_8Sr<&199n;~W/4$㕪tVŔF-K,hR͊ӮCLU }y:8ʪ} -"IJ(SܱC՘ 2aT<0aF<54r^EU]sa]WsJޯkN.!DHl&))) B{sL'&ʹr](ETj )2t0iʸrp_еlZEY`UƤj+LX m8Tt1p=e kuUfÕkfe(րrh'|yUkk8L;I9Jw"6W`SWUX0V~b5g6Ո{v7 !$B^r\Exg(\Q=eLv?KJ3 _Uh=BtMrvz֛` yu8ǻK,6ƽ ϙcoz=wqosC)ak[su݊L\[(w*XS5 5*f50fD: B.BH(*sU5%he˹(8֕D?PUHI4:7MɪSޥUNEڜW -RPKG8ơpqs=p{{`\+#R+1hq@΅j3ڈͅy|W=)U,}޵%< Q>΃TCK*u:*UBu{FRWmgUQgnkSB6OEj76]7bJi)l{d@n DBF-\hP5%j@0qEQ@~>0,lZW:+%7_w/>̫gSY7ܧpy||yv Ҿq{9&߳"Y>oLq).._U6 U@[6$>ϋurMvz-`2RJ,=̳" T xr%gv-xgNQŁ,e]9=YXQ=ޛ쫕ŖH$R4%%$A,YߕfzZ5W?Y{e)^}cdnU.OUA5c5W79K!bR_e?9yb 01MSf'DvlZj4AjYk IDATDvWwݎWPAy %PL7o*Xw`Yɺ٠we_ mU1W]~7$'{gPj:gD>d,Cz@Ʌ'AZ\1^{j@%1.۵ڼ]^U8ܻ:8OBU3~?EݫۋU47^g;;ca9D.a`*Z+ A n# ?w+oXcr,99ul0f:lUT c yrЃ1ZJ1w2TW1.¸},BQjL%vA!{|CLPpÀH`w;sz,*p]c9M"Dץp%4Qp7D^,TQf+3kw l$WZ۔QHR1)XS6MGTEs*<4uF/R)eY鹸VE(Eu:bޮU&&*qBUS+׼qJ>*m*݀ R R(n5ScX}gzUD#V7I 5>n¥(Sq?fbdraJXNwؖ'pqGY]G z·hj2g uls[=1Yq/ ~Pea$2ԩJ-y ! !r\{l fp)*)%Te} BXU&-Z]:ccws2)oryR`Eq,ާ6<&ϒs]Fْ6[ϹzuT\ QdE1Bhv0P*&ѪƍBmlFTT+tJ#TBWȥU3Ņr=׵Rrm*Š41!+-S*V[VqBNlڵclR0cO$`!P_1ubo-(J챕aZP.n3~;0Nxa\;DBt]"u MlUwnj2MM {yj$; clbdu%K"ޟ|նOLĨٳ[<9},Yxy^;=ف^/0`&tHVRF+^ٯ[[]ЭWѲ>G \V]-]!pWεBqk?ϐ̐R*Zbu^U3!.XnŤ͕ꉟBm(M`mGQ <ۿb _m,j_3킌7u_/灡i|םscqn9 {y(o{գibBh40Y.RMGQ aܓõ4#Áqqw )7|K ~%t \BNiQ شJԬAC g`ۑzU_#; DiV}cKzq3: 4pUa Q4Ee*AKT]p7\ Ōiʌ?{o$I]g~ 6{9j)p( qsӋ^PBD5U)32'txC/Susψ)2+Cg{fs"miUe=^H]{+uN]([{-5!qIjwJ(F4i;)׿ "+5rQUEqQE`{3`lyལI]Š6VU)lD3,ObמqXcriR@fN\|t}>/PtsZS"[5vY! 8gB fxO&SlbBp|܏| }\g«{SRZ9@XB GgI |նyU{cSM9Y7}~Oc2TJ)c>[<_ Dr' PTʋR UU\nh ΪSN'7}n f9b rɑ:dٷ=W7 -f MKJSD&WE.R}LY!\D6e m"L/&g$㙣 &Jq2/ܯk$y(7:.y݈QIu7Tz֌) 4h~N ̩1σ2Ms뜾d c%UĖEc>8䧦!Ĉ~c w}}Mz_g5>Of?"M:{e4&_1j_9W۟kfg58#X1$u$f%FakH}+jrf%}L~1W3hH퐜89YϞ8=y'\_ph֫5W+UEuI"'h~t1X o2S*}̷9[p6nsEp;gڷ> ==} 4Ӈ<cD~"S %!gC~߳5=m:])&KQ1VSk{S H64zhL7tQO.kh%UYztW0 Yvi%K:%ӳ0';L5TSM5TS}Ec`m9$ or1LʨWr1HkoI$|Aw5Q6$=vcg*G$m͖pq=bK5__\tu 4}Ǯb1gks$ܠ'YBU)<bl2cfNeMQ!kmN!s,Nݹ@ ПH67X=U)G=qD   rY 9fsl氵{Tcm;5;2 1G0c{rP`+D?FbEU;u-Ug1Ե)+IylJz]#_e)e5˃Syw΍DbayS}?PI-uyxra .z @>.IukX{ p =K)235iL64j;n !eY:{w֖.O,SjUƕD1o7`j/iL64&SM5?_@6S !$r@ ֫uE]$H6$ 68'Ca CC3m 4mK7aV;U .6)|H&ȡmiWWWTUX%SYkyOW47 /8@emg4JԔ`YaQ;j`r&CBfK"f;ᄧO+Ġff&cSՒH3)J1k3ꖬm&j.ϗRA#[KyBŚh}84&XlEw~LXo/jˊŲ`0P!hb$cR$qCS"@4VQ^TTS+DMӇȭ5kP>8S@R1h=s1*YApF}e!Udi뱆點0CscY칍Ӆt 6;L]uud7 =??jӸM5TSMT׶zk 5!ck,BH V/LvC\9[80ɓxg9bdsCf״t1҄F{41=8c)E^?G9{ti-u]ZX,\\\RiC ~?e˝t TMʃѕsq c6b$/83 )4nYWGe#Id$kqe|YQ/<.{g\ԡK`y} D| Mw89%F>!XEQZ$ MX!;f81)҇@N [p~c,juƪɗ)ױ)#t\9XY,䜹TSM5TSM5T_M 9D8YkObfyW\n5lv;/.hڎ,^xLE#Eyɒ{^<ݦiJw |J,W}p!;BxsjJv%= Ӈ#;>Cot]A 6Č2Ș*4/se L5 [Fë. Bden-+YTBpaS-K4Ss}?G3B I8V SP09&R M m'$fվQ*g=tM$k=15mglwܴh b-)']0BUyUeE ԑ9'U2QQ2/'5ˣW'LRyy6ƔE 59`ĂQvf%suיL.Kw\38Ge0Q3JeâRz~cpGZN~dP[AnB+#Q8|2 w2gSR'|n/Cx9] Pù#$=4k k-͆/..od[bM5TSM5TSʴ]\\]aQ&vjB: 9`͂Yaw;f#D@2x;*Y#l0wwwkvHa_Š'D1lgk]aw9]}Ï7yNbJdLbl[ߡ*wb]̛af=ʲef\ºL- K3!D hRMݦOjF25g^D,d$% kj1^g|36&(,y] vrs}rv{`rZ5ϹX=::~UYU(cBSl1dwzsMi0\G֍>dkQ$bEX#)+XBDߓ՞zrN4͎Bұtak_x́ eH"l]Q;z9yNak$2B=1Z^01ЊYho}*~J}eڣ%{Z)jUfmI &1Ĥ}{|ݎZKr% z5ң=D7Ũ:GDS?KV!]ʹδb?$f!QAmWr"4ŊE8*B*jW.9C Hr#z0{ t=ݞIWvU{:TTSOs?lmXgW!AH9t\^]ЇHzv&٢t(Tȼ8a\a [Dc,)ELq 1Yo?-;Q6\/?V}%u8 z>r\b缹D1c6'YcUnME$HR3&glĆ %8Dzb[R<`kOAadFGeb2@:ld!a㱩pU˜& VAc2&\EITzbZ%qo&tk,-ː]DFovxB@߃0MBI͜p6s<~8g>,_A-)*q =ɁcK:]0Ыkd5:+y[PLb j4M푼B "9io}e0>+ܟ'щKcn9WL2!㔒={3}Y= ]\$.:lMaչ'ΑL$͊:h]}O=4yH$yZ{G4;RPfӎE4,F&?nk0j?o/oqM5TSM5TS};???1QgޕHu/ϯhڞ sc1 y)RUrfsؚiáqsdPt6\q<x_S~~ʳg焐[x_ NOOyK./02Hzn1͔-J`uQiw̏rH,mTpDl6$5䤆H1FvԕChRJ +=gZ`UqaLˤDݹ 28AAx_a't*{ۖ Ծ3Zxf"?1uM^/f,0 g' 0Â&Tl0 rɭV6RRPb.تRHҿ\0( *Rc1'5e0H% 5)\qV^&5squÂPEr6l9qhObQ{c蹐ĞWnFť<|c~> Jң~6UGo$ ~tejjzCmy޻Tu%9NW' d~Ϯi*%J_)%Bv*TFʭsiCRx/8_#>)=b,Y,*yk.ރD,GGx`^s~?~jul6S6\\{"n&9s"gDB̙> &E(q;y$躌st`Ȉ3V]O 22: %NIlDsrjfLcqŪƊx)lXf#́dȦ-{^^8Y8=q.k|8q'[ɣ;Œg)fsb!{[}A(笌fk=)gB|kh.6av[AI\$1掛1h6b5* )dfƨy[N5^F}%TP9Qc1@a%DJRH W]ח}O<_k?ᄃ`+ӘLc2TSݖu>ft1ꊮcW.)fUД<"Vf.QUS!c;S5;rrrggԳ]cHi?~5dg;'5OOy ]4?d9 h,Jcɿ8z*ئA:L r$LI{deȈ(LV3u^̗Vk8cI${#ip0C,+*u`$mk@b<.= ł~ڀݩjjNNy7|9aQ7f^B9\UrUSKMwI8Ȼ1,9w;v "srrB]Ux麎tm334Tޓsf)+ϱUI(>#0FWce)+؉1 !b &bdyϢ*G堲жT4CvkK8(F8&kO5 甡Mb%D=+_ %,>9>Wsb1}JV<'<|pÇ'*sKĚwFͣ+#&&N1 u= }b AGּI(5(cJH 1R2x!0΅/ټ5XFS<_ nC;WQfLL:1Qwy:#.grS@Zx#+o!%) PUq;vndso )0no҂~ʹH}5;+0>5}yY=7kLTaZ[Sjg{B^3gg*#95qz`⣏~KkF'i|>>`:6~f`p|[C~ ="=bl82H88ԕI&u-Mۓ,R\fHRn 뺮fЫvU{ k[l >9ԕǢH!Lm L@͙|Uf/5ժ{6Db/'٨`8`b%b0Ƃ\LKXݤǞf̥׊)Ȑ='2V}3<|c}{]M!d(磜$!c;52ڦ8n3*/D Q ԙ6XɫYEU9pƏß~^ ?jkTBX.C?6S$}$O{U`ϺO;gӘTSMu8C`*pqy DG,ClhNizdv-)SzML-~}j?\]]=2NSZrS_\+.ݰ\|̣Gps#E*#GY:G9k{ߑ1D8{1?9%$&*먝 ԙFʎia1ӥ@e#8Q`"J..*O(%YAT;\eBvaV9{<vKufGf6f[6alƚXxb kM9%)*1U~b%.$_A)8Σf9r "W߇CmᨿZbGq84G{o8R?G<`E̸XSDpVs{1#9Sd1SW1QTaaӭvg5^wc$cPle|\~*@5T_+e׼Ϋ//r4@7&SMM)c m:`Z-'+sloy'}^s6I#k$"H6#斺>kffa61ׄ =y~@,N4^sVx)u FSLɜw}Ֆmy%SB\m6\^4 9R:bcJ=uݞ[euE,ڃ@kۦGDbԳŲf>e3Z\UPZg;o[6-;eὺ w]TZu?6kig]WCs`\l0xp:d guF~Ovݞgpyx)>}5Ŝx%Fc04ٌnUZjj0Gl%LHmUyǼr@S{1Ƒ!ƀjgFs Jk\ c%9X#8gc)RPfr*ϔ9 %S׈Q6qg;;|5FIr Ua+qSY6ԓ)N؞'bb9a Bgv͑a[o{,c>f8Tp m!HX1) AX2cw}uknUiB뢌+ (Rb$bg< `Y-yHR5M(rF:@ʉ,&yo<]|)Sbi߂O_Wt;T_f>^%&4&2T߄ '9=Α7W7g'bl6.arg ]!;blH9%EC"me^s8l[vMSh"Sxß񋛡ʦV, M~f*}˜^,ړX9RkNor 126H yw ;u;cmLY Lƚbwd906hWfޠy&i1+*"V<4ɉ-c  b*0S'feԱC&׉4 #5Lv' 6ģk1>'! )rEHN!Ko>)8ɡW|ŘqGȕ.HDQbKY$Ԑ-18.t*D=maa6b})EXQ]+YWWtuv/yj>,|~|c"}m~Mczk+>c>G<}nVݳI&srrJ3ڸesc~t!X6=CGFX<}^puuI{VO>4M\__DUU{kʲ@N;,a䌧O;lGx1Z7|{{SR&T2*_Ku(Sq~f4O:;e1]jh=Og,sZf}^"nM1SqXkɒ9? |usꟛj/y_u_X1dnemŋ<{o#%G!zORs.8N-Ւ?fo;6-YEӴʠa>MӳCʰ}({ZcNe: d WQ#ay1vི1FkgMc61Dc(}7J,Sʆ1J1j؉!~+j2f\>(Y^ CXUbƨsL&u.1K 4og!R2SוsLɢcdI#b>(hX.}i+ ,|+b94A#&\_x8r&3V6ƀHN^-p]>ة00.2X".m !1 c2)f79 lv;fL;׫3ffVV]M3!'mx Oy=}b~򓿝TSM5TSM5נB'?ec'S*͞BhO%w51ͨyq G<|,}ߍ9){BCdm}a憇5=k{v=}'ONhږCR`h>>JG2E]y! eھל٪0Ήa-:Ō)Jp^A\fNYYɌ Rc~9r_},eLFR,b6e66t! l ӝcQ ra%UΙ#!Fuι"/rNhBϟ`_.cvC{* HCc&?!u~!)>w-6j،恂~}||kES 8+DQ㳔Ԅ،,c`whX+uEeT<ж=1Ff^[,+S!B2_-9_=SM57>]64&SM5׽x~35?du3M"˗t]nj~;,WsnhD*gV2T_|Y@y |lF׵g3eِR9ǃԳm۳߶\_o xf k Dg8gxl;>w *P6̷mTy4`zX }Rbi+I8&^ }\,*6֨g&cb.Wj!w"c-)3v(11^0qx/##|#c%>/ENҭ;&eae3UbRԌkz.((Z{ 5 ˷ǀq]J#_|;enO8Z@) 3W(c2N*Lt\T wk\_JȜC*b{9k?1ǹnE Rq'3"FtN㜅>d.|?(-BqbmUzMQ՘5;d'x$SM574&SM5՟~C'K¡;pqq]h7{nXyu]hY.\^\%]`0۶ဈX,XVtm )EHþR]v=NO+lg 6"XV!ZPׁ躎1&nnn^rp=xJ/I#WQӭ(0QS#Y Ɓ 9#ujUP b32xӃ WʙtmG#KR1t2EJN"m}^qkF)#L!dbHBL>C$dq9cV[Clv_C/qʇfcDjiؓ\Z T%mqIU< 9ckȨA|z|?usg,UxoeW1kb9'+67S59ggk=~v~G?? ;ܿLs92P*;#@5 Bl-g9R{*o5GZ lJXXݧkB":RXcqN.L,1I"fQTzMxH)Ӷ=&Imj-0c^\T1boSqQɔn ݔaqlG7RܢŨa3Svkoc >+z9^h9{#rFVTB0}؆@e") !⢭qZ}:eJ<ľqu]Z])K ۢHIU:c$NJlk\LWjj7Tb y^qvzfám;NN͖"D:}snti;cnN0n8U]/ +b]9R*/hD]i M۱Xqqu&ϒduÛr&ِ%K-Ԣ7/F725m4u/MJE@ZALU)7wz]efeeրbsP5 mW3.z.c7<'ek%gCu0Y[kWO0Ζ8Rt7d 0NYEXeY"sSB)BF+ RJ 18c2b蜳\) CoT4('>c{Gn]₈)f\3ХO:uX]p.|lF(] 3oñS,qeEQ;?.<]8jXg>X 1DlUa+OM&n\`RW{_q?.c =)V:c4K ߽?yn{_k_כE̙|>o1?8&SBk/#O<3..9== 'qyyP5MSL4Ouii ;"f3ϙ͎h7O +w_:?O|ĭ;I8;&jVRq2g8<>cf 8./Db5gKRw5wiy988WX_l:u$$*Gw0Vxu+nݾɉZ\bD5M=#FXZ5ͦk\9ͤA6 9 7ls8i;gU1ʖ dZeUb2Rɶ[L6ʕ`u`bxkԭ8%RIA|j?;Zq l`LMqED0EVkAp9gBz!*/7biٟ#)FMdHQf9f!e:XrrNdjɄc ڄeewbPYC(!IP1](ڣk w]?YZj_mVxk1k/8w|y#8eK]qDFok_a958gKqvFDk-1D"F< ]ܑqe8ڃgSa!>}:2[$ͅȖL^Y=z\aT# pb|9 eڰ̦DvT+m:57 \ r5J %iHAV:\ʜp|cgI08;@Xq`,XE1EYJɀ$kT*S~vgPV0ƠR"ARzc8Wܠd}/s'x ëfJw硧x"b]@n eʱ_^a_ dwù׏@$Ne1`k~ɀ,x|zIJ{&CЅ+!a?A:c 锦!8͗0_O ۻ7O>7+ >}}Scel{|$ޏoLB]^\SߝsO'$[{{.b+B.X08::7~;G b`Z4Q+5*:HSA.344[ ))HVuނPSru.$d,Ie5[*"_X=yk:@HٲƖkrSX~SFVm`6D?W09ocLȉrMu[Sc)D$G7׶V m]9 +o}oMl)ȧh/{u_7ղk_$h0ƎcTN o19 ɴ+-uKWn)ŝLjdB||>L&>,k3@J /dfݲ\1ᝧZ"'''c8;;m[1ҶǏ3N뚪L&L&ڶ{b:RL֨tNŷ8yJH rD !pX҅{L2k;2uBepUDz9ul6CP4].CP"hvTӚc앥HhؒQ$Hǯ^Wb6JauSĐ~q  @[J>\s[ S&i /^|hyuuާ|YF rawESf|{1b q릝RY[T"7CrFv8_qr8r5wx1QW5V =9}$;`7wǾ|wok_׾}1}=igO躖{GJʈzo !cW0l֑9G6jX.:޽Ϸ4M͇~HwĘX.׼;p޽|bm[w*qa+D>努 !Ѷ9;w>ɓ'E+czfX4 u]3L8< y!'ȭC*g1j_c[.RRrW[HY+Ⓗ;߿vٝ}_.uwinRK??g$P9OTfwγZY,Vje})=!~Ǩo;fnۖ3F &MM еj.%BUW8cUW*M8X!1&Lj.6^A{xmԔ(_$P&Rc-IJ4T֐ʓ0F}բW5uSM¡l 6+Y 9+=~ <aF +vړ-sUڛ2YJԑٲꎭpJq?9+霻VU2I1gb6$A3}&YPQ7os5z P_c LJt]r$0u#3:;q[9m3%Y\>ׯ7]s1c-9χ<,9SU5b 9J%"X1,,t}rp:b" L ,U̦Z_qӄ8r^IR3/ =GN2'ݷ5f77!ͫΉW\}9/ޘk__,LJ'_Z-8::dE/ϴeZ&7MCJBI D=zHns6GKg8>>f2i8>>xSec8_#!DW(,.״p8ks6|Ju<~Jhl,u]sp8gZ^GB`\""t]GN @ GGܹuާ۬0RUu<"gTv, O/V<:]2`LLd,%G9s +b=80U8g X㩼SI-BH@gnhɬ&>ڲRBKN%w9kr#Dy]aG7Ɛ␹,#cn̮ miCOl|yh_r^3p95879Zl6+8s|NΙ~Ӓ;tCpLĆ^߻:wU`~ ؏--},ˑl{E;_U}Gׯلr&3&0}ϴi4\t1W0ۿ=ӟOf^/)l6圩IP̚d2a>Ѷ>}b`20^,-Y& nb>c%]6Z: 94 GcͨW[-Pye,SJŷڐpl~4WЋFG9eK/[kNͭ?@HƞHrqcPZ:c. &2E.-YKtHYݖ=Ɉ$(㒐\Ή$HQ{0Իyd!9AnmwRAǗΕ10\ׯ 5į\g͐ n:։_eݗ'ϻ~;?E–!DTZeU'ٲŐUb\$6X88ͪB_чsfb\X^wA]yVeNa]S9!ܻw۷oTFP+R)FFy7Ŧِ>Yxgfb]932CoWLk)8)R1@.|GUFy uGXt.t3Ty)e`B$s"bTz׬>HC4tkj||^7C3_yNhW=x|ob?>(:UwY8\[ ;CM9zs懇L%9d2o>6[eA~ٍ󛈮y7&m_͘}Z`2>}ُ{b_<>ԕg:SUm̎@ s UUc3WSRyuJ_7z04ŝ; =1и+u5Xbl$,Jfq萷~l18V˥cTsO4d:V]RW&F#LMj/Vc#;>`Wk4G|1GS'ֈrmpT b?TY<<j5/kUC/IɅ,[S`I32щ{jS3^8ZB.iJ.*c}dkV]Ȓ`֑҃ɣd[xz֥{yD+\Cǯo9Rv]~\d!i,87 z+jtԮK.!7]`5۲%fkX.+c1'1Г4oL%X]FVg5 _ܹsAM׮}gٌo|~Ub>yq^gٍ'yeY"}|5&W{]~{`!!9ڴ7-1*?SXrv.hn̰FjWJfz?4%\ܖ+rN=ggܹ{ќ޾C|#bX+Q#XV)sFTsx|} S, IDAT"<}z#fS5jQu׵m%}ph YoEg-b !c9 8 7(%`'eش#pь9vX̦5لz_0ԛYYL^}ӍHח\w7oc}}ydNulXK=􁳋5#,\MJBsʬ:<~M Tt2prr `{*oIlÏR7ost<'l%g$cpb6k49W'kʹ֭;,>=br1ٌ`d&%U#RVwic teBSV `m 1wrn`1T"Q+#3$+XQੱV1*aSB$*G*Slb$zɑb& 9AҘvT^qSጐH{LtXnbK9]a^}OU1ny b,:$+/۷‰|_<_gqp-ܹ%%1z20LrIg3n:f2ZX.qqqY$mh: }ߍ_׷mHnC7cm]yBaEULC,jf[qv=sУ^flى9%S!d~C '51F>*8H`κȠHO&ԓcU =(2IC"MaegSʣCxZmwݙwͿls#`-9 vp1:Q,$I|Kv~zat(&}=uι񏕌HSܮe(i95:+L>ǩJD烻v΄RRά7GUUTMMX;_յ-7#692޻`^҇DeI4,ٯ` v}k_׾urr­[X\>&K{C7=! N`,U5jqL}py [o=p^LeNcb*HWqyٜl!c>iX,VK6 ]ӷԮ݆:9\.Y*>qXXSLR &U32f-ē'89M b4ع)&PdUv$:L1Q0@fQDk>mגF`\Uɔ9 M1vd}\(xRu I/ uLRyy.j  )3N,'sa?"i<OWs$.>Y|}֨ .`Hxib,z_UTUMWܪ0ys0g[!Kmbx}{|tak6_A}Q'l_1׾Ů'Oi72_~pΏg`Z(m7wb޽><,f]YwVk agax _ZE3#멼X7M}c1VASul6k5]="D"td4[ZV7+LuN.x9?Ł>*S +KJA - ҵISs~?ost0!JFYogU,Iu1Wڶ=9 ) )}+t+aȬW=冮 "KV;o>ᄱP־4Xjo-cd!݀og[()1v |UY]e3в>dpB"e^;l <&{vpl5Iq> O*1Xa͐ᾮ'(k.gǘ)u}cK^9$'BcߵɂGHVɦ݌  e@Qh B]5xQ ୡ*6ʼJ?9^/q5'nԞGPS55l}k_׾9U##4CJvRW¾G0<@=u7'}bC&~M3c") Zm⸼\p~~lvD]7#}m[TlޮocY8==#Xr{ԁ嬪 5Njfu ۶%Lg,FkZ~Cǩ_I2BF=WwͧܽS08}MN5lgXryڲ\ٴ-!D9G3بOo-4FmeWGnc5ƑhVp zPc#(t\.^#(g⏮A_.{ eYwIʸ 3³LM0qL&r}#L& qajx6 UrTce:1?8'?!$霮 =)ev5z}W@s?6+u~r~ru8&_vzMwbYoaZжkUσz˷,:bLD8 L& }HsbuHNLd~XU{va<}~L}M֏SRJ+HWf荬5Avf~UUl崍ٹ8[9<}z"1$]weAl6xE,785캖w^oجOv+g!K3R]~5gq|t'pXq~$EQ=Q5ܒoU[;f.( R`+.k۷̾y 1;c3k/jSʜ/KMb"prrd6a2Or٬YeJYihg3_0iT}ȟ_pr|lţGO%o|HϿw[#{vhN>eڰaG6a ?W}k?Wcƾ+eJC1֩d83FH\073Ts`|wףRΘL*NN8mj&T1#s(>rV9wui x2)EZݡכfF&.O\p\Cq[f B3 bʚuTl .Nϗ|)pƀqt1Ey˭8 "1;O,flg-6Xո#1Ns 6 H#D{E0Y4VJbsA#Ɣ(f<͠^f-%;;2ʯېcRwl1}<,\dom>~ 1ZK65]7nL{w9q]f)?X,.5}ֽ[4G<==ⲧm3Of^.E==c>뮝.#]rsn{v,>fDM3Q7p p;o}~o~;TLX20t5"B3a`mwq zuTα^WE X;&) L?yIl׾}k_oodSWSD*Z8jOrc>mń jdȒXC3X6+=)%>qiA/=Sy7CIQ r֞,8d4T@O=2#7<,-v Ό1'2.a \Yh߼ (Fσ>Mƅ3@e}Ox)W\C* YݣBbHFY(uαZ]P9HZ{w!I9ï__/5.%-eK8)h>0mRz!HӲarB1n.J9f-XBp|2_~|D|Ӏig=_|s9/g=O?n{?&_1׾ H۶XY.:Jd2s!f%wdF)\rt||>TUeUkr53qʑR(7랜 T$;hai{kc&=bXcRi֑%86"UFbhWuN ISz13>x|m0RYY1t;$ee!-JϿ,u{Cj[r6N34\E@d-cM./! q`w޲ƁPsɦvwz pwM#oˢ ?'Ű}fQrHE)Wu)N fۏ>l\M-%jk-ׁlPkK~Sp _&f2Grll|~fb0׬6P@.,!{kl DUx_2~&`gcĺ̴jo}_o}77>?|c`)i{_図_Z6c}k_^8ALrYU}ppd2m+M5Z┯}k{G۶ܻw#?: b\\\qEf48먪ɘe_jGT>th{)lM!6<ۓ s12L tmg?X1H-٪LdŸn u&[7cq#GK[)FsĤ)CB"Cac`y״g.P@:mEFAl +l8[bi ';om ~\݉b+U|lnc 1jNsa58jZ\Җm3һ0\15^27]Rdopqq+7wHk_׾}}uvvw?)7!r$F ~R-- ꍷ%ɄG|>[6'XS4Bfa@fфZGCfsF$֪|Y k.g^oXxY.V%32u]B N.vcp>0HMKxo;=s{sT.F -YbF=Z;/x3!L \Xe.mtV!K&Jd!9)j7` 70Nq)y'X|;뿓YQ`yT ]l@Blc%[f^~6z{rvm I&)\;mL`z!`P嵵ry;X_3e+z-劲`d)u~wWTgw?/$M/2y9+p7WُyecIM/ksEqyӘ/ڏoL/SV o䤠mp7YX.Ę!u\g{aY% IDAT}`n1QUє1n-`U*u{9gJO$@0Ͱֲl8==o El-m3}YFc-2Eقx?هBȱΔ0|5c5OY%ꌹneH$d RR.FvYRi +XMYm"C1۽삫+rc` i11 blBb]$*7e(jyϽ˱ɋIk%.\dL9CmϤig]cg]j_΍f_{\I3%-D%_0#A,!$ȯdl @ RŖQ{$ےfF\nl6CucgC6fOg_VZk{EhږZ ,+bĹ{Zz u1$E%Bg 1{AG|) nu܂ϼOO_){0??QY^~XfA^sMuݾ8cn>lllh4bscHRU:y栰|&Zo`iie.UF1-1:\RPmۗgw* O&Ӕ0Ӫcu=ndݿ?Z.\t(ICITO 6Cs.*݉-rQY@J$Szb*vcŧhw(c>2B\){$dAh5(S$cĐľxOtܒ w1װ'BĈCLp7.: qTJ%u! :GZiDԮGEyV4K8|9z佀\* k?4>ByTi(3ÂkDXCYX|RV#Z|DYN &, BBqg!EDŜyAQw /YۿFlo[ܻN@&k׮۩iQVzVq~ヴvgn̘^Mϭ7VdzO㓳 Ɵq%&lƘdYӁeokl>q -#2蛆`wj^`cc5hlgOc9>&Eٮݶ-u]o>ָr 6`z;keUI( XS 1ϖJPY=d).ФtuLْ0p&qG`uuR "alE m&+)lmmLQIع1P\Z۔e.$сDxpiqmL0ʨ(u8cR՞*sQ/HDte+ Bd<h$t,ۏyBbh]wZI=1giزSܾ(ژyz@"]LWg.DJgzyR.`WZϵkQh134=o@l9'̚)A9|اx㍗)rLv˓"繿w0IGu|_N%Z6=6S=Uy2'񭺮sJB[$%c,u]SpS\ Q+++ ùw Eҝ gQhhkk,Y[[KJ]9Ѫwsdulڠ!Ĉs,'>gBbpVVYL^DR+{ ,S kzuv4[3TH шhp 2NlM|om@[5Ac$dsmiLaXEsav^>,w6aޝmSG1⛆Z7&mѴ5癸 XJΣ]lk F6~? 2ZEm^5%[uYxKiS$x%C+/.,SMJ*: ^0e1_H .JF㊇{;(-r^̷%n{Qv|㠈|7D[>?㣌;ĬQQ T ܧm[Ejn@$t=,M>\C]7`LTc4uke;:py^)~[k !0/1$u(DbLHТwke>;yf]BdTX[[¥8w /ghښͼO>N=K[an;䴟~4 F背;?H[|O^ [~)YSf@4e #BRsq4׀{o*1l,+"ѠgSFcLsmyL vF]u3; &;ls wi$) gPq]g+Jae40,(\ mvQB<_|ky!}M Y2fD)JI5,i)nt[ثo 7Y&uwtZҽxsv*M\ɚ,Ɛj35e.ìl+bw@klԵq{Foy?eQFC^cJKƻq3N>>ߋ덏[ޝwbL}I}|q~~*oy ?޻)EQP08*ԖՅ ܄רiUU=2k)˒lc.:Rn6>gMaB*M"(lbY]*Uf B+JX25}m;qIe,EiYݷ%a 4im}.&TUb4(i6׶QPT2 K4> c]Ye I;HD?oB"AE5Wu"8ǬundLr%o Jno%dt\󓚩h Ω3djs'GQ>飏>>^1t{9}<|Wfc`lSbhηobc S%o0-C`ր6]6p&QG!SA0:e;#eXĒl 9JN&SbuLڈ3UmR B XhZ8{2>hD/1mBdx́LQbt qBm[m<A|$8fӹ.*1C4(Z\J.N\,iY zN Lӈ0i3iu\PۛM:tΝQz^nϽw~[u=NiͲ&ުhۖl:蓭TL۱$ж-ZZyuf;B[xg0VG{G}|<>飏>>1ox͚HBytQ;k;mxfh"OӦv!c D-:ڸp'Y^JaTV6)zKL||_~bA&:ln֦aA˵g=I [ ^t(Os̜qLB'S}! pDkS3yfLvnw]Zx<{t:AI6K341vTH+FBK4y}}pQg룏>裏>Cqi^{u [dKt?UDݓ޲9IKlo1&Gι9plnhw]%!<\|g΃RI\p:(ٌ(2F91RN\@iE4mtHFhQCD'1lQк MIJJ%0QM֩>dU޵!t. Dʥ /}mVp#n )L 4"mB\hn[|L(SF{Y:ĤnȋٳRK]M$ cJd3%m{&:: SZ{u%vϠDiT:__'%EԼ>u7AF{Z~".Q഍*kWn[EEnJB E1?EkTƓ–(g||'Npyߊ㽣ngC¢e`~߹~#|~}G}q'%6B]hT|¼xq݁N8[kТh,qdkiEb~&\vގp8oC26Xkm(z/Sa9 9+(~+bZ:-uV';sI)k$U;ȡ3pJ&.$&ٮ+X ^$//4gLT,JaN}ҩ8.ghInjr1TCբu3;նL"0]+c[1H A5S[]s]..D-^u]v~ɝ"> GLB@"KYZf<.yo1_ɾXB,щP;sec]T_\궷x=.&bJ#t=k(\pErF%qŧ?)^QU…l;_|룏>裏>"x{'!RFen:@`0`cck<[圶b8295<(9z~;:шK'8S`#JK[(wJ%v`Hw:E1k&HvWMp(k (JVrt4G%gkUY[ &uon J#MMKQh<)ʛoqhfLqX.YVh m4.$? xBW` 1 e"1@5Dz8"A)bR!4!F606f3tJ'ڽٱRҒ2 X4J煄."TfS,x}dEv5 jsY{=jgZiYh^nqڽbw["]9@Z >Q:[[`)ͩ~pQݟ ܼh{=VV(+x3>裏>EQ(_]w.MI'&ۓ`aqE4=z0.ac ?5z=W\LS·-ypヒ6q< :|cl@Ec4 o.\.wՋٵ<>|8aBlYXkDkɓ'yw1̧1LhC"&8+Ν9W_T(yY][M"b IVӺfcW~J;Fm-8&ܿ4W&8vsKqIVQ Q*eR IDAT9`NJQM>(,\D-b'[^yӖYCdVvX3F:}dDhRVّ ~3].p'cGBg\まx]b,]ft-x$H~ ւ`Cʒ//`,L3J[0Ux)_xEV\t.qO>`ʝ?z}|T﷿=1hO>飏{#4ϱcڷ9Bک@85+Ӽv`?+~i("Y29F [mJ>!EӚ׎~トQhL9qY|(ccp@R>?} ?Ο{PJwg^wBL1n+g=ycE,ǂ$_1b^@,tQo+/bjAlb"u{1"do)/n;Đ y$e@+Qzh4:}QZS%E+Vc.?O< Ʉ[c{0?3;;u 5 }q/ng>ಪ?6mnP*$& qoR |(΀ `D uP:g4$cG,/1nN9o?W7e,+804q7)m Y< (tAM81~1BȾWڊs.p9)Gʏvbgf*:@QXB([pQ uUoQ;lV#("leD4BU%kZjD6јv2C$D8bFy蒦r┳9tPQVBAQ02n BNALfa-AMR#Z2T!,bRV QyOZ6'3f.+2hh)L`SsQm: Fǔm:+nZo!D:-(TE:bّQ1oG'0,j;;7ځVy^Dv޷vv̍D/fwgmZ#Q2POWXbI~ #hIz \<Dr2=ڐ#f%\"G>ɓxG>裏>裏>> ,/rywGY Ci\J5SlYR )3#-*V+eɬ)m\l6I moh, ڤi4UU0kB 0VaF"\^~KH`Xi24WrǞzF("Y,$2"uԎdFYllN.ұ+S{; M2=-p!n4\ JzFi QrIN ,קv +G*`dFc/Y1'΂ʹ]`O:kFlq lj#EO>3&)h[b˔]bhLΨ'FYX MӱIF)>27V7]C- %nok{%qR(2q.e[Q!^-5TUks@&M0:_3-sukM+2{ >GwGVrܽ{F_obwv/kz6nv}|>>IѶ-?;=s1⅔Ԅse&->zƵF1F4pH=1\@)kF,,s666 e4Жjbh|<j![,bVhm0JgumҀbt_d4$Rwaxn͘Mj;{jH[~4gEExy3'Lnp!\c*JE]7 lIiKΜ~7+=rI\ 髜p¾c@tm"XLauL`8M. 1GSf2X1I!"APQٌ52,xVzꠐZZr0s3\wkӾccZ+M"h \VkhO_~㣷vos9cAktVOkYOԂy6Rj1ulmΈ^8?J,3c׈QcM:un$כG=5j^{7 ,ovw>I}K/OY__]>e+eAHnn{>p4LuZCz;(|Հ( ~>_lpA3O'Xxixx٧9t}̚tQ%5Z*2::āxmց3OC!xePZC^{}B:q__/0_/v FFHiDos$-u677O8䓘\#Ƞ(y;~+&(sHZe%+x"=% Q;tRZcL !e&EIݠC "}AE:xw"1(b*6gM`"/\и6Eqvc$@_ȥݘ[o =1go,otY(C"PU%e mDm2D+ cAJ`0`0Ʃ:F.Qs%&3+|Ĩ9`~͗yw/DZ>؋sŪ[Yʵ~m۹x}|>>)wy!b&ji o<??dh4"g:+7)e55^=ooq컈k) +ĩ=,s`ox3gNr»O}>Qxasp0`<ĵ-âG4nǴId߰buM0*+672!.:K\z=<ڜoE\O+ "|UɴQZ?3cD1eP}/GƙSi&SʢDIDz 5,ҥ`Z(V2]9V%Q1-9ÌJT*fl.NB$@t>! 1@p;gm#%F @Q$i U/R-Vk@1Db+IfQҽDr .мcE[Ku-bIwǘ ?UUͯyd&q1kL&[I D1muۧX_`?xE=>q~"G?m>?Imߖ>12Zkv~eޞv4אJ_L@ LV<uR#/%k߻hZX[]ce\d(VyGOcG2A[RSU7_,Vz-1кek`87NMSS[?{:Q>bBzH{=@ǵRhkyscuu5){#<쳴mCY4uٔ_ųgPShE Q ʲ`0*ʲnj\2ԃj8uo7L|#zdO:nV~f6N~O^<' MT&~Gʢs/pۦaks?ַ;6!(rͭ>KYh>z?_g>?i~G^c߾ŌBX( D.] mFoeY"@@!r!hbL[ѦQ[x]YL+tD4߿̠ Pce07-n6Sۿ(h,(<{?`4G{Q 餳οf34ĈMQ`E>y(w*]z,^{^Zn[ns}}Gw[\r5cBJd/Evgf}s\pZc0ZsyΝ;/D[|p@@+ᑇB:+ kŒ?0f82E$AD$* hu*ŋ\tJ -F٬ЬwwYn; 799C-,v kc3Y[0:,[kqy{0iι S]x&u=h퉱as"kZ7#ƔeF +E .^`{X}mY裏!|c`mAPh|=JB@$ D$z#Gr~OiHL5/kOgT۫R--F?#y9~~r8@2ٔ}kl^;Gi,i]bP P(裏>`6jF rzuY 5.x{yFwp٦\x/Ǩ c B ?ԩ+fg#"416$!*- JRijΝyVc1GЃlfG-P̚-._^KbШ,-+c h[48ostʪK5§>++,:a=#c8K8[/y ge*1(|DAbP{s`uxS2 HH,z\H"Eh.Fڐ,g.6fYxַjfA:`> DYh0`8 ,B1jA+1s ɺˤ@r1 0x4]mdۺK)-*F1Nw},2/",ԯE,a|2gMPL'SN犤 eߕg-J Cz[<- …QJQUb,2{1)ǤZ3y(P銕id6C a4~6KJ`>>q3 }}G}8 MhCĠ_FdE11ZcʒO}3 F#z7xǏIr0N02pPڂcǞGx79y kB68qL"2j!G1Y\X k 39Y2q^x.]Q(Zs!N<"kk8q_Xו8%M1xx3iZJ,/]&L({szSck6[ IDATk._^BV=Zksp(PQ:MS /~ )TsI7v:X! G5||nm3z{Tg2Jk]< P`m.;%l- GkeuX<W +D:4 ol^>PٚeP )Z/$R691MuA#\e\~7côm?7~/ܪ8`߬᜻F5{nb~-ƘFY}:x]AKds1$zg[` [U(%HSCh4A>W%eY2!:z]L|cicNf(CIMzZxr5/Fz+E9ACPhY/ {v51!ԼAD/e^v{ȖR1) >*J;aY4/<)V*v\V P[)2j1R@PJ*A]9S yYZbu0dX9lxmR4\M&8 dG#TEģ FJEllcrKR!QrofD:1w"6㵵ʛn 7S7Sc?5>,y11k&2Cs@m[Z}tm\J#Q p H|յU9z5倥mLA=ʕ?`^^^f0ޖczɓm$&1IL6E>AdyuM,rۅ|6n ZLk-۶mG!B ];9xeYTZQl*}cn<Οc\8$)/<8|h|N(pG}?R܄dzvyv؍ȇ.]@eǬuuT(!0ZGpB=Y_]_ A%vXqs"p>s{)DyrU]ョJR9"o_*򒪮eA59|(/\z0{YI3d[Հt1 VNtRѝcq~w{HD,)M xAj5@iՕdSSXkE<>| y__2X]C^D5q"|wҨMXr$%N\B05E5j!.Ԁ,K1Je@sܲV2-F7@YzR!CӮ:>Hjr <ZV);4!!ltvsgx~=Ѷ6{rX+8w1z6:ลeC6[o.[A%˲BvQxX,@)IFm,NFߧ5yF:),Kq /p7`SO][ޭsOb:IL60&1eQR%͂׻t\Bg<){/SS?c 1Z0ʠƻa5IwCT(!xqovi$޳A"J TIuqEŅF&B uƾ07su ˔hB#^dW@ uUSUBS|DCAxPpy>?&t"Dsgߠ**:F$X@HhsC#nv7rT-Bsi1T5 W- Q(THa!HHt(AQkj `=A}n lQ[24V-fy;Ï8GAy7њ8yވ}#3-{cNgD}k1ƌģQn𭵣 =eـ k$b`I m#d0|dS4Ks)5iB682NJ9ZCbvz<'M1\%"XZ B!`}8`zv`#Y<﹇/wNNza{d cąʄ( g-J^~%~bRwٻ^zs yxewxIfF!8>*WzX_Ѳ~ Hmʢ@+L]L)$:畗^&XGeAPi=Q9bBDt|@Y4"[ U@ ȗPmuяYH),-H҄Nrh^ °^r2ɠb5mRTXGb[ihD@ZalgnCȑ]kf/qxܩ-xMkUgzzy,#h?~͛} vqzz{_gYRQe#^T֣u1)YpkkVWיfνEIQ(z$$K678p w1nG=6ILb$&q}n;^ Z>xoG9fgg9rVwO?nY6/mXX\OJ'/ wpϽGx2~c|nӧO3m]5r+[7 +d9s  J(ek5.t7@FdAQJ3* njmuz.62gQB$ư~k2./-}|8`az %IaS'R)!Kk_wZJ(: 5ض0 ڱYv0KvSCյ \8+\^YtunȦn]fbIcFL6'xc w屍 ƩcMl|o$[Pxk/fز־y<`0h4}h#GY5t6ٲ)4EAQc4 ))%ᐺNn`P2X_ QZQkk?O蔪*Zf0_renC]w`޿5;u۾@ 7;u-w71Vw/[e֎+9v_\`eUvډ6Hb $Q2!Yp uEå,}Ž(^=c˜4fmVZ^EŰ( 4%( -QoF *gI"?8#I藛蔕5SIJy^iE^2PB3& ( !R1brh뙯;l Ao&afz;}4S];ݎF*#q@*TtuL6+Ò3 j8^Xo<Gɍk?Y02tޘ͹ĵo#l-V4Y#',-ڽ>ރRQ_R4e}}x$^1,( "#BK : oǷc&I2(sV̛kx}FR[,y:ϭföbu#ǹtl6Hlǿ73n_d_(kz#F}M?&)R<ķ~P:*QݨT eV8xw?x??+<ê I T?߷{/K\BurxCP̸:B 2>c?^4="Wtz?|ӟ5ZF<>ξ׾g>󧜿xﰺJ}IQ9+Wܾ~#>r,RIY- JK~W~'OSOSߢ\[$It;kg}D?デ}ad| &v^yE>rLb(ʺmIoo<J FQZ"&.Hwcq;s,$LRDت@54t%eT  B8/kV!8 tSL/"%TS\yC Q|Jh{mU_|̫eM[k,s6[8axvQm rQ:(hbhQ=@i-Re#ZK2B}H*'N,&Ӵ7ZonnfF7s]ףh~~+֮\ѾAnȵ_olno̼[oL&1wZ9sKK#eE_v퓄BtR~c !9R8Dn޻AW)G(N˕1 >x13ħ(C{dê$6nF]UUɁرcϞ/_rN>}~7NU(Lk.,?ʱc]d@˸7Ǐ?̾.=BDR#CIIV1 o&өFI#=ƣ<%>wkM3A`i.fC +t$ʁ,ع}N>Yb$$FhIG+%BFVD-DV#$Z3Qڰơ`XV\X":hL.F`V579|3eJ7 aC +ґruTOQD=*`zۯV[jJ V# !qҴGJ!D鐦)E]F,pRལo{!GvU&|7 goIB޾פֿVOs ]2)^*ݬmTEҚi<`g垣bB2ry󊩩)j'5:Ic_@+x x6ʡPIky`P4,ueI@o $FTY'8T#k|ǡ5%X/-2H 4~W23a6fgof!UR*2x$v[Yb xTAp oIho%`C@)hE=͡X@?[N>Yݲ,G$8w PoFp5ku}Ps$ !FFu((]u$CkkB]GQAK9byz`;h/Hndtͻ\o]p7;>wOމ [\}ldL&$&qc8Sߢ,K$>8FYJbC 8E9em8 X6W N(Q(hArt\]cjNpcG+w8Vu+N1(^IPI;ǕHZ$~G3JK%_OŋޭIFTK+A-;E %WV%ceU $&*%%lPB cP㵎4U9t-!1 3Ƕm]v xD;* WK|/dErm~WЊc10zo!DVЫUna|- [K~׳UyoZ/6F\ݽzkan3!DV޵hmUE[ I]#ԎcǎqGxoDA}]A*wB50("_fؖɘex;D\j:u ,Gub&ԇ(Ԕ92{A(ȤbyBWNp))Cgس?ƉQe M6 -5\8/|hp9˾2 Z>PZǶIBܫRyWʇ?U:>ssl33A)FKB ei5R H1xT _/+Gt ^v}l;ՀLi$Q+:APQh< 𞀎BE uJ=o#ao%58z^E?=ڑϷT - JӁq3m[ ~*ڑrX(>uOZҟa&Q)klv~ϑbcyBF^R 5@SJ!܆?7 kBk<> &ɨo7y3wqr7K/7:;q]7+u'@ԍf7֘Lbޓe@Hw+U/%{6kki(SNls1ild#@65B9>p`>{V\,  ZὃPT=Ο'vΞ3Ͷil_u:$:A H햡s T4 I@`k x[vu$iQ OZ][KJB"U~Hʠ A*j555 }9稪jD+\zs}Oy8mn z7Y+k^zVGR"ZAvd9iʲm P2*hQqṢ,?\o3p>mV1eYʪBnFCӵ:{{n/Y<ӣow 9~Pfz#f㍎sAfU۵xV?w;N͋ɘLda{1j|K,2\x^G]ƚp]I*-[=G'`JڪSIz]?'|Dif\]Yaii jkɫ [$2Dt]t/?=4E d@ E>r>$,ٮAQ\. G YI4f3GJѱ$ZI:BUk`vʰca~4^F'1"5TILcA囱 dI4{PJcA+3 Ő6fnT41Z5V#*t 0 IbFqiuH^Iɭmvmm8Cz zm_k(FW5[=$ަhC` oE n)WosnAx;Ȑ"֪^S ]Q뉑sKn?2R 4i n|c#])kX+R ,%sq9߻ Yѣ=۲ؿ[doFfow7|zJ*@vVu/nu^yr;ɘdx'F$Y+Ex` 84K8? LK( l`'h[S8xk Lk6VJF[Q9xSCxŗ9sY'ђ!M$$8P REr^ / 5UY19P"Zt5!``J$xLfQMQWQ[Hl8Uu]sg<4!ؚDIdLSh (E5u5 ֛ltE|]!&Q!A]Ъ]X)3 ,`P@I! Luok hmHtN~DP6%ٽs{#X^\"u-BKҀM #w "D?cHD:AZ$q.a]TF Lu$PD0ǫm$HE*<6(>f-yZ%XXg) :oRs Zj3-yF?oU3yi}cNmeKZԶr|S/,@u#K)*lmvM(5Y]mGN֬Uw;UԱQw.&K7>׿{?}IL9i%oy0'c2ILG{'$pl=R!Fuv+y{-hl)TcU~u_|[[xu)l\|ػo?d D ѫy=LmFUVq-+WVpaN]!pޑ(ƽLeq#A9 >q$`:xJYDʘIך9dȫaܷ{wsLMMAU'8s$O}IVWرώi}Νl߹tN'EKP""D@д-u%u]1(تB Rdn<Mm"RAmt;]f緳},YU3r"/_䫫 ,+ =}==MX*2nY_[xյF*nmGߟB64 /c=-|so6!8Þxc?GJEiK|I{m=8X]]_ ϝGƐ M=4 8Iu~ffg) Y'k6s^ 'O6fr!n ȣr* _)oX&IPZS KKKK\8*eSe33݌իU֒iw>օ^W"#@%eI7-v9̓#hĤ&c2ILe9 !J%FKTx(eIk27~y%sN$Q}nREpm?'u$g=QF 2x%9p =GECp1K+%v+3X[糟31Bc]x𫿌RL mij}e_#.5C6_>MOs#t=TAia](pO?$̟r8|,;wuc }|D*Տ 9UsK,]<.#C@%<2 Y"@g`BRʚΎq=]S x݉6 1]5KsYN|,; R )q.'x ٟ"x@h{dZo/|$*1i>AM<4I !P sD)+]wwg(gjzOOu J E;"wuBpoHw'GᏨ K[)m;_y콸z:}zƛ3g?GK+<ƃ$FgoGz<{?Zn<. =sW^~WS_NPE7[37Wև ]\fCaF)OW%t~K+\|u'1ILb$&qwbmu>;w?lYq$I\ zfn~;$i,Yn{'?_[;1LDQOJ28H b}Q49wD6#p!JH#Dx%[SZJL Bv>~Dc䃧{d tz]Fp54Tn PѺ*YXX+'. <%!)nnKY>6i-^QC ! q1e C#wͿ\][?<TK#/^&II{ +++$YSUz X^wd$&1ILbM)tՍc^ц&d&:*_|s(iw+njpHP1IU0f_%~ga0"@a!Pk:1Qi C3<)>1=5ͯ? B)\E͔bs tJv,yzLMp$1}IY^^oo|m?'wr7=ILdL&1ILv2 }vQu"eY+W[VװU3сw=[L320Ϟ}x;H30ڽ^{p8!YF]UH$Y{ڤx…lS) QFS%/Ict41D'xxkjEGC)mȇ)Oɐ@>1*VI2YJjtE#rgPl"E!6#P[ҡ`£dE<;fږTVm;{x;\8<* lѵRWd~CLQ!I'Z8a*P ڃ "AjE}qd~i V.2XYן5o,6CЊO_՗Y_[C)KXkɒ$J+CY(Es)]"$M8/Z4^akO;x=(U%/\':s~tF`:NC=U9ΡBxIo>$gOFVi*J.\gC6fh$`kJH:Y!lTE19bC>ʎ;mַUf[bu#MISEU$aff@ χdYJe>ع T|?uwܓdNd ILvG&6b7:45Lw.YEId,GqrR.#')'B7T @]GwUꊫ+$HAR`GǎLɱd8ϰ5!%6%˒l8{{u;cc!?$w`j*Q_)١9Dg݌8N;w4׬Ӑa t:]}C+xzNuRJZs>˕kW_y6n݌ B(Ei-Ҕ8Ixɓ|s_|1Xxp_vjEkZ̧>x'o~%1΂iOeqiߴQ5QJwQ2dVMI/(|g^91MXI>V1Ɓ ǖ=sآPk JGP*HEJ:.Yy7vًD#dFQ +jxC%)V29 e)n07;<9t\c*&V)M UKdR'+(N+/#XjN<>k tUQAl/hy֯_3gv<8سg>QaPC<+/}%\=4>''?cO=I^HtL2jQkHb&k'tDeXQBTjN+pϽԏ0V+вBR9 <7ryN?T\PUVi20+\Iwwx=ojiʩ'9}4@uX~qD`sΡnzzJٓupe"Z-,9;\>C70Q0`tɚ5oU%YXX+2`7]Mxgg>1a c0'2pޡæ]9#1 γ/ryeڵ|W|#z]TaLɍYt1:6i>i/E,Cqw^'Ynx _4#WlXq+ذe7?!,(pG1 i1>uv0:>a9+d<̫/WPR-&Iɬ(q;uff,!f%is-a}V}D^JtQXbizW8{ $c9q IReXbz[Tjǟ8'G_ӿyƹ UWUݿ?qEO5eQ1.!pD<xcY/hx={9>B=t(ld5r^8_z7% Ogqf٤Yo눑V<"@ iFb:"#㯟@ 5"-[l!1Ee8Ϫ5O=CiJ8&c^F(9~NY5%_o/AA53t cMX*Ce $Bʿ!EeC \92gȍsG| $(7'X5 5Bi!wU63r FƔB(peX?_*tNCf,)P N/Y]K(,R@#LNe{:%eT^ ta=XGӡsxcC:{Fɠ0?OQ[g1ƱLY Æ58S`mAaݚ &@JryΜ>ͱ׏Q%`ΝacDzի%zKf* rgP{BPۘ"vm)nd`xC0lWuo:c*|}&=ˮxҚXcY^^baq^KgX[nw( @s[,߫7u7v^,wwbo{u-~]OcMm2a|B)ƘoqP]$Ae5(t;+"vTZm;#@igܹc eY)'Oi#g E8t)ޱ8;WJ@kw4Ni͇xfsd3\:w3'7_C8Hu.(='q#(r"B 6 3)JEY&1۷mg)9FZ)Sc:Ζ͛D!t̙gɺ9ΞgvfH`<8Rz֯_OQ}Y>r%e % Fh8yÆ] 8w^6+oa?Lm7a c{` U2cY*Y{,(}]CmqAZ.]@M+{^ (kl۶ : ƍN8 zcߣ#M6o\HfF%VdY(q)R`Gy`c9 S݌]({RDJcKHǟx$IH`՟H@~6l܈TF!3| ijs(”9xa 9ʕ$@heY;IHǸ!X1cK>1#/&4%) 1\px5x!RVXC[Vk%I:K-dK7~$)Q"x!aЉfnqK.S#A FQL8y!Z+IGD6J/Bdl^)zLNM< Ir:JuXx8fy}?3fggطCIbyy^}˼`D?+au<Hջ_,M81%EQ AG@pa~kC_u7%w( ۮ뽧, n[Iqt:<,/.aP,8 B*&&Wm6͠mcfsHgll굔I"QZ+]){&'W~ƍpoyvv߹ڷN[VVs{M;/;۷{BʝLNnw3ލq1lG c?H ݬgP UuJR] ՜9p-W61"pPhGO" Vz8'PP ]DH&e}#ZE<>©qZx,DPqVQxSM|an+P%#| #޽Qo6QJ`51(nZǂ*8N9~y/ LBArX(jZljVLHdu%8["G:DIP)=P]—H ˑ.܁1"вDeڋ3$*3,K3Zp5 12IdRkw{Hրpxs'@|(wsӶf;阿on7i~;yֿ~?(J}ݼog|V[5M1R8jX~7Ѩ#$iD+ Wbt~VKT.+ )qUr˩#Ȗڸܳ8{d x6#sgh֬]EQ8/rm )J)EAף9:ʊIF@)VOOqV=&/t.aa-Ofy~ gZd ܱl 5q12:2:@H˸x"Xh}P*B M$+Fꌍר54>T#(:-˂^ø2ҡES}p֚,5N)(Y}<)ˀ\4Y >4^F &EA8J*J$$# YPthWq35$#:#4X( !E{YHQڠ ~:vﹿ;A`9"BEJP voe [dbbBD E|5-$,_BhE,*(aݦ lܼ )VMDEVv1gX%E53Mv1.DVi\<҃BT ^aKHk5$EK%/@$ՔeW+ƾ(sLFd8z3ecc)ͺd9Ks,vXQKGv:yAȜ~`v`0 Hߋ}wn  |wjLc6ydA c,zz~ؿ?###{[cn@Ivs}fIB]DIbڲm+## ys)&'شa[RRKkLNNfFGGIdj$I2Ȗmݲ8C\y1Dꍫ|4%p{33HDP.KZ#<8M 7M7xNnpʭaZqj*:4MZ377?U 4MFZ-2k|EK8W2;7CDP;:[?M|W绝}P}sla蝻wK~ߏ2l`x^orI$i27HF eݓsAx3=rv"vپc;Vɸo}u*dpa$ˬٴi@ݦ$`*cڵk(u{hZZ\rS#2䇞qr(y(P[CZK΂rMʲQ!|f iKiHZw>+EV.Ys pc"@ K#tJJ ]+)W $AX,Fx-o\EKA(D"IZWOA}.x˰/$:y1jo>֬ 0,n_Nʁqv}Ru-+8bǽ1r)6oD lbػw/_tC%-c/](A{XWxŭ 'չ]Tp ^悙ysu:EQT@_ojQ`m% Ě`]W(ecO1ņkY116CL߼ݴݜ:߯2lc0~Y<+Y\ZYqG˻')zP:;;*O|)rcR219 d.giR2w3gpr 01Y/ê`շR22ҬX;v0<2H̯~UYg)(ʂɕ$Y( b[֭g:q)X&xV!Bo-iSU@JZf-"塦%y_ jZ]%~u 5@ BNTHs9()L+Aᅇj{R(Lq HBh)uJP3 <:QB!?*RtxNdzǎ%f<2:ʾGk 2InB-@TAĬ۰Qؠ"/yώ]̯ $ 6PyҊ(MH<J_M6if~zWP500ޤqBYD΁͔v(Gjo(1WՈ+(AXR/ kVb݆L[ϊ:*{Zn?懀߉IΛvwoo7w#nη>l60>u]Z S'I!+ۜ6v|3dZ~e&69͑쾗KLO%]Z:Bh(TvV()͒3:ݯ0Bnʺu7HAI{qlYEJARQ%E#$S fG+8,ƺޤi)F5%B;TUhASK%q8#QQD*{a^RoY411 "8'P:9)*mH5yu=R޴:&(&9 L$hW r*]נb zY5>ĺ/On؈IQ䡞|xcm4EY椯2 EVN;Dqm(b`IU@GsLMMq{8k,BnQ0Z윯(8Jn\rJ7P+xh ӄmn5h =1cɻ y:ETi#Min5ozng^aiJ{><0V[mh߉2)w ܼz{E~/xoww; d&-^aET9-z=U6Sdx*U +I'XZ\̙37!amrՓ+k-'OB ΣZYOZ1kהxBIMY8Z1{!c:&'yy:[%1"(Q0h!"rz!9fgO#vhކ>frr2*URJHX4^OH$JX}-_cLeZT޾BJln+R +%ΡRH%w%$J˻-E z#tJs-+[$ }xѨF<;aByC-QkHLPe\:s/![{ݰvyx(uo!bPYkyh^d?+]Qsh^!)MfB9 n}BBPacvY@|כ3oƘ.˂,BHpWƐcH(MIEV^G9FĮ]ٸi=;dX`| vA@HCŌױccǃox;[Ӻ^ rqiw}xunvY,y:wI􍷲;:Jcy+QE1D{5jA-[*Io5ҋt@}u$lܲ~4P;?7ϩgƣ8fzNDQ48;xf&V|ps,` "BenP^ӈDR#Di֭[ٰi#9k)ʂ /V7s<#(<1R3(,Z&Z#ENJ $oڤUOX?5|ؼ۪[Iz+E-&}92iq}RE>4ju(D#P⭵Ӽw0!zϽǚx) OC;Y[^oLuyh6UO BT6 9Z&6m Q4"d/?+YZ\@KX^\K\-!up;( IDAT‘gG7 t=r|W 믿-Dp01a cw19Tc pkX[`mA):iqmioi&DP >u4yQ_d[ؑ ;ţκ ܿ^Q3v゚Vkc-RɊa0eIgqטdcmF%\']`r$)ess ܸ1Po4Ƃ 1a|Ǜ}Ç1la cq ׯπHvj52dj#9uF1^ c /_3G BKsst}EeO$m Khi*]+t[LNmJ*EKhR5B$8.\rCGaLY겳\ * =@RɶGdEzh)9{4sσXNT(^Fcd_ǟz(eO<`y~!hPߨHSu"IZY|C e"VK)a)@H4N͛7O|!BIH…;m-"A=YVtV2:ҠR^c;*9Ma cq=la cD٬,/70?;Ith֛:`ԋo } 'O)`RS ='O'7M+[MY-I$ n رkGG\8w< 7打xP( $K?5(Refm+Wϙ1؊ޙ<> ㊌4RDRPĉG+XzU]8CpW/="ԋK/zf0 x&Inڎ yҘ"ht;tgQ6 7hMBPUo۶saf9D'/8eIMNoFͶٲs7*iQቪZe,-p/9DtUF;~EyDz=ZJ^FF(پsR,8"FFFؼe3Ht!u>uGt #DB"gfnSNAEAܖ~zVԱ} ^>+Bq+l+g{Hp>/%kOS֬^"/s򽾉ψw>w_0򌷔a$|lܼ1ԱkSp;oxo0On\ٙ-Q`hR!y5FGǑB-/!`01a c;R͑ nNI!ÔH%p.&I^j-eX0hqZ9FL[,.uWx~װ2T{Zo, s<:YQ W3kd;kA=>7qkd!\i#"IPoP8OQsuK>}}?tȶ6a c0AICXWrkdʗR޳;wbţ022{%z3;;Jop(!$/^!קr^g߾}ܸvkQ0dÖ<~F0>YgưjjFAgq9dcM9DY $6nxg}8?#yA눯}~gUIBw U:Cs/~ٲy_rfLkr?$I: B&ER+"Q֘>6MXI+JgUs%մVHSs0^dlrwnX}Yłz"9~8W/#{u(YƩG;ct,H(]Ac|5{OgqȘ\=}^k T gYw\9KA )D%\U*PpLb]iwɊ?x}[y T7&,׮G{`Ǯ1Zc,w;HUYYoSgȻ]R*!I՞UW?GDޑYPV?45z0:+KjiL}ɦx=DI-\iͰ{qY 7cZ7ȥR8{y&+on6lބP\[k҄fcqqXGg?WHI0/>K E$7GG?;wKZo`|Mr"TT:lWصk_qf_~G O7"}{/-Qc]4#+V+I"EKє,ϓD km#!OѥIB{A :b'ؼm/I\LQI§tH j5/:Yf$~G8薡nZ "⩣L^;(M,G+*{^F8TĈk )Ο ?{luV鄛vFPD"HBHE DJbILFlGUkyp&)&%$!"5rwѹot+asvIkfU=i}є%0knpu8Ǣ1ޓ OV {;nGOA4(xZ!E+ZRǬd@}u|˛YسiY s,)?S?^<𕯒 tʵooqͯc޽ԦZx$Xny'}'OϾ{~=VL4Ichv dy#ҌɸLG|&%˻]xYٻʖT!" jY61@p`:-O<p$`uuh4K8~-GC5ڵ[`ogae K"&Y. 9ve677 w~ڽЊEږ/g7Ʋo>3zy'>ɇ~C| 꺡2l?׾q(Xu n§ `bg׿icZr? C,- ɲ$=dYhИS%:.rM;tСC:{aqqaxTGis+Z=%Uitkimpu4nZ4ơeBe :Y1NZ[,b2p7d20X?yʲ%n|Ht@`,EHAZ$7<4D(a8s%ʵh ^dŀ H [! Y A;# 2X,([܈Gģr+1TC"Sġu@ʊD 6{357#ŐPZOH3 8_ҔP[h< :E'}/=L9N2 _%j[)q@ i]XL8O?I_=E+ghGr!;9LCʣ?Jٵ+fWqn N]15L'[dp8diy[nouoq$iӧ:ܡC:tA<֒uʎT2V emIU%d ƾ 3cGY_;DAS7:ɓL'c(H4cfv@!:Xo,ޢ()q.n6BH'*@i(P209D sOk XeS2@8s {f0gv@nzo2AKjPʲu'B6x"Z`LJZ4Ti P1:2'(C{7pgZ{cL=Rh@3:skt˛vJQY"mzR(}C?©QH)ӭ-6F#ք(]@cc5h)x<=diE%(SyǸAiRJTDػek1X6s>u9yX(*.;ihB MWܺ;rҮ&uԱ_1C`ڞ&iyƧ"wq1G=I>)'O楗$h5[r><2(Dh-yqmFFD(M3Y?_ !^~RYF5U=uSRWu+R6Z+u8P:oE)M79saСC:tڠ+Fх(%ܜ$K)(H}=+DcPZ| !`| /e%ϲg*++G 4^O8Çٳ"\YD%W^{~%$^zTB9! |u&l1hD)4|O{5V)H$:{ j}E^|};dII&2lzM p0PJ4yFHH8z8@/}pȁ뮇4"m|_jEA<> f+tΫВYTlon/}h!P75{Q/g7! # њΞ_׾XW0 6RxyR"Vˊ?xɓ;r~_#o{A \{\b{>r|\*.UŹg9{ /<,_yr45^)y@9 X.|k,M] Fc^SO>=C$g8XDJ{;ܡC:tᵁVSvhI1>|c"B' *E3,y8gȒNe4uM5)y橧PJ9G_ a[ ;G$G"19zմ")}agˋHI4ҷy\H!xL&diD3?"D KY__ɓyKSNQIJgm=ge%n&n~\up4M. l3 t9)d 4N{kA,#B54 ݻDX0nJԁjPK$BMܢNu O%#!~835tB95 LҐ" B:!p̉A':LYs N~O0 Z(}*j791^{{-< Iu=55:60ӌ7&$ xYN='>QtJEeӦmΞaQMUS?1nji Μ mEr퓘zBUG4UR!FyCxR@JsCM'[Ӕ̩5>Ud:`TgT#>NHӆk#\YǬ]΃LҘ,jPKI9{(pzM,.dx["e`=.-ۛ,xi4J[5b\UC,R)IS֔uICYQ%{T/9:تk>6Ξo TM{`'  0 g1!@hMu/>EK! הLk)Y"ZЏThpRP{' )i{x<{1 Y9ȳB@{4S5|J4ұkRjm/}{wclV8zhG;tСC:6HӔ~' [|B8)=^:&mtQ$J!M-9sWp:c#…wGtWZ#%uSQc5EFm+eCy&QdYNpYoصDYE^ !rH8zXG;tСC:6!04͔,f_Gr*@ J&^U41 RILHI~.FD'b,"/0" M<0NQZZ1-8I1U#p.rxeENYU5 @fئ!@$$;*A(XHM[q< iJkPZ"BN%"ꥈL!3J W !<"X!=ݣ*%}:UӀMJ)tIyEA xJ!\p$=[; M`T[H S*&8P“R\P:J!#():9MSӂ<+xz!'cN$"J3ɰ`2523>:Tk,RDy6XtBTO4 "KH)tr6Z%\n$%@Q pޣhM۸ pAJˋdND3:.T(3Urye9IY i#ձQ%Zk8!@gi$3l1cN4*IH[Wwk׏,1 *+HcHEFg9ΣuJ-BH%Քh)+@z3o >mE'f!"15Rd 2E1ItE1$Xo XogclMՔ `N}KTcom s$JKа0`8`fJ!IJ\ HT9nc1X 7$ hC%R-xɳx,bޭ*6XfN*AA"`iinNJӒM7XYE\2E#tHs(bB)|!xmpJPŐB<+)0Ƒ&BkT_sTTg@eHAF6!١߯cg'C ޱ+/;&.=ٸl{pϽ@p/S;ݶgOkMЁ@JDZ㜝ipuEߐ%k[[YBc2P Mcf%]F [i=67:ܡC:tAtJ+(MzXY]mx ibMgBuL₟Ĭg5wMC-_Ό$Wߡ%rF 0 Jeq3B8ynWss(dyX%JcL& Ue&UXW  ;t#nʟ< 83}m"a޷QRm=_,;4IΞcss k^w _G4ԉS>|eV$Z$x[/[o, ZeY2Wl׎i{WٳGkO/O +p6P&4i(4o+Z!DRZ==pƐ+%{UUc:!iT_gL$C >4`U ӭ qIe14MF` T2ꖬ)@ \@8&n,-㲉}`Xޣ[Sb;s{ಳ:̟,Rq^i4f .39ur҅٦Ԁs]zٲ.Xk#y>[!ʲgc974uC)uTUMUU`:2 ,K5$dqi^p`[tw+:ܡC:t51͍MFg;q"I䫿>MS:4M#iQ\F.wL^\^yi-A.Ly6qSj:]I-.;;IVR] _LB5ԩl=ŮWߋ1K >AFJR -;Hdۏ:s1 fgŪ1) E3@ȀV9 TZĜ^vcCpA5ř#WT& l`[5u2x'VF"<]hC1U)rj@P`sGy )\BZk%.ًmW^ܹ!/ugz~~y(% F14W8 {za>.o֢0kp-@fdyA{ceZ2h ဥ=A4,..l;O;?:tСC <СCkP"Řhs_4K) 7RsΰcvJ5RJVVVؽ{7xIi^Os<˘mq"ZKds[ lFxĞuҞ#,,.g<'њt&Ʉ-4obT+|{,Zh-) 2€%(]c^|Eyf3Ƶ^֚{ӧOS%Pw},--4 O=KHwVέΟ:Mi~7x'?-X@ } )%{/WEUUH)4MzeFVIx)fa^ x `)M`صg1J4MC[ascwq++-љYfdBX "V[{2n?h6&D4{{[B(q! BKD!,ɂA?c_`Q2^g{Ej놪64B@!TZƒrBp1I8v#:tСC^+LSrՁ=lo5L5Qfhs&o38yh2\u5yrkkk,.-g& xٻwW_s <ϟU&ؽw/?swOS=>_呇Gd?|ݼMwSٽ{7>h1NS;Gǩô*y/?eɟ}s纫oDȌ_$K4X(toqmE,7:~SL{?#nf~)FH/xǏo.e{]|cd}k񓧹 odS,3mᱮFyГ|3~Zzhnvv~>I03ٓ>P$)7x3"h^z8n|ݝ|*65}dgT:i|sjm4rg hp7aSKJ|VnkU%AK#ʺxBz<jv4O& CLX??mG jI A!@8 l]%x?}kGm:HΰHjapxN]f2a{8IPJD$ `T6j PDamlsCEtZFgZ74DZ!BM[ \cW} {B\Xma WE JR.mg,N}s+.,Lf]⭵c,KY\Zd:f{S[w U`{;єn^?kyά5s:t+݇14 ,,,S&ZMSv_5N<ǩg8>fZZa|O>q3JΜ;[XSo<Z779|Ym$U)i< llQcM``\q("F&Iɍ7dEf4&XbLCmJz%Zk#=©3k9|bˇcjV$-^L uSQ+X Msc,x41c먫I9чYch&c4ǚW;P(Բ H}@@&mAH[E@@Q+2|]h#!)GVc$BjBhpc[)C(ZG5YrhױgV*uéADӳjaZ4&Q(-e?8i?(ն_z=mtWnRg,-ILh%bT`УsBC13`&42H$6b߾c$I;{EDu9=}oR'%J!ؒؐ2k` k^[,jaD"E3軺3"?5=4ə!w $2;2"OS[OaZH) ^Cz/:R*~Ƨ?1{9oJH&G'i! 10T2&i]jE0O!_F|&`+ϷÔR(p}{x"k=J@&3kK]+s@*ڬ,/QWS}r8rdF5jԨQF B<. Y]kMhrbHvohBEʉ YzCv Y&&hjNYb:p"hC-u9MI@c[*Zu\kVk#R,H SNK| C e,ZB $ݗη^OOy$3_ 'C|s?__S4˘N+2]nC`J DApx~9Ir }oS?3<ǹ~/];/pI=N<7vn UDE?x3 uL$"D\}@*fE1nCAf ę2e ̦J"kQxR3׌FS&ӊQ"M F#{=Ɠ :leʤ d{!A(0tL=T6V.p1M/w7z!CqX?l|[n0f 6J |`5w]5N}W񽌷8 _?lu{^-@<{|>+bt:m dPP4*Bish6ظ"`nԨQF5jAH( &S1ZN'ËqdGCe"jz6gekUddmedLڙ@킧ڔFB]1^Pe (Q)-s}Ltf`D @舮&UuNѢJ2Eeg/>C]Oַ+/`OX\?ݝmT w-nM%Bf p%Ҥ$PNӒ}._Jg;-:{C6o3O?Ǟ8<,s\zݝ 5[ٟG`< 9b WwYrv$y8~|> :N@D68Ci$T^0L({Rv]fp%FP;ʺKj΢P#Aehãdy 'ֺ4\| ìz[,U;=<뻵n+YV Dd8# EU9Y?…`8 /~6P+̪^!4BJHYv?9FI2"gCr /ݤob#+}ZR Ssu`v8;y 4w"ӆzE"ŀBdV;UMmBiT#Yq6OA* VJ~ aj WN#y9fȥ{XҼtZNnDAEQPyqp|cOKϿdF5jԨQF﫜DE@d"6,t R8&1"ǎ}L)3>*u5hXY3(Z-:ZǞ|V B!es^7mBeob[=J2태@ /F j>ALdFaT5ݖa#.Y\^Q:^G*1\]='~ ۷6Z'[TVnu!gr^(tuѨ߳5bm-: hZ,,,1i:,/-QyrJ{;n+_#zvHк`o@@EM.BYrX6>&7T3Wd%Ҁ4੧moqki,;EDJm=u)+gINx9D I9Ԯ&x$bR)"6|,CBeU!Rڀ 鹈?AɻU vwM<TimJ)m+J1)`0-EJumH̿Sxvd:5ܨQF5 "?̾sx?wq RkiwX贈.PciZJ]l\F%7kYO vvmaN-E>^(F \UXZlf<5dE euװ.. H+3"Kn"<yٓ9ƹ'XZn [eGsF5jp7{?ϧ iĠq!qE@@KA긌Z}:’/ȗ @> ˯FkQ'[{^2Y<0'O[h(֖jGe@[Rl?uhAj㫜z@[XȉϠ3ũ*8r {{{,?T>nuy8"yᅗIԏ~h `7/`lYTgI/qZB>}j\k2B)o;fG>J Z*=D!kE%Uuu-8k&C䑺0ZJieD 9DɐDhF"tsF"ZAYZ(%k ߅6{UqAwÕ;g0,pp(U {~{@BD1#g󨩈R4BD"d1,k#!)Хh%1LQ{#ZN̍5jԨQӼ}Ww;+nXz\P6wݞ~/t_H G=΃.:zo~ ݪ(G<[t#ΎY;bZZھk=umu-k Ȕ" :H , )Hrcv=;nnlS[U R,Op9yu94h)sR!#(zi1HA bO0[!N?na }w|sns c;geN`T+zVi5*K R*2vLTՈNn5ܨQF5?X^{7ȻS{Uo PX1Cy\>?J;ə+n2̚ʣeN7 ȱwkR~8k5Ο~Wxk_eoҊ*oοgO?̧> m|7 TO~I]Wǿ`<',R:?ou~NK\~Ekyxq?\ę'qn11N12t2'NqWfmvE96 ܸ&O?O>ӽ-2_sb'(eu R0yze:%7 )`9V` {g=ϵk9)O.lE]E˼<+\q:kK}N=F楿'Dɋ)A[Im51C&Y5:h f! )+KmRJdB2\lH@T֦ y b$s1غIIXtZ9vԡDH|ޞO<{wN}L3ZeA[s,Ȳ=×۳SWsPO#e5=:BL}F+K h)J3'a`nԨQF~u/ wX9({=@9yod[F)=2XPt D1դD TU`M|,..'_Jϐd%zZDgn*n^e IDAT4ʈ JO6v9 %ʜOsEЎŕ%t JEΩN#}mLkM9)ѹD %rEe$&|8/R۶O0$yTD4LT塚Ӭx%Z\H<y !:+IJJItPA-J8:ayM]W&UX 1ݩ<@G ˇv^}/sc8|Ð=ϡ0HWU rv{-n iߩkvu@HP1e88kVyh4b<*2vwv['C;z> 07jԨQF;~/wvI:C_Eu#"BbJ L'[\̩s|`o DMYPJcHYFȲ2JWOQJZ - iڜ8{{Lk\ D@Ԧdlo0ޛP-?$R$#FzRی_]?`8,GkSLd@e/##-282#peXϱr1be_ jB]U1%Q--ҫ78s WNí[)yY~owqecQL1Rr .b̫ʞAGR#q# >$SZrd"ɐJ2L@BBa.sh &0y>S{v(Sf8&ڒVGstbI]z$RQYJH A ~$ ŷ3]_3[Cp\5!9GQhmAJyP3#R{l](hyB CHɌ 1ݭ5jԨQF?Zۂ߭u>wmd[O^Kvv#q>9yNH Sq$"ӊXgLwغU6+8rd=eeRkHQ7zmb]Qx`um#OQA 7/28~8Y㝥[׺Qbk<~+4$E_Ĉw[a~,A|Scqq,H _#N#Z!bT.҄r$Kr`m8eRZ5 "#z'AMO9s{9LK)߶1BHf& .ZC 1ji3~?M?|Y7ܨQF57v^^~z7}A~>Os 00N |Te3ZA. 0-wtZtzqڢ| #ry (bYS}j+L:l`0& $"Y:9QFB  u"$Ha *BN}Ѧb),&x b,Ȳ>F;k,2hABPdc"E (){#M tz<ӲEKRU!hBfࢣA5 c1ø&Xk!F #>$R @yR tocj:h<"b#Z+"ͷYE> ҘK yŬm 5*SE.cM 3jQ2OUwH>&1ٞ=;3W͡y>m~y;nS7>(Qmr~QZᝣheu-Q{BO>1jԨQF5j)^*1P.UAaa1Y"j(cl-m/)I90l3R՞VC(Ui(&p$T )HxlL#8ֲ EQ`A+ơBE$BuJ+!/*QB"Q +"5F!#h]1bA]L% J|=AHp\ a2I:(5sޢ,rȎTm61 [љj,Ui49i@rjQSWݦ,!0D :K;tT>9 c5DRcJFQbf'\j}"BH2HZȭ)_٤Xc e )H(u`^i1w!4YzE%n Gi0[݃,!NXmƘ8>lgۮf5>bb8p)SJ&ֺ`Fg N= z D&=>#F6Jh(B;N@5[x:'1Ɛx$K`aJN֠( bo{-2RRHC (T-P( UŹ1uFmb#Dj- ɽHfHY\^fa,>* E"xl9`k L4ı'Y bD!RU`<0ظu7_Br-L >"C*iťy ه9q^g3kfyɽYAo]6x#-B0&pV$3:#Z Z8Bcx( JK)![jv36A ;VVөG C 'ðO3:y捛\~ RX8Rk9DĘ:T~s$DLkb !7Yu&`l^ME@J5A ɥ:Ĉ &T5J̽&Ʉ,lt ekj#2R>i46*NQ #QVh3߽w4{;̹{VK !0&ulax5oϾyzb=Geuuej~s6~7`nԨQF5j(DG]N%"E$b>#DET5AxtaȲ23/Éfjaqj:F%hGܠӅK/PɶihBX\.̄/mzfHCKv;g99v[Wٹu^#M$Pu Kf t8{!vFj7H1EA.^bw) .1O=jqQZkm !L~dqRMn9iNqtMXX45GLFP9O%Մr9^9{/^<_Oq)}QR"y;%`=+"\|2A  F%!qKQg\cL,D$8BE!чTݖ;LJ\QAefko*ђBɷue }ڑ{wz;wyxk~.wa>  !̩s;d(*,s\Da)h+]}mKq'&ӷ LӜz@5%6^v+g@ݣ0@j iU2[PVOyc&mbHD͑#d-:ޗ D }V́#Hv1q)6_!DAjS'g#+2)x'0:W] C:"P㡳1UܦfW_ӟ 7i^|Eƻ{&AHVWzָjB=+ KOY<x# k+Kd xWp13~ i~5rC^F!knuɜLU23(v3+!RݎK1R5,_?E2- 9kq'h w#c]Panw^ 6Ơ9GUUmZk l]0Mx3.&_¿c<ex⩃F5jԨQF'z'\)d L(%J䈨u&nűck]!c[LƘ>gO=lnhgcKPqH6yч.J8#GO*V-Q\d.8X0b4dg ]9Ǖ%:]8ҙpD(77)Q2#ir3%v2 K> 0OVcȲ)ɔ b =1:_yC~1xzמ._~1moo&ƀi^ZVrVE v;(fQfLj9\1Ed;,4~2GqP|'~4}sL&wTG{|G~c=<<><0(UDZi2vw|Fyޢk,ycxjԨQF}/S; d o{yy}~PA"M,;8DLaDz.G16ٹ5`uKf:H22)rZهdk"nt xkyﱵ)1EMu&;ϣLk7^fs;ZYXŅ6./Qb­͒ݭO=Lc8Ω/<8뱴|'"pZ9aPJ|;;llmSprrY[\!z\QI;o"bپu͛|giWoj| ӞokVEΞ:A9zLUTt톺^5{p^HQ%2)''Qp6/fM)XT"+AՃf[S"aRgE(M/ي"@G-д QfEs}35;%ن{uRaM+u'9b])R1ر%t{QHSbLL]DB +R{br897by|Lg踦xzUv['EPJ"''}}gOejuƤ*. =}#v-FOh{B*fx ;Do^Dp 7{WgI??ͱ<霟|^n<뵿ns~OjFnRj&gO< ܔ TJ߱Zs5x;4P$mѥ5s)Ke:"vH aC:Ԕ*46&tݚt'"S"BAfDI#i<+4vxhj3P+%,sK T3O5)/p8>~LKj%t䪣bVRM*fïVDm!RjAmӶea1$W)Fp0:+¡R3)Z%Upcl/rtswP=n!>[L Ei5 !p-#sk/JԀضHʡPh$8jBR\;oScOA-es8gwIؠ }f[Zn̹uPsiΖʮӄe'kڣ:,}"} !n z5{ 9N)m'vmKo'.BbTı,Kں#HJ8;{+_}U\3+>#F1b$'yOϧn4\uO{SEYLʊ)ډB&3"II ͻSN>B cӓ *T66( f !A0BfGs!0UY*Ma|ET&DsT3(>8ˉA1Qr%єSoܺ%G45nƭ$'YL %J,)&;F1#iB$!__q~'>Ta۬*1ݚW8ס-M}[sJMMͣ+"F0' NG= v9!___%Ci NԺS}c;dO2\ˋjrBؾWgZLw/ȟAJH ab̓K .`{͊A8a[wYNNss/"$joQz=Tkݠm$ӯr.E"|-}-arbO2.0;w6T;3Hbi9?Ь.t6ɤmD~8z'mB 3po1@D_~_w}w`$#F1bĈu ir,IOw!4xTʠWĬyM\EL*"%"'eKF1A{2|@@֤bCL^@Q8#Ú#v8MEOIVbk)O=9eÍC4FpAƶx4_V)USW#iQ !#@zbkl2a@ZV 杻hJ?rs{T{a=G-x>b62`")jǢ@_r~r^{};`R%/uPoW3ɽgN)^Jj$0YO~؁{/*t=N؛M8Y.9 Ux,ۇDigEu.RN*-\"CֿlgӇCxXפQ%导o|=祗_;o01bĈ#>>ퟶӤm_u?xRu'B(Bs'Q&K[ǘ@샟Ǽ 8-^Rxj0\O/ʨ] U_坪Uw`%rH›Pp̧hz-u?z|y<. y\j}wmee[NPA DG4RH]D$lٴ5MaA )L8;}̺9>j~O*hLثD 9&4]ZlM1E(r!QL*%LPKX8l)3wX@IH4֠e {74B5дƹ9SR`^P"J@lYVk]"pA O(Dm9={ZSny?'~>8bJUE gF Vg ??:^{^yuQfbBs .kq UQ<:"_d$g7ԝP/N=o9{Bϋ=d]Y`R 9پdT5[I\ .oXZr|_j'm_ο14vvo5RM1QͦmMYIiGY8Rl.%."AF1bĈ?_%f͓?'m,yqg]ϳO IE%&=maxK$@3(^c_Yѣp{`Z."ZKL#]4bVcҲbLbBS9!M>:n~$E|ED)D0 %"9 '$1&Q=1Fo!4g `1{'sD@ DrRm6!)KmphG$3|#rFM+)'9L7x؂",/O!D[QvΣǧ.PT/ܦe"e˺>c,osp1M,*_ҡ>Kb{x mAe髲5='gP&v0 @kEهMj$a`1(p.1>IWh"l |ʿd =$v?%a^D +uQWIw޷nЯi=P7 1ue#b_xM,KVuyĈ#F1W'%]ϟ0LgS\tġC m)[{Rd !JR QP &i&xOQ$F%萐eSAKABb%5jǻ@S7hR:(_RMAcN|l">U"DT_D:Vts,fg:CK55wt42"SDۧ]O-^~&rzreC1tx1 v-E& Apyo:Z]2 vT)''x͆vQ[Z?nd2[P , FM×1"pzIJ6r=?pHUUݬq|&|ݺ uxJ|p9kx!e;iB$X 3<:`ѥ%O[ KP'-~z='{.=9{\Ї 8c躎mi 9u M[{|_c'8_uHG1bĈ?Q*CLdJ@G+ zcUEH}@-HA}K5DghS&霔Vh;#*Jg DH"3i|J2C()eQZx!y0f4HQQؚi5] ,OeFpqxĪw5F,+;a2cHRd NML'3B(/c:KL5͆^frpLHH g m\Aa6 3:[jud2GEq$ ENOX,YٳHu3փ4ǸKCSRͽEY⽧ij#⼲C|CozpyĈ#F1bďY6% ,yYA|*{sPbLwt&px.7xrDgs./|خ9Q |[;8`>CđRǤ,Y.X'G++y㐢*X1jc8,+_2N[8훯1߿G8ј놪PWN8=>c> |5,avJxO@3| xL1y9q={mNNO_:x_ 8HmKmWk;/~8^1_e2Ot5ŤզW(!KXh3&cq*_xKg3^/Md _`N?|M__u%u9nfurGX߷5!4*%՗{WU|>i6͖ Gm &bM*3V's܌|Uyg|:Y~FfrXY}U\ S,ԉ.%`)uԛDtyCUHō9(ĮsĶ4o~K7LWrzvBQy OWGAI(jRq#3 b8P"ŗ~r[?|1xt&Р:ʼngݬYm@̙΅>x/~7z!j4L9=Z&s_Iý zMN\IE0oĤlxF3ܧ5R9]󓂸ڲ?,_^t}W94[uA^=nw9mh[Ly(>@ 6888Q||fʂ|NY#a1bĈ#FAs%7n?db?TVgMN&E M ˳UMekut]KSGA Y?b^Q}Dsg7R8CtQqwn7ߤ^o=Ixtx_aS=|ѣ3B(H-8x|0qg8`y19mJ,9L}~N8 =LR\y9G|] TSXfĮݜ6ێYu믾o@L!\"@JJ( zڔS#ZKRLZ/r;}NnYـms͓BHEb6aZ"\oY HwWʗ%~7#HQz<ȗ?#%,HwyJ21ʂHBDu+e5%lZk<~|G}snҶ- ]׎yĈ#F1bď"1?e2?;9 DJ8hCiCJ zI)^%vJ_f!U,+R޸ɗx6pu0:ZR{#9O'*H n!"L]JNwrδ,xSP3:bqFNX!`-eNg?hX> w͝C]cB1>?a9s?/|W6bR!T7a>/"SD J/h:#SϽyp4R)ތR+hl'F<Qswmo31%u-cތ)/8_!. Jnm4ﻁ98<AY8:i1%X=^?qIq^Ev )M?=j0'̄ )RM)5et9w>'&%"RXA"Jô9hΊ1:\њᅦ kGޚn!bZԵ< W8jT<|0%EФAlB)bsB¢bI(>ҹ )QB"*rvv4u$ pPj@$A:iA&@¹ ׼C}HqtL&s2ɌG<>["=T=CЦ"z:SB6*ngggx/n/ʜ"O8_cPʲ, hۖ䄺fawR`Wp-c9b*eY0=/c.GyĈ#F/W;GQa66RF{efO~H~H״D~ -#)BAؖ^|]0&B!_ǩ%li1 f= Ĥ儺1GC\I:55XP5JHqBlV&' Mg/H!oD]6ZLjHU`$Ili7H0i32!:K:@wk%3'g[ڙOzNjS&xyı5ܾ{Ã[4D;$^SJb#qw@1;w%(mf=T]~a_YRB"t,溳,dk;mȴjRͬPfeR-˩g3A H$x!7D(}n'H'-._;rNrB·.F_y|߫ޓA7j~V;yU$eEK{%M)\ɉQ IDAT,&,)\r`O4S>d`wCzͻZazm-eeq QQ "K?ҋ۞iA=Gi{B:&t(-2ܒC ^W.9BGV@s?Fc78IQ7ܬ5f:g>_p>EQMK5(_U{ҕI"$"|^ĿsjπDRʼn\J3־VJc5/XL1ENEԅ{`lt ̑m'chI4;V:4<0؅ dv@vHv I˷T/gڮy.G|uQ jBL-pzvbU=#F1bĈg|^Lk/oM%~W۷gE uiGJ-ֈD,,7T穛5덐o:Y{#?&^O[.7LR]wiw.yH 1 )Ipḏ\uTX^3##W 840?](nDl$8NR[&"Kn}*ټfYGx_pxOj%nRRL"mRV8nH)b"lMګ%CJ'*ٶ{ANSo.jsnuiNm {ȹ-a+=!)SڔzB^|P ȶ=X^DR ,I'鲸~/zv1#F1bĈgdsUBp~~Wƽ{{E͒zs5-Td¬kWty&yQA$ejrQӇ'*fBo]p乫\.ϟb*{#8% ;f@ۙsmnUqYetg%gnG5AwA]},_vk.6bKQN[ictUs~zw9<'ut1EHmې% >[m v䝗T,/X~9w3{v%z -1b'kWeŤ*YLMs=%/۷]W356]vmu\z\PL'e{=/E A=rmQm fÂD~˯ST"ʲ$EvXvEcn5)89}8Ź6#F1bĈ?˿2EK~7ߦm-WFRdRǏZ|mrFbq9~>HIZH(+UN6IU1,'i1];J"~0,4 XV- 6D˳ys y6XV^:u`SC9Q޵琷-se*u=%;R;jdKSl2AnzxzbYsc&7x<4J^b&<|U 4<+iJlcޑwiv{-B)ι<{lVyf9_T HfXT-ͮ ^sT}u/E~r51,Qd%.gR46mmH!.`:{}?^@p}b1'/*~/|wH5)H1yĈ#F1⏃4/XW-mx'Qkӊ5mAJ O:Jgn٬b,FBq.b? |&EnVnAFyvRSXO z8pcqDC+r&EsyM s͂#;Vj'9,Lz2Y]fޭ 5AS^_!ΡL@WiqIOYg=*O59e(8ȺcuK{4YO4YU!jm+>x] E&]3}e niAY&慛Deðb"aqbC=SNS&m,94 "XWYo6MRHXR" Z9D4m &l8q.Q1qi"c9.[SFJs^5eH)BQ ]j^3UpHN!s/g̟PkXwh1bĈ#F?w7s¯w߱\'y#ipmCMҵ U+nyO.Ō[w^iIfJЖ#ڮF![_Z}J*`BelʐI 'E%B06h[<1L.O8bυa`[2Ag")*MF2;3)w @T"dN#mp.$1/nxhN)nI{. {|X, &0*)rxY^(LT,k3ޣNhۖ"GsOfbh[ۮer0JRr}YOwU{55{Rǰ>L)@E3/>d ݖ7"CNN !Ɔ*[AI#hNv7Px_oE~lN]m8HG1bĈY9+_7uwwX;|+GҼqJ$"fZV<ޕt$xWr+$(>9&ASt^/M=, j &;W87#ž(0mHrM 3%atIԑe1HN6wP f6]ꭚzkتƐey 3Y!P6ދ94^rlݝ{^Uw Lˊ476\3g~l-I!m#͚Ist2R'U8x*ةOe[UeKsIn @(.,՚:]\gLјv%+^Ḑue9TK( OR\H,A4]ZEjC IEӬpQUaP\{1:\pn{E88AD,:'rNHMWg=)֤8zRUKVbŰ0hx@#{H^1 Bkx_jvI2+XK5hc˯ŸoKLsuCHG1bĈ#XI|o~WGh[; ls̠m>@$PùVVPV?>eool6# Oi}fC@MI1_t-9{KMP)& }E(h뚘"nܢ 9_6RgQ!i:/K>g )E0IrbʊQ1`D`y@-]b5T6jǶKw3ҋuIot7ȩ";9'g޸yQrtի"#[qH$`'M%& BBXYBH ,6ݒlƲvk rܹMz?ϣǞ3|Ϲg{ja:z<9l xP-@@=+<|(P~x/'@pyy|deea`` \ JTiHh_E,m|( sN {hZp"ln!uP\bΝ d) PU?dY* @Qp8 n:¹N:*~k0?I a~$n׍[ө`ۡ()y};쐭Hb>> AE}sǾsiYq{F\"Y ]A'YqCQ `3 @QUd+lA7Q9M~uP *|>z{ $Q>o fB!Ds]]s&V ?[z. GgUT?Dl(xq"ɪB(bpMjdSe;$Q^`ĮC;d&]_!I66l6XVbpp@-pحp :K!Yl-AQTP({#v.Xd~8խkrCfsj#?BQPn*Fa(sBG^W=4z./ {nІLCqHL@p$6 @fE+ .J aem (zG@U18E^a>DQ©S`?^C;bc/pmdYF 9cc=8~#9r˲<|ЮʹsQd";Uǧ@Exy`eEY1&+Y$jx.MCu> n Nj=?Q ӆȲz.c\."~7P|EՅӧO# 7\kP`7 QV+/|^??6 $k+Q@dUQ\\c' *T5:޿0ePTr!7ӧOƉF__﹎(>B!$|+3`x≭x[ߺ TyTXlv;N;^ (tDE,[P`f#?_(Y1Cev;z !e;D9y(o% U_E@Up 7^!tgY$QXUscqtBTwl6+# |*rsI%uP<kQ\_m[m "5߇{j HtJap8U n<'J(NSD#Ee>}';1sgOGˉuĉqJUTTBOODIIQZZaQڊ2CeL @Ntvub``'OGp:0o<4L>ύ\ٳp8(+-EKK+\ljbxBnnDQMy&deeK. v{aF]>|>?̙3ffcgk+v܉>818F n(Y6,]w ~ӦMSp: Ǎܼ\=sOCiYf̘R\٨*6 V>x>(6TU>~B!$y8w6So_ a&RmM,$$NO4teAz}Aފ;6~m)|?mVt>=fDi`&BȘ$ KNivax<~w<\~y=N˘Ɂ-,BL!7@,_\6B( !B&. ^M6n<~vtg XB!̄B!cUœ9Ckcm߯ۧ2B( !BhI\|g>l6WoǗ܌|"E3!P0B!A$IAEN<zoFCCѨ7w4՝Y~DKGg}O'CK:G3!B(DLT{, VlU-p9:,J*bTB*+Z:1V:t9B!$h8l|+3eFXTVBaG`&BI0 :w9;EENu 9 G>,G G4,p  dB!h9p:-xэx6x|;palմ$Fޏ%4C݆^5#W4hS fB!rYƩp:->ڵ+ q5p:-cZUܑ0SiKO@kM(p#B!d 7\UoG_W_=VRf:+T.SBL!b:. $ȲGـ͛; sXuQī#vF)ى  fB!Q4_s$8<_?:x<~|QPȸ4qR8qhWt#3qNvxP0B!ij#faҥSP\9㨴kmntIcN-~ydxZfe#B( !BHXv\R cx [< dhZ82~?q7< .Ra̙4z)#u h2-P0B!aX v ]oãnw4:79Y|45q!dB!E¬Y tT~ۂ+apЇo~s6&N,(f9ܔXS)q IDAT+Fkj} B3!BHZ!&N,]w͆$ xX>ɓ I I0jD+p bUkW=8u fB!1/oΆ"駷vߋhn.,sU!P0B!AA@mmYζ'Ww߇g*PBL!26Eseeppspa5v6Ӝ !̄B!*KJpMMZ%10p饵p:-4!P0B!M җno||>_W^9B2]0`M[enB!dTS[ǒ%X7S Yo$t !B1^8u عy>n]]pBH !JB!$>X$~ر--N45++QXh!$3!BCƢEp,xxX"VAh(B`&B{lf,.bǯ}~,YRrE3!P0B!ц,bʔ||k`JxcxCx,]Z,fB& B\$I@CC.ՉxvZuAQTB( !BƮh?ޅ[o믯J;zj?;@B)6l:!BF ZjJVHU+x/ee$1!H<4isB!{@\@b„**z[g{É\ \Lun Œ%0 !6bضE{M1c:koEl t}xVҋR.Uf}_Gnb ֹ܌̄B!P޲e#ٸidI(.v$.- !s^065 X:ԝgixFj(&VhMkmmBHz6JKqD[uࢋj0o^%V)rHkf4MZҐʺ?~6ڙoak:T5R$lBH4ޔJKpFh:rP!?,DˡߢZŲZ0ۖ.?#+Y dֹ)n%2HHCŽ.,?#݆s%>3^=y'zzOkafΤMnƍ;q&<ީ,k|՛9lvyVz ^_Of5~FEY] mmBFPUyUUðE~5 5*Io]dt6 3S:< Mt 3KiKv #NBmi"װճ2D~L2޼jD؅ee{,mB҉)mm1ݤdYL>xLNkdvֹ^0!eʏ0ETHVycfeke.|+:!iHFgc8LB3DtB20]'ÐQI*d He{JHafNV&meR+Cl{3P0#!며a4.,1kZ1llgb&nEZgn*Ӑ-bG:XBpHׄy/Tt 3ЍbCVkobHj=լhyee;6!EQ2*fp"=:V^wVu<赹Q_o~h~tYYӵl2Zio?Q9ZjU"F|k#qft6 3'D7bK60×LsB0B!&<ˆߍWizfV^hH [&;TԹ)LIlB!r>xhkkE}Tnٲvl !aa;BI4lBHzm[ x~C.[uu54"5VNH"5kayf${zYF!LZGV6%$Ql޼ِXnkkŬY_a&B @! #̄B!)U]BfB! ̄B G !B2T0/k𗿬Evmr 'Pc4Mzd'xӚiH_dfBGSEI?vǺNX-ʞ#e#ad4Ǻ$ 0B!d`QvXVAE&[ś&B؀#̄qF DFH`NuXGxg^XaIQ ]QPǦ u'ϴkY0ė7pB!$CڵcG]gOWAk p~[Gg?#*N{3=i/bXd33!B_3+LBXdfN&T4qT1zDÊ1.!C(ٳgXft-CQg+HK,??En*o>xl@HV^mZ ܄ fBfDQnGz/bVq72Fν^5͵A4)?Xy7HҥNb#BͶm-x lr fB$IFZ8Dw8c R+If\cM,hڵ ze6̙B1.G~xR0BR@]QDsKt&kh*PhZ!X^KGҩxC2I`k;;Ǻ&bMw( !iG)_v2UB`N|XfןX[KOkFHDUm1V[-G6``FWֹ@0GzJu&UXB!lm^F#}|Kj7w+$"$5u7JH%-BI 3:DZ?#a$rʹ ?O# ~B#9œA< !BhnnϿlLˣ-E@A"B(M6޵+F*th2tms#aټq1pn3Ck<ŋoF[[+w˖ێ7f)9Bk5)7JgHVzeӯdZwҌ8뇖 ìY ͛7#UzfTdSO#U+b:I >ӳu&aID斐L`hP8/ԍ #ZŠ&\…]3cԞ%Z+'=qT>c͆r[[+f͚TAKk }5h;OClkIvhAE_UT)#gF'Rzލ^o|3 vetof#7sdaֳSy=0ֈzҒ8O#DfI< $qS !DX$܏'L~J-Zin$7BS| XiғDxO7o6,g͚5cTO3b&\L! F9NlKiݤ4fؤ0&5c}[z]3YE1ڬ7,t ^ eJa&7SoXDe-#̄4DW]uwC[G;J)g)zG !$m=%#ILI HqiC)"JK6n؈8gTa-^şdݬ :Us> LC㇉B2[c۶<[l94qd4YF0FG&Z{LHzLE[ #ƑD֓?uun<pglK˹\~*xpMVAh#xJeFZc1G>i23B,]ztCzDP[h/p}O;j3ic/y-<%ܾ3:7X) ?p=ZĪ't^w4GBF@`|xWWnc}sNz(FљF]؞"VR0pH2 k !d`N}?*^+mdž-:9Ew<5yGO/YO3Yp& nF d\㭴'NZn[uP'ky,Dv:wL t+Sy`M>4<Һt+in2ZoyMn;ԉp߫DmޕNw3"=2`-mKxP LsS*N62]:ҵ)cxugI;&Vhyon82P,Љɓ0~%.(*rf ɰǣUU h9'mDON_Sp}sNhz>3+hk1O^F*'F\ūB2g= 7׆njB{in;ΞԩAlt 47aѢj̞=y˳CE=l4}^UՀ]Sx;pDwf2s# q `)ش(sϵ߇"\tQ5ϯ”)(.Fa7BaKL!$sp8v,N 4K4bҤB\قv^yC׍nj­NҥSmqYӎ[c۶غ?3goV_\,N&EQ>9ag!?c\ fB!Q>Hq\ YÂ9s*0n S駷$|=߃n/~\3ww/9{{[m?>)ƹōHio?L#B\ fB!{6#(*7܄ .(ªU-xxص_r3_\ٳ'cX06o>{sg'^}/pa5.BCC7 # ?w!ҙZJr3#svoгp ZB2ARVR0B1UUqN fPPдAWV T2&bժ_G]X E2&+q)|GXn5G 5+8e{rBx31mZzưXs?%vGKZ!$u.3!f{>QT6$W2 EXby }t#v8[oK.AAY(*rbR| c n;֯?{⋻1qb.0xsSS)ʲpȜM7޲e eUU#XeZRWP :7yu.3!+8~^磠.rsz䢱/ oՆ{pSdI#Ə/,p8,EE V n87e;wvb۶X:x…U7&r6I:$cMy*4;;!s) !/+(+FN͐?COs\45wG6`.~{3.V|hl,g>3{vcÆx#hm=w9k2Ssrl<ۙ&ݏ81KXa'=!u.3!㣏z(-͂a1 (*rk0qb!{Wkp-p5QYsdUBYY6JK0kV9/nDK [wž}O^Uc;as6]H/BSc‰6k !s) !~tw@gEe$Nc,L-3.JwԹ̄B"Aw V N (-ƒ%ʕ;Į]f|QVvj$˳#/ \{w֬iڵgO7~}0~|n6}z**\p:y3 xSǎǸq>رnFX=do: ȝ +2.O<+ǐeb:3Υ`&~9kKx$>_L44⩧a͚v۶ǦM+]T9s8QؘabT|xf'N&Kf)hFe+BHX<::z(*ƍs%-<;jKqsPRjÿ;x-8pGwFaӦ⦛~/ hQ5<\{=ॗv;끢𘛱 ihah75sUkmbITw'|cLs9L!$,n'OJJ9RJVSKP^BSS)~z;֮=cnvOi{h9s*p 7eСxob",ZT p(,FaY0ItT#z64r?86jwx>zISM"m.'CYlD;F2Rf3BHX" EJzA@Q^; c^ Wž=]ig'eh.QmE0]VCNcƏض86l8?‹/ČXf.996NE(B#d*$b-)5F+lD_k>Iw<%\#믍kgJvԹ̄B38eCR &c2daҤB<l~Gq-0sf9,o6uj fv78 &~'x.q#?ߊ.+UWb,X,6ȑgo_/zz|ĆfCccƍ#+KN tvpH֬@APY eeAl~\Hz6!|R&57oNRG!>9!d LԄ[ZWpH?P,V+PS~;6]Ncnlރcեr1o^ Q]b7InE!x NBBx,67Xlr;m}1cF!\.aK˂\׻pEhk֭=.wן]BSS>f.Bcc.˝p8$nF!1& @܇@ qbY,"=:؄%KjQU>Ə~Ԃ`;|r֭;*ܬÿ;&qts2 $2LˏHykv:5$~8L!q6"{l\eIhlEi xvŞ=gdI-N̓Ñϟ( p:eչPUyqp?v8siу;NĎi1wnLGeYY2v&Dl>#.G""#:3!7TxpNb{F, TWg׎p  _%Ğв,"?߆<+&O嗗c޳ز1Ys55٘1fb\aKGBF#*"$ByVq6ZzmU4kM n=Z쭷\EKg8IK fB!P˃~?˳fh%LV2&MƮ]q9/| ٤xM¸qN90kV!Ν~}'Z[O^}1L3 0sf!jkkFaZQ$QW@ pc 3--cQhnbNb(zXKĊ[4-'Clݺ۶$C~?9߯Ȏ\KƦE;W&Ҏ;_>Cxq-.Fa.55Xa˖nl؅{'qc**6-f1ls0B"XG),RHaG]Ԛ6U]a`JtN$3^Z㢥EЛz5`&$!bL>8Dm ?EA@n#rr&SܹEt!r6uUaLzVv0eJw֭ضС>vjk1gNf..ڒ2:N8-6^і1[3Gu2ֶfқX!!_u6"`޼b|{ӱxqMBcJ,:_R-i/^}0߯Q[+(wOƿt#.vƯ}?v<`+z>XB =S-2--5☮B b#b9M@6R} ;o%%v ¨c%: {gP^Htʲ\+rr,81]VbӦz;FCCen FHiZGh 9RGnFB8Txp~Yp(5G1=-~Y'MH孑2V6d#]g} |:GG77؏.I{),=\&im݅]OڈSG]{3( ;ۂ ]ziDQ!1/ .C% wa&̦0~|hz?Dk$̶ͭ]:-2!=z涭xPVZύ]GwG}ekŞm+~GQ]QWZݖ70e x__7+$IJ}OO {ݷX1?M̪Vp{hm݅(rN}EGYe-DCKvxSf!R9020CQƶmD( |,.>ZtLˉp wŦwV}n§4wᵸz{g~f,^|q%|U*W@Ζq/Gn{QUUEW.2'j:;qቿ#֋nJws)eZQ|_(x =A_jO5s}D|HC&vd&@!dl] ~Lf`4BQa6pnƄiqBRUV^\0'Μ@?B:t@uB|u_c }8vcgôӰ˽]/"O=x s=|Iu]ãͣY0k[N-0+ B@<~|'Ѯ^82UMh"WLˑ]gW? Ndezr5b}@W5V#ln*mȯGgJ96D tuۍ5Lk{w@@G_0B8~gJ_AWoWZHG=PZ:UUϛ_ӧOSO=q_,SI 6Q%C0 -+<6!Cҧd2-d{#-ZɔִF*Ώph"\Csˡm;No€43g| ~T|ЏAi0aSچ|6}:/:;1`HlP_F]C8gl?҂~qk7%_GYaE`ܤJ?_~{YӜ68o(\ZoT<裐e=`>?uhuMV_<0tR1B!cP0+֚h Hz6pAiQ&oJj 5OG| 9!#̡(p< +$ f~S!̑i&83i4Dv$vW,ۿix @>+A dJ.ى#!Bk#M9Vm.nz%B`WڱrрH ¬[okp} 1$UYY>"D*vsx*N ّ.[yMkrU18v?p\,*Z$Qؑp%jVz!b~{>N˖-KXҥN2lh /7POzvYmz/̗c)ZՆkO@1YOؘ' f+p;j}'}=3z46.Zݛw f 8Rx <~q6pFWD8w(%lh݉@ӟqXqQ,6vJO양nϻ:W܎7}9ebh}4i#<2vYjIXn9!9sƋkObq hn.ux#xͣ1wnN#dusL+lgl"no+4Lw6l>1eHxgtbk:2HbrZhυ[SO@FaF<܏:)0V@IOEʼn⥗1 \җp㐟oń 9(-aNE󥗖!?ߚЍ# `$[rڵQqgn,|U`nu"G##W_ fkn7W#[% .߇{1J f[ExT|h)YuRa~ +~w>\xa nf";(-ukP\lǪUmؾ~=tkP^h&̄"|E W(¿]ĤB㑨/.aB9Zg ?}? !dvm[} ֝,*|hhe˂O}Vl6&̄VR=j9jL!$oGcҤ,]Z.+GAAȲ,bҤ|PXhë;ti/n؄ fOL!dCWno|>+M7abdei (* 7Tb;} [tˍNj m\L( -477G%ի_CssO !ьk֜"sXɓs , mg+QP`ʕmغO>NypuUQwBLH1caa(A>O !ш8}ڋ5kNJKq5_к\\|q)xكXy 'OdI-.  7#̄ ќJQSB!&(*k/A44O{~&VGAg:3gnf`B!b|>/ƛo@ `:̙Skf!?ޅnb;^z֭;g}z,ZT+3P0B!BR6ubN`C땵"˝X6oOJ)m)v](ChKP F"91` G0<AQ)MQAJrKA-{-awvvKJ6ٙw07[{G7ovWƪ( n_Ӯ]-:SO+/]:A F/ՈڵU'Nthǎ&]Po79ÕJhxzw*+ӪUN-\8Zyy1o6,MV~~[wWUSӦkjjO9GnҲe\9JK_3,0;UWժUUTǏ=jl6>ܮ҂{^ IDATzSI8++Us*77]va`3fTff*UW_`ӻ!bGtI:qBjnӥ2˺|9ƌfϖNJ锲8tfָf_hF:r>ݢ?njPzufjk۵{wZZ̙xaU{}e8V{C͘1Ro51nWfi *(矷vhҭ[ZtƍK? `Wsgj„aZoZdƌcIC4}z֭+Q^^jku}uu 30y^]PrOfԪU.-XP#xMwߝyFiذtdR(%%E99;PӦc5sH^dRQ3erBo#eg?4669t:TY9')kibԔ MSnX,jKMfA`MKn]Oݻwⅰrr\_jKMf$vkMڻވhHZ^^':E2^S3@zښ+}u)٠tp 0$х.A-vjKMZS3/GXyHm) )mٲM7ocuثb9*{f\KK}Ljrl]kc`Xţf5wmqG4f`.{97i 57 x>mgxp]F~{KƉP-l޼cDZ8N d[]oÉ| yK3ub]e]XIfź ܒ `ľ[l1lawrZ9_l 4L%%n4} yk\q9f'vm[Z~bu BMFfe8aƪf`[Z]_?`-ҁr|G>ţcH9Z-v\76~f)Sf_R2wظom3Sn~/…$IS~iӞ y?ns?le ڶx38j-Vdlc@ 3@n0[a[=d:m> ?iJK+B52nSPW SXaV( df 0K`7fO̎zk!nc6'Iڰ= ֍V>wJK+tɠ,-6&۶h'YmOkX` uX=-V55ؖuh@ ݇J[~m_7dO3ן*+cf\Bmfm[mmxP }C#;͎Yu҇ N°vmic-p<+!Mzu>4 Znam_w߂m[D9.Ԗ֚Ю]{p<[www MP3 Diags - Folder filter

Including only some folders can be achieved by this filter.
MP3Diags-1.0.12.079/doc/220_tag_editor_patterns.html0000644000175000001440000002316012040502152020534 0ustar ciobiusers MP3 Diags - Tag editor - Patterns
MP3 Diags
In addition to tags stored inside an MP3 file, song information can also be obtained using patterns. In the Tag Editor's context there are 2 kinds of patterns: "file name - based" and "text line - based"; they are used to extract track information from a file's name or from pasted text, respectively. Information retrieved from patterns is displayed alongside that from MP3 tags, in the "current file" table. A pattern is a sequence of characters, the main idea being that a '%' followed by some letters is a placeholder, corresponding to a field, while the other characters are used to separate placeholders from one another. These are the supported placeholders:
%n - track number
%a - artist
%t - title
%b - album
%y - year
%g - genre
%r - rating (a lowercase letter)
%c - composer
%i - ignored (there's no field that would take this value)
Besides these sequences, there are usually "static text" sequences in a pattern. An example: consider the file named
/music/mp3/pop/artist1/album1 (2008)/02 second track.mp3
and the pattern
%g/%a/%b (%y)/%n %t
For the given file name, this pattern retrives these fields:
genre: pop
artist: artist1
album: album1
year: 2008
track number: 02
title: second track
Note that the matching is done from the end of the file name, so the beginning of the name (/music/mp3) doesn't matter. The pattern would get the same fields for a file named /pop/artist1/album1 (2008)/02 second track.mp3 or /home/user/media/music/mp3/pop/artist1/album1 (2008)/02 second track.mp3.
If a pattern contains the path-separator character (\ on Windows and / on UNIX), it is "file name - based", otherwise it is "text line - based". Besides the source of the text (file name vs. clipboard), another difference is that the latter must match perfectly the text, while the former may have errors in any of the strings between consecutive / characters and still extract some fields from other parts of the file name. In the example above the pattern %g/%a/%b {%y}/%n %t would return no album or year, because album1 (2008) doesn't contain { or }, but would still find the genre, the artist, the track number, and the title.
Both kinds of patterns are edited in the "Patterns" dialog. Only valid patterns can be saved. Besides the rather obvious % followed by a character that is not part of the placeholder list above, there's another condition that causes a pattern to be invalid, namely 2 consecutive "unbound placeholders": %n, %y and %r have a fixed format, but the rest are unbound, meaning that they would take any characters as long as there's nothing to tell them where to stop. With 2 unbound placeholders there's no way to tell where one should end and the other should begin. So %a%t is invalid (as is any pattern containing it), while %a-%t is valid, because - is used to identify where the artist name ends and the track title begins. However, %y%t is valid, because %y is a 4-digit number.
Patterns may have optional parts, which are delimited by "[" and "]". One optional part may be embedded in another. (See the predefined patterns for examples.)
Some reasons to use patterns even if you find album info on the Internet
Your file names may contain more accurate information than what you find online, especially for genre, year, or composer.
Your may dislike the character case (upper / lower / ...) of what you find.
Your may want to adopt my system of including a song's rating in the file name: I use a lowercase letter ("a" for 5 stars, "b" for 4.5 stars, ...) before the track number, which has the advantage that it doesn't need any player support (as long as you play files from the disk, and not from its library.) If I ever move to a player that supports the POPM frame (which is where the rating is stored inside ID3V2), I can easily pull the rating from the file name by using a pattern.
MP3Diags-1.0.12.079/doc/140_main_window_tools.html0000644000175000001440000003442612040502152020236 0ustar ciobiusers MP3 Diags - Main window - Tools
MP3 Diags
There are two ways to change a file in MP3 Diags: saving ID3V2 tags in the tag editor and applying a "transformation" (or a "transformation list"); there are some configuration settings that determine what happens with the files when transformations are applied, and, because saving from the tag editor is treated internally as just another transformation, these settings also concern saving ID3V2. (Well, there's also a third way to change files, the normalization, but that's done by an external program, so it's a different story; all that MP3 Diags does with the files when asked to do a normalization is rescan them after calling the external program.)
There are more than 20 transformations that can be applied to an MP3 file or to a group of files. There are 2 ways to apply transformations:
  1. Pick a single transformation from the menu that opens when clicking on the "Apply a single transformation" button
  2. Click on one of the four buttons corresponding to the four "Custom transformation lists"
Normally transformations are applied to all the files that are visible (well, or can be made visible by using the vertical scrollbar.) However, if you press SHIFT while clicking, the transformations apply only to the files that are selected. The same can be achieved by clicking on the right button after clicking on the left one and before releasing it. This is similar to "rocker gestures" in web browsers, about which I only found out (believe it or not) some time after implementing this functionality in MP3 Diags. For the "single transformation button", opening the menu with the left button and making the selection with the right button does the trick. (I assume that left-handed people already know that "left is right" when it comes to mouse buttons.)
In order to reduce the screen clutter a little, not all transformations are shown be default. Those that seemed quite unlikely to be needed are hidden. What is hidden and visible can be changed in the configuration dialog.
Note. When you "apply a transformation" it doesn't necessarily mean that a file will get changed in some way. If the transformation doesn't make sense to a particular file (e.g. trying to "Repair VBR data" in a CBR file), that file is left untouched. So even if the transformation lists contain many transformations, they may still end up leaving the file unchanged. The lists may work pretty well when applied to whole collections, because they take into account various problems and only change the files that have those problems. If you want to get a list of all the transformations that have actually changed files, you can make visible the "Debug" button, then click on it to open the Debug dialog and enable "Log transformation".
You can get an idea about what the "custom transformation lists" are good for by looking at the default values (either by hovering the mouse over the buttons, to show tooltips, or by going to the configuration.) The point is that for some of the 20+ transformations it makes sense to apply them sequentially to a file to achieve a "higher goal". In the default configuration, the first custom button fixes the audio part of a file, the second takes care of the ID3V2 tag, the third cleans up the rest of the file, and the fourth is a combination of the first three, the closest you get to a "fix-all".
I think it's better to use the first three buttons, rather than the fourth. I feel more comfortable this way. Personally, I like to review the effects of some changes before going any further, and this grouping seems to work best for me.
Several points need to be made about the custom transformation lists:
  1. You shoudln't blindly use the default lists. Try to understand what each transformation does and how it may affect your files, then perhaps go to the configuration and make some changes to the lists so they better fit your particular needs.
  2. Review the order in which transformations get applied. Sometimes it doesn't matter but usually it does.
  3. Look at what the other transformations are doing, and change the lists to better suit your needs. Then test your changes.
  4. The same transformation may be added multiple times, but usually there's no need for such a thing.
It is possible to right-click on a cell with a note or on the note's column header to get a list of possible fixes and perhaps apply one of them. The way this works is adequate in many cases, but far from perfect. The implementation can be refined a bit, but there's the more serious issue that whether doing something that makes a note disappear can really be considered a "fix". This is something subjective. Another factor making the right-click less than ideal is that usually it's better to look at all the notes instead of focusing on any particular one, because many times one issue can be seen as the "real problem", but it causes several notes to be shown, and focusing on the "wrong one" might lead to confusion. So I would recommended the right-click mainly as a means to get familiar with the program's capabilities, rather than for heavy use.
Note that to apply a transformation only to the selected files when right-clicking on the header you need to keep SHIFT pressed, or to make the selection with the right button.
There are a number of files involved in applying a transformation to a file. Besides the original file and the modified one, "comparison" files may be created in some cases and "temporary" files may be created too, their name containing the name of the transformation that created them. These are disabled by default, but may be enabled in the configuration dialog to gain a better understanding of what is happening, or for debug purposes.
MP3Diags-1.0.12.079/doc/120_first_scan.html0000644000175000001440000001050312040502152016622 0ustar ciobiusers MP3 Diags - Scanning MP3 files
MP3 Diags
Each MP3 file in the specified directories is looked at and analyzed for errors. This step can take a long time for large MP3 collections (40 minutes for 9300 files on my ancient Athlon64 3500+), so, if you just want to see what MP3 Diags does, it's better to start on a small set of files. (Another option is to abort the scanning soon after it starts. You'll be able to see whatever files were scanned already.) The results are stored in a data file, so the next time you start the program you'll still see the parts of your MP3 files and what errors they have, but you won't have to wait for the whole collection to be scanned again. (Well, if your collection is significantly bigger than 10000 files, even loading data from this file can get annoyingly slow.)
MP3Diags-1.0.12.079/doc/145_transformations_list.html0000644000175000001440000002517612040502152020776 0ustar ciobiusers MP3 Diags - Transformations - Details
MP3 Diags
These are the transformations that are currently part of MP3 Diags (note that some are hidden by default, and you should make them visible in the configuration dialog if you think you might need them):
Restore flipped bit in audio Sometimes a bit gets flipped in a file. This tries to identify places having this issue in audio frame headers. If found, it fixes the problem. It is most likely to apply to old files that have 2 audio streams, but even then, the odds of it doing anything good are rather slim (but it shouldn't do anything bad either.) I implemented it first for a test, and I decided to keep it after seeing that it was able to fix audio issues in several of my old files.
Remove inner non-audio Removes all non-audio data that is found between audio streams. In this context, VBRI streams are considered audio streams (while Xing streams are not.)
Remove unknown streams Removes all unknown streams.
Remove broken streams Removes all broken streams.
Remove unsupported streams Removes all unsupported streams.
Remove truncated audio streams Removes all truncated audio streams.
Remove null streams Removes all null streams.
Remove broken Id3V2 streams Removes broken Id3V2 streams.
Remove unsupported ID3V2 streams Removes unsupported Id3V2 streams.
No change Doesn't actually change the file, but it creates a temporary copy and it reports that it does change it. This is not as meaningless as it might first seem: if the configuration settings indicate some action (i.e. rename, move or erase) to be taken for processed files, then that action will be performed for these files. While the same can be achieved by changing the settings for unprocessed files, this is easier to use when it is executed on a subset of all the files (filtered or selected).
Remove multiple ID3 streams If a file has multiple ID3 streams it keeps only the last ID3V1 and the first ID3V2 stream.
Remove mismatched Xing headers Sometimes the number of frames in an audio stream is different from the number of frames in a preceding Xing (or Lame) header, usually because the audio stream was damaged. It's probably best for the Xing header to be removed in this case. If the audio is VBR, you may want to try "Repair VBR data" first.
Pad truncated audio Pads truncated audio frames with 0 to the right. Its usefulness hasn't been determined yet (it might be quite low).
Repair VBR data If a file contains VBR audio but doesn't have a Xing header, one such header is added. If a VBRI header exists, it is removed. If a Xing header exists but is determined to be incorrect, it is corrected or replaced. Only the first audio stream is considered; if a file contains more than one audio stream, this should be fixed first.
Rebuild VBR data If a file contains VBR audio, any existing VBRI or Xing headers are removed and a new Xing header is created. Only the first audio stream is considered; if a file contains more than one audio stream, this should be fixed first.
Remove non-basic ID3V2 frames Removes all ID3V2 frames that aren't used by MP3 Diags. You normally don't want to do such a thing, but it may help if some other program misbehaves because of invalid or unknown frames in an ID3V2 tag.
Discard invalid ID3V2 data Copies only ID3V2 frames that seem valid, discarding those that are invalid (e.g. an APIC frame claiming to hold a picture although it doesn't). Handles both loadable and broken ID3V2 tags, in the latter case copying being stopped when a fatal error occurs.
Convert non-ASCII ID3V2 text frames to Unicode Transforms text frames in ID3V2 encoded as Latin1 to Unicode (UTF16.) The reason to do this is that sometimes non-conforming software treats these frames as they are encoded in a different code page, causing other programs to display unexpected data. You need to configure the locale / codepage.
Change case for ID3V2 text frames Transforms the case of text frames in ID3V2 tags, according to the global settings.
Add composer field to the artist field in ID3V2 frames Adds the value of the composer field to the beginning of the artist field in ID3V2 frames. Useful for players that don't use the composer field, if you have the composer info filled in.
Remove composer field from the artist field in ID3V2 frames "Undo" for "adding composer field." Removes the value of the composer field from the beginning of the artist field in ID3V2 frames, if it was previously added.
Fill in composer field based on artist in ID3V2 frames Copies to the "Composer" field the beginning of an "Artist" field that is formatted as "Composer [Artist]". Does nothing if the "Artist" field doesn't have this format.
Make the largest image "Front Cover" and remove the rest Keeps only the biggest (and supposedly the best) image in a file. The image type is set to Front Cover. (This may result in the replacement of the Front Cover image.)
Copy missing ID3V2 frames from ID3V1 Copies frames from ID3V1 to ID3V2 if those tags don't exist in the destination or if the destination doesn't exist at all.
Remove all ID3V1 streams Removes all ID3V1 streams.
Reserve space in ID3V2 for fast tag editing Adds extra spacing to the ID3V2 tag. This allows subsequent saving from the tag editor to complete quicker.
Remove extra space from ID3V2 Removes large unused blocks from ID3V2 tags. (Usually these have been reserved for fast tag editing, in which case they should be removed only after the ID3V2 tag has all the right values.)
MP3Diags-1.0.12.079/doc/270_config_custom_transf.html0000644000175000001440000001026112040502152020712 0ustar ciobiusers MP3 Diags - Config - Custom transformations
MP3 Diags
Read more about custom transformation lists here.
See the full list with transformations here.
You can open this tab if you want to see what some transformation does without pointing the browser to the documentation page, because the text in the "Description" column is in most cases copied from the documentation.
MP3Diags-1.0.12.079/doc/COPYING0000644000175000001440000004313111200232050014247 0ustar ciobiusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. MP3Diags-1.0.12.079/doc/210_tag_editor_assign_image.html0000644000175000001440000001146612040502152021327 0ustar ciobiusers MP3 Diags - Tag editor - Assigning images
MP3 Diags
Just because you downloaded an image, doesn't necessarily mean that it will be embedded into the songs from the current list. The assignment of images to songs is done automatically only when downloading full album info from Discogs or MusicBrainz. In the other cases you'll have to assign the image manually.
Note that even if you can't find the album cover at Discogs or MusicBrainz, once you can see it somewhere on your computer, it's pretty easy to embed an image into MP3 files. If you have a local JPEG or PNG file, just copy it or its name to the clipboard and click the Paste button in the tag editor (or press CTRL+V.) If you find the image on the internet and you can see it in your browser, chances are you can copy it straight from the browser and use the Paste button. (In Firefox 3 there's a "Copy image" option when you right-click on an image.)
If the songs in a directory are not all from the same album, you may want to select the "Picture" column in the current album and the click the "Toggle assigned" button, to avoid all the songs being assigned the same image.
MP3Diags-1.0.12.079/doc/screenshot2_thumb.jpg0000644000175000001440000002504411304162127017373 0ustar ciobiusersJFIFddExifMM*Created with The GIMPC     C   " W  !1"AQ#2Ta$BRq3brUd67t%5V&4CSc/Q!1aAq2"#3 ?׹*0">&-jB䶢VBP#}űM6̇SH=[[Ekhg&".ǖ"3z]F<'G*Vkqg(BUJߟ̾R]|/<%jdxO/eE7۞=QKQxf4) W #תcT?s_H>̪9 5)R {a[ Fkwb;!5@!U^s>*㥵( jPrn-luj#QM]?^mRz\)ww]{-t|`A^jԯ=d@)/qWoS^44;pV *Ju&!h:7H)$cH%M9J(%>k yonxpCoGk&VLގM~}MZ0\EN֔{aۺ;Pj uYJH*3z;_5]sN*1HBTȐKiʣʉJP: X$;9%^o~oucKjCoGk&VLގM~vi AMZQMx3R<#ɨ\ f_yL.faCKhy8%d%E`+Rr6Tד3*3z;_5|T:fvkcg V\?Ǥ,8֐7gKgKZ PB/a{ZĺIMTٗ 6,1u Z ]]F# "t~$PIՎ3Nr ث"C*A)N<> H6P:hiO9!a=anWl¯:;w6ĚX>*3z;_5 GS-:Rm#NRh6\:旔ܷ ޴v"o{\hY7_Xu4h-NjLW@RgFG^;W9"6MM]!ƿh4\G;qMh1Y1:%Atˆ(B{Fr] Xjvy4ǎ[U%϶W8]tiѪoS9N-Ocqi_a)kZ:;I~GE5.WYCKPuͮ}Y &7i9K)ŕV~ P:lRDo9* uHA/\!Vۻ| 8*yJUDu$<9I'e$Z" b=Ĭ^%B=X8d #xEW5e(ӳw%@ ~@IX &G4BRNvR]ZBZ̥*@ )VJ>euR=P@P/1 4 VSpi;k;c2Kla,H \7V跆-&[[,ePԈ*=Jҕ*t/\ :3 U M<җ8Ǵ.JO6{|(\'_Z! %vt736[K<*\:߲N7 =o֯x\KkڣʈRcT%+\:Rj)Մв6X%.ԵiK}CJ׵:~Ő 2c~6tU)&VMm׼-Zˉ̇&DP3D2JR,9ͥ$ _ ¡S؎Q G@Dg[CH;Gse(bW,)^_o ]^,=3gF:xڇ b걷`6ϝEAp\& i&᭛$܋:6NXOwd=]+G>a֢8Uj=bjat*=<4ZӮZK5lYSɫJH'/[#?G65ȑw~Tǚ{_ŏGYѪ,"ԞyϓBx`+Pw)$0Ы“LpcLSW{KirwYa?xZT+/Ξu)q*KNYPl@'twJO--/9~evUXŝFے3,u-+Lt: :I8V9DmoHDl7:S1K@@(4Q םa [{ "Ĕ[42zCPԞ$ k\p 9Q4EYq IHVs oPٝ! f9N9WR-!ZRtF$w 8'*QL )p]t'sk v~MnOnc0RkRt/mkQ¾_S +W[RU6)AurWĊF;\N6~"㞑e#Q<xn|[^dՖB)YK@&4XGW2!y~|~o"8H7n+اnJBgHHxqNE˺J\_y)616yt+;@TqQߞ3C2{I %~P4v#ej 2(fZX[!<4>]JA H"} .bhe%iX$M)blZrHGNu l(r#-R6*@` 9+~`mcZ>x ɦ ߒPINtcl>xس@. [tx#+ YjLեM:l;mId*M\ ذ !NBz˛orMJigvqZ%qU&8f'd'I-KLBƏɟ竿 m7XAD꿾 qO27"w@W!:BDn~Q aډĘU}&cRH#t~vwart.< t mb~e2Bl M7ӽX٩Ƴ ʠ)*Ji i;W]9⸆)UF6J 7ۍ1 J3vyVj[4LVӨYT+z{qQNII򇱣Eii/Q h!҂nƱ!@ޫXh5Q Ɲ:I_ rn*N`vxJH30c\HM )T]lqr;#aEZm{ 0EIteT-C2Q;p9FэJUn]MBRх4f$a)w4<-(<#5vRQZIǎ3ђhy Z%[rh_]eYxeM2,.; P"G5,6ƦpIinU*ki):֢y/`9&9&3tOA=j N=b:A&6eуNJxN)}k7V5b+]l2JKۃ/1ZvU\(qq4Y&7.A5&.JBOH2>R4<+%ZIVcGXqY W.Zԏ,x%?f퐋+83D FRy'"Sj,0kSY8*aG&6"E.SH) \Hn73}ӠFyڽQ2cKqPQ #w=¹%NrC})mm0drOէpܹOr}R#:a֞#dQkqoV3ܦ 9`&HP+$!)$ nAQ6b4L&URI*B"lmSU_r֢TYJNR,&h_H&~K^J$G;&c=ߩKJV4(RCLTi!WX w 9-Q) v.hI崻YMXƹNXOqSU_AFܤk\{[&E%ҕ=o1 :N%}X0͙i4;*Q poRۋQkUϔNjQQV\*2i~!Ȯ-`ʶ=y^g'S(U$BUnsoF* 73[Q+9$tcGei iDe,ː6:=tKS6ӡ"`[o)*.X*V6WqǙSǻ4;i',c~Jf{*ңحڃmiV^wq7%%ђ%(*V\oV9 4̀wnt:*Ti)B, Sm-/pG&W#]MLcLQ}\$jQXimE{}cʹj[4)VÏWZnwIc8`H`0` 0 `0` 0 `Cz`7U?L0` ۤLP :>4tM8?V  ٴ( ԥ>4φJ)rĂo,0>]`=qiSJ#Id˛r:ݛG^˨(Ѝ)` i\LXC:'Q*R rRm͏ 2jLZUT5[BYY<ԍVDD/GⲔ-H[OotF9ŁץfRְW;Md GJ@P >WdJ5MaݎH⪎CNdD V5:M\\1$8->ƒ{H݅{0ò(#-nlvRRy7UlGvI~V&3m!GKJ{Gi?Ag@B>kV'G}V۞2q:QK*BÇUYG">ZvM(J!*?aI}cWhIS)i2)RT$,κlGu݊M싒% ,SAjKRmjINۨ}VEOmi&`ᬀ.naWsŠ:I%*HD͸(Ԑo$}ce(/uS.(hmdI$݌dyIܕPעPRo*Xԝ#-rZSiJ * ;>E*y*5B7u>YHqdi7RIŃC!,%%CXBt%DY$ޑi׳oÖ M.vm{0|^9`—m;M6>} faK6^i׳X0~} fCkه,R i׳oÖ )p߃Ckك7aS;Ii*0aGkGY"ȋeԡU106,$+)4NV,u0Jx&[kFMФ-⦿M 'I\B=^qv&٥>4A/HwT47|A%%PERY)JSi2U7r=]ICQLV$ŐCд:vCPoNlSLFde W<׸.(:GcEn9>f ̰Z E˾B:|IhٔR Af5\~BdI 7 P2|q5⾧RHδ^\T+eI>Lԓu 6:0_RqT Md0$'@J~cএީBCxZѲϯqKsӄ2b) ISB\W3ӅoJ0Ǹ5H 6AZLŊŖ|Ϝ6># |/2z®ߤ?lNeoT[NRbԥ) 4RF H>!#ZC8܂ꔥqy:OP~ߤ? k%cB5>b-/ $-; 0 `0` 0 H{j4=_O?F r2ȇS^ˑY2##@$ ?piP7ۈB4hI)%)+pkPB^PI<\ 'OL@SHvpקI֝ZaWiBI <{$*Ind e6xUupOCKA'Go$cIlS_<')Qی6 %<˄\Ku4KYuDYz8kOb2<>PϚ;Tuz4s',>I'fK\)m>[t:vvd(Qn*D.10JvA.:;Z㌾0Z#iR bu$_6(bD/!n*ʒԢ@a].- GqbЂusb7Qf`f)L.!=eA#"fJ ,BO؍\o1C Y81Y]y Yt2}a:@ #UIbLe mֹ r/rWJpE~%'Dh{r9{Gٍgz,jD gz,j|=|E=w B_O?F 5tUzCm ~o׃I۴I^RZg.S ̉Qw\oRrACho 2  RAP$ΐCL'T4Ga mDY[mOIy(^4,8RaF#XkV~x0` #&RS t[ɲ|-IşXS,GSg_[JΒTBH lJ6 PRꑂG-F#q!dihT;$} j7X0` H$p@*R@h$JwÕzMɉuM6[uȑִX,I=0` c* pc@{# k=<FC/7lH'}$0` r UL%J+) %=Sܱ_GEIU% lYeJJ}*Ԅ ^M)|c )l+Rcj7?Vk)Ɍ# 6 -:ܢ~O :IN(v=$Y(v$e";lc{)'&H=B [,h%D֮~80`H6er SH@a v P¯/zO^:M~އS0``oL0gni)MD5h q*Y$MP3Diags-1.0.12.079/doc/style.css0000644000175000001440000001326711243520167015115 0ustar ciobiusers.Code { font-family: 'Courier New', 'Andale Mono', 'Lucida Console', 'B&H Lucida Typewriter', 'Lucida Sans Typewriter', Courier, Monospace; font-size: small; } .RegFnt { font-family: Arial, Verdana, Helvetica, sans-serif; } .Comment { color: #57628a; font-style: italic; } .Preproc { color: #006633; } .Keyword { font-weight: bold; color: #000000; } .Integer { color: #0000ff; } .Regular { color: #000000; } .StdType { font-weight: bold; color: #800000; } .StringVal { color: #dd0000; } .StringSpecChar { color: #ff00ff; } .Double { color: #800080; } .Hlt { background: yellow; font-weight: bold; } .ChpCol1 { background: #ececec; } .ChpCol2 { background: #f8f8f8; } /*.WarnCol { background: #ff5858; color: #000000; }*/ /*.WarnCol { background: #ff3838; color: #ffffff; }*/ .WarnCol { background: #ff1818; color: #ffff00; font-weight: bold; } /*.WarnCol { background: #ff3838; }*/ .NoteCol { background: #000040; color: #ffffff; font-size: small; } .InlineCode { color: #000090; font-style: italic; font-weight: bold; } .NoBoldInlineCode { color: #0000b0; font-style: italic; } .FileName { color: #800000; font-style: italic; } .Signature { color: #0080b0; font-style: italic; font-weight: bold; } .XSmalllText { color: #000000; font-size: small; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; } .XNormalText { color: #000000; font-size: medium; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; } .XSubChapterText { color: #000000; font-weight: bold; font-size: large; padding-bottom: 10px; padding-top: 15px; padding-left: 18px; padding-right: 8px; } .XChapterText { color: #000000; font-weight: bold; font-size: x-large; padding-bottom: 12px; padding-top: 18px; padding-left: 28px; padding-right: 8px; } .XTitleText { color: #000000; font-weight: bold; font-size: xx-large; padding-bottom: 15px; padding-top: 15px; text-align: center; } .XInclSubChapterText { color: #000000; font-weight: bold; font-size: large; } .NormalText { color: #000000; font-size: medium; font-weight: normal; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; } .FreeNormalText { color: #000000; font-size: medium; font-weight: normal; padding-top: 10px; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; } .SubChapterText { color: #000000; font-weight: bold; font-size: large; padding-bottom: 10px; padding-top: 15px; padding-left: 18px; padding-right: 8px; } .ChapterText { color: #000000; font-weight: bold; font-size: x-large; padding-bottom: 12px; padding-top: 18px; padding-left: 28px; padding-right: 8px; } .TitleText { color: #000000; font-weight: bold; font-size: medium; padding-top: 10px; text-align: left; } .NoBrdTableText { color: #000000; font-size: medium; font-weight: normal; padding-bottom: 0px; padding-left: 8px; padding-right: 8px; } /* for tables without borders */ .TableText { color: #000000; font-size: medium; font-weight: normal; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; } .HeaderText { color: #000000; font-size: medium; font-weight: normal; padding-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; } .HeaderTable { color: #000000; border: 0; border-spacing: 0px; padding: 0px; } /*.HeaderTableText { color: #000000; font-size: medium; font-weight: normal; padding-top: 10px; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; }*/ .HeaderTableText { color: #000000; font-size: medium; font-weight: normal; padding-top: 10px; padding-bottom: 10px; padding-left: 0px; padding-right: 0px; } /*.NormalText { color: #000000; font-size: medium; font-weight: normal; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; }*/ /*.NavBarText { color: #000000; font-weight: bold; font-size: large; padding-bottom: 10px; padding-top: 10px; padding-left: 18px; padding-right: 8px; }*/ .NavBarText { color: #000000; font-weight: bold; font-size: large; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; padding-right: 0px; } .Screenshot { color: #000000; font-weight: bold; padding-bottom: 5px; padding-top: 10px; padding-left: 10px; padding-right: 10px; } .Example { background: #d8d8ff; font-weight: bold; padding-bottom: 3px; padding-top: 3px; padding-left: 10px; padding-right: 10px; } .Reference { background: #d8d8ff; font-weight: bold; } .RightAlign { text-align: right; } .RightMargin { margin-right: 10px; } .ListLev1 { list-style: disc; } .ListLev2 { list-style: circle; } .ListNum1 { list-style: 1; } .ListSpace { padding-bottom: 4px; padding-top: 4px; } .SubtableSpace { padding-left: 20px; } .GenericSpace { padding-left: 20px; } .NavPadLeft { padding-right: 20px; } /*the left arrow needs padding to the right*/ .NavPadRight { padding-left: 20px; } .NavPad { padding-right: 20px; padding-left: 20px; } .NavPadTable { padding-bottom: 10px; padding-top: 10px; padding-left: 18px; padding-right: 18px; } .HeaderPadLeft { padding-left: 10px; } .HeaderPadRight { padding-right: 10px; } .ImgNoBorder { border-style: none; } /*.NavTable { border: 0px; border-spacing: 0px; padding: 0px; width:"100%"; }*/ .NavTable { } a.Warn:link { color: #ffff50; text-decoration: underline; } a.Warn:active { color: #ffff30; text-decoration: underline; } a.Warn:visited { color: #dddd20; text-decoration: underline; } a.Warn:hover { color: #ffff50; text-decoration: underline; } a.Note:link { color: #ffffc0; text-decoration: underline; } a.Note:active { color: #ffffb0; text-decoration: underline; } a.Note:visited { color: #dddd80; text-decoration: underline; } a.Note:hover { color: #ffffd0; text-decoration: underline; } a.NoUnderline { text-decoration:none; } MP3Diags-1.0.12.079/doc/295_config_quality.png0000644000175000001440000004612411262714731017366 0ustar ciobiusersPNG  IHDRhjbKGD pHYsȥtIME %W IDATxW}(コse[l \_%ƿP,B I K%[P.-*d{Ď$q?aY6dY#?-YҕCs{f{|nI3}ӧ鞱HJo574ϫ-R}c `qm}>VXg5g}!رqزsAU+cʳ #G^W^92`ŊbT>Zb /$㥗~GsssK//|,[6ccc* /Rv%\矿zbT:uzX+ώJDLNV/5kXju%%FDđ#/=??}:-q _xꫯ:;. ;܁\9jl7811: K.իϏsVKK=j-jZwqxuxg_~Pҋ111af0p}]uV3pxK;ll,:묘Z1ӧĉqVZ~?~8uT͝Je*/_˗OkO_x+o897׾oƎ'rS M/-|շ^{]\~񖷼5VMVbƉ\X,Tbʕ1sΉ'qxG!?!j3Ae1>~fjؙbxwŋ/眳*'?y:T&F:wV}qo{×'?jggqUWſĶm?̜ٿo/xJLMUJyFA_'Je>Ͻebٲe^9gescǎF"n[ϱW~5kQE,_>F6043N:±g3q켈g~"^Q97#^~:1󁈋7}?rYCKp5jʨT& 6nUV7uSy|_F2+"3k=?~:n얈F=~SsQM t_}uYǿi򑴯v#W_#= #F<%1:?G\!bwVnDE]gO, 4yQT-ۼ-Z;yx;jUM9<4߼NGX}<橏4+WT<Zj-klٲSqrdj5?X{lms+G^ߎXď.[jկL3ED|cW\qq\sED޽/~gmWd>>\0ϟ]0⊋c}_:/xޛxsD\Έ߿+b׽s='. s=g^g%O^t]`],ԗ7Gcnd}5us 7\,Hrrn.=plxmsӯ6N+_}Ow/ſ_|!3!PbUq.8lGV?5 /8UQLG"?Gk?~&0뮈sU-LIcZU+#b& d+J[7&so'My?ܕ'YҾhO,*i# ~_7孱n?]|?b||<^{v:-Kx;ɹժOvs]_<}jj2"j=]:?J_|a{@ߋ _p~=(+qY@:i0[MdhUIʫAPTGZ^g~oc\7Z8q"cbb"-ZkŸl PV734#"}6nT&3 *155SS_'e_׍S;[z0""֭[cHsbrr2ǗOT%.t:;X|"N:ǎkqCED_$nyy;_طydگ]ʉğoG=3#?=GU#&"N:"V%C*])~عKo_XOSiw0UzMXT}XqV?~lccc|DLL,_ӧO}EVZ-brr2jCxӦzDzez``MZY{Q9's]/JpxOXx6Jt L~\wK8u̲ӯ,_/8ov6&:+S+Jx㵱mۏF29uzu>O.xZV>Y|#8~X͗d%~W_|"/Jcժso뮿)^x;S<3QL~K`h{;ɉsG}_Lƅ)*J}wLJdLNwvc|<믿1.xEYss1q՘{8yHNcrժMqT%~/bm3|ndʑx7Lu+|ݼ^:eo<<uuum~i\t |Zԙ!͝_ zZEG jZxӛ.sW=/>Xl^x!^=z$n}8>|L  {!.M-?[pt>VkCuJ/o>cƱ_})j5l\g<أcο>'bq8~xѨV # |SSJ PV5355c m~X4/OWm.?ӱ:~Xؿ7tjTc"bٲe VW*19<&''K@DąJ%&'GVr919yf<%dW8r8rBi˳:nwËg1 ynu/~m˯V^ğZ-cll1bbb<-[  \p]m_T>VkCp뭟iCq_=J`  Lu#qaLǦM7` o*c ""@>_zXBػw,(L6]1m W?;e'??ODVZ#"ZƲ4?I|̗ͯ7?yYrY<&Ny̻,}~[.wl\']eI~R;i]ieV۴붻㑭[mmڵf[-R}ݤ]uSYuֲmz, flu}]qmvo}|'(=ҏcv4i-|Ek|{~y{qgmԽ_V2IR;ze*o]3{}F}iֶ֮^s.t^y4-cPݘ^7bۺvvX2V סCU}YcZ rԯlHۚڵʹ}H^}e9ޮEFGo_{)P[+vz_~v*Cט^cZ',ٻGˆdYS?zHOvPı&3Kݦ=ەq/㘗ٮ۵oQv?]D}Ѣ}uSi>((K 4~Kփv_vEig@ϷNۥkuZ:^9._MSBG}yij׭nٞ=eO2Þ=um\˲cm=1IN|g)jnIu&ӖS.[E^v>iyM=ekmPUەDrj(1reݤhvDu޽}ݻ8^o\֪:A9&Y)ߝ8{|""R":OOK?ui,y[AC޽{{\u{vs΋rϋ"],vDig !컛ϷnAVw#-`@CrW '׮m-k\vU/Z7MT_h޾e]:AcRaÍ ߮ݩǧ,6ܘziVd꯻w7ڷt:jʧ}TK䭛r JڜNmvsyQym;llz(_ByU2wh)*M[ױV2FSng028 y`A,iV nL}$2o*66E,k.ww:e_d. 7Ν?LUvTf9>ݴe+\>G%mj}>Ziw[}g/MsyQyQDv4%qy(jm,oi)vZ5kr{[xbklxbke;4'5lJ5Sƍ':ǤӾQvu&A=S_C}y^A~6QF=^w'g %GANsg?M>p`Ge|6M]kQWQj7}<\4 yԯωQ8{H4ҜKsxKԿ:1+{<|8lwA̬ڽv P^oJ5לNzL[Y"K:!2`eOs^WvUD^:t%)4Ǥ۲wt/m5O}9E7KyI3W}oqegYy¢>ʒ~WaQm/k= XS?[Ƶa{ڽڭyIYԱ-C_nCMLeVitZݾӬ&vSMm[Qu66K̓Ǽ˲~7ϬScge_s~#mߘ%oIs:-]aP>czQge_TߑqҋUe|&woپӔ~.E9cN=n%瘦AUĽh88~5*^3mf=Y_fE͚ƠyҬ_/5y`7m}ذ|:6E݋c=LSt_5(.ER[ڭ.rg+{ݯ1M&bt3EFٮBaYcz{{ k;K+K^{k~=vp%{}n:2Ғ4b>T)Y;ɬEy`za(k/ί")/A9ӫ)-c0QFRtSA-^/eEϒ__2wS뷌t/ڋ][n~{]nTai>W;=kz^s辷} oQ,򳶗e* Ӭ^A^S1Ё;%i4S Ӯ)/ *7JYtј6Y_F]M9EA|iu/SHn@NO\ꮟn,{")P]2N1h[7`_?ﲴfҺlm:Y^fZEiޘ?vvN3ur[("ouΓ{蝞0,wJ+뾒ϛߢ]Y?&)3`?X͒Vg .c˛4uc_3`g eC证nxe_eenNyo63w|m}>*ɸt޸իdʁ/Ymxݻ?>[Ros/زs{ `Lx>K(@knW_^~,e= ^aX~Myuvy} ^s&Aۗ AN?z@Kzݫ<8ٶװE"@i A!$>v8l؂zړAÖJ(,V~ h9ݲ<4OL^s:fg.KtnyǡS:yʒvS<4VnQ[uwQeN{<;[s#yt޴_zLN_s`]{H'giKy;N3 ˹m/kk־`Kq8}`˲WݝOy-inTQ5lb VOz6拡3i۬˻]iUμPv~)KR:y]rKJYTvt-sL:>n뵈6<;iv峦e?O.8v['ekE}.n( j|wG,0͹VuwQD>:Is *=o:`^ ǡc٫|6Fl3.-$]}H?iYկ kիϞ^n} ^+ uC7i KM>̼򳧌Ӌ^ކİd_O/32~(OGݣֆ ړx0y >}~eJ6NhXAWGy(bHxz~y'ƩuX砕< RcRdeu?^Wwe|nr7.Ŷ>)K~ѯy(b^h1ǡ87E? o>tx {_Vt`tn^΋+:+/7`0~^]߬Qk^] 1Tvg(ft3*ӟ[3 IIʛN8t;m+1kNǺz+ݧ,w[S2ϫ˟;ݤݫ:L{v:ogPd[z_ev%OeǢ_p7ey)\@_tnw?ދ>:(׏^VVQuw2z 3>g=}n|T*q뭟u׽qիW 0pqKs}P| ޽%6oB͝-[>7?@˄*.tEaAUaai >s>\_ fߨ/ :  } ]{uGm[h.qO]TY-t|;8c:ꦮ, ~X )Iۤnj*ɸt޸ի$͠f۷?{~>|8n 17w2lX*X|       U@V[>V1336ݤ"FsOȔ{\~K_-O~cqё)Ӊ'r# ZZm3JH| h-]{1Ә<&y4 뀹Z&.Z^ Byoy0ߜNeIΰYqѲ5k6;vYK 0UA} >eo͚u~r0 x@IVS5 HZӲ,d X0on,+,SH@7[Zλ,azAуjyY+6qv<hh@w3h;$ժzvgg={kvY}^r={ ;}AOY1eS-k^+ާu-1W^y5(}}nI8 n7~ 䓏|c^䓏7,xݼ?0,Wz1 2p/B'7^Ewujٮ]""`!lwzp`͒N?*s#aÍ ^חoxSDĂuh1Y`ne4.:,رuѲ;6l[M|aՁ)O"_3$ zGi[ |`JE@[0<@`Lǝw~)\;v,׶cffZ-64?J%wyff@  qU @A mH:tXED̴D?g#S{frˇrm/}%"B`:t8>ɏő#GGL'N]|.0zjZj*O.( #=&!tvqKfE]FcR9KN7jlffC:k{[@=v)PjyE7թ,ifl͚Y1ܹ( pζzbN`FS֬8֯wˆ@ ~k|?o蔯|$iY|j`'ӽG`8 -i'- yAr譾eov.$8s|oW\qm:wy:m PnI+*A@CYyժzvgg={kvY}^r={-i }̓"peO=}Ѳux}P|/Z9@ฟߘm,_6,߸7ēO>yIO>߰uz+e4P/r_NOo|~ ^ڵ~=ſղ]ED#0 v,V۶)Ȓ"˗f<9 -;w>6ܸu}ƍ7ED,X^_Vd IO4H3@ΓnWd]wsvغhَ[&0?0z@կ @@4F>0B"-jyi 0ff;w{Ȕinn.;k}133aMnJ<33u  z˸*@ ~̶n}$:""bffO"ӟ)ӽ~3nCҗ!0Z:ȑ#S'N.G>{q_=Z-j'rgv]{QXڝjie=u[$YݠZ&.Z^2Ъ<@Nx7ge%lY'w͚Y1ܹ( pζzbN;Z~]րWղԧ7Yq>_'_- 0gtv<'-kzke);h' ۭ4)K7z(2V:^ {[|5ki}Z}o[i9i&HPUS-۳Au^{<6{<&_헱~? N7/{틖5sSOmӀ+~њyJ)jI&O^u֯!|ўOoKҾ|X3E 5 <)oY:=7,zk׶Vv6à3Y~Ү oimH{ ΝĆ 7.x]_qM NH:%:t'kصk[us 0,0oͽ{C3' i4i)࿨ A4H7[ZλU>;?3 [!O36At7~/HPjqMMM9@t'崙eNyKŠ g ;G%E;β  &Pԧ4v?B} @hY ؗOĩS3o@u.uVWbll,@=Cl0dY7?˾ܖ8o7ͼ_`h [wM{a`8xc@oϞ۳jn`hj5v޾`ݻ/Z- yZƮ]""b׮m h;~r[2~ @t|ߎّ(ϖ-K.8jZ=z4=pLkeӦ"";82eZbEy=F.` 0\  E3du#q(ˡC33~ffO"Ǐ~/rm/eD h7o<噝;b?~"N:yw{!0jQV3og~@h$̬oV<@IڍvA@F uYκu$p 0 kv^}6+*^I}yR9˒fa266hآA|euW]u}zݻN`J;`M;xn~~KsӬ3,ZvY]Z۸[aԷ~E ~ͷ-@Fk^=~k|?Ϡ]՜u;-A}Vyfb nhvݷISߜu:V?ϠWo(b (>E7ܤ CR`ͷd] i MMMEa$yx`ZEMoͽig "}{@=ͻ, `¨ԧ4v?B}U 0J l'ԩә @ŀueE [^eW/לNeBV[xe<t IO2N3@Γnʗ'ݔuXIv@u״\o߾'ø*7fy:13sYgf$" H+qg"__FD#Qٸ/'ԩә7 Zj5vy@j`$ ׮knl`h$X[wM áXE8;ոulzJK<֗'ssӬ3HM]O\ov{,@?/9y  jvr gcNS IDATo/jTEivnwz]+b@[:벢2z9>O `XL Sf˞ߘ^wzvY޲gtڶ- J` }k? %({*Nm_4s }GͼԔ^(C˗߼i6fRz(b'wy˛^4n S\= q_דE “fpۋYK}^OĩS3o@tk\g3γ2򓧞c ygX}^wnvYt[OŠY+,ui޾}O4l# qUoxz{<`Z- mZ{E!Tصk[DDڵ-q[ac[.s C&34~1;;;ٲq%GVGfi `ltSDDqGL+V;'׶33u  z@@@@@@T                                                333qW\&${6mi>#@9ff} ԃf(g6mq PURJ֕40qvŠ&AۭŸ@׀v`fTcn&|Jqy~_\P @(( yr'Gj-M֜㟄_B*3U8 >}W>?*3U`4D9ȴL ȐiS ry!ldPLhg?~O'+V~6gϪ;o/hS U˷Çe}ϭn @23Su F tݸu_O|p:,/}elcϛӗů4U}@WV5LӮaeeZ2z|-f/fEP@ބo»w<wq6=8:@F-{۷O|O8:Ϋ2SfS Ս_*2-r;x5M,`/ ^{7Ӵt:eɜ-f嚿0ON:: NoNvOCϽ̯irtzg?"kUe)K*;֭o'NUԚi2dN~'tȻy _UϦLY]w>d)8/24/#֟!Y׿+}66qXӆ?4d *J*FMTh\62lS c܄dڀL%de#ӦdR=w~/ /^Z%֘i Q)y:=ЏsiݰkX\ȀL2\m(`އvy~ @s>+`+0{\3  3 iXHEdA( O_9- MP3 Diags - First run
MP3 Diags
When MP3 Diags is first started, it will prompt you to choose which directories you want it to process. Its configuration options are stored in an ".ini" file. Usually there will be a default name already filled in, which is operating system - specific. If you want a different name (or if there is no default), you can choose something else, by clicking on the button at its right. After you press OK, the scanning process begins. It will create another file for storing the details about your MP3 files, with the same name as the ".ini" file except for the ".dat" extension.
Note that you don't need to create or set up the ".ini" file, but merely to choose a name for it if you don't like the default or if there is no default. Actually it's supposed to be the name of a new file, one that doesn't already exist. MP3 Diags will fill in all the details.
Note about network access on Windows
It may not be immediately obvious how to access MP3 files that are not on the local computer. Currently MP3 Diags can only open files from some "drive", which has a drive letter (C:, D:, ...), and there are no plans to support "\\Computer\SharedFolder" naming.
What you can do is map a network drive, so you can see the files on "\\Computer\SharedFolder" as files on G: or whatever drive letter you choose. Then MP3 Diags should be able to open your files by using this new drive. Search the web for the actual details about how to map a network drive on your particular version of Windows.
If you have something to say about this topic, you can add a note at http://sourceforge.net/apps/mantisbt/mp3diags/view.php?id=34. You may also want to look there if this doesn't seem to work. For example, one post describes how you may have to run the program in Vista SP2 compatibility mode under Windows 7 in order to see the network drives.
MP3Diags-1.0.12.079/doc/180_folder_filter.png0000644000175000001440000007501211262655212017156 0ustar ciobiusersPNG  IHDRkibKGD pHYsȥtIME 8 o IDATx|}Ϝ#  i&8I4ll7ۛmҴMfsl77齡vn\4}4 [$@pDl K @gG~;?9'=9g;y;s_s=>|S5CS~J-Z$mmFcS25uQ.\ $ekrﶷSO{^~5u~ü%ic.oz_#7*l)I\xQ.EG4wtHdfby”TFGU9ڹ]wdLSSQ 3(7]8#wxoӟ/ne7'~\ɯ~u?'% T Ge8u9w~8oy?-XWM!"ŢEnŋ;-_/R*-7m2]y|V\W6L˗}':uJ}T־IdjOlxaeEΞy"k(rݭ"<<*Ǿ6*~w51tvvh !WǤ(>""eF쐻C^iW3/JԒP6ȡ'?x@DD>W!o|6W$_ˮ3/һ?oY7~ {-ݳEN<"EYy"׈7Wd-"ko+%KjCJJ-9{yeTA[=D4""̅;;ױȓO>ܸu!--rW>8#J8y)$Z%9zY-?<+T3)y{:>vUwN|"?3U w|Eڗo%K:dk~:;;Byus穄iʭi;bܤtqzZ~uo7S(H\OXoW^x^Ν?'+r!qgǎɚ5\. j==o[W/9xggy[Լs$_yEnCdMwy6©ScO˓O>-Ro/welxPo ʪU7ɪU7riUXr=6lX;O%ǭKO'l*weժ.|?_og_{8LLn-¾r5ru+̎8f=\וws|OT"KtJԢ\k7Wٓ)4|Dd(ΝN7,}R*dÆr†J9K,7⠲#T[C:;;B[gW;*O<:-Z&.L}qinn47ȕ+W2sxF\,+"7"wʞ/IPb_ 5#RrٝfpnRfrv~lWHkkI^nyQ=]ʯ[-K^:|X -W"rkW"o:OgZ:[dƍf}J\+'V;u׭!3*T gKk:]0%7p&&z雛IJ455Kgyժ.;̙3w9}y)Zԣ^\8=ޤ_*ȊJT׿~?>u5#iiQly>)){joYGnXyMOK˓2=1!ΟeǑBstvJkJ{\h-ϞN9$Ow={^Dol7=}in7+z!wWU===T?{R4oٕϛɻs.oIv,f\d/^,l/ș3gd}ON͞عzBaj /9^'}/xqZZ[g:kEgZ#G˶:W.>}}Oʾ}O=. ޾XZ[[YDD\".\ɗ\.?[[[EĹ{)pkRi.W6@P9-+eG~~˟֙{\)ol…)=rH:d,ryz*_, jJXzP}"--Ғ5""+V,R$--⺮4KGbii:].sr9_à޴娔oRtAϩ,F;l` 338NAg(ǑEij*e_|YmգcifO64kףgh{@}:zTcLL$.';=޾HGܹcٹX75L=ԙywKWW@ O3s 4 aaa> > >}aW*#β{#{zPol}>VZfR3jQSHl^>9f*@V4ܭP7A:DOwq@=l4LPc^ +;Pu8˶1W>T|&HWkt6=zW ~'lsc@V}YqS]vzŶٝ7q gVz7A٣B3Q%(1ev7g|muv",VLG]ǟU? zZϾP4tQ ۨWe3$VyL58f#ǿ>৤Tjtuu*Ԑ1?#ӗ>0~ >}@}7'r- Ekvk^sgM_#OV_ݞ]دl ,:t興H%eq_ w~l2}}7Q}܇JHs@? |Ɏ8+;w1.zQ\\X~dRH\֞o|d2՟&qdEfB ?9N4M@}g#]]};4ota@'  﫰xo ^|5x͇:>{OjC}ݺ-s=?pti^n9ztD8. {AAUp\qPga} {C並~IwwotǣCF>qaq auݽJeoaa?@|>}>āZP O= p\qPa@:48!]y5<*e IاgȾ>wtUC>qaq'@}@P_:8> > @Wr=_[ۢeP/?kM'80)" Es8 F;oC$lX> hIw7??o8y>))Z?,]]]3EY/O=_vOѮ뺲s.'HaŊkGw?Iٿml|,r/sZww|s<ط瞗O|);66&gdzY-l{Q4ټCq)uV}X@8!(8]6OlhW~Ө ~8 [Wq[NU+q7位P6*{sn$հC<=a}tBI=o'۷^6'Vm =No<4dϾwXyQ~USު:mitp8MkqX_An}55eaz JsMA֭OZsM- Wo "# h}Ǻeͧ3F(_'Wl$M~zgkH+uqUoҭt~$'lݿ| tumD}'!z=6=(ѝ.*hS_æS'î퍳^۰uz`{=AaZ~n,ޘgm2oXѩJ}uש7ǎ=3oj~0հ=XeV_X缶k#uRmPksA#qq7~"ieO؉8uZv(혧A[us3 iލ}~w5zC?yYrB[؝ y^l^f:8]Gﻤ 2k&a= t=y>N }Yssjuć]2iAuu[L؍L+PoXzlsnwq$]eT0]fn~hM׶6Ok_FafOG yהF׮EC887QAJ=┙Vtg⮗)q'e,ζ2T!u7.mߛ$o i>io`g2# 1::${xڵѣ_G7y ~>Y5~*A<كk^Z{sq7~T[P{xZ؏/=FPS=7ӳh An{ 4 yI?m"2Q9m;?5?%RKyݻ(==婧?~ vÆrS>/W ' XFmS{dŊkGw?Iٿ|c`2Czecߖ{^><ؘ|ӟK&2cհ%'Ym-?NyoSl۶F4=ViJ‡ ҕIpZYG Ԧd ɎYjHue]OYO#0d ̪M͢\>9#rj'#T/K6ʧST I~kIN<ϡZ\7 _(ѩuPrM81l'|* V~ρV~Wf; { .S>:|Nĸ<ƙʏPzM?yCӪ|^댬QK@_PVZ<:еlSa?2a&xl ze&uXӰq!gaYn\P)7zE#iAqe: I| WuiZnMڜcѡ\Y}_ }ql@}@7~rC ̯ܺ:<^y/Ś``[ {c 6l۶HM'PGappHvf.Ν@#PGa_dkZ|'#mmO_kʛE{a><(A;]jĄLNNY- aM81lht}}{#͍|Q,ccs:;o7=tu +GaۃU]1ReW^Qtō| D|CiPRF|:;,~c>a'/+h~''87:F,Ǚ.(8i*uS)zDq+}ӛ&]ub4J0-3X,hO2$=v/iyRȲ T!-F,+A|Q',:~wwe#6=zD4=7=A ϳ~rCRb|oyI ET>! r#_iMovkΦ#.E)7n5F]j}FH= aÆrS9îWWokeUi>\YvR_ r#_eƽ2lBMWt[[WyFqSܤqCG=}7S=Yvm t^Wi4nO؏SF8ggNW\[mDYauO=rcr7}+Sq.Pa}|8 Űnݖߏp7~V _y&u }?|{ (| Տ^,pqn~UԹ;^7@}AyӸ4PRo IDATsԲk=\dy)DF}PaVSyƍ|MԹѮ:-f[ٶI`A'UפaxO M|u˨VFm7pSV7'nڼ`ܛ9%'&&drrJ{6 GFė{rzeGb?0@}7%mmn݆쾷j= F>a@ެ7 72fQes#_l۶F4[' !ٱ㾹u]ٹs@ǑrlL릀˪^ϽsCaB=Tu#P @ljj&F>Mtum5%\{ q~:^yUj>ۘ?yհu"@w zԋ00~`5Ys;:8q't tг8el/Ⱥ>@H%wwPn¾Y5|>ɰzLˮA @ 7l*"":O%^Ǡ!MIaL?thp㞞>9th0yJ&u{> $}?<aS}@}@lbbB&'F@YݻI쁁=42}POmN#܄}?m3.cppHvODZZ7ue]v~џ=_'mE9#rjOF.3.zIG-2 [mTEw۾66콙E-VWhυK徿yOɇ!yziqg@#qTm7#,TO2U8mFE^Z^g3z|`I[_{\(_+3W2 WoZ܉ZA,!1m So=AU;@o ~Sʛ.o(.򌸎b.6|Eu:o̗DZ/V2Em[mW "n'4C~_k+٩Rv2SvD`rD &Ӫ׬ΗD96m<(;j4$o>u¥<;uR~.MM=23vnspv-r3zÖm#hT+ˤU/ ^vI鶭iZh}a1_,~{2-25=%e)ˌ;3[fڵ{|U^"۾^7KT_= 7uF> xr[e՚Ur~832HPٿd/,kxݺ- "W,۪Cy zyEY֗^~>/~FqҹS]<'3)2SskVuFA,nZvZÚm$H['۬KкqN}`хK__F^8,wnS&g67L+=3ͳ!K y(C%T&6>o=g2 mZWg=uo]tӴ4~Kƕejzj{3e)\6Eq\)̈dr>9thP qnu롳3$=7rMݶI:m>_t@twȡGؑRn+KaqAG 6͕)goHJkadd-xaT?*82^>)3/]KK"ū-"HDZ$Rh.EDƚ+ԏRsI9yJJȯ." l>l}~_/}\Zik:^}'QfoW E E{=} !yi7 ~ee$LʲQ~:G !a4`_nGg^aIH&wy&o)@ uP!ˠ2$~ز. aX?riIŸ~=@%]ǠЩ:t|a'S}-=LXMi@(}aߤdtK5e&)ȹ X(J)HOo,^X>Ȏ7?'&&drrjmlO@+Wհ/)ymڿ엿Cg?R,,Wv~$땁=lW4v؟isIѹ܂ַU,̻/~dEܯҶmٮ`7a: 喲9+E(E(E)J\;]w%#GW?o3yb-rppHvODZ*Ν aM9'g6ݢ˳?+)r7J[K>$/~Gso[H\*'#֍tU=}$H飖7MQ^^YnFk߰gf>ug?9f_ g.φRܾ<=_[u~ukSm]J}ln#Փqa *"LY+3eW L;R\[db>)?W5=A.f~ݰ/tJpBdFD.lXł ^p|,9W/p oY\*޲5{յYi>K4\Yu:o T zٿhKi[>q#I, d¾J XD~ڻ+W+"E "cтH$W5R F^5WVj2Pcz? *ưq@b뽧im$ 8"Nə fKYf~D/)9r;7x &֮E{&VOw$'P Lo֙6(&T z>]269W -E@ D t^D ܵՙ<L{fYMzeE#^ziZS~ZGud@M֫!sZ*uQ||͟勯MګWFGrRrq!6'–uOSdH+>0Sqkg^p:DEy튟z5{6M>/^vn' _'U$Nl}@\D 3E2{\.O'{ob@dž [R~8`^upN"ZܯS:hYau& }nqOܤ}La6_)^*ʊܫJ4$=OPX52Lt^S]k*ˎLy {fd^Lo-8ٰ&m!sˊ˓]v ahȰ4Sk/,eGnU>?~}><aDim*%KdS?{|l;}t 'uu.a$q?ɲ @)eѰ@zeG+{`` aԓm۶`7a688$;v'X-u]ٹs@ǑrlL릀˪r$l~Q&^/,IARozڍ8FqR@ͫZuK;|]} 뒷uSm6_N@}y ^zӼ'N ENn vv]7 ;,ccs:;\o|T/epek2:NdвS҃a#H8uӶ}G\@u1\/:\Yu:oph[Cus@jZiKM7:}@ط8i`RFR,Mo֙6(&T ~>]26*@5 /k޲,Cu1L|eE#ɰT/mPwOkD]>~ww{nݺ- r Zf{{ adWv~$@=ٶm;hNp@lCc}8r]ו;wI?m aq)V?̴n +'AN,Uϟf;%T&-L^&?fz>Ϳ1޳IaT=,l<,#2k9)Х3m& ՛=>qb.BXVK#vYZX4Oپ }@؟յY.L`ÆGv {V[/&êM@PuJ=qW)2LnlOӡIC)}ZNA_Rq nw`%Moc_59WQ6V57gX[Qic%QC~lWT;YއdT_Nml,I}Psa?h&e$uz_Ni}m tݨ/jYIG0[m^}"!褒n/mk{>@aݺ-'ŴG3/wPw}Ҩ_8ԭK i&a?\< 6/aUC{x,OA/Z,1@wmߓN-AH-'UJ0Py-*d>I\/E^5n*iOʎ?Uznk.j? {zСMn{>[aRwTfRv괇z=V :i:{2SNmy[7;QN6ogzBa?>Mþ^y>^}>հ^ da )eѰ@zeG+{`` aԓm۶`7a688$;v'X-u]ٹs@ǑrlL릀˪ﭮIrt{?[$%.Q܎6]6;A 9;ir,VJXZKO^&S7UV$'N /xy`{d^:e~Wwum ¿90Z7Btu +GaâU]a# l?l?y9顺o۬=y9lIWR&6þk?~`~M(*Ǻeͧ:]PLˉSЭm+hl?:eUwRFGԾD{+@;LCUʶ>QөM<кF'i{?ml6y 6NiapP=^r(l$0l=^udIe]t.[jFog¾M AW in ~'۶m n>mppHvoWຮܹKic uH\ZeuS@eYH7e kC5_Al o:^]Jm t |Ni-3sZo혷JYLl(f Yjr"qr"u:vn3a?HWfi7 ޡ~C@ 6:TrT29hY~ulz-z؈7&9޴t>J=j,ǏX0M*=AzuOua[o۪Wв+ˈ ޶Qu}Z~ж k}9͑zհرg|Iao~eD֥6'݃2 BMUcI4\@ in@u >U ^z81jx@^uk^g0R ]]յY.t*Coz2tu +GaۃU]sUeW^Q:uG.>gxl'Ij0Y$qQݦ>>L ׬Y? k<ɠA`UBN ĩ5=hVWвzu_]`Z_imlGwuFW}?A' Lߡעla> _u3bMʈ:8Ɓj*a$q9!nX=Q$nA79Zj`Lsmտ#ag{yiÄ}@7u_߰a>Tj=2aЪC}m ={<QE#hڰYvML['mzįA7/T $mrla> +' ƾYNUW&ukcM*mnҎqndhc[<>i$:mdnqnN>>L7nm.WGC&Qj  Ű?H8R.9>~2riPwY&uKs}}%TX7=j:^IN^\5 >յy]]el}N'\WPY_{>;m9~V' ޟr?~`iL%z6taVoz.F>{&0ت|U2m  ~[eGgZ=y ж@H$쏎 Տ^ @5uI2 F@um1h80~QӪ_b6l57[ke[IVþ##o##@ ^ޫu@> > > k&&&drrjm4,}^ٽC#@d۶4!:M Ɏ8Vu]Wv%1}:q\.[-s|d2Ӻ)Lf{}KTg>~'XǰW 3u[ɾjZϤڸR'n e|ĺemF롻iozS<+wϪU_SPsIk_}Y zՀ姫ksUw߰^~CUZi+ +7nq6 AuVYG6Wa뮻4nq8l\Vѳ}OWf9~@:=Ac2S.l ?Lkl àuismfQ'N6Q2KjUCFj38c[kocǞkoQ~ۨI y6چ=R'դ$;ml4ڙp8Á7-aekNi_rZ4F?<y-&4@ѡ܄}om-]s^/u;HUг2 TГ q<͓a_gd^yB= l?|eL} [EDd[[V9|T0 uVwնUS6;y)\.ï->@aСyɡCG( M\Ln:e_بJǙWnLӓ*{N6 >S]-a5 n;[ʉ#=@0oW$'N /x;M-<-W'[= j)hl; C!~W*0 #!~Cz#NT?ﴕzLʍ[K [߸%:֥tlI4G¶}ZU ޟr׃~]7VnaN6m2V;h:maz"uTM}m짶$hb{}`5{;oXy QmOtqCk}hu.uoĺrr&]{˼GEk8ʲ3jB^aжSc^#No>@9C[esYCzm줿nƶS)?mG>w\/bˌS$t[T?gcݽq{EjmxՏy:r$aPqK@uY,;$5+R۽6[ZJg.ulWAq^WFxPy-.:U0TonS>g4~qS&~&}TVK_xaӛ$=A+/l^ Q.;>;w}wtUu7mw;ɡCVNެdHJڮwp4l閕EM!Fާnqek@ a' W^&uc>mXy&VfPH*Wg~uk Vw0YJamZv ##o##8o?,]\|uJՉ,?el;~dUwicz/h?Fs:A6P]_.[-?qe3ibbB&'Fo4r.aԽ^ٽC#@w۶mic8*cw99N@lCc}ևu+;w~>H8R.9>~2ri]74VLE2n'8  īWo'76vp՛M+W7zڰǪMZ7,wIu}=;N ]] ^FaF+UBic2S.n謃wu7.[9~>qM&QS)Ǥè:tә~=ml8|t>` ~{+oރ a;j}}cǞ AeFZFt*uruI^~8~kׇR'c,ꚧ:m~.rgæ ~DZ& Gu=>ztnΗ{u^u2x_:yu\bұ!6nJ;zmHgݳSi:vjFQU>0A~3x MpͰn |:*',wXH ~A'C5Dvڡcz¤Κa:@eXT1|qnc1iw[a?W$䵝yZ{{Aִ|A-7uU7ESoJYq:-TN$u\ekde6H̰S`ܽlоڶa%߂_S|Ao'hy.0~@ܰ7}=a7SƯ;ܿzi O>:% yPI2>nK[ {Oi8ۀcy~<;;Mr[:؜d¾2O8uW-䇍?0UL:ތP6 CLw4 Q{_Q5:a\yuV'==}^Ws#8Dccӎ[['zo~-fj&߂ԇ.x}xxV{^C#E*:=&"a-:?fډeҮ:.*m|mTl >`Mhh ;Vk#` @@ECVi#@P111!SVlooa ,ݏ$Vr˄}ضmN#)}q8c\ue]Oג]{-TFg]tJTr[dݾ +WG2OF.3.+ͺU/S$?7Jl`Riv@ [f!╓ Yh 6՝-㝾zڰr[A6wy~ˍK(<*T?o7Y!̠vK}ue/ s]z81<ﱟiTm7Õp!ժnyubu[?պ7v[i;|!jcɴn_@H,wum^ӌ4 ɕp7tuS]^RCN=uSw0R=}XNBU|"QFi#4!>UqZj;_@׬Y? kZЪ;=DtAu WeP==:(Өgu{ouKMl}ϱcC]ו5knG5\=eDaӺPw4 A&M;n]xy)oc?{o"DQd[O$ŗHEԍ P qvȮՠmmbحUn u-vذeSHMȓEI(vt̾}>nwf~gf;oשf҄<"$qf5:q>;+}J\9н>oI?x׻9ʹIn~ר/iOS:dg[,ʺ-ɫY~ˍKߺuw@a۶X{~aNd?yIнvߨ/z{$o>>@aavޗꃬU <$3ea葰%@}5QK}@}@} 7SSSq\\fTa@t"r31;~~G,?=m@GT=L>b>5aRr96Ϝy<;uv9:ٷyFt{\i[uj{sq9g7 >-^_aY/:U銮w跠GAzd'~ӦGWvx~[Bp> ccK%,2zz-O-4F˔uy88YхvZ_iuLkg%g]7I5oV}{ :a@ <~x>}xz'}m4.xI}KNe]Vu++Fht~ ̯^;Y45j͖eNW/iܤy~/Π8k:TbȨ7~X/i;i6^=f&~5 E4%M{E>@<,7Kֺ4{{;Kݛ=P/KlԶ%i#KvݯWkAe <u^a Ǻ_5mr̝{9.;3(_(+&짙t5 ~=mȣ?y֥9:߲4?֬8genTv~'l>>??.~3Ν;w|Rs3_o=F>F^?oM=vnW߈K~sQpvDicaر'bˆ;n`?/eןy%<1Rᆍq#(ON<chuĺRvO;|8^GrTH?ztGt`Y+_ƣ|p;1xĞbT|ږC1|ͭqXuݭa>,lg/]1f**s DT*o~(E޺/2eM-o_?6 ULDi&V]q1UD̼z\z}|̞}=J1b㵱jm10x?22wO|+#@ZT*ETgfbl1ͱnbۿwCq{{bbw<#,xGp`%(Ge~&b0˯ƅWGi|\ڸg?l~'O˱=ND bt(GD`;%Xy^aT*يC |xi6}μ1<C(Q-%ӿ}K/F[_z(O,~]wu%*nv#Ɉ+#afc*us{wni?m z׿ns">P㍑ٙ阫LGT^R@9F#V WbPꡑRR[şOU1wR ]11}\M;g.yZ<UJK?#ikv+.A {?_wbkm]j?/;z@DJ9.\tjR0_2|ll<&', e }>];UuI;^ھ_ty+)z@uzo5Yxf[I:^6NcF8n}A>uԋ'&kfbxO};.&?!1u<6.ED%_l7bdƶM7Onez㷺[/f=m .Os!2պҬ<{ZoLGQgV236&>6G+?X?0˱s{G.GT*gO/`i|1ʶSO]3GدSҶ,ڗ}g&~5 Y Gqm6l_I}Ǭ> gȐZD/}r5{`aޟ[g4g[ _IӼn8Y?M?Ʃ}?*4uhtCҜnv=Ϛ&h[i4M}̲~LtHl{}q( 4w_['cqb ?K ?wE?18tE~K |.,L46j'i4~dgxyԬ{_iM݆کK+:Q^YpfLr+ ~];,iYoi^Y;K >֬U Yje; rDǶt{>SGNUq.3<;#o^_n3q)n]DK;io>ǏXZe}X_ei#vϳ?y%KhuQilAlK@3n@٭,\}L 9P5N~wbR\m5w~p4N.x@^aر'b^akA6n)oy G[݆eۇ|b˽k⊋gRgG3/쳱w%yG_2@{v%gN_8kYU3t{‹Cg1M>4چ[{7*7ǥUWRO;8:FYo r޸~4'?rPd6V g3xhI C^FV ɣYkI5kKjӬNn@~F7Q90QsqT1͇+cnc=Cń){67{?=i^7jكͦMӷ4}Mz\ynYRԲ[cZ3oJ10qŦGggځ0 D)bnm7F+J e(]o{WDDW#f/D%*Q^QT\p16׬.@gsf?1rexG k@""u[vxY^*J<b>5aRr96Ϝy<;Pdߪ%Y΅q5uJ}-V`q:6o+˒fW@?Py'}ejݬ?J _7޸㲯Ҟ-m_H-e|!#Pזz?W#iΘUi,KQ˙0^i^JΧ՛g^˛4mmMTO~y7 Vlv{ǏH[yX[և5 iz#Y,ά˟oyVى_a&z~;رg1W;v8v쉺  C-O?ѣW;\ЇZ׊PH'a@@155.\̵5kF}&&v?RXۏ=",'wE`E}&hӁ_`yT*_}}JR\{8 ѯ}[7?!-7:;2 cc19ydI~oll<@AրW{{ڛM;xiv~E]_Leeʺ6,{κm=Ͳwv"kYmO 1@aKޫoll\wڬ; ; ;׵h%-m;Yv,odK2vCYX/Y?ymvX˜eYMҸIS>Yٜr Y;uv[ jIXI۷0߬ٯz˝5wLfͷjuPT{aXaׂJy˄;ut'L(Lj'uΨg^_O }n'Oٰ_ۏ~|X7։ ۨofӴf{m&:ǢBɓ{\wTn'NF}Ze;ned}Z;5zɳ/K{izP5_@z"o>Ǐh!hV:i#vK'恋yVvޗǃ:mg=^aifk\ =wس;\`Yg} d GO=c`t9>>>/{B;  ejj*.\kk֌*,@7LL쎇~{QEa={n={n/-[v)2+7PFX^}aa@}@}@aaa}@}@}aa@}@}@aaa}@}@}aa@}@}@aaa}@}@}Xڙx8~DlrSٿo x7ؼy91q[DD'S&waoWg>@T*T Ѡ>jX| } cjE2TAP0k>[3Z24MkX]N-gۇ@υn8q%@W{K~Q4˩yоpP>@/#G~ȑΝG}l 3>~rW:_[|~u1.}=ԏb|%O=z"Ҟ/62>~ekkhX| +8BC[o%5:+];Cw:ammjR=Сc׮;Sonyg@O6?LWaצ5MvW*jQ[zջް@^5z* +P@'6jة ~OF 1 +P@'6jة 9뮽}2> >?ڛ8|?Z]X o7˖]199)bڻXzs1RcuJ/ŵn ,{g0K_π@;#r [`9z }ݳ,gYw>,/@}2 }crrReK&''k7,uðGU>7tለQ s?яc{vݢ"A߾ߊQHyM~gIENDB`MP3Diags-1.0.12.079/doc/1pixel.png0000644000175000001440000000025111202601303015123 0ustar ciobiusersPNG  IHDRĉbKGD pHYs  tIME JtEXtCommentCreated with The GIMPd%n IDATc````^*:IENDB`MP3Diags-1.0.12.079/doc/060_notes_for_programmers.html0000644000175000001440000001063612040502152021115 0ustar ciobiusers MP3 Diags - Notes for programmers
MP3 Diags
While a good part of the code is rather complicated and could use a refactoring (or at least break up some large files), it's quite easy for a programmer to change MP3 Diags to detect new issues or to add new tools to fix these issues, because these things are handled through simple interfaces. I'll provide details if anybody wants them.
Should you want to make any changes to the code, it's better to contact me first, especially if you expect those changes to be merged into the official code. Even if you don't want your changes to be included, I might have some suggestions about how they should be implemented.
MP3Diags-1.0.12.079/doc/150_main_window_all_notes.html0000644000175000001440000000764712040502152021064 0ustar ciobiusers MP3 Diags - Main window - All notes
MP3 Diags
Here you can get a global view of the issues that your files have. If a filter is applied, this list only includes notes from the files that are selected by the filter. The viewing mode (all / folder / single file) is not relevant in building the list.
MP3Diags-1.0.12.079/doc/050_feedback.html0000644000175000001440000001624312040502152016224 0ustar ciobiusers MP3 Diags - Feedback and support
MP3 Diags
Please use one of the services provided by SourceForge:
  • Issue Tracker for bug reports and feature requests
  • Open Discussion Forum for sharing your experience with MP3 Diags, making suggestions or discussing improvement ideas
  • Help Forum for requesting information about how some feature works or how something can be done
It may be a good idea to have a look at the forums and the issue tracker, to see if you'd also want some change that others already asked for, see if others have the same issues and what workarounds are known, or simply to add your 2 cents to some discussion already started.
The MP3 Diags blog was used initially for reporting issues and sending feedback, but now it's mainly for new release announcements.
I strongly prefer the issue tracker and the forums, but you can also write me at (domain: gmail.com, account: mp3diags.) I suggest putting MP3 in the subject, for better spam handling. Also, if you write me, please make sure that my reply won't get thrown out by your spam filter. Currently the email traffic is low enough that I reply in a timely manner to all the messages I get; so if you expect a reply from me and you don't get it, it is because a message was lost. So better just use the forums, which guarantee that neither your messages nor mine are lost.
I used MP3 Diags on my files and they seem OK. If something wrong happens, chances are an assertion failure will be triggered (there are many asserts), which leads to crashing the program, but not to corrupting MP3 files. I tested most features as I implemented them, but subsequent changes made some of the tests irrelevant, and I didn't repeat them, mainly because of lack of time and of the liberal use of asserts, which should catch most errors. When an assertion failure is triggered, a message like this pops up:
Should you encounter something similar, it would be a good idea to let me know about it, so I can fix the error that caused it. I need to know at least the file and the line, but what would really help is a reproducible sequence of events that triggers the assert. System information might be relevant as well. After the first crash an option gets enabled that causes many actions that occur to be logged to 3 files. When restarting after a crash, you are asked to send those files to help fix the problem. This logging can be disabled from the configuration dialog, by unchecking "Trace actions to file (for debugging)". Logging is disabled automatically when updating to a new version.
Getting the assert window to show up is tricky, so if you find that MP3 Diags just crashes under some circumstance, you may get additional information if you run it from the command line (or redirect its output.)
If for some reason MP3 Diags crashes at startup, you can use the /u parameter to simulate a new install. This doesn't destroy any custom settings, but chances are that you won't be able to use your last session until some newer version of the program implements a fix for whatever caused the crash.
MP3Diags-1.0.12.079/doc/screenshot1_thumb.jpg0000644000175000001440000003364411225660170017402 0ustar ciobiusersJFIFeeExifMM*C     C " U !1"AQa#2S3BR$46Tbqru%D⡢ 5Ccd'UVW+!1AQaq2"B ?˔ڔJtشhRcr[2Y'VW@0( v>Lm Ҝu<RHVzY#Ǩ*$PAZͦjJ #TL/&.Mb:ZUV^[=\WuT5?ʍ7ɧ=?DuOT]IRNF䀴؍ n hQ#R亄!Y:Czu uYGcqkuZ#!ul`H=-*9,ٗhSMǫHaR.MB~RO y=hqo_ժU ՛qVĝCvb:\u>✛Ry2)CYA7_lifûqPJ{fwnt:Y}ToY}ToZZQD$zM>7 EkZ >-b_u VBYJ[ﱶ;yuS&7;Ѣ nH ՛p> ՛qxhSɬ]aiCֵ9T&؄&DuȰ:Er|ǘ5NJqN2BV\ By !VI:v_=ER{in4vS</Y/YYANDH>sM8ZF]IH Cn7HcTmAp'Ky5]P )*J K Xl/SnqUv*&Vo&Voūɭ DTzV`$%%H!Mөr*+INT֧gzI]5ĤiN-P8\%jۜPǪ2ʶJ5MFہMFۋi_U9ũr4@e™O+ - i4W(Uw%"8Pl~H6<1Ư}zǧVkOIkUmEUo,7fwb-,im~}YS-4>w˻E-)TpY\F_i)Pg.ӜefRád؋}^QZgW yЅ"{k#zJP$L<`n-nGLvOq̽.rLB"%IMj4Iɾ ΢He yx2% 'uLa9W-QD$Vn;͉76Ñԕeﮢ*JN6<=;Y%c>%$k De|ǻ0-Rw] }8]Qr+A̡2@Kƫƻ>t]G68VӒ:3~CN hY_eK>%ؒ'N6r7%@RPtj 7mU3yD*mK]{5q!K $sGMl٨*^ #IZ QHu':TdN^b.bG2 /VVRKx Y!";T(Φ]Q A5Ukg'ޞۇf;QW$2WRHHdjJy$rnIG M1%SChqrW$K)$\}Iܜ>%ؑ 9q)2IOw߹*?^{ĕG̍>==p|%8TPuʍBlw߲nv$0y tK4VHy9UuW$[6oߋ+?Q~aCt}ߝQZ2-K\U$8v p=m'2: !ʢNM5{4촐$uHĥ5`y֏'*k1e@XФI"ΚVXkq㥱ؗפq)I_O$+d ~mξ {Лn]]G|?[Z]_ϰ.\GO \(W$2:d3Q (Vok,~nN\+T^"9RQ/d*{ű.gQ5R]"Ep"cygF#R76pqOnǟcgH!Mȭj !ӕwG8t] 8~z*Aƕ!*UIԗ5X ۷~$uGd/>SN| \hZajUgΩ}ATsQ =#?NJR!IJFQ;[ %7K )#kOMK9-[XЕkN&gYx"+4j\BVwX Iۋۭ⭶%(TLui::[bn|O bO1iT&[eT䲘L9/s ׭ZZȽ.ޒgUI[U]lt/g/*. qͰ~D3)#[~R<ޏDt$N#6;t3_0]Kr-rm/ZIoj!u9IHN12)94f\ҭ $|۱<+'g:&t_mF5?U41cU%W4ool-C_a/[Mr"TjQgHZl_A=f[Ilsr:@ 6k!`LҒּ]Ч|&IH&L /8T&>DZ[M$XO_@d*ks`bSk v糸`L%m51W}琵- ?1N6)*JIV ;  K94aBNIs& 8$:|ovٱ-qYހW-tjͷ' }t-_XK}ҢK/';eڌw[RAKt?(ų!ɗ'Yk*.[53A"?W[MͿE1 Vy?'>Jթ:ƧJ:q>O]Σ_C\oindB.T6R$}>Zc]u_]eFWVuT2&ڠ)F:^گkir9SCn\GGrmL/@zu Wl ֮j>dpOxju> UҭR:Po %]2d5mq?@RnE^PMJ*8Ԃ[q7`qXRv<_~Oy[s"(0QY8@};o_/=FxwiU%j^uw|5VҲD"Pl{ `%*J|5Cn ~//۶r?7J%R-TW%;<ss}[Z$:c#t0M*P&%1쪝Ģ4'w:U%u,v#7+DEJJboFqSw+!q8[#Xvb? )V;{"Ғ:Rq֒23`7q&@oQicA@RHBA}e]7ѱDj2 }F8 bY;w؁3>Xy|z: 5"(ʅ%U!5<ڵ,̸ǛunM6H'kܦEFtqebITvͼnXIH-P &SD(^Bnx|rMJg&UҔzۀY\gvOq*YbkK)Lt:8ps3 -9 TFUɰ |q>Oy~5=ጟ,>|q2*۹i4ߍO~n<#5W`i;_n_c' ZONf[RpvM}M%?QܜP+!R<̎0V2afxz~V iLJ?;UzhV&mZP> @.#_bݏ2תy?|S>/xa1UzmG<0^"é85 iQ쎢kc6I'k_d/07ҿ)U)/f7#P d AWD_W ewN+KG ec5-̱JUzn]vSw/*MV4 (٭1X1=[dI^ao<02MAIۥ<0e7JP2`f-fЃ fK+aoǜ+qX3~'7ߓe5J MXi6\98WiHv}'*=̆)1[V'bncSYҪ쨭*[mMնՙB1thp2cUCk=V]=a.գaMsS)) i^eGe_H6)5r[ |(Zia[߶YɒZKUq@ @704 e5&\MH`Cj$sҮ/x%ԫqz4\e7W ĐO"sd%d#usmͼp$&-]D ?(r>wx?F=MSBJ߷`0̆Zu 6Ϫo:QT qX F&Jv\}#*f}S0:3'Mz@\jJ^D}0LafVA=}8Dc3 ,`Р [N=JDJ ؎~Vǻ#ǨgcE)."VH?b)ՃĮaH#(tF=C?P#Kb3cҝg ~-Rۇlik:{|`PDc3>3r:%fm61M>2=\ؐm"WzXC1YXǽ`48ĭ J&q\OxљMa=V[VȔt&kZQ4lIzm:3>T !ۡ֯{|tk{k͗T Ϫo k͗{k͗T Ϫo k͗UgպڲH* P4.:6R۰ EK $p!#W98WiH4~[03Lf2]J[T)VXyHwA7nB»JG& UdOmͺ5on _HȤG()W*.t((j; f\XYZPt_@) JA-H&و^U<*0fO&݅=&DGmRBT (;m݄7г(AM|Oʴk OF?G8 *X$\-(le72*$dbiTgSChsZԠ/lUmICa)l1F]i$+c X˃`lvoFvMsW&P` uno%1zEi CIQi*%+ux_|1bKZ,d+#LހtT HHuaBD GjjPÊ%8[ R@ `ͱPǔ&uN ɤ$mR#WԂi^BHp> ϔ{6@QyZQ.-bltۭ~#$1Z5qБ%mLVnt 'nqCTD){T[Q/jXq:Poي''<>%O6 JH%'Qlks9C!5zhޢvIx \XMMb2$WT(p%56Buąc8Pr!.!YE 4GSJնuvQ۴9 L ) (rY8@emun\AeIWkiߵ:Ze=> I-! *) }BEB2,$)i> D/P~r|UQ٨E}N`q4z֖V77<>Ix/k[j ]x+z,}78bėE샗(J[@^ Q*P6]e(o9.& >0,?@y@ikH(k 6DIw'Q Rh9r]m6.$zL畩 {[Y+%ŷ0}¥:I'*A^J<:Ъ-am( VIGyGgFEN7Q4}ƭ-Ih`ܕYW+ T$XE[~@ҥ[w/ܰru;!:ZIRR|"&c8M&HJ@"ہ۽7qtIӜS\\kQ%7%AI+R ~¡%^I;QD!H2EԇI'P= ?揳(\QK "Ͼ߹RH`q;#3;˭/!BSk[VHVӲMa1%=z}H62Uf9(o)K5 )H ܯ(E-)<ÑQaiSM"Zkէ`Oӆ I5^f͛4/rRܕ8끻'I7۝눤?[L=}ʝm"KK0WJTW`a>1%oJ~TE"9[Zt-jq;n ˜+qX;-2gJ< R*SR2G6`7mK98WiHZXl[Ce-!"d͉}]~D9m$)q"+}6Od)%E. : O,$U@K[ρB<oNJז'm*L"R䄤RP&]ݘ=/I*T]CzJ[Rq()H./c~;AB' Azy bWqr䶤F^_6\O X4 +Hl7T`Ԝ1f}{л-x H-{xrWJ0&?ήHi° T4M8xĦ+S,%RJO]Jp|o7ě ? O߷B6r6Ù̸YtZj0jڴJOBSp 劂$J f{Pl0~u&;Tb 2#RPHVtF#ꔔڂc-$(ql&CAB=(_6W~L؊楐KZ"}$P;E6KE׷h"׾s|_x/+?o 7R;1r 8mIZRpNGe&hn RD#R$۳ tPl~ ͕tgk2ML%%(Aٰ%\ ŚƄB{л-x>FoT^rtYy5in<[P(BPò.?K~ O߷Y<%e]v( A;7sR؅R}:PjCZtAA) y{л-x.?K~&"Mqa-:a$jQSm[cy*JR<s]"MrNy/HR6أu+qX'ҋDSM>”l8]#98WiHⱝnԨ0G]`nv6R~_`iae/p6w˵H2듦ഊ]9Ǘ-hOJW\,loqkbcr_tP۫FXNZ،2"UM#+4^khbNzv;KH7FnL2)+ 9!<]-zp;Wdߍ̞W2Ht 0(I7;Jma|cU>?),ROMQ+G,;mقO_(|jT\Wvuxp *mR*g'Q6LW Hbqeu 9AH:@ As/!KU>S)Jj嶍JV:~ 6e94zG) aI98tǪ7sGykR8mv; m^< I [RUM (cT\S?i1T5lhIH):_.oɻO5(a e ŜY*:U w"sxS݈[Gk3#+ Ulp9ǿMYs cASفKW]պ 8H$nxS݁cɴpKE4HKZ%WR1y7Д%=H,s$9PZRoubJFw<)?1،93:}t0Jxf6֔)*I'Vsc-Mڎ{y bc|!)M֭]bB'9YnH/NΣk98WiHkW jrlTju2%ԟ6Q#kuT3w+{! y9jrj#rBI֤1pUbsJZ$nn{;IMy>rï8DH\?S``bWbYkO8؀|)~SN?uv  x>?S``a]ž?}gq<~XgWbYkO8؀|)~SN?uv  x>?S``a]ž?}gq<~XgWbYkO8؀|)~SN?uv  x>?S``a]ž?}gq<~XgWb |#*Nsv @hS&)){"55SYQArr cБ@ee9߮\J]m5@  Q^^Inno<ۛ8 ]U=?$j$ zx$ݎ55-!Z{sg>ׯW฻ FJUd9/IзN7*kY^=TVaE@ @#8hXu+ve߭)qsYvu"LjiG >:fZGVikvmuiXS1dN[QEyIHs <,8E ?fo7~&*@ P7=@ r>> e ,K"B]1|}A0N ?ol5݃t鷌= ÎbOj~׭خǦSNk,?tcW=lW2,1OmZ!p8(1a,K#7́#;yy}/1NFFj'/C k>:2d@Fposk6̊k&,:lObhZ.p؛qvLv{( Bʭ2kkcҔtP$YFu[~ѳe;y@޽뺘B @ "bs5\qɰa9->۶o_y:Ҏ+8߷?m򩩩k4j;[(Yq`YQ9 'yw혓_Ȑ!b 攗W"vwh׳g6V^ݰPNOOm"7{O9e"NxaOpFmy*X6,-[cqjws7TV%%{czFJ9uu !?Idd69Dռ1)ګ->k,gISp$&d7;ykK]] ەQ*ub_ @ BbIIŽcΜYʧ|(j!1сbn$wG,~e` `|t>|>Z<NovX%&q8bZJJShnvaAZ@XlF׶/ڲ\;X 6 7"j͏)|~Jc/O$JKE?i ݻ o .yY4M (2=z0d~wˏ@ @ xh'33j:_L>?зX,dfhD `󧿇 k,P9G^ͅytOxDƘoou۰lNh>"b=ƹ0 -8Ht@Rq&IMӖ$ Nb="`k3fx!C$.\Fޡ\L'Lyy%C l"XVƌN]]hxjN'F l2av8cl?;Xvu:4|HEZ(B54F5&Z5G|ߚ0ovfot>aAnZ"yy}#ý99ddp؛+åᲊU>jwsX:m7b:8f ==łl0 fv{fsH{c:Ng=Ng}~9͇Mi;llim߉OdQGZie[v} ۝h#$C_ $IFH(*B @ ǙOKK9;=6!ճ/N~gcY;vxv'&ڱ,]<vw"7؋kX @ 1p5Ѳ#g_&4܁bm"C.E_-@ c'P]]KBBj쁗g(BG @  66$ 8-#8[@ @ 8q?;@ GFh7{z%JE @ ㈢"}Y@ @ ?.@ @}@ @ B @ @ b_ @ @ @ @ @}@ @ B @ @ b_ @ @ @ @ GQ m޼{'`YH$I1/ozW_γϾG~IHHgT Qaժ|"jjjy≇DHw_q:Ԏݻs7k4M0#v×;Kr`Fo69E9DYQ 58}Uőb'{&c$r+N}}}L>k,f̘bb`6QUEQ"kzuiS({pAzT|-vL$2Z͞ A'Ox/Dazxg}ٳgܡYɩb;.ˮψ=[{ ơiRD7Q+ٲC~PfO, %c IvLV+N]Ң vYy=cκ/5 Y[> àOnO@QT 9 djG@P¿ b2"hp*~IkZsJKy6&Ns+Al'p3Y'w,&{sw'c4UN{ǎTWW3~NI;dٌ1CҫDu`BJUP /<^zl'P|m*ʝ87{gb&>[ۍMdaٛ(^5wNbmcXu$)@C ZM ?PCHHH@Q4$ܮ u~KKor-~Fu͛Ν;1 #F4kHT.QVJ~#P4_HďSR@cP.{" vQE=D0'I ]^R?Wꏕ*Uq?yUY_d0qX ɩ($ 8.ر;D:w9`>0_#>|ZK~駟_0g tT~Yd ~m#0lذ!B "Ʊ>@{س?7驢"BV0%L -6iyCt[y3`F Mj z\t"%jކ)!zbo>4\?qfүqjzL9&3i|^;X">o̅-̛_SF |LŚX=" 8v_]3/tGnw\yeLE9}jkk;),,O `޼Bn{G<33樉obÆm5N; EQbj˾ ^zY{.|҄o/{}I'u91Y-ݼRxoضFo4}zkۋj7Sѯ.~ EVZCaa NO^7 <ސ)?7'_Zm4?q!~"Ngr/\xy^¶gٸi;tn_l?fU&fYa>cmKEE%>_|UUU]|X[n&]o=Hȸ\n.Κ\ O=oHFg/s >I 6qqqrճdɒj ]ױZ >X4/I2,Ǘ:{lv:w4j6cͯh/HMUpdMkNj4θ<>ͨhXɼ_bu0qxv>}nv*fr aAA BC~kExt}Y#t}">}[04)$'MCJ0FfBs:P޺6g3&t'%.W ݿ?V.O\}A Sg@ t, #˒33gkӜ! ̉Ű٬pï0a{&T>"Ji )MM@bMd9YY5ϘB H4?w6O=?9nY#)qO;bs٥x'8Qdx7~9~O̺, ]S7 7r8@r{h~?a?aqG΀xw=^^p'1x{w;/ |X.:`uL9SSʕ?.|AAqRSY7n0iнxe7K~EntR뮻ZGfeVTQ=p1cӧOƬy1|ָ.Q>>_kNzӧFaT7c/ٚP 2[:t @ϫ_$SdH/vжDaylrAm7%K!?'3fȣ=s.@Ӵ(Brr2ee$'%HJJb۶m/dYf-ZKzz|ҩcc`0DG7žr-^/. E0lG^ 1@^&t1H`ȡ$j"P@,5X0(o蕠o: -F!HOw|73UU۝<^1OHd䈑h*?IÈ:ԍ_ g4׋te^hr#زu{;\؋ۿzgD;Q³ИT~PӸ9de !p͆͟?$lV;Ά*oZ(*YYym'n/lY}ص5;e'/pʼ[%%%Wtľܙτ :4w b۲e+(++or w67YVQQA p Tڵp`~O%# PXc+zDGÓ^ocm;Ed?u}}\vvn ԡ)LBUGdQYQV̴_咯xˊƁYB '#+d}J,֘:u+W<ō7믿_|L 5-{غ}+̾\4M#..I Mw^ 8Ӻo^)Z˖-Cufsdzp4-  RZZf9 =u_ Iom8V-ٰLSd,{ Ix3[V.X_1@>jI1Ij:ߪ:6zٷx+?§Yܓ;.o$ Y$9TghmK,&ՊbAQ-VdUuq12rym}`Gt_9=s=ԍl ޽34-f]kfvǤ=W_?be~̚5|:\tfZe,YIMMBQ$&OKrr Ku>4>v.FE|\sZ}?zLÂEѯm_/~~WRȸ?XvOAI3o2x{Mdlڴgu{dnCc#Uim0-K~~__}GiV^c~.k>{&{ ͵\w/ٳ[~={nk*TTTpEuJ~aϋG)oqPҖ7"zDQE?|eٸt ~c-/)ҳILm$"É_3+E]C'ުpW~>^=}t`q>1]$=U>4{O:D, A?s饗o;vh.B.)x>>~~^unV#G6l޼ZΝ6fÚ>&=+GkeEo}=Ԥi~^^$kȽ:}W1,&'uװzY_p#6m@} wAcFs߿sυj9z}~v=ӏN1Oii%T8~7ac"3RztVw_N:kxQv@F^|Ό}ezkqe&?lpzZ n.Jy=C"p:j"sGb/w|ѩr2$'ˍ7l9ܞ{̴$&IPp^gZTUE#\GoEw2pHr  }n?^xkPgfS8S4s6f'.ښ*ި.iTuE=Pg %VGcAе aL3jp,3s#zFryHHZleK>ydfffWNF;ߣ0 ֭[˟|{{ys45@ b )!@J@,^V{&~7M]E b)vԄ8#E&-ž_{G}[7!krxC@$IoMϡ՞%!ѽIC״w0iA J,Q `[W,X6uTXSkϝE 0*N.Kҁ2֢X]Ff/3nzTtv=dm-+`ݺ>p9YYqrEZ][[KAn233ɺ 6gO`Cdg ՛2et^+6xOfS׹!P~Sa66-z~Q;>L2eBcWOaȐPtF*[l磏VfM^F9 `„x|,Xm IKs0c@,Ꜽ̟! nTUE$Ҳ8ݏNBmm-/1|S$ Ѝj&N駟o,e|f̘џi&|FVQ|?y~Z+($)19]߃XcSQYLN<>\ToP)=pNLɈb~c̽A4Ms."=z1>׋1=Oq:/Y}$I _zQнwPOSe,_|x-sٳSNrqex~˼c3&+ˑe K9l"En+P_X6,x{D엗`ϴiزe gk=t}?E]Ċ+8q"/"W_tx7:QǜOCa[/a >u HIA#0[TBnFT?= իn"ߵج/ss_/~ ^7 D\˪U2d8/ 2x0.N' |^80}u)nN$ǟr]9;{e yh~tRb;El 7_r%'!oJ/Eym̘ IF5A{5H)((`ʐ!Cرc,Zo1CӴ޽{c6:t(;v`,]St Mx7H< 8iо>JoC IH8ɟ9W\o;4EE?GNW=qx `޽TTӣG&'4HHHkS;HNNnRIm}ymU&s=r}=IB$ġZH&YCe;Jаv=Zw2eOŹeh2 ;QJ'txR>\`3xQMf4L& Ð1$C2" ȔR'"AGF7 :hoM'4 &Մq=HCٮ#DӑwVsm)vvMO0G_n"^и}Q@階zudàZ(i}l6\WWհCW_=rػeV{q:dW׿Cee-[^p=N_4r <构,Ky|m O?L_(0s(eelPЪOOOŐ/HNE.ZicکwV0U5ibA?OU5z}2"E0 _O+)a l*SZW`1d8T|>n`Y`wkdR;8>cǠ{̙sYVV&&ҥihhs9b`РYNee;vtZWr]7o26BzW_̢E<*+}^IAGW/%$$rӹ\.?>w^'Ofʔ)@^p!?xh7uxY)cy{%M<9q^SE-c}EvҲsXu?̜+0ylܴ|< .gZ#1nG1o϶V |'~AP]w _ 2 lf [.-N@x1,jp;g*_gKIu$C*&]B7n `$e Y1 qJJ)C#2.k!55N?u!Mx $K},jk} p}@AB@$BS4jPƏ <^7.Z'eeU>>/>륮{^EQ.i6hQ ;u5M $Of&U5k4$dYƱo_9OHKC5ꨨ RZZHVV<}f0q|]iv60a' ?HRRBN[B )Xq=NEe2KC8OeUIZ,q!sxڑvO4/Ro\GI^6{=,P޽0cif>Af qqq#_G;좠`3gNk cƀ5\5\by=SsYw iVa֬L/vq=ǖV^X3wG=N8vC=Ċ+gͼyZlxXf ^3<[oLϞ=|`…u]\uU}:]wzGԡ@=* )x{nqQ8!jV{E}mBk$or NKK喛o‹f[oaFN?Lyyy[SN0%zyAAAu*ZGUɢfrrrԧ? lϣ\':g'ch bR&oE̖)%$e$q jhܾDct~I@)ds~%d,2.=H盛Y7C.ҝp?sמ;\wƣk[NC$vXX,!zh h$x}~\?OCƩeH:l~t"'3A}W^YM߾ٜ{lV.\qH\xTnOM<D:Ow)EEtݏ墾~#G?a\.GבϕW^ئvkY/oVۯP]]K<<'zo~ G:QX=!-@/Oynr0`f69'e3iH:/:W bIK0~` .WW]5vyE&--{KXΘ1:̶?h4rڴSp8;Yb޽!sEFr˘4)ɓVd*\{m;/}<훀?˴WWU?z;wNJJ <3 IDATIII\uՁ)zӦMfQ]]Mݛꫯ[ot:4޽{O`2kQUٌbl6y:ݻg)j1pJB/"WHZPr~OLJko6^kjQI7Cl`}\v%6m_|97nd駳9c84Stwp0*%%%M*MolRU`<5Ԗ@Emy 5exzd yh;1MLJi:B]97;/+jcxHNM!99Î!fds(tXCȲYQEQP > ߯נ*kx.<t=Gslw4eCQZ]h{%e:rlO1Uۭ `a0[L*(rH,43~ƅ]hhh$GuTG"~~J_.˱&11S{_F ~8`l2ֲgOIve2y}Cfոb~vE?tOCCp$r2c n?U|,>/FСŕA<>[ 3N $pxk~}Plvy|T'dIHIdS6QPp]Z[Z]VZhEp"} !}l{ IȞI~^yr=s<|yʈIkKwJv ?:7 k⡗whejv ScqԿw#g:t:=sVg֬,[@ ) IdYWkF o*￿{ウ4EoG.CVX͛F~x7Ԃҵo;wRWWץ.R4 z!ܬ/D?G桇஻׿5eee֢*v@ ԥOz!.?yfTUi};* I˃rQE)H`0t Ӯ~]y?r2?LII ")9.V}DanL䱉4l$.ωO;)~ĿòMd'TWVUjT0͢9~}Oj""$Pߡw I#-h~vjZŋlilATd4H VA ~ xx*:NN ө^(螎oՌ?}1/@{z/GYF_ @<܅`40'];24$( rpS$$>(tpX 2mTY$_A3 ?:n>̚;&ϣǪU;hnv~ @tؚ2c뉍aӘ~dB wq5./?A~Ϝ9n_|1鼷l#s8ku|9%'fa۲CeǍEeJJm9wRR0[6s$~qxeD3iѰMoӽS1%,h#ÎD^XvڍO~ >Ϟ<]֭ū7x{ncJ~~oZ-RZz_yWHo|s/Y^wm~ZV/1rrr4?d+G}}l`غu+/?8|0o~<9O>$]t=9w+Q@ D[:+ݒc Rw?ΆZ;55 |CL&L;coE_ch6èϰWoŔ4uXe|Hw&>Kf_HՀ|cz E>*L̾]3DVeicNK?9_R=UFk<PU>Q * FQD/0t:/)AY$$$cP|׫.yoqqo>f_ݛPwdi<­_c2j>QD鐤#D_|o#t$"D Y A}^bfF?q:Vs|G(Ɋ^ߑďʽ#*oWxuv۱0cj"Iַ0{z#8]PTI08n!2-^|fMܹTFū~;ʎ]pb7sϺ5/zdbQ{v%d3*={feZn,MN?wQxh BF=0mO~847PZzO_Qdl6#6 bbl!ϻAnN#pa6oƴiNWȲ“O>5,FEfltcn2x;vlhhq5_q=WhQ{1<ȫ10'9j!r$_?OnFAraZX,\yٲe\yHb rV󕣫h`(=[t֕=z s=T}kV)A KV9fJe+Fʙ+ bg|{>Qqlڴe'::믿+;ż!6"~7>nEQl|mEszykÀȴ\f!'*fyo]W= #yjv =/"W\ǢJD,\x)]tAȉڵ_3~6/?ǚӟYVXhK\ե5p!&N/d:zDS6t؞otuf7ʃdYzqx<<~V?\6o̖-[@ @vv6#ml۶m۶-dEEEl2>䓐׷N}RŖ'}Sv3y}a"me*áCȲĶm0[LW4y.a׮Lގl/]v"cNWIM/G-\ ]"Cby~477wòuU5;\m, F . #]|zΊpu`z%y箟sPd@%'^4lkYLM?}dl1UHzTDtGQUʝT:@ Pw@G2nB^6ZhРᄄNKit5HnՌ'D$@TbH6_#Ȩ1# N"~x1)ǭumN.bLEE=::;0ŋgG\~23ؿ:'|>b4ZILB[x7Yi.ЎKdd5.[,Q<hjjfɒY,Zt6￿zG0|a v9/`6G! .wK[j;>{iip:*c-.̿<̓obKp^_7_";|6VzI-2_D.Ǝ/ԭ3GA%..6u֙<̓=̙YS~b![<*hDgzGFUX{q(~[|4܅qq)VO?6cZ(/ M7ķ߮曗l/_&rl`tRrrAڈfN'n<"IDbq/8s8sھO2<?m׿v6yrss)**pOZZo@ȽK:1خ:;fJ8 aK11`/{߀@%w$n{~Y] ~Y{M6xX,f,3s?bڗU_iFT@LےAXE9t Ÿw&wҳq0r|}%3V{3} #ɍRK$ A ƪ#- Te+"t6gN9ģϯuF[3IB ""BP"S& 4szsN.~$NdW_hmfAᐫ|bNH2q/N S5*;'$Dss>eJV#Kbƌ3;v --*%~[^Ʊdx/v{K]ӳtR.jv,G7hљ_X 7̠F**E~ t} z~/ q Af?LZ|AUgG/m` Y)|l0.?SVB!5[X++>f߾,_>,Bt`7 ̝۷U>`ٲ;}(1 W3g&x-x<2+Wdg>/)t7$MF6v#--W_%%0.'O~HAAsLmh.:H/B2'=[{;bH=7~0 >_O0d92IT_g"Nrp" tP:Tl,32} ox'cSY 8Ā_}R KEE|iРAAzz]pGQTר8ص{c2?uVqEgsY:&#92)Sk0rdiLCUU bX5+l6CK8~:l6j!{غu'۶jM#--:kVktG7>h׋\yEIUU5t⬳f+F:mD46UNW#/Z)瑕s+qY#ygędE%;%Y8='Ndt}/Z\^^{)+n#2 t\CŐ9Ewy}vX6{,lhظq wY_\)**fƌi>Q3'7<_C5KF7tZV;Zt:\ŋwOuu57pÐn3dɒ%z7Sλ@G]]=;wf#*2PU_|„j0$5%#!P% ~cX 1YG!F 2#!* S~#҈9g SUUdC=:t:.U6x>Yv,I'"})*hD9;cFw[`|~1G<}z^E]'(%.Ѱ`VYjyU]vنQ^,h~ |gzM Ïdff,=IVM( *-(ܽ,?}qޓFzz q׽>.7n,ƍ+=TVVZl"''+VSdC^^NWOW\q>o= [tE8vv}%a^g-~@FDrgq\no͕\:=Kg=Un~z= gcbqy|n?X俦PYYACC# AYcEuuֱqflh6t"#n_ĉWxᅗӟ93^ ?˯嫥ŁWHP #[oGw\tQJCC5iDEXr%mW7o???38zX__~wp8hllr1}cz=^ &T%u {1EfkAn"#0 ^N& TY0QSXQ5.&ئLsU%e4w&)bhܹ344hqqzU8cJϋf+ND oY e>FQ.(h#(~ּ5,gW^MSSS^^`ƌ1 ][{'cc0 2k#(,3ߡ7ª]} MDmx&N:(!EmFWXкYc!4hrdfft ٗĠ~UAAMFٳ?z;i'mGZAA9oѱv9L4~@? /gz4pǍ?A&)Θ(@7-L9Yj╝?XsBQyeg=UyWDvxTw8&%/dW.w_?ْ!iF>x5eeۑvCvg[ٱc'yyc9=Gx/rd8pwYζm~[SdY߿s0st֯e̙s$7}xs啗sE/ѱx)*jr[[[0g$˗/g\{G?+ ן­cЪyY^dHFchCĉ#ߏI|TGE?c%QdR IDAT%JuRYU&MxV,ɣI!v{M={8YSS]MSc3wy6r5W) x̸DP>1c[#3b~&22Y32zL])Aֵ(К͘1-o 4h.D~6x'$ 'm^J7ɖ~{_t3fdSW׀ffڴ6̧lۿ7={Eo_dժq:} |۷SVVW/"::{#"\z<.tӻcN"))kzQy饿⋯nEstM&z<ؓ8zضm^ޱc!eeeֲɓ8'W+'..k2o<.w/Lcc- 5nL"9Gn5K?vlV>?Pz.WKM*+~{*_~yHuuaC_{9$5<*\-]y úIOﻚ7J9N + נACDLu;r賕'0sؓ^̷; }w.#GZE32HUVW|f$pE9[(*5 DZIΌ۾˨#z~kħG{0f2R)(䜑֖F+c0hl`1`&DA&$Uf^>7jkXK.R7mdbݺuŽ{ꫯ UVq5#?0կ8ewEڻ#վ322PUC=rʅ#fM%oqnMffO]P22/@D<1XǾz$$:/։7!;̛w(b48q6[^^{ŠX_W0ZG5n+%qj,Cn1 3)%rΦ>a" 1rZ!6CR'p^)9ӈd7r/{"_fpp2Z44mA 8Fbt{Oz(i׊ٱNvvW^a1 ѯsشٲ{#m9PW[dnn 4*1%rg 7|'GԠAъOpok0yTf^0Md%Lom:/Q:.Ƈm\Fd!"޾gCC#eǽ}*ՔGw}o7<ԔD ڵ]vQPP@aa!ٳn9OwQ]$ AOʈ44عꪫy!;с4+* >n_4j|I8˘(]O(ş2Xxs=rL$%Ucg vtY7_a CPumĞx#a 櫶\F'-Cq4lqq1o1̾+sO;пZ`#y7tSjRk>ꖶuQAP>" a ^-W\r.˩S dy0qv2BU yb6l%=ʍ7f1kV"Fc:1s/Ň4l'] r!f.s9;I}32zQ9Ubs)++elv&uDjvCBZS*M:*3b2(_(w>)WN$Ж:,SSsyX{L:Y|l۶G8xG⋵IVRRb[NEQDg0`Fhg-ӧO3 yjPW%ԫ0cX@TTTHCohlEQd~ncwmjqh%664Byyy$v#%Ȟ\+-=DAA~ZQ|>dʊ!WAu]{9QJޠ`%`NFh u+ qWCP,}2be‹{1l؎ɹk/ D -q |04WO=;FdddA 4h8(*:xbV,f3p,X0-+dğǩ(!u1J۬sD&2 2H( h>,ic@52(EZcc@%$2^@d6@oD," ^@DԖdp)lFL jck| UU0$G}8#6aIja?v{>k̟ȹ&`4%''3^֭Aଳ OV>B{ŋ3un։z _"pՌ>:)u:J {4mIb76dN lFTT$SN5hoy+/}KW/~XQ0IR?xC 4hpCUUv[%|q9:,d#Q$_GZ)[W+9:d11\xy!K/`Ljs^"4hРAS藗xV<( ,\΂#=u| ;9|f{o:֭A^oaC :$_|E%?>)e%hiSUF7ׇQuSS!P8ɱ ? $`4ȲJQQ>Sid_ 4hѯ{?X( )tTwZwETV5Fp˦Mux2æÝ `Ӧ: (-uD8Z3:]xV^Ţb o#n{iN$5Ղ"QWnȾF5hРA ݢfR~K/McɒLF&>¶mv<*BaaQQzN?=H}XD p Î6u^R]ُf >t$ex#,XzL&)lSBۿ$D3}TUemM#4hРAcKhis)4чm\23#3Turغ:E@;/&DBi,\x2<"օʮH=E8oB .WÇkРA !}VS_sGpMYdfF5ɳJY&L&Ibf;TcU)SbIJ2kdp裥%@D8#6.LiYVIK~}K(ժ S>@d#*:qZȾ 4hР;ڵU_ts晉rKcD#I)ϧ{w#nRŘ;{E {w-<96$d() vX:'^p ZDSp8@L1}F0%@y&ܾF5hРA ֭W))q0mZxdƎtZ(45ˋ&''*D ~}}c{L!Dž+v/f))5zeH@LLaYSiI9Jd`Uw[_M?`ZMjРA aYPPn"&ƃ ʕvݨ*&6mJFQ:->14嫯7ys2~-jt)_m_5Dp:md5% "9t(AfŊaϦ&#x|'4 ؑƍxU u݄ϗLC?-23Nc4'OdѢˏo%vjZL 4hɶә@MNfuuuU횃#EhhȠ1ށݾ~xV|-47f)BSS*Ng䡲rOHeE=HF{xIbQ]|\1!"pVzur$v <|f~^o4po0Pd?Clߞ╌ӎG>4h81q*cMi^m(/^Ȉ*fE5^֮S]-fyȭk詩1wL""‰-UUz\xƪawv>LŔ)_N*^/|:Gq`WU0k&o_.ROSDF(Ml`녯ֱu1~fXPؾ}#GI>w}{΋ / t5h0|8ô 'ȲBAA?_Hee9YY{x.8 Uc2s5k6&dIvΌ*ʆ 5|&bbt$2!|ķhho1mZ:w5xS; n-:G"I -'CJ1*s!s9+[ Yǵ`ijncogϞLO&::|#XR|>mbgk;)AEz (Jh+$] 4 N~0‰5{X$32,iunXXhɈl~Yn]6PQb̘h&LA <67(+s fd5i?UUihb>DoCGCU Q$5Ղ$1deh݋#`jPU5luWV( C!_ e+;;h_GaC[PnhРƩ܏5"%%-_X-0~z^ۡώ\^+{TN֯W<9KصC*7FDjN8yZ7NgT+6am~"QQT]^"#$'+{_G} QQzf)GQ#2~?UD3qq&JJZ(-maV hd_ aʮIXg9ybV DD9d+TUxdbc DFS2;hlMb AOpQU(u,~"11ҬDYWFעwV#4hРAIF+*\V(E-`Q ꂸHy$3yy6Ɠgzpض&cDݧÉ@@IcD3II&D1|q}>7d|_UTlᩇfbO(G_V#GZQUR_l]@@FF^p4w'~L""ttcX? pdqLmۡK G`IK`0H9t#Ⱦ6;8xz oԨqZ{W_icsws/m{:^RS/Y0%K2OֵeWmx*qy ɓCc.u-$'<9Ql軁 p#}iߝN?DQ &mþ]eohRQBII av_ngժ}鄰%.]K!_ If%*JO}*7am}md@#323SRRpB՗}:xgBmᣧs}J}z/A >d5+@cP2 $X]^phs_LN6lff˝ vJ]#UϣGO]zO+:]zݥSz]=?4d mm~ۿ6Mvgf?f o_]s=tU0p8^]V=7nͨQArfݵawdוNF i ̅A+)ia׮L&O':Z jlJgt'*dCD$\{hlaHA"メVrnw,|\wȸ?Ccte_ƾua@S{u5GKY+_gXy,X4z} յd`-}h4wVOuu・כ"l4upZ_=Pwݓm//}׺륧 Ews\_~Y?YLE 8ti8ж?YNF IDATQQ"?I0!hIS6W!?J7L``+CKGQCSH=霯5ߊRWPRUۻuj[](<DFr9SXc' x<2^ #CQo0e| Ϙ1_BdyaҤs7ZP]mJh;\}ؿ?v4{k=+|w 4o?mܹ;?ӛldee%(&#[&;_]?Leݺ}L貁\^r,Z77(LCje@cO?u/SQIL4!C PWS1>?hkyK;o;}G1j(f P56_\oo19@tdeR2V r'`phhu} !CqAyIvĶ<~bC!~ZeUz}esrS\CZx27k6n5uON]topq[Bx֛,ݍDG:5Ujk芁Q_܅XЅ-Iq`Ѣ0g>4W2־Q`(;l7_77 JB<+W;1#G47O;\ݝ;5pɲf16˵K=p9k 9طoGHəԖ`v? Msr&uhӜI}VegOݝ߷o1xPD;=1ȈfX^I|v.='Z15Tj뻯{3Mi"P-n0kmӞ}=g0:,'g{n޽; Pԃ6 S?ٲѣ#,<3Q=ka'f&L8j2mE[:5ӀtEdA/nL&#: 1?$::#z ?5y\R`&&@JQ1el_e#,DD0~`a0A_P9PWm =J 1݁I_/$/Qk85wvƌ̘1;)K:{Oi]{SΎ7dYeϞf^{m?7֑j{yO, / hE )(,cbVTͭkn\)ي]LՍr)r$9ME"AAžwfc`333W5;ݧs~|;_Oj^qb cl5g3K2+߉Эۉj4HͲȠ^pp:-FXZ y`0ko߫} AXߦoTk3(*;PԢ7?'䓟G!zNkq'kgsjo&ΚIjGkgﺿo[iW^/}zu҆5kz򩕿zn" Q037_bNzjpi#i K2XLط/_}*lIrΝ/6c+7[9N@"Ax{uj@ FFv ddm3D>+o92VTTIҗ׿5Ր<}Q,r Ťxl!wVDQoj27j rۗO6*KNX]-ac[nlC#[ƵVƔ쓼{P7?_?l_8>|>+)#yׯ07W@4}nY3z$ ss\m# t>6 18U[&ljX_/x9Zk#n2 f3:A;YV@>I[ z-_ػ!\zFqٷ*bА ){o@PFNOixe8f|Kx!]9X!գw4H$h6I)& t6BeEDNU)&B V3 wMR)gϦ?a`Hӓ\aD -Bvddg V~1Jyf ^P1cwR~a}7X_XVċ/_ࠓ&"na~x˅? 'F$LOqz <Adp} މįWS*H+jxMtʾ `P* q \<y+(jcG}!I[QݷOPCfӌ17l63dX6O@@@;)?}"fp矏۫])Ǧ  P3NEq8s& SS!dL$z WKBG6n7#29ѭde7#3~&A0Ւ_$4RIacI]/obo0>cEg񕯌iJN{.YX&{o@ӘDiLT]=A9?btZa6_ ai(Jp싢|C$n7ڞawUo6v 8]t_/4 q㭷wLNMuTx p.18S Zᥗ~ /D(Fѣ?s}'Nʯف wߝǐϯ'G{xb 6*^M….W_Cpmo$8~-)o>~!8Ioox=^h7yǏu}kEFA_;-Q/Ϳy>:[K%''055oȈ_NӠڵOqwogO 5JOpWU I^dL@@@@`|0?Sxq =oc8|x} "^M D<`LdXYpti9 xSpQSC+[dP]PTVjcB2Ia` 76nL $ˆ"QTjF82qmyD(lع3Iff(؞/MޚA}9N7ԫՁn!Lj]k}E W&qM xks}n@2&'س'5.x/f8th>]F:EdPTF>w5mH Z@*E#tbp EeEEvԭrٰ{w.9RZ>]V7vvGWվ7y=9p#ZVM ngk司꓉zڈVGyT[>76?|~~ۑbD?{lm.FmE|*.]ZP㏏Vׄ>^~Mj4S."I # t޵U`{e,ʕOvAQ[di(o26֑@D|Ϗ;US^VF]fDck&^DLy)VҮU\.B: 8)jrR~jY9Ƞsnl 66k硑 Jsg=CD\ĕ+IDF=~ofe_fdhVvmWKIFȞ}Zy9@*r2Ufi<Ê#G .̀e.U-'?j0aƇ$m۳O606@ƍ 4ʾVHϵ3OĐt~Պ}B$^^冮Ti&h# q*2v2~]K̙^;|+ګژzcw=u YՏ9SJc6 crY{ؽFy@4p؅~ !q"<;vf>oj5cǎ a)$>p{*Rnr{țQ:hUjr譍\=UiT3VV 8uj hLZ:]*8ujKK9AMSeYd(>}>*(׋fKx\$yGTjg\%Q,r0`6Ouy+݈ż"-a~>{k"}ݓ*4(sUJޣAnݣT6%VZvTxhIb=AX> (}}nv d2ann3H!f>q#& 0.LWo:1b2m ہ>h С z"_,>~C7"dD bp F66($\.c"TbF 4Ԥ| *`[09kG<:ճeіhE{F%GU~oVގ D((JNڵ {ppל>;Ƈ.b1ȑ1b>B5MH&)& xn"@P AG*E#qahgLI`v6 |.qQ`. `Yz 1A p4r9^ݯ4KP,ɾV7ٿ5߃/  ҧZ/JP,"I+% 0$Aw-Vk+t#j+-9QZ֫E|2x^ă. -ll8vlGgOPĤ g2YϦ7V~ۉRb:N)V ǎTba2ep{yS 'OfH[1?sg%28}ze8~(N ǎegåKa^ +hx!ZÈ$DQW04 d_Ox/D@`p۫zlļvf VXOZ@Q.\2/? " NP+ U7Y|{on~cp쮲XVH*v?={"=?(8M|<~^x@G<ȑ,-ټA<ؽ;bzIia0>\dt a୷\ػ0Usk_UͅD$K,hMt$;!ĕKO{<^ĩSKyct4J$ 8vl.$N+FG8e$yp9l'DQR$`Љa!;LtZ Yd~uX,fx<A{.Hjd2A |'-̈́ [S IDAT@-Wg"ҪV~o5?>S˥±$'~8QAĕ+|y?> a1",xyHyu牠p,r9?Xx^D6I^!&apЋ3Ne\0`vVFzQgW{N"UjȨf9l ԃvK`tJo{rN<+9eTڌVRh#1(X:dO{Vuuo0""[+eC[$X,& z{ؽZ9-aq1 0fbL Ho ߇+ۮ7BX # GШ޿Cd!qΞMƍ b><]<:E+K|>xg/dJf\6D".̈́LUxvcc8 "TbF(fI'cacG^YyꩉM+v"$\ZkffˡͼZiZeZ?c[ovVQ*8sfӅ¯Ƹnx }xꩃػi٨d2dl[X|i}|A_cWsZjC혨*xv a!ItCp7,M?8b>T'$ ^_W#@]w\Q[ZIHnA ͲmlǶ"hG4A($F ag Q7>I[jC[JRٳ $ׇyZn#cI9n3?lj]=< L&r/xlllFe Xk{$Aᵚ1:kG"R }@r O@_tk#c=j@\`WDgcoLc|< dp=D"ˊ;Cp8C)C*Ej5#r{W@x͛6(".ann󄐞 @N}qWzRy>4V(㍙4>t>w c@QydaCJyxf P$:RZ~##~Cy , Ӑ+s`tDnħbn.{HM~*BH&-MQ-^ZtyG 9RBԕ=J-l 8~xwGpW8{6@'C(4m1.dJX_/"f#d}؁9 ;ѣ?3|U*KKˤE܅TqJ<x`ccƏŸ͖pR)c~CF2Ȳ<8N'6CI @; "66(pjz(߳O5F$X,+`f& >]r6\zתF2y}[i9tJNR*VA4Ο_cáC#zy ΜI'Q͖h9iD?}MCĚeT)Cl_cy9Q00m#wW{699 Ö]Y,+ "AV$G+kdf 33A܇V ntmk>O[KkJ;Vc:=y=}5N@ꂀ3`Y/!cǎWmuJ%t A}HXsܠC>`u͌V텢BQ<7T8ND.l6!vٴ/A}mr$yք쏍m}l,9[;&RG&S0…c‰i?<]Bz}y&V J%Ѩʙt 8V  .44AD@P3 \|vC^}/ ##~BNSX\vU d+Zɪu5y=[{r]{k=ߊPf5 9uKVx;#i–s+p:x6ʕ$wϯȑmѴi%}r6ƶ Vs66j5?&Gt >^Þ%r9 Yͦ[nmHK0 ~ðu|;+^ 1y3 :mݳj#$JfˍZЊ<73Zjԓ뽧5A넂ԅ:z%WLWIAmWz 8~ Yt/w3PELM g+ه؄c-Z1/Z"d I D. A69 , aani5 0>ɓKMޮ)߹\쨋RY )5:rm<0JlnVz{=,H](E&Sq4x _{x!^NZ`D2v6[]-yؽ'f</QUk_Sr r9NK˫ѧ:mؽ;͌4R)ᰫkY>Ip۟;Ȟ}h5t[UgʿWV뽍oQW\xVNy)y^fduz]n}t#( ."QlF[E,6Wؠ02ׅy~Ӎ_$Dnx<$%J%Hd+W>Q};f ,N+|>;ʓ ЧaxvgRj)b>Q;e-kZLb b˅q1Q? ŸϳFLRؿ?QG}# Yu /GvR{pHi)0 __};T#-ۋ(J(X0nX\kb>,3FGF=dJ] d_rq\3vT+n3 I]qy9[ {}- х~>`6Gap۲ݶ14_Ƕ])ZS&ٷX@bi)Ō0*Q>&׋X[+ޞt6mϾ$IXX…U6<8lx~q,-09]7 { E9ND:́aȱ{i^NC!c>[5Ȟ`2CC>D".$2,CB jPH@@@@=8.aq1@WD_]-X xLLf5dellp`Y^xv(9H0:g2bfN2,7apЋ;()J|WU37~f:`jH$C=NE W$qB!|VLiC:l6axg(Z enDN\iGj5w>.tC [Aa)lWN򩦥T "JZ@B%p誕E#\A*f ރDmHnl"\aA$SHv #ab"͌<W?VU8z'ĺĆ2)`26|s -ҥ1;kprׯa2 X[wM&@ߍ !wމk*rA/~A"F0hYtM+X$|i++)7?A<:Ԇ;(!fqFWocnuAS=EIzU{9:'?e+೟x^D&s< ^|i<8l$IXfADx೟Lv#2ROVp=#DP}(JXx'qHz&۱5yJ֋ ͛i ܇>͢6WU3$׿^" E@@@@@@`|d2%;\O޽}]u; M#gfL6])JАᰋVT1?(J 0^$~IP(8^s#v!5ܼ!jA}QUIky9NZAW@$ܼG-']Ly^J,+c#F6[b AC0E vr ׎$ I#g.H_g2}ݧ$Vk6/jA#Ւժ\Gre+DlÿO>5pXT9vo52(Ouvax,/!IV`cd&\.{ƙjNR4XVe%pmػn S]Ƕ{4%&4Z8ȤHjM(}gĠJN; Dn}i>ȱ$1xAo*ISK76h1>eo'wrPRZ{ yE ++.۷?Epc-AA%.O͌]BH$ hN֝9%A|_?FLtJ~o6jym6jef'곝Dҥ5DxQU]n5]ג nlPW^( d$E ńl63Eyv{z 9aq2L& r `208E x^G,w"r2S>zv8V,,dZ5iI~]ݵn޼)+Ѣ2 A@@&KLַF62"j$^2>S TmPXO~&EZk2PZwL ǎ- )H`߾>EJ"N;vANV ؽ x<<zx]0Ժd%8:xpT#&j-&-kM֚T2(]5ݓa!Vr>(u+{;iܫi52M\NJyk!ceNyU`Ej4}}˧Uwf|iE>hc>h33iaT&_rlL9DBDE1g\BRf }}vrzXVB "ur\ظ]l5 pmȾǍAiJ| ]aLO@Om}Ϟ)\~e_=Y窥iU3VkO`ev@@TSJ]9Pqs2Ի^oow%Jʨ2#_=KHh:C8y2ݔ[~;f oA5Z5]>b}nA$b#DZU8,,dYd|+jZlEE <T7CJONbKرsgf YrLl<@ڤahUf *9%lɭ[-ʣV:r#7&mMWZ)OiuBjw9BK Je^Z[)w%S/9 WU<͜jc 5V F[hi2i~EmFF6`i)͌?w}mNf 8Ncٯ6+grQ J;W+j[n`[sg^ Y16 d__z0]%O(ɓKX^㡇b֝+dpdVvC%R4 >~dGvllPX_/adϋHiH y/w"VdftLvI^-FFX]-`a!uE>M! h7'P : AqAJHBTLyR4a||`Y `s&dGy#drFK /^\Õ+D8xpk# rxb`>2$ӆL4 a4(#d};?"ߵNJ tiYQ1l Xv6b\l+ڞT*bR%-MZ0?ũSKX8|xA˿VDnl iefKNl6ab">NTQ,r,$#]-cq1x<;ڣ ٟ:Ǫ 65uG<0IOW Ya2]VWY8A+8q(N/-p$IMX,m#WoErxVM +$;q67$ "7xlĪg{D r޵H패_]hZ'!W܃W^yk`ٿ+g3T'`Ќ~fm#ov|3H{%|~C"2~Q Ҏ r(9LL085;$ 8U;0:ϋˀ8Co_QoLEQ㤵EMWNl^Nﭷ_+jn]7Pkҡֻ%FiUCwW2ɲ pjKK9`wotwh\2("VW (;vP,07A#"0np>IP,`YѨHP.wpX1?E:M U2ohKJ'w{fˠ~o6=9իf50]wSj%-u.ZyGB5B[IZZ{-dE!ln"VW|c#I$UtQ^A9=jZV D\o_Df ccݶcv@%d 8NmiU(۫Al6 &&BXZ!cr2l!޻/,\8Eߺ2U>H릶J;7j}Vhdz&/Z|"YWfr7Aą +!GU1=c"JN X[+BD.\VҐP(XZ*j5ct4p 0>J`^5AM& zb j%dұ!n:4hrGö}Y8l8p`mG{]-u:)ai)w^=ⰺZb_jo2++xv x' !I"=zI_12Li0 n ֧Or_ ډΪVzNnURWitwjY&Kj늜M45dԒqnrd_|'O.b1ȑQ zKԗFR][+DkٖVNߟ1XY)f3#f| acC6 u#)\N t$ci`Љ{$)r~^dP_N*yHtboweSsrOn]5zN˟=^&|,iEWiHozqWzRy>4V(oe9)pЈ"7Z:D_74x^ b1b2XKf5_@*Ecpkk0< "/"W[o6Aꚠ.\.v f3cf&T6OLvmf4Qv쩕{o+5)Y6haΫ^ZtyG 9RBԕ=J-lzcP(8p={"V%lj0_xDلXDgϋX^΁aD xUjjKP(`n ^L44aŎA8V,/籱A6/ٿv,vڵa%ߕ&ͦGuRN5dRmx/vJ*M2<?\D2Iȑ180-mi0[իI$v |(20,x^Аo[<-plppm d!BN,/簸þ}Qŧt-4g+ʼn0M8rdCC>dY.2hd2%4 ",L&`l,`x ~.ǀExv\4l.av6  91ض=J>z pa )b><83+F' bu\A0$U a114ϋfKyF_cc04hژ 7Hِ$ 1my~kTtبov\ }ᮨb>|P(3gށ^[Whԑ-brSŋ/.^ad$}I//17F7qԶg;!%b%,,S߅Ѩʏ3>L!ziHh(xYllcp0~;ܮկ~.я鴿9`)Ru߁}AWϫ76P=FF}:H&x{ޅ{r~md:(oHd ?3C8O|B''gǂB!` yzne loH$ b1-WE씐NG1:ꚍEt^>z{c8t(k M{{era0)vp.`w䚳/ i8hH,..tB!S =tM[ɌAE+#k^W0?>J`` {( P(TP*ՐLFEb0~L݆wU@odӉn~Ȓjd9^9'uMsKgޱJ76pPw9t:j޵9cߵADoNZzj95.nf\rxv/`MTR`l,D,\^ZK:q@34h /bqqjW:8OO߈7mjꆫ9RWV)U}8rPם2Is .^K/-# H36Tl,3Π|ZΔJ5i$tf˘E D/"-ߧP[BZG:E<aF`z:^:ӑe|.^|2~5GaCH[fwxe.9eji*C\Om̔oB댛^[*tvm^~yÝwNH%t赃FeeɟG;v^}ӲSCCco ppXmۿQrT33D&2-W loh(L OqH|sE_/v ;hͩxՉ3ipL+ߚ'ޭKݢ7'킕.i;D"~UOlmf+337—H&{l 3g~whNR `qqkk`r|dڥRcssL&cI{FC8zT9k>WG| uD'[!jcajj]Ֆ([I޷d]"uOA$Wh(8{vt:B6ҟ+AIyn {{eU %Tu,.Pk02>X2{i: z| i`SS '= aǜGog40^ZjLHnw+9%E^dvd4z^tSV3|kW&,{uUnK';+92& V?{>찇^J沨VʠmFY'lg?{CGbGGSÅ ;P.cǖZ/=6ܓt6x[X5 3/=!2;"6 B?;nz Їt'N| s7rgQwb` ,,d pH쓑n33}?B]Ư;Q7X s_+/GҒ%g?Ã\ozcj*cֶG=#OD"6dbX]cu?9; s^wkzZ+k)hⳲlz׭OV|"yordL6*zaBeFm8믟3{o/# w~~׋$wfz]jܥ} Nh}'i~ IDATLLbd$}\Z [B!t383ӧ zl"ܙm*:(MJ!D&&zq&沨T81gB!l7`{"R(FGS@P\0=݇B t4 .^E>_A2YoCB!t3h\zaoL&C>9loq"ff!q5DBx-|!7}Bvuk܃x(F2 ;7`$H-@t"Ս2Ng"W14@? XY!ޜn=SNۀN2!DJ$±cJ94[Ym RJ&@No$?Iylk^ۏ k3(j}j %Ns:piJ%0> G:312›onay9z`Kq_W v-8yan~K{h4_ꨩ#2vVXכgU:ֿFя ꅯd6<׊ z4Q+x]?WowxoT5 kxᅓHm/}3lbo x.odlEr۵mGKgZ[FUE8C>_7="g)>zJzŴu ff_DxZX[;Vf'Z;/Z ̳zϵήtP{syӑ^ԫr~NTo/҇pH|_7q睷Cxmv+v'O>@`~->ap0V}X- mǾ X[Et\~|<^y{piOJqO>XEO|OgBp+ZzەU+~=e,QKEW-/c [;VWh9V˦ v"I"2l 1>qYn[" G"qݱoZTi;r۵i8L,±c cqq[[Eǜ}YUY!N gZZ3NuJhFܮ F$Noz3=E>67JE12No<bD֎+֪oL(Xt kk,/wMn+ 뭿)rݬZ)kńQ7lkvB._߮L͝;;zВQ/LeF5zWYy( 3 zoW92X^ΡT!׬KNNfpPBqW/hvڱm8+]* hcgU텗Nk᭷Q,yw=}#`sŏN)r6=Օz:ٺf5z-vYu(kX^ΡVk`x8TʟȦT᭷Q*01ыx$;ӬmSv^ٵVm;j>wJT*>\2;舳qX OV<,KkNVd_+=vtNm heʘV~r9 =mIwvby g yjem-}r{x?Ou*…( pHAN~=m1& ȑ>eQT{0;#N C䈵%qZz CŮ/C'3|8;nAA?NaYӖVjtv9҇!m> _ӟ,~~vvXYɡ'>􄥗NtnP(#G00>p=i]AY#-۰H{XfhU6u]\Vr9貣E!iO3|ֶ{w 0FFR,s6605֋}lI702h {{eR&}:Gތ8?tofy'{2;" ]۪( 67`e">\j g[@##)_FHibܜ^o`aLFGSm92LU'׳KfeIZFM4ӆj]ͳG&L?9,.T!tO!9[V. =ke$hLz'3y#)2q턋g%Ax<Çhh?o24h Bor9?~ J[pY9\NEkGFj.F'EdIԞlϬ:z鰣2GQ}ݧUTvϘyF>~Eu켅-B/x5;>ފx&Oڑ^aaaH++gojxp[FvhYs/Y~Ym,[~:\ *}4[HN=<EÏ>x#3ҝ8=%B|s}LF9Ozα!eM~2 O?>o  ?kky<3މݟ5wn}(k_ƣnu7rTFI~FT*u_gwO|XNYַ|ǿr~Hg('"BdcvH:pe^R1;nuݩ=`m-{Mr "cu#SXY->qȸn7>ߌkU6e}g_'t8n(cgHFwΠGwwK*H=l V;Mod2VUs_rc؜ͮ.$C^ho\&Ҡ2ݎzԍV. ]"aUuo}p7ݾU0:}&?_.j&'{NG/lH7 05x/vwKA|,p5to.֖Jj:2V}5B'CgeֺF>Y3aW.pD;I3_ 6?&cp&Իee,/pHvܫev18x/wQ.lyygر[p+~;z櫮22^kH[hQ~.y#vȕp',BM;͖uAQHUQ汰E2t"尚˃xm\RK fgwUN:rreR4v#~wviحS a;'zuAQ$ %tF~ E %09ًP((pu!@,µ ]ll^U~|A_k=jte2Բ^~;pF铙&nֹf찞M]/^Z?O?5vĉi7nd)6L<#ƸUN:p{R=T JES~h>p@##I %p糨xogܹWpuǯܹW]jus2±v73;+ГѮnJVȮUT7NZ#w/Nխ[SfnnZ-S@᰷6]^ltᤣ6n\㓟]v?ql+X\C(tiD"" jؠ7L~9 vP,V;g_f%Bg   0>ދpVYD!! "t:k@ ;2;v?B!ΠYrK~8H3_ EQZt ,H& cf==ag^\t 邆Bgpo20JJuj ,.!`d$ÇSܠ`h(},-P7'B3hFC>Hcr=T*uLNf08`'ҘEPŋVK{i{{¾I"B!: U0:@g Ο߆(E2a'!2LNf8~bH[|U`Ǐ߂'RCzLF[]s-ZV[Nj/>dҟ﹗ |;(Jrxby9s+^}u@{DY tub (&^y/Сh[es{ ܐwk=S?G2Y/Mvv7E(n00\(wPmb` ~gq  tdY6D+]܇{¥ z38O|BZASO0FF^_^W06F:ma-;%Վm8OMpog]\ͭNHe$ [N>!>u{/n͖`x8Ks ZB17MMp5bL~4lH7ەN}Lp}zfG9mМxVKv;iGè9;_^bDX?45\j#G00̷~d77pbYae#/ɑћ/_? mFCXYu uB -au5zW۞|K9҇d2" wb%(vOg2UɧEH7;Nϔcپ m! X_/ax8 "05A4*s>.zNt|gE7\ 9Yo2jc&ՊSK2dGk-͗m;vZJ.3fGRdwr]'6 t:MMt:j;ssGu Nm)J6w4cG67!c{|n/lvnm-}19ًp8:~'Ꜷ^ouF[U>{Hzai =Yő;xjo~t,gu['Vk~5 ְ虸_:=C ìjձuRnF!ľN;9}J6US/շ𗮲G IDAT5j ,.aokp1ǺupTF`;vAԲ!Vr؝`v:ln+㗯;%>uf0t[ߊKhw=y] %5tkݯaVjK$bl=ba=ڏx< ҝsjGYT43(cٽHxV㆞{QO?! y۽S/-Z3^rFV7ZMnr Nzr3:7mZ++y$LNfZ[gsc{EPh<;Zї,=|!>`y5lwl8Z;Gk9N(/;yulSXu;ۭ}lmLF0:B(Խm`qq%:x w'6:iWi3(L&X!_gvyޒmr]iwLws8Z ޾y얃vh(X_/ -ap0DW;jssYrevFFR<رN=<EÏ>x#3R;~R)>B!Ͻg:<ڏX-7_sٹm駷WkIw}\ +wĉH>҉ﹹ9<P.WN=})SRΟ?#_U񛕿/)<;R?w_R^__})J73(O92OʏeGUz{OW+{;N3;|9yXv 6D+]ioSR>(wsʩSO)Rf?>!m(x/{>>B|> 2'O~kNYpVtL{/mo#/_ߊ~}ϕw8K/-_}~چhmgf" hH kiibϳwvM>pcQBiBy{_SD__N#t3ލsi{Ekp>#ZnUD]gkWY"Ct%+7x^"j&ZvwKX[# TW3W5E6[`I5?e`T O㵴y1]:655u`~Uh3ZX 5rfd97vHNHmmW'f~kݒۮVjBUuWQloSB:c.^ERd=7&xGgksso`nοݙ}YV8)3IwE̊V6Ɖ(V\1 v{BYtT]'O\5A|Zj&V+Ғ(-^Ʊ#Gޡw@}fj,ьZ\kG4qDӧۈ]kV]jyԮ2D:c7KQV5ӳfl dT)eӬ|׬YFmv?p;~1qq(ʆr},/Ƒ#}m[;mW uVzĪuwԾGes(fұ>337Yv?/\]RNTKNߌ8jqљ^8Z9$L䷋HⱢ uAcᶌnPmZZ!݀QDžBG}3ʖh'h(X^ai)L&龶_ /=zMdfZԱm i؊2>rIwj+u_t}v֙ht::_v:! ton:ȢK8C#ٝ!|++y b^ %[N9洇8j<7nwPGW/9Z4;pu\Ewlw)v:>w\Z5n"5LNveY"3v 2:{t d-G+,XMՅN:>aLjӺA.Wv@)D"!)*E`rҝdS^\zvMZV"2Ci^nξ̾ΤrNN V8^z~s>WV(X8\ o"΀fl[FЮsoˢf6@$Ig`w"Ŗwb+cy9h4L6 $W;z}5+<j&neξwgE~&g1yE3wuvb * MMneUAQ[ έ2qfu r XY/ qbrg:.Rw;C4,'m<vŭ^Q'5#67^@"xHrenss)+qu/v+3F^q.7Yszሄ!2hbW2.4.CvlDztA9Emu͆fUi^8"a8bvu 3"zp"MNrkM/qU_G9⺯th(XZacLٜ2$7zpWvpͨBk-'9jYarz*A,0B6J9Tu 'NǺV *na##InvGqٷ;f~_d[%>VW4HXaa!z zX@!/Ges}Bܥfz}-~BWQ %Vl  `fD3t5f(sրրH\V1>!orp^,ppku]rx33}؉,6O2pifseǟċ^?p|Վ:1s]$֏=qiݣulHt !(}lmLF0:B(ԝ~`u5"z01ыPB.8u)>X,~?kGyO* J1{j; +~kT!D)?%!|򓓸dWZmm_`z$>_ǿr~^s=17 !GV;^)h@@UͿy;ݮlFyypOoNV$-w"eͭzo'7lmth;et>>)66 azH&#niR.UpZ/C4Ӫ{:K;!< ܻahFB,/͖qPccia7]ٟu! SF45Su1>(':v׃urenѝ[mT*u\BTJ\agVΤMµ+X5+#~rε~oW+γL KvBxP';ᴌ^u5]EV2EU 05A2mkۦկbW!]vDƥunKr^zuYя:Ź׻YLlZ8xgˬm7mWS@ZE gծ[9DTTH_zԏz2kɡG'ȸN y]ۜI'fB='ҽ6@3d's򋦭~{ KDf3:s Nj06|:(!'VN_[ȲVU)zZ[Iŋ-06F0 !tIvX6 !xs0A}J'G/,ٳgR.:LbBTq|7~+B!YC, k)Vq#bB, RQVxB*fQ(K +%!B:"'mg{ &OSG+S1A2Zew=b!=ڏ0+;!D:cG,Ń~ ?^#<ӧH[JCpソܶɌO 접=IEQkRǻw @ocuu ̧r?o ~=z3sy>*.pvZRYd/ Pg.<B!0\bNHVX\CPh CC| _!ӆKBFT`|47#hÙ}B!B|@6[|@#T !DcxT%!=m>VVHG4b!pfB!; Tw''BHav/ũrk'||I '''BX:-r,:2R!}B!tͳiLnêvukzo=v?x8RQKv4GOq>g&'r2.^LNfHps>B}B!t]͑V{(솯諥_4~4Ǯ.<'Z~bssKK{# |:B! Ԑ( _lZͳYo(gy24 sX]#az0%'BqICZa[Y=`6NNX^!k02!pHB!N; ,js'K~\HB>!B:?X>.ެH8z*Zaۑ׉8* ,,2Hc:B>Hq~o4@׌fzx^*Yg v03Ӈx]xB1\O!B(`m-d2!t !Bu:q;?R7N  OO!BoVxqB) %B}B!BLX|^rs>B}B!B|O6 ر$*BgB!?=baLL" Q):B!"![n?4 66 -7ÇST !>!B!~V~I '' !҉4R7#u{+6spu5 GVѽfmE.:RQ*09ً8+6!>!Bsڵ >J|F'FrihpLo'LP\03ӏt;BB!\T#uEyR( {fȫ3o5fNSr==aLOgqs>B}B!O 4ؙZoV XM4 Fj++9$QLL"v[qh1!Xqe$kgvZ̄gT/N#e s*Nbt4!>!B:VG=qZu*kv^EݷieŀQ:ߓIU};N'P.p*JbBB!h9ZΪf~׻Hp}j:зh\ݶP… ff!2~B!B!B!T]uLNb`B}B!EQQWEQ01ыdB}B!B!BI*X"8A%3B!B}B!B!'B!B}B!B!'B!B}B!ҩ' ۉ{͝I£ P PJ 8hcX> !>!B!hmv<+ʓW h]7 O+^8?wt5_ouġnd;B}bNBSmBq9ZNu[>#G( z8Thf6I}B!Be"Zѳ"οQXXE(O^d]7U}BB!b ndzaɊCopAk_ 'DO!BHSk϶ːìP.K.,8O!BVSkɹFūgfgEҥ'8"n!t !Bp_ﻕjKՍ7 5gNO6\L IDATxԟKp?D p⊏F=B.ЎL2ch\ om5WN9!D'Ԍn'zB񦽦}noIO<`[:5:٩jPnz:Tz2=kt֙zgj%"l&ATyh JyJ޹Fe ci(!BO|@h9zzNå'ֳFiJHfcV"3O-ҷ^2˃9̄+RvwKꪬC!B\/β,YdQvzfw3Χt JN+em'Wf=5d!B!tOZvB' D}2V'tdIl[g4C֥FHh}VV{Q&"Zѩ̬p;o|Q±Owec;ʙ~BńtvSc}X>)LOO ?^{_8"ѣ73\k(M۶E2!WN)rN jb%n^W׎z |:F#Y.C>O ?377 ~!wfB!֪#+'5?׺^X"q.#)@ji3Y锐n>i4„BqavEI(fNHMӔd#O!>!B"8HΫ%z 8H6Ѽ0 !BHW8N/֚nEv3':񴢲Y g !BHGbT9ƌ,n0dQ]zщ@vuM}B!B|9F:a/"3FG$QjܢOp?J9!ve41}\Yf*3VX|BwۜcB: ޙx=SoB!o}ʀ=j͆kʢv^j[×[;:u]Ƴjҥ<[^Ee$zȊ>d0KB!b}MXe6\DR_/L#q̮h ώnPuCDf\MGf˫H -m?Ѹ!B}cG^ߺ'@tYEQydm"܌;98Dtg~;qY)7vjXZ0[VDdSO!Bgt/@5'.w'@ڕ_dvW͹Sak+qIyEǜB!;IJ0K{L{;f>n'-"{ѝټt91.*A;˘.>!B>qőm.z]13sz; N'"ٸSsa-̓i"';:YKO!N=<EÏ>xկ#=z3s$ 7;'tHՏ (T*!DZ]"^ᡇ>5|3~fnn?|Gףz@w5T*`gn!B!t !ba!'ϣR}m" S?u^;,{nBJ$B!>!+5^yep08}fz?3Sh4<<HB!BB|%qnmYᮻ02Ĺs[x5Tu*B!:vS.xE_ny~E<2J!B}BHY]<2iqa1pPy$b^zioB!BBIRNj/.{[`w} ##I{z¸q;6w⋋(kT,!B!t !b}~  ]DB\s 5<< T,!B!t !^o?X?2>k1>6N&Ӄg}}=xUkT0!B!t !no~B!BBdkk[[Gp]S#K$"x'15s[PԩhB!BBܠ^oU_sakHeB!Bg%<gqE*ny$R(^yegnR~B!BBP8ujPQ;/%h4ø!,,d (Q!B!t !W쳳7~2q4  !BOq EQog.@Q_ţAiqRQ8|8_VkPB!75IGT_?A:oBfh4XYH}B!B̲vn8} B<;;=xj vhlbmM{@&Ӈ@,Guw$6IW$8q̴%!)t:ϴ p&mӋ>3^m+zAgyn$e>S&F6¼>ΪgWHό9s~. Ν|AOCņ K/صhh3W=_Ů]~=,it"`>,`/ߊwlšشi}qN6|xN@ܹ |8{F]H0]e8sXzIXj=4dbb˖ʼn:1 {G?eܸq7vx2orή=쳫G\Lٽ{7߼+V</8W,im۞qʭ8uj4n~L{ݎ~vld| bɒy9s窸?o~\v aqʕK/uP?n\27~~=Hcd[4oƙ37=a}l6Oz-bϞ5 !Fwqx8i ܼy/^{Z\46_˖5\p<̪x8}(YW@Jfs18q?~-3kd2usK4ƎODW׊xO⭷ǭ[<EM3g?{3$̃۷#^=ܹ5k"~p&(ҥwFw.SO9PJ{{k|߰ـ9Ż_wc׮glYݰ"$ޏ7r=FSSƉ"3 3 d)aCݽqDS\+WbwjMײ~?(?W^,[]w[S:d2fh•+WO7yy|++jZc߇رhk{4.]oy-6mZK69x59-\/G?e|صkMlڴ22٭Zh<0OGkN(}/6Yn~oq-Ξ5kƋ/+E>>:E}߈}ni46P<ԒWؐ2WոuAٳ&LMXnjj[͛WĉN*w-;s䵶nǧےjOSi?嶟qkNΝqqhZ$^zi]{ҹ /ڶTllܒVZVmK';wq_[۶=T%K _XO?,oFٹ"zAO2jw!?o^Gğyw455L~Mo|+_|~J=G/-~CCgmK %&W}rؘ̤ k~9V^24,_?x~2_^n,Y\.>st{Er~6~{߻7n܍%K޽l46fUeҥF><m{C_}a_؟FО::ŋgc[6׾_bժ%TU|X:rӰÍ3KCC7<;Շ(~;7~ܼ|JcŋgUnő#qxOطyJobٲ7C[c5UiR\$c筸= >DeECC&V~fai/oӰ8ޥRCC&>e,ZWܻ?uGdfo|z}:\/N6|>(>q@92ۭgO:NRxrӋ) r.MΗ\wDž Ut KAA`%cq8rd8a)~¿r^6^{x啑{; 6Y[PxWH&;wʕ""ܹ$~G10;]}%%xTާ֤ s?`^]׮ڵrA|Q>[w?)mŷ}..]G3q?omEj*յz~z`Ԃ σ"ZZǫ^+_krXl|bhグgV 9#֯4_FK_ZI N|j׮U7nʢ+ޭhۿ]wgcIğx5ƺsFW׎o//a\.7>=xDW׎WI~&.a#::G/W2LD{Ea^:\5a)ǛJ%>Z_)MM?Ǐ2k>׮.C);cɒƒ|7 y=EaXx≇_oݻ#%?֕3-\ PΆ ;ˆ]N;/=/.^xa$aaNÒZOoMWؽޏ$֭[Z𱔆L_hlDCC~az/ܰaEYH<񵯵ݫ|$w:P@݇}WO^_wrұ(^X%-mq)_æL|Kkb׮񳟽21,e21& K%ذ_%o_sAXZu?>?LSkתޭ[~mMXЯޜnr^rT >8,Xvi<,ݏ_\+W>_ ̭Lhرw>Kjw}뿾Gc"_LYIrq!A 9U+L&٬MrA a?bzvܼl}5;S/tL&0fwGia-- k_rZO< O/sG-nmoJ q@ZaF}mK΍7,/,~dmںyq~@دImm[bhlrhoCCg'EDŶdJT_iAa}\xf|yr6us\ttl+d" װewO+wtltd.Z18x`ڰn>Ix 8'绺vLhONwu툁S%&;V Q=ad[~ThϯSWaϙyP wrBWܞo+>R;d[fc#/ 0::cch  ;wvGf9v쨁 /iv}f޽  to"} ^L&cDr\~=1$E/ԇ~AlX]>{~>(A~ =Rqe8'Z[7usDd{r>\V|\/*Y*e[gz[s}1jc>÷PW۷r14t6ڶقu˒Wx%PUhjz ӽJZjrURo _?Y~kGLX'v/)ضxPj'|*}T33Y.~/_xRx4ն>00վ~/> > _h2 ˗/331eرR~{  3;gHmW~c&5Lƈ&r8xPo,HY؏d2fh•+W  ϯIDATm˶]徲ۖkowBǯd29L7ڧ|PM՜:mI7WT4/_adtK˦\.##]>_!d:/En>:Sn7_}USw/_'a)n^ 4Uᴝw~waN~[ۖt\mqҹ׉uJ͗Rme~3yuU9=c-39ZԐU~:eCCg}k -yo-iREpɮUº>zo}V{lq%q*ע\w-伩_@؟_ڶV~d( Y7ywB:W O;:-_雭_`anjH_ *?Vs*f{>kU7 /j3 ~vxެUf' o]/Wx=~\~~W׎]];ƗۋR-j/~Cco:0z>8y|yi(,P_0䲾R~^Nd8vW{e֏i6jH߅\~}@a_a_GGGclMX|A a8|,36ǎ5%kaٱw>@j%۽H79@د8pd2F4!b~c@~DD&l6kD\js ,7L:WMr؊suST?Ҳ)FFGs9_q_iɿf2<:RxY W ׸R5U):+ocE_8jKNnUOoWZ?pQVJOg})J_W׎ve8p&zS=RiTɿ2cqT_Y }}'+oOw1k/d~&[V7 *jWT7sb[I_9 h2 ˗/331eرR~{  3;66(޽@JǏ]{7@د8pd2F4!b=tL&lֈ&\r 0jY.0֟?ooi##磹ycw1--bx mcxcO_a/XLR\.CCgmK-14t|}f(WKs Qؿp7::Ņ ~}w\;~ wGDDGǶm_ax<=a s8c`v̗[: =ٱ_ad'[: ¾>?::cch  ;wvGf9v@ZǏ5_ln@*;{3~݋~$Ɓ/G&1 \.<1+GDd2fF4ʕsƲm/EsƸ|Y-- s\s??amK\t`mKDD|rۼ6)/kkCCg |r>?޾u| : /8_nz.i|rciaa!tW׎8{kW:rYq{5sq > /" 16vˈ&,_ ΰsgw>|hcz uQ@j?~aYw>@j%۽H7@د8pd2F4!b~c@~DD&l6kD\jHo؏77o,|oA z; j1~LƯ"~@دϰҲ)FFOҪX :_`1<ߎM1<3i t\A[[ۖK΍k//|J.]<ڊs ~]14t ė/ז&gRr %%_+ѱ3exL|m~,POPb>¼aF}];>~}w7 m \٬e ~]Jmk+3Ҡ~`qhZ wvnSLnSܖVL+ګ+=յc²>)nd̅⫣r^ͷ+_g'I,;_V F, /sa}a}aC[F4aet;#F;v@ZtoA}f޽ݻR񣋶~&5Lƈ&r8xP߿`d"ф+W#fmK.|`<Pa?"bd|7GFWM%a~LҪaO.om\ںy/,"&,+ޮxxYq}L0Rwe??޾5Ύ/okCCgchx[Jrea۷NXv♲=9]i槺-Upw>+jm>~-Bq5E<-Zu})^s{ٶJ󓭛]];Ɨlյ#{J[d_n_N_ɒ//n~ > > ?eD/_fHg߹;>b4ˌͱc:~A@,ưOe{vRرؽ{ A֯798pd2F4!b=tL&lֈ&\r ްQoonXr}o_9_2Z^eSz##$ |rTۿpbP?ӿr/om<\OoWgv3y,0Rye}k _ֶ%d>ڶ[',xxRVmDG6aaV…… }_=?6kX;O/>a^ɂxW׎J}@Z{kDŽSM>꯸|>}?iRwWNxy_}&ےˋ+G>kx`чi/oM>_0/ <;ւy,>FGGclMX|A a8|,36ǎR >mHczc}Zj{zz#ф\. #"2LdY#pU@z~ܼq|>i--bd|AO) cxᷣeS ,@~K,okRЖ\~ҹ|[|u'tے+]OjoCCg Bt|NWZ7?]imKO`QR$/^a^s{ />9_Ժ}UOUڮ\0~Otu(O?YT'JSimq }}'+[sx_t i+7,?Wo}az ν% /~-#|2@:ΝqYfl5G `1~ףh@_3R?Rõ v=7~ ̵jwc'kڃj#Ki0<ޠ/<#B ۄ}XHAԭ>,/@ʃ > ,>,/@ʃ >T`xx<իfb?FR̙sq])['ӈضm?& IENDB`MP3Diags-1.0.12.079/doc/190_tag_editor.html0000644000175000001440000002733512040502152016632 0ustar ciobiusers MP3 Diags - Tag editor
MP3 Diags
The main purpose of the tag editor is to get track information (artist, title, album, cover art, track number, release date, genre, rating, and composer) from various sources and write everything to an ID3V2.3.0 tag. (Note that although multiple images can be stored in ID3V2, for front cover, back cover and some other things, MP3 Diags only allows you to set the "front cover".)
While there are many other tag editors, the one included in MP3 Diags has one advantage in being aware of what other parts of the program are doing. Other advantages over some other tag editors:
  • besides retrieving album information from the Internet, it can also use a file's name, or text pasted from the clipboard
  • it can add cover art from the Internet, from the clipboard, or from local files
  • it can handle multiple instances of the same tags (e.g. two ID3V2.4.0 tags, each of them storing some information that the other doesn't have)
To some the idea of tagging MP3 files might sound rather obsolete. The reason for this is that many players create a database with your MP3s and add all sorts of information there. That's nice if you only use one player and that player doesn't have the habit of crashing, destroying the database in the process. Many features of MP3 Diags are designed for a different approach, which is that all the information that can be stored inside MP3 files should be stored there, so we shouldn't care about moving to a different player (this includes a different device) and having to recreate the database. First you make sure the MP3 files are OK, then you can play them in Winamp, Amarok, VLC or whatever you prefer, as well as on your iPod.
What's on the screen
Most of the space is taken up by two tables, one above the other. The one above contains the current album. The values in the cells get written to ID3V2.3.0 tags if the information is saved (which can be done explicitly, with the save button, or automatically, is so configured.
The table below contains the current song. The 10 lines correspond to the 10 fields that the tag editor supports. The columns contain track information as retrieved from various sources:
  • Existing ID3, Lyrics, or Ape tags
  • Information downloaded from the Internet (from Discogs or from MusicBrainz)
  • Information pasted from the clipboard
  • Information extracted from the file name
(The last two need patterns to be defined.)
While some sources may not apply to all the files (e.g. one file might have two ID3V2 tags while another has none), for a given album we take the union of all the sources that apply to that album and display them all, regardless of a file having a particular source or not. It's just that if a source doesn't apply to a file, all the fields in that sorce will be empty (and there's a special background color to identify such sources.)
How the tag editor works
To determine what gets displayed in the "current album" table (and what ultimately gets written to disk), this algorithm is applied for each file:
  1. If a field is marked as "assigned", its value is whatever it was the last time it was set manually and caused the field to become "assigned"
  2. Otherwise, for each field: the list with sources is examined from left to right and the first non-null value that is found will also be the value to be displayed in the corresponding cell in "current album"
A field in the "current album" is marked as assigned in either of these cases:
  1. the user presses F2 in a cell and changes the value of a field manually
  2. the user clicks on the "Toggle assigned" button, with the sole purpose of fixing the value of a field (or perhaps more fields, because multiple fields can be selected before toggling the state)
  3. the user assigns an image to the files in the album
These may sound more complicated than they actually are. In many cases all you'll need to do is drag the column headers of the "current file" table to the left or to the right, download an image from the Internet, assign it, and then save.
"Various artists" albums
By default the "single artist" / "various artists" status of an album is ignored, except that there is a button that is disabled but has a picture that changes according to the detected status of the current album (a single difference between the artist fields of two songs is enough to make an album be considered "various artists".) The reason for this is that there is no standard way to deal with "various artists" albums. Various players use various things.
The default behaviour can be changed, though, in the configuration dialog, where it is possible to tell MP3 Diags to handle "various artists" data in ways compatible with specific players. Currently only Windows Media Player and iTunes are supported, but some other players are probably compatible with these as well. The "various artists" data is displayed in a column called "VA" in the "current album" table and in the row also called "VA" in the "current file" table (the latter is for informative purposes only, so you see what's in your file; it's not used to decide if an album is "various artists" or not.) After enabling "various artists" for at least one player, corresponding information is shown in the "current album" table: if an album is "various artists", there's an "i" in the "VA" column if the iTunes support is enabled, and an "w" if WMP is enabled. After saving, WMP / iTunes should recognize "various artists" albums as such. Note, though, that I don't use either of these, so I didn't test if everything works as expected.
If you don't agree with how the automatic detection works, you can use the "various artists" button to toggle the status.
Performance note
In order to avoid bad things happening to your files if the program / computer crashes while changing an MP3 file, the default behavior is to write all changes to a temporary file and do a rename at the end. However, doing so might make MP3 Diags rather sluggish when saving. In the configuration dialog there's an option called "Use fast save in the tag editor". This makes the writing be done in place, which greatly speeds up the save, at the slight risk of damage occuring to the ID3V2 tag (the audio data should escape unharmed even in case of a crash.) If you want to use it, it would be a good idea to run the transformation called "Reserve space in ID3V2 for fast tag editing" before going to the tag editor, othewise the first save will still be slow and you'll only see performance improvements on subsequent saves. Reserving space takes time, but it's unattended time and you can let the program do its thing in the background while you do something else in the meantime, knowing that saving will be fast after it's done.
Some more unattended time is needed when closing the tag editor. The "fast-saved" files have to be rescanned for their notes to be correct.
After making sure that you no longer need to use the tag editor for some albums, it would be a good idea to run the "Remove extra space from ID3V2" transformation, especially if you put the files on a mobile device.
MP3Diags-1.0.12.079/doc/005_screenshot02.html0000644000175000001440000000440212040502152017011 0ustar ciobiusers MP3 Diags - Screenshot 2
MP3 Diags
MP3Diags-1.0.12.079/doc/290_config_transf_params.html0000644000175000001440000001207112040502152020666 0ustar ciobiusers MP3 Diags - Config - Transformation parameters
MP3 Diags
Here you have the global parameters that are used by transformations.
Names that are stored in ID3V2.3.0 are supposed to be either 8bit Latin-1 or 16bit Unicode UTF16 (ID3V2.4.0 has 2 more formats, of which only one is currently supported by MP3 Diags.) However, some tools use the 8bit option with other locales on frames that are declared Latin-1, when they should be using UTF16. Although those tools display the names correctly, others don't, especially if the file is moved to another computer. The reverse might happen as well: correct files using Latin-1 might appear to have incorrect frames, because they are interpreted according to some other locale. There is a transformation that does conversions from 8bit to UTF16, and it is here that you specify the locale to be used in the process.
By not allowing more than 1 image per file you make sure that all the players see the same image. OTOH, if you have files containing more than 1 image, you'll probably want to keep them all, in which case the "Keep a single image" option should be unchecked.
The case transformations are not perfect, and there are no plans to improve them much. The biggest issue is probably not being aware of most proper names.
MP3Diags-1.0.12.079/doc/300_config_others.html0000644000175000001440000000725212040502152017327 0ustar ciobiusers MP3 Diags - Config - Others
MP3 Diags
Here are the settings that don't belong anywere else.
Among other things, you can play with the icon size.
MP3Diags-1.0.12.079/doc/screenshot3.png0000644000175000001440000030333011304162734016202 0ustar ciobiusersPNG  IHDRڠbKGD pHYsȥtIME 8;<}: IDATx{a'ﯪ5===cf@BB2B$A8oun&{xH$^= $`;`X6 24zI3g?~ꪩ~Ns΀zt}_ xxJv=$i^A+_*K +;p~|X Q,1""""""&'05B2;4 gXJ hظ&ٱX XR""EKppǑIq%\vW@U!XPDDDVjϒ%;#"ٯUHD@4.D0x?8|+WM,~u]|gwyȌcm[鸿gϏ[ 뱬|ŹbZ7ro~5TUpc;;u|cjjH <^wo|)H BhV涩afL ϣ>`s`Cq FX|7q껃wxWuMJ  2<7bv^Y_{{,~x-~|;;>xzzceHe-3|`~>Q͋kZ>+5/o_7~XX0ǀ7}zhf {E ?c-D"D{g~}DA-GG'pлh_U7~lmRU7áC{.,ʕ]5R+@)% CBPUᰆh,L:'O`ժ\z}FA-5L3 U3'{AV=U,X0xq`N[? ;E5066nFOgяyGq NK ~iOR;=Z_K|ڵqM+ȑxq{~#!švb9r##磢|]tnHn VB$AWW …; ZрY866[o`"Ö$~eE'͋-ʞt:މ[oš5}G)Y|ZFG'|j-ph{[g5}B`x*[j3K`Rb޼.,^x^߫|H)<`g뎰h]D g~ |8kc@(;yX[!<.ZH uRY++ D"a?~v=Nq+rt>+}_W3Aͭ;a7Z&8ֿʮr݆`hJAJeq:YW)wV~/ZԬ-ZhcEyvtB…x0Bl~>CRo>/PUˮoڂL& )7]""""jd`N`E綍RJwî]H/Dww\Qg XC ϟoO`g'T]]( [ɴ8DujW;t]]{4?TX:ΠYH8ܯ \O4q8;*Uu{reWkԣ\-SvˋR2xra㵝xd͚>œH_ Cq ooƖl?8KR)(MӠQQR߫Mo>vl۶+s*;0u2a<at3zxKE[` 5Ν۰o~G=}ŊeF#FOтӬd{._q*rtk~d~{=k|x}sʥyh4[nٌQYsm[atmoC2u{D6dV߄PgϞqD,[=4d9LMMwyVX of/DDD.߯\o:_YǏD")ϊ|X\ǀ|| @ý@b)pVuxB f>9jR *+ {{U~]: I&pu˰bE" ;8bQtvv`^Cw-[Gw"p6Qy⥗`@*nx_ΰHwov'!LKߕ_W(okqݢ%HML"=<8d6 %B w q1kzllEw6L3։{3t sWW{Isrt]w0s "bl۶nw, tTU%_s2%""W^VC5e,]DlN߈fR"щkokf/~}7 !""""""j4(E@DDDDDDLDDDDDDLDDDDDDLDDDDDDLDDDDDDLDDDDDDt5km%dWr'^Y٥qdh1PcSZ׭4Wΰk}oUrBF=ӻU|ݷJ?/Ya,K5fs7汹Qd+UrL_}l ̕QuTtu>`z}p;Urg} = _3a7d쏈fz'[I%ǴV8=`+"b`.~V9Fq>s-.Q'8ټNDT_ͱfF'[=?og`&"""""K>_C!yv910ͱ@H),"""""""f"""""""f"""""""f"""""""f"""""""f"""""""f"""""""f""""""VboMiZ-_޾}=#DDDDDDDoYg$0[֙ """"""j5i͚&6|10+632<QPlMDDDDDDy``ry 7=""""""VwiR18x8df$0{VPlnWԩ3}SRRi;?G-7ݻ- f.0[a+ Z*7tqV\DDDDDD4 ZBsM~Ur6S.vEDDDDD4;}SjF;r2j"]gBrִFm]aH&""""""/ 鴹𯾺YYVbm<>ќ}F;]w}[޽{O|x|$"oθcnuDT֭O<'=<>񷃿?}{Z<0 lj*%*^5U37f*=.V{|͵ V;nԼigA_03J-6ap`=Rhh&yllc$DoH=˝;߷ޫ&,o+dmDnDDDDDU.{ YWʜMMJ5Ojzﬕ6zAU5^J:'Y~ق4K5ɫtDD[Q8_jF~6 IjVm5%q7vp~m᷃8/"8D'4厃}Ϛ^q/gAzQ:Ηџͅ&՞5* ׃W '_qdh1HcO%W+9fy*c8LFV2j][ uѽck\T"jz- A%Ǭ>M}'BD4ӂW}V:7.;{=v vALhv4DՎYp|+׊gJj[UrcF_mqi3fuU*V<'^M뱃q96QhqsmFvwFFD9 Wz2]vx MCU)^Цzyq:q_o]1԰6.7MIWiI6:w-s[K kGA4,;<.#ς7Ӡ6傫sg/MOjmRm: \qQTz rףJBk5{.9 IDAT-D՞ ({Q YỜA UU=y#7~o[bWU>麎G6웶֭,ey5mi'lل|`3W6U%W1 ,!ʀaȂfE $!d9z]1> w­;+#ewfs} s4(Zf-}-c2r'7wkO纟 MLrAo]ՖէMDssy AΫ5A^AT³:awLk^ypkk8EU| YR5e׉0puiHYi`.V9:˸x-Ô߲;avMo0 ͺ߷Z b굄H$ RƚS%٫&g.+j92+s/4d>m"suwm]6Y׳fI;JxF\(Vea sq(fp{t崆vBwYށEA+T!՜Jj kŝ5oqwhs[ A/epUU $ۯD*Y~ZRu1Z6uef+PV;j.=w?$rEC_DGyk w0-D.ch- e,$;ȳc ߋza/^i%3( ξfefn.zzLjBzfn=](J;+lݯvޫqm l*9. ̫W乮6:p"va䠁yҁW`"k&Ժץw_LVA֡t[, 뽚׻t>}KTkЎNZ~' s+0= ^֬\QknCDn'gd}F8m-=>_Vmq{ߵ\MYBޝ{~%$Ҁ" j*_ie ;.mkz;u-gm@)꼭šJ5 Mknc';0;mP{fkz}رXf΃r3eYB!Q j:l.w\EQ Ϭ?k|ΦȵeƊ rT+ rU \N(ճ38x5 4DE5 =חћWSiiK ݘTT}98(^Og;7rmytʝU.T4,SUUGJ.}`nǎڵ[ ^f' m yϜMVn(*^։oQȋ'bѝK-iV0[oWxm/^ۃ=k];_'sdotqU C^0;ki&kwMr#zܭuy)ok%en>_ZcLٲLD}^d;4{ud>7k7u2L4oEeWl80 Y33q$"jk?jZɤ*P8߉)uy9 g3̯k<2u J_ԂrJp g0{冑t٭r{dF#2 0ݤrO@lDK׼6?-LK)dŠ(JAXB_> !H$p8 -$fgOl¦T 'BTM# 9;rvnn.ђ*QaNHAǢcQ@@A6!C:r90!mYMS:$0̲Ryp0S ݰץBHl aYX^ձ"̐F89[ /bf\̏_ͽ`Y2m">IDTPpP $ueH@ISa6!g Wį|k՜ Exa_@Usz|~kyQ&49pLo'4/HYU븙ے1]J\+!k D}N("4M;r>~ܓ!Rr>W;<wոsg [~3 k5ԥzLS& C4dǎeYkGg*f10orvx>a(zN5l%ͫYs+-pZ`i$+o*.r5V!%9s!IjYJ< իW15˸::b oO>\F"FulLa L"A4Gx3[CPUVGGU(av50[a5h+8{! Mt奖r7; gad{+5wk<>͉e&|Rqx[}D47Ik ICMgaEQav@e*MA ؆a^fFjQ`$yϚG@W:ؙ #]05W:TsΓ_W sky_ے*%Ԣܗag%'+QyxO?<#&O³ȕMD{͟ I{ΰ#^X!yn}$Pߴ!w喆F> \VeˇDYŏkG O7hh qAoZVJDDDTm$Ϧ@~_@hJG~QYu]Wһ9#Yro='`Ӂ:jx|WtׄW}C  ~$ Jj뭶qRfЬ~^zC |]ʔf%pm} Kr{O({עUv/=ksuy޽BΏtp+<^8UUx +k\ou 5ODC'syŊpцיZz,߁I?kXvmX(c+}N%Ҍ=0O!<ÅSUU\[@Wٳ5=֗{z7;Z@ ouBϙ;{.U ϻ9p js9cMלO]fYoݿ9Oo^,v^yP(dϫނa*gp ~2uf;G²sߚ3tNb( Bt]H$brvi!աX6E4d2d24h c:;%SUHDCGGRD"@&2( @8H&z3i,B!$::bttwwattn ֟p8l_25kls9j3]7F(*\>Ir:tCxǑNLN@ )g"?/ \Ӧ{7  D#LMM!@j?ܞuPB"MD066qN`v6;R٬)MS˯C4hL& ) !B!d2mWJHD:١B Ղ<274M)_'M4wOqp{cQ+PU1Kΐlv>/ `)199\.yA7J!J5ΡPBvhH\\׮]FHHRHӈPLw(B:F6E<ށxc(aA"@GGah=f 4! f  Uk(u"@ˆcvtvv !NcrrŹ\Tʾ`Հ[a0 RE(|GjV-u H3C4-?ns!WEz6@:\ 鴞4MCYludqr9躎l.pXC2F.t+T Bbub  )JkuRiB!L)(7Mu[J  eaBm]J&caM ms .\{YZO̓D ͵ dc#"jY̺#6Of;kۑUjMMM!ɠ׮]?SU===HR4 dvMb8.1j c~,kx5M(H&S6!tDQ!p5n=" ksEkŧk9%TMaߏm$TU "@&''166xqO \B IDATe66mN3':흏Ԕݤ`j*H4 ]7ϳFF¾0F!DQXR"JCJi땬avf!("T*/KUD( iHRfQs}[) À=[JL6,B!f i^ ðkl#ُSUMS9jE`\ 3N3hj.Qy(!XψZ=4{ V:" l5öUu_m;&LM- ~;nF@JÇc߾}D"?>100D"k׮8wΝ;)twwcXz5&&&;ŋFv͛~z #V02rtB 6`ʕxqy\r###Xx1֮]p8… FE(_qի1o^pʕ|Syf,ZGP(T*{q㍈Az*CV/wrOO2+0 dX$!U# 6k'''1>>=CDs_FↂD"UUqmtԼUmŮqH͚t% d2P8 ɠ3X,$M#X EQBӀQs؎0ٌG"AדBA(A:7 B-2Hs)ݻJFu7yHDDD4FFFݍNtuuaxx|UtMLe /Usoo//___Egg'::&L֭~ӟ" aժU_,_n)%~m=z׮]CO|_$DJHtΝ;W_ӧ\ݬe"7B\QÕhX`!VZ-[`ժ>DQ:t$nfp س=zt]]ݸp;p1?G8ƦMpy28W"!`͚~lrFF nftϛWꆎsĚ5k`ub*\SN!KcٲeE:oo0\#Lf"\sn"FfT xʺٛtV;{gvu"o4-kGTuUYӴe޵k>رcxꩧpaab1^ھwÆ ?1<t$z{{۰a|k_þ}GtR) b…@"˗q(={~x/>ܹwu/|I|\8 7={ɟ̙3F7/ #օT2 PLa- )%>8qst H/S<{/_-܂;v~N;`b^t&|_z :Xl~7|Ǐ_sc>Co˗uxa__1p)Xxq3ΝOׇ DQ这{@UBmߨzfu{D˺kV}_}ww73Q;qF"iGH麎l6kldfsƹv'TصkΝ;o8z(FFFىxC{gL&\NG2Wo+W…$id2Y(Y/x$SSS0 G뮇F:y/wy'nu;~b׮{x?ͱ5U͟HvgUt].[~ݾ;vށO%၏N:m۶!` ?2: (+Ẁ {OCU5̟ߋӧOcɒG?E_pQlڴ a 2;J_ՈslQ2÷f+35asj#""": zEcuTKr οZ)D4ŭފ~[8y$TUł H$N1<<[bΝO~W^y===Boo/,X'O⥗^˗i&,[8z-|[~0k]b1q(qF$A8tuuen:|cÑ#Gс]v!111G}#_oIX1s 34kƊ`ѢE0 v{{ڵkͼEŋDpaa3q;ʕ+!<뮻ξOyʕ'?T*z ?я CT>}?8}\2{{ v:E{ CG:A29}ӧg;v?>x".4M;: ӧq5q,]xۇ_ɶyxxu;{flK_hvբnaɓH&vggdX`N1>>˗/ʕ+HRD"t9]DZ`@#D"yNo#aXtxP(nr Μ9gkZ]\&}֭Þ={p_k׮==f_/"-[GyxgNDؼy3~=Qttt؏r_ X~=6l؀w}CCCŎ;paݻxr :;;iᜦiHӸx"&&&tRtwwիB`p7oիq;v|\! ]^3B(Boo/,Y^,\ DD"17k@OO-Pp1 ڵkr G0<t:}{#<+V_:y ޽{q…| (86mڄ5kƹsWFR"_-LNL`ۭo+L&իWCܹEŒ!5p˖-ïگM=*vZۃjv6%+r0y!B7 # 7|]~9kt_|^xd:)zDZ̍r؉LM> DhSSSv-]+9c*yԔU_ gM$9ODdf}&E$G| YSZ-H {w_?x}< {X`!i%eIKҒmQO!9}U]U]]}LwL|ʌ>Ĭjqy=kFV+s[VIgffh4$I sm{QZh4J/|ItzkY Zk]zϞ=O~s9s$IP4|j0cǎ122oobdd|#|k_㭷b߾},,,ssY4-CMy饗7[oN1jz֚|;,cIp!>O'Nj5,cqqeNK//~i;7Z[n}s=,.,pE~_ĉ bB066Fdn~EHER4T+2/ O}^.$Z"Qlh6񧦦XZZ-IG>Ν;[oE`bboo233kVzM_}U>կ~zNE\ꭵ&MSO=.\lr…`eiqgo-24~a=ʻ]w>'ypY199Iǜ={^>s"L$I!">s!.\|4M({/NҥK?~Q\BZAk=6:\)^vI4bz˭QEsssIB^gff$Nh<ڔjZqWU!s%1/__"qu9z?#>,Χ>)pyh6%a.揯=1bvJS1ZP]{a*Ν{'< j$Ef[vQRގꫯr)^ę3gPJ144G>yy?3>񏳴ij>˅ nIoepA1RVZ3==HZcqq{w_gLMMaY@^ KMNN266ŋj111//swpIկri:{n2_9cfggtRY>z(?0wy'/_Gĉ|ܹswl""яra?Nբh_~JB9s KĭM7Ddvv'? I;pl6#G|X?sF;<ދ'x'xW^y(j\|SN177P*9\ܹs߿رcqėxߏ+W'ccꫧyǝwɁ#".;.Z)rczIqON: ?ogZ׾ӧyq8 y_7طo$Ix3u>O}A~N:ţ>֊P,5yr ws7ZkKYxp}C)FG4-*%{zǮ[ng_Yfx@@@@/rZMZ-+TZJEvήnˉ2Uq/ě~ӟ3022R >wenZw;bhhyYZZ*C1tƹw_c} iď^?s7z 33|2s9t ƥ˗2s"af~ %1oWāo8}N8KC 1} O|xgO3=3˯<PWX\~R30c}t_G9_dnn3gi.]83s,ĕIoRbϛBlP>}=$U;yIӔ|qg iE k3@ʹk+ z+7^+p׹o&~-X~ XNkvϿAoE&\hhhj'E>/cJ8 IDAT\(K+/uJ1P(˿9xҌP517+ y;](Pa###dYƹsVjZsr /_Fk1u)%"?gjZJ12(4kfX'X7Vq˜kUm֡_Aeϫ̥]݅U"Siji4ZZ4Mavvp^똝ejj4uhm_ /^ kj\HZ4fff{Z̟SNb&P)/ȳ1oh*ƘHRԝ+[k\c 4% QdpNn@|k/lۂ6"odp@@^&@=gzF/U"|x5|~{GAr=1Z帛^ne<̝rrTJISK%'̍#ydS6Ҙj6^3fY&k1&caqE$^\ZK,9ky)*s-STe "w5Owp<ŵ ENrs9ν*}?j}O9ֽWj/5Haٝj䝿wW?? Wni~ΖƘ9g]w=]W%ml|mǼY/yci txش֥Pӊֽؐﷇa$[v;7PkmPMDyCYGuբs@5ɲ»lZcn֥}T*+zmgs'.NR1JdKijw\b k3*BkjmfAPJ嵡;ᜬ"ZK[Vtf[ENyOpԳֳ6[maSy3Vά1vf$ņm_?͕ }W~~,+W,iÐk`)3ǻ*;$DYiw}b9|=-Is;N|f[^0 B6Rv+瀀훗WC{ M Evp~gYV_%1dhPC]vȠ;'Vo;iU|sjk4N_y@0'Ǻ-$s^#dho' (Bۍ[y=`%RH;60!Z\-í^cy/G{\9 ȀDe^qAՔpe;O\{u4[zfkmYHplmZmлžV=o~'1RzWӻWXkNP^ͭ0MZXvcJ~u{y{E&h[4P~&N|hu'\Gd6⒔`"xڕJa)$IV}htU7XTG;z%S) u݉tnZL5oGRVƴڹUBn;f<"4bZJ ;v wܶXx;Is@@@@@@@@@O׮s< H-G(}*R]>Ɖ}Kw(ʚH-?*V֨0OMM-'[@@@@@@@vmzy# tiZ)Dmo==fYEdnVנWmҧo5` /}mۏصNs9(~j<߈PZύAC-*a4ķ܍A/0a|ݵn; Ɯ p5Ѯ[zmF90ܪ*V3JLjVxFaoޫ(A}yOmυ6 `;V"Riyێ܍;"Z.{`O0WĜB,˲PTxx/s//kE$/oBǝsyɫ7^(۫Mz\yRq+:K^ZQ:Wj2T@]'3{+F։0]!νlۄ4MM{LNrE7oon۴1~~={W 5٩Z7!l 6 7 \x8C=gSeϢv~a뽞YF,}zWFʚ[ Mo^Ξ}oǏg{%q֋Nj9Jp 4hZsemq?J~}v"1kA4QEkDaV:mV MQAMGܻa~㍗zvxzyVq֯_6bkޮ7z7qq-objul#]{=[vzbgkYm҃*n限@@+0z"T,3 oPVLDGepZ')8AF"]m!J~!~Q4'/VzU4V?9'J<9_Tꖌ/} /{FοS(.t[KH&Wb[d[aAøNXlmd>ufYM7Iz6*68W85hsU Y,ܳ;V+(QT,EVX+)ZZ@iF-il]" {XGjxbltDP[kRh}'PmɴMۙv61n)݂K(^*3ɲ oي#V)Sں%U+W)eA)V}~ OYjk8nG^OFz9̛=FIkP1nJ9W0S3LQ R Q2|R"E!V%4B(DP(K$)6Sp :!ސ "^Zi#ZVf)i&4-dy/sQVZ"h:E"Qu)ے4>JreUF]Uď2n>٫V]'w}SV¼ټ«8+kV !kAdf#Z$_kWn?lE_rcR-I_mՍE(0Ɣiq%֪ClhPB)Ee`4hF8Zq9H *QIQKbɚTp 15C.Lf0 a9簙%RlfqΠH4׻ța*&ˍ&i 29^%0,2%JdNfB VZ+L.G-D2^iXGf3Uo7ŶV>/{)bZ^+6lo) H"'O>wɓl6yJXkIؾyʠe6zB$8Ȳ|%I+괛!$a$|jjo0Ƙ,ö|rGZz`[K`3HQs+1aQ5Gp-^&1C$XR(Jb3Ud)dVa[1FBZZ'ĪJ|d[t V8& KLͱl#cl:aӰ-b68QXC,k_GנHyۦ=+O.=9Y)q_m/s{InoZ2̺V2iqHe-"U 5爚)m0R5LdJ s-ad8+FŊJ#Gcf|"q\C%XmTFYDqVSь2וG!JhV heb,F8j,2./5y,Ss RKƲ)EcUPJ-bWA5Em9{^&н7zEOn6_wϞa^8w@@@F(sL0kK[}Dz<'"b$ ]Vd-a(TU7\21TcZ!֊$QTbGl,6ǨX["t&G"^9Z&V k3ԇ2"U!2ľVs%1ir%s@ޢdhP:&%4:¥9.-1tYRXMTѣ(""yĄEOfGދȍ^mZ+lKp? `6M:N]:v?ZCp^V`2uRYR䥌i/0JjQ4KYq1\P`u4ј7ƪC2T0)2TւpM)Ze>WYi+|nh$b("K8(IZ44(P-Aczl!pYN*7g(ZlRLRr2zq5ժTfIZU\kݺPL1T /0letJժߗevaVi0Z&CCCⵅiSMNAZETuU'#$.ζ{iÚ_Un9E@+c*Ɛu8aqؠuD:K}6^fem:NQY ( 5nf9.\:N2Kb4 C#4)s ,6eVƇ 8KNv)j1hNm4`GtY3\lNi_vÂR9za=]!SSS,..m˱p^h}uHuv>^o]]]=9~mzP ʿQ1퉝f) r U4ZZ6:|c #ը$Ee"i֎HC0o$TL WWRb'3t[w}D-NDa0G#M]ը3X5f$if,,,j4m4hVj۷cGc3˼uiˢ2G+ i/ME FD a^lA=2Nsl]1Jl9lj/}mۏصNs9p5HfrR.1X^<5zu7vfi@ Fy5-NYCZZX]5eIerуz0weqG!ԑĕ'ByUKQiJr394s}BZ ՠALSǜ+k֪uLFOTYj^l2ǻS\kqaaԑ)Łqn# ˤKMlj1AоCX%5mn }tF{9z`qt,gwmc[1d0\ml6T:ƽKkpэ(Jv ﲵdo \%wfy ڡ!N"jjx03&[Or}90ΐAPH m(]89g\۽,XP4b9I.P ΂8\eB-w*rhQp2DQB%FF} IFmYyͳ4gdhdɑa.\ũ98  JV+Oy{u bt^z]v0? <ȟn \xlÜts~e5a^4z(}b]XZ(P*Nw Wġ$S1Bl4:JjD‘ wx[PۜA`d-@%q =Zsrnm*t~2Gf"`tNўqR<$ ҳ\x0ɞ'Ww8h6ж&BYJ[E&C7Y̕ܕ9x2/_an 68bS:ı84>[+--c j- Q[݇x ,-=*-reP^|Bx ̛ZΝ{'< "4\P{r@VA,Vy:7m9%SXE@gPƾ[AbDJR<߱HMqNg:*F6%VPMb*ՠ>p`ƭG9K[–re.ֆ^sԉtGח5 YJiDk>C!mi=Eێno@{yye{aCpucγ"l֋$  E1Jz` F%Tj.Y~NrjQZciWoi+gQ;:U#qhiPb`D#Řph;q G&53rKT*Akeqn)f{%Gf[67ئc@o+j V ~ ߮|/V|i3Fnu|lSm۾V(eڧs9J wq?¶潶(Hyyk a@@u cLt{rmy^ss/*+Z׀J*Eab͓qx94dq8YIU]xJ%d #Oy/JFO릵/"8ɰU?qӟ)J)2d P L8?VqAE G -pQDH+q+ћoؑCԇkJs|66ZmZUD:=;ivz5vb#sQB>\ݩ9ӄ=Rw[[wVs˽PzB:B\~R*AEJUkF9 p­F0%U-M\aIUk_Mr/C^W8`a+9)CeSkqqގ(2iUU^{{cACW QUQS1J¾pdr?7|<*(u>Z+l\ /#:ZtW?]:o,w"w w@;|ӧ62W F:䀀5j ücp쀀&ڞŃ/ª$9młI[j{/ sQw!ReE|(T>ݖH J86\vG㵌!eшAҁ "SfdEk@-?Vk6b$I9V}uB .#K]EW׃VJ 1TdV*j(!N.@39Rå,.,15LVzpUKp] q?aZ0:lw}S7[Mv?/ךk͗ *ٛ;1.gJenVBΛ ɦĻqzUN(^$/$h0dL$G#88TEjpKLL)j4mٲ"vʽR侪A5|yy{ ܓ[NYu|iU&:Ie+Yd$IBysΏu+(kG%2q<6ƹK^J9x&x`gazAe_pްLAguG; ͫJѯB{.fy뺬nA9ZpmgJ@@@nFQA^Bt]O[,Ԡvj)еAܭě$Iorx^w%['X{rf0D8m" q:G#q- T@\NV#P0z3 t{i 1dֺQbpJeyβ-K 'q-Y2V9õ`0:4A2VH9HГ.ehj3gϳ8;|b8xVFFy78Hes`ۃwA!P71K׺7ߌ_--6`WMc]k*#̯t<\G%\h'耖NF)uUQ.c^H86Ψ6E̔K 8^4_+ dN!咷O"f紿[#b> 93t[k,գRp;TU_E1Kho]a~z ̾ad)KYl~c׃{/0] (%`ŶiJa{pbpkM7 MY"(C4F-#::-}Jb=D(N T^xP@'af܊z68C%'^(Zr"%}Udr)eXQM,3TRi0#aSeVG)ԙ+,LMS>qCJi\e3կ|ncFAS7[Ӹ"9@ؼkC@@I J {M֡02{"Sy-hb4r`̭G8xu%8˭IivP2:a6:F)%h.TwfC2*ӷPџ0^^}$tʲBhDlFAA$MbR&*5Ƣ LR!gߝav"#Q nV71ʸ239BzEWz~I#-<˪kطaW>పkR=ªdQrvEVz1,{eF9"%#ž 7DC[Dԉ J/5bR8.ꆖJ /<{l_&vyTo*rݷg^zKrzxl4%R6T*IoOR+\rr0+Zs~s_EsP]m [JK,JlW ivv)E:ȥ$PK"ő]G&y$vĕ*Z{4X^k`V:mNuW 2 Q2b(td:e:tŷ^q'U A)_Ku _NPi7e[¥$HbIMb;iz b N$n(34oM][/wx/&sNwFb%*WWRVa@G;簩K5H)EŔR`.s"t>\i֪h QJASQeVܮ;NO/}k~Ʈun; ɀ'Q秗gn{+zC[16*RN`Auv-"gHn;z1MX y YH-Qv}dhSOGmϒǽXx~f=u%1a`l0>Z\"C?>JHC,6+07dj3Z)['ϗr퍍ukczH64+o|O|v6usN@@@@BP".i_PE5]fi0u 1KXLHvTlZǺV"_z N+)xmroUz%bZFJh\xoBe CXJin+}b}=g8GH$:3bK s*LOr!E6u)a)KюP m+ƗՄSq" 5G}yO7\L>s w@@@@@@@Wz.׏2#bLX qס*XYD DF˵MW;VrtA#MQt󰭩{2H2#CE%c"?%WW7_`,X,|! Le96Zc\h,FЧ܀yˆ뇟I?ξ.9\zX4-1v$6cR>0.㑾=\gd䶕ߗ 5`kα>կ~Γ?9劊'uLVTTT>&It}׳v|߅ ׿?0gLԴJVsVij&;w/LH~#>GEOj}AcZ^aORҲ{99iLLZaIM*JIHLKr'^Mى9%\֣yaCr]s(0Ց0oAP`E Meâ6g> 77K.ξs~_e iX >w͏vұqN?"1Q}=E0N݊,O'YSQQQQ:m.#yK8*9Lϗ @ߒ5K'%g*TH!U C?}B&3!芊wc\ <)zuaHOQTҷy,}_d}ϞSO銊lf4MCzWlֱskJ䑩{Œt'$evЇ rem!9aYJ$#8(3gsw?? w5"D8(8kB x>ۺMmԃUJ.24|jR Jq:{cNfXwj e`&t]W aV֨K%Yh"ڦi^CpNNA4d-c+?GEsƕ}jiMuȺvBiXEÿ]/_,Ϙݬ`f4I[wС;gvA}*F*')d3ow>O7!"TQQQ3{?Ω@ճϵD&2eNvUʷ!W mJ(yZ?ԿRіe*S/Z-QM8Q"1ELV""9r 5+ ҚoE3wT|&M,,lf8kFRĿO"oeDxnJ:b bME[g ߀^#ZlZf IDATb@B,Oƴ#'{О8 1/s~/!i1_.k$$@ >.`W;jV3 +JD}7$h'yߣ*5jTQnLb,Kɮx^YV[ҋ`o< 7x)xݥx-yeO>snJ{ 2#[H,zlha ESJiD^/v$.4`|RrMqEB_Jx[b$HZNVJ-ĺDa[䤖I@¥# *c깎 @7]9|^/%sg7d=t?qr~a~I-Mw?urVT?F9P ኊ~fI)Wd/7IJBB, IXΕ}FԛbP %U7; \+DJaI%e{]q?OM0"=K$M8U:OBc9$ymMm(~]?hfT a.Z)bƋ W\..|:ttFJ^^+bx߷˓g7J_mO_^;Sؾ gC*)BioJNşaqb68 H83fylYzd&nr Ӣ6-c5C枳ϒE$MIlR9o' BwKVxYry\]DNeO\omnͷjt)͓_O/~oLBy߄_z뛴骨xHc='"Ml>{6m|rzKdt:<tMVVh6 Ɇk)La/B 1OO }ru H왷~Zc \*RX Fa;84Qǜm۠ !B XDq]&ȶbg,vVwHFYlۻ$}16lta  3h[sF2C⚏3~KnnY;m8k||asuS%/>iGnD}C{P]p]aca)96rzf6}xb;ȊDa2UKSr2>os=HQHb(FyB-)%="yՌD] A)s=X>9m,{cR kPq.Z r$^s},"1o?'EL9GI;㳳9xɿ w1gg  G8a|H!vs+;l &o${@ Y? Ǖm}B%s>+**<́< ޛc$ีfBL,'T 'pyq?ٹGҚW܄5g4b|inn^et l;M>~5,oŲEX$ :fUU)$CY((i푣rE{4"[pH8x?o'g7ۋ֯\-Y +emr.^sĝ0DФڽ׮'سd*auݶSc$hW ̏x5mR>ye#[}_ĐHQhfgk=JluO0Ooa"9ᆀ9ZRmnҜ vJ7n,ʾΖclIv{6۽DZvI[:OyBx4 xP퟾S;fMò,0o9vο>&pu}%?y M6q'\Ce{ODGҖU-bYb%mp^3TT6H%IݱN|]rg]~jx>dhqly#I:,Dg||y'=oִ3O]#3T;ӳHr)ɹ\ H_knwQGj;J~Gţ/uLVTTT<&/\_psi|vJXKڬDD()S")nǃBS|@}&vo&GJ{y7o]'K~O/l5wf TwjXM-,Ϙ˜"6X3CĻ5}&),G.y%b,1y"i^ 4bA4,{5o`$<"I@͉I#(4O3EmF#fWf._$KE,m\4ނNw8Xr̬e|L|Є|OYmCig߶t%C&MY,d![ e'tJK[݂diLʉ6Y$[p|Fnck̈́ySuADw8'-JwwNDrtBb#c<|. t91h}t_ kG8}@slxp> 4D"*0WAa%DԁEnonXݮ2_ m0543Ŭ+H F"" 'fn=u6wd) ^e{H:*5HnE9!)*e&+H!vP]-@^IeF{8g3DzFg3e9S6!樂}{,ǖ{Ev)3&#<EDD4Ae{w-o0-.?oɟ7EmےR|*[0/ZǧK>X2B҈ҨGhDqA49x삾ۛjjձ퍲X%E%6Bu'}"W&~jmfI)lQ<؞vE,&LO@H7k|RJ9-Z"qq?MER^$qx֛咏.;׳~T(b1ceGsG3IxoΦ[կ~dmMVǨ䊊w,YQQQ0i9b˗/aٌ~gP&Y١HwX+n'",@d n&pĎ dh 1fFgXZ4?٢+hMdU702!(u-v渽gs ct!bOJV@8K\?-%rit ."Ch;RwTV'vJ){!c=\Tcw8-5;@tއ3͢YY#8;Ht~ɧ|1"wc*wmfMuCnkFq, D>(|{Id+**>l<<*i()PϚ=R8RIӴ1jJguHZLXyu$hYYaC{,iު%AaӬ73R3QUGQPEɿ{),z5lK5,T iSfg:$QBkB,.%@QnfyH̤lsy/#_&2;p b0ƲUR >pX8w=a|(1{*|m흈0_?{;wc"bUSVy*9Gır׸5^QQj^9z|>k#YXC-f90II*L"M ))*3^w\YV} {ڶef@), f+QUw.q]tEr >d VCrLBL%Rj#Ab|"d=&ۿq+Py:D+{d^#ONO|WT x1:m3@D)0 ^ljۖ|^{6 !P9}h1Y$>HsX @xm)ZD-[7ST$yz6`}uxe;*L -!3X{V[noW]kv`mK`c (|oM)ۨV7GO:diTH`I5,dXVLՁ[)VSHN. *p61JY@p4q6qskl\zS7o9z@9/=MY`O~?흯+|NVQQQeEEE)jHsTL1lL@ aonB";BCޡ0syHh3oACA!ZD K?u$E~o*<? T<~[WTT֧2`****ޥgc?$B>}ߓREMňC;#=fkEEqM**z(xuQӱ+**MӔTj=fa23Bx)v+N@#N ؁JL$7 wqx/R },%};vg%c9RyF AsOY,ܬZ^nI sso pSD8l8 V@KMV$\aŏ="|G{K 3D=* I88kD|X8u`{<>****0b_9}iC[TݵK*b:2٬{ٚ;59J*%VLA XCJMzd ͔ThQUz뫯ιřX:ַۛ57ar9g>oq>mLA9g$z ]DH@Q%GSCiT3҂69^Y^¬,eFertjG6kaXqG:5"wN$b=n$F?;H3ev{Ɣ ?6y:A{%xm'{\r?KMv |#&Jrݕb)d$D𘤔Ӂm )4ųEboyь﯈1y-\\fŋ/Y6 Nf!q9y-fҜH1!ܺ!:*2 jǔXdsEEEEūM4+***)޳\.1rssz E4EHJ-Uyo>N: MCtLik9E,314"ӗR$֛1zEmT3)Oi-+@Nl䛩8U3$)bڙдK|\]r{ⷿD;o,-qYy![}S{8@4da?J<͈1=1Biwn\@*r]Sk UE՚9 VKU0!0˶_ }a$.+h^J}ϞƒVIwuz%GшM9Guo}T sEEE;\Ɗ@rBO *`6,sps/qa.y۠@-DxG!wd>H`d~mJI%,ϗt}fMLMw%fƧ~YfYeb*%9$*дͶ XV&ABmT 4?Ͽ|F|cWTT1YQQQvtB莑o v$&O#H Ho)R!z:!q:e'%8/g#VNVjbKU2cioĒdrjF4-Ŝt!XW5/_s{uW?󴋜S>fDLCշ; ^Q9l# )A˲Ŧd'P|NEOC$=͊P08Ի436MYR0DcxVa" !EЏ{؃7w*"XNoi[N)'?ձ+**>1Y***I i3T!"jܾݯ'SC6 JqD4^Qū%,0"\6 !#bΣhpMZm[ڶ7 ]` a*(fJ 1qݴ]~Ɛ-AWp ZLzΖ+7~L/if ]舛Rj["J2lEe&H1☵s.eTRK4+l3(soJ@J]d d7{ߦ* *)?fb2ާ,/D՚z,+?8!5?dj{WxE 0g1Q~&Ǯy8ߗJP)+6l{=~EŻr8:e͊69~G{<vE|%mftz{9* K؃\vɲ/r)*1(}Q$ҰBLP[[-XƕLb1d)jc~Ša$ }?mOﻶSɱwVTcb*o2NVHWTT<m#˙,{7o`p&vhBh݉O@OyIܮRIvQbJc=k5\ 7f* _0m|F)iRq"%PhS~^d>,❜P/&$]ȼZNCxeeeso-: T7!Op0}EŷcLWTTTE}tEEE]8Ґ!}fd' N[2!uGsk@}ű-̔+QH۾&vtt"ĔyW#i D(ǚd_i_s/뜍HDVJLIs"DHxG K_{,ڨc̩⶜  5;s-3C)/c7$Y+גcюBfآKM*[K-2f1qH wF6 A43V!^wVk6랗}mm;c>6-Dnd%!8:kW׼(f=ńEZ, 3ա~y^ = ,fЋ'l$DG P FN݅7cE'mj^J61Wҽ޷D?tdcԔo㘻tJ_~h잢*㿢?0_a'j/et~ҋzss& ^|I!%qcE9@u}қ}R$"@Lc!,&e5lqxi%!If1iK)6 B1Xk9씦VV}lws9,^ iḾ:2Y1e"$Qb*6K1Gs7ΒHH ?RR&9u\5}YO"!#!ꉉc_>70%L'J1e/$'3,D>G3S,Huea^:/6s>j_Z>1og]-W])m7_cVERЦDHA<&b7i-ucuK r>_S 9#;|Թw0N+*******eYso{xx֫ՆdKTB#a=QB}j{X1œŮus<>,P'9rMqP001g9n+mi9Og(.Gg]BDX.h=;GK@LkYQ3\u]ӡS!ԙ05 )d\TnOR!$btx>>?&0A+****vx3)CT`U_ߧp°MKA}3"Vk#Kl6%4Rl'$%[t9TżH$QmP*1HH kNQ-d[Fa "BĒ:q_b"8*;?߱q,kNY rXE ڊC]vaŜ#”vK-ӅDrzKSãc;SĘC QbڦOYV sEEE;\Ɗw0l#Q-Y6>6Xܝ>cܱZ| LNKJ)]zL^Q} Z"bsms P1yթ*)ô;n sJ(q S^!Emz-@w[)"fbqΑDdГ,x7lN_}m;i[o 5IQ FI"zux`Y ̈́T1AvSR%:Bջпn<>YcY3\fvT把oz~i Wԃ0T!)(Qo>AK\ȋ %Y")0'Й gٮK,6H 0KEٍ"Z4,چAA#)&f~F^,U)hqB YV?RڽNܖe!=ߍ%%'z t]Wrr2{% 0W>ʾΖ.VTTTTTTTT<o<ﹾZs} G3sd:zl'6=[RG'̂ ʔI@VXW"0Fl&CcXիµ`+'BZ}Lt kPU-iؖoB08U-fO$m'w rCzBotF&b΅b ~Gţ/uLVTTTT<N0KkꌫW/o?;iىEiH{SaO,u@yf ev…S!C{!vl4 XK۬iˉR>$$$4Aޛ,IdgQU<;%3R]yYdK6Y]]?\j'ZԒOлbJ,ee&cxO6Bf03q{( @=DHDi1˪M2RT< %mA+J W9[|,f=D56ʱr&FXڊbYj;]9X31*1upޡ\\rYJ9k*$ќmUQz[j#X%ee1kqМ C 8r_Wvzgffof|`1bĈ#FE˨:ʨjYh rkҝ5h5M^=f՛mڰeIEP¡E)Y=UGKcZyBq8\1eG|*[,=Okcެwf M:\ ,mם tS{-@qAJnNoW1Cc; L=*49Z֔d) ꔤ`I ,҄ħ8TmӒbCBhs&Գ'm#S!Fpo"sBFM?d:d_c$|Ĉjنuþ/a9zC/5^Zs?rO c4xHϫy7<jF Z1s`u7 f]9u]g,u?8p*{]'%8@{Fud/gUi-mXRꄵkVayĕJlDɔ2I|QW39#v-gݨ,jF8K1h||5Xc >V`~Uo6ԝbd2't: mWX:iu_v,}HU۾{}qXhzI#d쒤E'${BW= ֤lkU}UUTE*><>-[$̃푒v92cx:ۊIK|o=e3W'Z܊A/]N y7=;2zHrᄋ՟uYUXZ3zѓ)YdR IP!+GQ|QM2ȢI4Zl&$Pq{n{ל^}ޡ]ޗejׅRU5"BJ ]a~Ixj/$7ٿ,jP:#vz3,H1Mus31OYQlVThBZJ?xGUNyHM*W"ͨ.[x-,g׋6"fY/}'uh: U]#8SEN/8=9Ʉ=h%݁GI$˂_)6.xZ5Ds<=2$6X{ytgwޟ{mnwQ2#5^O#FxYޯQ[Fj h0}]@B8_p:9Q`6 x3bKq0~Y.e"}2kf37URϞ\qV\{Mye,{]\Slr`RjPfvy*39a iy!p^H 1M,V*bDe޴=|[z"c l~~{]kĈyĈoa.iaJ K/(b3W8;b,ȫ3.~>iHxI{d/9a&n~MKz\ylR{m_KŅHsYa5LOs-NcWFںabE943b8q./~ L&S&={FۮhjE, Q2I#Ѧ2FPqiD*0,m"];a 3sWfFNn..NӱGXp?RfܷXR޿`"Bqn~q|pŖf0TՎShԌ,F;`FԈ-Rjde宰TB›nM ωQU)r[(J(l{1HY(BE<^Nå"Gs$4b0L1/B A6%"-˟*Ñ}-.-9ehhIuOUE]@EkOP^2E5C'J"hRMc(傔"!V1{Y|#"ή .|C5/q7"9OTpz&6=t엩^%v{c :{uq=u1běN!vN̩oX`@n}Imd2}dbZ/!CEp)6@ u]bi R\޺bd ⑴g]@Ҭ Vj_wQQN$ULomؖV9c?1%(YN0ESJm Is]/N6e{'/YUv2atrt#¤8&oΜ ![ 5SJC$$@pXZ1 {Oi)UŒժe.qEuTѨZ8]6 Tj"vjngR0`yv=b[d9-?O>G~_m'xp"!9=Cwƨ؈74uqncĈ# ]c?\YVU16mV!6oC/'U ɟ(6SBg,EiٳjCC 3A-!W#0=,a2`)DԮxVui3)6†87m{C^Q]]"9=iMMu%{QutmWNzM̭F9Ňsպy: U]sJ8syOCMrҴ)`UskCyg)Y?p80-ĸv9Zؑ{Qξt.IC + u2r b:%'q)+\$gqѴ$ڦBG0w1Ǐץs1bC. HusC÷Ca.|hܧ['p& ~|ӏxϾDLf D49껴lALqpi+S:ܜͼss)ӹ,bvҬ0mVp!9 ܯ#̶.KW;#i[> ..O 4b %vNRcx$#a~c#kFG&fF۶k*n6 xHs(pս򮣧mσa8RT(U3#6xH֠sԂ*b\ҫ*ݭtRyqן+/P9ٕޤx25QEӮ)!HV^4iQ2>H<:+7oZR2shI>iW-;YϹ{mMB*}U[SL+4UZ0/vhCd1[`?sqBBp拓5rsH 3ڳB AiS\ݯdsL拠OɮdO'˪˙%lsG6)>yʱ!\\d[OO#F1bĈ;B'M' 1G vta)E kf;Y .JB4ǔKѴ"TU R"pHg|^EL;{Brt㎨cL9ù[Gs9_UeI/qDIu-z&.8F^TjfjaTSbł j.[ȨunJ10Wm?G;#F#F%ȓOPw'wJN[yW'̭EC|cQ .O|OM4|s}VIߊwǿG֠Tk|(~/X IQc!;gxݘ?.r+,[0w^BE!6udy}8)EbjX4+9]h+9/[C Wh#kr\1b}"HqR:UmM]Mʝ5TĽ3ɈZ|TExy)O\6ZhycWDL#=|r n(Ela.׷#̚rJv뜔ߙ.f+-|QUsn?9ELŊV1+^-{y+i~JXuW2N܄׿'ǒ8F1bĈ#nm5޻(ӎ5, ֝>s,$ɔyr|:b@uFCPb*ⶾ^k:4v ""ajM_O#F1bĈ;yhH)\->O*Zjk^22wnd3j_55SRg'WYbDɬCr:hD F'጗??ī.`JBRh~=_1<ʹX͆+"Y 6/oSD")*i]-Eˣ)GQAczP[&5B)N@f|ne\s,x/YrjUd:/0xS Ed:i |qrsCOx3h4ZxPA`F5d5[cqa;eVWi-*{ h1yF7YIz|t)ϸ5V7);~xȅ6bM1bۂS%+t!yuᇼ%Z(EW\f1I B.D#ekaߜ|=c69۵msEmk6mC_YG }vw{RbRX\Il52ۥK4aumҺ׺:Z硜3um<8l&Dd/emьf]VPDK]M%KeaI.߿ZtA"B*ܷ-(7Nn.[[w'J֙xA z ?FA?z~s1'}jÛ6mHFdy#FqqWmMߴl;,vJM:O?*|j<dD,>\B^_?G.Zz}%u} XN.Pt6QEYd tg:N@gz2xbYZഹ|.b-iӰf}y^vgf"ᷪ[ ~[ۂL5y7b8FG1-.t"9Z-mD4 J uW.YF~>xG57sFn?y#PҴ!yr6g".9Ix/Ŧ L C!{Cá:z11bĈl6i!2wM5"^asa`ZuMCQuֵ8OKK˳O죖~55xSD=h6/[ثy%?3#kfZl ZGqK܂B7mHu]=4%,DB.p'XI2er\,V*՜_iLf5+e\N"̻~Nel nIdܗJ;O&}6^w|^CH1ILjw1bۀ.j]T1FZkqQO/vs~t:VFCۡ(YEӑMU-n;պO2ׯEsg%L&M<3~|OV4%,zj%~C` hcDR9(*NJ09󘖀iJ}z"%KUHIX%%CVF\7Wq:x 9[uh>Opsn\ۈߊm{csKpP#7~gqlCQ^~Im㐅#zxktĈ# 9\nGL !"Mrw u4D/vu}%]JsGwSAaHEn2% >D㇗s~)g'L&sR^GҌMbb>vp$[tlh\Jƛ9ĆB c[KHq.-9$Y틭!RBpYNIpb"mn]R]H# 6 ))zΕ3',S UXD҄{& Zl)ku"БsqyenC폷~^+g{M$/|uFNZgyo77u|=v۰#9bĈwԑ̾]ns-b>yGbH{}QՔ-g'qm2.V,~}~F\҃14!9{Jx2ײeURy@zQ@:tӄ!+^wy_ABr^*!TTߝsk/qѬx?ū6yb)~ӯ^ `"L :GQrbj֣+6a@%[}N kB7K{ⷆ0bT宏ۻTcdn]HGnb:ͽCMpPU%m6Th%-"dky!fqT>va;̘ 81\WJVq|2 {G bTqs_/|yGw@*>iD (,H2r R~-e`D\*maFp(N[\DH; bP;B0BC=DHsR~rYqsU\.b>j&7+>%_~wykӐߚ舧'T>i4HU<K ң:|~C T105y/fytCG$dof zx'C,ײ S<1Ϲgg8=k|w2NyL4uE#O&aBcR9^Sdkܗ IDAT<")G*IkxZ>~eHtYog-߷|;g:5u=C?/~O^oM:aj!mL:{74utm1bcaX `76ʶ~}Ha&_KLmnEϓpcom^H¾޲NݐfҐI96aף0T8GY:G|3@UyD*$Pb)e?D咿7RYs$K κLX!"sJEYqbXL--7 MMSiY)*\Qβpő6 @]'t&]ZGCE%K$_Ȓr34ŭj%.. \{|&gْUXH˅E*)'3Iy82#mSW_W V㞪u)J3Ggѕû}羠{ȔV_av.`E :ED*&ŃxN.,aJ&| ^Tr95F-<~Wmۮλb2_xy~4TJ 6 #a'#F1bĈofMlF+X8!L!XD Hka 1rmCD/bY7ʳliOz[iO3N&ΰSݵ(m1+숨Z:"E,E9mݑs,tEIwyp_%η?1bxM1b]ŋc-['ݩqAe}#ۆ󶶚g2lTg^D0'ig(/=%YjWgNg3EԔ.R\:cj+vYZWC~y%J#D1Jwʺޑ8ŗ`UaeQº}wE&"nMHIQ%[(RM%^~3g8U>1矿y4Up1lʓ3)—zpsB}}U?7)1n6Ȳf1=*\oQɾk_Mk#Fx7qA`Ĉu49AzZo7)vO;B{a[ꤷm%\]~eސfPќs!S6B]jZcRT*Ѯ@dY-Rl1b#8/&4>ۑh0iy͕/6ןws䳇8W~ H.B.kTRbV”9_s˓pGO9]LݧϿܠ@]ՄلO&f'1Gۺn%ّLJw-7 ׹G׿'o띅͌1bĈ#F bu]'ZԀobV]|^18Q[!BVŽ#l 42[Z4HP3$qIӮ89w|~O#Yr4 LUSNxQLS*⦲GSJkE95ݎ0^=yg;bGނzyux)u.5!%+R:w$]αlOiJ&sr|g'JSjyWo>_GRl%e3ޛ=娾hJ_kX_ι{ A>v*̉w0w'n_~T1bĈ#F#LfSjx \N]k=0EKާ 'd1/'x*Sz{~jvźe!Dݓb9kzL _\\L0ms vRCH|rzqƫ XY9&M&S*0kìAuՈ 5"_o'KxBaRT>ьY]!hҊE’Q!hJ6=VY@-j"XRkϻ7_6Y.9ʶ'pAlU ?*| }}y}>qy.ܕcJv߻m.o3|Է.>aĈ6Mhd5oI%"gXɦtAB>ܛ>&ᡢ_hM %.5׻$\,Gͥr1sGuӅ 7o,۩\'⳥Tb--dȬFss*k 8>bυ/_D9Y{Z/I&5< 3L60eRO U$T,U9>biRIըEh?I'upDĹ~^)GRx$0mM"} c2'Ь4,N"'Òrg̎f\q?xη'-9Hsmq>e[$S֠kP{O}n\ŖVmҶ-1F|y,ۏidn1$ObL6M,,[ݞt  iNVJT?CV64/H*û#R8=ixg+mz!2}Ec| %_,8G 3 A@k^RdS7DL+Fo/a1kqg\a$#WDvoR{_Gw_jr!?62߈#F"d~gڞU'E^kfn?j ڪHLRHrJL Hp5O01o='=tET~J'̙ūK>}qKPhIU+Gjhf+|eׁ3Tt܂v #/6M }`n|21DH^׆Iޫw[uCsc>jۡm2bĈo3 &7*U.zx92Ք^TzWeA$즔2,*w" x"Ap{_O'?O*LjiuMpe]!ddaCԬ/%aj) kn/DfɺVOUMHhD۴hĘpjqj'  ,/.V˷| OYT'\ݬ~fr*c'db@tŅ1~;G +W^R|Un.kMu1z>s踽q 7i]F1 "Ęz;fi&2&!ǶMZ޲͹n?H‡ ^1pG؍0O&Hiߪjr̹F9M*vP2$#j¡,Z1LΓΨB 8жՋoOq?pOj=8*M-Ċf5u 5,[a'ZaJy t[؋;bl۟mw8Emc29f Mprprr΋3F+'?ow/9M$ PBR#iQS\}ry Eof)Ij;{݋y zM҇$bpcxěx#~<#~舭~L) c'C۳r15JYwԒx|R:{6@;xh:Z۶K&))wW*#N`W1f|2Aiο㋣ ?y:>j9A}Mj*WS˓rcɒ=" 糏Y񛆢@'ӱm`ב܏ߖZ+EJE'hZOt4Kt 5Nϗ|bż1zP7U#s/H"vՄ5J\"He(8LII,5f0CM78~H!/m0 ;Lc1ip)7m$#Fx{?8T?cwg:Tx1)U QjwdU|RE3Ic޶~9?;>'St,=IIDD 's&놞lo#(e,AܰQOfz-ymkOWxq‹E8zsfOpuM#/|b7߯sCRES$i-Y9nr$wg| \_H~Hi|HTu?VdJM$w5o3}۽n\1běI*܇7dW3TsOG޽wQhF&*жKK qЩN(KPU:E5~{TB͸`Dxu??8gMy()=uW){cSW UIDrzrW|>apTE֙vLs"jJ5<^p✳%uuG}#tBgs:>w}ߝqPԓ #[U8fӪ uzc1S _{H|ӚûB]w=Uj}ujևqvoϛ}Ûۡ6}1bĈG]Գ92P~@^~_ˉ)=Z+OU!pɤf(s%Z+|s̈mD0'̦.S%j9UVYjExZ5R-B5qO[|T8c6 1PJZ5NqNQmq!hwmj; I-]N'0k`'9=]rqֲZ g'-uڂp|ߝwpr+skAJ@OMicW%bI>d|քO_W[?^klFE]xDZ_g9{I7]c6up1bĈ8<S~]e 2I5 7CYܾ_B)Cȭ]􅺺]lTL{G9 `8/ԓh[בP˩ڎ]@"ȝ ks MX,Vm"41g~Ϧ,s\ɲνf{Dd{URCТjBy64@@k1@32 w'htNw~h$ؽMuۀw9{m+QŠB2 ͸ڴh:`eEصp]!( @ހwR6?u?Dw_~<|3~p?'xh"6AԊ961 nnpu->(;Jۋ 6aX(`gvxɼk^GSX%ǨZ}SwTۧ]QxLdp?w{߾%n0^Ksmk|wlcA ͲlxwWfUAGrڋµ!B<ǵVYC,UHI.WC1H!ZLB()u%W!H6{i}"+ǧ2E 9Yqv3R0@5:ACq;4p03~:$tW{w 뀭Q ^ᦀ=2t.C H\V@YwzSv>tj1 IDATo;d6|Nh{npoO>%:sѕmTl}AĀ>}_HnHn(g0DdQ(BAላE"` sX+h'eA._%cxRoB0 לG./!pM!gNOeq_S*iuӐ ;]L61QS^_˖U咕e, NF`.D=BY8t @vC6`z|!c# onVqضtxb4ضne|h"ϊR%ӧtϷ  4mjodiqÏ㇏O'tr5lX_̺d:, \V68Rio9#c2^ 1=v( i/~'o/p,RKZ9Bhfo9rYqvjcoNSY=Jf"4vQ̷m6 q'dO8рRǻ شـVƈmŻ-7a|J32DSlّ:E2 sGhW-MͦED^S| >vOnq $8Aœ:dD"^;o˟zަ/śd-=z-skB!\9XkMpX QSbk]?O3~j` ]c[We ,PP?iBnw`aj/6 P/Z[[F !DD6(uěW[mA{;Ç>? ]rt jDa|1ƒ#2ݧzmm4, J^av ~Ϸϲk׋B!DJѼqڔ/ujUݓ^XO='jf ni|Gr>ޱ,q42A&i2FO]?a#4-v;dK=A<NZw%)BŭRM.΢ #Elůn"6Aiӡ!3~Gq[|G.Q {@PR'`N`GYTxڵT4^. >qOg,ەmӭP͛~Wzm/o7!$!<'5J65ZKl *kf'ӵtNU"R҉E1>O*bb6Ow\5u9c*Ԧ,ˆ}I B![N̰E҈MզնE|@W+l6p%G&AE|b iFRF\z .g~G{Ǐ? ?}vSK^\7ВUi4MiU )D8dBpO#}s~t.Vas)@tBp!\"@7`(}i//}B!2DG_[ }tmht> ,OT֎D[I?ϹqO}F%/Ke-Sby&黾s>^tCa;Dҟ؄ GvJ7WWAlQZϷ03t}SƇOO?yg8d#ϊ[CEDP)MiSi"¤Yk/0_Ǫ8[Au臔* m0`sB=/ҿҠ~R#iYlWԱLh>E'B!Z 9ÐW?}"68 u&\.mW&h^"OOI*-3XN0w|c@Ԁ۟(ڴnp6D-[E4a&H6_KHC6e@gCv$76@Bb6 H)Hu AJ:y1(|\lI)/c_͔xwsnHnqϔmlf7ϟ?L ;2Ҿm fB!5cϩ Y|:w]>%l ǮPL_*wQM,\ʗ1h2wEWg8Aж wyż ()jtb%`yCQ<ЛN tQVG.-M/_F6 46䐌5hd$ϰlhE x鉽T,]иrj~ǏaVss bY{K{+Os-}P0B! ҧ Yf 4ݵ>weFE.8o;IQ)$D)jSÖ%ʭlǭclbrS7Ҋ@m[}$\ B.c[\R5WqU7wwCR`V}X>ĨկnKd<2jZ@D>(ks8?j@ >A0˺aTrsYs9۸%"'"w2+w\ˎ`&B!#at骦Uf6^D܁TpdY<\\Oi+)lZ~D}aS'E5t)cD"DbqkvI0 -ګa"e{71({D2m4`nң >{h!z]>o HReؐnqBqk R{uNM 臶OKCX˾pu5nC@ yn6~$/Nы'9_cbOr꿉̄B!d`=o-5Kw絇ӧ='etn !GeEm<.ZC؆Nu dV\9Y qL(Pī8dNKU8PLff@0M2j*J[2\!0$Wܼ '!K!h 1G,*wڌ>uA˚}7 cR tk=O ܰh&g⢓O?լ5ܮohIk;F !BQOfr7k\ZVSSVkU&fL5>Z8C9FíVz?6fƌZ3fwxiruH55;h| zADnET-ßU6MMۖvP*ci;4aOJ^s>^3?~M`&B!3lT,z)_Zwm.?sgZUA&F!* u~}{ Tlv{m) f< IʽRp3 }ȘC* 'v}k|4e[seۥOs 9 b?dS0B!oW0WWryYW?\gU;m+V#!@*Lv*r+st9(u=׶IJ"4|`wsΰِ$%`RMf)Iul^UNk88a9~uuQWk-|*_|i[B!Tq1[4jwY/˨uM։u/.Kw.8Z>ȉ.U]KUl`l3T^fM baZ5['g?O"F\k r50Oqy6W:ֺ2MS f7g~~/3 vE4pUd8zKX`mAܻR ;yf0Q|zcJ8Cd.!kXiW8by]Ka.HsPztqfx>y]r^]X &zg fB!r"BZGֻ8M1ջҩ]f 8/ls6RҰ{>k~6ϪȘi6i]zi_trDWv-d*C)"UfAr#_;*gE[@1D%"o_=OH9.LTlpD4xmg* ީ CD}|!|a!I\BL!Bގx]KcJJF+_wL 񣘺s.0i~~->etg|yLGhl|jkA7 }cim7x=[Aš;~Fuݢl5zaMccy:H2krVá'=vݘ!0m#43\P!_̄B!^qh*#v*:ej"~真ԛ;ZfȃyqL2JZQ֖IS!~r==`NQUvr.L~:Ƿ3`m 7[|wxwsMBp>}nC]~>|\)gآ'qͶ4;6wz^OJ]T>"\dܾahD( !B+ptڸr~V>眏X>9?@0!Ys۶hvu_TZzY(J%a< |nbPkS)!hv_\y,RVKۦ-mw Q}_Smt>^{QIA.KJ^TQ]3V36'8g] -dtI'̄B!kGeGUESQr2'CHz$/߻+Z&X:mB` 5az~=٨! g4%xa2%6O9LJ-p黜6y%k}WӍsHPt mqV&Ok{EWWWe-#7Żm=_whU{V]2(SA6GNxt`׺p=&OH9 s{뭗"o>2(bUWa>,RN>n\y#?qv`E|Wӯݺ.\Zr˜ͯ/l΋73!B9> YI 1AOQ{= c\Yh** <A*44 $ "0`Fd<s b0O.z)YNdOPW5%Z\{~mSO&Mn6\5oEA }ьOZ BbD 'x01-_d}\p#K驸:}JpDGˎ Cq%+"̯'zˬ^=E_O|\P9sM R:AL!B ?:ks;]\~Q&["rΊ x÷=!2j -vbH}J)zOo3')6C|${1LVM W mm۠u[z 4 $lr>ó,-BblCrP@ U/;;\ S/+cu?~{xyxn-Bݽͷ =OǻM( !B 3}(q=?^^t\G9۾j){ 2iۦYb]bZǴMT]>֔, ?}!3hIA#ڶEh$( >)!#6 :ذߦݠ -`~^7{e<a[)B!x8Ջ"ki뽙ϥi?46~Y>z2Gy}ydl+2圞{:QpPhI=<'þ0Fu%}xU8t{ذ@PDvXS}3S)gt]nХ.'d)$.?z܁}{?ŤdkLm^-z`~;3!BY>>]u]d*pω8ޜ39pyfŴLEW{@/[ad:^U$@}d]_00h[6Cm5 A݁\DH; @% qϸnbj՜8jE#OS&?jfU#ĀPr !IOt?4\sN$W=]BL!BތmG/yl+%p??KQ#~ԖG_ 1FghX}!k ubUBvB`mm#n`}ԣKm*h-nw#gK|'d"_S߽{7.>/6}\=q%>Ս7̄B!DX>JSJ8^2f&"M ɖ³c@=+ 3R}iah\!|H`Mݖo+lRƧ;`yþ͟]#D=Qi t.i8` xkZ2{N9O/׳q/YF9Қ:ηK;3̄B!MkyB~wimTDD,m//kJp apHO"̵m[Dbۈ ~ 6 ZQ\̐,O }'Xr f1B5f'-h,1FOţr_w+ɫy*s(S^]B!|QԚȗv-2 ~Jڪ홪`~N 똘 ?3 S6faSB<+6*6oZ BilL,AA"r!"f3}ĈO]1bAyWR[\v]_8U1O?abٔ?wymszkLkßmӼۚ@+*f#5/e!L&B!oEM95>X+"C|g*.vi~C(nC*F ANǨ-#A-ǚsI>eh?q/)kU)mQr3@̋ qSNC]xTv/[s@.~6QS7Z;}^zOwu,_O)c@U=gi <`֠֞@4}fVgyM h D~E9QD(b(8VdHy8NBd?=FW2q.pHp>v]!4Ͱs΃qV۝Nפ,z*Cu]~ٛ 0B!7SjRsEj훊(̂(mFRJ'bnߩ3w~kMOEhO)]Bur pw-.ե94%t:z<¬%O5 i)pAV,H6)9=ros01hr50+һq4―ZA`vt"#! 9g] }v$OHi^q9"m ?#|>=Gs03;I/OY+8:bp>مS=h C[AL!BF~Q̶mfnE`tԮ&AU07d-RMb(Q. ~@>mж(P\󐒬 l!&86Yc1"JѳELz1C`UEP-Afc  H8L)!'+i")RK(#E-ΚAEiK>c04.ܵelk\:w}L\\8))لB! 9:8Dܮ=HSmBU8i҇هG<".iłK:witl/bS.uB}0 fۓlb a07^}"fŬ+dXC^kA0s@>}ڕhy̆Uޗ.{ixʪi1ۣm۱EU}{vUwR0B!7nϟtKk rERDng"㡭|loJH4ag*oX{9!3!By;RJ`YLiSV*>q* TSܩ@!k+ٗ~{fL5ιD¢t>N?] fY|DݭYHщ~>M o 0DE* mһ\\P ڜT89yvL!6V8Fe$jR{I/Z"_`^sof̈|~&ruMw<3L!Bސn7K״>FBBx*fX%BDP2TLjCd@@ʐ%uq4Cz.(ROx&P( Ţʓ=ڣ`d/j"O(Je[g ۪`>S{QVLXuq\lfꪊ&FdRqg+ mيCl"'sw=ݡb{Tz:r"-Q#5) DAzɂt-K&eHGJ9HL=uqݹ͋ \cr fB!Vl6=4:FWa("rJѨSp 6E@JԼP[ }qiD hb "H 16 }I[V=#=PĹ9e8J>)5>/44'ut\=SDkP`|6>Aц4য়*+ }SJH ?,P`.B Brst0Ϸ5u?6T"67!kB~+# 0<\Q2\Ɣ`HI7k嵨VEcJ9=앉phE ( 5ʹ1?:;{)ٸh%qTシŒB!ӴGw4XRsUUp8 yO/ f  D`_uGM,c? Si!VDE4Gg䮛Sh9AXy8|?X^ |j2].TJk~P[koqT0^uv^wM;x=3!Byk]} AR>m۞|*§i^A%G1 E%:iB1BP lH^~z=y bW(&dkFfL5`=vB!| k33*XcQ6뺓CQٴVI(fVUǚebP|h65꘦"`53}~sz2.+)_b P0B!=RJ!ij* }cMH mM]Ou ?n3yqnTg5MRĴʊЮ:p<;Kh69pJ=#]٬pS1Uf%r`v5A[-+nQb|d=@H BFd_龾lEqTӹR̳" TG0|CDu=T777`&B!oZK˓(Z#̆?] k1\NQkGE4J=3a)ׁ1REUѣ `u 4ms*eZROy|h+>%YV waԎ^o"'`&B!`j}M%MS Р$3䜡"-B/oi$$*.?$?.(qy&jsBxCCg{"O5oa >Qc ^t_}~>~Fq|Qs6]cX'B;[/`AWX]|'/*L _;.xU9z_u) !Bȉ@ڇy|S(|*ql ,'BN}2FߚizMc@u"`t_[y XJN93cSWѪ`sZ , ߣ4GyMt,1(YYXpJJϻT1+0օe_G`&B!$Uhմ-uِS [^Jv<~ǃҠˇ:3^bG!vAbap8`fhffs(굖s#Sjkw2Nu L%2BҧWE?1>Rkޓ!O\ AP0B!/~jXTH}B{>E=WPꡧ+`]?G`eW"6Fl7[GBӧnZG$2W߳;BY{ҏZ&xbd͋:"^6zt?1\/^~-ճ;'I gIb ctCu!œu4'奂[EAT fB!>O] w[]מ.]1T#]rP)z* ꃿZ>'^&T#%[[Ii;Od=g:_5f{3xm/~un)mm|SY=^4B!\`\#Vf1ωSpL !ܫx73f is:5%ar:oG%i9@cTsJoŧU>ՕihFL!Bz! Oy@A21V!Wac\>P"0FՏiZ3N\tZm"{}yv9n~i75]O;ok[d6f3b#̄B!!JEn>NM{.V.YU-bAQ}QVj2Cq,/E_ \O#ò}_*Znf_>S_ENӒ_3Fُc\y{3PR9ڎ0B!7Ǐ'OӱUڹ9Ѫh1F=b•RBH}BSͬg˪r:OwJŌm[4M3KϞxfS 5sb~m ثR&]u4`~+Vj1iL8G\箅eԹǴe\>Gۦ3!b|] KL!BF9Q LhHi"Z圑s A 왽S4Z^{IWDb!/U;fzT=ֈ̄B!dp88ZOͥ.xU`sEDЯFy([DLd Zek(fevжE0l () !Bȗ@upw49+yN9~L#li4¼z`./BD`~m3"mr8tAχEf fB!!CQ ?K;efEzэrXΰ02,gfIZvuv{>! Ac&^/1rf}]򼷴K-'~g399wcl/viכ1=F7THIeO9ˊiXN5r7OHT-ewCߧn7r7Ġn[|!gG 5ApEPA Nt RًXpSNĜjXJ( =\G2Cr+ > b q"bs2!Dp8tM@5"'ψU\40wPof!͸\`p?m&r,O:VUmhOz>^0AF3LDl- /϶W?~DL!Bކ?p8`fšvHT}:҉Z aYJ*#=D*Tg ꦙ?W}Ց7 }ם<(϶nW2+})@ӖCS䵾O@4962^D.A:8gWsG߯.D_2R}Wgi^>Z-MĦiߋH.aNѪcd<}yV,Y^358?/ENEl*tg _3y0^>;8g Va`&B!onnnc[A9Bhrmw3MǧONZSc֨35Br\"0۩`^k _.+߾Oujit9l6\]]K*zڋ(NJgӶجrkbSP ںDGDD&¯f풚&ƟvqgD.c"5*1nVxZ%=!]@cr.¾imx9536sRSEd f]6e1f. .DdO]!H) m >f{̄B!mo~k׿YZ݌}s]1p8ӞS\ET R.kJ ) <@< <;s~=6VEX h4Vmq1 $. u/v 3/. Ԉ8"b L뜭  {$˳[ll)#7Ck)+ 9!i2w%YZ9dߩamQ 1NEb>Ӽ.Rei23aN@l7h+|B!={l[963~!?>}N bC暘u('˩d IDATqEר_=Z֣L){Nj mVQ2}uLCwyam?'B!Fmisp 2x|u^s6cߟ]ϝ췿޽0Fw-[A͇2)c 3PsdWڄu^c5-c;yl͵6ӜfO Pk| #j,:cݖ66CKCősw?Q0B!@CyKo|_4|}R0B!$BB!B!̄B!B3!B!BL!B!P0B!B!̄B!B3!B!BL!B!P0B!B!̄B!B3!B!BL!B!P0B!B!̄B!B`&B!B( !B! fB!B!B!B`&B!B( !B!7#r !BȒ˿}y{k߹{ѥc[~}{}P0B!oB,˻ҥ"-֚{1wC![)لB!^QtWk=B`&B!/"Dߧ]]B>\% /»v|o dB!g|Ϯ}=G=}ۺ%]jϧ fB!B%Tsx-v(PHا}}dtP0B!5o}=4L!LݰB!|bߍ?oAs 4%92`&B!d"/mq%D[ b%5ߏcGaJ6!B@4?D,Ox19_b5ƼudO=ׄP0B!_h~Cqz<~>;׏c~9x%lB!0͗3!ByVi(%P0B!BH&aJ6!B!BL!B!P0B!B!̄B!|BL!BaFQG`&B!,˶PKm!BȃY\_˿m{ճ1M6K>Zc="B!|!,]~w}ܶg1OlB!b]}{c3!o#̄B!H$bT鹱.뾧sv{_BL!B+ oaw_!˂)لB!NлRxv{q6!_0B!KR/>61< ?X/}`&B!_8K?wmuX/k!1uׇ)لB!B3!B!BL!Bȝ0͙BL!B!P0B!B!̄B!B3!B!BL!B!P0B!B!̄B!B3!B!BL!B!P0B!B!̄B!B3!B!K'֎~7~"ۿy6 !B_p"!K_?ԄB!b|&# *4!B!0B!B!̄B!B3!B!BL!B!P0B!B!/̫d?N!B!v{WU,,}\g}o^ \Y(ZB`)I^:0-&@ %QĐ2P^ Ӕ2xReɖ0e.65,]jsΞ={3sG=/s~gs^GDT+ ͰWHjh4JcǶؼزekffVǺukczYqX|F jn1r7ɮ~P"a9"^{T FHS`@`\:/|$)EϟmcV/j5l YA|Eӱ{9-`v{[i>,7*a>'<+BΝۇW/#ϲ,< ˭u h`N i2Hoi=I@[Zm'i岴u=ͳ֩"mQ+;N_|<]9Q~-=}iK; 8Q;ugU\vvrCćp싼>aU,5[-zBk~jYLnW bۅ@`^a9yy#[Lr8v>NVG#[IsDpin`+Ov%W#<0^腞џ"({[{i轨GeֹQ~<0Xqu˗fa;vl: #s o`vlXe@`~#Oa2?s=+xe9t4=!=^K; /[0'ɤ;֟֫ ˃OyLѴeց,[@G=&=?l -q͕u#Ia2-d s=,jOn:'mN}ԗԗ>N` 瑻JvYᵟ#a,k;I> େw;h/fi|!@5VjHd Ze][:?΅K^/ZǼ5oyI U\4 ,GM|EӉ޽c\a37*zt wRzA T1?_;wsy UAvh5[dZñ{UЏ<#0G8a ~A֫!0԰@N۷eN+M#0 ?ED}'M<z~LT~Fe^zޱc@q ̮iŒ  $ `JPձq͹;bffu5 @%֭[u޽{g`Z>=^%KԊZ{{Ɲw~вC7l6""^! ls34WqP~ 3 0@M(ty=e־yvo@JX{җz'""C>KCfXj}RGO?X0CFFCK}#Ёf(}Oė7Vj~k_k_?777qYO?1m/m/V]V]CXa`C[SOgkNKܶj:mi7*.8|pG_X\|ǧNZI`޴cso.vջ}n鵿}Ѹo׽+9č}_ R m/nצzOfiшKc̉xs|\(o{F#/yKo2^xq+OQм~~~15״`}ߏ~mRT 0c橁} I~xpp{bk8P;PI?Ƕ#5/&v?;ݘhֈE۟zGlzxsߛc?Nǖ#sX5qϽ?罱?нIۗY/@`Na"quZO.e̤e|ڴ]>|ٷ'^w˛be;˞sYL\0]OczC}{)q.cR><㔈vǮ≣O_!>9>ϕӲƮǷvn-.}؁gO,N|ixSyjPk֮Gcׁ] 88ydO6ⱹǢ^dLMʩ;ydkk;}`@:+&'&cb|"&c2&&cqɸgƯ7G3Cuz8w00Z6i(Q]EȺ|K(0UWszPv߬mq_,U_kXs`Ocn\<GGhh#GPP_bb=qq4cC^ƲF|1ߘ?<cⴉO%>O|vkc1Yee1^ee,Ǝ?8^?X/F꽬m+d۾h"O=w i㕿U-GZ#}gqGzxZ#̖߮81}anGZϫ/c>x#+QWGh<ވe&ckKohē'cn~._X44"DyYѨ9eC-L`"0G$<\A@U/Ͼ0O#ˎDgGĹ,"0w(bl~/~;c+]Pјk܁9#5/?C}{S񉝟}{q8mv|ľ{clloWN=Wqs/O Jc1qx">i^<82g9Ko][C y)>WV]Fʰ9*sE/Vo}iy^0o-k.\S +_3woqʱ_&EcYk/clO='O7h=wU|/gƟ|8^{AX8lT%>Œ#8Ͽp}?l5O/~sxiyWP_l|2~ez}xą^xyϋw]θ ŕ98U~6uX*32 ̝]pXXΏ^dѯ0m6^g1p2#̐ѠG-of 0ffVǭ~"g̬ $XnBW okVr 3 0 3 0 SS+ _*0T/Ԋ16\SS+2@s34 6a7 IDATf@`f@`Fۄqgaõj3w㭊-aDmtj*0@7S_WxG j: 5 EшFꤶjk*0@?dj8>4UQ }Fj3,ӫNznǎmgzzUemeQf e_ i5tmxݗQZG{C[;~|zh"V{AZ|_ Cm{6#Iܗᰃ8|xAyd_qŚؾֵ}qc{G60;$J50ioiNڗYX}]IkuNL[h Ay ״.յ #8<>?ʙ.eaNSi}|An^ 0wG$Y6 C#"n5i4uߟ0q:ӂAqZZ4-o8|x mi'_miZ~j:Lg^n+C j͚ q/}ST`>vb͚ '5 %ЭFj3 Hmt~fh-dڪ颬 ]Bjjxk*0@)^*Fbjjڪ颪݆ .|Ȧ{XkKmt1tzzU|K?O`'j:a1` W aa3r3K>,;aCXv3²sea9 'fggU6;;=vfIENDB`MP3Diags-1.0.12.079/doc/292_config_vis_transf.png0000644000175000001440000014614611263126665020062 0ustar ciobiusersPNG  IHDRPbKGD pHYsȥtIME D IDATxyxynB@"@IpERv,ٖݑ؉ęeأ{qn'bgƑ378}'TF-K+-;ApA\{wZΩ<:;YB!B!D[\oQ[B!BH/"[())Aii1f(!B!p0G1225+*Q^>"B!BBM MSSKJJPRRD~!\vCCCåKvmW.#"PQB!s5\pv8fգzf())H_^>d%L##HwՊ_x31̚5 ]Kqi={ Xh $B!WXl ccc8R)ztk1k\̜YJ\z ׮ ~ EAUU54/e+e1._m[_kW9B!.^VK9re#')H(.. hrrF:fI#Ο;ӧNabbccH&QTCQQT z ׋1tX vwaH$'B!Eq{K潒cwtDK"̙3$n蕫q1 A,DQy9k*+õa={G*BQ2/sH$=ᮅѹn#\@YYS?±G=3gN~$ z !B!yi[=n@}F._l٨nkǰkia{i{P\teܸ{\ӊ<+d29%2b1b1KYY9:mOdxu˛XwϽx_~Ela!B!yg?11yŋ8h~70\Z\@u ppM]@rSGqX/膫Nj/vo W/GEE9ɄcJƵtb@EE96lX:>E=+U$ DQwFBZsO—1x׻s={TU%(J1B!@>ϾOwYWD!}ׁ&O< ,P<LJځ~u#kd6<}woذdk6-6Ov@ 0 OV {HƮ}w<'}P)//G"Q˗3MD"(tZA$bH$(.)8; $i!B!i笄>N}fY)WU@ _v и'60^kL&Q__3ol;Ve. allߵB"7L|cߵ~S?6dݮ>i1:6{Nݽ htv`abkl¥Kă"N< B:B!@l|SE X|ppΟxsNOgiFE 8|W^C:?r٫kA`n'&3 uuQYY6]kfkhl;xξP^ _qݸr[[o_~m݌H$+W0{N&.B! ` 44d\zI9E'?=/+GqqH&rHv`[ǧ3/nEgߞ~^QQֵ46L}}ǧX{*+og8::~[hrɍOS2CDpY/oǜ9к /ODQRiRŢ;o._1(Ji1B!b ؋63 ^|4?LSrW_ kq}5 h-#6;{@r!sEQU1%J9-Xr5VS0::h4x'1wnQT$oH_:V hB!Bn]~ު?ϧ>֣/ΝGwD29yZl:?% ċNnM7;5s (b([B!B-CNˌ u1ki+S[ZP\ u߿tP<qu5:;q$ `b4sm [Ng2/FT*dkt`׮~ohC2RkݗG&VdjhC%];B%޳Nef=yޜ0fϞD" 12|s{_TGQQdx***1 +WH&B!Bysn-FGǤ[#k' L:k{oمH$H$ĜW_}^yo!ƮZ--0~JqcW`|h ZTDE55Q$_#صkT188o4ٌ|Z}5xr i{Fyk]SdE}}6q#\qqfñ5ٰЇfEMM-*gVafef!x```7o a8udЭEEEO!BKPWW{sӖFY-v2 ϪGf|Y;Lt:={gOh43P\\"$FFFp o$ $"4?`LW- 1%V\^m_fy522Gzq4: wڋX,:eb1B!@`i' $EH$j$I$EPDːHdp9^i bhhеLR=}ftƍؼY PH ˬ^YG$egTJA$E$2}H$xFB!Bܥ W\CY aݸqg>h9 > B!B͌%Dê(CiiI0܏B!B/3f4 !B!on=pÜvT~Vφ}MkӣRɨ-53^W/O?;]n߭N;mx6-[)؇++T?q"DrEQ$ K&tLgV;O _Soa/a7; [Z7?S4 x OaՙqZ?oeĄ,RR {34?yu^T\|Y67D]^ˍWb\뵙^U"q_߆: |okwNs//%q=~ԧ)~}t? ]Ǐ,Lkay sZvͼ ZljjsDnﵞqQiVN ;ZP z}o~$~jNz6^Y/%q=~JV*cn yf0!鵒'wݵǎܱc܎c&~+˲8ʧB(D KifxzYQHN=ٴ&0//2ݾi^NA̞sRnn~NW/~14MyetoKr9OޖۛIcvM0ge8rdߴtd?^=ܰt]/=Vv]K1ywun7z:ӹ:xdʁSy+Z&e)= 7rWY>)^Nm2EY`gQ]9 0eE&⑶!ڶh=!Nkg9tXi3ƫ2cm?nVg7NV1/MßN/ z{ rE:Ҳ|5`$_6}$#{{:@+~)NLInEQzݍ]ѵ=RXI =={xJCDeLZy`Wa{DIY}VKVʚSeR4fr[fUN乗(},Δѿp`?wʸSю^F7k}v[mC٢ES(zgW;1fYkc7}BPk7 t+ 7/N^7ԼӮ>B7vFopiy'7L2a5mt2is2]߭mWdg6Jˇz(#t8݆zi,vc7k^+O;]L3 /7W''B7?nVZSEmμ\{v?xp}Vq[,ktϻqHF!OQ6ӱL~XuZ+6'ӕnGn;ȶ-fyW6JGvQF6;p k}nn/c<4/~ӾQnC2uo2UONn;~ݜ^}`%vg,<2e ٽ"SX.ā;,SYKK; ew:F'@{iqgeIV:|JYI򳎈WQLPveML~"5^-*_rVkM=rez5~r-SXnVZILڜH7VWkjʾ}ۧwkT\ێ M1=7Qy.ľ}'fq~#ԃxʁetQ4ەN"nk|8S>2Xi߭_6]^"'韬g{V<79^lufԶȌkj8팟lz ͉>*HՋ_ynN?W_}^yo!L_"شi|C >;^Gzݻ%,@yB5)6_C 3gdٽȋc8qL yY|3`A 'Oķc_8 b rٳ BBX젆ӫ4=!fVʕ}Nž'\Bafի}kV4ƴ!,`׮7/xDZ-`2oiB !,ׄolX7 -k'aٲvnGS /477M۷<лB!4xq+AHB?^|6<#B!Lq!!8ˢE-=bRB!BHBßB!BO!B!B!BO!B!B!BO!B!B!B B!B!'B!B B!B!p2fighxAae9l#>}?~B!ybr~G SǷp2=/9!Bj#B!BHH Q/ߴ~zVdI}Z~3M/笆oL|B~ɬeϾBĽ,yޫwhxZra]9u2kőMeu'^B!oBPoixѡaϙ}w[OAYI!$}v?Qc}?~B!{aeN_/SάFAK!$\/ 'rJi<|&JB}?~B!ToS˄MnBgO!y*&r3InXFGZirfrmz$+BaϾBD^}yǿd2/hjj~xӦC̙3IB!B!avFo|c~ɓ8{՟B!B!r'B!BhB!B!?!B!Bo߾Ǐ !nP?}4B!D+WCggEZ˄BG ?p3B+3?kG"tws3c Bugʕسgt]>{] ⋯G'}z&t?xB>^/ȼ) s K'J`DxB B!'}> zOSSN<{K>5~iuuЫAusL Ν;vx>}vx>}vߚۧ\};(wmZnߨGvSn]bOdzg>>? /1kd;y^fߍ!$uƬ,^3Z9(HQ }<>}<3 7j}?ztF .MGVʽQ9W_u}}<*aϲAßw! 8(Pk--Ij IDAT} ?HӬldz}a>}rP/'Obv}<dz/Lß/XhŴZ sy.ˢe5z:+V,SO=cYB>}|~۶m/ ßހӳP{zhEk=g.Y/DtW^3QX x>.gt G>y4ِAa }ҳ_%| Wlwuuy./ B,?N:M | 0]]]իWcӦO!8H#>=qE!}J=gyxFBK?ĺDzt°~w0<<,LKrߏ7y` {|]"ą>>L5{h>Fkj (mq9_8#, V吭G }sSv EQ BAT_i[[;׷k s5;labնq# "}9vB(Ù3gM AIЪDnjYEٰFe z9 J] S>9UOOlJ!a0e7.Ӳ]>QDTN+ϊ2zN]s*f-L[&TenZ/;3)M4ˡuN˗|'~Yah]ɿE=BH~#M.KF5qCB!B!n?D"?kѺ(Nx S/ ( "[4"+_ڐz`މ;eNs)mV!7'!xfB?[=2HfM+gj#vlZDսhVH!5foHW kݲD=1*NYall?B zH''guPbw'SZvԯSs݈ɺt /hJ^}E#BH?JK=O޳n#SzN=Qy.:t?~ZBH>A#{yPtR$҉zIJ';?OhJ;BIٽVabeƧ5(=z%cr1^:ϓ3ljegD䓁ᨓA~!s_aY@!0 쉢ATtfjml4Ia/Gtz%lzfj`w06 IQxz\~7֢i:ޯ c#h_SzwNj:'2ݩ6+,2;!Lfrh_82zw+R~m^h: ^/<{ʓzI12Һ.QDҪ_ %N1_D>Fj =B<p,6Bq_%՛g[?GZ#h: Nf3^Hyzl*SdʛL:rǟBFdPv'B%7Xn'm?].rJc'kdiu>haCF˧>>beGx;o}JGnv_8C}'z !NQwk;iʤ#q$2׋υL7B!4 gïzhFq aysz !HQ QНC'YV YtȦ #l>|6Ê(/{5BRNtdp# ں=uî[o dX-~# o5+Zv S6N39)ٸD3k;EVgO6)FBwkng [ѺV;:t:Nj/5u@!B!Dm<BH{e !ޠ>yzv5QMndµ|G+ܴ^3ӇQދc$]B!+O;D֧z?ׄ+^zv NVe 05_Ѽw+ܸOlَ-[CQ̿B!$؄Oßn>Ƴ}N,yLVVww#Dv'މ~75!L'Qo9]kC.7+kihV}V/,yNh[);uRAnݺӌzww}VD`ɕG/.8E3IYZяQ\"d$O!kJb)7YXN+*9;zͮɄIǟBHޒ p*`ؾ}oE1N!A~1k0j1~`glN=WOßBԠAIj@f v3?n8nc\JKX,t<:G!ոvP`OH{8iv83݅I7B!D5!Ҟ)''eV hV&׌l9'Bzȇ;sgSB5skԒ;\dȽ>k4NvugQE1\O ða5 u~btTl80ȎxS}'o(]QF2Y916KoO,}'p>vc,֬Y+W {B! pJ!QRd z !yyiy׵ֿim=7p3 H^"Seӻ,f:tZ6;z3a$Vy O~صkv35;!19{)?ǟF݉p6rdԓUTvӪHA/VPK7ʦ>5S}#q46BE<4 !⦋d{22D 1+Z1X)Aq=PM;U+pm{Ybz~gKا˲zjlC֝FyzF0cX)9yQqg]"~=ǟRFz:u،X}Ή0 93 cmgw~</W'Ga{K!$! M]םXW햁jU6u^N~Yd|~/. 9sVlv-6^&^ak;;l=YeE9.p2lCt*17Yϼs2ל)fipLyS3fsO^Q6k76|4 wJ>q}ͩX}V9'eS !D S|aJ}w?zt?K!a(_ӫ8eL,gջ̽vMOOzŧuLxvYd7Lun:eʆHSʴUru%zRQfp3s%hRƒRHAf%8377Z_F6YhZ鶒n]F6 k_D:EgZ)[~5 ј΋6ë|_b@oBHsr\X?nsN-#B67=nǮ r:^-y!8uY =B!$P)7?Nɫ!l%~z !ZI^oWq7fMx93lp^F[e#߻QF2!uh%~z !PI)1f}ֵHNBZM{! Y7v 2:|on3줓BHb!A^,˵lAaSlI>N?z#WɆK/ zGыN0heXH-Vu;o5 7 YB1 Dw`MTN?Qc,2}}{9!2B!=F}wUjys6޹kfi}ϕ[VfkNUOf鰒2nL{Bz !ymkQ5 ̮+cMs">Z]n4VW$n+e*0=/T&aa'کYg w~"v2 !B =hxȋ>ލX7ڍ hMW*B 2\/1:(%h3֊;NxuFn>_$/}>aG?B!=.1<<'nԩqc4ـ]䅀gEA+YҗLY G]Zk]m;׋>e['jSG +HA-@*wniKʕո2TW'Hp!~>c5wv}"a_4V4P3z2@n"5WT6pPG̹e֭.Fn8&=YS$(o4Ϋ6o8mw<9orRիcBW~hkĚ55ho ld :90vޗmE;M鵪Cשu n!r xB񎮮.իii"X_qWq^}nX1>| sV`ƌ"b @!3f}2;RϸVF[f-k: q?V9"Dꗞh})Zk$m'd{zwK/uj]oͽ5vВS&ge]o@X ),rBGQ]]N y)׏78[OcΜrX1 7ճ`A !i~׭xXK ǎ1,z~鵻^؍tx714v_ B}|xV.a֬2U-mlvǎ]ŏ~cX saC#-kR VmPky}z(=įgD/.EKSiѯhf/HfQP%nMe4La](?݉fv&KyB!.^C h3f$Z* p5tw_֭u_SaC#6lhĢE5.AQQ`hM-3ꭆѴvfr]3{a,E[Mh2"Vten+niF3 KZJ=#(>;__ B!.\`K^ع6o>.◿<-[Nkd6\r6ϯDyyXa-=gdzdhܢ2I4 CV>Y9Dt u)Z„߻4-Yd=שtq݁_{G0tZ[B†+C+BdШX;RDz p'S֬x ogp5lt/p`ݺXuhh(CII7tsjwo;2-)pS^sR2;#]q\Sk`6\Z`%6h~] _Ɵq|cpdt JğA…w]x~8#cY&ϗ/:yAb;Qi=畍E] =oou7Fwswǿa,_ހfToNa"2unv˂]]:C"d63XEes{@4v=w?>1TUu4R锯|{yl8-x}שяL>ؑN.tq'TϪ<1axliRRS+IpeM15D뭯6zNoLZ/,MQC~)]Je]&F!m0l&3*'ӈF#(/Obɒ$.7رص+!޽طӇ1 3sR]B1h /gX~w4bhlH H h:e#OP?rd+!!i^"f%m}5x IDATKjЇKQQ )ex2v8͛OVƍ蘅ƊY @!EQW/>kPQUA)cib H "^2 4 C8rֆABd`'uϪw>yC? %%E?U{Gn/ص,x>,\Xkmok"ԇ"dx m(c#?7 !;[-j-SQSo7kOa`˖ؽ<9sx,[V{kbª[KbT$!<_בF~1dž3H'n*@ @P Rps?Bg/0eukzye*F{n>kZ p%lv۶ÙI45Ubڹظ+V¼y(+Kp)!6X-|܉_=uǏC4hYQPJSH3@r>}}{9N $ 5Z ᭵9LfDpRzJ暗cw͖(Xx>2m)ܹذg Z p;vʼn;Œ%윋ιXfq)!64_?~׿sH]xtȆ'(9D}A׷wFie73n4\߬?~)ʄe妑N9'EQ^D[[ZZ-xSط;wŎgQ[[+faF[7--ը*v})@zO: QA?f$O%[|O Fp3z3|܏>!B'PW7Xb:Y cY>|Rhnճqb,46V,hEĝSDu W^-Y6F2[O'Z:WZ/4j,?kEHr5zP4Ƹg !k}N^xǟxRKΝ޽曷Ox5ظq>֭:44@q3K"LmwDƙ{ͩ8sM+筦)]k='*ZfKtmGzϬ3tk3 v׻Wo}DEY/.k{K_<"(n1[  1qC!A'h3zjVb(**}*װsYl|։k9 ظq>:;碵3g[ eiMG1: ߉8>>o7NE}`E_ZV$NzھNfa8VэV@ ǩpEšfk_@ $ @$$ !C?ܥ˖XÇ/a3ز4z{Gk'<s̛W3Y Y7zk=+b(:#yDg5 ]ʦuwva=;ɛuF:R=ГKT~f0zVVV?{~(&oMEp!.z0e6R7"qJT ƱMM31o^6lhę3س6oΞ p_O~-dž Q%Z~pv"N0תNnVt($]D>_uZHhݔ9噽N5Z$Il/_|3JH?Bۈ|kIŢ,Fee1Z[kw߅#G`3/N~xTV^ )d.Dǫӝ8?rf!D}15}\fΆӻHX^1ETNeYcvԭQ?#Q8~JitQUUR̜Yh4I*)jO4ޏO/$3bh$fEkf񈄣gdc%>edFz3J[ 2't[ɟBz T*I\x'O^áC{y>|N]b(fNB aBNyo\qR i _? 000G,-DJ1>͛pz{wtw_#Wp0'P\eظ˖5`z,ZTvBd $ !ʼn`Ne:qA^cXNVXzƵ_zY9 &&ܸ¥K8qb'NԩQ;7EAYY \YR45(/D NۉQ,B MXa3:ګ| Kg|CHLN1<<8~z"/С8{vǣ.ʕX+W¢E5=3g# WB?yg O ?v ; ª0a9~OB?߄x9A'G)YQ088wݙ)ǎ]ťK71>BII)G{{-k@{{Z[k03f$Eogw7۝^;[ S9/w*.ǟVVSVɎwNp0Uo`YTNHEVx{Mܯ{Y7@a{Y*$^ʼnװ?×p \A$TU3ʕdI-fqb~4mWjr?!$t~7n92/շޮN߮ά=!i6(Ncb"7q ;v\q%;7 $1̚U,[ր`2TV(1aڪ 9fqgoFQs酭7,xe&yh|zi|Cͩ)nDBH8^>kx_}cc~} gg{޽8q\A*Fiiϯр*֖?^}Qγfi=ehkM1 K4>u=V4\4h]3'w-Yeѭ/BO(]?ºf\A!m(O# nZѫٷ}kHrZߢGP=6T*18qlq(u.wM,ZTJ̝[Tjlj |tqv@>YDFi~v-ϸHFi t晬|aD0jkYFҺOFCYSY+^8N$GwFz _c?O78J#+$XYof CCcD{/`~ ҥaLBuu ֭ob֬2Ԕ!%b%qJ"Ϻ1 kb"uW北 G%hz/(eu.Uv _œ$>؟ 'Bl62%'ch#׋D@9o?h7v7ϊ+X6|w:k:0@:ƣ(.O^G4xٓ:!4 TvgQUxcط~(Ѐx<ιhʕdI-)w0&Dw .[賲0{Q!"Fm'\"SR6ag c4?l>9յ~RRD,{^tM䨍B%G!^ /ę3Ʒҗ^ĥK7,ƬY57bY:47WadzO2{ o=Z/Dr]D6+r:!ݰUdhfE+_,-C6 /dt+MNkeGT,Dh"U?}<BPĸDUfil~݉8ƍq\:SX58p^Fu Nb/'XWb޼ZLNZ٨sGuy}J^>g5̰{z#d$n" !|\~[okFq Q^.uj1?G2G]])߃KZٳ uuR qXwWg=gUNQYkdF/Japb-?CT"V{^ |O໿7uB! =h.z_*]ř3яcǮ}HTT$1{vr,ף7P_?%%EdzMJHvtYKd NqV{ΩD'e ]4:?Hz:bbJ 1MGS2wDO_~oO|\OH#{4kFGت7Ŷz#=R֩ckEvrQ:!]qU7q/{4kfj\p=R։8d{ q7%ȅIQLL144@wߏDE+źus1 ˗7`Ѣg6+*KN!ā`fz-?"6Md^%y5| )Pܚڲ3Y~5nl_~OO FG'qN%;vP"%Kjti=Vŋk4(){1!_J1dfNL*PR Db13/qel7_f !'R.B%('x)X?տqc/Wqes]BM (RlЈzX1 mm)I ~ qW;滝?pMOWE9CvC4h(4AiDGh[~7jB gL-rVrB6ᔎ}<=.N+OMw%8pfW`|<30{v9Xb-GssJoMwB?QG_=h< JD2 LȎ@48Z, :quzD!{_?9͛|y'N\áCgF3ӌnW}Fm+P:=zi]/Zʤ D"z6KOF/[v# ^IF2x;q[QHF嵏3k>#9&Vo~kn˲GjE.;LJD@[nNOx|<7qz{wo?Ǒ#WpMNgaѢZ5Kc5 Inge NzE3Xҡq.#9e+n}@%%[v7H;h"wQ bf%E}D,(g\*rM$|GʦGw2^EFV76bG|) [[o]ƾ}ckC:":}wݔwi&jj2^}ngA(e$/bx7{"*}ݯgEYNφef9?ŷ ~Kd,R)?- t#B򩏧_4'100'o`γ/y8{v##"-Ž Xmm; $1z RDtSs{CG+G !?ueQoWv)L6gCV:hr*پa[ w=a{^C9_hO6np  I:2C"kjlrn̾m_|D>}aetIleĘ)erH16-pRk2\R[ 3u~k9U.vճUl;% W\S_ojj{t!S6LF;ʬɼIoCl} c@Ĺɳe:SݫfYu*]hګ?F?@XIo5 Eh:fR{>׊){VWdgk4]2L-a]66,>Ȫ[cm2Og?AOXoL]a2=Re0 (L4:*?Ƥ.q>& eQ:uxcm򠏯s*}ʾW>_Dd IDAT_0LlEWguʠH>2,.tkMY>Qe98o:?Џkw6֓ZJ&1vu/ bUzpՍL*6l&/⪒GeDn~j\{dbh2xB#6|*bN\O1C:cocN:O<r;M :-$=yaoyt7Vb] pMҡ{8eUOɵ*t"dUsmf vʶ4NWoz0UؖcޑUVج+hV7U⯒-/YMƗb[:SH4?8Ju >uۤ-\xVKضmUߏ=Ȉ2RCYטoobI>=Hk(?Pm ;P$LzJlcnU[a5 K "7(~Gu٪ktS$wB;ۢӓbGmM:ns?*@c{;_gm5 'V +5}r6ި/RoNvVRv7)g]µ/Խ+'l <7u^;S>8c0Yh'c8>]KϚ>v쎞t92U|կq ?fK=``0lŽϱZ?صynսea(<3Ixgſrq:ㄘӕJ;7Ha]uYDAYUxGYn8M +ʛ|tVps,H7ZS%MSl"uҫJn+|qVwEaTW׼PL6SUgʻtH:K8uj_]+Tun=:ϑ X gDƌQMATcgQ;ﲃ2cʷ޴o5m4|MӦ꬏vAU꘯8xwk %l_i:9#Nuؤ)ĪxpO}6a1wuaSŢìӸ @+iG@>s*o h,cXB)mێl]o䉽Kmşsokh)-puW?Po1Y6-uxs:W9(󹐃ߺW!B쨰 䙲{¨ÏCKهNKyWO {SuW霹6Zw0j4;]tIY-]iM򩪮\-k>_N]uVϺB@>nFl`|~}>XiџBbſ1ߊw1^W+]Ҡ+kީUT~H'Tuڥ\tU隍ӟ?5Mndʦ[ @WV {-ȕ$ .yatߝ,6[ݧziV=4)o[Xs,Mo ybDTuzN J.ۼ5lm/qM~;mW ڌeBuÊ?oM?&uxr ?>SeKg x҄?q8%L}>3Hm_/k=mych?ygiu":t#d&ϩ M!%l#jf`ܛx{8g=z7W]Uai6ivM3qr~g+C>a}>n8V`g?hzLcSafٲߪd(z'oFvyMOUFjpm{;zȣ @:@slE`~ #{\eV]+Q'-Uэ4\ݼ?CWWMw bl|Yv CIN" 391Bzp_#G/ж>e\Āi|. !Ilo333i9pNF>SO}Ifg|LM V4j'lޏ#[W>8i+dv|b?X&zu,,8l5}?&e+T+Zo;~Fd?h5EgmVNL<˫H_;:/mE\`ugY!9NZ'LEv۴4 V}2-7iDX@M 篩v <3ql3vȿ¶LN$+k>ݺyTO851 _EeQV8u~?:ȞǣQ/Ïl*?iɎaϚuh<.  ~ _~Cgո&ܪglҹ䓋 3OyaNN4 *8]&U[_tLje-[Yo?5S|`a t @{[WwC@G d;:nfG(UF?G@*tzq䓩m͓RRvv@{\8?f3[uo =>ޗZnm:+8z~N8YWѧ+pV|%t)^r^[y O7]gUu1^MZY~TCU>V'ӼX Kqʪt-)e>~U_}%JgmJ#%lr?k&PƼlF&e[YY0d 9ӴԕIJf< Y.kYjVZF})΁ OQ\sѽUkpfJ}V&U\e磊 4*׮IXu5-]?@guuU3~:tXLR6MldvulاKkjv*+oȝw>pc^ Z#W]_QBٴ|m"E]2-&]mv?`[Ȏ=x$@u|#f(:iinB6OKΠ+-#yZh2MP( 98_ɇ†6B[zgUgc]%[Pjtk_i.Y_3uQu:w/ 8;n8&PA[fRɬz6|6ꟶ.mAWզVXLeH<$cC+Ah𷼜&,'h."@$_ +6{}xުpLU_&IeFn>kW^G %| t]]}͠;W^_d a^E+h6yfsMǐpP.K|VP׸ e]DuƹN =]-ou ]EWE8iP%:^ >\23En2BD>LsL R ])Obw%HbǎDDd}rs^ |㺛@7MgFm*TFm'+.嫎u5՟Ӯ߿贉{ J]wMɡCZa6Tl-éIn3v G7eOl7t~]MEgffi9pY.Oy݅3v֧ cyzIʫKx/DgK6L' dWbh3*.v?}<@z:[mtLM>*RgΜ缆v$]cճL@"ÿO {g{@an7<4hfG(UF?G]\?}{ srr  %vv ٷqٳB8ڊNyɧN$?K{ K*(tW3ye]9 gN$?F?G9,{7 ]tNϮ> 'W_}hI'NVi;H1Bq~WSո-8 dCBMR'e 3EDs ]+JqʔLmLFݴ_z UN*:eu$}z]տ~C:H_.|7}>%c"e'.2qsAu<Ӑs hzƇB?iipI'LUkQek|֓ 1IXu -]2+^?&ȶ1Τ* mK賎>՘o#Iozw+YMȮRR 0]ϹtDUq;zRC] QUt Vc)H$= CwgO1HNs:eM]Rg1Cю>ݼC?˱c/XU55:;MjEke.wSUQWMθS4PqEw+@VIZ|-eQ)RJܵ:>R-F > G^;7 .}tMCATK6&&*+ieUmNh mwb۶6E(]qm\:ݱ)I#WI!lg0Tg*?[_.Pw9U=߆I"eRJ[->e t>S'g #o8bk38T,fZ]$%zBG./CW۩V3,Ri[U+p!^mkI9Kq3u$Vwxz_5h,>pd1Y([qIJ4e*! ߶LdYORK6z*cSWuu+uO>*:S:wX4ʿjQVtCRSLG! Xo]wM]b+uU;GL=[I'|ׄiQX6K>XgY 'e];uM;a1= ^z@c ǘ׫"uW}7=tN\lU^*u|bSM&adUЃ3$l!I_Hm4n8=3^~@p?]92Na3h?s\85̵k')M @' O {g(UKp:ifG(UF?G@' كwc,c0Ⱦ}˞=*gÒuXW4Q*w8ʃQ.7HtOG_SՌ4U ω'K*@PqP˺:W'|R]I/ڬKMxfڊP5֫oiUɣsU*M/Vcd00tQ1QƠ4UI7m\3ײj(T mYLG}C%Ot5VX񏻿E+ģK)e:ZczimS6>琚+dO]՘6gT!e%5םTթ-46\W082mBi¥ѝvIccJO?t5}XG7tHVR:fs<&k!-1[nd4bVq}c`\U!VShcХT;Lttu߄;|c^pSU`ԯKegCLJW%tҧ{J2wkUq &UCƪc0nﯼo-Ӧ4UaYx3pl,lܥ>O(# IDAT=]|u:FtmAWWMуW}߶m=zP{ngεRкtOwLKqR/T+o1#c1~UlDl|\ڄSque]ߵɆ,e]axat5VX*XɆV8v3f WS/4033ceW;Vmy;+;gȑ@j^R&?7d'bdVVXጿ~Cc+s,UFWWM~>9zfCJ>zZ2R=9l!a$+E2Rqc$СYٱk~0iGk6g;O?GehoʡC$g vEke]+ jZ'"Y7*LU7NY>eQ~p?Wmh~+;Vv-NQX4gR2j>8>,pʮ"wUUU&+ǔ]YjUZѽF$&`RAe"Kٽ]>1}X ^+\:?_;w3r2!mrV|!`:&]|ޔ#I7+` m\5%@8Ovt۪|5-3H9$^qtV6|?7aw,8l|,0}(kg"SffLGjg\aUCSpR}szfuU8eT]\U8e9]r _Š?8N{˴᷑.+` f` ` @ 4iJ3m'>vjj<޿%wfffi9pY23C{#*]p#@b7減L| Jfg޽y`0}={(T3PX t0]` 2}aNvŠ?@c^׏i\=FStt ]3)!eZukEײc~*Ea*;@(;ou/Q-@*FvYٵ{mU;4U*ppUvNǏ[+Ǐ׫d"E^7y©jtLGen:B-9xMLk=CW,7*t]0E~ȶ  7,3DL.4 5+o9?6]2 ˧a"@7~ }jBgUF C$w;W^eFϴQȟUm `K+6B^ъ)C*F;Ԍ41k %Ӻ <@jb7|GIHԊw> G4T>4mPʖ&6@c%ݺ <]]=O/2ʜ^a/rgI !U2A!Hnſ@Ju3+Ot)`-yH/o+N_bnLWai*Y߾A9|9/E[Q]g$m omg\mf4Cu$,_]-_Hj3}߫:Ȳ 묬̥KBs:.: uGWVOFWWi"gbdV_z>$EWO>-ss^Ü\Ce(IDMu~)033cmOOOˁ&ީO {gT@?@ ݻ!<acHVgg޽y`0}={SiصgΜ缆v$u+^O0O|4}-u$NEyn{Yu =S?5Sx`asf ;][oX(Ar2:l*n|3,1%w=sW_} LUdS{8@ÿ@W`ſ-[ǿ{D@7c-meze[Xw*CG'C-KzBy>u*{umo = +cUgetH?Lܚy޲AxjLeaz{Seq@lgHӸ2\Yg>(ٔ:-Kzf̌?\oS[꿫~S`2ͤEъZȉTnB+6m% = fHu~kgŠ5ǎ [o6GU]nʐ qomk[7x|:7oHML=CϺL? LFpd3ɇS۴.gYSzjm)G;|LѶ46KFi>7 K.[3 ?AA]:gn&鮊#goXo!$xC#6mUHyb%$]]=C0[:(q|e%WynFpMڧK.eg_o|m/5 n_.ϺvV兪MQ=+؂.gг'o&Ν_S>0|NW?zj^~r]Sƪ+*;]= 6\LSuzVx]]3L{CCp08g_t=C|O no~~ 7܍s% =k!+={N;a|ʨᯀ]\?s\85̵k'L]0Rk+SS;' P<.3az?w?B&x0%w= (][=({>Ų1þ}˞=)|r+T}?]\JD'NU6Q͖gr*zgM_Y}5k閹:| ]vßi.UuR4>6IFptt(e!K~ԕ1 >7gDʾN]pף:2e6!6[os+qs^o%-VBM5%SNopʮQn a"muSՎO@7"<娊.,o(:m6eP&oȷ5 xtguzZVv`}Jqz.6%Vo,N^OfAS4&|j;R)0UTы) SoRo"KeS.KgM3߳kEGJʞӕGynP4ier+"d:b+X]_0|}o@{3/gysy6%sKLQ&g% =kNJUMJ7͘Vm!B!VM8I۫\t} 6 Љg{*eJX:O9i"tMb;[[Ϻ_rm'ߋ,k&r<_uozg|GTN'K¶,tDxB6q҅"~h7u룏77>&.|+6tb_a货2sR}g+3VKL2\+jPW_Ogel2+r-uO7nlZ'>:Y>po|lz?$` {no[o8#K2X^ҢK_YXʬ? 2mSwɥ3ǃW>"T+ ;W[/uۄXbʯX?zl۶;@տ,Eޢ,"2'Udd;7˪n[nыW F&&ß%_?S;Lȿ1I7aYιԽ.W#GY b&W^Od(_zߕy+x ErlOV亳de;iY{範~㒼I~Qv}S Pa`I+K/]'_AoY., [n=Lg?([JNm*Y$_<2:1eze٫2+M-{W3+:ú雉l&m3E2}!_U|Um\UٙNUiYVlw2]o7aǎJHe(2*`eI.}HzW"5'x_)Kd"QY(?Xj]4OP oRѱ=br AO3@Ο[ddjn"v*(7}I2r/oqsgeen[Źs21!>]ߗ/5tlCwٲnf63T;l"6lTgK|)7o:.K/MnKSy@Kr{~/zjDd ѿSK8datE/_j\d Xک :Lu߶!k~̣!DZ|&prv+&:/Y)t 9{=_iy#ɺ?#~[~YΝ"KZs wDFFD rbAНw>pc^0}~Pbf7hZ*&OՆUlg~UѾӮ1lt]B ^ķ̛G'2";|V&'&enGK-Mkz"2 sW]4"n2G]m)Gf" M\e[U^u@x]Q}y]ԍ˦0U>k./u^3)S_;zSLg"83dHq`.T|_D^ڥeM/wO duO_nqM_:;e|5u_U#dw,Y'k@muߠc>.Ku.XšR\qEDdߑn?d03g~Ey3""ҟ{C.oe;3&[︃,ǰ}nO@uoI]ϭ ?*r%rgYVV6`З7@.}di-/>#Џ<۶mgR"@W@Vgtl qFƮK4E-+wR^/s2܂UdbS~{/ #ղjl ΟAL ˣIy??r#GDo`:V{rߏ\wom+ r{׋_dN?'cӑ#SYh3mdG&g#_>-k.zs"\dtE]Ux /Nʼ*|)H! rߗɭI^yqoF/""+2w\djK"E_I91* p[]y{mm6NFVO>-ss^Ü\Ci@TԱC_wlɆ;k s?!"/,M^''V;!77x>U~CIPq7.8.9sNyɧ3*%w8e-'suòEY VD"@ddB_trY%v]?2 c%ɉ9۽]pף:WED.]%\| ғM""gg.z26FF\vl;A6n + ]WW`g_˛l6gѵm­zfpgHWrpIMZ\ʻ^]Y|6gg޽y?1 d߾e ~ph$#[~R.~?9;+Ư97EnqmzdH"2oM=So iPv T6Mky­ 5N8Y9ĠĬ]~Ujd|uGgW7|c"C_Uһe-?&""+2׉FYqr^v3DfvuDJcyweJ2;:?% SwקD VW aTd:}Hl}R:?jk2+þ5٭} /_){Ȃ6 o,tl[qRh8(},CXPNrY7R֕Ui-s&䣎ٔ.Vͪt+5B3;lȐtLV4yf4ɵP IDAT⟟qYGe{5u1WuJAΠWil&VӼ,KgaSF Uiթ>D't]t-2Xɶ -ݾTosk&2S&lnZ\['__]+:Ϋt}6f+kBB_F鬞N"_>@1~GE[[_ ?Vd|=#!3۷8~s >U|𕷦2$01MAE iȯܹ̘H|]|t2w}g;M]?rID|\|,,㇤wDFWywb7iC㠠lսIyꑤ{N/NԗZ6.^,޿ A_'*oH&?Y&_#"w%o__Mlem7:0%̺&B[w>jEnLu::U]f#.?rANCV[|`lvL[dlM/" _X|sA^5o{{#l\ 0 q1ʐ7}jı l.iPAIIٽT0K3ʾwީBE2*33{‹rZF9(%7`夬J{R=&7/?d3RP-Ґsh{٬aoהּC`DKUD՛Lܠ*CtV偉s|JAt߱c$SOBE|2%` {no[o8#K2X^ҢK_YXʬ? 2mSwɥ3ǭۋXqx/`yQ(7I%@d;2)YY:FebͲe[dddML,ʇ?K*8o3vB{D+_Yo]Y "N`Qdq~ gdeyA;{Nּ~XF3!oAJ7.{oeק9 m(tq@:V%,]6GD[tQΟ|Ye$6omoUrk2;+lY+Y:]{ dJx$u z2},ʻ{2XYoy_>{|~M>uߺ7^|J#"c=}EDdTC6w_?F$Jcpmuſ/en$}Y,)eYۓ%{Q^{>%{ȹyWҹwR^P-]yI'W]ˆK"y 1Y%_{6[F6dTnxF;:26Ivwϟx*O7_?Wh?\L5aɟz?O3:t8q >l`[+` -܉c2n_NFNj EFGO_=鿸ZFk<-m"u"ǖdqLLnh `W6m. @↿'[u&Ae+2UƽMcڢYwم>?6Y.ML_YZ\ഌDG21.z| D֌M^6nˆY8/#?|ߪq ?6LCʤ277U;U.uS: տ7"<ۅ.@ڛw\m^]W6 .{GddD?//.20%G@ "߶m=zPm۩ H4GV2,7 u+&Uzʌڲ>ҡ\5l1!ʱ|.!ux?w[rCrͣr7_wNڱE_s'rվҙCiMOD|asFdbM4|CB?E=zH/n{qyl ٪-M1RS[K>jZWe /"~WeY3ڗ{&]"k"K_G_U#dwmVD֬5fO}ɀtbpdl6$trN?Ā۳tcȼ6%Wsl^/eyY;rȟ>E{x7d+Vñ3c;h:`h- G{s$e@x_uݽ-2M5lQ\Ly:a+b+!+:.wV/ty}LN Le? L\:-cˋa_FefjpPhSޘ9RG^G2p-kɷߒ#$7n5jl ΟAL ˣIy?Sk$4w=\q]>ڥx^Hm!7[?dAg{>'ܳqD5-_%y[Fz2(p['VѱU4l]2ccV@V9rS]ُu8ZR935Ue:oUi\RNJ]Oμe9li_Z[a8)r<_4Jӧennkݘ\C 1qscC&ME3![tq5ole3rhIuʨcE?";~ߕ7dեw0:)G^>Qz#vʓO> )?Cc t {DСk:4u0VED"w>yY5wN}ri:9 YQݏP<a$HqWj[wm>!y>,c}s^52f_!wڛ;;{P}̻` =.{P0 )b21!uI?S&6ɨ DVVddlr츯?(wl)7C8* )b%|uzn:rMmleQN&W;.V~arPFt+-m\&raä,uL,\ @t)LݨOU{fengUi]mjol'dɎڏjn's&333VFpS!^CHWa6Ts_wI1cJv\vfJ΀'|J9[ΝVDzzkuvTuVJ!+}m,y.]ocǪcݜtdz52MNT]_Ϧ3vC+qWuI񆐱*La֞'oZ|S7 zo'sh]oLshvEWWeN\e3 ~սUTmW~R5쨕*UM/Cjƻ|lgS%[luäW6|IuSM9R0k\u:qIWV@zoz1k>&U2gᙯ<3 gmZb2BR%ۼ/+PQWm &7N`c.WhA{?@p^{YG[J3i,Š? }MtIsv0V-::PZC0tQfísv@YD7]&yl@ T @ 4j@ T9-kStL)Uo'_N>jG>Zn>}Z潆996gD"Cqm1P11kcjj<޿J;@[&c3ݦV 2?4w?Bx0%w=?{Aջvei+EΪ3o:ip+pT-c {~Wjog q?(XeV1K&BY#C:ymr*;©Scڶ'NUJCV©=Dԑ߱i[}O}iJVUi[Wh+qKmj[u_/U#/\({VKzXٵsFu+a_u>˔_~1/YN Tywim&b/*}ʻ4.#A`@Ƹ] !sI_4QO\Ȳy}0#h|fdmG- ,LUEQ=tt㴉"qStuIizuԴtM72]6U6NiSLFV0i/،t:}ν6c!g>끍l!B'=]Y NCN(t3mNWT:kqitd5C9E1uNR'M:Xꛭ7NrLͦޙN=P_U[RG;)^ ձqNmFfslklūE4}lh{6u 4^Hm*L:a:רKnR64Ʀz*{Ju8pQut&b("8)`;Q>U%M]^?-# ё cNlϟ([l›t۰}QG[.iMs>˿LBq-dvd ݖ(wO@1o;cR:puau+>!noM+2h Y ݠbI ( WWYhI_rwuş(tȺLB֟uz?Ytf\_L[Q|>TO&BtgOCI皮_3:mBR725-ݴW>t(,ӶGYVgڠ]V x@?@IdjL @ zCL*o]](X@,oq.۰16w@tu?7`7\Wl[yw{]ⴕ4^_i)gW]&y@U2?dw k0Uĩ+NV%[L)6.y#*u,Fi?[)]qa> #?!MHmI1쫲MeP]G^#\}0eXmLSK\~fs&+M?m!̿yɷ脣r S,*G4ѐK:,֡MU2Aq W6LʪͿ w :#TQiYn 8McW*{B8;be8Lq#w}K6a!cAHiwl,Y.ՁP1?!-Z1MBHWwLGtuşU~|Š?y!ks9Ê?؀g{ +`dtB')\<.xonImU__H@ 4;~"k:bt$¨Uw*'8l\U6c\I.?th;+/Ǐľ?==- aU[=~$ tp]Wϯzȥl5]_&`kgAqe[_c@(>.=ʥIbFcfڼ̈iN|iZ_0ku'U11E[l||I=6(cK*}@Ic7t8zr;_l%mUƳ/GP&lǏJBR3>uS }vʓO>m,׿Q#t&kI}÷쳳y6|mw,eʷƕ2lF ;jߴ/|d@ Gm|1}<+с_x^)P՛QLm5E+6rˮrȿ5*~EgȬzWy߾>A`_e|orXBetʭ#_Qhv#@\:S[ʭ̓͛,?֚R[SvW6.s 1C_WVҗ_?Rx׏\geOEȀ-fNrMoU?НAʕk|յ^{ Q՘;{MeLVSz^HnyAxV@3^4leϔy%:u#ӥSV.7۲+_s""r\1 ͱm8M޴U~|Ug_R9^:g1u8(DZu GtVz\d1Mi~ŗ}ǎ~p~M8.cdM/YM2_u 鶕bHQ7-LIG䶳:(VQ|0]H>U4rn M0 gvE[v`"*~Qe>U4b;qd %Aо;%3625 ]uG,?@?ho۶w ȑLs:]lGUyk#]ޫJmمbjj| _4~'4ӧOܼa(W15C^qc+oC>_|+(նЕNt0kCrAi5 {gh<.hu9t<7P;3"" x~G8,n!z]sףg֭[d-ϟ={VX=[HAL$_[g_77l/+ nrG}DDDfg4zJ*h0s 3B`?`?`??1n"_W䮻9tlݺ9?pEۻ*>A%BtfiR?@[+CT;/Qi[ lP蟴(ڡ;61Go ?bZK]Iy\(((?Z@>^턓 RZKakkSgQhVeוּ̻"Qf(eéBߗ孹ڏdzJʩ3U*-rݸu L`&,/u[lXcM?@%+Yn*Xk&'xf\q_E(ס߼Mx~";8haOG;(ՍJYQwM=':ϧmg=/23U.X,ZWW7۷Nmeedޛڝp|WZ4hVIϏF3sJg4WD@ɥo̿ȴLX׿?jԦխ^r2U,e#Ӻd(F0C SR3i 2U,e#Ӻd̨Z ϟowF/ ֒L+̴pjkksRH/dZ~v7lo+-[dZqOrM<Ќm(nwhjO -?4\ .QWA=ҟtB|p8,p8 'yƙӟ B˗ ߿BJ"Рꗁ~IENDB`MP3Diags-1.0.12.079/doc/310_advanced.html0000644000175000001440000001403412040502152016240 0ustar ciobiusers MP3 Diags - Advanced features
MP3 Diags
In the Config - Others tab you can see in the middle of the window a "Misc" group. Inside it there are 3 checkboxes that allow you to add to the main window's toolbar three buttons that are invisible by default: "Export", "Debug", and "Sessions".
The "Export" button allows you to save the data in 3 formats: XML, text, and M3U. The XML format is probably best suited for further processing, by importing the data into a database or a spreadsheet. The "text" format is intended more for human consumption. You can use it, for example, to compare files before and after applying some transformation. Exporting as M3U can be useful to listen in an external player to files that are filtered by some criteria, e.g. those found as "low quality", those having 2 images (so which will the player pick?), or whatever criteria you select.
The "Debug" button opens up a new window where you can see trace messages from the last file scan (as long as you didn't close the application, because these are not stored on the disk, and provided that logging is enabled.)

Another option that you can configure here is logging all the changes to a file. The log file is located in the same directory as the ".ini" session file
The "Sessions" button allows you to keep several separate sets of folders containing MP3s, each set with its own settings. Everything that you see in the configuration dialog is stored "per session". Once the button is visible, you can click on it to see the "Sessions dialog", where you can add / remove / change sessions. Note that if you spent some time getting the settings right, you may want to use the "Save as ..." button, which will copy your settings to a new session.
MP3Diags-1.0.12.079/doc/arrow_left_small.png0000644000175000001440000000162311201736753017302 0ustar ciobiusersPNG  IHDRw=bKGD pHYs B(xtIME 77u( IDATHŖ_hW?Kb MZ E|(fZҀPBaRDaK2`-u[02ZlP[-h_ul6%_x}=\fڀ: u $@/zVM3Ng550?,h,|x| +~RJg2>8QNEEIF8(lRmhTML,t  \iW::B!_Bn߆+CC)y_j6ut R՛QUM7׀Eleρw1*sP Bbۂ৏Ƌ\uj]U^o @+`1mfVkVpeѯ}WpX4PtVeUɗtǜ𔺜*:`)MsO@2)YL0*tM|;71ixE>_ZPi%'v<5ufLٴAsMֺkJ3# 2%ov>0UX"rf=fu0IX*gfvs6uٴ},Dp9Fj۷u,WzzqXL%XB3͚VTWoON})YpPjk+ Da:;2'K&ZXJM7L,h9t|ḾKϖ׎n$IENDB`MP3Diags-1.0.12.079/doc/040_limitations.html0000644000175000001440000002145712040502152017036 0ustar ciobiusers MP3 Diags - Limitations
MP3 Diags
Only the "album cover" image in a file can be set (all are displayed, though.)
Currently, if asked to save an image that is identical to an existing one except for the picture type, the new image is not saved. This approach looks the least likely to confuse players. If this is not OK, there is a transformation called "Make the largest image Front Cover and remove the rest" that might help in some cases. (Note that this is hidden by default.)
Links are not supported for images. This is bad if you REALLY need to scan your vinyl collection at 4800dpi and save the result as an uncompressed TIFF. Instead, images are stored inside the MP3s themselves and if they are big they get resized so they take less than 100KB. This maximum size is configurable.
Processing ID3V2 only keeps one copy of the known frames except for images; multiple images are kept, as long as they they have different image types (and the settings say to keep them.) The other frames are supposed to have only one instance, except for POPM (which is used for ratings), so this is the only case where valid data is lost; that is, assuming anybody has files containing multiple POPM frames.
The e-mail address in POPM frames is ignored at reading and erased at saving.
The only format available for saving track information is ID3V2.3.0
One text frame format in ID3V2.4.0 isn't supported yet (though it can be added easily, if needed.)
MP3 Diags expects folders to be albums, having less than 30 files. If this is not the case, it's better to avoid using the tag editor, which might take a long time to load, especially if the files contain images. Even if the tag editor loads OK, it is designed for albums, so it may do things that make no sense for random collections of files (e.g. assigning the same image to all the files.)
Symbolic links aren't handled nicely. I noticed that Qt replaces them with their targets, which is something I don't like. Also, I haven't tried it myself, but I expect scanning folders that have symbolic links to their ancestors to cause MP3 Diags to keep scanning the same files until it runs out of memory.
There is limited automatic detection of a file being changed by an external tool or removed. You should use the "reload" button to update the file information. However the changes are detected the next time you start the application (assuming you didn't disable the automatic scanning) or when you try to apply transformations to such a file. Note that in either of these cases, the decision that the file has changed is made based on whether its date or its size have changed; so changing the ID3V2 tag in an external tool that keeps the file's original date may go undetected.
It is possible for audio frames to store some of their data in the neighboring frames (search the web for "bit reservoirs"), but I haven't looked into how to detect when this is happening. Currently MP3 Diags only reads the header of the audio frames (which doesn't have neighbor information.) As a result, it doesn't detect that some frames are missing or should be deleted.
The function calls to the file system (open file, search for files, ...) provide and expect UTF-8-encoded file names. This is important if you have file names using non-English characters (or rather non-ASCII, to be more correct.) I have no idea how big this issue is, because the test systems use UTF-8. It may be that the file names are displayed incorrectly, but the files are still processed, or it may lead to more serious errors. So please tell me if you seem to encounter errors related to this or if you can provide more insight into UTF-8 handling.
Not really an MP3 Diags limitation, but: On Windows there may be some issues with the normalization of files whose names fall outside the system codepage. This is because although MP3 Diags passes such names correctly to MP3Gain, MP3Gain doesn't seem to use Unicode even in the beta version that allegedly added Unicode support. Anyway, testing this took me all of 2 minutes, so I might have missed something. If somebody knows how to make MP3Gain use Unicode names, please let me know. Two options that I could think of were to either use some other normalizer or a small intermediate program, which would rename the files so that MP3Gain could access them, then call MP3Gain, and then rename them back. Also, maybe changing MP3Gain to use Unicode names isn't that hard.
Under some circumstances, it is not possible to change files in some folders under Windows 7. There are more details here.
Daylight Saving Time is not taken into consideration. As a result, on some combinations of operating systems and file systems, it is possible for an unchanged file to seem changed after a DST transition; nothing bad should come out of this except that the file will get rescanned.
MP3Diags-1.0.12.079/doc/style_ie7.css0000644000175000001440000000021511203263367015650 0ustar ciobiusers/*.NormalText { color: #0000ff; font-size: medium; font-weight: normal; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; }*/ MP3Diags-1.0.12.079/doc/250_config_files.png0000644000175000001440000005152211271143145016760 0ustar ciobiusersPNG  IHDRRbKGD pHYsȥtIME +K IDATxy}O*@M-Sl<gd'ͣ:3Glj'N&f(J,_LnYmWl}w &h4*F7߯i@׷u*c 6  Xx⋴rqi~k|/* %Z 0sK(?Ak4Q$JkVbuTP(P(t:C+azirrBJ%Fzd 4._9{tO/.HUi2S `[~Shl٦7 $IS t ^< lbbJãjNwUOO::ښdRӳz_9S&l+ީpMitdH٬%˲ѩm}uͷj]?9q|>fb jǎm5c65:2$ 0 4iZٷ*G׏ܹOOӟ\Q[^w:w:.췿%A.ug5eG'I2Ms̍,]p8ާo577# '/ܧodYhu̸`nxXg}V}:OHfԹC>$"OwN/{u(45J.n%IF#ڷ]m+؄L3 ǣWd);sqI_C~P?WG:Ȳ̺u \~/}if*\9lOQ_Sz#E).χ.u(}@$KwL\n߾;K/-wȱ6u4_ )2e*c5aHD@P 6 Ce)dJ^WOPPdJ'mv ]@ d@uYU_?_-.Ru9MխMڼO?կHU[U[{zdzz-Άn޼qq0H^z]شԲmWm@B~ɒ+ܿ0hTRH&u,Q6՛o;viRl:?N8.ÐΝ=mfk5{,_j^r˖e?t ]4l?7k%KK֝;{u MLL.ut!{{&]wI}RSwD[[X]ߢⵜffYbAXOO6o޸$ĹHԌTɼ)\~-[t}I{ŤI!xu}ڼySկڿgIC2 CcnB^@}W˲Uooi9seWmEept??O{{~}!ٓ/}ZI'/zh4")re]`IfO'N^ Šmvy@Dj٩mm+W,j'?4*3j.^~=a&]kҟ(*IhM閽J%rZz{ $YT\:m\nEW;/J(&}LzWSz/=n^$Kؔ2w\_n3fށk~*IǏ;w4%΍HO N\=}Ȟ;wA7tRy=;0eã\iK MAfmrsWn9Jw$]}6W˵2 C@@Wu 6nܪN>ϧ577'i۵e6IW* 7p-oG'N,NU(Xrҷ=̯K^5J4?{uCRdt@uwС$IGdݖ-gKm#sʕ9qbV{2PŻ!'+?t:ʜȲ,)huǝw['y<ya /Q.t2b<_ѭ`oo$Go{taV>`gzK'NH W@_:Աk|--*mc^%v4ŶmՔ[CC#%\m7-¬sa=m6*0uys~O~OW4ڦMؘFGd+UD"4jʑ ZM3u2MS󭦾ץ>u+L?|^az-+ɲ,%:`,k\]+/>f㖱бxcܹ{Z=ɵw_oﯭu;닽f|45X?]Ye[k~t]=]5un={)W3joFfiz4Wt\BZkX+׮vgsѼ ~wٮoDW۟f;v[Mk+ffຖZeql}}75}sݮQot;cΧO.ȥi7zqayWw[fۿpr8-'\ߥk/o#ڿǫn{VjsGfrf\Mu숕F_o% Q_ߍ8jjr#&UJӵ0>b}Wnuk_>wܕ_nc5ñJ~skճRi6_uNZ'OMiuWTZ)VR-OM6;eO5R'O^Vr˵ֿTWjb8n1鴞N򯥝+zy=upg|4{ڍXPrۮRs碙ƝgҰۆvWϕG9^lcjWk?xw:QkvƵױV3Vvܣߖ$q˒u^W.9n[)BNsۋi/v)ܦRֿXK*dѷNƤz:i[;}R}^RQvt~.ww:2Yb+WnϹwvWح}kDYNv/:)[h\Gݻoѣo6tܔ=碾fm^v۪\zUG-?竭ݪ_3Nwc;t AƂn>ղܥ0z^*rWy}۲m/;_]GSXovvfr˵IԸ.W?GߋNVK=;,Ɯ>\4ocIYI[Uu_M?yF7{WsqJ׷'1B517xJN BOn}[Wn?'rɿ\UŶ_yuY7xyV=ʕRI2zgnY즿R\~GZڴY鱖.lĸsQE>rբcЍ*ƾX}^V[mLuZg'us5€͸~ï覛Z|}-wۚ/\jrVʿ) vsMwWX:JyG˵q|kn-UZSj]=7pg|ji1ʵW5sQE3wpawͱZN͍b3´쎱FԻN6{;O|Q>nj{'|J=!kz͟#_^O=7\qk;?uK6kay={V_җL_׸ɍJz>K:+/N~)3p?-V,7gjj$Az%˵IX!hj\[<g u믿$M6k_k`UwK_q O}Kחuv^gq_=k`܁MR_vwJ~i&0wo8z|ۺsu= zCU?\\]G h:~dMf43W+W\ p_#3{뭷ӟC`ޛu{h ᅬVw /Y?߸f_mu\hu8}rw8G.hIO~_*-' _*2ngnNrL9f%Oz6߷R:-*s}ڋxE lF+礼NҪ%ZWhv̚vuQq@ʂƷ:tMu0+ՎSM[g@B!vjSkOӺx1&sd,&HdP{{G p] ^C[k:3gf\Ɍ.\S2QwwP@*n +̙5yk*HB~}H--ܘ $ L+[{׹&MLdҺu&w@ບ^ t\RO*\Wwy\ϝ]S׹fƒK*k+$<͛Ê:q"sf-'5;V$WGG@< IDAT+U-]'uGRsGaN0ՎQuܬ._^;׹RY 'X *\W-ZhBgϮͥuҜ$iB\WnmU"ɵqlZI|3,Jh@۷/\:00Xl~ɲ,MN41R(UWVY|s3UKjjj^>uv0*JS:|^y5>|DSݾe?n)Y|HRgj~>۔kMiK %uv0eFMiQFUKXib7k;nj]x8ipnt+ҳ>Ψ^ftNzgA}{( i۶guؔ>vMu*f~>˗J22pQg䗳^M5Ow>yI}Gt!}lAD#ڹ3u􌦦RDVsOfZZ|*4*|!w߯~Zv"n6}u=CWru8|QDO?zW*KutJyuׇ52g7@k;Jijۭ\I٧m''c4͸NNNi|<}驧ҧ>uo}Q=3G?^:ڢ5N_.\Wn5qc.]:~}MfGYW ˵Aזew&O'oVNgչT]\Ox5JWW5͸Ӯ]70 Am~_Gvݠsu-Oa7$iRxZOO+,Kn J{߲ɤaMIيiTԣҬOJ~@-6ٹAeĉEyweY"&&.7m-hDaMOW)vuB:I7K0mViVeB!bS,Kv[olݻw˲,bSjmmiF3M1B^ 帮.T12bpF3_??uGJ>}F^* ժa oٲY{TtZ?awwNuػڼySUXC}!iL!$uԴvQY4RBZZ|v:+ɍ:NbYf\ծCGSO='xBvޭ/| ?xcbw.\Ra:t{vDojtʕ%]vepZyFUހ֯)ΣA^ \ۈ[k韕Lڼٖ@=='( s{L[nO>mmH$3wܣ}L&7_'?LlꆛK˿<;pn ?~<400oԣn$<׮7?O}lsY}K_V2q3 '֏|P/vܥhMؔN8u"h@#DtiN mZ:fbYd[g5Th:Fg zjj*sFڢGHMmm\;;M]43gfgOehBiA nUpa+MZtN)H+Y]\Z}}auvu-4aՋFھ=<Ԫ)|V## Y[gV|-BW;vDtr\##IY*ʞJe56eI&CڼU֙MܹYӫ#pMkd$!!^:ZcMmТ\3)$d^_ǝIh@Iҙ33o2g&'I+(MG&jZZ|paN## ]w]XMjv6(Oژ'z{nu몉} ׹vtIY=7L+Ȩ#Hak:}, Fmw߹$hg!y!I ^XjdzzڰE.ԩ,T*$K==A< gGh 5/I;FIOu5iohǎ^{mD'N45jΦuR\ސL; 5u߾}4k.}k_Yuj7grA({ӮHįY]o3==g>[jl,gyeij*Xl^-->uw< X#,j5NNN#ztMNN9NcVa<ׅ\3u)WifxRؼZ[}0U4fhW;mPXZDߌlg6vz?v^uM)#w׆_'t!MLLv[ؔ}yuvFu*4m؟:Ne7;F~mC:}zFX)r:pcT*ujo,;0W[C#JK1 c\Qv˿VMj[k<7/ڷ~w}xN>#:t萾? ebĩSh{kk_/ix8єJeuҜRzzBM})`|=jJgYkeYM㘩Z =UCڷ~߿(x~s}:pPUξ{]4r9]xkWѤgIvnWuu{׾Ao}[)XzմGb+pm魵J]m^lFۏ)LXg>-uvkmʥ[)JmⴝAk#p]:ݧg,Ҿ}^}K&曯ꓟ|vdKN0Վe=tmEcNNn~4;փ>^e©,=wvn3?kYvk; +v2Q/7ӪW& |MO|a/i]FMĉ]O~ajkhְzz|9ӧu V~&cf&~<|r<) SwS,٦5bW^yM4.4`ЫZZ|:~VCC>-2K ̤Q4;"7[-p3k xBޏ+g,+g}^sJ$({쳮nz6mjQWѤkε|ˏ=YߴN[kn.ސ::L|WF2wR~یRwE5c^vt \8}e,Zx<ڿ>8p@)dlm/Nr4P__X%:5X,U6]+VɌ^|mR)uv2MorirD(o:rVsewֺ;զt?;:-[::J{.4V999W{W/tPSS1ES[s*maˏ=YW۶ z\?Ct햯Xy uuwߨ{C{JR#V-7*zUʻp;YҶee+c?;uYa3k fZ <vAZӌ˝n[xi(ڶ-nSccI??l|YXb˒dYoHy<NVJX!}U,4rVu3&rՔXle2P_ q`뎺HTVb>9H0~}H7ܹ98oo-[&ittZ>BYy([(&cU M \c)8,VS/Νmz?>dS!kJCC33Z>`в}GFj<[bu*oգͫa oٲY{TttZǎ͛7=,v mvZ{Վ>;7?eYOΝXO6+]8T*sLY[nZyH5}(NթTW3>Je6b^װ6uuСCڿ^|EtV1So +۷T`\jxliUWWP/u]֗.OXV鴡eYROOP~UQ}yqҖnAbӄW}+&\1褯vmj)[/?8v_i=['C}HO$z;Ѿ}^}4K&曯ꓟ|Xi&r WRnkw9=;:pݮwiϞ[Kn- ?:^oN};t{;pSBNv#]'P),5 o4Mes]w;8R=es:+u*?'O}Ξ=/}J&Sz7nUAS_Ν)҉ۻQj瀹R늽owrѨ_NTʕZٳ#< ,;&r:mT}cnNw-kupclRZV|ipbG>Rs[W\C!gur\7ؾa٬ɤbyE"~^S#O%K$ǟ` 9mmQ|Vcsjx8sfgO~LHR33Z>Ns٣p ofUˌRn T;ka:{vF'NĔHdsLp\DF֙jkr'Tq + ?"I:yrZLf4] 6E~cMOϻ~6+%5=(; \aS0U__XW3t\3K)%YE~E<+\(wyA$ǔ \鬆Jjo pah"J$2:u*D"ZDFGB^+Fڶ-,I:uͥ54chÆB̸ pCQ__DO.ix8uH˔\P:׮.S=5]xԼa\a jV͹93vp*PB٬"?  m! '400lMi-< GzzB yWT0 m[XTVO|̼(O pE "m 0iMLTe-Qx|<zzb\ }xqNCCJcc MOϫէNSz+j{uA-o@ ,<5MZHdťIgs,iz:ٌZZ|jo!p@ e-<5s=X\FF](   zsg"ΟեKş:=]xGa+5yss-(h\\=54:£p:;Mĭ\(_۷Gd sZun.ɔޅ; t'W4X4G%:qbZccIIeY51R QGG@^/׷ pEB^ݦ.\եKsf-Y4>T,R8WW)+lya5>ٳ*42LZuu \ кu6nl{kFtVqRYut 1WHį<Cghb"d2,RwYD;izQ8<˗ '44W\[ԥKq;7= cD liU<ѩSkr2pاޠ|>n+(kְ$ɘΞ":;Mĭ\Aoz3J&(e pJ mVW\gde*@\ Pw Z47ֹssfA( M  o:ɤ6l) s 3= (h>͛[X19Ŷ/|i[ pmx[ivfz{]j+wmJzru3m7}'ۗ lKt p]+ʣXP rKj:ͫ+U( p]5Vrlh5󬠝Yf,/汦*\l Z^Xnȥf w%l̍hj+܌kaTZRەyC)˥[lt]Kvw~Kի\}[RU:)&j@:)rR'W}}G uW<Yhjg4'M p@ k ^_*#Iy^]p uw\W}T8#{pvl_´ʽ^Yb_iRyRJ-6.F4+ek=5/p֯vM+ҬT&;oSN)TaVJY\޹P)઴nk-=jOMкV-y-mTko45wk5M@V $ݘ}߶K7ۈ3;iIh>kTn\p׳g- ͛Wz nnራw g]wM.wjͣ1k=.;[l?mWTa䓿6u6W_kzͣџf??Zr˭˷nƊ[IBb˖_ub+~11q.17FNtu!vRk᜗6\SŢuf&?s$5_nܸ]]=7.ޏbͣ#U9uu̹_8rg1*Yq* g>8R=icn;>~<L*SKݽ9r]9}+Аp}?]{ƾ,zcc_|=-<}pᬊ7>I9)S_lRީ+Ix=uf^QL-1@ 3k96$]Ϛ<9M$IbֽqxMW^hxޛGc?g W`u԰ʓG3\~ߪ߇k\u۶^-t]*\Ţ5I9۷I9C`ysuGɁoʕ_3,Ca[ĉb׮t;عs{ml ;18k\U޽_aߟɴ#c?5ɤ?@lvcZD8tFo8t&ZGFƪU Whx]L.^ӆ Gk1ޜ ֞֎n @FkӅ+MV׸W:Z] }V׸Z׶٬$lZ4ˆAS'""M+Ѷe""G&@SEM= D>>cIENDB`MP3Diags-1.0.12.079/doc/050_assert.png0000644000175000001440000002347111262642023015631 0ustar ciobiusersPNG  IHDR>|PbKGD pHYsȥtIME  CttEXtCommentCreated with The GIMPd%n IDATx}߼H./BEH;q]HSTr>+!ťRBSq9T\Qg~);p؆; @{h%$ л+iwVL؝av_鞞jK힧~_NN{u-ӹB䣏~bk̵|/kѢEZ%Kb$;w^OirrR"I*ͺQOvi۳mfڴP(P(;wܥtYˋkT.bz>Lv͙ .xpQx]1Rk҆OK'ǤlX:sP: ڏJ7Izu['Oipp 5yyI҉T.uwZζa!z6=2Q488:eM]~Gԗ#>>eu1N"L>OB?CQTP=4,Ƨv~HK?GU6/U.AiMҵIx骫С}S##U.U.p]۬ڦ_1;w>oF ʳ{ճ7L_ưƸ gΜU\Sg(^JymA.S^WVW.7LBARQEMW[nu:{*jsnZ=E)~\SSknKӟG?[ҏdۅRN7ϰEIzP::ܫ2>>mϏWlhG}:03UC|D7~fyj5%]7QW^u;q}S}c{Iu֫V@&<0G>OWkӦHҞ=czݣ>ܧw=:'H^j3S꦳oJ^:VifiKvPUfk\VRFڰZMM͔yanYNC){ժ5;zt>ӰeO\.9zVu[nj~fjjz^u5o 7Ԏag(Ux}{48TZo_o>3gNihha *:y.b$& ~A z/NBdX=xzg$I>%HRRРq=䁿>m~p&d㷥|{ҍLgwRFCkdd@i@.lZS{ ׆ 6T~PpvxWk]r9a=GW\q6lQOG.]ҥ*Z{ٴEU5H:L hjKJIRaR>[ӟ2'He^RCC ɿLrE/J}c͜@oakոuͳtaÃx~\bN0* ϶T~i>Ӹ2)^maڎ~j.{~F.՜?@a2ci )I{m 7Oԡ&M=L҇[*/;{ڶZ h۶:sf澽vϪR)RoXjrܜ`4440gFyj=q*oO?$iÆzޤahsJ|[R)kkt2uE?N-[u$i< 04Qu~ַ~ 466 /G>r)(&fO ^¹ 7Wfuaܠ;^ UUzᅗ}mzᅗ\o1F@ k/Io4zJ{+c#N;.ZXOor9U,7-8o5KcTTKRI7xv~+ϫP[pwVk7™۸JU*emzv/I_}mm>0YYLo]Ɣ/]T$]NjW2fOi7xqЀG ֶm֠v}swx\,cÆ %̙Os{zJ%cz&y]~ZJew]M?zd#}B~#m0EԌV=ZL&ɓ߿$vYgϞ=t=83 Ȓ%ͼ:~-^(zi9‚b-Yxԃ0 aR/kUW@dI&@aI0 $ L`+-?vz2[lg>sd#HХXa$_}u7K<k׮cIaItbr9LhRurXvh8hOهZ.+qEϟ 3rXY;9?o窿iX66upQt^޻sq"Lֽn\mmm86I^GT~+{Й,OnYYڑG9Cuf,ݴwv ä߆鰬A[t6 HlX/ J5\nΘ&@D\QV`;4mg)m6x$;1 2-)^q_Gթle0+lN?86 YUD^nS-vLs*:^vi_V,ym/dk2ޑ.;Vn1f26!#:piYBv&Wiq;7^n>L o \2R8/wUרmMHX]mJ~3_zeYؑG]]-8zds}srlr e\X^R te喅 Z<&$~#;lB}F: L0 $aI&@a L0 $a\}kn[Lj޽i/-,׵uaN[Fmgä$y?q3aֶE^hӬoR3v$,r{z@¤ye_)׫rZlXퟏ2u4tEitYLv~X'E_ڟÖMlQ gvLb{wl]@bd%ߓV(6.MӦV^e}fѴqwm> h:qtic}-JoӴKRۧ8ȦGD-@F¤ב^3q6IcËņ/N]?x&'+|$>>AN׳S}%{Z% +t:RvMi3_InV.,KMWˉ {]>g]?§ץϵԙ8:ݞYcѩ>͗غa}徳P>j&7\wN;$t91,w_Nm[v;h]}rp30KGrv2^ۘބAzձ}09hޓ\%h~Y&qѶEY֫!/>mp} Z/ܒb{t??zVgäi0LХk7b\m +'|o[iFi ˦ a368ǩ>.Z^ⴁ2Y6Ir{^Z$.aI&$ L0 $@aStYؓO>Nt&]U ݁ L0 $aI&@a L0 $aI&. r둇VJ]L^ԭQmeRfW cYG_i Ha;nӾϲrr+sL&q:2ݩf/YVYI Ӻgv=g:BGQ1 BvI%}my!]66- m4P uw/,ܠճa"KG+YD2fGARW^$u>Х}šPVEV ݽ/z=R|+L=+Gn,lXmlGo\7{&^OrjW˾q^ufYʺuEݺh¸9Eo:niv"lMʫ=L!to^XtQߠ6{CqJrN,._n>e3m ZmC:n2u<~ohOUY9;hesyALvʊґl OR)+0}"NLtyĽzļǭ]QqzIQnI8t²ʻ&طvj{w9^x!+HJ&}<HRK5v L"P-[݃ L0 .IE7;L1Ggt~D}^wzK}+k}[ʱ]F9zj&i?<{&|Egߠmi7Xڼtr1]_y7օaralmǵ)'wI}'˳ӝw>l|n*Ǧ ge&iq:u59@vM5y)~TQ߻hni3ge^ډp[mNRG^^Nԥ[o Q?؉ulm[ko[׃`:ɬLS+i~\/yN3Ŷalr+0KϤUN^?as=o<|zmM)i&чMrIz;nzY? g\jH-&ݰ67 J'd}\li趯{.NPL'6U_ YDL(" isD>-mv5^ܣ/XqeOu,tagﺙ 0i4zlOIWqCR}dca2HA2pVg$V8mNZpuFhfbY&;o^nkݲ|WdwĹ<lDqrtK;CBۮetoIEۺ֟8' 2Y}hmhPnn_QD ze4m:mRtQF_}|zo-\Oq}AUNMe~awzeeݳWP9qL3 EY.5v:־)~FQTgۨe}G-æ]equSöήn2qqqr&illם֓)r \Gi(ۥ^ws0 @\2pa`p@{@a L b/DnV6o \Mˈ7 {WZRK{ga:E *&pi:/&QڂdXt@ @2w®$^ >d u6 P'2%UM.ņ}.҆{:̧%ex]IDAT4 5?H"+!䡢86Dp_$T*Z z6{$,@츨OJ2|>%@9S @Hinӳ.7MmBOԃML=: MP3 Diags
MP3 Diags
Motivation
In May 2008 I decided to improve my MP3 collection, by properly tagging all the files (including composer data), adding album cover art, fixing VBR headers, re-ripping albums that have poor sound quality, and more. I tried several programs, but I wasn't happy with how they worked. None of them did all the things that I wanted, and some corrupted the files. Worse, none allowed me to "look inside" an MP3 file, so the best way to see what was wrong with a file was to open it with a hex editor and try to see how some specifications mapped to the various pieces of the file. After a while I decided to give up on the tools I was experimenting with and write my own. The result is MP3 Diags.
There are many programs that create and edit MP3 files, and many of them are broken. As a result, many MP3 files have various issues, ranging from values that are not standards-conforming but that are tolerated by all players and tools (so they look perfectly fine to the end user) to files that play correctly only on some players or even cause players and tools to crash. Many of the tools are quite tolerant of errors in an MP3 file, but some are less so. Also, there are reasons to change a file even if it technically doesn't have errors; for example you may want to add the picture from the album cover, or the lyrics.
What is MP3 Diags and what does it do?
In a few words, MP3 Diags is a GUI-based application that allows end-users to identify issues with their MP3 files, fix some of the issues and make other changes, like adding track information. It also lets you "look inside" an MP3 file.
Unlike some programs that are designed to deal with a single topic (like fixing VBR headers or adding cover art), MP3 Diags is a one stop solution that identifies more than 50 different issues in MP3 files and provides the means to fix many of them (well, not everything is fixable; you can't make a 64kbps file sound like a 256kbps one.)
Some of the more important issues that are found:
  • broken tags / headers / audio
  • duplicate tags / headers
  • incorrect placement of tags / headers (ID3V2, ID3V1, LAME, Xing, ...)
  • low quality audio
  • missing VBR header
  • missing track info / cover art
  • broken track info / cover art
  • missing normalization data
  • character encoding issues (for languages other than English)
Some of the fixes and changes that MP3 Diags can do:
  • Adding / fixing track info, including album cover; information can be retrieved from several sources: Internet, clipboard, file name, local files, and (obviously) keyboard
  • Correcting files that show incorrect song duration
  • Correcting files in which the player cannot seek correctly
  • Converting characters for non-English names
  • Adding composer name to the artist field, for players that don't handle the composer field
  • Renaming files based on their fields
  • Changing word case for track info
Intended target: this program is not really meant for those who want to push a button and have everything fixed automatically, but rather for people who have some technical background, who are rather picky about what's in their MP3 files, and who are willing to spend some time to get them right. Automatic fixing of non-ID3V2 issues can be done using the 4th custom transformation list, which is as close to "fix all" as MP3 Diags can get, but some may not be so happy with it. Automatic tagging is neither implemented nor planned.
Reviews, opinions, mentions
Some sites notified me that they reviewed the program (or, well, copied the home page and changed a few words here and there), but this list is mainly based on the web traffic they generated: (There seems to be a relatively large Italian following.)
WARNING
If you want to use those parts of MP3 Diags functionality that alter existing files, it is highly advisable to back up your files first, because there is a real chance of data loss. It can be caused by both user error and bugs in the program.
Now if you wonder just how big this chance is, I don't have any answer. As far as I know, there are no bugs that may cause data corruption, but there may be some that I don't know about. I didn't lose any data in my own files, but you'll have to try it for yourself.
I guess the biggest risk is in a mismatch between what you expect MP3 Diags to do and what it was designed to do. So reading the documentation could help.
Documentation
I'd appreciate feedback about your experience with MP3 Diags (things like if it compiles or not, if it crashes, if it corrupts files, if you'd like a binary available for some platform, parts that you like or dislike, new features ... )
Ciobi
MP3Diags-1.0.12.079/doc/230_normalize.html0000644000175000001440000001367112040502152016502 0ustar ciobiusers MP3 Diags - Normalization
MP3 Diags
Normalization isn't done internally by MP3 Diags; instead, an an external program gets called to do the job. MP3 Diags is meant to work with MP3Gain, but it will probably work with others, although the displayed info might be wrong. By default it is configured to call MP3Gain. It assumes that MP3Gain is in the execution path and that you want to do normalization in album mode. Otherwise, you'll need to go to the configuration dialog and adjust some settings.
It is possible that your files are normalized even if MP3 Diags says otherwise. The reason for this is that there are several ways to mark a file as normalized and MP3 Diags knows only about one 2 of them. If you have a normalized file showing the "an" note, please make it available so support can be added for it as well.
Normalization doesn't always work as it should. Several times there was a freeze after the normalization was done. If that happens, the thing to do is to press the "Abort" button (if the normalization window is still open but nothing seems to be going on) and then wait for at most 1 minute for the program to come back to life. The reason this is happening is not completely clear, but it seems to be a bug in the Qt library that MP3 Diags uses. For now this issue is under investigation. Since it happens quite seldom, it's hard to make sure what the problem is and to provide a fix or a workaround. Also, it was only seen on a rather old version of Qt, so it may be fixed in newer versions. Well, an workaround is possible, but might not be needed if everything works with newer Qt versions. If you encounter this issue, file a bug report and the workaround will be included in the next MP3 Diags version.
On Windows there's an issue with non-English file names. The problem is that MP3Gain and its derivatives can't use Unicode, which would be needed for such file names. The real solution is to find a program that has Unicode support. I'm not aware of such a program, but I welcome suggestions. Other options are to do the normalization externally, to rename the files that have non-ASCII names, or to write a little program that understands Unicode and can forward the request to MP3Gain in a way that it understands, e.g. using short (8.3) file names.
MP3Diags-1.0.12.079/doc/006_screenshot03.html0000644000175000001440000000440212040502152017013 0ustar ciobiusers MP3 Diags - Screenshot 3
MP3 Diags
MP3Diags-1.0.12.079/doc/style_ie6.css0000644000175000001440000000534311217173531015654 0ustar ciobiusers/*.NormalText { color: #0000ff; font-size: medium; font-weight: normal; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; }*/ .Code { font-family: 'Courier New', 'Andale Mono', 'Lucida Console', 'B&H Lucida Typewriter', 'Lucida Sans Typewriter', Courier, Monospace; font-size: x-small; } .NormalText { color: #000000; font-size: small; font-weight: normal; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; } .FreeNormalText { color: #000000; font-size: small; font-weight: normal; padding-top: 10px; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; } .SubChapterText { color: #000000; font-weight: bold; font-size: medium; padding-bottom: 10px; padding-top: 15px; padding-left: 18px; padding-right: 8px; } .ChapterText { color: #000000; font-weight: bold; font-size: large; padding-bottom: 12px; padding-top: 18px; padding-left: 28px; padding-right: 8px; } .TitleText { color: #000000; font-weight: bold; font-size: small; padding-top: 10px; text-align: left; } .NoBrdTableText { color: #000000; font-size: small; font-weight: normal; padding-bottom: 0px; padding-left: 8px; padding-right: 8px; } /* for tables without borders */ .TableText { color: #000000; font-size: small; font-weight: normal; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; } .HeaderText { color: #000000; font-size: small; font-weight: normal; padding-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; } .HeaderTable { color: #000000; border: 0; border-spacing: 0px; padding: 0px; } /*.HeaderTableText { color: #000000; font-size: small; font-weight: normal; padding-top: 10px; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; }*/ .HeaderTableText { color: #000000; font-size: small; font-weight: normal; padding-top: 10px; padding-bottom: 10px; padding-left: 0px; padding-right: 0px; } /*.NormalText { color: #000000; font-size: small; font-weight: normal; padding-bottom: 10px; padding-left: 8px; padding-right: 8px; }*/ /*.NavBarText { color: #000000; font-weight: bold; font-size: medium; padding-bottom: 10px; padding-top: 10px; padding-left: 18px; padding-right: 8px; }*/ .NavBarText { color: #000000; font-weight: bold; font-size: medium; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; padding-right: 0px; } .Screenshot { color: #000000; font-weight: bold; padding-bottom: 5px; padding-top: 10px; padding-left: 10px; padding-right: 10px; } .Example { background: #d8d8ff; font-weight: bold; padding-bottom: 3px; padding-top: 3px; padding-left: 10px; padding-right: 10px; } .Reference { background: #d8d8ff; font-weight: bold; } .NavTable { /*width:"95%";*/ } .NoteCol { background: #000040; color: #ffffff; font-size: x-small; } MP3Diags-1.0.12.079/doc/070_miscellaneous.html0000644000175000001440000001073312040502152017343 0ustar ciobiusers MP3 Diags - Miscellaneous
MP3 Diags
This kind of program needs a lot of screen real estate, so I recommend the main window to be at least 1200x800. Probably it's best to just maximize the window (which is the default behavior.) If your screen has a smaller resolution, changing the fonts should help you cram more information into the little space you have.
I made the decision to use ID3V2.3.0 instead of the newer ID3V2.4.0 because I didn't like what I saw in some 2.4.0 files (invalid fields that some tools create and others expect to be invalid.) Also, I couldn't get my Archos Gmini 400 to display images stored in 2.4.0
Future plans
Crashes an serious bugs will be fixed in 1.0 and new releases will be made available that include the fixes. Minor bugs and new features will be part of 1.1.x. Currently the focus of the release 1.1 is disabling UI elements that don't apply in a given context. This might change, based on feedback.
MP3Diags-1.0.12.079/doc/310_sessions.png0000644000175000001440000006657511262725254016221 0ustar ciobiusersPNG  IHDRsVbKGD pHYsȥtIME &ItEXtCommentCreated with The GIMPd%n IDATx{xu/ou.$ޝQ! (ΎWY 尊;ø87/ޝ%,̺$eT$&}T_|?]_U*W% 7 """"""!y^qe˳-"""""2M!hn,F.+_#""""00D ڵ?A4**Q^~9k,ǥK}jԨQ5 ѨZ뾁}\؋>C!|y\x=DQ F?]7q ͗7jT"h|X(/ȠA#Cqq1JK(**?~Ղ+pMo܀sb+|ܧ8wyxXDDD+|6feut| Ip啕/o-7)k_ 4R\y57+J^ŋ!I2dYƕW^q'7m&&NƗ_~'؃bx?&C ]֤IpPQ1ڵrisES .CY٨xAh`$IO(?|v~ "B02(".¡fXt|x% ""*P Զ[Kz3fĤIq BE%"אB!@PeW_qh\ ܹԩnO+/Ybry (E0sݎ ={v3N:?_["""Զ[ zi{snÉ{+ڏG/Mo~WMn-A?2/^eingT~mgTVZnC>WQQRR;64 ; ߿Wky,%%LDDİahlD"+ |98 \ ?TtJIW 3@S8SGt? fϞrx8p?~|-g/^ǂ;W^u5z.|Y.cÆ!Mܗ_׌/]_ uǑn_Fˌdt#0%мAZຩ@_eW?>P`{쟔Km k^~z.}zmsȇo>_5**6vۭz P׹[{S3SF6ԁvFǮti~3)//GiiR e$C?"lT¡0N>q&R)w?I\Ǩ_W,Yrw|zY?-cpm .Eہ`2k}xQ P8jv`UUUǗ%/זoTWԿkAxñ)hjfʰCy cON6ǞiʉjC!,bi<HG>I֍cq' g`ܸ $wq#""*@Nge*cRGu\\'>_]] _>K_-{9 ~Oי}>_e@Z~<[J`1(++5˷EEE9FkrHQ{YqR.]C0N=P*1Ԕ^2fVr|ձ{u\U5>\BOc˴\󪭏tTI+c¡-OPQy%};9s ;_X^TV^O>[ys߼a 0lhe,+*PYY.u"dd:79 ס̋ xR86pǓ ΛD !f`}W^]w *+QQQotc{0>\ƞbv3 Éhn``tf.JIwa)/Yr>ӱ=vH$^/*+G֫AgÛk)տCx D1"|[MA8,Ku p?l,ۿM^_-*+] c+UUJƌ_ LG_ăvLے%]VVNtLJ(sR_xNfϞq;ڨtlv=>]VY9^{u(?Þ'fl|cdAx<K(J2"""6z.ڠ'N|9s&Z9x0s7/W>݃veuA CHh Bbق 񆿶[g$4hC01՛V/E NYYnuJ'j(ee^%.૯+*Ǭ @7.1ԁ6 Bb]WVoUk|lǞM} ytXZ@ii)<"|:Ս2/ƌ+ %%ňD.̨nsnTDDD mahyʶ W^ݭ@Сwg }|Aq%@҆Ñ% P~p?ퟐt DF[Je|Erc=8|X|M7x"ѪufUlwv7|7P(2ҢIYZz[/>ͦMlf]>Ա:SuݧA@II1PREФLWȸ]w͋ .W (8uv7iҵ(+b8r wY2ʮ ϝ@𔖣`9r/Cy%(߼6_vJ9ƧڐJk4TzjIz%T=s~#u^k:m#=ҕD;!ޫج{>3q:V oM7l$I'bUѣ/W_ &;?v5]?ǧ[ IJKBFo7o`0d&MRcj;ߙa%|->`m֬[1id|oP_#Ӄp_HxJJPZQW#zeyɓ',=Aҥ>|r9TPV* %|t BpP(z=W>Cmk;^~@PVTUM/W{Ani TT'nV%~ϓn=:ںfyS:֏^[3YQV6 \}5J\Qy%.=EEJ/\p_YʓÕ%|Ņe:;媗kۤjy^ɣwY5s~'FT(8$Iڵ?wx s\ zZgN<]K $ůݖ2:e%X>M6jsHRn50D< q7*w͗ϧ6R=8 xei.g*4XQ^>==1zXOZ }(ge/APeWEh\v(W͗ϗ!l0m) p r86ݰWرcY+DDDDDdٳg||*!"""""70l1l1l1lшUlC8s,kȢb޼9˿CVE55qi/oҥ=taC 'O "ĉ8ԠgeeI/pAYI:jk[VP ho"qNѣy&hD 6Ԡܼ+vHfϞt2@ {VCDTڎYncL̙3m[#? ߊ%ul<~xЅ/|{w"ަ͛x뭷x&hĩ_Ǘ/AcEx e4l]hzDQ5k~`z]Y!+۠~*v`0^ADD)۞ ˾|]V jNJuj}˻ad @_L8 Nul,Ztv~= jAAXDD ۞ 8-5ͺab}4  <@{i(j 64?$*^ҳf+v ,sy c~u9j^eںHu3$SkzL^hYs0?v ٓh\~9 Ѱ XƯ'a#6r6{6nt"'Bȇm>5T3mon\Y]>Tu7\~6#{;db;w24aC 'v UQ}XЍ[N`sO8 ^>..OԊ^ ]ظ 8tއ | ӧOU;Q5naqo a7O?pN)s*,48@rF\|ȿeITz6~scP7 ocrڠ  D6ppäx쳓[a# |q 0.˦w+:?y:j9FǢOe)#ۆxnک4*'KχhshfWֵshgͩd6馳6ϰ1!`ƣᣗX |Eߗ?11}fO\ 1O ]%WV~g7q4:?yY ݨ^FqmcÉr\ıeo9f;zцLsG0˽%UfZ?\ԇo#Sd6[ @:A#iU#x^ %ST #D nTfFWW[´{+9)-lȷWCy l^qȠZ֗sa# sZZZu/0P_F)PTWj| bȼLΪєְHucoݹʹ2sc7hYG44jjaϞˇ"l@* @u!"9P  n5ҝ }tdÆ2g;ur̮ilskePm˨sg%g2dk\'e#̜9s4r-Q\`--%֩mL/†qq!Ǘ7=I$kF!ɛ155Ԓv |g(عբE߽YA!I'_}2 eZ>نǽY}v>!(?ga)͖X4j}v.3cT[  =t#SWU5'N'Fހeu8/EoNf:bР|3;A+=ʗ5 ˻J9fʹ^ǝ!p^\m9ٳ*ϭ 鎛Ameʃ}oD\l™3gY:Əy_㣆3m1mLYy.H4pz<ٔr✘vxzɴF.ʗ"@yǂ'ȓETPʕY:nm[#%"!۞,* IDAT x68}،Xڷ1 )c!@_U|0Qsg̙܇^{amφ՚^fƄF_$w~=4iCPdD c%X.6Fcho+Mʹp@qhX,^YXK4nTlahko%uЄ 1%TEDUV^WlcC7nnev{;uMcDɗT󓗩_%og"2~uca… 0.3HD'$i2[m t,lHҳ!ScP7 ozS7 ֎{i:]0[e `tzV-(b_=}tO:@=]DlWFǴ&MK^h:GlQBٲ:[rrFѹv--x@mJrFH$_yVԘNΒe'NjNhO){䚄iz6(/={:]/801Xv; 쵷w`͚Dzg?kyذ^j5jCu̴C{)d&n YBhiim4%*V|ɧv2l|QTWM9p{ ""2%ۻM|So~K0w?))3 a,BHqu'O"AwvGa~ DD"|SmA&%p'\ dE-0L2_[nEg;;Cx7*""JqH+&8u;'׻(arkȰLu-Z2*""rmeʃ6D#aƎҖ<}[2i{uc~6(E.n J_ B#"O )6(l҃x68}،Xڷ1 )c!@_U'NߖV=K73f7ޱc6TlDZhQwnP.I'_}2 eZ>نǽ(64Y}=v ?aR@vrm{ODD DDd̙3Rags=Q\`--~R0VRf @( Y2ND‰ ""*$l|S U_XAD4yXDDg ""J[ ?0x=+x{[c66KXb}v AA\mφ՚^fb}ٲ~=4iCPd:3 ]ЛGDr2*5h\cF86FchoopLKyqlDøh4,C,,q{AJgΜX~V> DD,YXwΝ M]BU@T_euF?=t#V&lX~z( n #ːes ""$ ~nh†$*=P95<,]<us+6 Fk4C$سA51lŰnzH†Gq׽}jq 1jf~XNDvÀAa DDY}Kmv~xS%zLz \PC]Bj'FeOuQiW/a20@4DoNHq wO7sK\"ߠ,FNꈿϯ! ""pU˖urFѹv--x@M7<](r)wr]6ri/"""jjaϞˇR@vrmP{oٲȑ&\*6c&M3܃7s KUؐ(.H0VKFX",5($;q0yrMv߲,ĉzл ""rEwb߾׳a>~R0VRf @( Y2ND"ijX 3.s ""r^'hćwF./J^'{6x&o7 7l/aRSи[ ?0x=+9//z6$Qͩa1[Q{L>y7ۨO^hV=Q /r31lQوbx飸YxuV5cpĸp~̆Q Hnu ᆈ6n6(3#ӫk_rz \PC]B:C#a#n϶1ͰaXC DDlP?NB4mƼys jdj=1lcgR@v@Ɔpj4^T(ܼi޼9İADDGF@$@KKmO"Qim=faXA益}[Z_FH0X4$AQI#e֝+V<, vϊ Osjj6(KXb}v @yYDy /f& ""Sl7T/P6wca8e8Ȑ˛ Ii9g A"41lQ˶g?EjM{wr1HlYPeʴ!} ͏{41 DD4C{~øffΜaas6a\4!uC̙mjڬC8s,+X NDDw`ɒźw|eh†FO"*++6Q72ae8M8 .}NkW-K7_;Ϩ "2m@ilXr9X֭=,a IR—/_†$*=P95<,]<us+6 mSW$z˴ah_馉w p뭳3$2MqYug%kΰADD΅tC6.g>K]gU3Gk1ɍ}mOI}Q,"\}ΰADDe۷޶mᇗ;U 70; vb3 DCa ^\A4R>|҃af: jb ""$aƗ5X$-K".1X A2-*=F7(oʘLfÆAa20@4DoNHq덷0 4NQq`4=66ʲeu`"~tn2]KK+|#X$;Z0Wz_ʼӧ#*1l-55Ӱg^C6 EdK! d vϴ 4~gbNAٳADD6͜9s4r6d1   Ҷ`'P˖Kx"ۻM|So~K0w?))3 a,BHqu'O"jL[ WUHXS'O[_ѺVʠǰADD)70@X<DzHĉ)L\0jF|:\Y ׷Rrܨ ""% "2]]m y]]miCEWW&OAWWg&n}}}n|{ ""JOAmeʃ}oD!Yl|pͳ2ꙦÎ^|4*1lQgcEx 5f]hzD""WSG1&y)Sfg ere7Aalɶg?EjM{wr1H/? <@{i(j 64?uOD6y]7hc8"LmYFO.J9>LO;] DD%T=g#Eaxޓ|Kx %j s6::>ȸ, aytr~_f*g0:td3lQ ;c6{_=KꫬǺnDʄvHL<]H6.{7sG9ȋ ITz6~sjxXx Vm@ԍ̗ D} "64c|ǎd "-?z6"y(w/uU1!#l$@A4qt(1l fϞ^]Pz}2 2 "&QclADD)A"ӫ[_ܲ$RAXH)b '6n6(E^ @:A#i;>]66ܭ{ ""J/c6C@$ЏMkiiŃorVW$NrsQ g "г) ^ q`pyi+ˈh?~,vڃ;wc6YѳŅ jih0HD͛oP~ Samb߾׳a>~R0VRf @( Y2NDeNͱݘ& ""(۞ oaj x2Fza* "dn>?FlQ gʔY1lѰ/AcEx /^\.4="d<^GŰADD%۞ 87Q jc3bjn,lr|ycC0AP`` "’mφJ AM!q0"i x(P@mh~;uȠADİAD4⵵C{~øffΜaA.lɓ}s>CoE\uՕ3|[7`ҤÆGq׽}jq 1` DDd$IX|iݩ_2%+ӃkEEE|6/$B|o,Mmo&m/"r!n-C%VAŰADD^FnkQ\\Yqge9c0@4DoNHq 7O6\0V6(_s42njI&ĉ`zAѹ[ZZ>KRF/"} ~70lp55Ӱg^V&!L8>>Oex<L4!]/801@ؙ6̍D#ɛ j ""1s K0~YM4mo@"ZZZ-C4%*o7&L.;}?aRT:>T۷z7ݏ6B CLH! 4R\oɓHD=z=ï=DDlU_XADPp ""Jmpjճ̪>UyYfs/aRrи[`@Y{Vyf Z'N'sD{V5izY pg#_zJXwH}n]a\t0ȶ<873R jc3bjn,l9r|yc?s|>dFr1|?(~ф˜ ""WKφ|ʹ3O{wu1H/S <@{i(j 64?sŐ@#! 򭆍)Sf㣏$Lkk|i{Æ26(v ?<$s=dY$IX~<6oAAOS ʉqhX,^wPh$Æ2Qo֔újߧ[wӳށ%K.߹{ IDATKaCE?&)ذ l<ǃ7]BU@T_euF?=t#V&lX\qM8uY| T壳g?Ip??oN|v:mfCðADDγ{ zylڈ+jh/zp!>}fˬ8,JφoN KAJ4 t ty]DDfv~=mlA}ut|_u;YSk΍˨vlhFi+AMQTT]@BXd1֭_bC3O]#5p1zx+{u͖],]Yoo&l5@P2*""rݞ Y}Kmv~xYJI~ kz8!hTWWaS4 8Pډ2 , #KeNF˜7Q>ҽك Vb˰1cyǎd "ʼn˗_p'$ 7nNՍlذ6qIĥ 8K0Л-&L T84W$u^iD?uw5՘ehoHNqv (Q2'lM[x]S[2-ah ~k@O278`fmm0ێA\l?=DDnφ/u˖˝ FO֬Y͛W_mqAѹ[ZZu^]/6v/2[FzD(=ɿa "vFM4ٳpU,k֬ϋD"(++ڵ) z/@u 7͠lqw5İADDγӳ1s挔h)Om_iظqpF枍(.H0VK CAcȃ˨ vl8U7 qa<*`-H!. 4R\o sgcصk6VwyǏe ""gTy>T[ \a힍yԤzb ""K\1oۍib ""g o+S@gE'(j1lQj ʓ4XDyDA DDcҳh0Q jc3bjn,lr|yc}:lN4ga TlDZhQ-ğ 6ݬ8苤Ζ%@QL2'T "gga chooxLKyY!I֯ǃ͛7BT۷ߑFH0XuH) 4dFˀ;CAc` "dаS7_7S xr\=gNzNZ؇~/e""JvH[^GD΃2l9QF>C ""KφV<, v ޖ( 'ϗ}_ ""J/c6"@ҷ'ȓO'r1fÉFWU ,e ` "ҳJ1 2lF_86#֩mL/†qq!Ǘ7=62:Vmy/glýgc8ў i ""*(ҳǢEB 6ݬ@苤2ԯG2~jlC4Ԇ~aنݨO^Nwu.K^z1a\`'hC{{j#;(Y!I֯ǃ͛7Bʔy6ADD)^B^[6b嶾ȵNk8xN>3eV\ ⒨l@tͭDۀvXk$[ VifK(<9.} Gv\lHllzvZ}-ZZ۰ ""r1ڰn Aiza׮=4,Yu>Gq׽}jq 1`n!1ƹvw ~3 DCaL)ٖgv;4CYTݨ::>0,Sٷ€1 '2 ""W٘9sFs4씧6֯QJ`{6"ZZZ-C4獗Q!.w* ""r1NMž}-g|h#` RFi $[wK 'x` ""Ty>T[ ‚?w T(سQQgF.{6Ə];ncex0~X ""rVlmeʃ}o{6͛oP~ SaS= _,»N$(1 B#"O>QŘynLY/=~qK4Q jc3bjn,lr|ycw"2?c6ar,_z6XS=ݻ'b}ٲ~=4iCPd2\PA DDcvz6ڎ]q]S3-9FdY$IX~<6oAAO6tˉqhX,^YX c(;=Xd;_6DQD}ShjRJ^\\  ?xx$iӦuY>:N |4k'mS"dFc~n #F N2/f3* @ aZIRo+v?XpI&ڽ{oVА z_i׮'M}pDW&dȪfdv3f#nʾzL?A @ rFi/ S]]{ I:r,Kڵ)a4&Yv0O٬Ӻ|y]wTF`u:Jvbҍ7ޘ:;i}zceJ7㚈J'츌=5-IwO(]H?i0o ʪ1fò,YV] @c6꯹yzd '''w*[OfR( ː˷xSUV_  A ?57/f^C\`^eQ n35k;p_S+JyI߽5Z٨tecf]r_lRmĮ!lʘ|qB)Tm?c\COc&Q˨=㏇c.ZlB=}C4ƣ5i<69ca6=5F\,YcU}8S\ӡ^*nF-lc^S+PVj4u򆆩yG/~b4/akwSJMKRgt54~ll,^L.M_8m><~ƙ3g58|ܰM܇ò,%IܹG ڻw H3 C/(O"kN2 iugoMTY=U62B׶yg I /~*CZfuW_}S0MS]]ر]kSڵ3]fLW'/#ɴ!8_ߒމaiogUb8sJWfBRP@%}6FF`|>2rqo?aP~//ozK^{ :uZ.]0kl,}񤙪lRvmu+b8垘;M:/'ݖRI@}6܌p(ڪ6l*̰Qh 0gN͙3GGIRVXfvyM3kQg?#UϊeԈ f,.yF'^+v4PMT2lV1l㷲aYz9=}aIҦMMcթFSbmmJD5hL^ a1ҙÒhɰQin+'|}UH&+6FBϗ.rK~CT=$6Qذa$ cᓁvޛ4$id䂞yWڵk{IS_D%3ѕ41&LሤkèkV3 NP贚+fO3f09fд=Sz^Sb\$9rL%GxLJ#(4rfٹü^垄9y?ӭ^~jh9?wVeT[\aH7xczGܦ{׏)9@܌k"*p Μ洞Sz-3w9*1Sq"plj'eYٹ-=/k޼yھg;I&$R2_w z9YT@|TLl,[Ξ=E.~*mm?n'>vQa) 6$"a@Nk (n6;f#護NzZ;[z㭧S3 treHFHqK [)*;TT1Aܼ G^C_ո0ӯQܰAePR0{gp lW+JyI߽5F D .TBV6V8G}aԠ㤇ѱL>P#*]ٸ:rO?Mvv7q XR{4ƣ5i<69ca6=5F\,Yc7ҕ/}BO @`j תU?zx3xl+) R׶簾s.7W1>9oxj2] ' XT6yV62O׭UrDT'4zZNU`(wFl65pldBRyU a4!(*=fc`._eg᧲ֶ}46,3R<Vu0o *]ٰwJAƯC=x뭓~Pҫd$o=iHY#-C2rF[R/MTY+/'?;`xM X4 zC5| 偛F%laV*f3gjp[ ommQ[2l\wj)h|ԍ$Y 16G8P,{Zo߾n˺ٌ"j9 RwʸᡧFt1ԩr$ZBGYjaAA#:dw[z&&gL5=_ݷtː%+~qY Ӭ A /] M~[6kԌi<^/) R׶簾s/~nFQ}Xy^s%M އd?9 0՝žH4 IDAT qظօrRK_=x\V_/ӢE-x܌ \FmppHk֬.ꫯMO0c:y Ih7iN K;~SҁEdnT7j쟦W}vt` s٬/j˜t{fz P29a~@;4S Cڛ֮Mߢw%ӰWrwn`pT;lLU6o |2xHD?w٪s0+$|^>lj.ln3kQg?#UϊeԈ̓X\Rc6@-}J ?IZacdL2ӹŞ;-^W @0>x$iӦuyNJmS"dFc~x0?әÒѨvؗQ9RV^U+lH]w: MMm T6H&ڰa$ ,r+$."*ሮM0U02WJMሤ9@]ӷ0=D365zUL1)hlHșe󺿻36aò,%f ?H[ ҥȚ}fm6Y(u rDT'4zZNq_D A NC=wf{(tZl8[5v-;>J&R'eT)K.S*0j'dZտYwn,KCC輪|^lXr(o' ږG* }⑰<9@ F2*@E4護NzZ;[z㭧S3 )keHFHqK [D`kmmѣoS l6UVneyco;JappR(UVgeo_i†þa7n'2~os q O/__X(%%5(8顧Ft1ԹJgḇ[+:zy1ݖ~IE qϗ.he12dJ{6\7 l[kժv=zr3xd4H]۾Vjڮ~Xڟ>O@u6nuae\;X#Gd'{w, lwY_nimmɻӰ CZ*x~._Z^g]L/ܗ>F@f',CZfuW_}mz†KH2G+ywH;6WdwbXcߋ㏇hQ?wfϷ]T eT|2󛲦\f>aPB29z 凄FLU6 ko~xX6uߕL^}aP Oabt,Xym lj0pZ//$x8ޝ9}+Z[cgTQ4Olo{,3Vaaa@@0[x(t^y77/Qs:@(6v$)LJ%~=ƢE-!N ~d>ʲ,kƍJ&Y6lؐdѢm~NlcZ?adܩ7I0n44MmܸQ$nPOO6mڔ7gKm` yԡClٲtАFוboVK}hQKRZ6wB[غ^M?fz}r/isx}r79|W6 K/Fw$HoٲE]dؗgؗR.~tuL{nC^l^D~ڂ8n^)$OP#} S Iڿ뮬۷OelI]%^¶tluҝ:^rE8`f]ٰ,KdR7oΪhHАl٢؏!^N2/L< ]n9g{fqp% mܸQZZZ44:Q$uww:{Bw$mo9Yj?i] *z+=3eTa覛nJO?թS~.r:+3)(蓶j3SAޏz^cO7v@k KJ?uM7i߾} &N3uh[j;J} r't徦~rlO%ڂ~c%xݧ^8h= ;?mV-Xʯ~L[>)ir96#L0]gttT(i'U6O| ]7@m{(Tc=)Ijn^Hho_HHIENDB`MP3Diags-1.0.12.079/doc/240_file_renamer.png0000644000175000001440000020433611270552756016776 0ustar ciobiusersPNG  IHDRkibKGD pHYsȥtIME  -l IDATxwxչ?3MY\dbcb0BIB'i\HnBrC~1 iO* TI$ i]rmIWM+/;~Ys4c(ٱ:xzAQvee8jKK9v>vκuT lcb/ECU%xlhL23EWW'<ٵs]kav  BtWˎ3-ZB~ͺ-[pwt$Yɘ1TϜ.cժ6~ns&}>~W~}uOkB h~u,9ihFd]+--K#n/ᅯg~7V3ڲ{Wp~^̿g/}7U5tu42/  Yd>K~֍gGώ | >wxa͂W^w=ԞCf==bols](v;{>u/y:DXd!v}Ps,YʕN:/0!<=!**9D%mKdW* +ڵ΋{ㅗ(2l6Wl(i(<4 ͂ȁc׮L4ÇaV  at»'?Siۑt0~ a?x0,dTfR7S^WQQF]]cF{xln>h"4 M܆r}'.:Ca&F&BrK#mK֮d+k#KWa /4FKS<<^/gfΚo3i: 'razz{}c{+{v3id Ð7e  B1mZ=sL8uv@T544tHAADKԃ!b k }N}}-e9 baNϽ6sD D}|pzE&WSa@'ӷ(<|,- x  =!AJQ( eTT ֕+WpA"cCQ~8qO,u5GtܖME=祗^:{\J~7(BGyƐCEEŸݮEj`hX:@]o1M̙pb_iCAAAȄX9x<[F _SS-O;xŵM8&j8۷6{{_c+Q5}:⬈dvA; ΍*SqTHs|(粒yvm->|tPI?^=+M1849e?f+D4p]3ΡqVՂn`X)/aD/XDgg'{/ttn/AA!]bͨ hx<ޔЧcGH6jkk7/Iww6 -9~t;}p45McLh^,}N]]z{1~PT[y9%Ÿv>ĎZv҉饻;=$;{q8Y{A}8ڳ^o l; c йb0X}@DN:yЬ 㨫Eyy٠0ś*vFQ9Dŋ7QXdҔNٕLev8=f55R4-8ىZA{[[p @j2~AAAHG;p޻@ԕ!-dK׎; W$40X쫉_v5k׮8VURV@ 0 )(:TQ**qNqBQ ?y],{Fe瑶F7U"#GBj[xϡ RwhiJ'JҿD0 |i"_4  !fc6l6+6-Vc۱٬f-S#aCooO֝mIzD,kƲ%ֵgu+Vk)ۚ_}~L}=Sv%BQ~n(*2xOEQXT4MbD  BQ]-;JO:'8`Mَ}\STdgѢCp9xEEEEvɇ3 AAA($j|6/*3.nw eⶴ6AAASVVJWqJKK2?2gg%   B|JJP8R ގ   Ŕ2vAAAƠ囙8qxEAAAmmmy]ǪDAAAF"AAAAľ    "AAAA/   }AAAAD   }AAAAD    b_AAA    AAAE\    qt i^>70cF}AAAA(d6nƪwq!E"*++eر3Eh\.x X*b_AAA 7\=M4R4͂?nZ^y>0g**+xއǗ:g,^ V倏; VȘ  D`um&g͙oCKkTE# 9b}6k&'aX+ʃ3Nǎ`Y4+W0gTE0t4MK/c]~^(AA kUzNrsǚ[c B{o+Vq{Qc=?x)E9`vvQU5o|Λnm)M 0yb |˗pOUG9 03}z#=/>]],X+W̎!wyu~H+-m0e"N>^'~+kq;&OAR'x񢬄qܸ<^λp!ӚF^|C(ktAA#i7n` aٳm-xn*hlj_b¹֌&W͛/^ nT{ 8m nDq}hOBß%K,' )ӧO{~qygh\qŻ8[^4k֡*y |abcwfUCaL0Ν⥗^trYgsU`˖-1F~b߇Ǘ_>_+( ?o>4AA%\n/^@臿ȧ~zC=u; TYq B\^7Gq2\|jN;+\sͥ=x}m'KR__GUUv jie(+|>ņx~^o=gm  Dtǃ~|}kl+/[xW' 9S[SOwn.hIBnÁy8tMˎL̾/`gbK'W;2?( (jpaBDYa=X-v;Ŏ@hO_}:ץm({TʧmCҟLc< =UL;a%cc6nbϮdf]Qv7 oz =^>v|^_ 114&&Q%=^Ƨ/247m¦M[>yͳ`RA(XoA>rG\x=*P⽬o{@@g̙&b>FbPTEQQUE5QPNsF_h`ab CG1tVݛ'". |dg,%(ş mP)ٴe:p6ӄ˟޽30ULE0ML$`nAm}=~~7L3( 3 T/š-FڇDlz뷒>?NL5elvܘof(N6lؖ()Sf?tPPL\(u!0FR~a' @ b) Ú5輋.jⲸMȷ5~{-ͪM9];]V&֘;_.t@$7&z'8*5nUc=:*kFQ^]Eie%s-{. Ul :~4mRᄳGъqRZYAFglC'1)ӧSQU߯}t|nOM;e3:afҟ 0Plzs헐CB$/VBI{8ԭe˖QWW>ڸ >|_=tbOo0o\L#5{(_x~ɤ*ӷ dI=~6x_N/:~ׇa=jyy<1wbT~IFG'СClٲ͛;s=p ľ>xO__+W#ԧ~}c_ٺNzwyNʇ>AWh}_\zڋX.}}8}}XmC曬=xL"+nՆnժ`b*bb*f} (oFf =8`럝Zi' p6Ft #ĖbLUz=Q~qe/ߝ\| \ "=^>S3P15U!_g73s| t@u0 TӤx:nwmO#{84po:B?xrn؋-ֵLdӜH,dDH5]|VL'/37-O 'z8N|p(GR 餴\y'=_tR9nvwN 򗖖rRTT4pO?]w݅(W傻Ot`+佋\āWΥF']^6fMlɴZTph VC0C5DQ{Y}@E nO\ޯ"0 2?i.,p.neF7eno&a /qy}~@CQ4PMDTNr HF}x/wyy=xLNnĴa%r5I;d6L#Qlp1oP(ռ̆ȋw}ot^&&3<>ʺ8k,ʕ+/e]_דuݼ;tttos%p-p8?~<^GM]E IDATvP8 jVmK23s,e\9>@*i.r-b)ڇS6|X(iX,<<#_bΝR]]wAee%'j(// ..Ǝ;|r#ۋL4_XVn, 6 ݎfuO{;b/*xc Ҭb~f7CnjrņjSPu@KTUfQh)&z O>_m:rvجiß2-Yno!g=+[!VJhe6y*/M1\.^?E^EEV ͂jP8waXY0 ]34]UQ԰.KyE||삦a%"g֢ dg7p.і2d%ڗ8 a)PP>yd-[7M7~ѣG1MO \p800޲e˸뮻XjizҗTyp[NYYߍjp{p:Χrck֞S7;nXȸ fO!v>ȶں֝ٻG;zu\}:]^]rvNŊbbiE4;/|shU-`Ke\-h3@ b,/TN'\ty~!n֬Yûnz)o|'|2a;K.zo}[O=T֋#mooyB;E%覂vr m ^Kl\ý_;6oY:i ק05LPX5 vb=U4-aQU5jbRُZ&Lٰ-stci#])ٰ3鈥J K*MTbAӂBb 4 U󦿜n\T4UCWeJpپFqr3()+ޒDeOud#7tC6vK˦? "d+onCu*gcn=INk3)PԏhOr())˕Vx>(4 Mqq1 ngk: * 8]>5f%+߹,z}:쵣WՁgb=8`hجVv01uLN91+j۴a$#ˠA D ,`ƀT ah3Zෂҿp ahڿl__l}Ύc|9Oc%|,q:G<;Nǟ5_)#6Lt^6H&lLۥ|ח?O⦅>}:Vb޽̜93@3f/2qā# vZt]gƌ裏2|;ܡe,SIIi9^ ׉=7\_’vs/QIQ`Ah)*X4 ͊aw`{ c?`O#Pb2y*F !PvTAX4jv^Iƫ\=X|*METŤE5&fY},( Eu;oueyO_s,/"TCH*0|*++7?Ax'=z5]w%%%(2a_u1n8_~9V˗O};oywx:fɢ"K*8rrVrj}e_u[G.3?z5Ig:0`̘"v`l;KssO̮ϟ?;v :_'6o޼A>}:---ihhn孻 4[ եq9q8Φao|D*_o[yL.i >o:@b&g%Tsg"5LA8XzT>0y7O,Vk~}.߈2нe#Yntz|xgn,<_SQ}wk@pDWTER& 1PT'~.7L`Ǧo1î]KYC% G8~܇(uV]A S_*X=N' O3`sY;n>z~f]z%MI^_p3>ML@Eһ'+1}t) r=qbV4 _뺎iAdGo;-/=MW8?(˜1E\sDeqVŵl8IarxK8.E+Xv8Ыͦqg : C샗,f)Ә3l=/3gE,AAJ'ܗ!55Ci`±@lz cz0a8>Kԡ&ʺu]vkZE 0;O{Qr>t>7N[QTKAZ7an?yow0VFу醁M2ŋes% @蕴_¿k'o=w.3[~54MG吢" g]ǣs=ZՁ\8wn~Avm:eӾ0QeU`> IGo`!T[Ayg 9454膁3o FYP4ks;,R0Z4|4u.quXڥ B lXk8M̿9\bqN)+rEc XqU3̙"A m? 4[;(m6JҡWG<-:#J|Ǟz_Q|ü{l)u ְq.9+߷D2ĂG `p;xX*4N-/P۾r1L)Džrr8&BeT __w1 iuCi* Z-_; \}gr(-IA|3y^' -6.]7AVO~r*SO <~F9cgӱvFE1854ȶo`Fp~ʀW󚦡(AoYX,X,V,?}AAHb8s% x<:=?ͦqil/4Mw`|SSih(r|a8~,gr55 C6M8NUUV͆jb')  ٧WO4M|p7O=UkbĒa AgjU/xKp85 ?FI<쭔k/,Z5݆nc8ll64pV4AAEwQQupx <>l6~Kd_>V TNM}hWNgɇi  ѣ暉\q4Mav~x79 _L۷ph̝[Ey<-b_Aa( я6r0MX"A|۶us萛1c6UV-AA8E %|#\uUP?X>CD 0|n]>Μ9Urc>  BƂno3x=,_NgW$°4M۝l|ܹղ_ľ  ©+?F.h,.WGx? p3hi9tY_Hn  yDU˸)=we'W\1j8IaAh ׫3sfc~  oj*u_<_ Md Oh -[?28f$s9mO  a㠺K7xNƏf3A ,cG%wRVWeF2͛UW]1tb?$7m"! `VQ\<:֭+}@tq f~<޽9x'2~Hv2֭ۘg@SA{Wz:߯rF{{%~"Lc 4Iِ44ai¾}*78oի;س/4P\li!iii(t?>G硇vo`R>33:o8wܕqY۠OQ #g?B!) Ƚ+NEaѢQ {ktofSYt4EEa&)摖BS;vڵx:U[i)嵀Ґ3| !?H~ rJ]e:~_gc-X*gYá 4Iِ44raiuq-̙SMieH}!Uľ NA e,YRG `p-_ɽnL<]vi!i?r|"t1~| 3gVb("GAA2ҥ Lg+ktp`,Z4 M' 0$twXs` CCRR3'Ό}[A: +?!mD\M폴=0tX}l "sϭG ~֮ ?d'ٴmE]eÏT< 9{Pk( =#I>JٍLCiwo--ݔX?fȗJg"Wh,{lwcAľ0d2=iҬA#H^/\3-ݣu{m孷gaCsV'>HOxmߞ=[5ԯIT}-'ċ/Q^ʽ,;"}L9n*\e7Z \¿IJ1U-HMe?7Xq޽Yľ}gL4k=G#A({PvJJ,|>~ fs}j7]ۆm&g^Hb?Q^؏uohl<ݻ7G9PEp4">6lՙ6ѣ j_*Y y`F~qM ]b:'D乱‹v]Ix"!jv T&On>;z~N8c;ɶ싼.pTu&Zg"z:5{<̢W'zx≧:ٵkcA6&fFkg#Ib?GLP(b?ڽ$}2{R&˅${e7vm0 zٲ8Nq~1~x=vOj/l{Lqɤ-* ϴh4Q;Kfj 'b՝zI D7T ??^Nu#R I! ^ ʷ}!@y1 `|+~WmHBdIƓ螔ɽ=^;_N^`cl޼ &|]ڵ>a"v39&>)9;7&5q$;wn4()y}ҵ/̾0\Uչ;72yr3;wndʔQ]N%tۜXNH^GկDu+Q;q7\ҀosQU&ʆ~]HJgkR]68ʽ%tMG{>yGj^{k;ٳ+7(*xiHUdZ^ttvGDGcdž*y"qJ4g3mROľ \vw)ڋx7x%0z*:6'NDHߥRݷE `ǎ-䡇pS@\ȶv! M NE68ZuB*YۛcdžsM[~yt75a^'= <02lXE!<3e{@N~L9۷JxS/-SD B}:+J愇3uܴ۞Bhg~+}iIu+8N3G.| W^nF;[mL_D fy]Hb?޽=ٴ O'߳>Xش8˗Y*3ldVOn߾$*CӦu]Vqeu\|ڴyu,t~k:L<8+Tۜ!G*© S_u&׃9 {;O=@GMBeeeB(- oSD)?mpduhT6b?|OJixՕǛ cŬk&e9 m-ZVtZ[1mڼLTHG Dw<6dNdCa Զ"v#t^*u5L4o0czJk"*LC]G˗m[PZjQoN{VBoiY7ߣ. /ٶ/̾0iiYF~^"Ϗvnv"NG8S?H_2H}FzΤfĪG; v6lPU8tMIZӟv3xmQ*mLp$*S'iN'Kc=):ʽ:L>ޛN;9zԩ45Ҳ:6-^ -j.VMeY<%:L  3fLpÓOczG%SW̕~)| lp@d֬ Bgƌl۶&eD Ҹ ܻNBQ`bf,wy_ǕW6P[+_5"E짎a9ٱ# 5qغu53f,t,  i &paÀ={Q$ARٺ/MMeLZժc 9ASA{ ̘1'l۰ZU.l6hל2iukw~{AYʫ}A*  {Q&\37rGmP1[%_#I~R׶;imXc֬ 4"  BUaƌJ>:+VtAU.Rү$b?>:aRJXr'}~qqQ  JSw1&LpգqZu?isEIl$|MfM~ASS1&NK0JCVZyf=u@Z  KÄ *Xس'woaݺӦ~׌4# lg֦nMSw+;PU)) C>.nf;} xtAU˹+FN}4|:+Vӟ9x;/nX'GIa8)~{O?s;߹9sꥼ1 _3_y'vv_L81鋿i.n3(ho{.*a IDATnf s~ûp:1k Aa؉("t^}u߾ܹ|+K)8?Y?J% lطwo7=ϓOnkֹKyc/rao&^[[wy^e˾Jb(aI B ( ͦtD37o4k?^kA `&lx*g5 8fէ.LL?Kra ( a&q͋incobE~Aw9LVÜ9X,8fWM0mQ~7/]zI׼ڛQO8WdLLz3vk'Rh+1R+ Fe0Ht]M ;kiE<ɞ4&Bl/O EQF+RTd g+yvz)^~,Y22pn}gd-k`?h[;]0!rEA6pyY>Mh ֭Yp,w^&[Gz2p[SSy{8|\n\;ұHՖh3#ϙ- zwW}wGeev.l:&+;୷yiH[w"sO2y\¿C>N%"OwoN(Sy;Cc7޵$qG˞dlHd1$$&Rs'{]-^8ڜ]ߧLG*>L#5(_x~ɤxg:*T\O8mGs#UtDWT8~x+x=,]z F׍/8ɕhgڔmc86BcǺYp,ƕT3j_},T'9[ƿkצADZYhG{l Y칙đJ!~+xKdXb-ytg]*q'LL܉϶3-'x?ZK:e9KR:m閇lU*oLv?x_5%<^fkv`_bM'_7 (1;lj!HdFYɞkjF# GgZOn?ؔz-x0T#"-D➉NlX +^؉~ }<oa$#VS7|,qDN]2"(Y+v}r- = N~%-Iw v^Ŋvq rUW䳟]x~񋷀: ra˸v&a{p&ʕA!XXG:8QۍT,#q:'-3Jǻ>W Xh2NnQ /r[pYBʲB7RXsCLқ0mUQRa㺃b\4)5ofTW4/r ˗oiuG!ɑoBX>y)K'e~ L^z3f쇪N*k~nә d{D6b7|jw#;y]}|+ۯg ~ mPPVn%xl:̆uhPժIzQ__ l೟1ܳ|Eb^+RCiU"0Q̘Osjfb*u#rmT/OCОُ)lؑm1LgųH!d:U?lA:TkIs*jlghq*+$rac/iʌYu<.+_Cq įϞy衍7U):2t]9-sYP>}?4v1>dʔjfͪ4`응l[i7cq+SP3ўw і'+㝛eLk&yxϏ&46[Kh7rh~KdGs ?}[>VcDI6he0 y@2e9dgc h$|RrV;nZsjK9s$\صQŲQ0eRn.a4CXT 8vs:v)7 ;ަvC?VEniS mv*lVQW_?]3ccgbJ pr*VB$&F`WGd7~  Gtt$磺&K; A{ jjP_M{炝W̌0 8Mc"(-;O$BD(Yg޼,dh3%Cл.2r, IiQ\E릆V ncsY1RWDp![nF)(HA2?\DW4:79~t} /]K} Soo/HξpJK0==RRX7c2iJ::!ሙN0c$O2[(%nF'δP\r-WSꘐֶb|~,Te!..ʱr &A/x =ď5Å HH65Oےu/9)aSSCaFqd㘠*ih݌F+L0Ζ[Dgp;]oӾ³97=go>{{Gkk{QWE!;jkݰf_i`v@'z]yJ(]vӿNEs^tkٴ-3k6⑁ R]\'}댌nчx\Zx .atx''~R@\;fcEzyAc B̿¯䧨jy'u/`ښ}V;vzy?yv!4j栧swB"œ-ծW^-8MiS|8>>ATTΜߐO_)zv|)~Vhپ aWUCK}Ɠ`se;AgueE-8;>hXUr ߸^4r6Lteă38Fcdғ%t5}sY'Sd 3%rtUԔ4'Xm/4|- p'Ӝ&Y(;%f:9xy-}'fO8\l/~9e =ZBAa#w&gϑ }rl4 fOxE2Z$3;Bw`LT 1} Ԏ_Q M[Onp:6c kNGg>Y_9K:FFXuiuC֓# 4G<|w^92 79`2{v^l.*/V/5{Rksh-Nmp{V--_k))ql"3ʢ4Yu]3em9 nǓfX7" x3TcOZɟGN!7/c]Әx\bG-iP~h4Le ] "NV<Ȑ oر<61!1:\PhCdǢ9at$ BqQVLL<^Y7!!1#ٹgMif=?O9 =,e)uz;6'&`wsXYŵk϶}-0K^' 0y۶W҄ڡf7sԃuCVɎWіaaWVK%89k++;$c ǓM6+Wl{_N9Г}@7"&z4Yoո}sX\l+' -8 QQԸz㶲ŋ]W1>D\"|rDj<0r2Z'J0*?͠ӛXz%+X&'r^GN$22uhhgy;h\̬DA Ellk_+Eee""h?+r9X__> $};;9x-#Oֹz:ϳs4&Pju}@8$\Z{udd&8j> pC[[!rrhr}{]w b}yj;3،twEFy͚v݈썖]TWµ# 5a9+ ( 񑶔lVNiNNw)>Gbb""fyOjo@ng/=yBĵ~Wzmib9oݭI']mysc&Ia>~=ODz먨̴C=-Bo4O[=}}pJ꯮<3֭O w~~?[oѠJj;}m.fYr$F&{Γ $99K_`|tQ\HA$ۻHZ[)?ܐd3??@'\C;'k5e4RQgTFH^Ze6+OӍ51| ].E^ENNYIDKK>I0?>'wuzu2*Zh˓'on*vFWNȋ @Vv"^Z}9=s[ENǹ}:.;;YsF9jkh|%g__RRʱƛO5Mc7K)J|>GM!O5J|ʼ˔dj},Nֹ,1B)]CfSQhPl <\Dw Z 6Gp Bkyڵ䲸|??QrWIGs8u~(o, r1Y KL9m2Br ž9Z#Z6Yxp:" VL !O2 <\D)|jQWkk~d)҆OT^V+P\ikJQfXQ\_˶1tcp KDx9H9 琐+()K&z{fql?'2hD 98>cj9V|$$D|Bʢ'FvWW7alO 쎯nĎӬz̴7t?=zn p㕿ۍnhZ`-+KݴOX -DHZm3&TH^f,RRv16K7s)vlCL"i~_٫z)mFCTT ȥOVnN(U]3m^!n4'<ǵ6c_4m5?j6r;ΒʛoD-ez鈶$AXcxpÃ(*NCTT BCtuc{MM tv?2g}}{{'$ē .0&['A|lC|w~ $ EDGG:YY4^FBݼ!䌆lN3eP_DS6-B1lE$b HJDee<>adgׯ$lg/R{>L8@ EtvװU?kGbR|z>-rd_öVirǭ[h((?&}uyn~_y\@#L xχ _)*EEe& "m<|H"%eB='AJRR ZKU<_ w14'O6QP C}zAAA}C67OO!>jj2QQN:5ξ{u D1 *J|̋ LIOzVIαHVGrt+9Ir$%Ţwk{h{> kȶ+jCʲ-CgdgGTT ȥ;V%NsR7SrKKT) </ħ^= i-H*]6$~ >\RV/+ZЊ~`&[OEE&&^i`OB aRRh3e=vkfX.4ɘA.7wYtvX$V8V`fVkf- xtH9y c>Jĥ+OFo,FGVLۨO|̼H.҉&V. 7f{]]9󹨬0WUqĊ~SP lvmȠ K("Ban,;>ISv LNykuZ}Be OllZ.6ywlF}oG&6$G_g[BTTZZlig_1~WUTV{yJU CDXBi~+ َZ݅LXV27e;2"Wrе"?Dd"{E?|2 <\DO,gP{6tg.N5.SېKLѷ!(,LASSbc#޲UL {cc}dE4|CogK+fJ0DpFi^Sh^9'!kj hX$Lor7eo8yb+Z3iϚlH2t}}>=@gqX?ju,0OypyW)5[;|p]:A-4/Qg /{@pzJi+ڹZOqɛe 9:f+ YI].[nOyBYt }bj)xM,DDPY EgC} Ra@ iRzfC+ϛQ &yEF &r[K(U](Ayש~8IYYBnlǺk̲ڤKA(C} ԉĹTfcyqLa{CDXzzsTT6$4#g ŽӰO=#У0W^+GTt$zg13IB!",} \\ۋvw'BMxy9AK%()Mutޛ Ostt'\iϐH>AAg2^Ãc| H0Axg=C砼u7w!5wޢ AAEb130x ݳ8[Ab~~ˈĥKEL H[?ss$}  ^c?ݙ6 OqttU=CQQ Οs.˜}v' Zc~ى\ƣEI0AxOp,n4څ/.ʇ||*ub$=zkk`(96/+fͮVw]qeOM3k$`T[P+s`VU]72ȋ\imd}q^5ޞ9L!3+*'m-Sl"7؏vLdꇗ8:o SS[(.NŅ !vӮ>:{]L{Ia G6jPI֍nc:x`?򏍍DKkdbnf 9$`&pj;y9_sPV&F8/+;AξfpՖWhCuq74Z)W;u<,!FwY:P\Kr Ϥ:6^@W{%Fݥf)af؏y¿BYz~%ʲq<\_^^ʱ'OIQ>4bȟy籆 륯Λ+G>βQ-[FDvjm%]vf;V-Ր;n̨]o|mX])/>5 /"vNf_phI6s&uO׷(.NEKK>bb/RF|$3Ӌziʓ}xSQ`8?4:ZYPEQ*syvcY,àeMY7 wY50cʔE̼Wp0y5@IDu DtFV}xTcmCuM6cgLasCl>s~`f޼G'h/-s{{G8>׶][Tqxy?Ŕ'BBgg3ޭr~KcYO BnN--:nC$#3xpc#+NDD{#D*o\e$$Diiqfݰh?dY:dG_RhV mG/ñ0uxpry-iMl82$2mU^#cB"Tdco]38RXiJSt'0dW)gr_pxxe>Cqq Ο5ou1:[ p'S+ݠ eVq11%XETVg3?sI^WZQ[M$m'ُVpjm}JQ37_O7\mXoZH}3̌ߵ)"Cy 9ߌlǺK9dw#+YZԓ8Eh=/*r5mLY=c)Y}H_DDPYB|M7 /?ŰmvANm+.d) JV=ͶX ˘/}v7vaJ?ˇ ea- &6qttBBQ!=#!9%}YOA,nϞ<Pא$$D#22;bb"qյx3hj)Djj G0=e$%ŠД~moQ#g )?AD0?߷λgèBo.@Uu6rr9qt ,co~,RHp4GG~ޞ9crb]5$4Gk{ 磤4Iɱ 0χ,k*/>B)7*QPJD#9 _F||4.\l?"gu7o~H!z= 3)]6i.˟7B~~ jjА8dfF#..a8>x ͟DFZ/"d_ùV<706h<>۷煞쇋ZНCړ zNNxܙEO0?}}F{{.._.FmmЪu V44 :^J8h7~ p > (+KCqq ^{ss/;;=MQU pJ1sQPhׯ|@{{!q$J66q vvܜt@"엔Ծrlff6ii#޹n2vXcVVɛWXͬ^i~*=O݃b)L֍ekXƘn˘gQU+19908%|0Ξի%hk+DMM&Z3==_z~x` .8U5{FS}x"/̺x@ MuDn:,vܰR7bOʗCll󓑛 gvCC{ws/CI%VP\XDFcMiAb_|1J 1pHۅll죫k'hnGII)T˜}̎JFғ\г2U~'vdh}WlYkRFP53thcqS=#*)6ͣxИoƘWw̠{33O16_bho/׾V%!..qRΜċH|4r- ~&~ jjL{u 2a_Q'fyŠOωQ[wYzske fQvHYR7h^feQ-ꦯ6[ip=^Ø8ơ:fJKSXz~1/o K)И*'m'N76GOOb^qCZ|YSp#4g~S:!#2AwY-zI)柮/,LA~~2ۋGV19o'?'<ƙ3hk+D{{sPT###p\.p~)\vTgޯi@uu+FG TRHcVurce:j|Xe^6`YkF^+}[j7&yV-EIm z:qL111KBnn޽Yܻ75ܾ=/AQQ5~xR/ѣ]LMmܹ\W3$1v6X8åLLle$%ŠqviVEk򪮙ddWHx26"C;OMx7cCyYad>Q*fhgh7o>FII* qr1PRcb"V8 $}  ٳ?zzp >\F2C8w.WUUL@ttD12y=(j LE&W|$'ǒ`:MMxyCjAIA4 OؘH bzz7o׿Gvv4ΜGCCΜGnn #"?ccEb$c~LPg+ UboooP;:7?;:'Aa㿷w ,ΝYtvabbxeeihmMk1)HJt)տ?Bߨ4'ݏɮ:{F}? ` V#/jGׯp֧p;? x᭷fBA6>1|_/S-/gp?*~TWXk%BNN"⾺?*ʇ  P_;wfq._.FF-7$B.~x.mma ?aҞ|>~HAA/QHOGzz<ΞƷ]Ǐ7ۻ/ÇKY OАWKV F9_ݻ@zzmGT??Fo"А%Ӝ}v' Z_wB>~ sbdd ~)\\<$h\VdGcc.h> 䱶yҒ"څp_RRx|ffD7 ϧ:i:~z̻ZzjYf#혔jWlvpfQߊu)?Zw~(SfEi1݉cK|>G4 ũxգ͡kOlbll?(*+3pr1bbrIx]]Ow;7Ҙ/kj42ȼ?rQJJ,Z[ c`Ÿn׽eܓmk?==便u6$<:Fkaw^wfIe rVAh>ƀHwˤȈdVר>o]!99uu٨7y{,08ɱ(,FbbU iLux"S~VY7~;ɩp, w{ZFEycGN7pr{nѺ9ܻ7)ܽ;{搚lm=ǯWLcm}e Y7'{!엗crrP8QC7P`C?4-4TMﻒM+2ff/`)Zޡf=,)*?3k7r4'fEUj;-Om̷cʧΤֵZ+JW׋d^UXӐY޴Y3 ry>1l46ڷ D.Қlak/6:g4bbb@@a؛9av^`e ]:p5Z^#7JO-+AUNf[o֤S 峪 & !::pppf/jaYNŧ?Lziϓ;+v>[vyɮ:a5 ,: o Ɵ=C/v_Frr,Z[ ,D+2Lsc|c_HVGؕ~+eaV7`&RY3n7 'AfXpDA[.jkP_(.2&1U[Rl~mRЏJ4H #_ `4\BZZ\)Fjjcg4~cFYlBHx unD|6{<=us)ֽ$d7XFE@F?3WFLKXĚY}TxuѪ>MXA<46on6jd"nXg 1AAgcc}}K89<$P}R`BDg|>A`Q wiuRYYYt 'dk?~/BSRb^h.dd :A}]2ɐZdO/=3&3k;hnCCw'9XAA;NHG%$e pCRZת9zUKzIhZGYWz2 59JKmxSţ#zmeD7™]tu؏ PXBB!쯯coox>AA9jNZZ7OOV^"Ze4 9 +eƛiYG~+zWߊSw1G\E2Um,sL1 v] w؎8 \EzzBijK[վ!g?H8u~XIIW~3XZN`D ^wPe!a̪FԺ1Y2,k݌:<ƅ1l4cr cƾ#,`eeyATsB횼-Y5Bv<j9Mѕ2ށ e cu3@c~xA^euus8> Cx|+ғrUsSJW\9szL䯔oYh} +ݔԞz굫Ӓ4A:pB+wmMl6 ϔ0'OcO![FČJm%]1Tv3cL1 0Ϗ׷=47确Ι˰IDJʴye8^ך9ӈWUT4|7t8ig ,1FQ4XyS-5"cuEYeʢ{vLݖLQ}z8AfڐNfii 5Aca' 5oZX^'08~Vn5yPەi+2aee ʇ>W=/Nwhx!Z{aR5pVޗeݴW=s kqڛY޼H9dͼɪ 4;,32#h'$V z'=o {hjCuu#C`it֌izKfk\$n.rLD2ϗwyF,4pc3_0?% vԜ%Y uԜ,e.ߵ>?zu`_F{8ui:MKvOаKD^F~ ~w_!,a}e>⹟}nz!'T)2lfXۇvVM^9zh0S"N-O}OH"uc:њg1ݨi̗約:Z<ȓSNLz*O땏jy=i/oyVv)9jzO"2KNYn ;,NN\ pRݱ ;SvVE&eړ^!H<ǵ"~ oF6cNTF^sת1)g{r݅ߨ +jaik} D\u 0bz!hՖ ȹN9;y˫KK;^ //B6c0e7~A(xQ/Aπ{BYף/Z.'άs0YiV}~-Bوvsr֑  M!1Г})@ wz3   Icc@NN"Z[ )p$Ҟ|>~HAAA?>\.^v'?AAAfk== 8>99$‘H /?5|iM h-||Xr\<% ᩻etj^NlKOzT\E121h1my^zy*=)K |qnhYJ_In}?ď]CffZZ]¯wOb[~OÔ'u~XIIW~mIߴFO^"Lu*HԬz_N뗬u)3dt|nXr[:E$;s9'o;;.]+E}}kB퐧ֽ  ^Ư$82Fӱu!JF2oYj|8n, oNP3b3+]yU?jNHh;W|V;Tj2R_KXLzқxѓ3~f]DFF4Bkf)yY=:4'yV'Zߕڅ<ֲiRF<\i#r%#S=9!?%dۻ;gO4=N YeRT^YerJ0Yt/Vg&4,Zԡ=yFd.\|(+F8aY1gV(/'RY3nZBXe}SrX93NM8߬㬄CkhN(huME2^֠-Áz!zyicQ ;;>QSM4mi*M(8M{w^a^dfٌ5H""D |lZ-F,4KFgtVv3јo.]os/=G^7TW7}tNi*)13RҖNK.nGkbmY'[BRm}eB:k[oUvcb͟iQI[nQ'zoc;׮1|Bd۞qbuGpwr*7xG^FL[Q-ЫSGFz'c"%dž\joD5JCd.Fh, k.bTfwC\"cȘcT?dʊWY~{{GDBB4{9gv]{?,GQQBFnXgNO03J@ff<ᾶ 89ٳLNn n5bH@Atwۻ"-mB6/9v07 ?U…|=t%!))줰#}LN++xhoOΝY";;cc$"̜u3oZbb"ql63`uuSS[Z]>loO!)))A}}6sP^D$&FIa2~XXF_nߞ½{{?$/4141FX.c'sY;qWu2q'2ߩ-uNa/]؏U!77 HHAԈ@躛7?@dg- јy瘟?CZZrscP^8";;!2K5jO ё';.v03scD$ 8{6HMi&BAr|ؔ2vԔ^׃y&B=ͬg< ][Q`Px{~U bpp[QPl44dl#77 14m? oavz{Ng[Ipr**ґ ~|WgBZB }W4mkT? Y5)KKj2bi;#u)lO)S',UK:=}aGj2Q Z;P_c*67?AlSf z[>uF"GXZV߿uoc||<8. Bii㐐M(A k9?2#.. ՙv׮!yyI U9jN,j9D,m4@iՇ~ze ͏EFu-h:zGeS?lx^P2藚 x)!??mmO%/66 QȈGMM&x[[1; ##kxhCC_2eWQQjlYrݞDNff3WztL>߂-Ս%zr=|'XTd%Y2An&FNy<,N>WsL&ΝWnFqdmVvv]sR+ӋjkWsW/^L{Rmm>%;]UU9:w._׻UX48VBVV566_ IM[oUG?%VVVRSŇ Pǻ #iFs71]?7'i7#ߩi {8XMO,8z{I8\]]Kׅ IbRZZR8tG?YEz5 UoԽ{Ȱ(s3?w._UU9*(PFUK =ZE>OO띗bViSׯΝJ]PL7IQߞ-U:sa\;m;mn 2$ҖXux_~^ X$Rݔ;Ҹ|.md07{55Z ytH2}B~;lVίU^^nxZ['H5\脴|@I:;ji'w^ 2Mr*+ *-͒eݞxU=W_ !Lj~>ΝoڵԸrt.ICzqwp٤c/2bAii{ヲ_}W~cx~}ﵲ{K~/V\.\.O59uu'{|\ji1Pu).e*+&DzPssNoG^yĩܩԕ+E*-u2l '>ڊ`G; Z[ 2tRp4q!9E)JO8SMMENݧ?jxxNS>edXUZTCCΝWC[9rӕn!Ϋͧtޠ:;ZX߼Y7KuVreҋ` Cͅg៛[ѭ[:u k#:Nr5=W{osTn]55UCC=VVwÇw?%ŤR~ZF.\(PISI#khhVOb1Xnw:} C]X5ML,j``F~=}:Nf7~,3gw&WCEV^_T{O AkzzYizX7oVn.~cO,,ӦlݸQoWΫ{R>zz&إsT_\v1cV544ǏG}! *2uNܩTSSJKA/> ؗj5N۝z~*̬hppF~=ғ'Hii**Tmm=:}:Ouunf(3&P %uwOa}eZRFUgRݾ]F<l6:) Ǿ3SpXpXUXN)ZX;/S[۸^P_*++M٪w̙<>S\ OJ?p!-.{vX_=ǏG?ՠ<~VoY"UTd鴑)ǽ.{L~T[y#!8_r?详&WwThvvEm\mm>uu'{lLVYyy:uʥӧó׻U\Tf\LO/{R|3/Ws󘦦pXT[W 3e1!>:.)VRAbnnQ~~=k51ISWׄz{>96eέ\9QMK̴*5"8܋?<֫WS UP7Jjj*ReeAmlw[ih޺=Hijͭ{͝n)͍NZ^~Hƪo:XD0GZ>R0S+`&Xm#2xef7Mt#+9^οX=';ïie}~))`eM#˗SzlLw͉ΝWMKr:m<8BVV5661ݽ; 2T֭R]VS\cǏw|= Itۃxn+EM^isuۏa<剶nhpu=x0e]ZluAeDEEjj*B@>_8忽ݧquv544W\.JK6W_VeeSIzPzjJ/шyY,fUTdVΟ/PAAvzq"'3It_,nד-Qͤt=Ⱥ H3Y,f]F ?q/Zɱ)DsPsWϟ{7goi*55EnwxIjk)99iRؗ 4>q}yԫWSZZZez2ݼY\Ӌ M_gxm;FvؾndM27AqؾLҸ7]Nj꺞=SOϤ3T$ 8FOw\oj/oZ~sftPZZ2А~_~CU @25?Pofٜ,557*trJOp{.ޔx#-odF5 "hٶ/6&Dʟys!RywSL{.0jn.O4?oŵ+ ӧ)ᇿf;ZW~ߪ]| PUQ8p!뚛 httNݓzܫ'466('Ǯtptlf&v_諯܊\.=}\7o6W.]VC/>5m6Cϩ<Y~n@46:ke%{}Re';}:O?I5<SGOzlLfKPC[/S\**TFUF `0=}:YL&85%%N9V>W8d~mr#XWsW^MĩbRqp6#nf+.?oN~^R[OO{Ró__23m?̙}ՀT[۸ffVnQC[V;w*۝]Z[ ū;uBl6@?RSttT^K4;"w^/_Nm\Z]]~]NSeetBfN]v{*H BZXX=޽A * quvTU#y@|[F:DL&*--O>MM-+--U֭RݸQs8dq~L)ᡥf]ZL ?d2SpXpXUT+W4?Ϸ)quv544i}Y22˟9˅jhSyyrsӕnl"8¡XZZ蜞?ח_޽Az55y<'z ]^efZǑ#ٶwH.{(oOF*~W|߫:eQ{ZP)/}`$_nnjksYP~>=˗S Knw]jlܹ|UU娤ĩ4lL`̊^7 ꫯ:.oAVYNtFn.*(PZZ*7-<6+9@8~2;GFйsU`O))&d…-._T__xlsWmmỲ_~ٯ/iS~~:@g䩪*gsT&6^^ 2܋.ˮ7ިoƍRԸTzq6vZcm/RnO;i~[u3z3$#n-uvvs\f>pN-UVf֭R4:~_[OϞի) I?u+''M9:>_g櫦ƥf?Hff<ݻjijll^&T]ҭ[z2;L[cto$x~'mD ۃkY#ۋԮۃu6!mhdݯѠH=㭿z=iD?[v$9duu]--^M(YA St>SXЬ'W^NɓQ=~pTmLW\lQQQ.]*)|>okihhV_=wnQISn56zٜᰒB!ͭhppVOꫯge2IY)o"e`,>N҈9v}H݆dzL2ʜHv:Nw7G2nʝcg-~=/b=.OO/aW,8L~ЇN6Uk^v}.@UU#Gtas=39|9q{RccZX(55EyyUTdYΜޭ,eg)--g3^W_ ӯedXU_e}\neq' cwDG%ɓQoM7yqh46:ke%{} ִTe(??C?=% Ϊӯ1;ǏGRUXpy:uʥD6GP0B@szlL޷ً TX7(oTH̴1|TkUPg=ZIF|gD%%N]Ro.&˯9N_GjksuBΞ<[.@`]޽Aݻ7v&'nѹs}L7o!O:pĜ@/̬oG4?ЛoUVw9d2j5j+'Ǯ\G^Ь&6S_P{OϞ|ٳ=2N'0\Y=~}eN27{=̖۝ RSo?59.>֗_٫%edXuGׯ֭256zTP!=c1M4KW1 ?b1b1鴩*G^FF=ZZjoի)w\.**А T_VqSiۙo/B!-/ill^^}iTVWxjtNT^- ,CZ\\F>Ėb͖*-UnwΜO%NӯNZ[3uޠN 2TSfaaNۥff3GFzdT^l6jksujn.ŋ*(PZ'ixnѵk%Na@ ~fsJKqT y TGGx|g_zjJ鴩,K]\zJJLҚFG:wu^rsz ݾ]^+SuKYY6Y,pjijppVN?, {;M[Z^|˗S٫?Kyy骬ypYf&bm-z5}ji[jVEE\)/)q*=B/>sUQA ?N˗ &oA=oL~ h``F}+ӦbNٳ׻UU#!z"SCVVٳ1}>֋ZZZSVMV7ިЍ%:uʥ;w$1~A#8 `\(b^+̲6{[ZTo::|;rUU?sƣ**c?[_j~>i=x0/ӣG#ſzXnf)=B&' ) phTeqܹ|-/ibbQ3^oZalfeέuG9PFXB!:{uޠ}ZXrZn,U]]\.;c=<Q@ ??5դ 22*+ҵk%Ww5pOϤ_z媡!O?77]iiGj`0>WhddN&TT?6ҥͱpm77}/ iqqUszhDާǏG400ՠJKz*ݼY"UTd+3v#Xד'QiiΞbۇ<5es]+&koݧYuuM[z.^,P][Yre[ WW5=I}͐O--^ML,)=ݢzn*ӛoV#;^|%ݽ;U]\j pL&lRrUW_Uff?qut5 ѡt:҅ :}:OҢPHkӳgc~ݿ?iwg?믗bUW1m#m\]Z, p򤤘nQzEtP;p_뫯aUqqtbT^%!ݢ`0ݿ?Wjn_Tjjskez ; JJjl$NYL739x1]Wg_==jkOzUTd+XWQQZZ{wP N[oU֭2]^\ee1$Ē⪮\)Ree RR)O<Μ?=Dփú{wP6YT^B!f?Տ~T+WTX)=/_4PHSjiR}#p<OL|,F '@`]--^ nfZ,f'%=x0U;R'};4K&/h )={6 n(QV)8pQ Ϫ"[0 ?iG>ʺ.^,TYY9`&pTm22zXYY64jee]^Ω"[+50S ?5]P@ ?@0|,WU'^2uPQR~~`'.>&pe1u={6YUVf|YfJ;nFNmn}ۊUgtTHm:jC]oZ7ZYn~oG;KzhDΝWii;bF獟wz?RPSgtA^"Wmo: Y/Z[sks,P(R}o УEݰ#=FOt9#:m[HeSȶU.#L8X^^ӣG#UC[/a e eh'4AZVsւjj*VY)VLЇonqG}Fou4D{#VUv8hPHSjmWzE+3J[г2tۗFfxctC:K2iX&F֍ƿ}h4?qojksul,R}`=ҿcG.tۈ]gGz~oY]dnʔwcqQ`H==jk鴩~`u~RxN=[ǢzųLS]6ߚ!#8R?#ۏOo;ڱ^ߝmFHt=i oAiu5< i))>N|-8$y?Zk#]~|hb֟9ֺFoFN>JnB$z, ٖE56zttRS D36h&܏uSwDsw2ioQ ieeM.(FbvN\ǻHn7ZOX~= ۏn2T؋#18j:;zlLYYiv~zqEKOu@1{UXe:Ҷ?VmۏD:da?K>׻ !0r }dY;Vyyjmm'!TU5rdJ(i@g˿ ik+y1N>ZY %ᴑY88WzTWsIeKztLA]R,>, ŋ utttr+ 8)UC~`Q6>N/.v(>x{]֦i`!uuM'ˮWI ?@D }L#p !'OF5>S\:}:Of3 T֞P!8n}re6o]wwѶQu۩ޑizjO#umGϷozH/2 ?@/^0ZPldޏF z;mw: r#-k;^`,.ѣy r~`HNpf@`y?ʱӾدϷ6g'H Ȁ(n~ӓ 3_m = B9H=81{HcķOf$Ȏ'p6Rdiyۉu zDk/Y98W_ХKjh  ;~ŻDKFcFAeiOMcll^i}=k׊U\L ?@Dpx!S=_g~`8ҖV<%]T\R]y !ҥBg(>j}=vvef8|Eifi^><U(ҥK*(  pdmvXUz(_W֙3pl:y}$~ Ie@׋rurI}PF8>$Ix[wTd28`GzxD~n,UC~`a khH|+//]W8L&L&}}Bx~QOif4~Ib<._.R~>)>C1Y³_T(H&d;z뙅H6nH1v266d6bf &;4]H ?ȕTP <Ϸld$Ÿb˅s(!@0fDT[۸^C ?zpXK:}:Ouu{}Ic2}?^ V##szdTfIMMxH=zP>uwOqҥB1`1`|@g' p QUR}Ic21T1@ւjk/ǡ˗H= 'a =~NqER}. $YϜEϸ i6o'=b%}Iq|9fy&I))L47ÇÚ[љ3y:u~`644OGeT,;F41l=bn.47Ff$dP}p ѣYYI'|@Oj~>3gTYM'@(H̺q~W iɴg=L]X@ ?p?>'\@Oi~>*+s$c8yfqx+Wri`q A?'H OGJJjj*N4$F ?+zpX;S\\$UJ _$óz|\VYMM溜&ux7R.^,fa}Ƙ`0Ę}Nݿ?56zTU,>#` IDAT+ i``FOf3bRC1d2m>ZP--^Ϩ~డg@ffYRÆ}I1f583z~ఢg@\VWO/)! pL&Li|W.^,Tu5)aC?xѳgcZͺr~`qƘ}u=U_ߴ2uGV+)aC?æ7Cf)z$Ƙx BңG#Suft p~p<:Y;u|>)> 7n p"}&#1BiIv}0"% 8rㅞ}IØ}pgc}Ic263AppGZٴw;~ҽ_eXn/W^8<Ƙ`0Ę}㿸7~#v6ڄ4~pܭ7vۗg;-}[FVheۺov=&k?ʾFeαh:&999IC`?m #28ی|"eDZwrG 12n7މH' 90V[F+[60RdJ=:O6# ^;HckAr2m"AfGG=vL<혬 g8J$d+vvsChMMV=eThn$!sb=&'>xOֺF˟6^1{60B;_NsDjw&v=xA}aiûI97=l#G*}%nF!VOp<$ZYvڏ}Fϱ23A2ѭ7#@&s;<6?>w٬z_[Op9 _$mݹSA y-=? ߟ 1aؘW|룏~{]z$?p$5g>F@F6_ p ~]Npг i#-sc۟+Ԏg㑬}E;-eګ8)ċ}&pl}3y{|~a='<3=z wQ~^7#*嶿ubN[gmwVF΋HۈUhmk\ouOV%Hs }IĘ}on?Gۇvz?ZiDʳwFʷSymjݞ+ht9"Hi,aXNCupftd7R[jhm-wf`@~@J $]  W> g>[Ҫ544)}acHopĒg=.&7-`AII!;_[ jiiMKUW_--^uuMhhhV>߂d2aUIS=KSO=S_ªfTYS\w.WUU9rewFLQ|`]1143}Z~g_~z5Ȳv 2ttjjrutNr);]EXg[޾levS[HۊTx։gXciD5|1z$z豊gxnp8d~ЇN6Uk^v}.@UU#G8B>O?I֝;! %ͫoZ>ut;%wASSKZ_nOUvvʲTSg=:sƣrrpXeg{cw1aؘW|룏~{]z$7g>pN.wJmm>xՔ4;7ϜSuKeeY=Vw1qkk~zzYcczcc^V0N˿xiEE͵h= p1fؿ~iiUSS˗SjkWg_3wUCg<= 3tRS  ? BZ_iqqU˛kmW{o3H22*(Е+E WWsOp>$ghm-pfܛLRfMEE*/RCCw} 3&=U`RsB@KSOϤ}zbB}}̴)?ߡk׊QcG9*(PvvRB@o| `><>(YuuUWׄg{9EV8UYpZ~UUnOLp졔|`{ps?9p}W_]] ? oaaUfI99vUVf2G n׻UU ܛ&n}K0V/jhhv3-{B3*+sTSRCCݪȖPVL_/I uͭhbbI3PWׄMM-kq1s,UWTW:jj\*.vf3}z> ŋ 夆f59ޝvEòd{Ww׻=6fHt_@_U@E EyyѾ $h@^n&waYmIdQ(R=}A:x IQ~3>3#73C9V|. 50Т+W5>ޡf嗀ԀbݳOpY XJp\Q--m޽l\P; bJ$r:mjiixFG46֦Ѷ\|n@e2"VWw4?t7V8W2ed[51 u[> cܳzNggdW!mjz7VL鴡FZ[4:mr]##piW)ajX,ggf643ގZ41ѡoS{{<= 8,o}X,=v˟CZ[*S:mA_ENMLt'-) _j)zkkQ-.45Dwk~>E" y6!pp$ه xsݻ뚚z HBTWW^zƲ-CCZ %~p~nnSSSO4;U8"y.]U__;V]UKKn PnX9^Ɍф=l l}4̅ <ֽ{AMM=S<Ñ~xد]|XJp\Q--m޽l\P; bJ$r:mjiixFG46֦Ѷ\|n}ub٧>e2"VWw4?lhqqK++aq%\6nMNvipUِ۬N^NUNggdW!mjz7VL鴡FZ[4:mr]##pi!}g G?3 -,v,rդibC~uw(!p@TU&c(Kik+G jffCojm-kwjiipQmzSwqry &'KRI8= CZZ*tHgD.vR))Q,ذj}ݢPȪHĢD"vѐoP{{FWvzPZ]Sjr͛}6&.,ܭIƝ7^<=a~KJZi ~U׿$_^Je'qTKK; iyyKvadvߧfhhY/z7r@yowR wsWs^kq=5aJ<7L8c:dJ鴑;~w74|XKKa)I> v56֢+WZ5>ު~.]ťہpo(JSԁUI] ^}MɸW\OOߗN%1puʗ}X__fR{Z[bXSS!mke%lX,xjkkd}kQO]]]r-퓃<ϲQ?4ej"Wլ[>췷ic#@( ڮÚZ_NRVEMM]Ш7=kHz{tbjhv?n?!^̴q`^W2n.S7a…hzg~uLfBq=~ݻdnv&.\pW:5:ڬ4AN\6V5EPMqާz tii}LYq&Cau햟V\j~>-χvwS,zjTOG##mV__{l6=-epaP-?j3v >p~F;{rλ~GokaaGD rᾹ٩z{4<ȈOutH 0Cl=L6УG "wo[KK=z|˽mWOG^44UwG zs}e[ LZm/?>O 0U&좐_QtGطZ-&H$[v4?*Nho/-"ϡK򇆼߫.r:-_7o(4mj"We{< w Z_D##/ҍ8a?ݳ>`0]-.Ft~XFўӲۭzkRwwpSwwざ{ss@!1_7LP"NRkk1j~~G -/jmmOHJ!ӪfdzΆjjrܟVo=zl8B0~~53 u>Pa_2,۟NJ$ҊF܌keeWKKQݻ|D`\;;Iӆn|>]kRGM%ZZxr8gիZYY5mj"We3)ar}[Wu8S:W.Rԩ єVVvˏ>mig'tڐePz{ztBZ[rmýL&-Yj"WV&'Wt7^mX) J]i ҒUIB2JIX Y Z ZiU4*bdK 7r %⢴ľu ^۷uM^M|UƝ7^4%[g\N? ^G?Oݹ󩺺.p}=x`O$Iҗ"MU5g2pHXkMM6mmXHd7nތZ[joO%#7FC!U:ÿS5MN| ^&^^~w| N7HB݊e%6ٵT8KC]iL#)/./!/ƤδV)Rl?L?+{#o藿|%IW^=xZۚʮ>j}=h4%0vŋitԧ^jnvO ,g+uQay9|gJRl6n~^xU^ QggZ[]jhn'beW- IDAT;r:`a@rx:sÕ /7k_P8TW[~K.Uv; 05y73&IT˼e/W.> z.IQN5ǟΝϨnrnx㏺zOпoʀ#p,at;F%Ο?l?;sW7_~rlpnv\J8P-&~ 3*D>& PϹ )S ]fQm(SG =z'.v; -9j=UzjY1Y@}*eh?;æF?K}TTLI1=|8R?~\w!J)9n{Ϊg+Ph[3[>i?{T|q3a^+z`yNϟBUrU!eM\81s/WnYׅd^{K;\)Ŗm6R':!+Wl*pQqr+tRW8nٟ칠[Hwn a{Tgٍ`p 0}hk] 0Ҟ?Q+~yXwvزw+b sujV+lX,z7_^}MI:rR{?*BrI0L?KݶJW8a`DžBfl[br'}s5}'~p?aں.[ō_L7b?g_xf/s|up!˾꛹yozQLZVǤtF  m.U1̺hPlZp'-0u>*e? ߺFn֭7>7r[vWz\a ][ :pbVZ\]+尐uϓa˟*~UVԷ+_:[ae.¼sӬ}g1]mam/YqkZX{2PLBֿpWWJԩ9a_o~C?jrSɲK sc¾/%{R_:O 'Y~>Z۬/06첪+R2 ZYe.lU8q3 {xS~R;iMs;lIV èȺ[g1)-|ΓkVT~ѹ K룏~裟륗^ ^KY_~ϽWB븘}w:K]Vp7K-[ǫ__mz/"@Ӎ_aԲtد'ף? ύ](g]G]~a@?NC'j{yǭfX{ng:(>&P+UB~zZes}hr;)?c>_}r~rbpnv\@ @د7^}y69y=wwOM'Z~8㏺}qпya8KA}P'PA{8cA{8cA{8A@}ٷ|#PH P{?7\a6 @߽;%IunwuIҵku]?teIENDB`MP3Diags-1.0.12.079/doc/290_config_transf_params.png0000644000175000001440000005507411265542672020543 0ustar ciobiusersPNG  IHDR"| cjbKGD pHYsȥtIME 0T 1 IDATx{\} o_ݗ[ @ J 8,5Nv*[)k[dgkf.lf2gf( ۘF$ E<$#K_qݧ~>U*sϷ.E>xO9BOjK_V[PP:/U/җs΍syQcP0s<7N8w T/\ ,{'=6OOџ;wn̝;gμ8.o-z8vX:y2^}x_9sT*(0x^i; .XK..\>ӧL.U/X0/fѱX+}+,\^zY\pEqEGDıcok/\³1gP @'|xb+NkcٲbɒEɓ'رw⮻C\g%Kϋ .X/ śoou4^{嘜,G\%Kebkck?a1<<>uZ^}Y8ni^}Y<pcxgOtj~Ts9'N't̙xwĉ199' ^|!{8}t+];btt||>-tMk⢋.c1;o<&O(bX,X.ϏN^x>:?^\fxxN MM/^ωWoz̟0Ͽ:6^{u%?n]c08kv6 cUWů]?Mo?_<#z_/p%?c/R_r9bddo>} _y%{oL|4So[tuF<F,:b+ln#-[ hnR׆ k#"bqu2S+y|7cll4o'O"_==l|+""oKDZdF<*>;-߾i$f˚#%#W47e"j~[58}-lDIJeE ""{lYA~7x]ѳ~oϞ}Ӂ~ FjӪC4ھY{lY7cHɂ btt<^{mJR嘜,GT?9spS'O3.[/g1::9c@'MN]'_ɟ|7s>R]`s%7FLV}Y[OC%7E|"w^{_eΝ~%+Z?q8yY[/Mdޫݾ6oF[ɓKH\ncbrr2vR_D<޻psąE<ↈOo{w h8ϋ-[EOk^JUze%$W8,N'"'Ojun^u~l:l:b"߉)~x'ET7x=.hj_|~\ŋ/bg3r9~n^ h,Z0F#Sώ]ć_SmC#OUU3{᧦0m|e3ձ⊉8ptZoE>w=u֔E+T6ͼ>\/J/ă|?~?]tq\w&?1447w&_&N:d\Z֍_hA,_^hDs{8^t>cFp?66˗-H(bg.'JX?Gl|?x(njzje6@/\^_yذJ39>>1>>pzWuV+|Ft*#I[J9쳇С1>>+V%Kp>}&'^zYDD y>PggOoeqy`|#ػu6_g#0c)<1<qF,(UM7]=HDDe^b v/??kZ>B8Loy̫>='N8>R##1<<'FFދ3g3dqU|144s 9]6/5 ͸^:۶?Xlٲ*{PDD<θkޟ?h?-Kc 7[8Բ3yO]8K֮sIU豱MOxcllts*)|<-_~~ ʗIF>,rDg}8q<.pE^~)Ngjp d …KVƵ_={166}ht:wO%~ll4?o?Gctt4FG]-==/}14Tke9'O߉oR …1vqf9qb|,^zgqxџ*ɓc<}p f\]vʲNW^uhJ}OrKWIJeخh}5*Ge RϙcǎƱcG;V~/z,k^unx衳g!|c^v>)JSA{TRi'KR Ŝ9sbxx(dyK>|,X0u`I+s7͸e bjJE bܱYUws e^7"k׭|T]3u/OM~coN?+BVS(yFqNkq9s  ωyΙ5/|rJwȑW:zH@|@|@> aU]۷?Qtغz|vۭ*#" *ŋUfؿ tӉjm*hͭ8%Ͽr9rDGD4zegoSwԤ<͙O0]k_WүV/reX?OceۨMfn;3߭ϲMm~^%Yz'<ɲuhF~ݶqf{߻'722ۿd\Sdisufu׺^ZۨXc_4GIk˚$+s5/OuZ/Y^vLnf)oeLJk!;Gⳟgq[Tr25UJ?޵Im[M-c6zꩧ,=~6:L>ҷg'KS~+?_ gC1<<N(199Gh訫2VmlС]w%g!16Mg2`~VVG<5i;m7V6gR_追::U`뀺v|U'?I\\ǰA?n;zuywzONN g[۫Ç4eiu[[61nMjrU[v=}̵ǁD{Pϴ'yڼVqڭcl9n;FvFgG㯈nc2> 4xE-rGD޺Y,mrggx=}S^^nxWrWO7tzUK~lgRF4oy}vXYؚXjwjΆf>g.X_zy dE 3}lիw]wPNeI;mW;*y8xp׌rT^$Uժ*7*OT޻ gmR}vߨymzIjۤ}2m9쿝zn7:E^'ٮ^4F_ feOS4>N?}v?>դI츙oy{ٝ%=>צAχF}<\rdiFyne)_uYOu ^ݩ""c{͚M3[͖u W)_uzyJr:zm&??1_$:ʔ긺7zIh4}2M9mұ߬ڽm+iOO$fϽvV_ȚvSgvg49;nW^v+c;}qrܲgu^sy]"e)_;uܓYɿڷog _7ٲ}vO24þ};ck)imfڠz6IN|)jn2K_˫O&-g|g]^h,=yYΔ^廈yˣGg,ǜVNzw̿NR4uլkl>jUfyϥ=H[z狃pCD<岇ͪ?7oimMڵ]逸vXS;2 hf浬QJU䝟Iw:NY'"⪫6oYYn~Zm^Dݟ$lN]Yg;~VW]9zjGW+>7˹WI˕W^n?yiy{ )޻цU/g[vݾ˚AtZA'S6XoVfnUi#kԖe7i,Wu;n'?i-ڼ~4k/d Gv2/8~/qJfeE^yI4u,Sm^ryl#M { mW I7\믫w}WNMU>'enVmЉMY^س秉,߭ʟu4N_KZ<14/Iϣ_wZejwzf&]/|7 O<Ӭw?K8sI+7-+g=?fuѪю?_ݲQʛiʖW݃?f]cÆߵk{eOڛbS]WoM4ŦUޫNZߪ gÆb׮nV]މ7$z?A'ZJGslIӾpYu4iz^^h ~7e|qIO)gw{YÚafS}-X^V>֍r?J>xOK_rXrem;?늸;۴'~M޸[c*@tBvx}:Ϳ__V!F+one۶1:ϩb#"CٍW<ԾlbbgxOnUk@kPBy{gxOÇ=g((?֬Yl+R 9.bVZ1"Vᅭ^ڴkש޶Y>*m?wɆ͂4hw)}&)P|m/L}y:m6}=ͲUi4z`g@Z͚?qfa*@̲,i'"i;o"g dVNe{6-J^N/>rb$;[ݚP6!T Rs*1߾8|HewyGtoONDuz}@'ʰmݎ] X[^?x~%F $mLΆ+Euv@'ҫ~ʔJYqAT[A~מߋMWxګIMϣNI/rrw4 ^WVkeڼ5+c}U??IY;kП$vc*?@Q2oe}Znoͤ$w;fVu&ozbHӶgS\y#۶}>@rku=?ןmeF|JW +~yP];i'yhyW/$i&_m*o.iNjFIUʙf i3@R`+ɕf_4Jݴ#I]ziY'mfu|Ѭ[Κ״*W|~Xi_/6/})Jpu[N/:gO>$f}Y=٧g /5no׻Jߍ]'Nh5S N=Sپ8|ML[WmMyd6A:Up_$m7(OS/ ;^i?ԛaʁ-B _˴ED[կk: >4:VAe:I$(4A_??Kzi}r&g H/h| +W&x۶nŋ'Z;Hg̙3ZoʴH<٪U*pp?V S9r$ɓ⮻X)r9@)#s6L'aTpe03999㽉qkU/o^ufYyW^#|`FM/0YFV}g  ZN @S*TۿXn:h6{"zZfS˼%?3/{컲MXg+eʳ|J:+_˜Vy  9l޾}; kFek^{Vkl}v6]Voߕe_ekm$?6]چWT\Sދ3g"N'զقUs OkRfW]y2Ew4ݮ^?IywWعx챈Q*EDO8fuZ.RFFeY֯uzMukiT$hAfu,jl|Z7ӖY9v6mNY} i]+0h:Eݺ-䓏ܮ4*6oeIjILN֟䓏źu[fwęxW?[w{T*OY@Ծ.bfF ^,m}u[MknEC|$fnM;ɺYI7ҴGuZ&iF|;mv\0){>m{|bGs}^%$ZU^otGR\xܸqX|qDT:GL=uW4C+ҽ B'ݨI˚ezi$y?MymeiNLW}Nfk\ y$֯{<2czծSy-kڴ^)ŵ.K/{1>kg\>;^EJ[[(z5Q)wtvt^|v"NceuM۽{v^g@V^5[?eIW[^%Oߦ㥸8܈j#Ln߫')o|6I^ziwc\G L^;TuK~Q˗Ӥf,&-O^'u|D P+ +5 c W;Mر{/d||JYk+J:FQ<uޯu_di3^ڭɬugj_:NSϕ7>y(Caچ(Q.#hQ/B/Cu,d?}nWa\>dmjN=g']ny}:v܏Ń}TN6 gCt.ly:lT}[V}B*@嫝zZI8.շ$5Mkv9b-ұo{ W,^nG::T}n[,m(ʞ\h>tt˴$Yީ֩u{,汯zeo56mi`+rԃmנ?SS K3v )ZFi+yYc`֩'Bݏ;5q9{ދ\s^k弨(mz^[E{X\Eq Sy tUi֒GQּھuAcjNŴZ+|E.KEMcEhړɤILNOQu;Eck^ԙ>ts\tgӬ$ffӃ?WS9i;&~F5KYNfo4ѲugىX̣ҌvVc j^if͎/ө>N$=~1F:1iTnudRKGn}e=eYI?i~W$9^sFN\M;cqO'CcSN}f3v>0<8OhlVRtֿV5K?k}'a֫:Ex"iv뇺L~;qq>Hcxqpay:Grest=7JL֖{ozP>]"i?e^ym'f.mΦiNAgwVEGؚ]uة1ϟxNNw? ;p,Rot{ҭ^/vyIM`;W NYK;}v'j}myoN?D]f](?ild^ӌv˝WvR1dUs xvh:khni/ϯuUMWcIJrf99q!͹G[rZ_MѯzH7A1Kl^ekN,W7yW8I?IrFrS_ͫ9Iޛmg]ZWں>>^}d7h<4h@^tsrkVƼ߉qvc2X ~on߉uܮYzn~Wo2~iэlmmԋ~҉~ڥE:QiTQ؛Xܫ׋5Ag:kɣEN$m<7?O|N:yuϮu҉`N zWMejuP-JکggBm TV;k:(wQ-:o,WgӸuvȲ]cHYQSwi*$}^?96˳}^V"`*?vԉ'wjqJ`S] i<<;c+I/7Lw>{&w+.q&T+k?Wݜ(~/ҤndsIF6[Sk{5;}\kN{W:9:&B=&of]Z7^yu,v>\ʣnOY^cy>;O;=ts1s^&ɼ8Vίq^gyTAcq_~1 +۟9Vp98. wR7}p}@L> ||@@> > ||@@> > ||@>>  |@|@>>  |@|@>>  ||@@> > ||@@> >/UAJ%@]rY%\ ~(Rs*8+ T"?iYMͱd\jӗ&'Q.O>U*f > JQ* xN>|>J /Ҍ{>T.g܃!{|8ȯ@O*J14T?4ȟzȞ@O_`z~"fjbbe0v{-Y=/b9^…#*{?&&V ں銃Z'NDd{$֮]XpT{;Sޟ7C&'E|VJ>J3C=|{ "(/ضn5Ņ"ڶXٵ wkG[^?]@hljE:o:sX&&VNWnۧά{XzeEFU 0S*E T*:ӷAr|C(19)ӷ@O_y>U}߽{{=|YeZ|8w>@Vm7E{݃Pժq4{J*J[hζ+~#A)YUSUn g>E_OO<hV*ݤ͚z1$ISwׯ{_?l+۷?;H^׻ ,i_7ty۶ݝ[Z'ND8qtā8s@LL[g 䫃fkzPC Q:;vڽѣȑ'cϞ#f…@T.tv+4}'淺7Vn^As|I{Euw4 }^ih۴},-k^m/SpkA=fB?E?C>`.M`$FyxYK19)3MM/ Ҍw~)%>@zFGbsWߍ͛ύQS;ccsW/GbllJ~4op̛s}#qA&&V֭׫@߫~wUqwk?A Çgر ""w~7~=/!0>1>P.\.?G''APG''@VmCvwm,'}ӯ'&7\11>[wyeITﻝtȯ? jj[nǤQo3Ƨw!OԮ4#>{=_~r<̞ksYҦ+!DW'3*OwyFic|/N[Llu2Y}͚Mgת7#Ktҙ@ S[ igfמxsDĕWnO؉nqV<~0Ԏnv3~~l.+cٲwL0>~O;qOJie~կ|nݖ4n+A6TL5;az&N;uWnj7[nݖٻѳ[%}nzFig͇}bG#"fK#y>Ac|&yYO3nJvdtf1a'0 ׍K;r˜fY{_{Ѿck4~zA~7IO'oW}:Ko6zLgM'14rL .xHvJd6U޽e޽4&_Y^N3֯_}͇?kOtu|Vi4Ll9&̖ i{ҩ F'~| /@6g|b|mIDAT{񃈈abbt p'Ґ*> '&Vƶmwqfm]pvuA71r:wp0[||@@> >PLў=Oƞ=O&^Æua:-E Mmժqz)i/z_jye-Ju>"{[c wsgryVb$ }eMՍ}P @ߣ8YWW.#_j*m%k]VehzifGA<5kFڪӝc^}&I2 ~TfZtI$JfDG2:;i^^jy_}:=Ҥn?T@V}}SW:AONu-o'۶[<w]+^;9NU^OrE2ʹ~4Sl,G_,|MW5ͮf?E7A񠔭H?W6D> (!{A~ \m@AѬ,_R%}"K:YЉj>40?W[V,f$ٮL#>avmFZַn}c!q6VJ>xOK_rXre⍷m;nXxqu?/&N_ry]^<ۓ!`<ЏvxrH|+_'O]w}{W7lX_S/t5= z!`<@~ 8i?0Ɯ]~>  7ܭdd7lX6BP$^6 WNs4^_Vmj+o?+@1rr/2E?< q/0`6CryVmtYu#>fL$N[$oMfGm:y/@f}կ-kn}nI */i4ofYv_N+z4Xk'kmt;P֦h?ݨn'@+I'G>)ݘ:u֞>M9MUzSӺBw3oy(ehe W7 .y]^Ak';/ݮ^ԅ@ Un:%tfT,c~uvfyI,M)Svt^5VeLi6K#Cם="eY0 _r8~L Ȑ96?0 {d<۱mskƲe14TՍ/SMa?ӧ'c7?}`H|X-G:=z*ذaq|Cĉ3oĶmgũSZ Plذ$ſ26mZ oc7_ y癶 #_vXlnlذ$gO=V|qǚ5 c޼( T*żyq5KKŖ-K}!~:{rAtA\vEP);o7x'?y58qm+bű`@_dLOۿ%q/ģص'.o .dizW.z9c߾_n8nz9 /cݺOMWb߾qMVĆ S=m~splڴ4.i?ko=vE\jG/B<[;_"L_|<6mZra\vi T*Œ%c-+X7Դ_Ď_7p^,_>7 E522\2/?46n\bw }q౸ⓟ86o^inذaqXqNlذ8bǎ7{vۊVO@_xR).o0֯_?j<w'߈|Et2O@_tCqSk?}Ν'?yq\}ذaq\rɼ暥<?Z|;Ǟ=oG>rar˅z;W /R/ҲXjA\w+q=޽S}ti7ݴ,.`nx>VW.ǃ>RF?G}-nsc"ܹñ~ye˹q=ǏJoŭ^Ez}U*bغX_^|㏿_3o_7޸,.pn 4<]tN~űn^#񏯈͛ύ%KFM@_dccsbڅqEs꫗wB<v؊G/ի9ZUbq =<vΝ?">qEx>BW\ʹ|)~bϞ7gΝ/%q5KcѢ2m~aUXqNlrn|r )ӝ|t;iwiilJyj/O/c~1'?8H?X*}n<.W A+Pu_9izk߯~.Oe+tFlT/ORO:nU}ݽ-BWw/c9DR" rd*% TR`BAAJ~1;P$Α4zV6-/"v.yݪ $CKY0( 1mN@ )}/ $U%_)<:ai S^SukW!픶S֢.mq5;& T\Y]bډoZU'MVNkkm\ǘ^g? ܩs)u6- C|}fJP*oe\vڨ͐ۥ~wEW`QŜq ]%ljD:Ըxc[Ծխi[hꌿ_RRMmj`K{~gA#l>^.ѯsyꢛ5ihM[ƱC7Ԛ̅6S Sw,]rO/_~/;dx0LvK O=TZ[;e3֦ syNbBo ^^f:+aoat3ytf"X\>/sHZ'yyB @|@B o2 }p3*9'worel~խAU m.8}7QC2iFsƯpO; cg!i'}-l},BOEgch٘>Ug=u^F}n3ebuQ;Usue+M2֘~4R;?<ޖ ^7 } Ǵw{L;ِ3 e\;פ&5Md[ΙVmvCS)_kJ=g~I({|><=^FU ǺӇ3pS7 U-Bk}b[DŽϺk;.6ml멚7uS@<1%}E@VRo eCa/~8{X@3yˣ?|84Ca'f]m^\uQ3}o6gud/o3֠ݺ5b;}= a<bOt}߿QWve}(j+u,1NcM3^u`lXMeab꽣Z@#ׯ{ر'ŋod2xN f%cd~v`wwd t: Wp;D%@|s}|m|@wT 7ƒS(2 ϟSӁk*Dѷbx?Bt Uk*'+НPclE}[)ZOM]g}~)oJ_ܥ7?(믄?KtUk*;X}(R5u?[A}Y΂Ƕ$R-sY͊B~Y:V8ȫS񦜭bec{emիh7ױsl;Uy_Vuj#p}Pw9weUcUPlP2&(4G5TzU.u^Y-el,b=p hA]M?qt|rea*ݼ >v- !}էqdϘgu9yۗ[:_\{&f?Hzok>_sʖ볦>@E\Ԁon?ƬԩxlPX";@!ޭݻNz!ܻw[Ӽ=ϳ:ş ?߿wo=~6ܽ{B]{Zi}#gkX|;)U,g iocm.} Zlu~{F8ulUm>`k>lm}Yدگ5Uzg?Rl~/smԾ9At;ԏ>j:|MG 6p̙_Eq*l-Zs _"nٶ!ڨt>|Qnk#-aBj5")EQEP`ee>⋿V2QkөPs>_ՍGǏ?-TҔe<<0p>=ܯn0pw#>0>,A|Xp;^{%y?}`:,h:ǟ>9ҀyEU`no;CyV8˿ !3W_}%[BZG?IENDB`MP3Diags-1.0.12.079/doc/favicon.ico0000644000175000001440000000706611205532026015357 0ustar ciobiusersh& ( n( @nMP3Diags-1.0.12.079/doc/210_tag_editor_assign_image.png0000644000175000001440000047253411265552612021174 0ustar ciobiusersPNG  IHDR8bKGD pHYsȥtIME 74_ʭ IDATxwx?{UҝzeMraWz(CIh$Z-_(jcL1ƖlY-[8$dIly-3ww$tB@ @ ]32t$P^^ʚ˩`0@  QZZNvvon1ݛq]H ֺKDLL 5P v4M\IC)*,0- F UU TUUR%7w>#F1clټm[d2^~@  ;|{/;b^Gݟ{`71:x*աy I(f3F Krj\n`\6o(*Iw` A|I 7&RYYA\}}{89pf@ ~bˎ;=;w./oUfݺ4h= ֵ>2{ʔX,q~-- mRZ'接5p"m|~3NTEAQב8l2sYx!W}ϸཷu0 *@ Iӳn*-/3\Pr΅\0CR6Bg%^rK0z0vf/*vQ߸qkoMg1[_~I*Ǯf{ȮeUͦbw9ٽBn}Ӧ>d$&%SYQ[D@ @Ek-:~^{Nպ--ֵdG \J|=N%ޜ#Lxc?fST1^SSנW7-- ͥ>7n o] !ۉ(1afs{E41Å@ @EjΰaYM>vrPi:Ҏ@:T@ή]TUմڎ6 ( VYm]Bp:d3dȀ1͈]S?R왉bjW7$SSƍ^3ΘHmZA ԠisK ! -y\@X UQmLMM99}oP>ii kd:y5nLjh ˆ+,O~^^~_RSSE||"Yz%"SYYAB @ ]H7Fzztut>}_}Co6IOO%>։bd~ /~[[_I^s ȞH!9>1!٘1呂yap{bEbRF?$/w7G&+7,h@ A-{g¿sr  _>؎Ppu'_]#ۼ> lݡ`hb%f6?2=R \ gee=$#IOO=t}.entQ{ިC.Gʦq#G[8'8!C;fı3<|n#i͹j5/IFAhT ۗ&A3f8>CdYFQdqW@  4=V!-]PǐԨ1dg[Z1^/:'J|l4b1''m1s0yy{ذa]:8|PDZ0B%8F6&R5zaߜ0mr5god>!Aný99}CYY`-PYE+أ"Zю%rƍo2 ݈V-uJFLSOH$!>ظ8%PQQڵ+),(h4_ @ 8UD,!zh,oIvoV/44yf 55 ٌdDuL[&SP{Ŏ6kQQ}NxSi9m[mۜ-;q⩬\4 6zۑv,[k꼎Gs A#I2eF$ EQ0!@ L짤$ed`cvD싓XfƎn6Vs<'=@ ~b=W/;"zl͖9r(n@ @ h-jb9:g}ԥ=ǙlSFF/: <wz{졲wJssaĈ^YY.REQիvU?~ߧ{ w(FTȗ ,c}\?$ ]ww])&b?fig޽Έ#Tޣ5$DC*({M E}/&itb^1!a1*}* 8Pͥ=A0%It>\Ybꏅ R .#9TcsaY,~s&'Ȓ(.*V+cǎ_PPi}O>s.d2yVfGdbj|/O_|7|ܹs2dqW_eٲeYS'6lX~~~!UU5Pf>0a„q(h46qCjj,m[Ϫi3;a;5cW3-g ZFa /|yHtߎAMON䭿Fs2;1ƥPOL:{﹗ 6~ڵ2tb0M(Xn5w}[Dx!P~HL:]ٿ?۷oG$zl@m<a]A`f@Bڄ{'}h֤Zl) nf|3яb6P^6f%-Ļ_W3RF UxUZ;X̦{YIW9s.^~+1?rETWWsE#f͚upyd??;y'_r%/cƌ9nbi6lELLLo9묳P%h믿СCɡ7q"k9?,kN;Wb4U}Ϯ׋|MgrѹI(ؚLg oVM’x|/_|og?v3e:,x=3u<Gݻ 66ٌlp=PUUc_uJYvoL^~Y}EQ•,pHXF jc'phwy:Rl>\s~$910ed秿:6_vRT%x=\9k3gf0.p9 ľ@ *eAX2zpϭi,b=~|=xLjdWGul8}wǜ$I|;cݺ ,Zͻ˔QII) ~$ }.!>ᄏ} =)Ō5 $IǸ8ztFСCX,X,pZR6l¬Yg?oMdS2TuX+|gCz lϤqu0(2 [x0{K~~>qv;FíëLƘ@gdL:c\~Pz{KK.cH.[\^U) Oquh~k׮'?@AӧO/ƍan.7.O]c蟝`ݮrnӟ?]o_.F/a˥lݶUyJVV7~s˯RVrA&jYa>cZmKYY9>]v1]| Xr .ф5$JQdNŹ=[nHZ_/cw5I-[4111t:[ճlٲ MӰX, >X4 QsdX7yٱu%xdƻbɨ_lg=Y{7UR8 ?3 ic}FF:~ ㉳䓏뮻ګ<ÇK4h(TnW ϋQ#{eYBE-UGW4 tP6VU#Ӈא5Ţk ac!Ns64$*ԮB}ł%tX~!?u q7βe_tx=\^_xYbzv6_?{a`V(.j̈́ Q#_|?,0씳2j̦Xkc1ǒw 7t7f*,f]ݗ 6J=|f={cۙ硇K0ΐEaǎjzj [7+/0_j f0HDSh￧d~4cXoIuu(J|V23 7"FqqIMM ɀQ6aduw-m 6:E¯ؼq)^92הH<{&ONgTz1eni|',:jbD'}cq->\ʲe7XCԧ`_iVǀou3ef?O܍֐lM }lr/OGrjv/:5M%%pY9\žddeJ IDAT#)ھ?nݻIOKA$~\-zA5xHLLQ[Gee%E O3_Qᠺ}{iUGff)r5?vޝ4M#11Aodz͵55м]@]I~C稡n.Ӆ٪#ᯭ/0Y'(DZ ۀ1KCI=t_?+lE>8Uǭ׌G[xei>x {px}3%ɓ޳wχyow\E( QWW\"=aCտ HL8uϗ1D h #Bb_4nv~?Ӊ$4ɣq/i?C/$s^]qWI( JlTC'J7f :v#a$Qg஻c쭤d ;aunO~TS9b$."Oj0u6oYy/_>\Bm#bD|YMyypxJJ2 ?s\|\2҆m8}{f/}V G]-aQ9$%i#.ݯlY}w{*㒁d߯p5כ%$wľ``\&La|'aVXEIIik)--2#,6lȤoߵ$7w.W5iiyGmr>|ɺ,]M>R7xhhߑ4W/"g%_w<ĕ%k:KRϨ(T.e}dI&J ۟?_-~eE80IHθ!e$l$/x2SNbuɆIB$$IGd:j[?`h6Mdi(RËF3b=2ּc[GOg&'Z=>ؒ=IG~t,yZmUm:F6)c:Y3Pd4M%{}3C]IˆO;+Rby~~6ڸ~fw曟?y1,L؏Y0xVȿkάY]+̲e 6X(cIL v{Xtqyg7=fSkݷCfpЏShS3]W?5g3/qyUl8EzPT¯j 3=XLmv³[n?l_G># M7U:TWqp)ݺw[crrC4>x!uǭxFMz!l[Y˾frGmm^͍7Z+3<_InNYY^ziX`Ax(;G/-}=~KVwB lge\un -yݕEp>:Z35Mb |y]z/bm ~{pP9RQ)t5dX r=S1GW\5k;vh..I=^>|>~m*++!G&l߾ZΝ6f*.\ؠgqhА4Aٖ ؄n63,Wnaɶ]ԖQ{9i47fD,s3y/xSaG+nѸH>oI$Yd>vA'aӫջj蠁hZMS4YO:{wW٫s5:8z xΟ o|Sqءh.Ih4 ]UQ{~R&b_k.hF#Mws}z|y<>/'cŰin=uy4HWcxE"~Cs1axzj>+/K1y5l*Yiٛ~}Ƅg E$`[~5Nq1E!tgԍҁV^} Όs/C!ru-hˌF?uuxkkq8(++b1$sGdwobdz_3ό[a2\pAOJKݤ['hlT1Աי CLϽgpԠVb U)L\ٟ+*x2nQuEb@Ql0Y @S1ΨQ1M̛w7OqF&.Όmdg琞?}{5f$,J A5ظq]]W7][BW%cP# !s!u$%(cHbKgk;S2[R)Ɇ!a%NKII2s`}q@d2'ȪPґeIsh%`woRT5j@ @"ʋO|vlD: g܃e$` (C>)+䲄,-Mzno4)'9j.s5JYg NgŊ<6nOWØ1AWtu/'===3۲e+q`P)SF7۫xy䑿pYSn>W/ǘ8rΝu+׽A&v;8ppCN9+pu3檳z:.f5땳ygY!?%Lk񧫆pc 4ػ7}>ͷ. MҲ?/`̘݋ طo?7ocȖD{C~}v1HJJwsp{'MJ3ͼi(JO[778pł#?7o˖-7>nf.6cDG_#E֜Ώy/3g{9 8U7矷}H?SO=Ō3x7$r.bv.]v1zN>j}U!w Fⴛ`J6 k~(>< ɂ@Q8Ö}z #= !>_[ֹ0nA\wn^z ׋ۭa6{''g TVV2n8^y5N=4.B (((rs@ee;QSqt]'%%޽{"4Wi"UݻwZ5=@ؗ@%, j ~_cЅ ŋ?vyD H?IRvb`1}i~VXbέG{ZMx~ Wt ]e a,Rq_GQC@phv5Dk:IsTh-Ѧ+-ݣv,#˰5;Z뱺%FҞHwc-Ӷ\ѦlnǏb1h() RYI<p}ւ.^B_TTUl1pT)Z~,, Nj>L2+c׭UWMaȐ`tZ2;vֲ~}F`„Sq=|w,Z]II3c@\jj|',X)uu. $E͠w~uy|}>d`nT0q f>wYʕ>\=1?ӦM$11fQ}ߌyQZ*-'!>Y_9=1bظy!q)+/$g >HL'@J|qdΔfn>?˧fҢ< K]d`6zA?^})=(q=ℊ}׋dVc8u|7,^1$q>S/>:x0t`VTknvxoكS'wxZeNxر)եȲŜsNhi" /$hd5"=,ZÇ3m4vyڮKYj'NW__JBBB'}[ș|xЭAR-^@ _#z Ŀ :; ),*B׍Ę<]!CkL0!tpPWWn!'gӧ)/ƟK/DRRRJ-h-m 뮻Z%\n0c1! itYB1ŠĠju(5T,zue ~%&n#/ױ[!P[NDjZ(p_ްwI1<;MSW] Hh((J98v_#8~AOk&ހ@@'U~18~Os""-bm獏ch\ڼSuzzn[-(F;bّyD;:yj*.LJ&a0H(:(k(i/z%UCӏxCOUU9 SƧwp8գǑy|wA60p`OVǧnh1>`?^`AdF`"{nX_̬c>n2ۘ{\5۶՛O>ϕk2r ƍ_2f?ڲ ljn ykppT4huI$IѱjNJBR!zWd 4lhT*NWLe[(K8]&!7{Ѓ hT?%to !ѐMTkWuNB*]SͻM21,6뫽so*.(HR~Ȁ$Rp*z ZQ7YpRYϋ{<n/8~LGZN]UUÁ~'c`ՋdY qP)Z|iM>odcЋOm)4<5_uNwgi1\|=6uUԔ3cV$sm7sɥsxwٲe+g'''7r0 \&D. NE*YDVVVߚ٤09ytќ~KD|5tUG4Uts"]еup`\;׏A 5@/IH m֏හL|_ƩvzYz74]QXjº1?Nǣtv9tzxO f#66ł9I^ݠ~Ϗ&|}^dYZV#!:h'~KXֺyuja8AQ$%Lmpnyuy?)(i>N'{9l昰 tzۃ/X]c|.\߯ߠn9d% ޺kΟ};v{*_~}Ɛ|l?}L3jgpY W24$ˋ򗫇b6ʤě?0 kcļ"p3fTٶ`'wMFNvvZVݻwkc=EQ$zh$W\IҘB. ]P EQQeIX}rZ c:7%x<^~ M+Cuu558/^)7xn[n(gWCj|աv{|N3f ӫ?^cy2bP\/LX-vqo%=[ç3ZG9&g㨮6]]duYŽ۸`^$აNHBH!$!|B !Bl SqmMޥݕ|%KdK,Ӕe:;\r%K}]rssyz|p7d?† sNzRE]|2ܻ<u]}7ZEnbac0zɑБ<]w_rssQ?Cb,XL`<]tn!󎷫zONK6~EBF ď 55P\\׉Ug^NNeJV4yQ#=~2Y~v\|5W}Due%M-.PDz&08HюL=ekX$PzߡoFo^L;y%g u4;.&3Վjl6b0A $ @@z}x></ހFEѠhB!4 W>%oׄy };3ycޢlV+'R`;Ur>=!),$"C $!i4hNy.X"#A:NA) A9$G(E^Ͼ1'M:Y4DŽeTUXj--m `{*38Z f#Ȅ] 7؅,RHQ;+wxk?g,nf%2%֊`hhGӋNaۺ=ʈ5?ּ)=OޫfPXS’)1$ٙz4,f~vgzg-q7FCvvwEӈPӧp!矯ph.W8B;v]o/l6Oi祗^ )|Wocy`j^xA@C(MiY^\PI$=9;Xnnnf۶m>; s077cX6tf4?~|k1]q$E7Q#J;1_8Շx8'0Gd.½h|1ڎPܬC J$N: ^OgJf ?# &#J(HEDQ@#ItZdE]K",w2~4>f Z4Egd*Dh$pVԆ7kmAH" a #A2⑅QFJxk#E[OY9KK:>OSĘzWhy\q\>`~FRR8x:7,曟p^o&:: F۾/ƪ*[;y 6lan._M}+x'{K,0F+q?u򿿢Yˢ vm1dkѰtj,0VKxye770+눖I9deev:{u(55DDy>y}?'x5551g~?V旿)&U> Y,YhDyь{7׋\yeRD߾8B8H_u=-ߏ'z ($IMfD_/`ԩ8_\}XV} bcc;1ᰯyyy/_V;9|0,2*(!ֹюqZt]uG)̞iǘ|/,,lvzjmd6Q^^l妛nbÆ|u;PLv#%MFԯ72@oDa יo޼cLYI_#"" jIDNJ(m%"%Izj& F pװ}Z{S^.1c $qQV^xJyu=!yL t:rqDiȲL x_+ c4ZDNF 9SdgWW_k2VLם%?\A e'`O0ৼ97̘G#gY$Kqh?O@:Ec{HJbٲiڵ@EUZ ddı|_r~7رϝw.㫯qאV@Zχ xUrO\z#= ш׷sg%UUF7ZT,EL&s `u$ąvIJGq8_1.أ.J$(۲# Zšm-|ݐ=3sN~4hmZE9Њo[ªUimm壏>+ڿsLLԈMjͭ?B,aZ.ckZZ~?,c jϷآO;W`ߞ܂ :"IazCh}ٜ}ߧNJaaa{|.ߺ\2eJ}߿= C_haNug7RZmĝ_#Aqаcv+ڸ wC#)ϑ޽7Wgߞ/@5sef"L&#&Ek>`/2 x@LD'n X<&j'݉zgw Y8;v{Wsw3} &2TzP$a „@h7\OGQw~ (rM 9k!zfjN '2@@ _QQB(2ur6*PBŨł,{'4Z]}C v C4cwϴ 'LyiڣJEY\q4ٱy|T;X;+0r\fϞAV8N36l(Fp9\we$$ ]r-p-P^^MKΝh:.,45o̦IEEMh"70 /\ti46UpǷ @ i,ꚃ^bSp` Y3(v{t!-WO2?x>VAeXv--N֭#5yp|p~^XW]uV`Ŋ֣$L̙œOy3?m?ٳ~xX[n6g@s,-x^^/rF%bc٬-3nEŖGZg-8&cw%&+Q@8!|)1!M_=m]@BB/0.'|,e\t8\zWޓI`r= }|~;9O_<~0z 9`K"e,Zxg,~7A5(u*65k6S^iD^-LPVH27'h5"-Jn[9#Rٻee444 KԆtRFJJ2gWrEl޼8vټy+{6輸!g좗|'ߏ‚ѼBo3_~:b4%V:3ԗ41DFvh4:iit..wEuu57Էvgu]w݀c/^]@ 磮vffCQ<k~Ąi0E5D#!Pd2ы>vrwS8Mx[`0!hաُW`PG< 7n>&muy*tirRSIKF{^f&ր)XoW%t/}Kۯ11;D@@G,ZOO~= 6MЈ`V?V__/#] LBQ))I|dfy *N>{III$IBÚ51a8D'Xy5Mˁ.rTĤ%G}P:\DINX\戰PTUR+Ʋr0@U;|Ʀ:-e帜w}x^Z3hƭĞML+R6/E^œ}Af:)g׬YCssqeX={1_R\{kV f=~FLjhW_4/P1IcB^;k =* QBŰ#%%ˮP}I yW (pevn')!s@jjrym]vSSù`< S IDAT'9O?$Q6Dhȴyn<`C=rPf~)hĔ}%RYx͘bSI޽E̜9}q触.EE޹w<˛&]̾@y(@6aYg [3 IILO2|ȽH}}}+{#ݯA Vw|_UŸeSaREmج6'D5"HV<?Ӗ_G uPICkb6{!UUPd=$J7dӻ+9R"?|'HVT/e̞N]]#̙$'ާAjRoWt'|9g%/WRZSB>ө*nO2_:zn@;Q~ps C-zw(**aժq)r".ZE-;BpvbHD~kZQyᅿ/~׈ȢE 喛0 wt}v^oc6n Q[[>SLN.SWWNDD9˖-/[o_|ZkΨ;CϦyp1-=~ݣvcQWTBXehqMDKtxEȉƞf:-SBdlr`QXxx?#Iw~No}233ٴi7|mӔ$~/z.mb%2rgDL&쥥"Q#wۅK/|i_X_X2/%Y\Nd*@:"(/s ^>;$ ޫYexoԜ H$" d|>VDadTPqB#i$@0H];>|9Ӳ II $%% Kڕ60qQ# A˲BMi#p3)v۷I>rMd߃^4N~fU1##7Ψ҉ΤlK\I]~&lQfcpwWu;Y-oÿlٹN71q,rq1==\KH}z,p=t8*\.dYf֭\KOOg'W15k>Kw'3nl/?VJCgC|_Gh6gedhrnf݃. %`7̻BuZgω3! m.^uqD_QoY}*37o֭ᦛ"(\u񿹖Wʸ+j jjRV߀!84b?D?I~o+m}~1 Dр=JeЅZj $_1NN7of}a?rvR杍.>mD߾f6o#.ĤIaDGhTүB]|yĭcMjR+[HW>\Ç/n֑_Gy?|9zw[/x-F>ZB|rt(Zr}U 2,@~$E@rT6al݃ȯk*Θ3=@~u$EviP::J?YAE7D"}֏S< ;p'*(y1O0;ib gٲ%^gҤ(XcZ;ݿ~eqUCRvȄQ;tc8JwR+ yO{zn?h&u_DZ H c]N+_s]>Wlc򴉽lswS{YZOO*TP10>.^{/SG%#׵⣕iuz:2anIW m4*3Dpk?"L=ҧ *f|B+>.t+2SLcim!-jp#hP!5> _7˹!*"~9CkbDyy)oCJU!!jdʕxG%%ڵݻw{nٳg{a߾}477y:"IhuZƌ+Ř-tտkms֮ߕdDw[E4:XtzM<5k g5nVn_NŚbN&lɗi(Gڋ# h#Qg9 e۶8ara˖,]:! | *H"l( ٟ7o< } ҟ?w߆ 6f}$0Q֎fO]Wykٽr%!)X3OI2cLQQNv>M0 dV6 2Q,kʐ֋nS1>fRj ~6Iy kك$vc#a~-+|>Aʊbsmj%hG.~w1.mX,i GЙ\yR$&DAƌC}}XşAA-Gށ)2hn-69#0)ϧw@}F@B-et:Q%z֬d߾f|>d DzhQ,iiVfʯB@@fϞ&vhdp?_?I,2^m_5V XDg KA< Bh z$ଖ4 Q0DJHx]XC?@kD("2^%ZH[ `'M jRu 5uˆ杽?b i_KlmAkFw̥(֭۱٬L6p}A 1LM_Ω9'=2ySZZʟ^<#NkoMM>:/6ҬDDDTDVL̜ɗ_VUdZ/e- >*Thi{e!n5TJG ~ȭ4SUAxxZ * Y'2=us Yz}U>8m~(+Jٳp=ۙ>=IHL4cjU$AF YYvƎ53{v}VźuUN֯a1̛MB^R+N #^kBF IR'UPB3 OkkCGx$?mɾ DDx4֭bÆZƎ53yr3gF2~h#zb2qb))΍bݺ*;((haÆZ9g fE2f N]QBȀ,+TTQQцժ%1ьVQ*TPBhF0qx()qq@ :ihxq,^ݮSɂáK5+{ͭcFJK]8̧VcgƌnrM˓Qt̘IzsCN6leÆ6-K>=hjBS_Es$ *TP1:ɽCi>즺ڃGQfGO5YCz$ ESZbzlc6la:LLLF\ QR@̛CvcXMjY;=;sÔ)ᄇUY*T2)*rɤPB *Norȱ姮KI'NJKTVrPICtHMigpViWnhi@V$<\OX,;Ǿ}lRǎ ))q駕dfڙ1#SIOp I2xq,;غ55k*ض>(cz:+K?ށáSbTPq襨ȉF#jbѪB *Tfh߹om P_塞MQ(/wte0$"#LFZ bb l:  F8-kF[ö;KJob(vkW#uD^^=yy ƆVlf̈d„0LX,Zugy8N#g"2Ial\ڵ;"7 cX8,;V%*T8)Py}EKJU=B *Te_P[롸IQ.*+p: zHdq>%˜1r?ZhntFak7űeK=yyE\ Շ$)_ Wdh44TK_c2ԊQB *F_hq[өYOsK/(  Cŏnb1|A)(bʔI\~ݻB#zH+nw8nw$ #zZ=&S#K-&S#ZmPvb vACKK,^ZNFeTP1x(CDjŨPB @0!z-x`PH$Z - Nt:7䣭-sn?!N5+Ǯ"L8Cy;N@ F!6V&>^&"BdIB%^/TW <9hf II26tU<}C-3 ֢…ec*C*Nö 22LgJS{N7inhkAlV"#!2Rndŝh'k9FSeHi6AFFL)w˩( r[V8Laa346zik v8IKag8;cZc6kQԻs(A ИVW K+lZrrZYx -l\˖-5;ì__ErS#93qU~C0Gmg>͛kY0̙'0ujQr*Zv ].2Vt24l #]~|x d< MM>**ܔؿ{(/w2$EرBrrHH0il֠KȽ,+G o_ՍS>&.6Ȕ)\|Xٴٷ={dg;5+)S"HIbԐMCQ2dILJ['eKw??%K81CwƄ;U}C-ֆZjEl*c m3ddڏτr2>ZZTURR":䢮A)),GIL px{uP@jՒi'%1&V(kX0sύ'+ˎŢ}jM>ݔbjIIӉ2B%jP(/?āPR⤶փ@C;qqFdet0vp=V^lkVhUPB>|!g55m:fǎ ֯RW'[qbb$$r0n311ȽFG~O0%,$$5+5[Ǟ=l^O^^=wl0qbcǚ/))KKv^"=JB#*֬)[j9'EbIJJ }ee")){u~f0ϟN)߉<7Zds@3Oc̈́Mj;̚EVHàHhIɞQ_G l;cǚ=;/O+ط[ظŋ8h '^__YNs|jLzL{RR1{;_9 ^hF23mX,C^ع{jOtqdP_Dƺ6>1t229弧cu7S9:t7á[{OSS㡬Mq={(.vR]-N'#)ɈTp`0cguGtUB;C3HLSùؼ(* ƍ1kVӧGdj۩_ouR\ƑvX,&O#-QYS֓ė_Vqq̙ML7Iy i8 ڟ<\c yV277ΎV;JT?x\%*9:K]T>]槧뫾O~۽c;r2.W(^YYkw),tRSӆ150Az|jaH|>_ѓtUH!)iiV̝EI;ؼ{ذ:,LƌdgBLw[Nhwӎ^oi/?SV3#HO`A4~Z5lPC~~fհdM :p*DSS'tE{=woڦ/:?2A~ m=~cO@O%j!xAZhh2n8#I'e{{6nm濞{sͣKj"m1u(HaQ~#o0:é 7Fj[ ݻ칀^zb5S\$70`Zq:IM%-JZ,bcCfV+Pp IDATWWO^^^.p9OTv\INKgh"QQ"#L`8m"7m(-uQPš5Y>=3"IOpt,= )x &!z͋!;YgEzu9YSm̞Ź1yr8z$tW{Zo4`hEo&'HQ@@!%BX槯o?T1`|_6.詮}$um_RCrFFz[Pz& ^ ۹g),trpimm!%e,cƘذ=G=ftL4oM?*9QwO2 $3FfώM^^۶Lk:v'Lpolrpى?xpW&uMmw0<<^>klR̝;o))1G?޽G|ai}"c•d~UN@ON+Wqc]ܽ]''Os?uz99:nP<V;۩ii***LT˳_GV2پ.Ɨbo.>Rha3,G񶿥w8%0>bp07w-18`0l HE#z23wb4P46~({~8PyMt,)iSOeg\844w(O?X' D&F0h2#˷__ a#E;w$"1132Gc8mmn:;8Qlv0RVfHAA,%hVWo^NUJ%'33˖tܿ5 45SW7SSӽzL&2lbQgJv8uj7GuO=seS]mlVb_ 01|0mmV)aC!EY-C~c}p==>ZZ471< #hl ()1R\l 'G٬BQ$M?N} =Yu.ˏ\.dRa2(.6o_&qMssW8ӱiS:۶YI#'GNXU/' L-<ƍ\ĉ~uܺ5ʾ}ߟAeQ)VN+DGBFY1 `JQ 2\.Nuu#ttx GX6lH<,?+K;-Jٲ7o:YZr/fWJNFMƍi<|ܺ5ݻ.zz|{8ujr;vؼ92#5|.FС6lH…a>l7~. s`fR\l@[bf_ 0c2(,4,~}n;_F%B(^o >Z[=Սr [F4hTBc6SRb4K796-|\Li!$,ԯ@^ݻm7F}{{X[kaӦt  - NH(-5ev+.LN/׮98p ݻŎT]zu Fr)(Г e)򗰸*cg{LJCC\yrz-[2(*R\l@nnlYV;j.#ᧅF<ԯȁzuk[\tuy9uj )*2um,TT5" MٶC\0L]MM\0sek-j҉~!C @ݮ$lH ľ(K F#8Azzb3mmIq?x`0J%'=]ojw ֤~z}ÁO-}`6Ö-z**4z{ KTrf%յzJJ1󓟴P  /^)!kk78 %"0tup8ǥKCKE),)a2IT;ʂ;46* q|ϏR]!??rh"뗕CIN9* p89y~R uf-ZTΟ$A4 2dp88>pJh$l?QV4 NBa;w`ῄNN^|%5R/;EQ$}}n̙N^k:6n䩧 ؽ;*vFD~p8А+WzxF>N{;0$| ‰8tu6sE&0M>4Yb PݬYv~1W).N1p$%vu1Bo==8q:a 9f4 dP\l'?߂b@ST~_O' AR_$YFd2FJ~V'׮rl'wrB/vg6ع3tL&5 S*8r'g;8vW{qL'/PʫVS[MzV}(,#^oa&&"[6BuDlY~@ a7==tt頳訇`0R)`P\lFI rsӱZ T*q I2b4Mʽz{Dͬ`0`ٲ%W^!.]ҥnn|FE={ٿ 21ՊU*iod|Ξn*r6mlֈ@202⣥eJΆ LjQ(@}$"11뤻;&;:Fj(+ˤN^^:V^Z^TcZJdA'\x1[YN Iϧ]w79}7A}'"gJB!J<&Ri(QPƞ=8M#G*y lDyLXY8t.U]}5;rZe\.}a"(`ctwNP(`Аi&77 JJbv 16s/V ؟Vհ:tT] gKD^(y+Wz8{vΝ뤴<͏\?VM4*-[xj),Lb>o!ZZF9s^J)/өVWO2OuNrwpQX~)~W]_-\εT/snpenw!7}}N:;d ,X)*Q\l'7ׂfhԠѨ T!q@EE5ޙ'GVc";ȓOܿ?Ĺs;E[$55.ΞʆͦO󫥃uk6V/&Nhƍ~ԩ6gJ((0'%)n\8^o~,֏@ H)X=~NAR_G_aZ[rpxHjv#JK3()ɠȆn`РRB/ؙo Iw ]v4I0%k&{8|jQ3If׮7\ۿ!O>3ϔm[i ó`:XL&dҰkW>UUv^|ΟA>_bLTl3۶j #󵛅d2K~%._g?O{OlY'm 񅏯>vl}5S\ z'Q~px7Ã;A4*өMY(,QZ1,߈ɤ3!!*L^0 ?#^O¹ϔh4Jmm6_IzpB14\QUecϞzHG&SFgߺYM\ժ"6ngK8v3g:._bf|23 sY^9-H'r﹞ID뫷w1\A~ѣ(Uw0K!ѲMf,&rMUe888UB=ѨΝj>3gioc>CCx<@5clF),Q^Eq X/bR9rJws9x%+٧Ȁ3dcb{_-Ο>nƍ~~[o.׮M#ITr*gjk{W{yb^~]F,g6xY}KD})D7.+X6̾:8OrĞT1I&ho O>8nwhTBUa6k)*qiBq f6rT BKzB.6r4-0/f^z._…nꆁ2^,%%ܙ8B^^RNn#G*ٺ5g;yq}=Μr='=]+~y̴d>|O*^{g]cczC+wDV%z]gbQ`0s?/.aʊ)-͠6L3_/o>I dG"˰MbӮ(3cb׮|ܺϿ_(.F==W #IʨT 1gO>gt\w{L98||J^3ïU/how@äiּ,Η,ZLDw!ɴP(dh˭[ntuŎ-zzh4*\.oNiidg1utĽQq!ױOV2ӲRc++mOo].y|xlۖhHRt]t iޝ4qFo}Sx* 7^Zwo[Ꝩm$rByB2K5;Ng&Ik ~V8]!EKr$`0=FkaH$Jh>,|kBz^J3z3-K ) dZxtDN57t2`)>ve,w#'g7G)V`?ǎ} ,FW]'Vd ybiltrO(nx#}2ϵ?ߥ*`IO' Z~W6h;Z:Y3{l۽$Is wlK_$(^oa/c47;hhyr JK3).+*[ ռfv$9H̉<#|l4Zt< c\Dž ]ܸσ|'_čZ05k~;PMmm6G_4G-ܸOFر#Gy&&Ÿ\e/]/مե~?RVf!7״z )D}b}Bә _b)ƞ˙dw!Q|##>zzik߾=@G 3@ Fc4)-PQac &&ڨ:f@נR)~}xS# B/jh)fqPIKӲyj;/\AS˗{&[8sR vwo!7ggZKe2ݻ󩮶 e?ȇp|w'mrg{O]0ѨDE-@ !FGiowqw&rlYSQaG̙233E ] V+6i`\W?Kzrf { d!{PUejŽ'w5"˰Zu8PƍKqq:&:Wkdd8t[srk{W{yb^~]~l]Gijr04䥠LUMHD"3>>Awr.ө$)b{r$I~/~QT 1ع6JJyZ[Gzg;uk3g:p4vc߾Bjk)(0c4~2Y,jk)+r@?I}}M8p]򨬴aSz{< H]Fi*;55v^{Wx6b2iPf}h"@,VP'B:xK)zBb[H:B?@#{%k6kPʱZuX:6nȑJ9w.e:Nlξ}ޝφ dfhvQQRUekpD Ǐ7QW7Ls%>W^(/NN1?^-u.~`6A~͛ɤaÆYt=*E-l(cOaFGiksR_?LC9iTVڐˇ9z%%_{M?Xifڣ/ P'b;Jrs:xwt:tP*ō>իܸǍ}󎑭[9ps)-M  jlɢ|A~͛ܿ?4gVq}Ãx+kVr\yMwn>(|3qzf$s0KP(B fl,@_ߣ3N?n&#vjj2QVf%7ĕ+sHcKZtVacI6zor||03.rXr^(Hde sJw04sT;z*vߖ-YU+?&;󨪲?ĉ-?ݻ<ʫVyye?+W{X+QC|eerr D-lhIH$D Ghi׍DD1{w>66n̠J~t-ZrZk_RU>2~ E~yfZZ?SY,˱na=5V5gO>_FN.]ꡥea}3yvΧFFagkKr EElܘϗrXNsd+׮rO2=T6j׹4%zz)(Zjj2HO +}$Ս /}{X~Nٰ!}vt-z B&^My_ Xebb w֝_s{Sl}wA&f5[y\ŋܽ;ȹs\Mnmrxn͡0 Y,#\ݮJٲ%CyΜrg-W*ٱ#]Dȵ fBb]$,>ZQ +}:DJLLx{j//zzqD`jձcG.551qʊ{!"++kijr͔ٖ.K奀 }Bud1)ddlݚÿW5>g.5Wl$7"+HYeθk D-lh>Mdhݻ(Հ 6 ~o~&._n<p&V X,:t:%J|Y}|u*UU[46J˄xKf|-$\\t.&mBoTܗ4߾}tuqZgvrFwr?q=[dvQRbl,8_!/8 җ6kW k}^~^*gӦ,L&uR=MVHM'nki!i_\hz6ux ʹKB!'-M˦MZ:TFc+Wz8{i:cG{iS& ժWA)OxF߾ʩSmJSUe`P , ~`Æ $I|##>]459azzq:Qj6mrԫSR[׫PbϽ@ X_b_ ,ع3/|[x˗{Ak&{cXerZ;EEi8Pĉ-?D]0͗6^y^(:+X޸㴵914lܘ6&/BQ N #44䠣訟j,;wQYRXݮ`PV+Vd@ b_&;뵂\.hTS]mϗ>ΝΟҥnڕfSXF$e!Ŏڲ%2 M|a 7osѣhΞ=h4l4FFFAKLṿϗrx'Np|wrd+ZEVAhlt).N''( E X~j OG9s,#47p(2V1x55v씖Z4`4{@ r/A/jF WRb0} kq绸u۷qIFc'jk7;?Jjjk7q1QCuMNNÇ#lh^n|PON =O'ҟ7h|/?q (Zɓr׿"j[ x^{o|/x,aaz E?#ȳ z{K+&=AII=Zm@!*IhTN$bbBK >aRkŽBA@y1h>T 0rydMB|| 'O⾮k`0FI7@ T1ƱZzM[p D`6;1tTry4$Kt>4f ˆÑk1V@D`5yP*CP%&D"JA @@k7 jDzރVC\:g`9H2dZ<Źsٿ=w#\wxyx IrqXL/@Ptn.\qӀq lΌɠ~ͱYu*L]сL*U[M` pdMGOOēO v:K8xpO6TdD|e*I;N G/w ;$ZɬŶxlX܇ñ~q2 -ᰊ>28V`LcY`% ùYXF8}pXHzfc8vJ#N>Z6ߕ$TV)-𻂤r=+[$QѨ`P3)ι j H,R`pwogjh~hJz\/SYͬAʊG[+k38~/YAR9ؕrb5D`pOlodt4>,9O2 Ih~>;9{5pZǏWt:bI4%"9MM>~kׄ,_\}R^ p9{<|>#>@@G8"#GQ(te=~~[=)'[1J1 IDATD dju`z.u )$%Z<fv8Dg2F31w߅ݮw&(q80{u~+#rr+G 6,"j֭"Ƕf*TLžI{ +X>{9l.$"ñe.tK&BDS3zϴiiʔVZ@ p挓 Zٷo7ϋ%A l㍷WSYK̕du{٬ }r{(,l6f'$]F[:;+5+Y \ECII}(9կ`p@4:K$B^>كxm%b0Å\ArwgD=$LI |_Q@!<4?V mQVFrr:Z0ݨ]%F"r<4z{KLrbIqkfrsIY*.ٛw˵o9w if_.PQDZzMSA tfyt'Bl+Wn'(c -늄oOGzFG=T!t:/<ן,m/uKg/Ha{_ /.^߯k_B4U%JD㏭$QrN'--6HVVM@j|?ϿFw~+}7#G~Gzzw۷xׯH?С/ub;7_XgKHDA Icl̂k&"IVO`0IKdr%=B.I(x̌fr٘СP1\LNEԷHDAoo1%Nj K$ Q`PĄ/T/ FgGP'|M.O\ܧJݬY 7P/RĆyry{nlrϽaqOt UYc|܂L&a{ihe*'n J2/<:oj|*/vÑ^yd9dRIO`pd|HX,#l n.^<\.`PC E.Bqq/'Q ~66s!U I:ևF3u^, Ѩ H6##:4?}h~F((`}Y{ !B`J&XP?GZ߈۝6-c/jcՁ3'jV Fq G=#־Fg tZZo]-?q?1E˟ IPDP*~*rZ@ O q/Xf#%2dfH>@ž%fgAF1]l|F-[ɠ~f&kYZmzi h&B\.VV0:B"Ѩ@@$@O5!%IN$MZB!C3Y?^+#pd12YEvvM=23{1Gj3B pXe&&RPBnnzG}`ɈoKjjk7a4E kf`+ I P_KWW;V+'7WMU'0PZbQʓjhQ::\:͛nz{'P*L޽ilb$3SZ-*{ }6/hEu#H}81e|zzFY4;cF7m9}z ɦp:+tƽ,h45's@)ϷOwoG`b_EW~/ $inZNk\cD}1nGK~(Wkm{w(U]ڃ0?n՗(vRYÛoÏ}c gӦ~󿠮Qh|$%裹lڔɓMn/̙vL(,&({ Fho!"0[) =;3s?$#TURV /5 IO#--}ff811zWUZebKku*_NOii7?T;Nvv$O=UhIL Ye ,ONαA(Pr&:y{}__O btTCfm\矷pBee\X_NXxNBB06%/47ov'Z;ffnijA3PSkĐbwW'I=:::F^ett H`ʊ //Hbb sD }b4ΝkGhٷ͛ qe~9b_iC;SRH{g!6J>Okn)wT P>ciIg˿_M~~YYsO}=ʙ3ͼ^'}v;3׭%//~OOeZ$7W\ʕ?p-yTUR_?뇙yX-uP}TwluvȾ}o`0j#HOdihnN222EG4@$7M[0:L& &!aF:J9?,N[Mtt M7>ũS\WQSLJ2F`Y)֬._>zzzbؿwܑBVV]y1 ̙KmwKJ:hdgGbwh4Ry5Hg(?G qoܹ*n%j#ӠF{7sPUxxx(/])[~ru{l&Fƙ3-*7}ְul3s{e? ؟{V7ibJjH7j 6Cg- ]"eJaf Sil`Wxpr.}Oٺ5 {wʃ1~rH===I.r A n-P:,?\!P F`bbo}]j`0^ttsj'Cۿ>.ǭƒI^^懟'7dbE2ڳC[-=;=mwީ2HM cϞ{,pE ~zzN7*˝5o--f^|UFF)*O{xl:&f6vHO`=;K47VC걝t**zRSCIJ +O!&'`]9[ѐO!JKxIl7 ʸrޯÜ1<4̙fƧ6R]W'aio^.:w_zWl,˿;vqc7%%=Zl/c6lgD*+{P|n,v,2|p=/Y`?ix h4apF>*S`vu0LS]״iF&yڙWVi#h4@+>{ّk?x~E+$X0U^:629gD~z ;w}|ADIXԔ|zVZjjJmd--[CR-[hbg{=g5Nurc0h5-xy /~q'%%>MOׯ=zndrRcڵ1deEEn;' //ƖGβaڊג-VJ}a2T!@[ޫ&***Gs)(Ev6$Ñvw9gu,vi`kXE:C͝2#fNpON;Rطo ϷquJJ:`3an%[Y>pBB|n~;۞2䤞~vJ磏j))"6rNHF%y:>ӟ&%%?%vw)&hk{~}ATnj((&##\ 99$'荷ϡ]L{DP*lJݝۊ.][m'==mےټ9hbc{vד< ))3 GQTTMUU/g9v{䮻K2 Dvv䍽ׂ;0}STURUKsϜ~KR/6eIn0"#(S+b4n|j2^(ҥv|x\yf-J[#"b6ApE|}=IJ !99 𦼼NNjܹ6jkgf~5kپ=}-,~R f͚hf>Grnyl#||V1jkQFHt]4 S_Oyy׮u4H_SST*!55P ˋ2? q/Vuߔsb;T*>lڔ@vv$wޙNQQGsL3ee>\Z#UcDcmmDFqcﵰl^odrR$mmPVMEE tw1>>Z",̏22ʊ@ --@BC}J$a;g]7rl+I|۷ "AXxyhg~8nNl[O>''G֭lܘVF`'<n׃8rr 5՗0/||T6J&)-a**3lLjAAjnhVu|[&1}}tthm2IWӌ1LzIl>Cx'AAj_455Kt)qA8B IDATeAǑ#Enj ###S qJ''O6qb;47r4Ql͉deEk{NOk0Ǐ_СJ.^lxfOvG<4^5cc_;Rdb420/BIL &//5kf>Lh/^^>mSF$g4S\\Jq0;3x晵lߞLx#G\}wu/ʤ("KJJw!1Lʫ#-V|,4v栽>Νk̙ʺFNj"%% ٶ-5kIL !0r|Ogƍ ;GrJr',+&m 344VOBB%##:Ǹ~}>˻쥭me~~^DDn],Zm99È&2ҟq/y&ʣ~}ޫfkwo99K.QT*F"nK"VHtt˞=vqL O7SWOmm?~XVm%u|V;fiHI edj쥶v3HOwwFFd __iLYq?EW(CqZ55}088h[Mx99(,|d||~y%^ou=[o'LNٲ%} 7҈z(?ߠ 9cg) +iZ܅ՁRa)f?JE`&n=~.\h[rK:tkcSذ!ĐYʿkcHK ;RZ厛|loO!99ġd:[cAVVRhbz4_=ψ{N'[Kn\ $%̽5M&Sʲ#-&ΪaZ {I%9/*  1[cQPzׯWq+zV%II_\d1]jd(YWz: T= k_0ݻTVrl+'O6QQCQQōdgGqc<[&0˦M dgGsgEEU=͔vsp џL\\g,Ѓޫ}?23)vv}O8SQCMM--CM򚙹_66h23IL A' f狯ŶNw θ<8q7޸õLLY&U񅖹B_eMM֨N +Ibblڔ7ŋ9mtrR;SyCʹsꋧǗ:*drs5ܙpuʕmK桇ٸ1}eOJK`ÆxRRBeY)&hk+W:9s?9GVVA^^Ch eD{P /sZ|9ɟu"66m-3ωe0s;QVsf;P-=k]{g5[ |,ٯ`ʊg@ʺF`=w ff׬&!!&}]9tN?oM>OlOh/*m_**z0M|ɛh4.덌O300IKvQUKK0==cLL <܏(j#j#o~>(oo[Z8=uM ?ו]ı;1>>MII'oU lN ٷo ޛI\\0mSYqe[9Wd ,OMͣ|IER7sP[/DTpFGCp; յx'& 4AA8u_>Dc U͉@*#[ˁ/2<%1q3s?>=deK&Fl[hhߋᦸoonjkihwij!!ddI^^3>2ҟ os.T>Pjyp*9;sJhs#GrrfϞ\+dÆxg,j+їbVϥ)֑lgA4bjIKi0lkZ-xx dC7r)wg>ի?ٳlْ000ApM&%%(3*A_/g'\҉Vkw:o]:;n?p2=;s?9ghh[7?🨭#99n֛Lu68s?{^ee/55}5* ;; ّDh{l=mRL8LM㷿-yHx"={rIK tn7~AXb[; u̞Ngo1uk; }Kxx0NO55}l߾/zO>16%TUc"O>/7ev~bz(az- Juux{ΎdT+䤞46R^MYY7337Ľ'&<-?#csxaaz_F{v~cq2L Lrt3oq'RX>_wm[^7 EԔ(.--vH;gUuqv's2`KyHTT DIl(TW>f۶dnMDD oW_=Ƒ#u7AQQ5[$2=mvg`0)*:VAzz8F^fl4 q#L"&&Hrr"'-mf~@FO<=sxζ^?={h",зdKmCh_ sP%]9$&DGwr=_p]lY/; E+deҽ+kxyn!7l]Gw(2G곽6e>*x𰎆Ξmq_gδp\m0>n],!ØL9ʮ]~5B`z~Oٱ#ݻtw25߽)սŒBRRȂ8\& A**z(-&1Lxvm Zm$"HJ !4tv^%AD=TńM鸻s[3gy^oۓy5ؑŋ|E+Q\9.۷u ,eUUE ,AzX/yyvRV9wedqc<ݖDaa411<9yC*9*[t/hBC}z3YY7*tmfgGFe>g>>Bo8||< 7WC^^YYdfJX/^2s/n`ujFUU/qqAH_8SS|}=YFNN$99È oo{AX%&G8rQRIPO>YSOfM %AľA7[MLL zk,f׮uqdϷ0~ Qlۖƍ&&r*壏j''GO b.S;3 NB9/##PoOq9u˗;8{sڈb8n=oO[8yO>…vʺ9vԲ}{ II!x{;>?66EMM35iL&z =46Έ^ih)==gVKGNn̷ˆ //1Mtwqh=U.^l'8؇G'ٸ1 I(A+.#>>|{%99(+Tр][@`` iCCz_|qZ[uLL .·RS6QY9ƵkM&''͛ $" OOnK$/Owo4Sכ錌흦]G[֙LOPU">އ$|&4 <=U"A`j드8114'!;ذ!Z 9vS:;xNSSϿDOW]w=(,8rh֍`02::EK0.su.^lu!bb YƍilAii7ϷQR2Fk+tw{[nI **OOh4 wxr۹LEDd`0111$S]=3{4,rR@ors#̌ ??HRSC$(Ob͛ dwcë\8Zky5lޜ`l#G\}wu/ʤ("KJJwaC&W^y={$Aڃ_BB|ʊ`׮tz9u?oÇkFCʊ`4gN?t/heǎTx ㈈X}}jHI ]6LNe~n.C3Cbb07geEDp>>jj) e߮up<&==K Kb3* Ѩ[mm3 . bbx<^f.\hA{ %>>(z{ink9̝ws}YFc4Z>uttt:=DE8$'ikqcll AA>NVVZ̞@BB|  b2ĉ&{o&O=Um%#_aeYLT*E?ѹYgJu:] FaU*OJRerلa99rsca 8}N %::i׹LٺUGP͸5Fee~~^]Cp&ɢ1LM}wByy55}tu2::Fn\͍@"`LuI:27m;8Vb©d_\h;ir<IJ aϞ\͛o^رL&~T""2/6B_e945U~^RRWB@V[yy ;J'!iS-%~|Apq2P-%ǴeՑΌ \:WNvm9t[{{oY%SK{`.^##3z{g/ߺyOI^[z1dXx)m=EC+…o1668P֯ &&'B@a{ˍ1AH#O}}ſ]I`+щU:bq4^:{I?Ԍ\w9 :Es1+mLhoUʁt?#..Ht kv͸puVOXDb ,eٵ%a gjm]Y䭖OO.]j6ӟ\ {c6mJ(a{_Eѣgm횥+P♥ -6g Bgm1eUN=+Ow?r?֢ٳ'd`波R^AX ,}Jt-3ש=pA|1אسϒ8SUmW{f{JJ2J(]AD2~{w_RmEX|51jfQ@FƟ-rKW__j0|j롣+deҽ+6*J?_N- s btdh)=a_ Rϝ=r"ÑbK;.&==c?~7޸_022gl-BC}]}U r^]o~Y/ .KgZAApI TWN%--Ccy|9 FXj IDAT奖AľzAY( LpDoqS7xٵv[]"Oa)_vuYz 07~/wV+)ޫ5F_СJFc '+ʞ=т քYkw^qv!RGL~%h;Y/C3rb;mEEQP޽w_& P =Y:JhT_kk n/-~kKm`sDDy)|t$֞7w~;e#q%JYCpML&]]>= /k%O9y5$'a6_U0K ,#JŚMn;#쮒']V*7KY[Fnnߖl ۑOٛܶ7=MʆȀm RHGɤZM{o6L&LM2za?Cf0m[]U\ha~RRUKf麽*TYaks0,wؖ#/;~➣J\xI {m_I[{ke؞ek{rŭ0Er)W37yk9橧 ٲ%P?6{'[AAA75U~zrrMM"U1"1x[쇶SN6PS_oW4HJJ(֩};xzzH[-3ωeEs09?knܻ2oK8̥K[x?{](=WY1՞n"]޾{ }GXrvp16굉agδ_P\Νi۷6Bݥr_fh/ }ApGccS9nqG X[88ꯥYaKfc9PVJ'ɝl/r"`mJ44 PTTe̞=rbn iuCٻvGR:=?ۑwm犝$-uOg3m{cag϶Wt:[$쳷cG*~6Ob(c9/4#eL%ח%gJX޲7 Pa1m=K+aQUKd?{'R@~~6s% ڮYZ?[fž% %=;6) ,Ɩ8"Y6w9NywFGt*:ulܘOpDGaA`e=Y/tC1/#ګ_f?{D+)%ϖJC4tge.n"(]w Ö-*E%qQfsηʟq2̊*eچ+mFa /s`*Ȓ=K-gOX۞pX{Y鱐c1oG½ 5t$'soo,v}~3م ouOɴ{-eu$-޲P뇭6E)bK[KgDW(G65.^l' 㩧 Y.@o޾*Q\_0wپKe ,د,# :lEBbɚh$@- 9[nGÚ5>DYPBbn=yhKX{ˋg;cKYV~@SVo~SFQQ]]ch۷ݻ$&V{HB AXb}q`*c__wsE-n̟5.[Žx)JR-uBPG%V& K8{//5wkyBlI$8GJAľ 83"H^6X`y(r{åNk{ʂLMw*hn"++硇IK Sf/#}Au\w ;[ܰ6so[ޱ'Hvo9ii [sG?~7޸ʩSxx yf-ݖDH/*bqE avb_ʁn~N*lqܳsr=`O+į-؛ܴuŞx, Ճ^oawީ7)Ay\}46//$ ?0g7wINN%*x)))U4`k(9$Kr-DݪX!Lp(u Jb8qUU;ϕ+#&ع3@2/pc>_455Kt)]Ư4w ȑU[7VsE'fYl8Ww6ᇵ|5ƈ Gry|rr4x{i\+~~הIC%PD엔|[X+ʞ=т + ^&^.up5cxXdž ۷;L'::@fAb3* Ѩ[mm3  +Dg(Wzx"} Y.??/I(A ayO?*<7,sǑx8R_p*RApE[cmd2)f3lӔvs`EEUSP޽w_& KgԾZ*C b?))Kѝf/X8 +ӹAʾ |va0LttpX_6س'^qzvWsK'’*t/))+~AABS_?AqYgx"&%%OOe AX(juM&M:5KRnsf1?NhYAggno͗g\a__~W~%jJM,sm|&1yN~+OC^GFF I?Rp2~s}#-R+%a)L.!sliqV..ԱYSϔJsOq_OɉX7%O\fpobkbچź?5e?QZ ?Ϟ=9wu طlh(#55Kʜ7^m~X{bR];6xUao2gϾ7^7箵fX b?M#[6-[.[޵V睥AK7bK\E,INl7rDj[n ;dBC}]vXvpWsij7n /ҽ\s!em .[$Ƭ0[#uV?M#GfnPd!- f[fk~%e{D^gg g[ݟ60Pe44 £=dv<^}4_ bߒ1rGeTTA:`I-5 u Z,8& 3[ 3ʆR+{DR[S344ə3-U>:oOgֲ}{ /~"B_A7vdY 8'%,\4成w'@RF;R`i*|DEoitAV+I:}Y;$őT,Z{JٹYLA/,^L+4uUָ8C6gS$뷥rg^?m566ͅ mO>gll-[ٻ]҉ C"\{hBe\?Rv+deҽ+kxwl %#5"|Dwx/*%m\}e?{ĝ-;c-nښyKa7Ћ[js[qGp3oDK_evOwozE*q0+O3 }ōPUe1, b_H\◽*=hm%wJ[hVM~;^ܑONǧr*kֱfM O>Yg ž JD7ښNψ< Dg(|Rϛo^ҥBC}y||ub A/( H=[xݮ+ {09ڵ.~R ;;^}eZ! % "AAWh4;Χ6ޛGvy޿JRUvl cc 6Dχa"'zb?3vODw 3=26؅n6x͵/M=np%%TZ_BRsy9ot uf|:>$a(A,(u +I  "ѣ}'o…,77/o _5פ1M ,is~uΝ;سI)!AnH /3C)E6^ ߟ3r5]:ڂP>-|32^[DbasK9 ȸضlj<|gK\sM3޻ ,cAыXRϗJeV<7b߾|nd뙢gW ZA y饳|yųh|W㦛XNAͲi%;dAA=;OGrx?V5pr[ټPȐA?>Ws73We& o~' OzX_&ʟL`t^sV_\2дoHO"K5#jFUx ZϷߋ5} ,lFn|_qB_8~eU| WXRΒc2A_f+gywWoyg Ӟ +  h5w3E2[3mSǻoשxU-ПRz\,:੧Ux;x ,_%9" bX kr=iS0ZCLMߍ©~6 ngNpTTD"sDubeT[H^i{f}{X~&+ #?<]$a߀Re+}|_Q..HRv ,=c jMTdjO%㥱-rZ!'{ug:y2QOZRlNVg-S}Wf ]mn#jL:w\v9xL__mZ7fwݵ+gwlY&tK?_m<套βiS3jb1K* wnYik oS=:3SML=DZ3[A=R/f3j0RftZy*M9Iۻxޫf纯PJ[dm{ʃ^LJ>d2,# q˜Կ=sfxc}v\&b_?u~*xҀz;qr3_lblufVC핶w!sU*J{O{a.])LS:0!y≣_H\i1ubxzKEdϗ8I+mBn>/_{+瞭|ٲe䘲Zlmฐ޿k2_Z)ɓ'oS7m$}Ab7D",\ĥOAr^}?|={Nb7ݴ[nYGkkL6Xhݶy9VJ/mg͚d ,/qqb>7 tq]gy<O?}G9ȁݴƹm#brq.wcYܳo ,Ab``BXqAaP(ؼ%~CP>n}VkcIr ,&xZ:` W߹ַ3(n_On.ҰP'OoՕ6p㍊x\N/ IDATW¹sGٕ`hεD!^O,RJ{ur.Z4VXP+sXOv8Kb!_IAlW_~?*Z鈴2XضǩSgG34TfFq ו-׮;fmidjtkms9kKxgXt5zz<Z0Vk}0F?^:Z.Zx"Ǜ|jQvI& <ܹ!x(?|'hn6%ۿ@8l<ΩG]~YXq.IՕ񓟼o~s|&19v|Un-I?s%fZܽj ּ5}*q]75.~9tx?~9E.WqۿWk\0m|ȳ]J)˼z'?~{OՕgg+T?ͫ^QDu\sM:bRDOL,5zl \s`yӧ3$!s3ݷ}lM7M=?9}:7nXN,& %='LRAG]e~+ W-dbjkF (®DDm-Ꮥ/c=kO5zxWFtx ?ռO/5.O?}LĎuXDy-ݻpt}'vm=.cDA:ZղvKy ]`a|EdbA6UQ7wM?2Lt30(ȏZw*y7}Kr<)_+Z_˃^Ǎ7.'~s)mf+Wy }?C.Waݺ4w޹̶mÞ, vh{ص%.\rX_nma4=[T;\g_w)5'0я-;S+fNC㊮z35Y^g+-p˺=gN?(.3 <~ief*Geht ?'8Jooq&Vjȳ,ie,P|*<gNp|(_vo7޸|S&t]⮻vaC/ٳ$Oopx?XM2 ,%?zZp7P}2Z7G:3͗za62륔\c?^:X]g^= jyt2=*~Sv>p={|de]T뾚JזNONO_L5qtg=СB!o{ʧ?} 'Vl`&~ =w|;MX0/ bcoiw}[578Eq-q% nGΉ? 1b#Su` ʥZߣԣ<*3HcZR?]a;ڝy*n>`6ÞzRKGicq ykͬ_߄i3nN_#k_1cNG=;]oߞǶ=li_?c011u6lhY.o#GzwruB/R={>?z%)AI]ǻfyg"jW-O%Ӊ{+=sYO&lNV+Oz?^yqW#YE*ńE5IVط;̞='.ё;6q[vfV5M9woa͚F~<1~ ?!~Ab_a!1]"k:k' ggxM5^ȃ^;x+=S 璅7<_糬^K_ᅱ & Bz/y:Ƒ#}$!c޻}l5mm h^I6mjGk8uj@ b_XH sL6==n'kh7p! /G[]u׵/]ˮ]u^uk7v}{.d2&"Aa"j~eKXE500Pⷿ=G=C&Sf4߾;Ďu9F#|Skq]P~Ab``BX񘔌  ?khm婧G9s&Ckko\A:smXa>;wkv=OJ ,wCA&oW2aы4巿w:l禛:KI%KY}]_ȭ[]JHAym% ,h|_S79޽y,Ö-ufs377O(=A޽/  E)E.go_?ay==::w6{ !)Y# ,&:~ŸgN%^2q=o*9RáC=:^~r6z?_'/  [|!~> שO9EAXjxY{O>y?"s2g+޺kI b_AXh7%&J9TC#SyD3jϱXqurֲң`̳ϞwI"sVn昜]/"AR ]]u }h\3Z`%\ gda졚}=?k ^ϹZYm{:5 /q ni wݵ~v+W6`e A浘}bq<*|&04TfpL__=g}heҠ{' "Li|3ɋzl?g6j 6_Sx_}m;7n]hԒ |Q6e22L}}E 30PbhBP.ض7Xn⓹A%&{ SKk}xi%Oz7ϩg~e~lotGٻ4gHkpr9JOD s=H@;m{J.ŢPeK-L&(F M"( aIizh?{' s0&xϙwITm{*(zi6s^R JeBd˓Ra#47hk=NkkT*L*!FMa1 }db`1 wC%$%?d2e^}O>y={N_dFyfv쐣Ax7"A&U|R(#k懆*-00P7}}Ey\B8 aXbժ01e岰O$B!"P-5 Iu\q/,5 #Gxɣ<1Ξ%G?'}Awz*y\B6[ҥ<==]V2r`ɷm\MS4a7{e45Eilqon>DⲘl$msس$?~}G?|e7ݴ+0MY/}Ad_Je> |i"_LBPGWZe a֬I˽%F:O&e|^ļ 0WtwysgGyw(mk7rزHD a w;W{{ G6+R(8Z/k|ž9F"%6bWTdDB޸*yAaJ[>osP?< z{ Qs3_vv\FC'}A<ST*.GX寴Gv {P t]òtB!cxgT(mmqhn15W1/ ԓryq&1ٵkwݵ}l˗'(=AD 0ǣRF\gdtwG/J%SضGUsW7-VH!e |CCDfX C\,#ܦz| G -sB^:᷿=\{m_s'}A旘mJw>GŢ~`7*44Y"IKK`,}t:2bKgyAa^L^͋/@UR|-lF2Aľ sC 1_]/_]ʍky{dahD"&dt:ڵ#ا]]4X;wʳG[c]X׏礏;5we;<%mcDe0^ pbȑ^~c8u*C:pGVA/BmbXtfy"LLD.lWx#9^b9nٲmmq44/o~wL"pkgrdּ躉v-*q*8n'8ٳC{0oy Թ5sV>鵬\ـe˾ "A*y+32l\BKe]"#I2񭭁E^:% žahbAՋeRMB;cYlRa";QǛ % vYL a1y>==~}_>G>on]{M(=AD 0n~W̗J.C.gKwwʏW;W]c18T&x՝Q];Ws-g,ճuwMl'Omzݻg).^̲lYo\N*%G 0Ν i.mkT*NQ*i:NQ.ضix~00 e)LS+O,F}"E,߇B Rhd2lNf^j֖2iPꑶ^3ٽYkMd3S+T_Vo}O&uahcB &tt8l8ct]a>ѨK8CDzLOijD>\%|&Ϩ-kjukrcq̩i3Ƌd syQ y%P*tw9w0NX&˲e |^K~ 0>;w^7 P7G8?fYAAg۶OQ(r٬АMA M6k34P,.>wyp  ~BRmm0!¤RTx$0ł򁋽&-r֯1k\ԩ˜}|6p`={.= TO-[WeKx\V 0{={|Tloɚ}A-1oہTs]*۾|6/aYd "a>ySx?,}J%b1W VA\a` žRp5bu ҈-I(TFt:Lssx2GÖy}*/B^A&[x^ 5k|s IQf b_DWϗZbXtr9*#Bj_,rZ{od3=]t"T*D"aNV0--a p8We  Drxgȋ/v]" qlߞ\PO{ePb_f`U1_*l~ MF D&jW,&1^׵D Bö}ΝKscDzB:P+߾~r:A/׭.9( 7ż7,r l2L"92==* :FijXNcc$TQZ[㴴H44,b1k2o\f/07<IF "/m-S`͚8!% KW7s]wWT*b'ߙG6J>q\ B--&+WG,͡!nL.waH+] t˻.dRn X%٬Á7顧L{{o^g>-[R$d W T@nr٧P~r@gވ/|l;^/hT#6H& I'N, ^z$݆ k9s $ KQz?sur|hSZj 7 "a?{/B>V_ݰ. \#Fx\'2HAH$N$kbҿjU|̸Zza0uA\ҥ3\A;|mX'֯! ȩSE v'ʼBJ9.H$R[V^y;  L Wd26 3o{Vs|3ٰ!I$b8C0n356n5y#b>X_ yP⌶ D .G_]嗻,]>Jo.]zH FRh߹{q0Z&V8ϞEGC7 ;ڂ?,LD7 4Bc(sJh,aXa:EIR(M/)0 (mώ IDAT]RVۇ:,ko]#EMFt0 <0t(h§Xa:C,hsIQ7eRhƙSiJ'Hcl4!+ b&DP(ڸ ax< 0Sg+4O+p<8NX4J\v]BT#X3r014lRn$MFUtbfM-4Wg pimם$/a#dr:Y2].nt)f#47$Ye;%eGvC1Y"ٞ88$"EV˲<4ӝ%;Pµ ʭ)5+괴7G;I\,9 /SL::0g+V&S.wΡ h]JR׌k!gK: -@ѣ,ʾض XO_7niz/Eijk#Q4 /9~f<#7rѵY޾ 4oHGfFK d[o`Boo/]]][?a+ebٸn-F(I؊Z\S'OqhoEZ4@7Mzz2Eȹܹp^}%VY#xvVYO(Hq)_|b#c9NxTGSeN;H tźY!9uhDc^$s~҄_'?{BiqlP4 2u\diyp5+ڸ曱=Nsq <.R2 8k7~&M$*d_xO<MaVKXq#o}D‘]Dp*60PB7\?kNb[K? GQQ.Nox-VD)k5m`- F:+6]wh](niڜ8E4#t_x3ґlțT>D;nl +U6z7&|q2"o_\4¹SiN- .{!B͵YBZ<͙6&\c&4p\7h(uLKȻc/+(m|t4s}G4lMq=N%P] ggN-,6HLrE2}]XNH>N'bضixz(4Di><`iycMxe+ ,[L߷q<=а5nSP8>^ l4R&RB1JV0ٷҫQ';q2YH(v~bT $C 6^C 3w}") шAX\T*gyNw|ص+8JYAhAqXl | QXiN:`  24 Miy(k}}똦YxecF|0劆ְK6VHPq)k>S$S*:xfo FoM`F|rN \ sEF_|_Q,B>;H2d*DI5w)d4شĴ!M(ݗVAwb !,-JvA9>z1eptCA7͹äQHX* sB4&K*&HHƈØnDH6Fߙq!B,J<2ttMih}4D)E3t6C ^O? D *-`!ߠ4X!6H'pm6c>|V%4@(Ww u}Kw<Fsl?45b)B8FGM/XqЊ? B94ѭc&FH!EӲ?} W 7/yW_chfժ8Lt76-4~jNX/|y'+v\PqkHRhưVCP0Zox;"`h^8a@j: e/l4]0HRW-wx=rpa/+@ӴJДy~yqr jX+E4C qreh0cB+ډh lD4<Ḏk kST%~0qUxt.>{IAC>pD^.q|vs[{skhH27ԃiV!绉6萭ap/;!l|>y  xȯ3\ĉ,G}íE0ͅ|<}wc}>> +žZ3^^KaQ}: 2Tn8qɰ^ +̇tFׇ N0({:}9,MG>C2f, f+"kx7v_):|x_kUG@X+0+ v|| U]0@Q\"8GX(\ 0}xn#!< 8 4M#S.1 Px k Wyx.Sloؾ_( (= eܐG)ll94lad>ò>|c_{[B!BIhy[3qRi5 [Y.$Nz=}CQNFP  =(*dt܄mYi5{6KrY~̲v@w‘8$hBϱ@FH &!hЎvf1HF2iN/nhXUY骪=ssELt`$"`uNd ?H"osox\÷$:@*j=" Z쌠e<'\!ȷȢڼN1HMbJ\G?zLζ9hL&{dTM,K V1>[˿~` 1c|qӟolGm////qt4hD݉pNB/rz?߉i=νn^}LH}%1DD0r'%ѣ(j/@Hu32b%ڸ: nmH#V !3A/' I.Bbd/A&>b}|TMZe7%G1n#JԪkcSC7 JJrTZ BD؀9dYQɨBz?ƀI RY!81nPsL =8)C8ivDqA""uiHFOڟgϲy{Yv.\cfcC1FIKݤ55ɥ? >(i3׫ȣ,s3].Di[heHtB1TxZ-9K.g?qIx,WPACpXgiдRc˳9{4 ;`Zwib [be9;=+N^fae+7}:E ',PZ\ᑅ"6sc?cF~q5.xxbN|F$o6wǻIH߽~ױ#G}e񶢷@FڲA-ѯFG=ĈӇPZ/{K$vR1(*K@ @! MC^hw#Z'캭pR8)oLH?rw!1ύ9ɿB0J4&R}EU28[ "i"DĹ,B$IYF֠,kr[U!ȚiϭB m"eqHc2cدJh>XU`ɲye6J #A[^`cL"IN[qF!O}P%g9l|(+^KHP%JЊkP%,ia1!C&ӞĘBQ1+(I}uOsWyWWhL69qVPl:J?!z4R"fhHRCi$2mb>FﰇTҕYz,3w$:/_9ypPw d?@D%$:w&#e=a[R`=Vkr\| TTeR(pCLfl!LtԤhS2n' E{eRT"xrQ3 jP}?f;s cݝV-P!:/R"It£>ſ e~J=GPw4XKEJAQ$&ph|"Fn߯$RE+QZE HHэ4ЯTy`xXh4[,Jiwf9e= }H[11x)Lk84^^ey=6: G#K ~I * ,NrXrTk< d# ǘMv?@[6Xy1CuJ(1(q} DV"W 3.uIOMNf4)у`@)'9G-[ۤBҜf'C *Rw,LFǤ~1 ??]㥗v>r\?c| HqޝHHo&/\vAwLȓ}aADvU?A 0h)z\xbARI"(;O 12ک!ZAf ~Alad)"DQSqsDGi"Z_ER0)dMB]@:E #!RrQ#fW(I^z^k\z`z4oP84#wYyc%R6PEC֚(dz]}6ZmTjӜGusaꏑ'ElWd""5=Ufdd9lm+$&{-fcoN[`d)9ob:gi;l*H#Rf|٣;7ε-N>zS\p( <WʯMI=^kH%v?zUN;g&)1tKqTL6$g@'$N4Qes:>Pp6%D9>|Uz"@+MtT =9;Ў1c|~~om_K_Z_]ܹ Z-{~_w[~?Ǻ[q7s IDAT{nqkvc?G,nckwdxGQG)%"΍BhVCypAGhfPT0#4B"Г]V7k78RPR"Omf'j$G]}QF}Y { { G 2x\XkG{G#T!`Ez#kBJYY*Q#"" V*$l 4f"iFЙL}.ROj$V;Z VaɓlnE5ZW.\I^l=tG2 j3M>f #$q%%RTCAP V,!D-qŐ^_ҘrtQI:0gx:\jfȝf-i(I990aÊ-E#ѿ#4l \AzxyT$j W'K3>a"A[c1wq!/oH(gfr2HGL`D}ͽ^~kSl #CH)Y\\W^Qܛ@o|5H2?JQj]M%Y=ʹs9 $..f"tE+*|)*O&5^ljg+6 2E!jc1k ?O/ͳPG_[T߇:Dz1~dڊ<[X׍oBJ@!h&)GJtآ j7.^![t[Z*7`vvC$LjN5[;tmol)>udYJQ978NI{A(^ DKRFIH2H=/$D?=GJ(!/JT0ԫS !ԩnc52dH"ZBN߄;9*iح(cMc8pclb? v+fghMN2:x[ŕUD*>EǑ'AP6Iz;;$S~y/<##A䰐4mef*f{W]L43>8R1I+gOpJ~9S}M`baX:qw/@!l'OL4n9Igb^L Ő+&NXwIs|BtR((mhů_%69g<14 CA05=CQI'=<"adbD!Ǘ?I>/&@ ºڔrNDB #+kySX^39PM|pH%p> DH(ipO>j3As `@,lBm&X9,RTtAs<a%)*N-+r:.Y0;}&iNUgS4vwȇVǘ>Fuqփ-d1v4v/9\Za"Ez"ÖI*N&I~FL9ט8D1r{rxtd_'Kαgth-.lc1>>oo_amܹ._2_"'NQzc1E.A)"B@ %FIr[D 4RTS24,3$tRJ)]=jl@I#7} k1bD Bօ-B|ZG4){@Dʲą3A:* qRDofx~+ߺ/{|Iqa=:E@U2짞A A6)'Ѳ6ZTD(py fI&m,.!AIYY:SIx"k/en`ԁ)V0paaq饔c3(i0iB\ $*W*y:EڝaZJvzTpk:Xvoh vxc19<*{{ EexbfS%c1$%nGTu漈t:5!D(>@$G3ZueY UJq!P~eQ KaPC@`藎"QSmq>]$ Z.zB)db65,2:&1 J3^@2JQμ'PpX{=ZՒ8"Gzi"qa |H c&Fhb~>{OC%BYGxoH$N>HǻN|*<yL]*3nZn3?dw퀠L͔DIh -vT7 p>gᑦUy;6dQ*{k f;ս H/DȄfnW2}dߣ+m\ۭ#U# QDz>ZI,k~%̤sxVu}@! 9Ǒ ?#w +#G@Z*X6 B BHY*IQtmd&;GCh"0,;A3k#:02#L<<<8$uU<BZbmdm[G NhJV`~zNA{ wVټ|":-Rߐ,< ?9/~J1P(e@a%@KYɏ/3wzEZ3md&HfDB$X-1%ZҘhmb{8{M \=?3'81di8x3A"n􇺵cjWfWEÜb`-Gh) A:2A;3ll8y|VB^kAQ!4yUtI%MYl&2H "2F\H`%֏uN~=_92@5D4HI^$m5FOax(b1ׁ4My~ 5VJ$I]h]%^:緓:{^`y*S@ J!PDCH,e}sm*zT4R:C /'ED: fiytNq88`)co3^+""mv(>E"x g]9N'D%)2EFP"<#]I@—R HA#iHe""YZ$s(9w_ _~,&$r*`B5ȹ_gH"`g3|xPna6H3;`?IUUJ6o;~~]1cQz?^?!'OW8}C1Ry([ 罶 6sσns*m_;WRa]E D_J1뼪F]BETú^oXNj=QQme$epa7d LLwPR({t]/DFQsf&Z!4beRT6ZS!!"TQV^3UGJA@DJ]w đ??R(QJHb(Q4ePVLN0JP%?KhHdH@T[yiK xD S%1aI.I͸_2~Do<{ jy|:j"aV(mDs:QaFbҌ3"Fi*kGmm( G ~C(eh rܳo\ ^ήy(5}DGűHUK? JCp }d'`( I!H/EN{He-wcƀ mFH*>%V>ULpH.ţxO~ |o߾ɧ,=R'$Яl0q8GEN5T5gO= >"nLwtzNGDVvwz~¸?c>,=W\߾΅ $yc<,X^E6ov߼Mu_=ǻskz 3w[I1d*ґ)RJ0SQ羦7lU!PҌґ#'"˺㭴&H/hfmClLRkLMOs;9S6R3n⋜F[37ѡNiId8"Țs5i 8[1)nAE).(4񅛮(Z=)w Z( %$Y JiS[D7Q(Hq"9Dl+yЮ xG @냷N>6C N!}sC׶*eChRraMb7J]B;`HbuT'Q9JhMK]' C軈)m Itn2*z;taejٖfwx ';,Lt %=FK)0J!aB%dFPaXlihvd'F4GoTJ4. lYi6. GW IDAT& )m`XF+M3kf)(L@EHQZ`MHi6Gsط'G?o~|\{9o "sρ!U,Cz# *$"sتBEEHCy;;0 ec*8' 1a@3+ɦ%QJ$J %~*¡]pp׾Kg>/~QʈJaCIpk;y?#7c1~c?_~Ą>_#9L fGNDnuh wrM\}{P)ʃ1>|xf9U#u+[v1]OjY uBDպdND|P8<(HPxBW )!K4EU@% *3ݔL2噚$F$!!F(K !d$z@*FHj ‰E$ƀ/#F]ZFg_ Sˊ`#}V#(RT%,їh01դ, ' Vޕ(4.xhQAy 3ӗ?O}onu~CcC^śln"K&#DvcV[%BYأHXvXz2B,N =[v2;muޏfun?wc1 ֆ||󛫼>1F>i~&ƌ;+x+|/o]~mu]˃úֻN:=cL.hc8߿1^wh~Y|]Hs(Qǘ)yrR1 Z% U=7/{l-%2ք91 H* s-NJ& ;t[-cX u_DDBTh_!PZIDE9!\(R׷}Pb4?ES֎A:*DtxB $F0DJbAx(nsNDD X~B(s$ڀ 9H1֟SQڷB"ie}{ݵ}`0a*HQrYU(RW$q>*)Wr.ӪRX ) $X 00 f0K2}K>;ḟs~9yy$іk.exϞd^Loğ kon1f=['1G$uBP=d,M,p|~LUh[+ $lr}wચYpS^nkijAgՍ\(G8wm~e*Ӹ> }]\̃"WH5 KEA}ND%DZ,6t bgi*w 5qk^ogۏ.|aFi9Os?Foٳ??Ǘk(q8FaaoYK|IVIq*5?PJs<U^yg-h1EQ'!KPMSMiDw*fc՘$ F+>y > R`O@lٞ/DK#€,ͰH oZFI,Nֳ角f%P 'JD%hU !BX %vek,98G{\c/CxF~n寿fA h8?T8y޸2byNSv/E\^_uyVyrq^}9uJ++L장" clbM!>џ`&\ڢ:3wR=DdYFVl@klPݔz-$֗"DVg,-1-ZFcmM?xͪ`:=k^nQr>f SQiv~kOnFa{}ol裋|e^E}t܏0ˆ߈컜YSKYн_V˶t')ɱHJrJ+pPSJЌ2Mj3Px' iapx@e2IUlH8dӨTq$&(!) [ kh3֒eX S2|LJBjdE W2SJa{p($%qRJav0@QtQ*8M=+0^jpf|(a's%чln+ Gz_ t U҂=B3!A?={8S4G#0kQz/Σ.+Ç|;y9E#0?d_iPe|(JsArhWVeD{My@ JGs! *UV7p#rgJ0CcIDZhT=8PҨWƚ(P!n8xuN?⍥DQU+L^P$ 8:RWF 1ֳ ~hNqd8I4/l\fe "Px4B-y͠()g`zpAP*,/ # &t[ ^_"YLVX| f+l^:K8LvaRzދݶ#0ot:ǖxRc|+&Z0Fa'oGt%֗Un!@)sYi5\ ]'MG]Y 9[>d#D+I?KJ"lY1͊@yP!bXL%Q$QH-V9RjUdV+zNj-EpiN( R[0@IQ#ql,hXl##N [ lן UF%64R8zA>3ȠiLNG)DaHybPZo1^{ҨҥKw΢ɴG?~r+R:]GpHCp"g^^T4QCzO]G@&V8# 6k Xx[J @ ‚ 1~NDbQ&i+?e%Cc,CR @H%)R%F[\` !# _8!ʶRNRc+l E$cE K/oX/)%Zt!t DU2̽1xS-6GZޗ;H!2^Qzkb렵L7Uݿo^O_7X_ر#|}O9c^&`&㓏|7)$35HLnp@Iv͟OMmL` Bf >ˋl\:ED[>(Ay9@܂|-p-xIٻwӼ_3=>EegX9|`#N<৚,]'NVΟa JKd@aFx( }oo~s^k=?>/n>Yv(5[7̉QWf{m\7{ηAA}}A?ssEV(&5069axA/3lmuB ƚP"0UC/E,^ WRQ8B GiEjn *y (ȝp[t+FLV%TK}zY58 Ē87X(- pΣdjpII-Dar'CzNki)RQ#T -^ 20d+UxD2ٿ, #u/ѐ" "}J=C!Z:cSqB?o!l=ˋ,_f1EPO LʕE NQ+ "޳'/!d;X JJ0Fqi??Oj,v`X['9K/ p HsyaD7OI)Jo!^J#?aICsr3 <م*btӎ0#9/ /j[_??u*'~Hߌ~VnVq{>PF9 ɍhsŕunltz.V[pyajw/kEd(#';ZR!Աo!SSq rGdR:j5IcIcF 9qd X鉀z%%1$ҼLyHtK/qhY)xk'@ d6p!  Ms8$3 $7Pf-A ,#Th |F&7ksׯmk_1b N9 Mדx7_Ӱstcfof9NktzO ɱ zo >aޙ_ _VWl0O}XĤӧ_5L!im"mfhg̯e^7V:OϡC1d! AI2$2H@Xa%8~W=f`O171Y_ K/?%Hs7E/)d~]i.>yky=?mۿc#0eٳ[|;</}i'+{&FQz?~퍪{Θp3)nWq3eio4ww}"'QD"6r[="geeF5BJ XYY9N@2<&.uP X)"YSD#K *oe>ISd^C+zW70[9YVF,R&"' x/ޣǚa=*#9F"GeÅj IDATS]34tsW ].fkZ Hw{NFX\Բ{3@(\(j_~_J(#$)%-^yGV(mё"cdW8xXW.p1ecSMC:LVbPjmٺP]\U&* ageb&S=p\:#3a/S xUJo嘷x~7"o({@y}9}?缕lNo;7[d-~BK3MR_paiThr*IBR%іjN)Ǩ묷O6}&48GtB G ^H riX39>K1I=aZDԎ6b4Im艌4f|]LiiP )8R _VSc~^wnwuB"=Uz!ޒ IUa ^:sB{@nX`{)Jp8_@ &fZi>UwRxpŰB))IMA'c-^YE:ӪMw";'gs}.RR/#Ut%bgM3U>^7٥9'OTU(:Gg&=%0=ώU_ 9mMXZdAQSk |GeƤ=%TFf\8r ^Ȳ=2ʀv+EJ ,@xI^ͼ>t-rX0WH4zO`WPN>ǤرVB&nud&&XcwQ`k=%c-Dۻ>dt c^;"R sMIPm$Ԛ9vd Kl= :Zm-s z^ 1TRaFhϮ3l^]C8!dFqLL5Xo>5OW`K3ߧg;8u}I_gkn?o%<q)*&o_Í7NDF}ŀFÂ,\'wtK)>Y](Eo|`i>h9UZ" 1TJu;QU'L0bus1;ĥ6Z)!{iJ0lrqǹ uƙ:ϽI{޿xW׉* 0ۗ[P[,f`9++`Ң ҂ HӧY 7طgnP装By79(Y_^W*']"k!bټw9pA<ޕۍ8[҃ 2)DDIVm}j@aQJ&Ho^ }wlLϾaK-g'1CģeMTA $A;ew4+TꗩvWihvS"4rI+' k*(Vh՘;>~siȴ;A\a=c3t soS!RX 8NdCeRᐾ\X "A*x~A)P<'YY^?~91zR9kD1U36ő_$˿0Npy6sBs Ԥ%V߅;w2{7SUG=#0‡8^-{l_{q|S3UI? 72S~ =͎Yny+㽙fdx/~?lD'6;&8n@y6`).̯UBÇ8"RyiŠc K(`\YV#' R3;1U ph-1$x:^){ CPJ㭧YԅYUg10Yh=x]K,T /PBhQJ0"y, c@ x˭_*uh)QuHJ" (#hBy4#VQR^VB~;") B0LK8!Dx:ذv`uPII&|D1Eڧ]d[6[]$21i҅#:}z0ηٺzj=M i K$c7:OdLؘ.uZjLR@h9Ӑ8 ض9YI޽{r<=xj%%{\: :O[]EV$^;? Mk!IϽPOg_9O៓LO̟k6O9tUx!r#}3FaZ9ɣ.st;ydK:qFN߿߭q˘nd>w;c[;Vrs^nck}^ȾpwL WZ@xGe$+ѻ!ԙipYVpS&lll/^8oIЅzy=R"A!GaUA( oͣ.+\ңWwK GF#'L b(egi4߿4sG9y ^i.s;zu}vJc!JbR5XX"C XU2o~NmN5Paz]Q0đB 5~?Gs4`mX+FZh<(0}' YZPg=N0 H<;s8oK(S`RJ콡Jk~qT88PXYiuL]yd+p =rwe~P!`X1VR[~'6*&lbWI+XEdE&R$d#ГTOM>?s. byH\$QBu#=UI;8@ R6r$ d2R=Gvw-wLí{/|֕Шz ȳ[EfMtž1Tī1>DIag+xe>eXfsxIX [7ymm/O|}CLԈ0?2JVyE^MI|p/|a}nQ#ÈVFEQpue4RfAۣެ뷐RXsSb$\&T0jwɭ áЉ_H$ƃD`c & hE h^lW_IaLN3H PRg >w` OQHxo z3<~I 81@H;$ה %45?r!сBԇԛ(V ٢ +!Iǻ^wQ# yy=S+M5$ 5Q5Ƨ=Lu4Mƣ:q89Y/Qϝbzf=f޹a<[,y9:hME#` _D*g=C=ΩSr~ /~/ƯOʸ CY?O+]{bJ;r<^?yEr_`]:?ߐ=zfnv~5ZF^iZOK^7 v;طFGaFd@4H(hwz9jûzXۛ8dM39Asluj:뛌5=j 6qEnF}eQ^ɶltsfר(iʓ>[Bt{<)\\2ٲga2փE9KaJ^S9<P(R'g=$y,]{?\(e_(@* B=/8I0X-pCV'L phnݠn{?Kj/<2ǟ=wy=HP:;*[=iX*9;#c"^BmFu30*'4 /b"B AW(?A}3;wW@r96P =v"b`,wu0/?qʆg9n(}Gso&erQ093styg +r0Fѡ6Y3rbR|t>S;v0s? WCu?u;_> y f苂f!W ޏw;γ}; NNf۷voF'kQzO,쳫,-Mwq=hFaFdCkM^xYX[[J)7XѨs#={+:5 0)Qagcc}I' $zf:V8jHC:G#",J J]-/GK,jH a!*)JwŚy5Lp,KYB`Ec$=SW3,PJ(A^7xwex#x+ޕ-A +)Jw@;)#p$|Ka<  %5 {,m8ַ4i#RYAhܠtG`mc{aHƉ+ zrjm7wq)+0A5tXûmm[EddY!b; +g}cKW4UvxB}?҅U$hS/"FX*K?82.јL3Ýretl?)|Yd!þB5NPf\VkqRhNS4y}SY=<Ѩ/Fa;w83jjC:)>Nݻry~3/wz˗W3KB./U8^J~g@8fWKlgXnHT-a£($ eB $suyZ=A<`=L_EAa,5߹ڒ{#-,dy p_P+!TK\a~u@y:e/4} y$5$԰hݻgkV)ѳpCı)\}E%D8u`-("圹Tʘ]s+l^y͐I(9!adL)CrNtO3LL,lCX| bt"^D8IBxW~NԈpˠWjǩqӳ(|u3>2ENwJG #I/h^.mB]*!@ O"d2BVʖs%B*lkz%2x4-r\^hrl]h2רH; Z s^zg#0"'Kg)TTĶ:(Y,H$ް FQ"Nzd<ȔQ6^+;O39qʞ}'U=lٹ/fij|)](bXiqG]?>Z΋EQ Woق{9e֭x$Nn!644wntC<96#'Y]wrkغrc{bz}YH2EBNL1JDqAҴAo_z]p)>,XY*]%jEGTؽ'NGlG-,IZYxN {iqN`@h@ztH3wyNZ(4FG;E`QX1B̺ Y}!BO!^xCVdR>}=-al$S@ OZlw+<6'#>[سﻴZO5 V:#Kؕ"i&SV 4(Geb! pJC>Hs|#Wa@:eբ/e /WsB$z[p͓mB' 9/5R%x눣2jc׌rxIlFdLMLP,da[2 (}/c(˂Xqh>G8(n=L9@c:~lȇ+v5; Ͼb"tsdj ^{B[OpJ\c:ͦE~$=vSZtui|f-ho IDAT_?@ooJ+yC;75+ yZD&Me/SN~(J7vrCbaqU&E̴A I͹90F0XDˇ&ع5R@aQI޲,.ZhR+B)|QhݍVHL!N;EaZ`#P-QW{ %3ځ`Y-|ΐ8=:Z.T$)ڏ6H'#P1I6ZBJDirco͝k!c5rO=9Ƞʯ5ދm!JEx_ F;bb}0XVF /0";FL~*0z`C[Qw8>މRUy(} (.#\5VHƍ<.Z׭A:Ǐ䎏g^g_:e4-kE^}W,"֯f8nCrTfVꍔbqyg5TJ5/}>t=["κlc|OL#x9~Oz->+.Τ/iKM֛{G^8uKS'A_N߬1~k֬bnaVs6d<ωJBeXkRY$YV0=UgnZAIWSˠFjD"( "+,if1m(rL7 ;;҃L̑,S5&4%) )ՄHCRҡ߄̸1"7mA>L ` =ރcBʢ 匬m%w ,3:2c&i2)qX'׳iZzqƧfc DR58&6&:8'dU>wߘ_btR ,B,)# o-1>PB'$9IT4JaEI RWuMO҃(|Gz*BF`8_-x߅iM "y+D7,"umcoY;>@IdH#OwoE*ݘJ nYGkqlF`xt-&{q=080@_gXu3nbDILc{}ϲ1O /,AtAs_ᡇNSd{Ws]lݱH5x';y:;.sw|}9qkoFB4͗GT0&>28M5Z5̎MW |~}ofi֬f˻֝^Gu=΋=^O|SD;dO:*rpG9ɣȑ:_ͽ曇.:ex\ 85q{}m]h|ztA_"Lbժa^{0XCaAA=* $yn8zv\Y*eJ j$IBB8G$3Y.XYOG꼸8^=B%YDCEJ)]ΐ!kLPO-\9+ȍ`1UZA\.wkv[ P%QTd㯢EVJ81% ZK8kHMNfΔ:Wy vO߽<"y"EpOB%a}'zN /U)t/B $ \<" U :Kb..ŋ^X@i0&]JI\fsuD1EA)jMGI\=o bzx}kP{%׮TK\ڤ)Cؽgdk뚙2 nn9EċoNw ٲ5O.rh>Y3J5glӇ/sݼŠg@ﶯB%={m^jJƵ҇wO{ַB+=ߘ/}){1oI {no~/F)ZLx#ZpE՗i()A+kqnbJ%d&HmAje$%IT!w$[2kBɾ<I Z`r!eY`D{n8`YOJigs=BHA{/YnPcG O=CN;Y$X!EG_RuD !$Z;Mk'}@ɲỹP- Q)X;U00T(#Z@  h1!$yaM%o?G,'eDObqfծQ[$NȘ8,kV\,@G(uEq^u߱Fy}+ʹkj-&018饙/<778ܚcf]RbߛROҰqZn[+O"#6 m 'c*׭;G ]CTGx'y9~_O,?{'+%UJ_~K9 pdE/4'^m%z/gqWfַB_|Κ5g w=ʖ-Tc=xm|^s1_J#t!+D\wǩicGjMd Y!5{5C}LLL/+{oLs!Z. vk|PG"i<l f2c9G% $iV94$%)kxg0!۟sOTB]gDHH`qKJ yJ\(oGJc[GHt1XywY@Œ5\w8QTWWdX"j\Kqbd,g+L$B((i)s.f޵„ARۭ.AqAm'j^vYD) 04,2[KOzlYj^'^`ȹ*)+p6_" ypGLszcnM^~҉!_4fkKUr c :Ҩ̚5)FbۍWƑdȱw5ߡH$q VyCMJ@WB.4 U \}^Iᥜsh[&&8|Foo}S Vz}}+k|BJc_:wsSAs5񷉽%!7>ZyzP!&w!Q:ylfxp8kYRB$;vy*n%8U;pqc(Ɍ:2Cm>:A)l[Z!fҜ)M1x)BH%R`Dcjλ6asMP8 p t@- Zn-8.G&[><?HoO/caaZmr5@jCK1(<c@`%@[ 1??T:ddkv!])ie]#U  Ŧ௾>Q* =]i@26K;(\pb#3oFs: R"^;\:ŚЯk ދrC0elVm17|AEquvܾul֭یk7{NB}U奔݌Be2ޕd WydΞ{iMUWuq=|lԱ tKwDi $KsH@G烍Ai|llQ!ۤ Br[O! 4J<G=REtc)hxG]3齯5 F2 YJC\A˥x- Bz!α N-f\hPH{Jґ(PR{ޥ(|;!_&RHHYL[rp=q9K) ذa=}tu+ߩEo؀R)CdVc|WC t]! mLp`F06Ǒ Tk )bcQHWH2szG,N `X) *шk-BDH)@vGY+$RFʅP9 B ldNAAES[P::J '#z*CkVQ;Wk}bi5Z#Z9IS!! ^(b ؿ }2*GPvD-%[mc䛼C@)!Aypwx*uϾL_ qp5WU`Vq]wt1ڥUbrn_.[z~mXJ{t~.֗{d0珞r={xq|&##ec^N_~tAW/Ku=<  R0v-_ e#%&7&XRSpg5WXGVEdl|v_X'J#(|[=̑BsbTÀ*S %Q%im͙=T꡻ Zk|VT.~:;A0 ^d_!S$}WqD6GSLԨrX&郵*Vh>Oi:DNw$){Qʡ,d=k@ Av68W ˕J)(\5%ɲy⨗ $Rs,N#.F')-G*R94)0D8QLb K C4&z D mbv2 ’mg@D#Bx rк輾~284Ķk B禙G(WnweaaGٰaq2헻Byc^v\樂r᥾|,?&xqǒ;᳟]m 18ر렃: $ o5D_cv҅}1E_/1Y}/~[8ΑM׏4?whۦ.d{q~~7a˛/O Ϡ<}g|_L;d׮Yp5菎񱏭bݺ*I):}2O=ڽK=||q+ ϯo$8K,,~'6Ou']e鍹 xH:7e`s_<9qX˾v~wYƣXW噗a\`2Մ8Rh!Ŷr0h"Gp=ARȡ4$Icm-a IDATr[&;v߸_{6yLhX"(.oKJD+C$=|~*yѠձyog1 "qR#9:ÓvՄ8EN/װX P7L E.)#,m>^?_JT=" D1F:.l.GłBJ%/"")$Ok|.oqiSWo0:k ~krL,9'w HBe&)yjqi8Ho"/詔PZ.ICo9Cv Yw!ڿK4h[z9HdWeKH՟v?B$"<\JR0?;CWDkti45MW.,,.*.'P%Hf*SYk"e[D,HY <RCvkLQd)3.ehiL@fa!R/",0)C+m`0hQc'Ʈb7A% uQﷴ ()zU?̝l:ZRN2*#L9:5RJ ޚpJGi k.GGEh 9cKyyvhdi-r, L(ew5:蠃_yya͚JJO?D0:ɾTOAvK8ۉ oM[?&F3' pD:T_f9dYJ,z_Adz|+8* RD!xo5Oú2^Md >oڅ~xk] YkZiqB ƇcBG0&0ˎ?)]JGaXD剜7k+ܹf< JɻkC+Pk%^|92zKP{x_Ayr8_ 'h=Dڜdq~@mnt3gCHHAE!K_!($Ql)朣j\:wgR[0~sO1=5K)TLVUf=%h^GWoPXrG+w6kY5x.}{y+}~_w~( ?~.]oŎy)9.~;Dž{sn桃V_/JF(G'Iտ?"G>_unVGؾ}>Az8|d?q5k;r칋h,6X5AςTZ!GPdV'^,Ҁ H1SA6FTA:%̭_/Bx!6[y\JJl_^ؠ /_B>G{{S*ӽQym|^k7͵{sX㗗qLL;ZƩ9~h9s]5'V?II,%oym|w~dk眻g/%_aaIꆵziS sxJB 3%pޠ@yDI:P2iN*d,c q M APozR=˿isXο2C - XS)vSh'uzQ Ls[Ҥ\~8g>Ң S ,|u>͎[(Zƍۛ\;JWҢi_^?^NT։KOt\?;>'Sc\?M4Z:\;QZɓ9\?{*;N5ԏcs&8Nf?MZ8k3{D5x"|XT#ʿ}ۿC$IyG4/YerFEL-arE1FJ@@^gxco5kac?|Jju'S~*z&x׎x9Q9'>wl*\Ti3Js 4x" "g+_2_WqHx,g2 R+$EKt'}ǝYqoPRRrJKgf^H~ݿ2roLM8E}3GoR^X2}׊\QBqZj4 ?QjI/|`5 tRD 9,@%!λT_qy:B3o0(a5cPZ!BFF K'dɒExemmm#D7x5=>()䝇# zfə/M<P, h%x .:CQgjrFyNBJayANQ8;w0PP v5o1{v0Z :"P))'@!<wU£\GEl BkE.ȃĶMo^7r<9b&j2/a{Ϧx6@P M_֘҈ $>5 :JER 4'$^z!9&&&@KXq}}X^9/_@MDL'[ӥ9_1nc4q=ѵ}>޵d7X̥카ɔ}iٗAY]ְp. *sG 7z+ Gg'-}<سA㺫G"ΙY!I:臤I!2|/yH!8p >2?,[r**01ieNP ԕ$EBnC#1w`3zY j= dtgG`YgM%##gFD?0s_LMM1=51{ PZMsZ::*33Zۙ!MbZwH@885"c:ZsuWz>իA)!In{xj|wC8ĐzĀOt+Vӆ)o-6IH:qFvސ} W9Pt \sg>CĂadQfHGP(I&vn& ɵuR^sh^LTkS+#D78E%0(W@p ($1Kud ۶GkM^/bazzh返PY GGf`ԑ0zh05b, L40ؒCS2Oi쓟T4D?MBD?dio/9Ғn KpVɿ \u5@7|1,O"w6s[o~ޗ񾿥{{]+QG5*{69g#a_&hƒY cݹ|(N`r]ǩ<˲Ei Hv=y;NZ>-݉Y~<i/#e6.Lpn#IkwV~CEeJp:~/?۶GkMVĴ38sdE)W\ڵ|Cg\?yg+8c6d߶Dv;m:v?7.@XoNE*&AVT %4u\[ÇK/"A>֛yMV(`h-ۡ32c& . "qa.9TPIMjBuL#8;ł!mFAPO_0Kx_`R(K\X8ɿB E\@ ¨7u{䢀Qc維W]w#Bsݻ7[[n~@(Y4k 8Az.!('aW/-l?Q8Fc˓ߴ\FU YaqQw?Gr7h׿NjR|_+)Z[۩T*|ߞ/=5׾+4 obLzaؿ8!ٵc;|>nv.*>;bMD-!+?LJɅ[ؽ{'i?$I)S@IJP7hz<9 -]=o(BPn vH݁Àͬ8Wv^GlLUj|"!)C=]\plڱPL#rZ)b)55&SSDck}(B =KVгt!-TGZHQHL2=^frt38 (m |q$MH('1RZgd^L9RHf<ȿ1fR`֭J3RP`%FR.WDOyض}3zb޷p6#=SSS}y >çcg5{^8cB?wf.R~Bx Z˞ݻH8{3>Єs2o˓O>Ygj  @fXcRjsW񱧷O000ֳt0=}bݳϡ v)Q.OX\q58ayGx4x-x(ɕ]BOO79KoFMSz+Tw?ƒXcT*⼳޳C^mX2VAl͔G[n~ 9 Br*-[FyfA}Ӆx!0d[8B) )tmo5i ȜIj k^KZ!*aՔޮzяG#)`ftvHLeSl)GTGG}7$ig%G|_Ԏ/|$`"KEy ZK%tq1:VE*/ r\H!P)WY8[%Ϯ]XbIפ3~4^6DM4D?v/uZ#7O23ٰb0Y O=Dž\ą^VO>B LOPA#IXlCËg<3XXj}},YhZݻvb\f caRPJg~ΡuI3{8|'qԂ"!L[(rZ,GV:ZV_Ggt8g V\{x/y衇b֬Ys)8lV#/G B;P*@ZTIbXf iP=\{Q}tvwr`q*s&iQe!(m yz{:94s{H{*D@kZuU˺БgrbbKZS/0IB=x 16rU_ލji؍K5C_^Um?Bmtnz3=C_<v`W!v^j݀sHa6uG-G:"_lzE +H&?SJnJnf3r$/oWʩ&h&h8f;0 O?,.M_0U1Y\tŴ$eݺfq434R+.J _oYttZ j/AO>GZڢ-DQR NL%Z! a CzvS \ #c\7Ŷ 3=YށV " C6?be\yNv/lR믿 ⮷7]Ogw7R*n&SKf%N.c/Ikv$] 0OA@VCN>{)SiF\0,29ꡐX* u@Zeѻc uOcty\pJ,A`+߸QA1D0Uqլڲ'=]:-,n2YEwiwy9SqؙP&[ХzgffxrIZEK1S]H!=ľF4N.TZdFG{(buW̭ի9tx =VHa&E IqhRC n4HS5dk0$'!PfSVzA!3\"עHY<Ք\х`lzA%y)5mM4Dox,tOW'[+X=S2(cA"IO]FH[K%gYd߾}ڵ`֭3 腒QUW߀FL..B[k7x#_طo_V\pl߾ )$=m%uPZΚd^@l 24PZ!\."<T#f]ΟNJCHjBADA(hWu[n;N H$W,gp`c,-ZCoog<r Z"YhIt^Ga`GM7mx=M>|LM7X͙pT|{HiI/#MO3X&LTwŹRD:'4qN<]X35UG&W %2i?tJa)%p>zّtPhؙAK'T $N3Z )ltBRMge Ik*q" &ƦP@`tsh7; gRXYo4UG+*ȴQ.G1IN[Jc$Q7ȜК7(+ @"s C"NLƦ aKXiPlo&h&h7~s<4iKR" 1%# B Xc,\5b](2s .⬳R)O g^ 7r`x!o^K=?Z$C[\ǪyC~d#^25\+ Sg#۟gpŵ ,=WmeXdO F[wXq՜}ѕH59Вo _",W`ٲU|l,R8lDx,!A@ʍ7Ⱦ}xv}f=a]8`#`歌=<<ָ9=AF%vcDG9` A$HjTYtE}y{C"FTc–^dlD<9Q27wp)@G!1B! ~FK O{TkD0) )W**a4&_x)]LnE{@?{LK9:eHc| Y*4z*dZy7 5AӊϷKcdU5~93`STa }{I- Bݺb'>0D ;хRk ǧ%djiDM4DX=OD Ot@_e8ֳ/'~"*d?r^Icˉdd<{^mͥ&^/d_JffjR*n~ヿ BrW_R.O' ;|aŹ+x{"ÿ|x亮ۿe3OrrZNV ϹUQ 6d[/ 6 _ -C\1y uB)Ǣo +kl~V(TpWrށe+f< |[ikEֻ~׮5J=x)+ihkcxx/ˌ!xo'Mb*03=KA)+U8pB?yPs$L!-'"(0lccrDGW?6Q:0ceO +1"Xc^h GZ<=&f vQXC0Ho |"^OǙ;H+o{峄"J!KzǦo݇0o'~ToF+.ap%oS|}S;A /bQ{*i<Rk;ʳWr]w#{?@_xOK>_0zE\=y/w|ƍ7[r{f wnsfz?iLR݇QJ24ԇVbs&VY¼&o%?ԁ+*D!(A^kw3ƿG3q7ɾI&Hp 5X\@lơ0jS ;&H";I]4Ikc6bO?M$C]+BB(ʡbK5.V(@jgy0u)'9LQZc'/Nxlq:@J3Sӄ5A +Q(8pIO=3\ j4$Hs9(j+LLPJ,h#5 4* Ȃ5ټ?=ՖbMةx&~Rx/1uyw/.s.Tt~r콧,ϵNUMy3R(.ƹ,'? >u}(b;h*»ߋRJajb7T8#8g?lW}EhbCϾ!VV 4RcebNZAqh!08t`zB(͎'dólQ_#zg|TXk&m;(=HݻwӨ|vt05>(2@Ө̓ʁAH-`VYΰ~: |\1ւpj5LKKs&o,!7K)a!"!&){K-24`+Q 0S`RăBBR1 BP' Cd4N!* H)vȸ&57-#hoEm#<#3 7)!qIu ZZV"911RHR r_ST}J*\9O/Xp,M^pXk8zx2Xeͥ"O^wkm|<33WMɾw(Hg7,̔+GSIx|=> R!2f&apgwRK$G,($n9w>"-}ؤv =+l u$APX0 _g<Z@]HtFmR*;ۑ:F*52BI !糃 # 1N{{+-"c6mHXKBC9x0&$&Hhk1*VFIS+HYO<vJt11Vf y:C(O-T84hJQIaT IDATZXSuf~ Dd?dnVx8@k5Ƥcgbr| i$L8QTS,2qƵ]fI503äGh샤LO|et~+ |A ^l8kIj\=A[14^xT">SF TGhjƤ "I;\a BH/qRDZYFJjXJQJ-H 8+1 M2+XH@ P @Ky8" 8f'(ZeDRV4khcyM6s==Ы)x$t.rͥƤtx,2}:\t8L4T?u;5esT,MNWv*ϟ~=MF~. ;U羉g=$B!ϬছKW# ‹/%˳zjpe'Bkn-[P(زi3J);`7'@Yxy*;(OJMJFl$3 ZR;' H)e?0ΖN/09=TZ/O09w* ^yw8N,YG=6B;!2-}F.z%^J8GEI&_$֎ږJs&{Fx8JM88H[g/Aһ{+I|R۵˯%BY;C4{As? iXŋHҀ[3zk$8o $E8c BSKeҊ8:Ӣ Y+y⤁Ss`CK!XH%"}f` PA`Rt`j 0(eށ *x糃 )JKr24Jg@IPYݼHIS\(LD>nF:<2돣?D4ꭉh @U r05l;qpdCY`>C'} ݌OL14`hh!,Yv{y#ظ~=}}l߲"( T5w 9t ˇN:xRp5&A+I܈NgnBph Y`%XrxςN" !,v5 q4b kaFϴ>8eD¬? )x?kʜ}8JgNLLJ>R%rE&gѨZDHG1',tStʎ֡$^ >=:=jĶ}D_D!tw/ rۈmLT#6yTH@I8^<ٻ Iw{DduWS-nr{0lv9kY]2cͰbA@1#^FZ- tTwW_U]U]GgeYy?<2+:3+3+,-#Ïpw^B֬QdT"$j | $K@E4Uz2DmuUM P'61TM*Jн\NU =-$iJڗPm &K޻DMA*6sy6enQx]ʲ7 b'ϕ76֥(>Vsk_K[fc.k|䍌qsR!nmC~szl3;6+.1N ӓ]»MK:gO m IZO Td jzrڑc\@ïd۶oI/"S?GiL"/CRٳk鋞tKwvQe@:d:D \$YJD& 1XEP`ӦVyG&(V)BYv޸&Dk  ꖺ.sIbu{^xFa%/hcMpc}- /C3[ ⧺5FlDE{"}tZ3z&=.1љb`rlqjc[/&Oпa]>N.{;i 9T`CS(lղ.$ x4.:\iwD^Ju $P(A@4nhWܒkOT땝$UtN#rO׫20 p(Uw*(!#N@T9H ] ߒ{=?>e͞]|F&&os] s_y/yN6sCXq,=F^YP~YZvsꍎ+]n뵌\Hߊ+ elB Wi0=uc86}'N395,{7 ߲wSO;t3O9?=K<ģ9Yϖ{8qӗ(@p0*8Qj5ضiTƐh09 * 25bpAҟ(rUtJ ګ.os}Ѯ2JsV U( @kMet]ReֆvMȒ~}a>Y(?wWFFTG Oa'Nq7k8趧=_~(%󁘥L}Yf>yVztF,8U.qe(Iv1IJL5*wDm0IJi-;hRbu$ ĐMК,F`I,(*QPZ2U } IlRۄHE# ('éjJL>@(P!b"Dh(ҔfP(xq e!u\3qqvi"OR&tXΥgU`ҌrZ߫x̵_cRI V([ֽ "_Ejظa#EQ-C7&G *&gn_ownfۨxຜw4g곟fOxlPp&K =ލ.rO*0&jsÔ# }hlJ3>仉~:6>Uh_0OL# >$ޓ8_v*xlm( @u@gЪʊ|uX .KFWC H:QzY`PM h\tN"pjxJ1{?#ć^>['>]_) ~ _}ߝqntB!`?]ҩҞFMaep^N{Ycρ}\>>gq~ˌm2|87kO@Fh6tThe)˒m[~C:s?i]lڄ73461;ۥVN8o PWxr9t|㧦ٽuMC5rIkYߕ("S݀ךrLtgsBL+-^jAZ/ Xآ_UhX[D㜛r4&s/;*8Š\ѺW|#_j+ @4+{y~`U=>f=)'O@YfC|;'> q{݅K/d䑯}-_lq̿e˷CB2̱{Wxߣws( ӧ/7ċS>I1Czg ]K;lA P_QYt*jT4J*l՝>:@\,Qwq*t5V9l:ZC5-%/(\$ƲIZ|/[] E~UwnGaT{wݻzofi J0(e+BE{f6#0Fu5: ٴjA~-LuNO22O :eE?M7ew?~WWOO!4Iu? elz2:s=3z6xwظL;ؓqq9klhٲq,exH12d.'&.‘7F7( Q jO:^k ^e?,2^#.HF+OtqX}ZF^gxxJBg9~6] z?_*]WutOލٳӯ%͒@}v2 D4=-GxEiOIf1f9.?D?vLd_{.C:mfO'zߵ zzX4wna!:nB 3jOO^@'Ivn5=}sL>Hsi7+-w80&}I r@DcUAl|՚#(ѩFYp)^CDSPPfZ5DQjWzNuO p]O|?sl!wL4zzFs^.8o7܋n[ "h>I*Ek8s c[3.Oam$ CRotKk?H?6:/:lWgүstPDgy|w¥KS[73:mtg=n5$EJ1~3S1*@-E(0nLN%5 lږa,s]^={vU4u% {s$izAjAoP:[Q~"%?j?Uѓ]A4wWpts'K @Rqx`< @9ЩSB3k''?Ύ3>.fjO=Ba_8 }nfw}%d=@/`o%fK,ϿȎ$ZC;v9O }7 jrdڎt_~ R"G?J2Um hE9z9.$}DҠtڮPzJ) ƠTĕO@{HtX!Ѹ6`q:'9TVGE(Jb |Gwg:;Xm;~>xCy=c@_!ĝX.T s- ⮷rA}.e-=r_|rYR^i.wG`);6gґ LO_,' o#Yئ'~yvo7IVgȧܽP$\:w]$8]026KTZS)?IqqY(cO~Cm&Ӵ\:>,*8:4vr=^̧6!5)>xR P:Ke,ZU4%*wܿPݡW>t8]-sUkZJQUC7⃧jCeՂ:22D,W6][?gX,?i>xUpN' {%f4~l斝<?=KVv=E_sv+0v..)e0G)?;geOᩯ5;Ir$}>Q㻾Fm ~7eS|lbӯMmO~ >iعlb Ɇa{qSF1;{이grZq$A9, 7uR%ʨjijjH5{BhJ 0DvG&TN WRA)\t( $DF$bPjWJb%wl &Y>v~Mb~r𡳿˿oZ}WB!$_,Z*^,Z\mtTKJ-bT JT,ߕRS. ֞uP G,"fD x G{#o]&tf˦7SSLcU5.=AVcxⲭ2ACU6)=ڡn#c'_Ŗ${`Q6I!n@tt1S adKZSi:MYXXK `ؤ CYBh0جgS)Z/9㕮@$,^7a|rj h >,P(=N{>>7ҧUۼ=>Ok&ԠBsZ52 &VMOh*ťAП/"ӿ$mj=<șok1pQa:%[Oaٿe#EGh9H;t_}6R!:.9|ѦaK;R:QmQ T?O`>zVxX1Uo"8O ޗXmE SREt'j(@j-jTYVkOanө*Dht}eTӎ'b_;$:a/U%aO;z|!X7KJ,5׺r]ﺭ5Z; x[_I0x:K.l^+Yf?Ys_>Wr:>Vs]쫔4Iq:Cxf.R;/A=w9YmE85t*Tģ XmpQGiV ')tܿ}#K\7+Iy/9ӛ Pn$I(>(mγ~]y x!u`M>gO`{cԚubǑ@px.NI_N꺸TS E(Qޢ';ءj4u Q© IDAT#JBl5=ybQ +)'*|Etk 1df]VSVR$6BI*0Dp&Fb)LJ #v smTQ%Z'D{=X^f}C "H(%y6h(k@kpJUGѺl*03~UMܭlʮ_O?•u_%Q|j* ƽqd?q/n4 \^k*\ox UvK@26_E$I FJ@w BbgQFC^\ƺiq, h g%jfw,}z@\)(!L'`' }h]m¦,p e\?:o^8F9E9?CԊh (|+*1)!PWʄ[{O./n^MKlY姨fZ-23_oY^~]|pׯL>1_,z=/Ko5%fs=s- RX꺬\VmUN Vʃ<{y]RYw*nr^s Yv뵽Tޘuor5Ug1D)FZ68i侚+*ў3Z} F.hMӗ76C&!FA#* v+beT𘲁u86ftT?M̞?}609uVMp{ylڱiTR'6F2wjگ!DW-tC,JmN9{MJkzk-޻7M}um {ʐe5 .bttHҌ$5j)ye9 8~:q~4_?[4)])B+A&M/%Ugh 0s^102|+Ce( Z5}A]JzKmpNEgH U*jJ3u ̈́0$t}.J2c tY2}a0FYh(["&!=} Wv)CK-1h(j|/~u߂W-7?$MS6D"Yj):ݪ5BYBI^Kбy"Ta"hcPL_O|'3W-{g ~kS详~c!WZجflr_FV2r/Kmq7df[6Ɉ:%Ui{\=`TM`3/#WDi4 3-IiY_EvS1:x1>2 E )=|W^}JHĨ*ƈI,y-TRiM4)Pմyeк#!D4LJٛ29B*OsZ4;:S~g~vۛ?HO5Zn|R-+ ~#_n9FqVRN׵ZV}!n)}&:dZ)\.N3)=_DOt$:fOQ$qfQ[ A/ Ѵbn%}h,{/ }X1Mi]"i,Py6ơ\=t;h ރ{-Eӫ#J+VEQ ,4RȥTLu:`ϞD4XrWT`G(NI3za0bT80` )_7bk4t幙ǺY獜^s-cd+^TNeɾzx/Dcw$M?MjD")L,#QD%]ŔH zKBhep>b"pJ&&^Sg J Xu3N ,禍U5!*UAM fd@cY<8q*9_6Ye᯦.ӺJ{m?_9 Lp#@&dIJYtc-.ZA FˉE 84èZpCYe7ivۡ! 1R?E, bMRm ^%iTAATW禵 X.AY`JwhS=yT+M%Jb =T&b;h ͚eXw, Og|¿ſUU"z D|"4M{ n~,1Pot:-oXZ#M5>8X (IBN,%Hڐftt4D X9*8R(2LY YqrQy J%w jtpxS(I'!M5v$!6YjHtUb>cн^W % d}'hI-!hL]V>z t]yQh YcyZcL5Ay(JݒGgoSodjaSVs Vz|}՜z\m٭xӵ[/Bu`¦5wStI|>C*'+|\ d*1V< c1^7*pB+oZH}Okykl3٥s,ﮌz"6M(WqQ͙>ץY %#}\ntJwhlsέ,s8H P=V!⃧,Kvej<(nKQE9_ )i֒$; YTL1\B*.6jԌ!Ņ*H&wqDbJTYMXtjFQ'O#Y=ZS `lB h<e  XC<E7Z}6ށњX_(GJAaC@3Vc@kC%(U%5z:&8_`m2i) %W80Wֶ'sNJ1ȔBgtm 落$PiD77ۦ>z!DXZ.f?ϼ (}G]LPTm"sXSGod؝s}ȣgAX *EE#Ε9qKԆ^ a.ȏU7Lj6\7?I4e+ `: $Cooic+rCV{˼A643>hXT*Xӫdr}ŠWI#خ;/{CfhcpVk$]bǀ ` &(2yC$@Xc>[uy *b᪊()pWF @QX1U$\^@WO"&UoXU8H& >F҄a|[6ʀ/IjiZMQJbBaE2+(^c5짖ѵfNZ+4FAѐO!q !`<󥗗XS_h/X܃@39| ^{)webn_wM@-'E-5۪\xju+8ηX⭲._d/l-B![B!B!1V.B!wzS&-B!B!=FZB!͎}A.b]I˾B!Bq}!+&cIB! {B!B wr=Cg!&cIB!.2f_!B!`_!B! !B!B}!B!BH/B!B B!B B!B!B!B!$B!B!B!B!>?~BB!BœOs}B!B!ïPC\DwY<#Ia!B[n|㟼}_PJI,c7~HوlA}!Bq#! Ƹ\)qcB!-C&H)!B!$ؗEH)!B!֑K B!B[eYg׮9qך[pŖ/rKms3ֽ[N.ǥ7w !B!_Mswm;ƅ.J^kޫ,ǹw.ulsV'B!BH/n[?"w_=U]kϞ_jk-Z+>ꞺY1{R6.))S!B!LPJE`_!B{K ׼"!B4iٿH)!B!$ؗEHHH!B!-BFF!B ŋi;rEh4r}l]X6 A!Blя\% GFee3w B!Be}{y{:i/>7}wHܡeS7|;~cB!g`RR* - &B!BRֲ" Wt7 B! amYweNnǶcmֲR-L|R6B!B !?y;w>pLe YQJi?s-Lܚ@_F!B!:7c]ĉ=ؿ].lB!1o_=ܜԲ^ߵ7U,B!B!*{8~EbǏe{n^k}-||+Zx ;B!BuDZc_xm>v#{>>w,26)w)!B!봏k۷5{>|u{n}A!B!gW`n}j׮5}=iB!B!: >p7-_8rE]XoG~~璲B!BHÇ_pߋs>|ss/Z-7B!B޴{k-x[o]lnuR6B!B %B!B!$B!B!B!B!`_!ݷ;RY]]Iq΅7*Rl6"`-T$1mYH]hɐKu2--7Q <9sfq#o2~hEa}}-vvުfNmvw)DAY۳60ѰOwAym&<} ~lm$IT4hT J#"$kMOh=FǸuQ'IIa`m6هq~~:6>??ID(L<([6@};\cyfTckܽRφg~q}tI˞74fuv^gIDAT˞iy}A{W[ /4h4Q“ڎIKW/{^~񼻔pywV(ݾfO^mv~۩v֦kLI4n}zcNo:oz}1::gzvݾ0c:TZ P𰿼KK/-=W}r6VzqEA.dmoN ,GDoeywxkmqǛܲe߇9YW}A8:бC[2N9F=!#üQ}sn7x8kS̵S;s|/V8VZvn.paS[E0Yk~xqg=.C0?`BA?H{ݦi[r 0%ay¾_rnm}{*23@(g___Sw QP֦k0ɰOwAym&<?6p~[[[o_FloMda?_bZES..+ w6ه}߾Ucva|V=7oR~I/ 3qLS[ssڍF#[F]~C$Ϡ-s6?:~adaaI|9DDsDD1E~D;wmgfm.=^~5<74c;tO~5FcG1缾~o 87xdAgZE ֦kKK `Fu#w}k 8uٿ18:P-6gauEj}Z%VW_j~vܸ#Y[rjU=?ɀrk~m^8Y_`> //˸)33ry9}em6 tJ MfmscJ=ysh]omcm^!=>=X ugsmлo ayy-""_Zz''awT .# wp|ƾCݽְ K1q9X]^з<>t;:;oT}y/ zu\M95F?Ƿ]UZ}Z/{rN9zL?_:F?}\վPk ?N{AנFݭ P¾1_^^My3쯯[̩;((kSWdا5E(h|B޻ޞaRُב$4~P #"$kMOhϿwI(ufܣ8??هq~~hξܣ8;ro~q}iKsv^OJFm“:;0J}g5m_rKKd?d5嵈XZzvNx ^cWV_t!VVчWW_aa?ڽ>~~v@/X}}2˸)33ry9W{}J hw)ڼ|9ٵc>W*:$QєFobsS-(Y؏H$U4"Pް1>۷j銞}"]~aak{nQ[haS$7w}X@/T Ya Om O""s} O(g-,?|qa_8: LbmaaVZ2|Y[u{۰}X@/lدV?/O{׵ۇB}@a_a_i quCESff( kV5sjN! ޞ}x ֦k69[wدTcku$I)F#ZP$I\__hwEa?bo㟝}:E{_36SWVj$Pim3?/7;;ss싕2nc}oaI[_zׯ[y}yLRwnenlmJF~y}F8 BdG̭ @ҳOLOO?w imJON[k]7gs6?߭H~qL~uC<ey}hLKeǹ.=x&V;Z%VW_ؗFlw{3 7}o|6 㧏IWsپnUXq(]}Qgk ?˸)33ry9}em6 tJ _6E7C۷j1v%IҪYzױPq~~Gþ17XeQJfܢN}8~4?'m}[/{^v;/;ߩSxov]-(on/.>zaIQ:ש /} quCESff( kV5sjN! joXƚ"~|J! '6~lއJe?^G$*h4b{MlnA1(W؏H$U4"Pް1>۷ {.#{C{Yssڎ;??''w|Q~Eč}y1ӨZD~A/=Fzylv;=“~aq}Z㧷;][_Nۧbi陰?p|r^^^c// aD8>ڷF[^A|u}1,J6Z/nWW_DVi;;;6P&_8Nvut_zNc9>OʣGL@ؿa˗ǣGik %ǟ?mj ¾~˸)33ry9W{}/_RIaRُב$4~P #"$kM7G~oU2Gq~~mDa~q}i?;ssU_?_Xx֗V/vlk ۗ^wa?mqim!: vcݮ1l_; IOO?umX 96d?5&۰n}M_qv^LjX]}N߫;tư}7Lm؏Vw=6Z}?Ph^^Ua_a! @˸)33ry9W{ՎX\WM`_?e쥥gqvv6{k"-.ηv?A/կ~9 Nf'߄}Li `%>LY`ʂS}(y`ʂ~쎳3 9;;_ꗭ~]_ %O>GD?%=~?gDD<{DEAwm?87&IENDB`MP3Diags-1.0.12.079/doc/logo.png0000644000175000001440000000561511304451544014707 0ustar ciobiusersPNG  IHDR2̝bKGD pHYs  tIME  8$ MtEXtCommentCreated with The GIMPd%n IDATxyX?  (BWMJMo]vR+5"қXr%)P EIqd߆1Ό8izo60MVB5VlR?FuС& _ƋI6İOtxtVv2 GT_DG< |C^e7uںh|`.8=z #f5:NjeTqf{ܿ;3B;Үֈ%"C8nެ76?%]s4W]ן &6fy;OӂemJȒ0&`ngAG}OQ^Pny||8xT\nq,HHQJЂחA)H d`ݭn<>|6WDZ7 DU7F/+!jeN|w,JcfkΨCf0bq+ß| Kl ¡#c0 HM1ܓW廱=Xgg9Hoq&V.6L͆_i"Hͅb36돗ϾyJsN(G S[)\&({&[شx#jk)~㛡_PSY _q|[ 8n=p VX'rvG55ݑF +)WНa06A=wnaӾY :Y 4zt7:w%hHA_56XvR'Spg8l?U%!cD1̍]c_5 ̀AN^Ǖc8&QKԖhTGVݧPPSp%RS8H058]#1?s Zo ~Hbڹ;ܓ/' u?[HK?82vc 5}{@>Z{''lߦеjk!/*>}Eg&4acL~ė\=KyAN~ZD(Y{nSrGsrH(D$k?Qgb7e"%GقMݒhSĆZ9ΛšxOc놯zV*+K*IJ{!5Tjuu84S8, GJ*AVb U2ԕчER|w~$?l\mݛJ>& qc댍'!xuW4hէOW?#pHּE=Gv 5eZ@{S]ZEY?K\U#9J<<Գv*2V"D+e6unaϐ i?ЪJw-n P\LhZ[RTfglN>G/}2+gP>Sɗ߬|<̱xHNBV/pa"fb'foR zsH] AD⇂<sOהU)5gh?-;zcIeΖǪ"E{n 5ɣ_iڛ{p"fF$.Bd?MliCdJP|19w, "j Z9/}r=28+['r+Lc&f7޿Pwr)`~5+*MJ^Nn*k83wp".~2u\z`aO&TUo~vOQj^: 01WjtzST>ˁe,W8꩹;}nbt~xm[i'3D{;aО/yAL48ק;97/5v- G?˯(;x5 Yk[v̈ng$aM;oQ>v?\mEQBH PB}CyQv @zlNn:4&7ZUiGA:<Qx? ?|TIENDB`MP3Diags-1.0.12.079/doc/140_main_window_tools.png0000644000175000001440000033415011264640407020070 0ustar ciobiusersPNG  IHDR\ϦbKGD pHYsȥtIME -.U IDATxw`?SvgU,ɲd˽ 9 rᗐp)KK.!ԻRH(&J16wK,ɲ)?xerdkgvgޙy氖F3.W?lھHgq]Zd>{X6o{5 4m_}A>{l?Cm^oFEQPϩexG hY+/=Ϫwf9`Y`"@ #ӻN$no嗩yж&,:r_}M6T]3`=4OP5v99^3h 66g?TӦf2-.κ#I-eOC8K׈i|^  5io/^DhOG $Elq8COeXv%{[x8(** 'Nj͈+Scz ~5 Xv@STTiLPuĺiŘS$hakpι0fX&NY1 Qc6cx 2GuL @ gCpR\C2Syf9b8x6!I/|}'ӡO&4L6i^p0oL9]aIA C;ȲBSS{phUc$:p]̜5qȲ,F)@ `[pI1\~pNz<3'L(.9ڵ\zl4-:@g8!`: :Cw 4y'd0aa(A$dh|V\ u3+*ʎ9OZȦCIty-[tty,2t3Iͦ 6[Qg`Y&vɓ2oB{Ȳ"@  jǗs^ʕwuH+ƱCcj֯kmKfŠ1O!ud;$Tߖr۟>;y.)UBZ8hhƼy3[N )Tijji&i1K.9x? SZZݮvH8VTl6M3QU>_c+=g>]]],}lC#@ @ r.}}X~BK̉Fc'sWSǙɊ3gۏz|#-_u}?Bl3g55)-*CĺXH͆CGw84R_u=Ȉb8b؀u}h~(Xv׳q̼,˸6 ]׉D"BAL@pRsB%I"'p,:d_zi#]Pv~hfg0r4w("0{wS_+ebf&&],E-E @ d(BӒG˵2TG`Ii=>?a۰, ݆nO'b ǏI O ?'5e'e{mݣrm-ZʕGz^J;a[?I$)$Hlϒ$2Z@ @p\DAr^$ ۑ".Ԙ?p!H#xq:a9",QBaP]72Bi.\.'.Yx"yV0 1} *+'2qiZ477F$ Ee YN~$ YN.F#ttto_3#IyNBXX3A!VH=tX4 n 3I2զdZ6M\@>wVe_CHUC~~>cJ>u:'NDȲ̚5k8pE  tzQt=z z#tSNcÆS9>xyM=}e̘1c:R1لG%]󢺋,HУ$L;8;{ ņ̭-,˙iwWWAQT QEA$8Њgy .iR_@{{'^oN UU$6t]vaPP(Fgg/Dx [u$R ClaRRRBm$4xx<"FyȲ *IzX466gO6yfe%0g, 4- `eao! p`+[lְ .G3,kP;pJr` ?*˖K_8a)XbKZذi#sfk.<5wlv-"&Id}2"-d2Z)-sfwLeׁ8_5]U`d9gSŢ6nZry666SZZ¸qTV%?ߏn'D좼m۷sES\Ryn/XS3'ݽ O((?cVxuD"v+Gbᰆf!R_wmBg%1~ /z9w`l"Th}Hk7bi{FŃ>»g<韭r _i?*o {T,kl .`Q0cÆ*OK&5e]cd@ÕS,r^D#0 esرx<#:>={6m2ǡ7 Mi-;9l޼3ea&tٹs'dϞ=l߾t=ix^ 3bSAe0a{?rĖ6B(6 0vTUEUUEATX2@z=D"Q\.)5"8{ #,X}B0/ UPV6qԴ+sQX?";XC nwF8r:)ž]TǗ?C4L4MbX 0۷0NȳH@[w~qia"K&&%cZ)b fcٰllv,YɧK/f©'Y]l9\X=su=Ŗ(uӻ\yLƟ:\|sOQ2{XK/?^篯y{(̞=-m%ϟ z0w<6o8?͊ob999RXXȖlv>Yp!Mnn֭DMMQ+a۾W'|p8vw($ q9 v֬YC~+tmm]=+iH8 z =k)zJ;@ɝW}əgT,]W~ßpx9 ),v%MCCh4JMΛラ?N*MǶm*($Iqnq 姥Nu{/vU}+fs"rݶL_ ǡP$~zB:Ŋ=||<7_ԋ2]udn6+V?n4M.\Hcc#,pҟEɌ31c`,cƌAut]gܸ*V\qwD(~w]K$W>ecN{w=W]u9~O|6\Nb8&R[;0 #@X,F"H$DL]z0p:x OuuNEԀ!=ii%rxxPZhI_[ibPUH$B"HyL T7Ȓi% 9O„ ޗ*nTMUmjJrw@OVt9%k9OEk}_KG2snv5\JBq@D45%σoNxD\rY"*gidž Es8(//scٲ3)Sjݎvf͚AIIy~x,Aoo?kr-H);e˖c[7we¾}bO~?޽D"1OOOO&ĉŲL6m4Aa"эH<7ea $yжfQry:0I4Q(1͇A,S4gĽ^'>+xfR&NdʬI(#л/))CsXt9x^}կ;9Z[ۙ4un#{~׹2tGoܸqgwcS<D8.^|q9K\6'8//MsPSmvŞ={ikk~0Ph4aߢr9q:]xrss)(ȧiӦphq<9NCOO?bCИ4718Nl6ljFDB `&LrĢ纺=y3IuYVUVK4IFdܝ,g$IN;VJ,0hB0 n]rQFp%4Q[7l7{D"NY:t+XXXd v{ml*6{%=J^ۆߟKUuI..v+[~O`5t&-;C[:>op8"{I,CGe_i墋T}믿 0,LjEud?^:Iyg-_"+AGGK>AS~EfSyTVVpues`a㮻>};ooH(K4`b^[իssG}oҶ/ٺuG͕l #~)e Tj:zz_Eqqް۹b>cy_i!?0k,0!%EK#׵RQWa1&8]( < 3 t 稞1'\|Z˖/_ӧOᙥK)`ܩ#疏\5~E?_|peզFNn.˴P>y9G|}BTk &МbdYJTMH%nnАO//k1@[K^d6g6vbO;FeDMCQvjvd(Ly K2|NgW'scժwH$Q Q?3 lݺ#ֲ,x=I"K?Hww7`f*Cޞ^Ə4M{<ЎtDWzyko5~.^@$aeē+v:1{#aa)f \5̊=!~z{.!G3aB6l`֬YFRyNϻ疭GV+/ƟA7 ԷдUҹ™|KZι!Ʋ," QR2CCUAvN'h@@J Oy:n4)Sj48 h4$^o&Iv2R(S.ebI2,IHH6.6=ՒI*($Eni3+qWhňFeĖl%&D_pnj2H^3?zr?p/޾C0ˌ%ݜ`I$#1bDFl-./˟/meӞ _>w7Kuz:&OKy-s%P]]?:)6EXe-g$qʨ$Yv%eLT3(;K-[lOy+L<Yy[\.c,X0}ۇ,K,X0ɓkFO_kز Ohal[2T,)Ғd+f}aX:N D*[N: lU]đQ:7&ף~Oܰa3ůwqҥZ0e#H+*̧oߦnW\y_W~m^Ν(B^^]\رֶN*tuNY5!,;`o3$JrA_^H|+k!f:C&_ ˇdVUUA$Ǯ]0Mh4J(xa;n Ncδjr. xBq1m8&TWx B!0mRUU9jpah4r-IbQjxd{DvIuxEvםa[[;;;Frd Y㱬Gcc3WiɑF(SL qHL',"qH"y{{r=Ӱ0}Jug z#H`HX d%dEJzXXG+y#=[2aE^M@͔ىn j=e;3!R)<_ףٓ/A1,L`:H}N`@HW['O[|)/vœ -B P"7M ѣzjvCq6nVsǓȲL8{U(#߮0- 0M D7 0M r F osU xTT8Nvt%y4 0ia#١g2v߈{{f<z{{I}[p: Oݒ -T"&R*d(YfJа,30Zt RVRp؂ l} M i/ IUS$'0QHt9qDrrsSAGz*JcT޺̘3yleZAp\ڹRpqS_>8x09Xww7}}}gŸn[Y_XNK(IJzIr&lЃlxo'7T6MCQ5lv`&JzusU{ѲFbD;} -}4ZvN#ڡ5,S~8-haymV1M=COD1(SX^C,~XJc-qH_u^r 6 1Dlܸ.U(~ ?6;55tq͚(غ= w&3֭;Ga˖-\|ŔZ] ^Il\\{T \r pEqq񀗱ϩfʨ2P"3ͺ05fx}RFLpY=L^e^y}-|?N$ψ+e% %ƪLL0 G?z^,SPK{{/veA O8te7P]ױ,dxCkkn9*vaN$IE^.7+۴W\^I !vr %pDĴ.ÉCaEu(w %Hc)MǴK1C 훳p#vNқ%% _+EhD{Dq֬YeY)aEUmY"KjM4Mmɽc?]]]ֆiCr Q-a#3i4S-'??FZ[[CRU1I>#IT@eƌTUE";O"2M 1M4X,ɝБ-T`n-GZsy:y\qB̟iX B7M,#4M I$#3kFDٸj6l9]nP;#`TUgƜюC7oƀuMM7} ݋˥q-׍J= ^b˦M[|o%K`1 #xbl6=G܃H9JQ3gfeeWImks 2uLP #j& s2м1wn)3.[Xʖ\= k/ Ew,7߽B&&oj?o~6}q,`9hvgϙ3Ms=_'s Ex4#/߶ sކ=̙7'znòL:::X~WGG6Dqj*™-uRNThb{Cs8YKW-C-\ee!-HXh0hk}iQ9a& A,'c&nal6nRb8f n?JNYEa7P˲]切cHDIIt I*@`0ݮaFdp8,Kb>Mp߆)YL+;Yn2dG<(!EmD[_$|k);2o,%Ţ;(An$ˁ Gee%+V  %ْ #:puAuYa:f>4p]8%d׃]gx/_?$Î #ŵOrQ6&h@6,,+H`6j\4ON70 #W #)B6m~`\g@Lfpy_>NW=ms k H%9z,!KrHGxieOUI5:n+s&ӭGoo"0h;4ӦM;#(6l\'80t?ٸ=.Q Ŗ 6#IqM7q5d½pB<<O޸N{0h@FV6^;4 II .nмG--?ʖG>N}&A ߋxN2~[1n#Z=f_?Iyqb8sϛөr&1ud>q;Nx9Ptٽ{&L"??n.\ ˵M466GؿΎ A㋜DtkuhxtgdLq9A^:4Gć8cƏaio勞/{mn־r\! IaJMq#Xx9ES0 H4A40Mlvoär^ٳyg2e">rs}r:L(JOO~~sBdYVp$&Xsƨ4~KK.~L3=v"#AsF-݀Ȅ`o͔IA;jdb!3,:F:+Si =r,[eft $EAD32Su r}^]TTN" lHEQQ1%%/$6[@(:;9>EFD̖Eww73gԻeb`qbly3Sl1.OϞ],i'KIE$,+9[$̣_)#ƙɰ0SjqCDa4mT nys`re۩= P{!BCP690F҆NGž`e&pF(j$'`YIIQnYfin(fY9T._P?\qiJG_5+/apnjk&1n|-q ţLwvg&6nLr-\s5h6ߓtڴi|37 كWWL Rӟ(((`ɒ%'/<18$b E"ރ%ǙO ^+5|^JJcK菄9!rwU7ɾm+GTpyw]&r7ʆ2^P"ݚzJfDՎ&I^1Y S1Xbq0z b;w62uTƍӘ7L􍤡1*a ܅F~~>6:;;yٗ8]Q ä@Sfzx<ʭގ$ KNwnn+5REQ&=G8JGGcPnc>/nYeƌ)bVN+pLB`EQQi QZ꩐"92dYYd /!L6a]r \pl2ڰ"$en\|cf"L,x[3b5dIh?yfz{H-?rk3g$hǠbKv= }|3,s:D"Dxl43ƅizcIJZ`SP2yt\Lu>M ˔0da躅 D@%lT=@r4AX'"zt3dm8DᮓSv9Q[v KƱٓޗ*XeR IG6~)/XĴy)fJp~\͔J7hm~KD-K~9B}r,q5m}֖t3ںu;ܗÂsG8}eo ؘ 񨬬ŋv" /sϽ-x<,mBqqu~bwb>S[aO|+MӲF0%a6 L2;3_W d|;!HP\\pĢo^TAA2u,YBP\. 3c쇡p6- IDAT06(tv*ttnxHay dv4z{WyyO' 88(?"vKݻwc6?{Wq~ܲU[ )6`J B($B!5&ZBbqŽJ]Il˶d;}=+]ޝ;w3=gSC P? jkkݻ)S1t`2ȾFP %$P"Zkށ(QTуm$AȐ(,7sp> pT5覅YƖґ^?Jjm&//K.$d6 Gu,t:˖.KmlەqPT5iK.[}:[DD  >QU5]]a;[x}^C!ït.(H.dZMEtՋ%m࠸v 4-tMGv=eOA~lþhs];b:u86as˭C*˱F/=1&Nr %`oumn,47X՛hY\h g,匙P,t,~=)BQ=&qW@~=k\1u=rf&㵵u\z5o&ٶ͵_>}z8 ?>w}[;pU⭷Cu Duu =$>"O>Ǐ/7gX3ȶ[_̬Y\61%JzpjA"o$C3{Ųtw-+/ '>aÆ3tͺшHtO JK Rh?jFAEs#J&j B,?^GiH͖VAN껥/_ҥxWx7fdo=J9gܳϱd2Ͽ_X#nr0o<ƍΤIgvV\c}In@RN]3&pq;RVk674P*")pD]_oEQ0LPѱ)%%UTT9pXx ### ^z,jqOryȵR=#, (uDGVr&@[Ǎ$rqӼ8FnƎ6OO1xsQ.cU1(ߋi#x[:%(D)6IK,Ik$]"&I+`+ڔ1kg=Y9'IuyAJJe9mXDŽ#A7>6-_A>P``a^h&IlRv~Q 8Gff&-iomͷ:%-vM+gHHr5n#S%?* "PT%Z MwJ'YĀw8ӖX$'Oc@:{VR?ľOwN䮶~Wio +.m #a*B TZ'!]ͯ$9ҧm;~7,s7:tk-ehj'no ȑݫotW2uT.-ZDaaa[ƌ38կ~a]2!]ÐX68N'$<ħ~LCw)0mwUHUkƻ4Xp) yǝ|.Le.n3bsye1h~}>CQP+9'3?aɒ%{q,Z㏞>(h}F(,`!hNH6& :A w{U{TSt(r9G&7[.T9Q[;䶉i464!qH:iQД&9& LZ1["hIm[wn;iv %)qV_3 1hE6n(voU Ҥ~ d HMA#2@K{ި0VGK 0ZMl)D;L.yhϖu"4ꝴ^i!Ҍ%)-@{6Oʲuq5m /qs(D /-)Пr4'.>E5QDÑSTՓLGsKQUiljt,^v-lz-qKa?~Kv o-+iZMSzj 7V2)9kƦiMd)c X{I|)򨦍a3ϢrKuul.GΗuG† [ />OqI:zW0n+qljGI' (h#R%L?BU0:CÆ3ymmϟJ.el[^dP-n#0mto`彅ug:jki hhj!2|`o hqfw'?w1?rijTZՍJIm '#D*3ac8p_cFE,x.1"hBl6HiuMHqXُ،mtk-yFQkPkh{x(B.nUUHg)ciN#y;[!(,*b 1 JK<E:H _!IiT`.\p>Y;E2{mnذ)g( 5 373jo*7y 7nn-W]u=o.}aL6 UUa NwP YȢQr/xP(ɓ'p6ZÇqqn,Y#G0zht]oW^Ars)S-++KD,6$Kue%M-a A$ 9I\(Cawvpo QAAAAQ5r?J<,ٔ[Ḍ:N6PSDCC#o>-L8dW]u~6zݯOv`WOC{EtIR7UXHTy]sm%;k٤](g|6n\MS$ŋ`z*w<|>7#q0p)%2]Q,?#;;]뮪*5dys0E @b#djǒmKh 8o)"_1<^-X/7nyDtyv$DeI ɺs(yAI%9]1S+((={Y59N)-M4ʹm͛ٶh~ӧ7ׯ?BE8 : vT,EQ^c+lZA(IMݴ\#A=DjƅG}C}I{YK> >> -AV/"%8`@ @ee%999x_mHnYDXR0l"#(誆Whb*iUTSAU4p*.]/)vyώξ~Mxw\vwz㶧U N{ijl4B{v=**&KσL5gM$;!_ma`l0*BCzC$ ,x|Z"&cv+xn֯?Gu>mkZ/^ƒ.|O۷yfϾQFp{?cio߾<L>AjRv2dDZLQ#KƦe>sN(B=t]wn !vI'̙3꫷W^̙3m+뮻7n\;C9 t/Xc=_̯ш6bl!A]6Ab dvnU>Y5MB }qeˈ/߼U[RQO3vUX{EEEѨRQɰ;v,kV-dӛ?_(K'`5Ρ P6)aNfInȂq.딃F#,]6 *3& /Dc(Fª}kY=|OS~_Q]]it \:ܹs~~=CAAYYYlڴ eÆ >syyyVWff&EEE_{zO<O<?1DV}\?`ZC{xyo^@$]Oxxs(ReZ>wK|RKh5vݑGu&ʶ: ~/>#SQ=9?K,n V2 ` <4/?yX9w4]&Fcg:A8)=C˶AJ>Ÿ8뚿 ǰߨ:%Eqrs1MFꨫPK-?mXEU|8liFX"$B8(늢8 Q0b҂Q׭@JJ=I&Dw McmtzxW FLk I)qTqQlo1vh17]|96WP2Y!U薖iǣHIEʲX8Gr014+(1j0@IFI$!5F–x-h*"$E)'E]튾;GqP/B`k u(yFt,ze\c&*x5@8܄PdbfOqXSXM_1eZ&<¡H 5L|.hs[o }99zM8wϾ`֬y'߿>i?7|o{ أOmE( Sc`-ĩZ^!OIkK~'\s5l? IDATذSN9on,333BA=;v,K,iTU_)K[EJɜ9sx L8:jH)xjDy?c~r/Id=eA3 nmh m}tn6^xen6}ɽ޾KOzS's?>OǞIJ,̙É'H^^^]] qfR-ː0C3`ZzW_q׷[luX2-ZĄ G#GdtI5uUU%%%:9Ǫ|deePXXȍ7 7ܰoԑlE% r;*Y}, +̅ 0^Y0E^$VaxZ"8 +Tpm~S9k P #ޢ3Ȝ(ZnoYJu[d{IG %EmYB]9 plRGSSsD0C7o|&B-MlXc1CHϢUN[ZZId"`V^ ]AT 'f%ER!KBZR$ I' iöe%h+d;*pVjHu痃RSMM۶innF4멩ISDMDu(++K:]쌔H㺮SUUEϞ=ի7X߷]דka9Fm紂-)&8XE"т!l];IK#56IBCǕ14Rwea*.LQ(3@x āح>~0.^TMG$EvK8Eм|)w^8G'kߑob lE"!PU (,o[ # ]Mdi\wM3z\s||B0{}7t+mӷo}?0xplwksx7)))o P$Ol1VRx 7t̝;k5kt)ؒN8_vVÇoW&DvvvYigq!k;vmJ?|vF[GI?Eo'hGa|FCsT&VSb=r\aN7 +~y;ˣ悟Ō)#p0BiDQzI}}=յv@+@+nAJ^8(B:-IYҵ'N TZ8e QbhgfH2%A}PId ||+ev[/W_-CK$vw}7@Hx]C"Hxx6%##p8LSSn.۾z|38mi<}\z5|x |>7|3٘[VشDbd#~oiP/䪫%x? =}|Сmrrz7ŋwIfӦMw>kwrtX= ogGhXYgݝl^&NDVMHGaV7)T|]`=yT [#>BU<>+ Z***0n;p%c3`GF0ÎZ9WsfO8-@Ir$v/~m6VFN{fl (pC&wm~cK:n^7] .{AQb63~˲an\2aV-B:eSKFOJ8.@#l&  {^EXD6nLOAAK\sd&#pO(~ί0*{]W۶5貘RLo)%^h4Eu"!m$4 DQi>quӤ46VqݦC$ X,vJBm8(8[1]J'g`؅N"t]۳7͸:1,+@^^i%cMM̘1h4JYYsqߙA ^zk=7F|dy#Fł@J>+>C=Y?˃s\lv{p w)g6㍬Vf Y45pHߘ;tyyPP lZIB5+a.^,h?NbV %OcK+@Aٓbq?".\yvmRɉ'FNNFp8sϝ$_\M3:ׯ]~at]n hּCdy3kyqWdɒn[ƌe]ŋ7n\!CXfMZӰlOii)˖-c̘1ifkK/qKϥ4)fۮq]geؤ2ٝz~Gy2ϛ{ NC w?KwQ[+Kf{߽465{t*6WEI$CxG|<в ϓd >aQX8f3Nt6?m2!ef6sVJnCT~9*S=-Ke>mGB[Om}S)CJ6M͛ˁ1zx<4[Ed*UHd8"AI;H$'$Si' ȸ)IuE2Yw=5e< H GgN)Lڞ%pםG_'AQ&g%%%ifSJqD%H$`K K]7iY0mAݝGX &r$ߤ."rrrX~5vrw/?R&*v8aGeǿÌ5ӻ_? ׃O4Xעd֖+I1nGt r G;s8Щh4jRdg$ufTUsK/9cԛ?i\rqD6eC6i 'NO5#mv]IѤI,9;@oEѫ**V軆u{ef˵\UFm#7|^r-l )@oߵ$y'frɤpࡻڶy+>"ȣRvm9rBUU.BzAp91tPǝ>zӼ0ߘǴ" MÏĪO!![F;nirs.ܘ-/MmbqX=-vCfONg;GWu׭wߟy≿!&MCIIn]1)3̲߭Aq )((`p |gl8q"~-3gdŊ|ߥϘ1?H$gAw'2~JٔǗ{ɧbcL]iGO1n ttW%W\t9K/x* fԩ̙g}.E+G|CCRRb #^[LjgwOeF{uygcgS s՘0ݽmhEffG=7={vXk2s=Ùg;s=iGݼy |r<uG!gNt () dZt.m " -b= `KS_4O`Oii``0&e |z箔hH[kPgEP:wi:T.'ON%2,T4~R?*UUU 6w1MD"Annn2ǩu]G׽N#N#77>AC3H"HlmtS}1Ǵ}򲽻 jD(++㣏OfKG1u-wgR:p<+q DwWo,W Y}KG/@ p$W Gh`+=g=7Kѳ_/ڬB=C'9yꨇy =v>{''F F ޘya5lk({z{@Jwn{{Ҿ΄ mӓ MOvUM6ʕqA#wZV/Wu4M/?BQ=.t;ycl޼`-2T.\NSHFf'}᠃"+0{KӜk1> 34e:>Żͣ"ݓGAMMy{>zrr ׯ|>?{'{/α? WCMG,_u C`,V5="▉͌/4w['ǩ1vM~º[СawL4>55 ,UJ(lQ\q[Hc`4PQ^PMu:|q ncdbo>l%=Qx=_'.x Y+_d|^ Oǧ\)3g#hGQAMM ={0 #((( kW@vkkkEsP~Ȥ:|?BEk%9v`K |I'+#\`G>3>̞XҶUEAJ?g֬+/#+3Cw]«o^Ǐā8@twϷ[\e'ݯڷy\%3;($1l#By XS5 iy˲m+Y~c˻V2$ W+A@s90n~384LW2F30?տH05wHEQ2 IDAT|>~?^׋AQTTz5t{=i_ dWTT_]֭AEL0 630|J9tg裏4M_$z_~ GIBJJ{0 t_w:~ZjAG3:rN!!Haa11z=a4?$|o;oogtw\57I1:iR*?SBB%O=/Ҕ>r7ãO#.{H5oi܇ZD;R߼(Hnn@iPQ q\ <܂$nwqT1[nbq>Ñ} >~= +NFI9{^#BMB 䆕Vzt x(`H<,5(ra kNp5%J RpIIIQW?ESSI"xl k׋7ڑy^ :OW 9sVRМk>#g /bH>w}[Ո'?ybJ"#+ YVphQ({  SU4LcbIXOrQ.:z etFb̙ӮP bT @0k[b(u#oS+X|n *gTyYpe^ejQ$&&$=7+TvmQC,Lp_W*BC5lm%ɤ͉x<~jyL>IgE|)ES$\.n3ν,x2338}}mS;}vjkkUYY3 P?P : q(y?C]l6ه;PI@Wb0'*.^&>>>jjٹs;c SV9=QFnE7X~ D W =`#wҗW3r {Vz}|.<}}>5~5jSMsvtC5z#:3}8K\\ aa455cP(XY4!0TZ6E8O.*L3tF?S\3vL3 Xaʝ~]˄*՘T2j4)JSHG b)bŝCg&mç.j5ѩ:kqE{M܌4a=p6n嫯ػ +7M7œn!$S_?,Zhs+2N\$&̴l2^;ճxyJTb4G`,&^|axݲeyLz!˼G[E;l$ȶti͙);&O(.宻R((f6" QDD4YLll ťcJdx&,1s뭉^Nd`[5O\t:eqF<[|>?z錅Ox߬2qlGV2Č=䪕YOPP`ᣏZa^n=5k1̙'SVo~S1$'0wiVoYOii~wޙ^?uJ"KeVΝ맫ɚ5?AR`6k/[h,h52FdY;4q|?,.0fV+045Q"",lvӄu;ž}MưiS.g=_#bH,peQ#(,M A/v?5g?[JjjHNAQf"&e|i=\hc(n-#z>U*&F 47ۉ7I~k9vZZOn~JK8w;NVIb0 UQawDG냢\~P(̻V**\h#*JGRRjuO$Iv}1sg2 UˁJ0Tf! !AOxZؼ9 Y.CPf2 !E-8́m;϶m lݚ@VVU*ii$$FaaĬ{>Nk)-#>~}̜z0|/(/JSCC>Z%/ p22B ̉}~5>Q8h~Lyy?_EH\L.9~!/6ŒP$NÇ;ٻn9\۝44 a2i SQzC@ uNWo7iowjU>N\!h[DT`ذ!0?nW_[oMdX6(*JGZͪavvﮧFFG⦛ X~Ld9w!J pCȒBxki<_j9|=۷'k))c ŃqP 78ȲL{ǻqde͝7xuutt8IH0:'"@p"2.m7~ YDy@׹@QBLL ˖Egm_ /Vjk9}X2݌74dg'Jqcfn?ݻiowPP]l4{K_=,r挕aETg2 ˗GRP`!54"o'o矷3ز%1K.#GNBClG\ar8|7T*vH!l6ʽƟL[oMdݺy2,@(8c@]ot'˺u,^l`MwJK "="@p!I2uuz~؊$qG2<p1fBAXn!33+JK{ٳ^oOd˖8RRL3v^TBZSz`XBBf瓨u|i ݖCh i#"KoF;gX))饶vՃB5kYk9+qGr@xx<ee}44 `dȀ /\QadҰn]LL5dNdŋ ғ1@ u'Q]m8p^]wrRT*qqoO '_tmTWhjnKbժ(tDDX4ӧ{pa=#0}j-_~IHk!eVdn?VA˭}==ʅ,X,:"YB~P#t8tW_͖-<@Ơ]Iq`J[nI0bs&qqplHjjf>f;.)իSX|rH;>ªϢVcj, =/xz=lc-fŊ( ?{^ZZ裴s笴q j- !??իYB|ITYWZOB'XwŊD#Xn~JXr֯ERNlfbpx*:Q(x'PNS)<?ğ\^?~8* ?SȲx~ӕ$&,WVv:cAs 4.lms~N@ `d`'?TQSc#?O,a8BB9jJrsIL4jU|Aeexc<ߞҥk?bk rrFnI\ײ3$cG <Œ%h4k֭+14䥵΅ 9GEEC8> 5!,]NAA$RRLD`jC]]N|wm@Urؑ٬ ||Ow( n%| bXmmC;։gb?QQJr;S89vCZDlF f3=CAwJAnn}0wb ˞=J\3@ tz{]|A3ZCsEEQ ihNvHahtcNאNqq[Zc4N⥗.RRCLH箻R3T~{K>:;\="CQg`ݺXV"7BrE`~r@ ZCۓxt A/ǡC;ED;H&--4`}}.jvhh\@nQ\C{ T!L7=OWá +8\Lp@ ̯୷yzl6/[GU`@Wm&!!dv6o[͵V\AfF5/higj~75?Off(>m<$ɣ"KM>{f,7Caa$RSM *FN^y'7-"##4)2/x&=uW*ǎ+%$S[kIʕ*!N //fu6GO22B_W .tv"<\@\ m@HLc{x<wޙ̮]Y,ZZM34+WF-:͟@ii/ޚĖ-񤥅^6@VdfgNme,MEenuY£.bӦ8BC5Ȳ$8>]R^KII/ xQ*!*JOQQ<˗_*hT “J^n^zX2G"'ʹ&[X^ᒜ[Kss\"7 E|J-|Ҋ^{RytRRBP(D;K4%&bbϷ':ɓ\h[nId2 fP 99f>m1|UUF=v["?Azz(==njkm9cc]( f-EEQX9*X,: e -v1<}u;E|GdhZe廽{5Q_?|sgS <?[$*JϊY*&3 Y…4^٬3{tR$lj0s"IÂKjҫnON^Lcy!E oddPWwvG}JoKjO'=SQaWj8|P ߟ}`b?ou"23CQ*c4w!|ömQL0ֹxf*>7vdbc%"#uȲcsG]H~"ed4mdJxyrQ@ .@ ,T32u܈HrW{hZzb Ŗ'j(.!!CsIDGT`ETcӦeWdΝ먨cDRRBHI ~ΞxN!4Tڵ*x]].^p--X6`PR]y&dvL;XtA@|ࠇ;Y>fNRp 455m,/b9Wx'g畟kjpt=0n] qqX' 0g#3ilt`0 j|>etJ]O'B9@gW㥶UԌ?nzW?VzSO8>NSص+[nI$<\+>P$%d-p`;~FYY6 #Px<~>?nfQEh^V^DHP-`Ŋ- #6րBV^ࠗ[ؽA/ߞ'9GrrݖHLE SZ~yZ hAU9f{3S,Xnj/^{XRZY"N0>Z]9`"}D+mx$jjlz EBVcc2vM/>^_^ffv֞!33B1\"@ "55T%\{VֲQF>OW}chˡCr-6- dY z0 FG=ѣ]tJ^ $Z᧩iICff,,ZFBI}݋,#\~7rys,=FrrHP'QZ'R)غ5pJLpX?ewo٘~}_cmkiW2DRqM#e:S]yچ-(a2cg*vMg$IO.Bp<3IoѢ2]E;k$/~ɺu1W]SjX& WG;M:3YR`4IK3k ŋ2ĩS=r- C\ɮ],^6gLZhiqre$[:w׸,T@ٚg(鷾駞}Ge75EMii/UUǼOΦ2VhQe-*VzWŋ6j2z=/&c;^NEp%+k5q+۵,@ e Gvv!e3L}i==n>={tQTɣffMzJ<J%DFjIK3EV"Iڵ1兓` 4T3TxOܹ~^}X8]2 G НNwqx7Zn=ԙmcES8&*|mSzq:twt)^vvetH=S o[~\&c׵N!OY6#ggccӼ^"h@ N}b $%tvػjd`|{XjUG+^ϑ#Ljn)mX8 Y#HLM /\ɓ$'ٵ+ի#G$XA>A/wܑ 7D}[ $kwp\yͲQc7րR2?&?{7фv.v~M^&,R]+{"u{5F<; ٳ)_X'Kp.@ TJ7~G~H4π}ۄc8v`ɒ0j qd/ZGII:?;L">0”mmNF$*JǃqcLP{|Y> II [≎W5Wn dg⋿!33tBOzrOK?_D}`É݄STINOȾKӜj;˫Jeߕۺ\TVdf`4ws\ˮ+ӻVDoܲ,P(&mgZVb!H [ؽ>j;xT22Bv.^}RSM<@*OdNY%+#Տ{\7 {F:BS¥IK~eYK_QAz"MYl)..E  ^55f RrI<@ ))!AzFez{=|qoDSKڕјLbby9pwmٹ3;H$"Be6ZZZM7Λ49n?ee}45ى5PP`AWp(+bjᗿ|_ 땨EL4#_^ wߝ^W\\܅Ѩ{d ( QHA$ɴ;y}~kFiE׋X-]fn9O%>r8|9ʼnDDFNm\[ĒXvvt89yO'?b^W׉姦fGaXMMyY9wn#dt/<\@ ^kرn"#uw_2wޙHLB<>Dmmx7ǃxqZ3Q<'{yz]Ń~-L!I26> w$jUITVPYibr Q͚I8[y<~**TUوֳre&*`웫V76T*a2n$+Q&w"@ t9}W^x==DD*\0k5pH7;LSHO78<8s^FNJ%;;4Yn>*))Fn#*J7y6'{ufM$99aՊ4z{ol6WGh]-$E7590de5 'X;8j*Xօ\@ p8|=k5PYi###Jc'Xx\~JJxFN#2RΝؑ0;Q~*@Yy$-h4-Z|V FƓgqs˲L}%%}tJV$:zb\ aOg0ԬZID&`웫D}}nM$%PA္l6Fhݤ=Koo/s/~0@ -9[oR_ ;'jUj+ ) +S+UUC$&l"<N:Ws_oȑn"#uW!n_[?lIQQ8WPxsd'RS ,^wa+f}6=9Ig023uxn^¾JjpG"-M$e~%IcA/4#-|ygnszN@ H *NR30 !A";>\Q0֩ϫ(-Uc)s"I==*h BqR5jLV?o^/95 S^¹scϵX== >D˥$$3ݘmd:A[si\եL(q:9x:CE ]ԩc˓JOR4 OtB@ q`.>oKpt~լ[dHLcc?/\Nmm[oM㩧VaC F*x n|9<q(.nOQ(x\6l7֭7r]; o{GILT[nIF&4ǏVq7ϕIxx<nV[odۑ$y8YyRrsC[ʕї#2А1$iWqٷ=1:_VF_ZkIڰuy<>߀DƩxo9x^LC=$nƢw!_ѿ+v6f{'^M_~yex$$L,3<_r`,[@ @Ƌ/e E_a4Dp1rK} w~"VGu:Yݼn%?_{Yc-'11tA䯯{UQVAf_JBBhر6>^(ƭf䓫X("hI8ʾ}U( '+ȲLeeǏwaӦDbb u p\/z֮l^ΐCS 0BZ@ ʼ8>( SE9l] O\SmsfBTmZ^.ls.휭2LO>gڞ`a-UU='K%~8|-˖ %(^n8Wa੧V%K2ѣM'pSx,ln7QWgeDv\Lx>pC^mFfUb|Ϛv|y4yyTe47I2wju(XtՓ*..22))Khjorbt}9|w6ş+VKml2ӱ3lZz]?c_gpp&'QQ /w4v-/bJ!}}Nw+3?Jx hgxs8}Xzjk$.vvj9x(#<Ȁn/̓> ͉L?(I2.qt'!!6nL 6p}^?^u9M !5+ Z20AUapk0SSshl-¸Qd!%gob$kCԩ6?ǵX,~BRRb`nou44|yp))颲J\\%8ul6Gj UbR\.YaD+2nhXtSz1V)4-m) IK[z |;޶FHW~`j߯fD˾+UjoSl@r&p"ǕHN'Z} fd9O-O^ɦ?u'ss*{qX3 '11%.$Ė 47x 2lݚO~ R ъBbx2!*ȏ\Ď LV'UQ^IVVޛC|)muqH6oNda@#eYm(iS))M<Ҙ$~w i3r^uh*2!X2N$&`_..羵xqY&m*#W~l7ʥDyͥDzy&p82JMܯulLљ8n2v9v-M6n>>+kmxZ8^>#F ᆬdx~>FWCy^qi$Iܹ^N$4Tˍ7&8\nS:'550ou_&t_|3rj}~7φ~^ uuVn1; 6/ly+bX2vv:8r NJdgͥT~x֞L`xA}&gc8&Ly }M-50^@%̤c}j)m2u3ѼOvٶ[Եk:xS\͊kٶ-CxA!GxS:@T}o>Z@jjx< N/ tuٱc?dʧaj 6wKF%&GT*ذ!Ѐm$LYY7z֯O <<0mnjmbX;$$g1GxXndY&"BN75Q{ApT8X 3v:nŬX(63sq v9U \tuG67X6gY7g`4jD.NQQIJpV7)N=\fRpATӞ[jyDqq>{6/WjUₛw.PRNNNޛCllHuzk ف,Wdjk))`PiS"[ˉMN[S͛V~Lc-DH GQ4QPDF|_Y ;VE gmS ;Axۮ%TL$|2 V r9roTo<|T;-9Ǖu{kf:_Xj.7QAdy<)V';w.u[,Ė |hnॗկNM7; e3g:OrHESش)V9r߯FUq=9,_ЁrG^Nlֱqc"/ǏĆ 4WQ]QNGS#),G4sQ_e mQ8I IDAT&sp $n6Y٬eE ʒo^YY2qm@ <|1ouJ dx~;oOo_j?\AnnXhhk䥗x x}5pxZn$>>xʲLuCZP*lܘHR)`s}:LJqcaa!05rVhx+Lw+I26 ב؂V9xIx$õͺ) j2SfO,iM@ \'QR/y78ѨǗ$3S-ȑ&_wo%d%? eqg9^}Ywy|C\^%i8Po}{7өZWnfݺ)/;tu99x~7,Yq]{z~ꫭX{\'H $z{]x<f_7S[F<\f9R$XV?OguDFWk2B4 fs'<)JJIJ ?.+p~b<SxbzY6d%yy1 v]CC?~z+6M\!?Gb۶- ߲,ر^Z6%hڛ ԓ(V[ۡN'*ô6/U ٽ9|{(l9'"D2`8c'ޝ5w}޽35wםkf 3x ؃&P@Y(rVVǪ! 7UխK 뜪:>{THJ ~{d!0e\U5`OٳOs85rgΜHr)Vz}-m+/ڵ ;it(JFFA{$z_/DXς4MhV!+0<~( NjUh,GG`Ў˛+Ķml{5kP􃦇LG?GMQ5dR_߀C^s:Lap Mf`86f|0~/=e>{2%c掙7Pp2itZ'c5<,'4 Lc&1zk56lH/YvL(Zܹӏǫqj7K+>BHf)ƟT?oCH^{m|r[,Lg6jaxv Lhh_`ji47OKlڔ`%=p= 0x8<f 1;C\?l1hv`<_uZc̰-eK>}^fqT=:LNsg~{ lZSNpvx饕xnF}p^^س' qNWPS3nbcy2 {O*ՠZ [F!77K:VC]Y$#15ؘ PoRd,E|`rna>>qss[YY+^u:RN{˵gOS}K3'k&6lz1.Z 6bZOeqi]]2^5N\fy=V''clLO>i¿MTV ;; ?\&XYOd2%ΞmƩSP*uؽ;!6ֵJ$8s(-MSOp* Tk$re$c,$GK =#MfOB BXk4ZJt }lJ Xy!m]M:uoŪמiK;ENgXyƏMf*8֔k0`m=f[.P\FrT.ux.-8~x<*X4X惀࣏pdFGؼYeR;{3HNuiBŋzQQػ7))ff:AcӦxDF Ǡ!kQ[+ؘX:^^X-=t8-U !!^qp15HJ\=))==- +ی+4c )ΦGx-u36Obql+XPW6屩ϖVl˵?cIxFc(Ƨsn9phAGN0=Ǝ[QX ooO$h(ܺՇޫD2͛xBdfFi 8{Z~;ڱѻ^nnns뫐M2NGf[!FС"ƹgq\3Fffv@7%i99HNl*:$Yx#+"glHB\=NCMI5r rJx{#&{KpnZ\\bqkk~fkc{c Sej:-= kbmpj#[sͬջ'>(q:%[{aPƀFØ4?jf!18J7n7)'4W^[yy134͠y GVu [qc:ŗ_އ'vBaaS-;j)y qq @`pڍPU5FAA-qJÂF2@?>o8'@.M1HN ApkdlbRR~~"ö$bڞǘ2>1_ٖg, kC:Xa[s3^ ^W6qmg!wcd\8?I1vBDQ1=ƥK8rd"))?q>{.qq$8==$I~ >"#Eع3mIǑH&qt#m[ vJsJܸу)5lIFbI8)zaժ:CCFzdw3霄_)a=JU $6%ΆSRr`x8: ɢ5/G&!YdrTˎChȚ,ldgGg?[!'cbbg6㷿-Cu rs_b߾|cQ/sZ q\؁rSSÜ 4͠iwOD 'c"##ii6{;,cf.K>A"b O׸4 V %5p1wsb?iĈooA*29C&!G{4%~R_ɬL kOC[A^k=M .GybȺXrJ =J-N6_#G*;c7`dblDh5TxL8P%QΞmF}0223P.0$ƍ-b F-**000y/ z2bHa]ִL)xx!yE(\癥1P0np .iiy&iovw7dp%Ce;yRbVdХw : 1cKC'1e~_cn,}uam֜gc}^TbNaw5ؽ;?:]@> JoƱcbF!/[?>ʽt^xl8U\Pu@sPZ(;ssgnX& ~NݿD^^8e -kxi@ aqj5YѾmBpq:?HPl|Kns˲,Tb{ݚgEvo{Lrfִkfk?ͽdgqd*gcuqر3-5AX~@A_Qяޫ7t!0 /}t_gAQQя 47a͚x>\ܨ%nNn4vJO;W,nBAqq23#g.刍Eaa􏱧lѫc :,Ly\tM@..9RAB.bcO;A FpX5*+ÇWdD"%BK:QV֋?< $%9_xFm*+-[+FG}{j5p:e*ho pn02Uȵj/AXKY z "<^2.0s#}@dv 3euش>'[j[˖v=͵=e||ކޫFk8#q`vJ'Y\vQ){.u"..a۶% o4sZT3ذ!sӯ\ y$k :FdFII$BBDi 9e@PP*a SAJh[Y.s cX1f0 `h?7e[SQ8mg[=jmyXߒǎ9mlIpw|a: `͚x[RfppN +gq\3Fff{.11N9d6nLB|pOOkPU5 5֯BFF<=ݡѐqHhH:&12(GDR2 r|4`rR\Xzx.I:X*K9=jOyMek?\OpΗN)>.{VpP֬I ~؀ Jb(ݻPXqkJz)ErrJJxXooBe(D"wE 2_ZEA.jVĢ`-ttsFDBB1 Å;T*\ߟ-bvce8[Yz`i vẌk(=>?'NBa,~}"1ؙ)>'NBo_$I>݈i_ v!0)200WTPR iiႉA3;#A(, %K0=c<aҘB ?KK~~.N> ϓG &߭nLSӀ2\M,K1gzDz#rYscx=1")Ȼphh/Q_?l5k( kOT*SQ QRttDWK|yHOW ݢ1ukC BCPYy _˗ZoyyzzT|yZ-wP( [> QjTe@ ڎzxX}|yϗg0=M(tShlM.őly%oHak 6}kg~ckeO=WSs5Xglklrry33sA=/_F],Cxlh4]֭#կ6`xxz. àMMW@ؽ{%~{z믯AΝi8p`B:ضm3}c-m+/ڵ Vэ^c Dahh4Zh4d2l۶4M=94mFZ\ox6уYAhA 4jbrm,@pN8܀4 @t( ZZqoxt x1n}YA33}@vvJJri x qT=>xUرc9o+i%{(4O<@MoPX~RS.2=EyFGX"yyKgFoR\ IDAT刈CjfD.ƔP((gMMUƖy>{Z .ئ~}vCDŽݑ[z95,mG;ENgXyƏ7@p$Z-Qut4}6ahDdFFpt#<=+yx -=cBW_GYY/gORRBBU 重,:i n 1'KѨ)tI13FjfbR?`|\ FX\Jhƛp15KJ\=))==- 0 y#ٖp1 K3@0Z=ȑ*\ڍ`oJHK sΆLٳ8yJ/_sx%@ Fp|4 /6%Ӊ 7o`jJ'Q:TU{ɁX& ~~(%FF:  "6+esjfJ I0 ^3t4R5t:"^\.KC,΂D 8Iщ6>&*06o#fߺ !)&Gff~uط/ A j]ر*H$ظ1 !##bI^y}\}ܜ(7n@" [\/(Z-F)EII4Ed`.{ nn@DD SSRr쇎j4I1W/-X֞ˇ lu¶.6,f.m[z{5k04$ǹs8y2]Çuk 6٥PQ1w߭DC(VovL<%ٳQ`δ:)ܸaiSbLL̥Jض-YYt*-'wW(tP aa>| s;;2no^ok^1FgQھ1/ {+-+@ _azZ[S۫QR >>DIhܻ7wީ@yy?VO~Rlv5.\[{mh(TVi qqؼY, EUybDFDQ(@$rCdo)u"2^H ЌbLΐIczp&osmh47ĉZ= SOC((!|رj\ҍ IIǥ% Mϥ˵@X\kޏKzz>cnAv9eQzZưl3}GOkti˘3Wlqm5[?lڗ4$Xqf<>n εΎB=xJܺՋ j>dpÂ~؀?l^|1?CPV֋ ㉧v@oo1(*ǎRIrHJ DII4IܥN`xxJ"zIz!==mmu`>r k 2z%4li ĶњgEvo{LrfִF[<Bߚ>gl"շWC&S…8v X< 3K-0?qds>bcNAO$ΜiB_4oOŮ]i.SW7!FYܼ9Y«Gh( B쉀~oKåvZG @$vxX3g5BQQ.ƣ &hRBn?^a9vJÛo!55lI -.^͛Yc@G!ؼY@aZ hn!21 l-~0̩]2\JP)axpvޞPo n$@ Kf=?m)ـ;ӈeQ&Ñ#UhiGII*FVV/64̙&Y䄡(#e,/P l4Ȕ1k-gX6žrХbHR(v~ @ avw+Q^ޏ*B.DH0 )>>DIB_œO`2bl=یqEmh~ؼYP_$Ecظ17.1DWsϖ2k`-?H02N :{h$OT@ E857kp\ t:wg jU,< \&.:ܸу#G)æMI8tK:~nW_G@BnnF&S5 g}{*,wrR71>† ˋ=9#l*vseҹ4v-*CC @t%,Evarpn36!_rFs[.sJ1 c:i/Ħ^6Z:p/{8z!\}ZU5GpbK+q@H&EDQQ1w߭DC c[jU,.ݯd8{ ܙ;_2萢b>>ز%Y0ˤhA{$n;6lEL Ib{~^B`fF1%D"wS{. hbbz{[lG}B9H>]ty]lÒ= l-r Ys}}mkyZ}jqS;w2x\E66ȑJbŊ>6$: ee޽HJ qnA"DZZV_th44G+GFFV W +k19}cpIJ\=))==- 0==-f X!dCQ/K]26 SS*|uB}0pP1zj瀜k$IjOH"2h7 ŝ_1>M R7\,u5?3ε s=ܱNT'8dCNMέf}gƒ-@ 4=رjw%Æ 7?H'011ӧ?Exl<\6I|y4 7n;'ž=YX2ڥNL(qJR% cre`LLp 5(,Bn.Dؘj5`ojjj2{C۞Ƈ&HLm|ƒ\>d`C}u9g1plj/гP @ AQ4ZZ?ft4~tabz\{ؔf}!ZĭMɅFgQ/;j ػ!c@ Aw Wڀ5kE:|m7F4lIƛo"--!x8ǻM-70gPa86Dz}RbVdХw : 1cdPŀ 6Z[ᨺ _W{Ǝ*GoP[;+ / *ʟ[M3ho{Uo%HL xT/:\ރ[偧ZhUnLMfM#A9_JÊHI r}m?Ǝ1RLL O>%EmmuHOh[[wLZ/&`ls jm\ZVC㗵:r|Y.2q1Ƈ\5mgs-{N=dZ.VjI|Q#N6%ذ!ѥ:Ĥ'O_/O# \#C]uupl3FFxT22"N$&'U8s 'OBs+y 1hZVذ!匇^5fbS=hƘ5 BYY/}ꫫK+D2Z}}8Q TgB,!qu023M>L"#\j5ttHNV03[C#//^y]sK,92|׳{ҘPz-%4@<\%.Q5x,̎ŋ{[pR'yuuHI ū`lDGBBpv{]]2lݚbE81׍=gOVv>=2"=P*uX:iih'0HfPV6777"11n()k*`JCC` "Ǯh."JP^J ahrcssK8֝G(螰`[qx ::ϏO~R;#$ć(I@P!n%FjU,,B^^ Ye'ǍU`ǎxT ͥBx/y$aaˆRQ(/B[$- @ii,\/Xm(Z)Xx{2.8}.R~~..^A@;n2.e<\pkYC0 ;ݻI'& z PѣU/[23I&"!24$_rεcϞ,blO>iBK8Vųf"<5CT:TT {! +QV6 m[A&f01\Eh7¼fR.nnnii``T xlh `-J7nرj\&ADK/DRR *@R%>SZ _^YvB5 .^ 쳙Ύt=00WRMM ITV&`b0<< R`z۵>!x>pdnuY#1V[y|m`-mW^:rĮopj7%x㍹t"km8qSSjxdlr`uuCwoQQز%Y0r-nD2EǃtR<>VK#,Ԫ2vO opo;oŪמ^F{k^[t%a1} 8q͍ësgD$PT*._ѣUƎq`IgsLMq|nX^Arr˶W*UHJlߞUb.NO nM3X.bq1̢ИP=H cxb..))sL,0,>,I'XBmO@ðDpH lH&w S$o7]WgGQ^ޏ#G:>\(bl9Ž˱fM R[$#&&@F*CBB6lCP̣R01˾cOX,H$.4ؘX; /ɖa{) _za;Xde"ɧ? cW.:g{̵kηр>ʧm˶Y[;> AP8y~O7PTg_ A ѣU@ff^5k O[!Eqq^y%dI'38u}ւ*< ɪ%:;8s ر۶&5=j)TU v~ظ1 'j\>Q%6nCAA$D") ~iwF Z \l۶4M;p-/~ãh߆rv/d=8~YVw% 0`|4M(:(VVFA|kA;| |/oV.t۶moځ`N6*LNj BDݟW.Ά/SSs əDYhF[pq6:L_eGGx9r?Y 04pՀbN-ɪcF{;ЫÒ˔Z؞^KڔK`̌|Ӆw߭DM - ob,%flL>j7?J<\6BCIPc6…u As t'&vM)< 1F)ܹ3 oolڔI͍G ..M3PB!>>vft 6#I3m 5s1H\E&g$1`o=86 ~"&NM,֨æmla=٢Wsd\1l5_!v矷6H>\]K$`?^^.=QY9??mKLYˇ L!%%$%I/@*UC⍀{-iSǤ6/'y4ИKvl֜K/$\bs>[kk|2Z0e4џn|q/8mg[=jmyXߒǎ9mlIf7|PQJKq`y$$3Q*=Za9vJÁHN%(pLZZQPݻmV(uSΎDQQ㧯o7n ]`ҏ-We0׷`_l9KB 1%(Ah7|}ߧKzz>ɝlSpYvaX1PKo66|,awdkti˘c{?`hb`;`)]^))lg|˷ [::8qLDO>oYXL'ee8v K~2:THkj7nҥN{wrs]?uvW Wv6nL)Bm(ݛ@||n]b ~?+Fz2)YzP( ςhDDQ.T:?ik3R6V|7U햎3'dT#}Y{mma{mEv>tgIVbS&La֎Is|l/7m7VC,-aS.\}m\&!_z4rkc[ 3CϏoAqq<=݉XKtu}dlߞ מ:TTiIIxT #XeeV a+ %:C_̫oESB{yٿ,,E ֚</.=\e~X0b'>jeG\P.hkW23#1)j.ty0DX.$vHU\Up%35PB$@dC K& _:C ,C \cZS?3X/{o>cK_cs.c}-er .__!$$9$ȪS<NZ\p~xBرܥ=ٳh(ڕuA$pv76vaaش) 0jLOkp()Ś51P }qzZ) |}=C⒉BX@ *{c͍Eع3 > ?'4A$r/g3L?edD%Cqq}a,??/'=@ 1BQ pa`j13SFu >x}}*"/O2c [fft?q""DP&\_##93B +qR|ڂ{TY$**(9kWU>7p^˓ݱy g|9ofF!h:4ݫGwpq$۷?EJ@ EҡׯW\ЀKPRSH&"'ApV<8f;$b R")"QlǢ%Č$gg+;C"=?*.*-Kv"SHʄ$6XujT{sp﹍-۷W&}Wp@K˛x/lW fD_{x| ;C-#G^;c9NbvJ_lEUUޜtcnl<-[w\D8p\P(P(`0χݻwyx e?BaALO```y}e?};KQ(l:_g2xq#pp8p0P(mfq'xh}idͳN={uu5 n/I3å=eKK /&   ~?I<ً%Ay/OzaC غ-/_>yg>Վ١l&&xN `ǎ*44,qܴQ?އl/v*GI w G0>Dzz3ZÕf00:hOOO/Y,A?w,ꓻ }w8إ-2Dէ7~SN\wNax晻ym@}4|:+_لݻkE?k!(ȑvg`߾5XfQJ8vnQ2g$˝?ub˖R)Ebr2/t7.̴N. _Kव-=X}VLM{,{Yr܋ Vi2iW_ v7N[]4-3S-Ap$~<،)uWxNQtI/ydey݀}l9rrh?.bdď^_r'nm ľ6i٫N{ bj*/ 3, $]1gr5;KysN48sJЅ嗉݁%3V׈(C_X+z\옒(VtTb׈ϽzBx]$IWO_$vhTӖҟ{E͸]x^@{~&- _7Y:t/p. |yd]JaDC+NEuu>󙵨O Lo uk//YnDRq< I?åjͼUUkuy^9'+HI4X匧s 9Sʡs/rΩRjꉿNzJ)gWDSw5!gv TTSI=HDž CO/#-ͅ~}-ǓFbj*W_ >z;**H91xիDx|+ysy458;wV S ,:GPZ7㳟]2JhBƏ|W`˖r<+r_{ԧVcݺE)s_WGq dg{q5(-% fq-BFu;p%.EGu~_a sǞO$aP[kh92աԬ5N\;ժ14~v4= iF?jQӶSo[,6*݄4Hd}Z7'Ltt֬Y _b=(ؒ`pg}_'wYF3tС ΝxJ8<;{3Yng8//֭ˉHJffIҥ9̴.2ooowmz`ٲ9cr9΢rbw"Uזd'7!>v\ؼrJ]'T#ZKoe$>㯓mGf%yg9vYS-[ʱ`A}'*gVߟj%@Sk^2ehhK_u~x 3I9:o{mmشi)]¬G\,]%pdYffߕ/0QX+ݢre=Z[\X-]NeمҵzrX'{nҹ;WFbY,Qk;r١K5δ!K#TЅpⳃƅi~Β~/!\-&$(ȑvd3Y5kS*0 xq'O"'Nj;xqg3-,$}t4.AnR(%g\ڄ+眿zL紶5渖`:$f%!6G=7jZd";{ض1w5O R?#G7ax؏ZG`u%kgϲ[55ıcƦMKys922dbY'֢ec D٢4FVyѥqsKh?"[BY{ +W;~Yrr  L|ص=vVZH?`|כL˃NL!  cOȑk(-]e˔An&##ڵR. hi™3wW0 :{2Fd7FFfƢEYxϜ9+f3\037]i99  `Gol×GmCA^^)P0@ի#o.I DۉIl\o/f烲IjŒ*1Se6pbfD clgt%M::t2ȑWȊ p:GOO#kw99rB._A@yBl۶ ˖Ϲ&Sزy=D8p\P(P(`0ϗ<3\[c_!gطnJ  BiLbϞexQ[KM7}ز{BaafJbhhGv;˰rBlvDx,\\& MWZooY/AAp[#.]eWĆ %,^'}gS3Q.psK얖!;7lQ,2"FF]L٥ֶƺ?bY y\.׼Wɬ6,k{o&AD8MMON~Օ'6c˖r˷,MFn&ŋ/^ v"++5w{;? JаH BII-ڥ(r5;KysNB1arh{vk_}4Z`eșL2A΅oz: w{k!1 0U<ًB۷y) A6?ر K. #!R gl˷h")箪jͼUUkuyuuYN$~#'{ "uzz&q`3?۰hQ6_tR8}xy{]wU쌎N1XQm*SrKl"5>_A9pܢl}}L TWEg%TWsc}X^TtDbΖg1Y^'%_K/fgի$G?SW-:W;r}ڮTy,mز Hf_Ë/^@zӟ^LR#qeiRݻ:%w%HSx.lRˋLH?!~\sRǣeWs]Des\np# v^77g?pvl쀋YmN5-k$֠GymѡQ\OZu]NwV艅(ENmٳ Hl&&8|2~fa_݆rDxvgGR7Q.ps bѢlV|s{ν~|{rAH>8,fg(+> 8t}OO/M"uv_ p^)+"8ΣrzePXWm[jؙD=Y[+e; "xvs##~ݻ _R (= kpRz7Ȉ߿ ^j*b3Q 8ʣOR2ч,f9QD X8 ?¶K{{˜J{{ [b[lY w݅FlN1QdʾڲU "ph~ShoaJ<Xfx:Շ<ȺM}Wzu'N@Vv`ɒ\WK4ZteDkB,WF#6S7eڞ<%.R\v~1Nl9N\ZDIȊ{l=, Ԃx9Ӈ$Q_?~ؒ1|t^y*8޽ysYJo}<3wc-e:R-RA2Rټ=P!?1=I%ę`hh.xqbU-εrVhX0"Z(6asafCV'ߟA/ח. '?9GP[[;kW 22hgO㥗.u6o.޽R:Q.twOw:q_!,XG\˕+grds4՟ Dtž'k.5rĞSS))ԔZ %ːҎj*ɦVzQꓞ]d}QRX7o8=n8 4pΞG^^vƢE9&Z}!w]bZZF!ujG2, f>?sRG6@zEk{bf7Z XAIr)F62,h7 k.N7.EzCK]ߥH~h ŒdP#k8ZZ-oTzpʴ_z1bD>Kg=?hs߅;;qX7`ǎ*TV)G$ @nn er;R "A'&JפtF|`AN0ȡWStR ,x^@IIC.)R466rrɊ H vJԦ6Zg^(s:m Bvزk.rD\g f!#eu KQ}}:lp+dA8 #rhKFwP5AL#eY苅^1o-BI$񼀳g Fpx(BgNv=>{ &F{w睻q#\qBȟA<4{Θ7?yr0]:Y sWc)lrǼrxG$"D8BaB!!|47Ǿlv }$  >A@[(y. ;vTdJ*ȧM5;_Uoxadfz rٗ47?==dA}a-&ș}L1 "hlA{jk m[%rr`HMx^,ff((@AA%2.ږXG>+u=VQNv{H `ZzlUf8*v vrr$ܧTD=څ@ m*f"KL);grR&TJuq'ן$ FMZ"39,^ Kejtw_,rreb`?pv?taew`Ɍ~h탕5"g2@h|S!(9_JKʊ]uB`1RFe\Kƍx\8QTm*QP]*"Q*5A!'WkT @ oŋ㌭>TGv0|Utu]?`)n4r 7 9iF NkVMWP&CdבU-εֶ  mmIT)9=Y, )/TPNmʪ5;+2@##pldf!WR\ע*v0صFD/)[b AlYrje6zLjُXJq$YPM#=5zբs wjY"hFYو-? RΊQ5Fw^vw"Ҳf1? ' ;vTc)U MjyQ ?/7 Y ݾ\::.)u踈u\z:-QpV*@>h zĞW۶uΥZLtgX(rZdن=? vΊ&#a:o;օQTW஻*m,Ǒ˯V,fѳ,h`ÌQ>ez: 4fv{tRpQsEÉR̲rױp+Z:jRS|%ZYM_l++˚HˉH=\O/#NY4F M.Bmʕ OEJKb$I+eӤWzlMNn0>T99^;'9\/[V3r 3E#Ė$KE&K-[uX1 ̗C Dt1̨uZ5NMXzd#N^Tlh[8̙> aULE\˵/V,jkmK.K&#*gfݟJ9zr^Kjm9߬av=ZNScVR}hټW^{kPRC!Rph'8 99^e^}>/v pimmsnz6&ص?RZ](] JOv}žWFbY,Qk;fpcNZR 1]\+6R6 ٌ#u~dV_0-(sR?D=RZ OIlP;(CFC< !?8N@AA#޸q`˙3g`kW6a9^mҴs峞~i SK[=}֫3-峞Y2i=B_zl{RSzezd{?geV~ww(BD*5w TUR,<ra̙3.7nġC/8?rYٗW8 ")e5AC(>\<I ୷:09w,"ǃp(Ϝ9+ LǞ nLA"D A^^:Kf0266J&&  2:;qX\.{PYiY;WE?.V_5bu AruJCZ䎗O8cpЏ`CQQ!WRT__C[:9 Y6AAJ`4FP[o܏|22nq[ T`C5bvԶ9@6Դ+'rf3zy|M' ;Y~=Y|00x~ ϟEwWs4v)={7AAAv^|-po-vaɒ\GS#]#azJ:eƻo(l:'  @yǁDq0 BGP><Sx?=>޽ `hh/|8ng`AAXc)lrǼrxG$"D8BaB!!|܂%A AA;AcD\0ӧ;paVlSj,ff" vaLGl 8c 3M\.AƢExpI.Qw\ɡ-=X}VLM{,meEd/c ֦[+Y:ʤ]z3Wq+,*ҢF܌i߉A1ߦÇ߿׍;Q^le9bJ]{\-m釚1"}/,HGII$]"YFR9W",X2Z`eșH2٨@f2-'v|b+%ٌXPs%7EkQIF5"޾Qz6bzm6zO;jvaK1c<물 8. ܹAgc׮eb"HD0Lx#[Rp8o؟踨hqguȕS{ܵ[^ICmZrHBF)>jѹ1ӫwf뉅(ENmKzO3-6 g{jua1~s:s $,wxx-B}$%' r (*@fsJ;a%Isk-<*Wm, -B:ͳ-5eW.j, =;UbvlX1>){&yr.A hműczݸ*bB?!?n.Ef1%}*ޢ8 V}2s:< gQDɪep}HvPs B;֍kưrBQl/) D chh^o,Ɇ׏B IDAT뜙`)=%>d=iԖ$S"$d=`h;6:g(9A N"۶UbŊ" ĻVХ9Zz3\/X|Üp1H2V jed ZʨM|>(?SLZ3r"c) H|B!OA,^+A!6|p "3Ӎ 8(%g69re=Z[ 0*r9 5y ՚j}Y{M _%=ٓ^ɤ:;tfٙ6 T;nb}&%燚z)vYKV {{ubr2;Q_n7%%1x^X ;jEfؚ4h9&Փ QMz ɖ0+ >? S+Yc,Ƕ;'֥>z&ic QwM;I@A<^4>łص8JFk? "CC8e`tGwA7СprKyrAAAhlAO$;ː&0YD"<)3ÅH~AAD"3ǻ!n@EEcrtY}+ؽ{gL3smkl<-[)UyD"8.HC(F(B0;AK JK`۶J榓bB0p,;+QJR   %3xqc)֯_Lr BBpcLڵ1v)̌tdeAAp0NCaavu\\pps=()v\2irСÖ)GBVNAA!ff8><1ZP*y+%u2c]_7k:ab,_z`Wp GKp={ҷAAAhiŃng?yy)Jk(l:_g2xq#pp8p0P(mfq'xh}ix{PRR@M"wV,_({I.-x/[[<ϰo}9AA`0'{q*+q=U, Tqye"78j+  p̖Dr{/遰 06} Be"38i"v)Wk[zdcԶan].׭Dz;ғTN;2EHY VcL" O}IwNP0sM%X~<p 2rIå⼭bעyF_/!WNuroy%meBCDڡƗ։=XVYWN;T+nΫ5- JbAAhe/<=D"[8l^ND>&&8LM 9 9f:=CY9!Is H-MlĉrїrL1r({*ʦ䴫g6fjƣsv H{zvVZ5c$.e.p~s)OiiډGPZUe*PR.XRQxLLDrn aCdХk֬,.n -vu+||!K;vgk:;ZT[N34Y%d)vg47Q;e1zk '[N0;gʨ}jmWn2#2I6B1Q.`!u^鸔#*V|1;c!zN6/u(}Vs\J_b#%V }ӽ^;cZ_MRZe3߂녝o{>Z޴ _7xp`Ѣ,x<\^/~)rV,0ⴲOo@Do1IReͰ Rǣ̔Uɒꬹ}# p۱ᣔ_C'GlY>Jgj'rafodAA1=Q3D,1ڑڪWRj۾vS+jV}jFdU/m%01 #ʹHǙ3vBCC1nsfK}}:l ȑW  mp:&Hv3u8||M' ;Y~=a=LNva|ǏTx AWu9(/Ak99ԒtYw=zZAA N&HO{>ڥ():A k'l9qH!# " !zex^X;Qn,gΜlpaBWVtw_Qu.z,X9}S^Vͨو+Nr,G=}eQƌqI$Geת'z_K{.' "aóDz\A@g{o}}3ص X%ם3\b'rU꺌˷0jg8Ωue}5R:uꉕ>M?r?}S`p.9?Ni_Lb奎E u)'WFv%S(ĥ'qҙSƆEE^dg19kuiӟ^ڼya N>?qYT/gTW<>zzք3E0KgJIm2ի$qXEJ/}Q˘Q=- ;5CN="7F?;F-3T}^}҆~g:e\ BԪQھصc.odOX\V|Kmz;^8] :hi71Lc#HKsЃ v9GK~ND"7 =}nׯwgCceeKOL٥H*0q55&JIxĜ1)'hBkBZ~)I͋UIŢ='ʨȠ'ФNYRҹg+ېG:3}^J̼/ڱ>R&8j쬀 Z(f-W5VbA3dDbP vIʥ _z{³?1mrA<][`Hs f9#!?Ej'Q]O~sA8s=C|߁fIKQ|` EX@%z\-g/Zc-;'ʞ)9zꓞ6&ezCV- +L( 䠋3x/0Y7ojaUejQ3֬CX`O5cMzy^壠P/]hon =diJj r8~oэ,m+ڵHK[b..\B]ZI?ET0[˖աvv:xNu `t'Nn#f=q&=Q)%%ۓՋԾ E`E,h!7@*h؋+[Bz2Cz'7D};r5$c>}=\ɉ 3dx7hko~s ~S;뗭O23\-_׮ h*ݩifm"c?NT ?jկfݞ\"5i0+5kɥyWԫJeXe>TV~L()ÅLq(.@N-!]8ujxe((|l]~"A7:|Ue/f0R;"6Ee2Ij[c=Ý'WKc?W3SH9q'A$:b;.VG̺XhAi vѺXgB;UXn2%A%Y{3'+E(#wYYB ֭K'bٰN2RYY5kVKԻIkmmhpW:&œj59Rr\Z/z˕S@KJr rͮqfP*zlɈ~r+xf$ ,^̼/X~J[/;bK\S:3("jr(a'z5cّVS1"ame3߂녝9<^/?-<= (RY/|x< /@F/Ԏ˗PW

Q-(z->&20266J&'    9Y,Y\ayo}yyxZ^]4e*8MwL.u8teBa۶dAA)|@D1||M' ;Y~=zCW#K 8xʖymm8xCC~lVa45M^x}'|Kw*AA1֫QH+Cx礎G(ɯw'Jh=VQx9X[q&IGv{g;J$NCp"oi1@xwzhȏ_oBGG+W7c2xz߮\ J͘e,t W,Kx^/rxQP4/\+ᇗ"=m[K_xMB\Ⱦp˝W*h 'Dz@#$lH;a=M5I@X.}-#&lѓXVXrC= %go|]]ݪ.Z~Xb pf::.fݼr紾pGЛDL<bתY VX8IRm!7f˨ fzR'Ffhvaib_m8f<ì%)AX-Rs\mZR3+m2M5m[jh,f;ե~a}/սq0R\Y%[T3>0ۃxl{A<]9>׋__>&|A@AQ2xw :Ԋ{o‚^CA8s=C|߁bI\ryԾJ-MQ#>]grDͥRHv]6 dvл󮶯ZdSKh%A=uѥJRk`Uԯ-.K=ԌǨ3ӃsXqms-zzGy7ye׻psϮDmmw/ ].\uX.˖աE4"wNϩK"(ڱS̱ע'V΢S)Qd716H|F$ "5ѻ;A\dwa— ' E7G  W rx*fr\.;2 fiQ{.*gέpW.TSc^ς.Yè,r[NROAARa-,%ee`7 7 3v\o…Q_> e1|rsuxjߴInc?/_|9+Kkv # Hj zgBa)szv q2 6ok]ّŊ:&uc54  (Ʋumam ()ZW" dfy_4`0ő#b߾ذa!ؼlP't5%67nHX,k܌&̲}؄$j,Ȳ=#a3EX "u?~+x'(7~#knv}w"䐳 Ysw|Џ|+PU|UUxhi(//C]:!a˼/\\9+b)w^,AAAA$knz<nn (*BvGp ^zDز^6oU݇~[h    P 8N@,ddyĉvm߾`(5p! Cd?AA^BA Ҁ xi8kK#&p))fp)mS  Hh\ g˜ICLiz:> ˰kW9pͥG}}װtyݺ5.ccc񛮬l|   00ƃ𤻱 4`j,@[+V/bݏ%E7n\EEŪ9\r$R__C[:9 AA);RA ɣ50{D3{CuY04i4.dLv#puN;p:7v=D/L7 tu]BUZtu]w5D5={ҝJAA#G^;oP#tlcqr<#qD"B0B|>v BӉw^N .i̅FLaHHDHY\ \2vI،'`8 CmN:UI-S9uy}T~okcfŋꫯF^}UyW… _= X+ Wǎ˯_ckGɃ~پ/[~eqSG{H=Ჰ(w.Qcٳ^6:E+y«ȓzyG7h4]hd;!Ξ}@$E?a_#W]xp䵯]߉g̰˧lSJS2!ԪsmJvW N^+ԣ?Ѻo^/ylK'qDMLMm3^ ԍ_^>uoe1>UeҺ3/Lh+Nu͵BD[^_,,,ٳ˛&ٱclܸXp?tP^x\7 ~ÆwAy'o|GoyF|/?}YvFy"nȿ-eqԈ?p U%5oki!e-abnKJNmfMuRm-pKqA]w'Gݺc6;}[`{wo}A/0r1%6݁S~<'AͱtZG2lk[_.! ŋ&MM:!˷onwSTSfZvʿǗǽm׈jZqpiĦb8?,;\`-nq;1;;L0m[y^;4~[~4u2ܵ,e5ͦ-[ΒJinz<ؾio+/NcZyEDnk5--K|a<5Mx<#iӵ|v9e-tGV4mӸֶ6]k\iZe̸?K_[3~2b8n<ڪaU*i붙n-K,\歛j)6.;i=!u]5f>ㄋ]ƥ9pk3][5],7i'8|$By:g2ϜyvZeN[^_ 2T̙ge1M:Wt[Exm]rw.ź(.oy]y%k֕flJX ^'\l߷r#?Zi,_׭8̙g[kqmѦmõ< N19`Јoyl.ɮ\LUC+VBu #Euragnm6 O~fͰT1r6o~;.ׯ*)v!3ķ<) C#qR~Ajm4bܶlUzvu;aS>Loh[Xv02R"WYg79`nff:urSrV.ϓr(p)~^mUkZNU|S.V\U.l MiJ4Mgxͺ4!.1r]GJv:i=m% S.%_>R<]#?7^yy,nSW.'?M6-m*_8įi9y$XU="b'zR&.ߧlຍ6nLLM|''x{W?|>1h58iU i\X5ŭ u]e7-%~]>`Lg/Dmd=~iu]c$'V[ 'O>M_cۨgd,;\SpqfN8$[ް3uHe=!@_8q Z.p7  HH"+p%\G/cկvqw7U q/(s69Eډ+}ܹ?bBg3.~ZHe$\pPӧ$)ٵƠe%\&ɖ٭O%].dh4kω-#\/_G?AyKL,,,ݷh4rw<˞=x/#\/6SZUh$/^t烗W z͂,Ðpu@W'p&""G(305 s|@:HQa`(ə3zw7on e雦u: .$;Q=NO_q̎uӧegK%RPH˩S+33WM;88 ;VLMUm /QNd'W|UN@^v9Aݸ#Å;\۩GB?4[̉ҢcYZZ-[dff,--Yd|i|Sw,--c$\8Q IɓO֭7X|0q ͱg_T;&O|vxl$\8Q IZ ։8ⱼŊ&RwN0~;Vwġ1pD 'iǏ/ dyǏ/h"LyƍyMV,Kϓ$Kyx|@_;;;t$x /L>WƻCԍkd}ːcNmu!.6][;>Tߔe:Y4irrɉ)EOLMm3gLqXMrͽ-UuGl蕩,m´6nMLu^O3eW5 >6^\~me/Oۿ<Ʃ\oM!u'm):}wL{G6:'k;-.uiunZMYYW6eSmlڎ|ʪ;Us]n8S-6R.u~򨣩NۿT[]Bb賟5K^[7>"O&'6ٜDjK~Rգz\R]wqލǪDY} u\آfOXem7nާSڌM.8!훯bxqmNnM_F}.jnbnKqND퇾`N'\ninɖmpO{^CЎs'T']l?:HQL7 s.I'D:Bۑz)_x:rae޵]MZl];\?;rwlU/ŭoe1Mr,UbRw:mMe1%\6)滍7)҈v`Φ\|rm՗߇k4_(n!m+d{Ӌ] t@ }5/ƍ;>'SSS3 *~E\S;f~syo'dCg$ݮs1r= e\- IDATu6 eoWLԡ˺M;Kٮ1볝d1摫rؖw|ck.r]ژ)~G INTHQtueUin (s2,.>-kݶڔ۷L]uiQ亝ŶzV}>wؖgZmC9km_[N+mUbDQs{c,3n4S پTzin6^NzϦ;zS,'u.9n❿%Y;\lED/Q1^֭|Jݸ}N*GB mư+Z_Mi;~1滎\6׵tIpٺ9y頻Z\n}Rmzqp6j&.,^ض|AM!~Ҏs>f%#E[ 'N}7.5+vժp~BиdeFӺCI7Eۊr]iv@r9mX}|Devv^_~_vO6Ǹ[_xe,..]NێHNضvRmL vEr>-;\^Sj׻Kշq @}EYgo߷weٸqqdjjz{![СX5kvVwg?|?OV)/<_=hv m{_'C^6+OS-//=|EΟ ww=t#'IKrk}$uHuH(SK;wN^ze.2jJe~~N/hߟtS.zY\ r-7'[h\/_¢}F#ys|e^Pe4ŋ;{yjJg~u/>mq*T>~s^5iu㪮c]FOlt=w4` r dEߒ$j{n7T.i}#&\U6mv00<6Ki.l<;s5ӅTJsJ0-{n7\W2]ɴ.a^;QR]õw4eBZ.FT5$g;<.e]֎PUmwxCHwh\O1=N.IeffO:|gKӻV|./]=-ZL7.gy\OpYZZ\U]ZS6Ϸ,M]>:;\rѩGrR ݦRǻ( Y*E%5['\K\1o+h3$X,ƓMi-jevv^_h7,XUrj8*];Z P.bJx;?u JgΫ1NSԄ˱cevv~0KS%:R6zQOlj6&WS36>;?ߢ?RtSI+p3.H(SK;wN^ze.2jJe~~N/hѤz}t:R/~Ku]_H>K1РpYXXry7l >Z5 ;\.\ 7ntoÆ u F,eX~miZNyUmqrAXJʙbl嶮Qm56sWromrhRfS8&iEMǕW<ӾLQ-p1O?Eܴ1?4et6eZgvQI!;ٛޖev!v]*'uYV3d~%FWƕ>̯1%[|j_\n\w4'X>&~۾4#E~k X`V0>וuMY^mm]X7(MLmv|6fj/6leiԅ7]'qisA TCl݄+Zw.SG1bا6g7lѾmr߶տ>ےi;\۫F-7~T.}1)l6됶jS~~fcɶjT>ҿq\ݯ< ?Mמ1ש|ڿo~<ؾi2[mqQW}ilomzPybg:9>jŦsUmEۊsiwXŌ;2ibԙ]R8x/v$=~5F;u0)JrKqx/q ^1}BI9tqinҎCCn{! G=taoyoJ;>^wq)v*Og)\c}6v.ByCyVmc(]c컡bO.X1˱)c3LUwVo>MY?6{2}iS~ho?&"2h2\V`YVcmM10mW.wVm31c5Շi^ϭ=ˮ v> @>mSlo֌F;ho[9C-mQ퓪/q;sp c2CƩH,7n;LMMYϼw7dvv:tXny^_;;^y-OYϷ,9y>RT{+;ݺh%f'LOO-#(k׍+驕صB pPFzCr!1a cXf$\mۜlg0e6 }5/ƍ;>'SSSDzbra1a cXF,9yI*'\e" z$[fgR?)"t JL-H3??'"!#~ďzΕ?ʃ>^ebaaQv]FXWD{CF+OOvVF\xyg^Ɛ?G@ʡkl<g!#~ďzG… '?G@:BwwLMm[ik#cT=5rZ[~hr]uŊ_[꭮;\Uqk;0׏.i.]4uDD̙gW ڶjX힔|uWmSHr]uiǯM:+z >=no|k}6ϱ*2=}>LO_/7_'O?>%\h29ӧpL[b+fH2 h+']m캍u2+]/p1]lSWNc?71n<u,Ǡ\Vm4-6677morsU mfۉjv6$\]uDzb=x[t\i:=WFaZzinv|RuZV74Olz'4nKT-?e,s]q9mf(qh:nǗӶzCqx1W4ϕѶMezs˖-s""(Xe˖9.KKk1_NM.밴RrSůmr4-c)k>W%M2]b5GꖥTšXXƹK=nM+U:W)˹-y7xA]ɧeV?y)`b9e(.k2ɓO[ok&asq0Sm|}O n$\msc痱Ε|Ht 29N8qrޱR'O'۝J4-?e¥OIQ..˹d'N :mϕBHdp*]}Ums=KE\)sݹ-6/,M㛖Y>Ս3͓2/ӴuR-v!m~l t/!|U:Ɛr7ر?Wg_mg'v6ez2;vPfum;4rMiMSaڎsNo&Uq<\t|=t)mlOl1pAw5;ѧ-kW<ر{=T˃7p)#GmG<ٻA5~Um{6pb=!@ys?mR,!~ďzG… '?G@ .@Fej _|Q^~W]v/cȈ#~sP* 9.h~ ZƐ?G@ʡnrmT_>O?G@ T. {2DzgϽPe4yx?>K-@q r$7:\uLd]Lbi3o(ϗ>v=~Z۾ٶ]֕j\][-ujjO?Uz m 1b b'm}Ѧn!f:^u>דN@/N.0ơ*F6w]ۋPtj[@y]K\Η"m¨m)MC/̵v-T6vF?ԆuKNi_/&S֗m szav~h=M P<^7EMvnr:9Ai.lc^'͓3o&ej{Lm<ϾR)ڹOu}l>=mUu4msH}b_tߧ ڣ~6/|m-f?e…[IL ]恹/̪i5cl{9If{U4m9o?Em6^M;k2M#}myF[wut5֗cmh`S2%sch#Q.nyWu:\Tm.q:yWJtqk:IkɘF;)ѧ!~F]!wW5 &QėƸvspxtZm{cVM2mvN.񊽾]K2pܷcvߣrLPy@zOHE82i;.IZG~U 9jW8ƥ*Z16^\jc?vm6}>r)G-ŵ>oiGeLm[em!ˊֺo p4>lL0.3ֶ/Ո2fX7QH{i/!1XmE>uhlKcZm(f-KAklnjiS1/8ȵ嚀"@ָ]]#Eu1 gZAffbx \бeG[c-$`Uۙ>:pm=?ӶޱҵLk1C6rG[UU׷M[W9b'v`:_=r?U!V$vC*2r[u/ig4sُKþH$ق[z򞅾ecrL1ۧ C|.}]3GmR6'euf~`> E}tqHloxy:^ϩ4N%\ENt )nCl+ ) C.M8HJhDWELQ}C/rMk2Xf*v,9;orOu"tq?9xҥ2QW_6Ճy'_*/vSS͋˽ϵ7u]]o#zsE>Rx{zY{p惃k,|ktRT5Q]]3%8ڎﻀ߮)m-KW9v'C64]7Ű ȨYIDAT@~ F(4ƾ󣶽NY7Š>߶2V|}rM/6ָ ߓD9yO.EDh;Ʒ>m,پQʴd7hEgxj6\N#b=!Bzt1#۾^_c~!f*Nbg*fg;9IpSV 4t޾ &Bn$;2VBm&S(d]!|٢Oht>/'4ڝK_گKXZ~hM[˹X}>8ç|!bh'M ;\q @DdhnpӸT/2I@'R&ɏƕ*>"@m?گn w"! H!0OPه~g;wO]$\ Z}pyV "SnH,Mzюoywٷ'~߶ߴ~kL)vu4mO豙 jxi|o6rT]H$aJֹ\̸>asS1AH 6@U(lG6fG}.61m:v4ڑqy>f./tYM'@M'M'ϴ>Ahn.hf|6NBmߑ;mkQ~h֓]zJ~VN7֨ˮTp!{2ȉ9_~b־4{N]^~)zCדŘ־݅>"zu\}mcеxPXy޹j>6s{l&:v0l hQtlC. t`1FbmǵܹŪOTh4989+.ӆ)E_ӋLSLaH'6!ۚ?j_^;qMڼ'SSS3 *[oE.UoRGȺu<#^XHf'}3u|_"4$~v4+~11n;r7>L;Nh޵Rܕ~ܥrLwQWkCu tM>P.rU ٞ ֮&[L7./մ]_[?T}\f.[p" `/.\J>|XGNL]Mƻ_\]1M'/}LuͣKw1p#1)rmG};"O cV˪܁ TԗXh_ěkR7vssqzL~>Rw*""?#Ӎy^iB7Եf2_cd}G.1Σ} 04ݱd;H)Ks;W/a Bi:y5O}܎Rǯ "?M⋈mu+}AaԢ4ǿkg<qI(&BuI\&Lp/*u4);\Lu“}Z N$? 6O|-6֭/Ƿ0 ,4 H{Sli-#ZbPÅ[\n aZG6>xi. o^[e4\@+uB)>Z4:/[޴xi.@D Kk]3/&N (㥹ʸ@Z+/8ϷqjJe~~N喛w@7 JG> jCO(+kPI,,,ݷ{e<˞=mQpFrEΞ}F2_&ХHQ]7嫺Sg2iKshL1׷8m$!!Zxl{ۮY3,iq].<Օ3Ue)Pb;oqi{d~4IvԶiڸp\׋Ϧrj︾1ćoTKHQW.lhJTiq hm=SN>IHTN䂮|Y.Q KxEX|MMoڏ(IvK+ e*_0VQ]l i6m3Vh*ze˖9YZZ2R|{PWՇ8nM_NeqW .KrKq.访cPQXw&\zlzʰ[o'%ٸl/4syi}웦:1N~yǷmU-S']a&jUggN6w|gneK</6m@k[~hgH~6C_˒&\}({p;.ZAH(SK;wN^ze.2jJe~~N/h@c}.G>Am\4?G@:T. {2DzgϽrmT*;\F\xygmpGڋ,^N @z+E>;u&Zfba!%|U;~zg5<}Eoʵުըmɡu};ܷ 6˳4M?bK;vZⳏ'ñfJ weӦk {xtuٞpZ.]yHۚ"~5 h}[:q]oI];_[TNЏC.mkLcD.""GDSļ ,oOSqiRoMXu\W\}i/2Bt ۮ' Ipbmh-_, I>7G7c汼b2tGY2'cPtfꨭ6c}m&\s2V}u61mu}c5ƹ8,.d{fr׎72|@,#ηllcTWrPoM;wlkJ\WC8e˶ʯoڴ>>.cI~X#&f Bkײn1b$\&ISgy%[>9c+E#Kúd) QTrq>*9cX>tg1DO,--<3}Ͱ/}_;YC{7?ŋ@S<^Q,e6sx7VSn?/;B5rӵ/|KwknlR{gzw tKLm1_c}^[$/mM|U]"/RcXIp(c?[U=zdR-TuTh#v6(V={rleevv^_h-bZWՉmmX15n?m>K[g]9U-UwlJRƶI_z{hbBg}ډ{l4(c3eŬ'Ͷf|d}>M;vPfg  "$Df<Ԫwj'}! TNnԧֶkdtvR.eQF?'suixGѣOaAi.± ab@@ ej sK/<_F-^QI޽CS#~|$\v!;wZvj?~Rff6g1|a~ff,//pٵƕJΣvۿr啿jx#Evh]$[#<nɖ}$\-U?DRU".l-"$\-QSw8IK.k$[x @dK;\֗,//Y0Xr啿e. hϊ@'xRɟ|^DDox'?;6IIENDB`MP3Diags-1.0.12.079/doc/170_note_filter.png0000644000175000001440000012020111262654564016647 0ustar ciobiusersPNG  IHDRm LbKGD pHYsȥtIME 3 IDATxy|$yn[h6 ̾aǀ1f3`L`_/c5؉/7}\B$y1~M؆`a3Y40hvI#HRT=եSޭw>LWs9yN=}`g4B!B!su%J6E!B!$r<՘&>m STcB!B"}}}}-&Iluu[B!BbCOO/{rlradd^* g݌gϠChooٳ8T*D"AGB!RtvũSm̘шک #턾[U5LP `Zm,X9bΜy1cfκӅm8q(?T*d2IB!R$9ӅXzgY;wzLV;;Ӌ=`t´z̘qNEeU Μ9gq٬M0mZ-_Uaᢥ8} |]g;QRR•ZB!BXhlO?<k.GYY&̮~y7~_W6/O/NR)R XTVVˮēcC&So ~k'B!,øؑ`-+0oкX|й#׀8C?#["^ye.h ɤs;;ϠJv 2[hu9V-TWW+/y&ا'^u{aػ]=z}|q 7駟UW_iuhqUB!"Kd_:n&sJLdRܵ; ǟ64~( @g뀟m lّKfunI&\yd2dyl!,7Kb`׮=yenteW^y1xc}:UUUHpk4MC6!HG?RahpǼy zlު.!B!fP۹-_Cipz`@֐ufO`J?Ne1!7<^H(Kխ'N>U|WF"D6-ocᢥp\7}ؿo/ h!̛lo&B!{N|3’%ӱf͜ pdۄv~|(/y=y-/]d:}wΜ钶C)\\̼.' BcX&o!twX.0݃.ZWŋc 0{y bs,^<ݍ:N bo_UkqeWa£ŧ>y|bӛ#H3gg"K!BHq&ajL0{U;?4 ͹:?ِ6,jd2ii;2p [ٱw@x;7?"Z)mlG&o!c+ۑ*o^Hww2t-4XaXE_55 _H$pql|׸k0kօXt9/]$If1::T* .4ahhvB!BH*Ln}lYYKDrna=^xak^d0}zjjr jÝ}/N~Xio7&V_~X( =dP]휀 MHIcEwMM%Ɏ ?д"|t<4 LT ]f1B!BH|Y q6D֘޽mEEr[kځ?\ {v4ήކHXdM"/4VZLmXD"$T,ck;]nuV$}>K N#LȑC8p`2V[ ڦ0g<YB!LdEvz~r/nľ}c/o\Lf&LXʗ^=>o?Jʀuzj(+} ev?}zÄ9rx6pWZ{0}' $Q}7 MBӀt:WK./~$R$|B!B Y-&ӯ B.!o ˶&w KYNơC1o :Ux ,]B8D*!\ܚڸ`w?en]]BYλp%$*'BwMF,XwzdiLB!.!QY,Y !<9y&P ) uXp5iB]p5Br%.!Ld9ŭճ;*}yD.!w a" p&Խ{xZOq{ɒ&L'D.!w )D6 ,i;! bm>}Nu ! λp%ٰ޳govaR,ٳ2Ǐ~hK]B7 !bNd9Ba" BK! IB!B)$"^B!.!D*!&w !0J!0K!َ+(, Q%sAyBdw}IdV''BH|B.!Bw7mz+qmBչaKkCK!$>lҤw܆A,*9Bk%mnމr[M##5GB!׿ y%W.!$H$\MNǎXqQo:=Ͷ04tƳN'9r;6Oa靬Ƙ8o υ~=j=_t 7.'9fV1׳B);F eLDv&cIl4oh5ÅyႫ6o|=_+ˮU}#H_wF4P/"ǡ ǴKw.:dvҫ]aN\dԪ-V:f"vrLVdJŤlDqZinz2ut2Z vN78؉tzǘwɍ9ė8eC z; {5qxWqˁϭqگ0;&0uy;nu5]B;V-TMbO.P'E&Skߪ*0(Zm'~٧:vF9Vluoep|lUc|lŊ2=?Ȕ96e?m?1!Ѳl/33m[3דiJ6 U(nwiYQ2"OdV:e j|Ua勠ĭ_Ĝ2U {9=؉ͭqAvL>>D:howQhegnUTfWw`#WfO*;*byv~jNJ_Q%E> *8?Ȗƭ"_~32q&̝ ¼U^ƍv:5Z#G4P?Q؎2oxAw~&_s!zA=p1Fr>|g[,MɆl\k±ү;7~m'cc:Y"L _Й/ Nve)Jgc!k?cL)a eʕc7ĩq$:J_8F,[v }-_~[rQ>q~Džyv[?c]ѣ 2Ul҉_H}egVƮi,T1Y$ǩ\v|Qq%;c%+2sTwU;E:Tِ(YJ"SV*li%;dte ۗ;L/|lj N}թOŋU)SGF~ƟH/9'$V߼RAQQQ/Ы:VQf?'C}]<BWI&q$ǮnM;l3|SqJ t=^.&x~%~&vJbU뺱/3.>B?'nDŽSeG(Vd5^e.&~T/9%?qirDNbk\xGTm(bX˞|=⮯-m]X}6sئ }󇹝[9-/믱LVVmem[ŎYn">:NEEÄ>mcY}^ǘ4f!?u[?$sk;/fFV_g,szqOf]FYv nd^ iS%V~UѶ}(NcNS?d_`ט8ɑ釨Jlt{ ;& ,>mY٢m*n.Eٵs7Q]AdNʼͯnj}cY{deWcƭncGI綾^&RNSۼ~Vũ_zMʘedaXٽS兜n ŗn9~z9/Vq"YBfʔFA+Ɋ,!>#i!ĕ6LҘ3'Dy7LYYԭdrORpE4!Ds<_+ޚ0V)DB!{K~9{Kx!%bB!$xVw+W^gd !GBFBYi~SUՌPRU5#T]*6Y9 /Fv"q+$'~z\|'{:ݕ+ϭmv۹mD_ YGewۧMX 2fOq^О]`%e'm/TWDw@tynFc{;9'YEVh?*h6ᘎ^7eEwX}BC鼋/6)l܎e!AumU%y5DvU,B!$$։+Ů]G U>ȿ$VEqXDEVaYduYH_eTQр Q^^XW$[,XvږZW/gN(7*gl .,OmNپvնm23.~lpu{Ȝ VdV[g;={\JheӪ\O;einklc_S3 f嶊vvʸ2}G6dڍqŘN6{9T#s_q"?/~lȬ:]\m]0.]fv:[UyS>r? IDAT*q? 8"9yUD#˗Dٳ1uyyeq=aȌo1#KjsFGS4Typl"B/Š;Q]*ۗg2n}Ol71~݋]AΫ$ANAӄD/g˻ 5n;UPykq'z}!S$ߦM0Oiڶ3"c^cίMǯq4n!~^,pMb{{l/pTmA}Fԏ.$O8,v)t(4?;vA0mڅQة̙cyB.Q8MVe8(sn 8;B9+^իsuQ}nuxmś G}D88eag}u{ˌ^oq9(YESg\ΣΣyE(SJݪ<_2)>W}nvLE ^[N'}*}r+窫xnb]uePT]Ӧ](qk52}PKcܜHpȬ/I  Y+.׫}Nv:@~VנGcÿ^q+[x[pnIVIeϫt+ɴ+saܶOY~ /~ՏqcML{ 71GY]^mnQ6ƥ߱Ae뤓YϲZ,x͋Ͳ^}}]nqUK?eFW?7:<~Tɋn}y5DV޽ͮn::(j)堏 wD?b/ތTVNǹs1[P> ZR,89yۄy'c&!`͚bǎCg"- ;εKӿ3Ϋ%8^ Ɋ㇐EIޔ –п/}F ǡlPmB/sWd !2%t!2ؾ}C_n߾_ B)D+BHx]{=o>BI_ihgya\Lwc !̻a&*fn[v2zv?!\UCw_磭P,Yhqb_cNc/qYSqzzN'"Wd !Wd !"kwփyuO_ggkgcIݶ}crMlBTmf,m~>Vkehe=~NeuO֮/<_Cg[>wˌgd s]2;2:Vef'iZ+ON !&q.ՓMTe JTl]YujkeS"q0OK&.a&7xkBfLJ _eNەdBI"[,#;ufXWSVueӧ/`UW2J]ݎHNri|DrT5~Ne21IfHVde%}nBs;?K=!fB!!%^fkg?83f,?qb 5kT;'vdG27c!S&selUO2eQÊ%2d2J݄D6dFGkg6~>ztO^dܖ1{Ҽ6g/m>NQXʜ~x[ŁLY!hj۶=unʝ'沮ue3SGTO[B!!%^Nh$ҫ;wń:Ʋwle͞4Jwrrc.m?[CTf'MU݌~xx[g+[qK>|@u%ASS3B!z!.+%;‚,Wόmc='VT|3w <˶v0u#_gff0>Qf|1~t,XGBHYHVdPN%F22YQėB"Nd|3<:ʎ}۞clg%Gok.a֥+vɶkW&_'A~Qwn(Gva~;?Ű"kNDVɞ(%*nlSILuBHȉGJrMXqygKB un֭M7>#K&B?BH$E׫ܵk/l߾)2훰bEy?B)Lbu}6w` pq:BLd|{82ͪ\zlyͳ-[^/AXG!ae]HVd&r"с~voEB ֭%aYB!~ظL&{*Ν+ǟĒ%H$ܼӵMMQYY  ux 뮏&vz}w !,6SZ!ݦ= gdR$z !i2}iR/ ]MD/!9$;q_@"PniyQ|#FHBHǼ^yBHۊl"@6UnwH'6tCCutֲV>'[ aV?zw~v(0@mltv]QH2+V1׳↕7qGX}ӥzч$&-z;-/ebb\ӀLA}GQk.ǵݪ:ʜO?EvEosvQ =Y+&QVVӹ}?W\7F;u{ɖEۚ95\;辷'oel;mQă]]qŋJ|6q*M܎yPǝml1ALb"kw|_,76eKԷ6v:VqK,[fO3s8N{&UY;]8AĆM"LdJtnyf_^^?N__t"+kg]vTT4HtJLVj]?sSQ`mw{G7_%^dU }_nCQ;?N\׸+cU& =U'on?p^jedd:~xF}\FCü\s]sYvrT퇕nh7Ao(ΏN>[}}ioaWW%>ꪜbT&fn[ ƛDˀ/"NJWeneZGԻǭ~Uz8]}q'_11YYIl6D/JDI2E}dGc~= +~2^^tlekMBJd 1 Fo^z{PQр6evʦLi+2Q"mvƺV2WG7+ 1cYDDcɯ2?|.[W\ANeU%{܉qz(iEv8p`ۍy>uEf\磭PqҊ9*޽*6苆yyN}6uc/ǛYs}S4^"v}Αiuo7~džȷ*M"HdYsZ1eJ#Νk%;10~sZ'UVNm'*ɴ*퇓Nܜcj7Ʋ6r=e~%x*NǓss˴N12~J;Y Qj"+Ŕ.Z~Ɗoݴq~^ փhlփO_ d߯D֨ &*i%c_C?dEfN%sĬ&^f"glVuILWm:;8]*Qq\/vrˬɔ9m]s;/r?lɔlXr:&܎С:&n}q/*q,yBOd/^}zĮs~;}Ƌ\+~Yշi뗿DEi܎s1,9FU6e>%IlF&ƽ~sʿǟĒ%}.s1888!5'}mmxggvTU@O)6 { D1& bboBCC{nc]m݊{"Ν;7Β%MػVƙ3g_ο"=Eg럭ؾ}֮]>!Lbo߅ ^ĩSxn҂p}_ vE]qavBȻzy4>_t].5g϶ mGFFt{r=vVv%BD3sOږ[B;f'1Y=/z{q[M'キUˆёH^B!Ld'Tz2mkjfDޅݶ̫̈́MW xB Xد 4 W~נ"SʼkET+\%D gJϞ=.5Bz|_[ռ't^氡H|^B!Ld]MN?@!#K1VX߽Fg1١!!Hde~mve\%%6?ك c銥hvZى>vSTI(K!zWBiW[;G}Md2&l{DN?ø !$Zas3;´iBVb4;ymjZgΜ7Q%DV:)_xڼVo'tvtAmmsbkW@m6l{ } ;:ɍч\'矇=wQRV2\"-FnW㯾^B!//5#Av/~B!$,—ǨQoD`bTe}ܼw$ 嶚GŒGҏBHY/ST݊l}\-ye~2sӧ[rZ5(L"keVFNnA]ݜ<:Ÿ_˘X;!xv5+bhbQdٱDYOok*+ܹg3zUQH] 1ZŞ9>1.qflEu8]Ld#N[_?'|nhl.KfC4Ƕv:6dQ'TSfLG;X!$hwDSxŨVn&GMe1Od%Jq0<>z vLX߷JXԧ}2 }E7㺥Zzj߄}& c˜M*U#YOٶG:wzNll.W""G44s%Wok?,zۏ62e2%=?{ᒥ QKbKF1Zr~vt,&VfQՌ93o*lzfk"Kc0I[3ŔfC-X- 8wጀBLe^d6',*/F4~nl/-*1n;gc|BC</v|oYϺۄ&Xڸ}}c/r"6) @+0X)+vTWOX'Xk'5 CLeN֪*˾ZJnۢ~J_c2eQ{wT<mw]?UίmVmlĒnB1C&UY3vۭ]'O2 dL@:u;DV]ݰY;ߨ[6NDq8B[BH|RGVdL"Q@* TZѲQd˲cŦ$HYn!cw1f@:%v2_ Z],:]dP)s+x;W*Nl)Ti_&7qVǸC>7rÎI2ӧ/𭭪,r2/2s'&q7A!0c֬H/(CiY)FI`CJ adt(P1W $KSfg׸.殮ja]Q_VWK^s];ۛzEuEm0a[flv2bUN g'1$]vġyNFxT2N}{T?Z<::ĉ}:'N-sXn.>̚X62Lˮf-&7rk߸ }E/ {~;wMͮY6=W @)|{f"]]h QHg_q;vQ߫f9gAV1uD bZ<22zyW\d#*ɕruTT[˭g ^Y9q3*q! BHdGJ%N'k+VN_7} HvH`쾧XjLfq65Pdٶ37~/[ b[Q'aſɉ:-6b";22:ՎB˂p஢!!$I=xv̛W.Cyy n]~5.<$IKuccd,MddX5^^ЉVc(%a6M%;cW"2XdbmqEa<9/s+Yp$Jo\pҥ{l /{l ݇>_ 7²e5(/Nǯ)swpb}>`a@"ܭ>thw`,/=+vI׺Smu.rmgbԩql/l3UƟ*}7n;*+~9ź/.xU{;Yn)ǣ궟oV ?1c\tP\WExT'^#۷o^?uqGBH5g=?$/AEET) O2e8396& l2_9!q'(RcWO s|rܔwIjr{~~C=K^ݭ(S*r8ND}}**C8 *B QFz#gkgLHd HϯS޷1nZІ5HjZ|.W+R;愀BH$MMOyjK!pհkYp`jiymQdN aIB̙!GqITWK.G:-?fJ2xCסd$rρ;sƤBBo)G1:/?8ʲ>\qR?LgdWZ-빸n}mLnK!,! Ylځ'8~3psXIF/l:. EyeJdKI} IDAT!xk1!b<؃S{7 VI= TEX^dƉBB&\%BLtt g᭷PkQZ+{6OHfmv}k񖎎$nKGGlKG.sukQf\!0%B\/yTl\}tƔwo\,)o!ylʴ~k1o&[ !qضO>y٨M34忸qq]݄Mo6uȶ3m谬O!$"K!fz{]Xw9sT"H_JjnsOK@۹Ϣ\9C,rBa"K!|0xӧ㮻棩T|X/+Qcþߞ>-l]R_oY&j'BYB!$2zzk|Lw9y.vrI}׸M!,!;Gylg[gc4b5MO7 cݼ5טZ|O3W0"⒆We؜Ba"K!Ď#Gchn>z஻c$_> W[?@*1+q\v{;.mhP.ӷe/mhLz !,!M{N '<Ի"q d0,~??P]rezsevX](BHwd !L:FaAnG_0˖UUjF`n,[w>Il9ΎKB)r"K!dR1:Ŷm'mCgpp58|; `45n)$I,Y*w=7[,?7o%oy{YcgBB!߆Maz^S8rĥ0R:DI)TU;>x>7̶VFL!Ld !h8}?.{1mZ9>5ؿͽ0Z:nl"D4[n*>Of;::ׯܮ@!,!R '?ىQ wݵ w޹o@6EhRRZ )&Kgßw{\4o'MMOyjfۛCTz !0%[Wfck?icCfPW~sdi1s'#i뮈$B/!Ld ?ɒ2'3 {vߊmNiXD‡ Mc'$R#᱄4S/w_'8 ozny' 4 <(.ƃBa"KH&od*3Z0'=NQ.UVTlI7~󙝯7"Sc7яvbƌJ|sM QR/i @+KҲYh#Q ZVCr8`RCc ƕ?MS|dI026j #0 ?2$/,Y$." 2E(9 #)FZtD2ic R[U52ьc̹%;xѭص ?\l޷@"KdƶX[ 5*kL^r7~OE=kgg^?I̙瓅''XI\>srNc}+9ev}0ֵ'nNW73˰UNǖ^t,ĸEM'OJŴїNq`7.mO;Eo.Ȟg<1%Dzy_oMIJ贫IV/ B-*;K1oT|K+ԟb``(+Kaʔ$ t 2NHb@2D&K=.sOdzd45}D+ co<+{sBMۚMo<9&F]2bQsH2䨔k/OES?i5oXql ۪~ezmŀl:ps<ƙ_Ǖ(T_Ld !&eԷ )+| S[dooUe}/u_O|kp Q^\l6ah(sqT?:zpx/jqmQSȖ$ִIePV^Y3F}eOtJTݠV~F_qe7ƀ_r`>ȱ4vc..q'/x+tU-/Il"rWEedP2T0%Bs|GhQ-ŋ~Lhp:;qX7};vb6;֍g;l1#5kaɒ,^\0kV9jj(//A*ehr,RC)4 L=ෑɤq_ܹs?Xd֯olȂx%FB~9~?=_cǺqiZ[{woZZܹ!@UU^XEjvt\وyĉxW_G'؉oDv8˪W] 7k;[q=_𰲌SZ{uxk& "!d{ذE:Պ v---x`pp5B)lvnwͧy gQ^^+q`͚uѢZ̜Y2@PNb$E55چ?\)|i9('0Ld !4ub6@iiuu7o*/Ŋ XsԠb9פJ4wo×^KE"s.WB8v8~ J$B pZ*W#2dۉw[ulW\bʭ Y|?-w?kϭUWܹSQY=o+'$!D!DBM{,[0Y.-_ MPYF:r|A˞!&`bhN+ZƄK/JŒ+NmZmѬWdLU"ʗzȗVdilL!ȸTjÓ2孫BBHbvɄ9%NuIdCFL",*P8ͪebx_{<Ba"Kz1ʶK5'vV)LQ1 V8ReK<wDg&~ /ǎ/U,>)_:Da !vD9>zz[U5ndǂp.^(:Ps;?M?|NraeeƷ6^eo5Y=[u5\OnW}pSqZN_!HIKpb ihO:Q$,qD /[+DvU[?E 4>H1wq)_&dm0nC4u$oKj׎.$CwՅɶyx*rQ񁱍Q[vv+{J\c$/?7YPc'*1,y2mΙdzߝb/Hd*pcʝ)/kU_e_ jȔD/b Ɓ;pjOrd.zan{*+x_ed[aw;X#Ë܎WrUmaq7:ng?Y*bB!|/)4p"'(ꋲOA]P!׼/^c!f,=QV/7ǂ(6Ax BG|a!q2E`2o6sU mî](4娎YqN??0+_Dp>e"K!$Xޫ >ͅ 'nQ3nkElM^={m"]sO- ~[_çv3~/ZD>ϋDrܞgd| ~Mnx<o-&B 5մE[5~614v3ջzl2IyuEuj}Bl6>l?tx7bt(Kxyȑȑ umO|2Dr\gdρNS|c267*q\%B}m/^v>^=rWϙ-SzΜ>~'k>2~5Ǯ\Fܠ._q2RbJ/nxʏQ}uv%q3ڃ~LU̝;W?%Ka&φ8!L" [ۀX|Į]n=|Vlg<lŔ'et\R8 D;[aË8u<ZZZCk8];];΋V~ZP㧘W[{6OGK6!o-&$$Ƌvg$$x2 WZZWZZU 2+}7\)m#!+~lYB!ldmk55,!,YB!dRh4 ^}Ocٯ2'_n_غQ/nmk[$BYBb?U/YUZ~$&@ޟmޜK`y3bەJ^W/3ʰjvE,WXf%ש/6ofBYBSą¤XVdz\Soc,cWn!mgN2v}&DX&vI}^9ijellcmܧjSY$Vd$]|~~1yˊ,!DœX%:&2 [%]2ɢ[eOI?_1 _OD,!&˄.QKvn*ɚ=a$VF^MʰĆ$⸵Ba"K$JpVd>+ >TAOGGUT%\%DVZ6ꔬ$NuXlU-K7;ŀjlaԴO<g#6"BBJܬ0iu~dEP^*&Q-N~h6pR\p < %YB -2}UfL"d⥿ATHCWyqinމGyKn#$DB=Nκ=fn 9I ! ( EZZן޶wz֪ZVZPr$$$@=ewfg؝es}=}u>5kf,ˊ~Ӄ4P:0s m9szgm뿴k}*m%Q0$G5TyThUqOĕO~7̜gc~v>q{%zmȓvu$X;o_>iQ:&qOSqO`eQ&&=歽٩|?g}muöm1IYƗ{6Gmô[Y$΁zSڨcןw<ϧrxYƿ0.MUܫn_NX>'40s4i<x/:vim]y:QΗ㾖?" @*WdmӧOkYzIn={rv~}\4{O_6X^˴NNO>=iL~*_Wzjn1ZWmx1hqk| oPq_ֆ}uln-lp~km3̼'w9v|Є )˺$=n74hX_e;Wˣ.*_&i2mǷw\ϹmIcӿɜfnm׫$_|MpEi,^Ez=t>^:/|m^hom7[M[ؚ9۔8V>u,њX&ܷ7o]k/MԱV o{,ӧ@`z/.^<8Wb]RcMmk>f4lkocϗ^;_uI5oW,Y2aW,YRc`zÞh ÞK4X*=zt7YBP>o߄ }b=oѶζM֕}r2ula7Wakg-\lل @s&Ⱥ{ݮKݖ-έxula7WQe:ng}%1: 0 ZvǮ]5c,8Wd##UoFk6]f̈́cZ. HrllQA|≚֥@dN83gBFd@umܸ^?GF,5\Y> Ahm'˲Bk۶nouM7dq> %X%۶C8pjyTa)Q οx6ʱ6c=·+4(nN'##S̱/C-x6x4Fy#YZe`~b:F8j)LqϗZײlH>umԵAۚWZO0c dY9/haoZr;LE=A79z3آLv:gMa~&8+4x/-՟c'f''8(Sw: SF;ǢŴI>MmuQcu]AEKKw]D-ŝ_Ͻ-!l]gcq7J߯J_?{4(>a&1F׶vC1Źz?o*Hz8~|;Z?-(+ W>La,~uϱz9I?+5([YT+ OOL~vojmZ5sqk99jTKGΏ$osx9Qkc;kyO2SvaCSVPxu]>öޤqVkItaϕJ֡t'ZU /-4Р'HV=\iApEi> ,Q4^Z ʳm;Wrܪϩmz9X>=ՎT[mmsǿnm~qJ/-` Y|݄/ vFvjq[Dž[xlA)bmdڤ߇֞sY>u:oIͿZu,l*ە>Oޜ/v.ۻw[;=hoݹoy:vܶΫXL SCc7>ӱlgZc:#̹v?̼r.$qκ3X{&!AmkXsVؚqSpE1&Μ99sl2q{Ֆ6~ۅdI$1uDs.E=aε0Hu;Iq3y۸ǩR" @ u/I/8j]+VDu60kMm'AFs9U1u4j8?1M90m3&n-yӀs~^?g" @=O?>E}'/B_u^*bz}}BQ^=g̘.h<~Q~߹yE«<;0s6] ;GgMjlr;̼LZF=גus~cZQc)͌48x4ϕ$%XDܽ?}A|~a uw=̏?z-o}ZCO>ykD+Ժ'AO`k5J1cK4J-cV>$Y{ZyWkٶW{Zj:2%}_һ_2_GNÞ*Sn㶽ד0}E ޯZYSWj&ͯpy+YFkOVs+$d(7GА>xeXә ѩB]7\nƟ}脫<2yUzmڎs(}~md? 6>ӱc-Ok&VqM8i/J8N5m%A:Tz..}*)P,h0v^wtWkpdPlQvVMd^ {3ZjäeqkQEu;LaҶi-<ŽtqjqS,LaΛz'TjQwaQ/6c"[Cߏ>߸:?{NV.3Ep 3GT)8RT!WPUSS[~^* [[^i7k9?Ώx::k`58dԓ/WsOuݵoRv`TPAE]Мs՛U0z%++*keՑi MҤ'n50pdcD ACa}[_kFŦTHFl)jbQBA|Q|a<#lj @M=O>CmHAң_tq<5zUX b@;RPNG{)/LWYBק_oO Ž/6]T!5d aPTլUt|, oޣv߯sרY}gTh.ȶѰjemٖ=l)Ė[KF A dTL̎g4\VjfJV%ÒfHv-V(ՖZ~ڒ FʾEv̜y_vtw-kG,u]b'>T_Z$5^[$Ij48^K2v,ԦtM^Z<\=d]W?R) Q> 6v;-)/)+P,Y\ ,˲(B=t~[9 GmXm?2WJ)٩S~;;HBwx6uq[䶭[ wx{P?^qo}gRcOj^akO~nUd2PJYJ&%Ӣu_~IjnnQzGWZc_@(?K%ɖRlkz>v0Pu~P0;ϰcp ^ !8ؓamZ;d4;(eZقGt;6Ϟg9?⏴nZO{tp\v}K^ꖲc e nm$f^IdQ @CS:p{n=]Nĉn>՚3uWIkzV}?7Jˌm)?W󃚿hN6W.┕ipaʯJJQT?,חΝ}ںUڽ{{^ziPt -[1j~v.jV_R6(LQ#żrRpRڼ#~o!yoٹ`>5kuf-ooAiA%m&,u^_zW۶ՓO҃{%~I)-\خkgiÆnlsN::edZkVy/tѻ5wv9&+R*ַ^M>WsZu|蘬֔6ݟ;C麤5kaU5ռA,?~PO?^|sdNh._ߥK;٤TO,Ku'~ys_K4>X˲ 볻Rg[= 0&}oufQf]DD=vdHA9ʀm;zYO=uX/xJ957hL ˴xqNO{޳^f5%Ru :{n{c4^9~uݲtպҳt>Ygx{?La AÎ=<=zũA5rd40O;dYVU}5YԪ&P@NgGhڽz{4^]r"]xXѥ^zZ?.͟ߖxVuoS_U}d'Z_ȺW@xJС~qL=vPO>yXv k^slY<^ښeY:r$`=dZ^DtŶ<_ō'ɤ`Ab6o^Mҹܹu*& !C3yMrR~}%100a GرF=qρΝ#/GjϞ:ujHyf꫗Ki͚W^S)kJ=O83gB0AdrJƅsܱ8+AƱKQ\/<;{OA)͟?C7/ u zP{{Ӕ %7?c_=^ת_AB$+sZGaT>7|˿Јfj uUh˖ZzemmS7&K/IE4 *ߧ]^0g%>٤Z۴j%s>e2)͛7C7 /\i`nݦ}k۶nouWd켯@PW/{u~l}%zoqiT~s;w闿|Iw߽[{ׯҍ7ϟix,Kb1~it}v'Or[ڌU#.Yu^9 &ۺmtS w9qYB1Y7/Њ]ݥ{Q?n=!]*rylI~鮯=zߦyWb޲ n9ҥkXAvܥ:~|s.]W;^z+]Z_ZW?gΒIf9㬙_ j.zG,uò,uu oXϟ+zIrj/T&iڰa~wsw}I'n?%KwݯjX lڷ9m^9Gǎz5X v~#m m6uR+ajfZӠ:9'U+YRssZVт3uE =ޭ_%=1=~mi˖]OFU5wN=)躎>o>o6{ROCW9Ǽ}Vr<:ռůIz,ut4k˖Zj^١l~ÝzúUz[Vkhs8>iҺ+}v=/o]N+m߬~%z+kmWL{[+aO^WgNuQlΛlx[jiy==LcXױ S$k @K,͝ۮk]=vP7O_M7u׭Ԋ]ln,JJRZzR} *J~)5רK[KbTM#/z _>i|^m8M"ߟ?yX_Pd&pz;NI A%Iiz;i=яviW'_ܸ{XŢol.lJ+eJie2toOiklJ7x>{N}u{jLUԗI59~B߶a {8۬Ĝ´SqG5dL1u+EښѺutl]zb;t/~g=MfS:}:Y]OFʥr)Rjz=.]}UJw=yv.}]7烜ɽ{4r>g V=wn[|Z_Xܶ/-_aqi͜swkǤ~uSy @٢׼l{ Z{DR{n]{B\9Smm"Satf4c8vJ~/F8]iz_MjEO |!p}IDAT_~~vnKm9,O(N鬳:tn<w<:o{}vj:kUTk08b8 k] |jm~HZ/ֱcO %ݵ)tIk/ @kjJkŊn-Zԩ#7رzSڻ_lQx2;~Uf, NULeYtZ2cїdKVR*R*R:V*R{KVu/+}T?B(WdYbjmhժ]~fz{!mvJ--)[U6-42=/t7/)+YÖRC)SҠ3=`U/-Ӧ_{ҩt HM]~Y˲&]rIVɓY͙ӢᲨRMc˛%Jj$)% ѰY(T)+II3wyvnZ&yWW9jdsp,II-jO.S&k46}HjTۡ0jKWoR:V1[|WrNArI  ߌ풤l6VLi~~NI^M4bg.8_`S_ͭJ4邮uJ-۸qDƍuԩԶVL[e+eS R#@~tW3+ifs;y 6mЦMbcuL@MwYdS, #F$%`;=G\IݸM,QTQbj}#Rssfvġ\1WHf2ܬZٵ"@zl٣A6+I:SM:GgkYR;"u:ת噥jmj$ E dS|J6(Ulэ;WR鴬+QTn^tbHWdd-[mjDmgUM\?rm.%~Bo]yE a\ /NK.T\+I)҆*dkI @}z'5'utnʉ7N^Ka쏻ZOv}"Pa\d @d @d @d @d @d @d @d @d @d %Ȳ,m"f" h(\`wPn9d dk֚DTR?c9Eݷct>y Ȣv5mPy?o7JAh:de˷Iۦmx׏ÎolQ뵭x9v~o ~"JF_s \V~vcΤ } Fqz[mq ۆxﵽzXW9 ։x굝J_Mz(}[cTWd+Qz?1BYZUN&ؙmai{ 6X8 :~ۇYu4x-L&ssK4}}:(}F &%`*@,PA@ A@6J{{Ĝ*}%CV͹F@}i %0 <@8ו/+nzRJەwoysarn6f.'h+a2my^9d[P`0 A8hyG_ t^m]fnմ/jn. d0-&´r۾#e ^$'u Sq=JAvvP պ6)J~m'U8sh|SBfz/flrJmߤT"p(,C¼ӏnMb}1l՗_~j;Jޟ%8/@=(Ђw;lI!OmŽ/qOj q^bAfYA,YAcVk}+9J5z l e(A+rmYmIW&1F:ۘJgZӱ&@m0 o^[?ncIb~6(F[-LlC۰At `XzF |ΫΕ[~ Av_+Iu> ޳]-V6̽ZWgMlV c#MKv;F}Z [3~/6ypn!+hc30 {ۤnax LeQ` m" # h(\HoU>pE@ A@b|2s'[֭>8Q/\>1۹fNa/6sR$9a2AV!=OE $9 >Hl6Oܖ]2嵿W~}x vΫ~9:9aL4ũx:3l5=^ [sYiZX{1'q^LC_[AQmoRc39L߶~}˭^B眈rn&5~d\-OA&(xeӗq]2@t&,*GJd&WRyuoJ h)2|Ig=e>ݦSgN *jCu_+6 č|崚}D%_nN|znpEL>x'l;Ivm^P]n&)츢ozxd=:GlĹ ,Bsma׏6^cҞI]jR9LLۉӯ_0 Sǵ&ۤjLM#,K i&5AlQ"Y_IbV_:\|fH**\oS6g8RY-,fO.x~O]+7jjc{7ks;5_?S|]ҷZJS\T@a@#UGSJ}/Pz1Wu/Qo\T渤WT:wIPMҌU7~6:S_$8tR׭UqJmӂ'{$b.b6bvD\j+;2+t [K'S)IAS4Mr\im%l[I<RZ+(esS|I:bßl)wOCk؀Fzd<{ZzuYJG7ܜe7n=C]i`bnӃ97,}-مklBvH){\vN :yR!U^ڭs8of,%84#ZpNtMQ+dwL2jۗo׮n57m4}/_&3FWzw[ݪQ0s s Ɵ$X ){sN~xPm50"VW"eGl}e[KrZD#WjEo-SJ7SihId}06?ӱimW:$Cо?*S߰s [Gd 9)W[ #<ւN\]G7jžw=ϔ׹#e,/-(IJ+K7s.x(f}^}U.gA;XMnZƙDP:iP5 :# Iv3C#U}Iؑ )TRq ѼWN+?@O;n5Zt۫]]w?34 'I'^/4 jAc5mڡ*u4j};(*?tF{e5T[li?Щ$ޭM|Nco:px'_SiQ]}Î^ڬUJ3&0ɀ<>ÝhUSg3ڕno~ҩ!xZ';Z:iYΥ)zO0)}qSfD3jnEѧ9uym{/Ku+KUۯao,ݫai:>UnaOR\AYpF=Se}B)KjJ$6jHmf<ښBg׬tA!^;-MRvAvWm Fe^}}Ȑ3ǯ-:DW& q;7j}|AHҚ*;pL35cުeCO_xR)h˶ɲ, ?_dzz<Ӈ_W:!;ںt˧ '_Pw%V~̄gSj ,SSwfN-]Ԛf[[Εf4%]z?DȃjIWښaP#)֡N @>sҪ9y-YЌLAG3{_3@CYm5EZw(0" )+UoK蝹Rp_{lJ)uXR ~kB,-:۪\lY)+R;#:7K[~vZHaN:bng*noSE#t-Sf< :ضM @}JM(j(-[*] 4L{RmTg+I @5YJ-}Z(C*_:UMM2-Kb3/]#ke4 @-lJYWHg]!I*idPlYM+Y9ئN+§d d TVcY{{ضM Wd#;(PCu+E" @ @OPuDeq>q{1oO<,[T[\L\M1d$4{m!A˗pOZ\f.T嵩<w I `Bv]b6)09o\ݗ;kVZ#!A@+/О=NsϞgbz縼$1&ե^Z R+~+jL ZU&s֨|~Au!H4T:Ȟ{F֚N~m,l zlDudI۔w~!Aqp z&Ԥ+b5k.4JYIXEݹ;w>5k.ΝOVyխ[;knw$uI0PR}=Zvkns=1~_2"[e;k淮0*U \0)U/jsVuZCgmu)_}Zb+~{dL +I۶=;mߺkSƭz۶'Y~v[D;DaC>A@Ac׆dT1d|+D PC,a^ժ!AA AA5B BYxՆVY.lӟ˶x_l+.X?ֲeK_|O0mk<;f˖~N&!&~A l8!8ĺIQ@͛7db/_G4Nu{y1A0! {d by,B,4t%:Y@CXf Oe~͝=~oҗBUu-}IR6O*}BnyTP!ouٖŁIENDB`MP3Diags-1.0.12.079/doc/295_config_quality.html0000644000175000001440000000746612040502152017537 0ustar ciobiusers MP3 Diags - Config - Audio quality

MP3 Diags
MP3Diags-1.0.12.079/doc/250_config_files.html0000644000175000001440000001370312040502152017127 0ustar ciobiusers MP3 Diags - Config - Files
MP3 Diags
Here you can say what should happen with the various files when a transformation is applied. There are two "modes" to interact with the settings: a "Simple view", where all you can say is if you want backups or not; and a "Full view", which has plenty of options.
The "Simple view" screenshot shown above should be pretty self-explanatory. You can't select the third option. It is selected automatically if you make changes in the "Full view" and those changes don't match exactly one of the first 2 options.
Here's what the "Full view" looks like:
The wording might not be the best, but what it's trying to capture is that when you apply a transformation to a file you don't really change it. Rather, a new file gets created first, then the original one is erased and the newly created one is renamed. At least that's the default, because using these options can make things quite different. Here's how this works: first, it is determined if the transformation would make any change to the file. If so, the "changed file" gets created. Then something is done to the original file, as indicated in "Original file that would be changed", the default being to erase it. Then something is done to the "changed file", based on its own settings, the default being to rename it so it matches the original file. If the option in "Temporary files" was to create temporary files, the changed file also gets copied as a "temporary file". If the transformation would leave the file unchanged, then no files get created but the original file might be erased or moved, but by default it is not touched. In the first case, when a changed file gets created, pairs of several-seconds-long "before" and "after" pairs might get created as well, if so configured ("Compare files", under "Temporary files") and the transformation is able to create them (currently only several transformations that change audio data create these "compare files".)
You can play with these settings to do comparisons or more esotheric things, like moving or copying to another directory all the files that have at least 2 embedded pictures. I can provide more details if anybody needs them.
MP3Diags-1.0.12.079/doc/020_mp3_introduction.html0000644000175000001440000002535712040502152020003 0ustar ciobiusers MP3 Diags - Short MP3 introduction
MP3 Diags
The high-level structure of an MP3 file is quite simple: a sequence of blocks of data, each of them with a well defined function and format. MP3 Diags calls these blocks of data "streams" (for lack of a better word.) Some of the streams are formally known as "headers" or "tags". Here's the list of streams that MP3 Diags handles:
  1. MPEG audio stream. This is the most important, because it contains the actual audio data. Normally it's also the biggest. MP3 files should contain "MPEG 1 Layer III" data, but sometimes they have something different (e.g. "MPEG 1 Layer II"). MP3 Diags should be able to handle these files as long as they have an ".mp3" extension. Note, though, that very little testing was done for files that are not "MPEG 1 Layer III".
  2. ID3V1 tag. This is an old and quite limited tag that stores track information (artist, title, ...)
  3. ID3V2 tag. Also stores track information, but it is a lot more flexible than ID3V1 and allows storing of many things that can't be stored in ID3V1, like cover art, rating, or composer. An ID3V2 tag is made up of a header and a number of frames, each frame storing a particular value (artist, title, ...) There are several versions of it, and MP3 Diags can read data from ID3V2.3.0 (which seems the most popular) and from ID3V2.4.0, and can write to ID3V2.3.0
  4. Ape tag. Another tag that stores track information. I tried to implement reading from it, but I don't have any file that uses the tag for track info, so I don't know how well that works. This tag is also used to store normalization info, which is handled by MP3 Diags and seems to be working fine.
  5. Lyrics tag. Track info, lyrics, more. This is not fully supported; some fields are currently ignored, but basic fields like artist name or track title are used. It cannot be written to; it is kept unchanged, so it should be usable by a player after MP3 Diags processes a file that has such a tag.
  6. Xing header. Information about the audio stream (size, quality, ...). Some players get confused by VBR files that don't have a Xing header, so it should be added if it's missing.
  7. LAME header. An improved version of the Xing header, which is found in files created with the popular LAME encoder. Currently MP3 Diags doesn't use the extra features, and treats LAME and Xing headers the same.
  8. VBRI header. Also for handling VBR files, but many tools don't recognize it, so switching to a Xing header is usually a good idea (and MP3 Diags can do it.)
  9. Null stream. A sequence of zeroes that doesn't belong to other stream. MP3 files shouldn't contain null streams.
There shouldn't be multiple instances of a stream type in a file (one audio and at most one ID3V1, at most one ID3V2, ... )
There are some restrictions regarding the order in which these streams may come. Among them:
  • ID3V2.3.0 must be at the beginning of the file
  • ID3V2.4.0 may be at the beginning or at the end of the file
  • The Xing, LAME and VBRI headers should be located right before the audio stream (so there may be only one of them in a file)
An MPEG audio stream is divided into thousands of frames, each frame containing the audio data for a small part of the whole song.
One important characteristic of an MPEG audio stream is its bitrate, meaning the amount of memory or disk space that is allocated to a second of sound. Bitrates are normally measured in kilobits per second (kbps) and values from 128 to 256 or 320 are usually used in MP3 files. Roughly speaking, the higher the bitrate - the better the quality, but there's more to it. There are various encoders (programs or libraries that create MP3 audio) and some of them are better than others at the same bitrate, meaning that given some input (usually an audio CD or a WAV file) both produce files of a similar size, but one may sound better. An encoder may accept parameters that define a tradeoff between the quality of the MP3 it creates and the time it spends to do it. Also, some encoders may be better than others only for some kinds of music.
Another thing worth mentioning is that there are 2 kinds of audio: constant bitrate (CBR) and variable bitrate (VBR). With CBR all the frames are compressed with the same bitrate, while with VBR the bitrate may differ from one frame to another. The idea of doing VBR comes from the observation that some parts of a song may sound pretty good when they are compressed at 128kbps, while other parts need 320kbps. There are 2 conflicting needs: on the one hand, we want the files encoded at a high bitrate, so they sound better, yet on the other hand we want them at a low bitrate, so they take less space. VBR offers a nice compromise, by encoding various parts of the file at various bitrates, so on average the whole file has a lower bitrate than a similarly-sounding CBR file.
While VBR files are nice, they introduce another opportunity for encoders and other tools to mess things up, and some of them gladly take advantage of the offer. While the VBR audio data might be OK, many players need some VBR header in order to play that audio correctly and will misbehave if that header is missing or incorrect. Symptoms may include showing an incorrect duration for a song, being unable to seek, stopping playing a song before it finishes or waiting a lot before playing the next song. Anyway, other players handle the same files without any problem (because figuring out what should have been in the header isn't that hard), so you may rip one CD, try the MP3s on some player and think that everything went OK, and then try another player only to find out that it doesn't like them.
There are 3 kinds of VBR headers: Xing, LAME, and VBRI. MP3 Diags identifies files having an incorrect or missing VBR header, and allows you to create Xing headers, should you need to.
Another issue with CDs and audio files in general is that different CDs might have quite different perceived loudness. This gets especially annoying if playing in shuffle / random mode, when you constantly have to reach for your volume control to turn it up or down. This can be nicely taken care of in MP3s, by using "normalization", a process through which the perceived loudness of a file can be adjusted to some standard level (actually this can be done one file at a time or one album at a time.) It's a good idea to normalize your collection, to eliminate the need to turn the volume up and down all the time.
MP3Diags-1.0.12.079/doc/160_main_window_tag_details.png0000644000175000001440000022654211304431111021200 0ustar ciobiusersPNG  IHDR_lobKGD pHYsȥtIME #& IDATxw`?SvgU,ɲ;'\hGI K!\]r )ޥBG1PBi6[eI޶N+[,kμ33|yWbVxB @ @pJ\rRijr}?@ @ 8EJ#ey}?tr9p]b@ @ 'I(&D/g  />-%@ @p!&vt:q:!$/nXVzz:@Qd$I@ {zhii;vJJsݑ}NDB|VQ/^‹UU5ƁF^~Y\**PR2&QY@ ^:6mu.L$//g)wǔbx EL2rsx9twGG{+iaYyy~TU3u,k&ƚoӅ""F @ ohk렦f H۪C]~|>ϐ;R/(dӍ$Irp83 N4% c8B$6H" il6͎aNww}>jkŘ1s6W\!l6bD@ @ x`Y֠ݑ}G_2c,jj3jh|v [(DD0$h6G'{ֲyq Ιe%CUUd:$%? _N<YkF:[4@ ?i0IkCHپ#9a;v8KKOćv׿{ҝ^ͼ_< Mӎ1`[g/wZIwFgˮEAQmx<^/XȓObq㪎\Nh4θqUL:!ݑg6NOHGjds;SǏ'-dy2mv=Ÿ`ɥL< I1Mޥf+ioo/ǕW=H453fXL# @ ژ:Qv53}zQ/;k9tvC /sg-ݽ'ݏS*Lѹ;4sxZl(; e\[[ԩtmz4fϤd;e8FAh祰0~E ƏIGx>/7g\c<cUw|9y47~/nrrhlϚիPNJGE @ oėlײ,rs}r~zU<,C#'LJO$4?9!I/8N~NG7vvҴu0u~@zܹ3M.ilLq840/Z4@l\_n# [áQVVIߏͦH!jw3c** ˲H @ e?_k=>q㊨MƲn]^: MՏt'Hl-X&He o9>ìivrruE'VZ[2+*N8MaϦSpzv_m5<+V=X,6`i͑H`4NH$H$l6UU t]g߾ZZ2,L4ܳEeEgi@ @p3PI_~宾zAvG=X2XN}558sTa^^{m\23zzN!:~'ҝlbzIDq/>/fz=^|J.Du8i!T4sgNP~ňK7{=i!Mje%]\rX3l O(hD;D”QQQpb&@Fq:x<.[ͅ]gL9eMh=$@ 6'XNy_ΊyGit&黦/qw$Ҋ[#dy`fԌW, "`% I6v-?"8B]֯7/@oo2}&'Gp$G̉bIn♶cXF 8P7ʓ-8d/wf'-n8Z&Bdܸey1zOesՎep8))-#?l'ݾ|l8Pp~=|5_6mM2eYp8lN$! f"N@8@JOT$rr8ϓZK@KO4-㬧?^?G.wfg N3P_Zrz.1 nuS!o&if!;BQ(^@ EtO4;vY&۴>?a۰, ݆nOj!ҏS΍0M@@owjbNuy՗c-h|V::0U)u$\$I)%)$HRP2IPUEQPUE.@ J|)(C`n9jc;~dEjq:5͛/699^NMdGES-@ hh)w$Y/j5G|hhLR_aGaG@ @ J^]]=x<3n+ "I!kwl@ȗaR5PŽ@ @0bqHϸ-σvG @ @ vvΙvGj?"@ @0_Ja@ @ Ӥϲ0@ @ !@ @ !D/@ @ C_@ @ !@ @  !B|@ @ B"@ @0E @ `@ @ "@ @ !D&M6m[GTfΜƬY3@  Y#-\t#_6`@ @0(u4-"}}$It:eI3$OpP DqL0 $IB, Y2n%%E棪Cw>^)/e4L:b2mEC$ }D"& ]G7 $$L$ljǣQ&NA`)`&.i.EŲLt=,?ilF="t]6(*RXXNOO ;Y:=GNPp8B(B׍in ˉDO$tlF0$MNexƏ0M&($(2,!$!ihoBu$I"??  Q(,,Lfǐ jw^:[M, \N7~FIL^jS2af@ innU_H$AUm䐟ϨRMQ*,vZljl9~a@1N/>x@|ݔ)Sٸ}9^^[G˳wvӧO*ݛuİk^Tw1P+zi@P`YlƜ Cʲy>%3z=(jaS9@(A-8~&Moz]]mm#N|1Mz:zsp:]$ɴ:n ͆(B1::zH$q YlTVSRRt?ݻhiigܸN'a_@~~>XP(XDQB`AWINb1)1&)twwzTTlP:'^˜r[yn;(MHUR$$ dYz8.zy;͔)5h&Φ@>0L'PdIn^ o&]v}:EaΪWb ^  .Wa&BhC.  ;pGy:qGKYn ji"I. Cpy"kW=SL(jj}HPˊut싰9ʁnވeYUFL)uIG_{?:{) ظ= ä &RUU9 Nh4Mr8DLdIvI2Ƣ{l̝;3#ڜ*Pٳgb&ia+V,' s@3`CZغu+ 'oQTUaʔI,X03 ~ y]|9aYsP/ [H 5#|ŻCeHX ,uP7+z71{,f N癅i`k42I"뽔l%Kɞ6Mi騑0]qnj<:)q+E+xܴ8"mhh1c*M~N$%Iyywࢋ.(s ?>S&O=DuMgL־wu' zD<뢠 VݿA  X,ۭu5l6 LgZJΘh>+чYkhy qϻ[f p(z@+pG]Hh_ݯ݈Ui_{Ń>»n`I<韭rF ^i;*ÆBǽ?}JSNk7dɅ=6;`uulܸw]׾vYaKߚ7DI&dOO G{zy 1 ѥ--x<_޽ L: F ؼy#ll ˲0 q:ڵw^vAww7@ TUA4^/acڴ) 2U7x<o%,>>6vØ1Jx4 ݆8nd}\{UL8\>G. ,dGOxGen|~;˖wы 7(2}v{|F;cVo~{6.JKKROn΃=é1~|Ր7s{-Zx=QS]ØIc&y ?%Jݿ#B̽iZTH?` X>xl &MHԾZ(wf&̭7zp7|^H$<H$N]>/`477 ijj:BUxp,+9H(C]|/W^yiy[[;).{N,y 9 : =k)(:*Y@ȝ[}笻ə#˖86yq.B K=wS__#RS39sŻ*}n' Ixo\JEEYnZ|N"sb.ZDۖ[,/x %Jr\0OwH;YO.tK(CCs1Xr 7v;i`e FH`N'ӧOg߿ь5 ]u1cXjKrxH(~w]G$i:es.gOW]u9~Mt}tbq&N 1 p8¾}b$:D@ @4RPPOuXp:56lDUU%>wHG?RK44Mˈ/騗#SҢK2M͆D"D*ee獗x@,L+)T&dęTUtTlkSS—V2̙wI/Y~R-Z_:fMD8fp{7>Օ hxֵv:g)dyV"!&/xwg_i<.M9mH(Jqqqkq&zzz9,_6F2yAGkk3gNE4x98ea $Ѻv%Qry1V*ҋOz IDATPb ̛X\hGGĹ^'>c+xf2Əg̉(C闔c9|,Zxg}~Nk6&MeY)  5%Zx6JU`4d4i8n]e&Yz', sE5ҙE̯5nMNއ݉bH<_~뮻!1cd#:vfS>D8.^|qK^6;8//MsPSmv޽hmm>0Ph4ar9q:]xrss)(ȧS'ph1#3>R&*2M,^k+Vf?ΐIݿt_l۶3scڈFߋ #*eݺTzz[Eqqޠs\M^x~ADZ4X`.,h2JefY #LHt8,,lC5r=kn?jYOzʅUFk[+9x<,BQZzO)]SM{bCe)5" &}a/V_b}C\<$p;lܱg6uro;.fHMCQLd<W:::n 1pJ4G__`8p؉.fϞɌ0M<8LDENp%D 9#jGjj: x܃OI__EQ3Vz5 UU퇴8DJzr'1cJ(%\N4vͿۇIRPI +`Zg  a:wT䒮''f&j o~pRZN,ddLtMFLċfæPS.;ޫlt1v~ėlEJDvَo~{Be`ZOƲ58a!xf('1HKZxYpR!&L෿堈/xp4J4?X[ ^{>Sv76+aqѰ,b8]]=xl{(//q͛Yr--Xt)gz&L:0"S^1ƃȒa$ƴsY }XREޟ3 l۶3seYx;UU"֎ᠣ_̜9 &O:9p?O7}zM1̥"²52PՄhkV"-m ToΊj\duKx઻EU}7g-KfTi1/dI_>'=I"K/HWW`fDDƎ4M:؆tHWzxk_y5~.V@$aeԣw:1{aA)fsYf?z==0Cr772sL #BeMs7 vƔ{ڨo܊*\} |>_?%-nat]gvaYJg ()á!v;Nh4B Ds.Ʃo` h}yA4H)כ}IW,w2aB5}HNGLH$$ . _x`"Lz,Q&jX48r}9HvI7Q@?>2 Sv Ԑҩ2$ TB$$$lvn ݎݞv԰QEEUlWz b1(yyy%[p~vtѥ11Á`$ٗGO `xcQt`:z<@  'Dp$F,/1|S9mlK7T[C2&ryԏV֬YϤIp5!yy^~xキ6.ž\h HX mA"JuVQYYĉ5jGѿsiehrI&!2o‹~~zzze1iR͐6KxmC=[a]6`ư KJ>-N^k1Ba,dD/z%.BADJF([ƛ|?a?'nܸ_|λҋxv2r~fΟ2Ye|ӷoS[+~+g?[c׮:E!//ͮJ^n.X\vIKkW^qngMz UEnM'%9ڀ2$`t5px|!߯qq僿Dw eݘI4% ejrXs2{j59^N<:q 㪫x~RCpVrO49xKXx<2Q:ّ%Gֲd푝;wQ]=E=u~VD~5PEXV2c+ѴCCtWL_M"maL4wr(Q{_]ͼ#!a2Wd5^)ba``ڎxɤj{5rYr`;Nޚ)Qݞ+>2)e|Z[j{jщ㨪J{{{t³ lYXX,N, zb bqXLЍAK;v(|uq=suIUy.n 3LCC3.h8Lۡ&MԩF|CW3o\b}}|-:@aaސ3OַW˼D!,זo~={jYCeˮa߹?0Ɩ-ۀ!]w{/_׹{)..o5j!Vx&<>E(ɇ˿UL5,L`:HO`@Hg#[;O[|)/--L3逶%71i#1ztvJNo n~?aftB$A}~F.Cl8##Adq dJ+JLea']QA$\.wDظq~|5/ :^3|c\7-ɇ/,'%M$%$9Zuoa 6[l6YUL%[9̜pQS]p-{spD;rRct]'kﳹ_O> u9kw$Ϻiz"G9xb#n?VAܲ3 P+GaSGnR$eӦm\ve}:r\ _4?pةknBƶ8_3Amɷ}<[n/dl)w/[x$ _ϵ^)p%( ?{H~eVƗw_͋dI%+H, IhO+&$olng%|U䍞DG6~z͍q t{N)HRZ05eU≟qӗ8,g-f3c,l{.?h7Gnf5̛7 ]L2O$?!z_vrz]5xZr8rLTLL+=s::zdYk`aXP&K~Lڝ0Ȱqޱ%KmI8RjtCY常rBf,E+%ړ ՅvZ,BM,j\Rl*i}VMyTU>ivuvR\RBkk+i-ǪDgnx̠)D|hiisС"4 &_:IUt$pM%IRŗӧPU9AɃ4-LS4 $`զ3_f;#H98~Εm?|u\qϛiX^B7M,#`4M I$3kFDٸj6n=]nP`ݺ-TUei:D,6;ٶm.Wrš|c &1w~L:n0۷K[;K /7oM:7x#K.ncF&Rxl6z!::::OGpM3ڎy~>3k:Ok\x,SD!" 5#9Hn0'q _sR9r.l3vWđ|t7s], mQiGmHko;$bn);2O/%Ţ;(Nn$ˁ Kee%+W$ %L5:x uuEuYaZ:a9p͞ݻ8B%d.3GyF/^>$I󩭭%u]fMtQ6*h@6,p㒅,+Hc8h1o`F毮FRDݝ+?2'7^c mn'Z%9",!Kr\HGEWe#k (珵zi)Wg$⭫OOO"0h䝛S'K?#(7n\'89t?ٴ=.aI;w^6n܂$IhM75\^ x<< x9Ύv^k? c*Ec@5Խs<܎YHJR|q+௘->f{o1W}Q>qZ63 b^TO}Z)kض1sR'yljY8Se$1e$>q;Nx_ٳg?M$??.,X ϵ 444G8pvɺ&EN"5f6h|F,>)6<.'[Gf+X{0NWX!dЎ>: {۹)ڎ?GO_0AR\S%wH,'zAQdL"MD1L2܃2k,xY&O祰\߰N< ݍߟu=#>Y*\(I"V>,Fia ߏiNd`0H~~ΰw`ZpTB @InґL,$bEGH}e4JNpl;؄.(Hyo݂\rI(&zf%0,eQTTLIq vƋ/$I`  ή{ON|$heŌ3z/ز)X\74aٔ)" O`O`N%PդآX]N9HIӔ˰0үԐ憮E2=ޑuiq)1:s*(#u* LuOvZ :ca0թ.]'{nZٱH43@Q-TL$9) HL[e&\ɨ‹i&˚Cy<}|xgh@mݝ6z:|#2f"cV| ԗ]K/]'D*>~߾jHŗ7|=n/3˖ }.;#jpק>c>JcSe҈ǣ]Sg,ZS N=E\7/74mh4W'@:m;kԿpnFQHjr$A(-%u>9UnWbˠ/ikWSLaswMH꛻)_SwFGGO=;øcL4a4 2o,^/UUuD"} vFn (*===xdDԣD3ZhodTAؕb_4C8˲̨QE8B tenQ0uQTNTz*HNYVhGXEa&oө_j_bdbEjũnLqe30Q{oXeאm6&NG<456KzԩlOښx<3a<Gs8^3~ČXf$I%e\w5.L ד%*iMAI~12QF5-,S4lan'  Ֆ2b@9r+d݆jN/k3ݏ'E'cu&PS` KƱٓ*XeR!IGfBKHYĴGWAj/|;_ɕr: IDATW^i{ALԞz$7ɓ'sw_f˖-|;!HP\\̼ypĢ@#^TAA2u,YBP\. 3e06(3t{tU@>'}<#dl7dv{WyyO'Y f8TT~[owx\?sVn )B % z HL @!7!:0+U^-$[d[|Gwϝwf;OyXnuk)Æ@׏rjj۷SSR2} T1gGn*%(?":(]5t_\-K4ǝ UM)RW9%ۋmv鶖e%GSSO> qHtqCVV>]ױ,@ *D"N4cpp@PB#Y|RBҐcXVdp }m#8WB9VQ}QV0Duu!Lb?Â`FM&eSp)pT!\<#wk[FI%_TD~16Q,GLfgp`(ƣ\2A1P]S;mjB\9!6c}SǒO&vb3!Io9|wel8456PȪu[i\h3g*Y}P!M~2*@aj=Fq9,P):CǝDs]`Z.ʶFeq_>ضd%w#]m?˲_[:Æ {g}'| 3G{1dY6wy_-RJt]/fΜ9NqDۄ,G Wa#匢3<{4S޳RW㗿%'pB~ȏ~#<3<=kx[#,](H]i>4 K@(騾9s {h"s}"ӐH7h;Y~둶\h +V啗_7ߠq'z*曮쟞s>+ ~_"AQ3N? 2~&O>kYpM>I^36BRJΘuǵ|+Xi p6lAQ(% . % cfZኢ7LAERJ'$TAA?;<(fr8iii)%ot$| #90Յ:t;@;MhHTzj+f8ıS`1~z<;ö"5ͭļ1\M(s*cPF4rssR@4%??k/]"ܵ±dIڑ(Iq$ԐBFV*;11Z9'3HE >?EEXR4mJ7odБJ#ӝK [Wf`B08>P8lHH)(y!==榦Q{ @Ȉ\[Nzj&233x< i9_w>o# 6N[`dY HgDUI_#$J)`;bض$%J#m뀚EofW-m+nE8'3!T*-D_X" : '?ʓD1B0@UUu1(XT{7֪75lo'Kd||,aM/cs@<;b3cEVVGlQ%޸q3\peez 2GNvE]+ѣGӟxz#JxG(,,@Jɋ/M7W>z+ѷ7i_|'|z۲ln,\ izSJF;Rڈ RP<)ԁ8hԨC+6m\pK.%???qd̙|W"wKrk>wqim9|}BRJ<:x]aw1>r6av$tk;p[c*%KVPUUϝwP^VƨCǑ'/kSt/E-[qǝ@&gN3J0j'pcKmq[4}M՛EA<o;* .E&2}D i]hYX ex0 c'ŶmLy67Ճ镾V)#T|BG*B8;]yF Kih.a!L#@s] 17bGBH3m^Oa+{sSTFӆU.**"FwJH,F܄b*.΃,Xw/;8rܴᘍ/-/N b}R ~AJl[@uQ BCJ8zI!az4,i '*V gq4[%SW@m3bb~=qCMM yyy/NK168Ա O$A4{OD&“r'vUhVpx_ (ABHdSڎBNS)dܘB6i ˵T]gS-سyW<&{r+_|NzŖjM123p{<ݠi*S(K\3lL4,qh,N04x<(jb}#geo~cOdsY30M!"(# ߹٥Ǚb܊!<$gx L$33[n#<M:ȼ7 #8G`gsm*L4)S^S]]ӱ۷SVV;o644~z}]x'ذa\piii;/#.ov>Ӻx3uz 5H+1Y T3mwj˯jHJGNPg&-1V1",9j-zi A4M؊[%RhCń"M!D~mk֪=avwO^='Rdqm##lђ.![X}ѫO1HDQF(B"5i9;`Ik͹waOHVo ȱ%id6,% v~w5*L ]--Eh>)~)R B2!$H4Q}m|2- vqgg%\,ITTtQh*,bo+' ΝMOVFɔ?r2U%'7F be)ﲱq#40 &PWWrz~}pfd=J\FIH'#Ci.&^64UEUT x&nA0n"0pH@s{ғނͅ7׺۩F=Uҳ,hCݙ{2JJpyoI-Y* Ì+E]ŢݖϝJcCYޚTʰTJIv ;&M*Ka9¶Ha1!$(otZlYH )f] HQX͋e[zDը54MG]n!5 Eq*Գ] EBDylQNE ذu CGE 0-CJhס@Gc+hWInQ$[PzEQOqqN !"Ple BiEzl6hFsss4ٞ0E9nJ2K4SUWKS k󓖖FFz&t~˅ %0U ! L0MA,'ƈMrߚWIdK{ QniEGd$gwx`v˞7}Kg9}ٙ/ztbrͽWvmlTa9s;cz\QDqlZK,BU$aPj~>n779Q݈͊XUL'77'F0C5 yRS5_>i6 hG֯sE? '337x/##O?}s歉5I~k?EQ8׫@E`o%\cxywׯc騪SFqriW|uQK`,*9/x!2e"^{nsڵk1b?~<<>N5jcƌAu';YkN:~oiiil3l^.U46A*ݒ47d$}Mm%TgօyyyS*3Zg **p2xgkNi}SLS]H}}oLBIqR$%AL!0%R=.^ׯ_/7p,^YcAS0"wHK ++ !SwA#VPF)% U]pkMQ %$9@j(UE%2byww+OwItzvvںzs]ʞ7 `G4T5B[Ų9**&ʌ`DžL5gM7&_mgp,|L *!iy%d`p=߽c 33P E1\W\|@Zǟ`;jXl9>0~o۶̛w'G/~RKy1cFd%Ț `(GK*|y睄a~d="Q||mN:YfqW<[Yf|+뮻?~|;ŋ /^svK-5Ư IU2/xuW⮍Pr'7C%je@⽎`)w^r;i\"q%e환kV^^I8lif>?x}W0d8ƍc%l}s GeDrm~;5ݧc!8qJK&l7>Jr>!=*{向+VlH펫%hDXţ|7QKTzLLK3 @3&)Mg ˲(--SMqN$}+| D:4c%$tpH[|uُ"5:l;jsk*>YL"PK攋e'hE~zR;IfG% 0 :8h'eGÇAUTli+**b$ ÿs9PԫXBBA 1+ʆMK# HLwO11x Z<+9d@[ZܿzFLw#zmemrk|X-M6PJ,o6haѹi`w~ȑ;}2un`&2 }#ZvUcv?&m4-;hi躖RtFvX׶m%cD[]D"RAܧma6, esL/陙F$/=S|ͷ70dȠ:GQ R@)`9FȪ pb/'|5\͛8唓J6<==> J qƱ|6`KiiiLUU^|vϝ~i H)?>=>^xI&1{Sq}Ԅ%G ^Y=?~:^%IhAGv9nnr!-cJq5G ~!OQSagbN@ [xv7>˷O/ӟN(p?M(od Y~-(%U|0`.d \̠B 0A|iJJQWWKnnib&KO䖇ޠX4B0Dmu!>:Rj;@31 )qFxgǼP-@ULqTCUM4C8GUhA4ƓI;GBVDA_C<,^{ Vo4@$1P{PIJIdDPP2}tH),ׯCcfjm/_Θ1cڀ BTw}G<gڵ|BLu-sΥ_nP(vIoPW_{??Č 5`)hE+*)؉72xL9ESҵmGReOS!xvݟpQKC7VƘ;Qţvo7(ٶLSB(44ԓȳ xs*/ATRb'#ilټ{}zj:Bw4C+m&8>p`п``֖mALW˲ ReXAyySξ~%QɂQyUgPSi-SE?o,3o]1 r210  w5ٺNIȥ1 f3u1bEב^_m<&uټa 3DJ# x揗2O~*pnnnNXϣ9Pt!lRN .ZI*!#i43v2aaDGҷLMuȅ,Kr۶i3NݟT;&B6ollOXESSQWWGuuu*u0 t]D(u='i}\u*++ݻ7}%z:m0{ٰ~#o\n%I$m0ŚKvtzA @HM"QL'9X 3s#C&i{vTeŮB0 ӷph Gd\{_[p 딗1bDRF233S Mak؆ v*C:{^h&ϗIẍ́FJTQzu la:.N7.6U«;֎b*W 3gy3`2-=8!^ؾrzl޼ ͶrLcƌIgeeSi7 ykQ]o~w2n$x ?9YS9lʆv$|]0#sLfw/eeq|>vqx^^/wO^_MjF,}'9u$mBaazM]]UU5XG+D`!zAJdm(B:)IXґ x4GWIΝW_-ÏH&vw}7@ HyE,K$u\XcY|SI"&Q@`I!}p%ZA LN^.LnEa\<~Ѡ/YuE+Iy}cddd_JKhllrCaa!|'̚u~[Nݟ9yzmfaGP`O]'2-"TA;hm_P뚓),l)|SDhYz!}6~~j|j7t32o"  Ľ2p9DNr]7=>f_}?x`լi;9ǮC0oəoyM%eA Ҳڂ5;DNlBiGZJJJN?B8+fAT$8Y DvRzI4%''͛(^0r)BMI]ZVzUva9N9UI^.jPK -4q;o.]uw~Uץ')r#vqN(Bu|>h!~0,+Ud~p8mx<4M`6S^^u*ҳ=4lZS$SR [d8'r03EF z=fGmm-MMMQ9񑓓C~~~ xIIcc3g SZZqqwo>ZC;!XbA #IV\{$/~q)^?^'OZyun! _ ԑyxJf֍ .+d=;.e˖1~aÆ~biin/^bV\رcSΎ gͥ^ 8:oZ@a/.v^cw?3dC$F9ۋmh"ޫwrTWWSXXnJg6}t,X_lԩSUw%'5/_Hl<i%U toV?:"`mܽr!-jML85k$ hjl /"++Mqi'w|Q^9_`q6RxG~};H} F@llx["fk;xTr`=plyg>> N\;!hjjBU^_ՕOO&SwLƧQp8^BŖEZXmz{@Zb"#E BE#hdKdzu&Cmt%-B97hKG .ȮHM+x YݚcY`8dGxכ7t]O,IzMf$ߗ$۷o n6UH>:ĥ(mq#o"nli0v?h'\.3㏿L0TTʕ2dzRJ***ذa=PQQMq0rssmO?9sgA`Ff&5U~2Nxm-Y0IJdNHFEh)Hb)ԅT3-5oYY ڀ^btMe n OϤȭ[q&JE!---Uja>SYYIS,!۶m8u?m;bYYYY./3]7 3bpZ#!/ .G [XH,"i,~q8rQQ@&ॳEFJ-(lPQ#ٶmsޣ}e"q׫ȹ ;5lb6roMS5`Z }Bor0ݿXU`2x3mD#((cd<"5{g]b.! (~ ^[?'ZxF&O={ ɥi{ܿ;0w}7msǢE;0i$[f͚ի[9s&>P˪Uڨ|Jy  `Gc{ʥ|KLΈiSN1nu\TL%O\t9K/x*C eڴi̟g}n?pꕏ#Wc!G&T!v)x|w_zNǣI23=Jߦ2`eKWD?/䪱Azz/ǐ49f:o!{S9∖{3<{m{N;C) S]]MYVN9x\}B 2#!mP/tdBjZT<.- "XT?ˏ兩8 ߇ԥL/4Gڝ{Ԛ!TŦV]M_d^Ρ*N\Zj'իb|i씤%9?* >C1 X,FvvvRRɿu]G]"-NsG}Ɛa[I$P(V$IFAЊE C'`XD ھM*|>JKKw93=6q$z~eK(v$>nA;hm_O_. W ¿#ی˓ϗI0ĭ C40\IvavE3K=zTGmR!͕ƈ<5a<.nfΧ 8V1TmEݶz 5TUAT9ru={@Jg ~{ߑG` DCme~ӧO#f:z=rȨNKOG꺎|G(ץ\;0wy'999[m۶w̕;k%KPƜ9s?I~8C~ }38Z tn9(NM{wខCc4yTP]]OZZsLcƌ$++Wk\G^E jl">zmUHn`Veq&LjbB~|<=Iy<N=qL "JJ1yм_ܼ^T-"Ϸ[qq-E,TOy&2 BC}UD%0)zixO5kGuTT~ !w޸n"x< x#[SBkjjۥ{H}?l!ϼPAZ`% Ĉ"n?gGFzoL xiΪ ͢E3gά=!ڟcX IDAT.շS/?Cv˷e'L?۶aGuPbVìێ^RG"tu UW/TێBLx0:zɬKjl#=%^ܰ -ϵ`us=WAHλrO+A43{)k)U.hor/~+goX8 DDv7 a9GK 7~m=/s/"qL$"?d2y%%{ zLQ-?,w-&bg>nύ^(OI7? In{]Hi2ŝ S ?m۶W7(ض8wn$wWjʓ-*uNLBoV੧½ދ2ƪU3%:saΚA}޲̭*OiSmB,%@iC[wVMUYk$ OС6lr+μ6_|у_ϱ:w=XTDi X׻3j $6^6p!V(åx <X{Zus><5{nE|qiTUUNLL˗WÍ*ެbONN"D"@k6upf7GkQ }c W V}Ro|xi TD/_r˗ GjԮ(zV_s=Ν![ q͒rT6ԣeG\b7 |>\wBtvqꪅ_Wx!"\=k0؄.40dƀӉ/#4 -+}PVV׋*^ "]Լ/n93?A011X,X,~7_֬QTUU`ZN;{sWZftn ===yÊ?}R}h *`A%/|6E00掅1w.*KXfњL9z\&09{SI\ĵĕSӗ›nI*kZDG/K.W_~\p]w-֮]yCetr=jƥI\xIӣUZZ%zUgy7MOC,3U&=8.%E\UR^;K0>Lf!SYT&Z ̙\n/}=#kFڅ?ӓ^?-͹ty06;HޭzSZ7KM͍Y*+We"_ȶk.絜n/0R[9;6|K VvyM͍=jɵ""\[[8uKq:)uSJ[-=;IztWJo4ezzW[[ݤX}JW)M+O-=eŘ?i_6qIZlٺt>g`P;w'Z/uۑھHoMre(/:r?J3חbKOV-=##""w|4k5&j+69J-%@4rh=G>jIDDڂ()==|DŽHjI?s J\~oB==QwˮgGr}&s˗kJO-m#S\e7=+|s, 9zρ|Oo_f]#?NߍZS+ M]\o%_rsGk:r3\ì':ye?zB1zu3;s,NmGX~---/mmm"""""*Zl{mX9=/œ'ݳ0rE[[LKK {yc2B(R{{60gczLz0BDDDDDn*czL=_ tDDDDDTXezLUϗ-xΟ?mQa0+K(TmPl& L1NO;]w!_,DDDDDmefy0uׂ 1HNlx nd4,ok %}죲'A $!Id $Kef| Ct3'AT㓈bаUmڊUo;1or7ܺ6SO/#MmHޟo{ [> >mJz:⚆QOyGcfl]tK;~kR~ETmڊ93駦ILb<6yьm\ JܼCذ&|S5N$I$ $I㓈pB| ;q=_B*"} QNE@ -&nRbvW2yŎ7Fe$of\zZaez1gx~;"19Bxb'IE#?d#a׮e^H cX>\dٲuYSj٩S]3:ե)t|z~;>fVMuߪSbER:jh`V\QnaDa!~P? ltH# l$NGхaeH]]G?;+v$|̚jk "jkbfcϭOp2ojvC:vZh~IߎT#ef싑|f^Vv%=eFDDW$U]BѹȀ},$;Ǡq.:h˕?+v$ݡ:YcX_nA-VnیBΣ[}drtsrmWm!+ٞADD4;T.,$Ԩ.p[GQ^/Օ9je:rJYPWJ;?8Nl[KCȪj;77܉f7Ꚗ2prL'9u[K0fc= /{OSSjKXH6Z؄ 2g!|<ʫϏ5~,[Pkfj1_Vl4=bVA˺tZ*ZWv=9YI#W]ߎ_eA0|>>nN2__3S\?xy(>?ܴömjFjێoǪUǏCEezw]#hICkwk_-OZykЬ -mQ'#eDӺ3|kdp|mk]Oa}- ; ߏP^mT':`5~jhd! ?#a u(-)q{.tv~TWW~JJJH$?f8҂/ǎ1رÊS[FDDDDD/χnjlwږX۲ fj E\FB "߬쉈HY#""b>""""wc|!""""""" UϗQ_,ϚCDDDDDDDӎBzߊiGv;BDDDDD3"l|eHf%;^q-Yв-zɤA IdR@2dD"z%lٲʺ7>D,8MOj}E+ܼ}(߰Y94e!y-,ni]8kn=MnX9%z?ud5)yh"6mJONS$&c1\üh6uIsKn^k!lp9)'$$Iqbq\pxzÝ瞯X~!E>cuTH]Q|x<9mH$ʚCDDDDDDDiG<Ȏ7Feg2ivlON*fִ<.ɉ|:TVzRiz떲3R^DDDDDIQ=__c3I֑.~MkǓcnΧju)};rۓӚQi)/""""٢h|QjkEl f|yniZ( Crkd͵f0ATT,ECC=^ksx,#bqE%V7b/HhllĜ9ev?\3g"\yTgF]}fc_fgv7ּiݞjK#Jwi<ٖ絖mu#WK]0X9/RZu_reh4JrmZWՎU"""*|=عs*lv]T~]%UPi/>8"򫮮" ؖwg<JEks5H0!8כ紮7~\y[.fuhuEK]X=/hF]ɧḪ7z]Q񘘈Ǟ @$SOF"p4=bw h?$EVԿGٙxܹ ||]ɲe&u-[9t{w=-y3{rr =Qa-abd -=ZHVG:9F!HDDD`ppHv@]v';;02$g#`%SF4*_~+Y#IOOgT[[QNO5vmP{~^Ӽz}Q1D9GMFlt,20o[^fӎ;T{%tww̘twB*%Ym|+bF:Cn7\sPSScyݒJKdyԗ@c`2unA-okFcrR{T%4zkoHx/n){b澚]̨DDDTBjj~[neC@:V2MMM/ ޾c\٨tʕ8q"lmGjEH3`:\:󌔋|WcԻ*4'/j꭛Z iߌ缐 f52TW IDATZfw,"""*Lee>lЌI Ƕm:y}>zF,kUvx~͌Z_ێoǪUǏCRlWFԒ]nf~,=ZGoV+j7yaeҳ'砑2[njLQ x晧A__?jjQW%~/- ;`x5X^oi)+˖ACC=|>p=S_;ߊiGv;BDDDDD3"l|e@w`[)ey[[--!RI @ɤd2DҥKزeuoA}<>X,q ^զ(OjB:ou7lVN/#MmHޟo{ [>jZz:⚆ei}7~0m.cIyO3B2~MJ/M[ғ#499X 0o4qMksAܒz6ܤzNJ D"d2D"x|xX.\(/p'x<_HEQijw/"""""""RWT=_<-vD9DDDDDDDə3 f賡P)y(GM{<w[v-sv-)]'הYe<.NCNZ>r\eYUzUc8)ăg賻v}ߔv6ΝUUUa۶O"z.؆@LC}yL_uu5o``V_Jޑt3%>2 & zP5= o=+/zŌc {h +\Ԍb4?N2@]y0նkkob"{"+PHO=D.g}"+g|HZQydgVs.LN_~ "<E˖KOf_n_1;e?ZfE̗?Aּsn[un8n8f[ϱȵ L"".>!eQttt9۝ȐDpLE{{Ѩ| DQ5|𥶶==驶Β/fSfPk*JѼ8]O_3?T$ͱof4.''O1_Méɻq=̯Ypތs PSScݺv+B(ߥjձhjj/_~`߬z˄Z=L* +ʥ9HɧZpEo9J=MNz򢶮޺弐6ͨ+Jוɕ233aF]T+gq"""}C3&۶=hznp’xmV۱a53/۷?H}U?ގUBYˏo(nWFԒ]nf~,w=ZGoV+j7yaUʧߎco1$"""<55ը[CfvK|{#Gyu 7[ZʥeAG?@8|}kPИceayر3;vXsjˈHϋ&475鹝fnj8PeQ_֯o͎=Hg9moՌ<܁pod," DDDDTDW_EϗQ_< g!"""""""] ~P= 2 cYsH֫35^[[kvz7~cjzí|[w㠩=i=+cE%ׅNv'Qh{_Ė-D,8MOj}E'5[|f2Ҕ݆壦w iYj H=kXRީSLL_&.j֩H?5MNNb21foS\P:浶† 7y H"L H"D<G,Dž eYcÝ瞯c%Q?]wK)/ǖgG"Q"""""""҅6-zeg2iѲu2{MUZ9ľ#T*+eZ_^ɲtu ~]~j1/twݨl$( F},};rS  h'^lRc(5J53k^z~yrscXdYȕKTlƲ """91aDXzx^פvX ݝG02JocY_"(*++؈9sfe˂/Z9sڜ<9s4=OsFtnnB(MH'>|N =Rֲs>y3"2'n[.jAqD9QaΝUUUa۶O"z.؆@LC}yL_uu5o`ּ9Z_N~WQk j3LkD- W%u4δh{nKnL-e[ VթzeFASZAFlf*c=."""*N1<(D"xؽI:c1O`d({F#'񭧞Fi1=ND700;wggOBx_lk_拢ںSt7>%ofo_fv>}2붨\j 9nVF늙熞:&Л!W32&""!>2#P2 MMv';;f^H';;MA{{xF%pnɞ W㮻NuNUI:jkәjkr~.s EǓ E% BصTVryxk'/NSyM.Xd""""2C$ͱ|7 Ĥ'ֵ#ԭ5Zꃕ&'-P(j֭u4=[By.PLESS~ fm/f526֗ݡ'srѓO޲3r RvZΆ}>Hr^HfԕtJӐV\~}ocVNDDD4}C3&۶={Ss;χTUExmߎﯙxپ![z>X*vƲ|Z0#]+Ŏkyz}V;ZGoV+j7yaUݲ|1-[-y5uf`0gyuuPZZbwRߠQ^] SlY?Aoo44Z_˱cg?v찡>>--Mhn{ buS3V75CnIJb/7cfDlkk3iiis4zd1XBȣYbbSt\CTfY3 j̗Q_,ϚCDDDDDDD͘/P={\(T{_d """"""Y?`rc05;15Vsw-SӻqƏִ@Ɏ1ϢzO\㎭k,tj/P6x뭷oW|+_WY{ & b<~AGXlj8>p$=]|N?+Ɔ>?`H|AqϞ/].Eŋ#…4:/tܹ3=/ΝϞ=OeMCC=b$rR?.O;ŮCb8xo.hzRڗTSL'bwwmIzb)|ҌŬiϞ.LOb[tvNjIOFFCΥ={^;'<{vzdNCC⁡!55 ŷg Ѩ?ɚ1?cz/kڳ>gΈNwZwۓ'WOs=*%gGR{b[omxCK#|..m;ϋFFăgϊ֡!tS{G{%[yy~e!9ynBVJS(gμ+vwwGyA|wDQŞNC/늗wl?鏋y|I̙S&_#:s瞯c%Q?m}?M􉈈(ǟl| 9N{ƍdSJC0ZZB'A $!Id $Ke+?D$b144lzzUf(>YnQ}(߰Y94e!y-,ni]8kn=MnX9%z?ud5)yh"6mJONS$&c1\üh6uIsKn^k!lp9)'$$Iqbq\pvg^=_{__jboo3iGg@[8 D""""""rӎ Qӏ?lxնw[v-svoWifjM"ȇh3ZHZV[Wo2v^E#@˔߿wLvtY|ϥ!iWW7hM1o7yʾ۝O)3bwZː=7c,"J;u GυBhjj4%_55}/߿ח[&ORa6ڴik˘fԘ/4mb"p8htKP.FX\Q|X:K$Eee1gNyho?p>x}`Y%\+,5?̙+KAOxfc_"FӚ7SY`ipDio> E=Rֲsnj f+=Ej]=_ӻ1'8a9wM fu%[wwv܅ht0= ۶݇@xzn9Ճ}oFwIe6T`ˣ>Hd}H/ >.-[95]@ZCGѢQaCK H>ii͋r'(g[r p-e[ VթzeFޜ(iFK^,W~ {LǞ`vyD"5/WZzXш/[Bo޵= ̕sȹaq)k ۱˴H$cyDWndP}F|ɣ "R^^So۱ې;ӴiGb'7T9ݢaؕ3myb99m}ekpB{LʱnIe~V@i̗\+ ;ɋںFooɵjF]Q[>zKfHr7'w3ːeZY۷?{Ym s;χ~8 ExmߎG>.BJ܈ޣlk/Γ3 M]]AWQ|ý >xcRRˤKxWpm_#3ڭ8̲q`}aމ+5˖-+ ^q-Yв-JDQD2)@B L&19@"H^t [l̻IG׏jխCiiɌub144lzzUf(B[ Ce) moaqGK$8~W`y}Ouw iYPZ=k!tg~ kR~ETm:4駦ILb<6yьm\<&'~ u6lIDdD$8b8.\7|>xFF뺞__jloo/v~X6{;vxƲ<- Y=_fhiiBss(`5鹝fnj P~}3֯o1ݜ|ڑc=^NoW˱@DJcTBX.s@Wb}aމ܉=H /BDDDDD&`;8ɴ(-,`*|+_W|?͞/D$;pӶLBXp!k3z]O;mDDDDDD3"5-ɣnμence?d2Lsȉ}ϧ(2-nvٛQ/{n8DDDDDv0zX|W،y2-s7Z2ynidki9VןBw)[r$""""*vE| ̘Ao{Y276X-\(5i̾˅h6!#DER44&=b<(WTbe}#|>+DQYYF̙SH^RZuOYm˂/Z9sڜ<9s(_h0dW<3 prP%3JyӺ=n%IOz7Fm)}^k9V7f3"2}h73iNvHDDD݃;w!Lϫ¶m!;ENgۅ]RY=  +裏#.jl qjnTV<Nc/wg<J}IzRF4>u=iMG>H[ʋr1AȭG;BJy!E3J埪3cuCm6QᙘǞ @$SOF"p4=bw h?$EVԿGٙxܹ _2LOdzZn-J_Ԃ'(bٲuIeNui (ݾ>]OK~jz?cf_h*uz}mK4sg] &W9 43<(W=.27Z .dgFl$d*ÈF˯'ɬ(eP:tںuԖ-?̅HQYc U[yq*mߎs{o C$ͱogC=jy7]3vړΧҘ/ԓ5bU2|mA_3"""*lP55 _?֭[hzn!j]v]+& P_oIt5U+MpWO2ֻG JJG rd3R.z\[vFҘ/a'=yQ[Wor^Hfu.3ڠ_ru#@\}|ؾ@mu4=|[aIUPs;׋MX qʊ_ߌ{N(T]|K>D(T#3w*fFMDDDDDDjjj0L#GSS)k,~;ObΜ27u8_pKhQF(Ԁ/~N͟O#ޖ_ϗԆ """""""*:z/r_3Lu|!"*rG~88\6|!""fM=jk888ehviGDDTR?O<<<#"$}/DDDDDDDD&_x|!"""""""/DDDDDDDDbB Y"""""""" 1BDDDDDDDd!o A89k ,GSS#˄er%""""""+j8{̚L-͛o器þ}o+K^T̚/ņl,|j[QVV3Q;,^z_ ׌DDQdIL c/ah 3/ /[zTW?0p"\o=|.#1L݌r)툈mW\4ܲ#MCIM͍XykִS^ZFV7,+qejI6nbzڙiZ>o;"P7~*뽓қl`[u;&߿:w:jiN}6s>0C:/WVt]hje(Wê{ۑ])iݎv+"""""Kfz{dd942M^:MQuovd楷=kHnPZʲa'&5l˕֕nGnyHvJn?WDDDDDDTl 9sT3JAqQMiI2Ѳ}w֕n/|Oɾ-uqT/>s'"""""1_EY_0vF }ѬecxHϓ^[6ؖںГiQrŘ/>tpt`ٲu==_;sY0V6F{7oV\.]Wm[jNcmCk~RXcY-ҚN}nXz^m+}""""""*lv4۰LsQ[˥ն'#1>>_,2N/Z57ߊÇߴe[DDDDDDDJ,*V[ٍ=_,2(oQ Xeo""""""bW%/̚/P=ĤڷMqgy&K+K^t#{21^z&+K޷555!25e%"pU>|%`}رKH&9㣦t$y<^}Œ%X0DDDDDD=_tZZ:x\`"_t7ϋ~t  oCDDDDDD|!ҩjK;~7I bH_=>񉥈AWEKDDDDDD|!2`Ѣ9gv5y_` 9qJDDDDDD/DoFMãػ7,"""""YkF"˗zz:IܺAZsZGEzb߭ރ_:iS9^<]2_vzܹ[˗ϸ+}qhѲڗ|Qqکw!={"DDDTH;Eվ27zWKozMГϥmW;jpؿ;;Dq~N;9۬|֘ʵ~>.2wn)>q\/!| GOSֲonjDDMQ7E鿲ҋBfZd.nG^ѣwoUUhzΞ4DDDD̊?''y%hl[V^{mG"X8k+w=`[iڏzC>蚑"ʇO}\+D04wpdzo;""rDDΕ=_~띟S'x<^}^[7,r%DDY(7| ޚDV36܀rr??v5%%9rU[nDD>DDΰ҅_nj_ q6Hhv)/o²eW…8 9>Kkt=^gon""Ҟ/Z~pFT[E>|zP_lO~ҍv"|JX@T0?sJC^ 6񛛈'U _FSa*n14!^y%h2 l\?ε\x-$"rsF|1ǶϨ5q2ʗA0| N|ׇ/ł^ܪk$DD]k?>ρs曯ǦM/رKCDDDDDTd|!rWcqo` /D)-`kuk%| crR`ᐫyrMcA zOUd ;H_x,W7IQ`aee%x?>%"""""* sTapس'9.Q1`JK=XZv໇ DDDDDD"XЋ-[*a 8~u8D2_\fn_?#xA%X8DDDDDD"JҲRLL$wow${*8pO[$}9ul^Z]4v(z=lklS2mJX c@a _3c/2ؙm{,8@$FWe lRU]}Q/KwuU^}ȌȬDfFfef}?F3#"O8牿N5 8'rmI>)in='x n/9|ة\o|=:ztNqP|^1 n0ظݨK#`ٳ83M>}R4R۵K_ŋe?CӡCS2 *>_ /|6q ۍ¬*t9=0l׳~M|@WJHO;ZYYӇާ/~h)z_ @VV.sa}XeŌ1rq]{F@Or@׾}o'/!seM@.ޟr-]Y|cymlh?ɵ~wΞ}[ja6wqGj7m/WQ{}ЃuiKn3`̐Qcѣީ //A} '45@ noCbxf V`F*2Ȳ)tt1g%_K'NAgm6b7X%_9K^/˒۷Z,;YnǠǡ~řw.{^z-}WKڳgq{qݓr *n}XnY'dvM&m5'g>s\/u}~M@&v_Ӎŋ?-Onm:v쑦e+'+LMT?w_o=W'0s0^.ҸladOرGl,+^|}91`"b6g/Ǐ?_{ _+-A潟s4WLRf1nR6^>7qdGOmY|xJ++/7]v堎@`R:`cN X'_~O'xtБ'nٓ=ňed/KK/m)ղxuj]qE;)nӖoA/z$_o f⇀? 1_促 `'_ޓO~Fr1삿Yr"9ڣ1Yly; J'm(jf*4ʨm/d΍ۙ%_Ξ=1#gzq?۵+Y$݊3ȶf0W(}{<6G `7}n$_Сu:x]FmcW^Ə@^*iwm v˴[뱵*B:}6~Mhq>;1m97o߯l$m}nX|N^1@,{1@߭/<{&)nl08|9r.]zMG-;|!]Z6ҴC$}>I[Fv{F`Rb6}ng,/G>W:rVW_c/KnXx]VW_m6'7q}2y6 }nvxY/^i}uύqACFC3`b6>7IIұc-?v]p.E…sue%f|t01Mpȗ_ٲGSg'[X8Y~+l$:mM>7!Gru++/$׵{ٺfXa??qqgm8,+&3v؎: +~OrQK `|ȗN嵚}q񔖗nnyOՖ//lnfNmN3w*ձzv7|mn`mwjvIv4u^ַ:V,q_}7nM=M{z'9 IDAT7磗&~N'!vi.h}n{Gxz̰ni|ڎn7!~8q/0O9muFaK=G^6ɨo]>70>}<0<$_cnuQR:]]n7kqwێ}4ruݢUfimmwKQۤlcVカSU7OۦݶCc=g?euj,t ` &vk|~kj*??Ç*̙1FgϞE8}i}3م8?D I?_i 6 yn/_?B?d{#xԄN9N `4ۙ%_Ξ=rmn^>5=m1Z9h3@#8n)ӑ/9hՄkޤ7qxM0~iG>rիK:x]m0Ì'1nl $_\yС{u}7dmґ s`M4'o6"@~~f>Pou."ii:\2^޸.fmj^Zo7w/Yϱt[ڑ'nsM>7MVW_ѣkuպmؑ#'3x[[rHdiާݎ!OO IDQ`'ldk/֧]]?Bںu;4m89јw]ym\hƤHv$|=2XV_c7[֩)SҞө>SW7Nɗq@>7}n$_Rc*>~bmxiuAgڭk&Qk=ժ>f_Y٪V۷K9ꓶw18$_F1n; K_~6ͤL;a~:%u_R'9fmn1(fm'oiA/G92 qFC>7qo;Z\Olu\i|/3~OJQJ N[=qei!iivY7uuj^L&Yvmne/Ӵe`R:l'$_o f ?@b6m D@b6`2M\~]kkhՄYXysF nOfɗӧO̙Ӣ-!o~[4q'n' '?G#qFb `̒/gϞOYP^>5=m1R&c;5kVm~稔1JOIz??x6G `8ZƤE#b=vOXXN6+q_iٮ;yn]^29Y'` Kfe:\yC>+Whq f<.y6fi.;%-M [훵SrӶsseiǖͻܮ=q&1B>7|I׬\:H0hulF/RvI^1m=t.sIn=ch찿YQ6lOB k/G$]Zm#'Z_7~Y9%9T2yq< omula'%:]Ħ=e'Kύqdðv$_&1n8lb7}n;'e9#&0ӶqVu vȃJ;%mݱ{I1Bsymmm >7|_ӖC"\rsK=;tMt4&Qo9:mY&z9vov PIڢ]>Ӕ~~z=wݖ?6'=n%_s/ '%Iǎ=RرGt¹}Ҕj~[|Ӷi^f-SK:ͱz4ǐ~o3~ |MOHlYv=eǵ~ݎ6@6/ܼ1ؾB+K6O&v0\#|Y\<T++/N|aniyhwN0>1Mɑ/iLnxzylmٺuC:8m{in &#OnHhi饶e--Զ7hC>A0`/s~`|:b69/7dCF_f-K/k;#q1 c !o f(׵vVM̘/%#;˼n˨2eoV4.oUNէӾ:ի"i3Yn\}nb7Y:shyim.)kU2"N N4+gUa}ߢ >&v?!M0O>9a%Gx\OɃf#dZmL7sWmlL@VV.n;4ng|9{~2p.R}kz)b4soF7lu H3ۏ=v0rsLGc䜣U]{FF2uΒ,{n_<mҿM0niG>WR=&GE^)okG}2%rGW6bl&n}nةQӝ?tA]|@WY:nHSF7맜nSYIi:mMmuЃ|-~H/^W00=n?)>7d"ӑ/9hՄkޤ,6q 7O;:x^]%$M4ɗ+Wި>t{]60F>2>~}õ׍i\|n]c9 K1d=؝|0Ġ1#_jqԖe}4nӸ>mS9M4X4=ӎQi_<qvڎm vo/{~t2xun@=/@Fb7`H 1n|:4iZ[E&Fq M,rI9uZEۼ4Mm6b7/ '?G# [\\dje@Cvfɗg駿,c g({gz0Zc1LGc䜣U]{F0mnb7 H>.zuz,L:60X#+WhЛ-otЃu]6-F6Ҫ nb7;~ZӸje,k|2?ϱwmnb7 ؎|9zaZ[~ Wke$_6NyȉLFOb7gd/G>eŋ?|l5~cx6ЗM\pza.\8셅=MnmGϿ:ڲ n0jjΗVAzqTf]@ nb7tklv|V_\9@fH S$vn,r9=e %x_SOF q}~S4b72csjµkoFq Mӎ|%l365ˡCʕ7~Ձ'nп%_~H/^uЃ|uX n@6:ٺK^[~ȉu.V[k|nNu]rqMll{%чj]m>_G;#{ nb7q6/#mЁ'n Uݺ^} t#..S@ nb7H#|9~Q?HHɺةx6;f++/G?VV^o|}uͶM+m9kV78tmnb7 PG,/⩺;& ,+YN}qw@&v$_$ii饶۶ZRWӮk7LJ nb7oɗQAMa t0@|yCm v`$LqQiZ[E&Fq M,rI9uZEۼ4Mmr@&v@&N=zX=L·{m v|yk ѣk1 nFvgRp K "0@$_ 4㽗L$us j *K|@*&_hi^l$@JudC4$M*kmu?ιu2}Eu׎vL]4bUrFr'Ur/2[FԏN|ʒ6-q&Y*_IVKT?_K%ݸ1FAVzlie\.|>\.WYཌs[߽c$8HW)>yYgےlInzaXE2¦g`-,L~adӿ[fNkW/kdQ^q;iS71n`d;1r:D1V2y#ySI8d%AQ)ɘJSU>NSIRm$RQq¥2!`0.Kuj 5-qYmҔ۲[wewsn/Y`e:TǶTy)7VZy[=) $IAXIZSMrOmn#krVcdMeʜ3Va* xjRW.(Uo%`bɤMH@'&!~ kㄤ 2'AnJ S>OinnN8>@bI퓵VbQөS._zKgkT*uk>O>gz'd͛7EZ_}Çu5ݸqS8ۿZ݈1y6 Lv#*XAAe'Jٮxٶ*u6ɖ -aTGz裏[;߯}i}}] t]wi?Cc~7SnC't|٧?|+{?y\szg{{w]>O롇ұ]tYRI* zk!9L#WA,9OGĤMRL4ꖤV*>,/*̺Ƒ!j+G(N뵼ٳg[[w\۫~W_ z!}{Ӎ7) IDATkaaA|^#'X?/Ru~(̅O׏~Z_P.޽{{GKKKAPIx1k5Yrg[怜Qu"`e+u;Ac|H>ŨLx77[nO~R02sNϊʑqZ^Z%FmtK?yVV7?Iy P9*훊'y}d+sT扩{pY'$ݍ=+~w`_IeޕJE岂 n3ՄʥfhThGCd$<4X5Kl>)ާ! CMfJNn7i1FOxĺj (j*@G(9R%0T PB*WyYoS]7Yn\1GTw\[=IIw47\rGc~ڠ~ەq%їmGՑ.Q9Wg_?J2۵{Hcra6&yWr&ˍhNui]w/\/f E&M]]m2MtRT[VH2@ȒJңp捛ʻHֆUa 唟 当wFRw*HQIEjɜn7jF^ F#h^K2d&LҾOsQ6i.+ExmfiN{gqL/q2%Z"#뜓 BRYF3*5=i'ݹܫ;r?ctu}f?>F>X?wA,ɪHN0ļ_㈜xY-Q#+kZ2 L/risUd2m_kke$L,FE<_:}6 $WPqmM9#R=sۯ]O߉tWn|hd#/yS=9WmG9V %4|ծO0j2MIvs-O=ʼncB( *cRiȕ83jߔdCZ'}nlڭrS^&/{}.=zσ: ?w<ZW ʍHJιʬ0eA@"H+9_IxʓvnK%N8WL^/Sy̬I*oݺZIFf(RN޿iX|^'W,W<.n-DGcۥ8eQX|* %jrN }Iұ=y_zBO>4U9|QQ*ۭ`zF%W-x|`TԴ ׻;k~Qiډ5mmE֢(2S*[2.H/s/-O1 Ӂ|Y_zU0%eFޔmY>iiߝڵd3%gG²rS^XԮ#>'>2rW,2͐\VmG G'ڍ_oޒTx*Cc )*.dKd$>YdU1EM:hSY3RԺ~7wOI UF/:A^'0i7mMom:կ^[t<ڥx=ècxvѴ߻n-GM[#4'לL˝ث?9{KLDsR`y'#/3whEfV@{@6Kή9©՟d9ef3"?j60 f6l݅ 皖Ӹ,6iM{ C/e 駭%Skev߭^uxr`2d:% úK jċwՑ0+rX+T2N6_UrӁff>RHQVIޗLӡ̔\h5[%r$5;]*T 32dl<{ʝQV2Jzw|k a\f{.yN,;YVVr%o; ]/ێ$SHRv}YyM'ܧ9g7{&M 䜂QYl$;FyCbYY rS9\(gI+mTF롣{wW/l]( B9g\xs^6Hr/e$/H\zPkũHVr!DMvmuKҸ$|@v2MSyں8OkdFӁGFssȗy}]ݚ5ٜLKɄw(Z/"i歜+˖l. 9y$=Nߖ׬ͩཬ*y+\emSĻ,y;M!t՜/ݜa3U/ɗi%\m^ X+\H S`@ 2a^KєS/9}޺0о53NK6+ |(0S |YVd* 0P\W9(g*Bdl 6嫷ySw h^nmgvz5jOۮ͒8sB%K\8r NJMMO)ZߐɚsM嵼޾v]W>?]d~~uM@륩@>r"_Vh` JL\{4"]\6Ki]:Å "i'n'iu Vg;4'Y$Z:n̰J& lR1J%ʹ|(X+'_dC'dK n;hzj>x7}REQ W~w$3#֍n˕/RuB^[p1rY_Ll$4n7moGwsqM9g}NӴcڲӶkU&{ҖC/1KoىVFX彫T ?7oFfJ2a^* @Hv*/@xKtQRYBYɕg%XPʊ^w;a"zNWH"qe\}E&N85 L/s*ջx$o18>A(P|\xH.KY#33 I"嬕LyȄ%sN9 d5)or(^z;ڷ_[}pK׵e|.N\ƘJHؙ'LFv+iA%+d6j+/0TE2>P Nz(G r%T"* ˛ y)2DVlY8㕯45b ={^I 3%U6ՄQ?IrGMirK<~x2g>һi':h$s\h^A`%c*$r^FF9?'SPnfA&>zVEڻgZs>Ξ?PRi^V7R#Lidikm)FA [}>n:8QYfzn/U.W&U`\ MdrUY^%UY挦5|\ &Rhf힟Dٿ[[ӆ/SXi|v햩ʍRb.09K#7Gh\,qSx=}{o)dʑ|U"p/ 9'9rIQT1N3yV CP{kz6CNA"I,Qd lma2(tW&B(|DN0pJӲʙ.N>#m +#T*KrHeH QPXR^Fɇ*ݵ.;uL+S*8ɔ7or2X#]u]IV2 ɳp"&zM~qfe٦Si^ڠ}4kV 91vgz ݜn`ۓ/^UP9\tnZܔr)(oCP64He'?GfTص_΄*C'l9%[[EoqQF3Vsge{|œ޺?ѽ"mR1t.g岬 ad^^L`%`&]6.KM/ a\DGc Y4-˺$UtP\)"(+G**m~cMnrƺºLƆ\!9\*k.#cK%BQn}C!mlHŢ2gK8c5jn#Ү4s.MO:w_~|I{Pyt5JŒJK:N(5A_`~>?36hl:ϣPa|QyS'G2R;/c#JΆ UԆ|0j?z4ʗIJłk43n0'dBIٟ?_ivjJ뮨܌JkeT(j i˼5$bLrҤa]2J!]"n̓˹Hr$y9$9eW`Ʉ ̺B]Gӻ׉C'Nߧv<0rlVGHVFte \7\3yׇr%'oQYNMޫ2M!|kAdP[1ǰ1tu`N0 2M׏1Ud"2*$XMr g4;=raNH~*W+{oׯ?|;uϽsm^A"ZYC |znIܒhi܆s26qZ;?)0hi u0#_ܲL8dQHEWV. эJ#tPz(gFAz_oм-鎹@iGE\/VTizfN{syn * *ˊ|e2:\$mGqݓT#ӗvʱ`{2y\1E^%~sC@ T> u6yVTT8krM&ۉ'.$Lue/@rF#罌&TS`Lm4srKP3GRWnrU% sDN2Fe9:y甗 )r"T" .NTG$ʫ%Y6R_1,.d>n,h餺#[]I&A*9!U[].'TJuo9ZVDosJoesTvIt/Vl%-nٜe3ё7H H5d+#Z#]L4oVv4⼓m"Pܮ؈ov*$ U䛌L1[zLIfMdyRLX44ۮg[m۪i>߸}m߸^iڭ}&KۆݜQkmL?1 us7K$_6qB%s%9e/~CDUIk]e^Sx3HuF{Q˾sfǑeڅ(jwZ `|K;wȠ/I<31騵(&F}n24߹VEz3 G,;PnvE}A~I3pVm)C־in;6H\wP# ,ڿ{j uK3  j۴=ko:u3dosmg`h{֏^n{FcdRfھܞo6 uC]/mż0gHU`9W'NzF7~^x?O ۗ/_֟PPԟW` 4 %^׍ ~7Ke39_ YFN1ml'M*AПV vb5.m9ibv7ڶU|q  IDATy7N۾߳N>usKm?w\v廞sݔI5˰;tB 4ii NDEdN/^m[MR]}ӴOǖwפA?Y$.\8׶~.` ; :ktJ`i,8^Oeҟ` m :K<v~n;ݩ r5t̍rrqwCIpLn&7z^jd6nNߕnըazi^Vev3 OĝfvNVA&]>iW7qhNweu֬}e4j'_/YK;ܶe֬cizVIϾ1%}Vm)N:OvTqo0! H.s:Wk}ۍsݮ۝؎v#x4`)CM;#䣴mVnFùvIz*@ۋ4yr0O{ ۿ:|#`99s?ueNnsֵӮy a#h; ۋ,IA춖4mk[w*cj>AmKg=Ae/H0޸ۻ;a pd 8"p` gHc)S\!7"W6R}r +3{pnKrfy3ȕ/̼si3w3X͆/a@'W9`3aOhuˇc=?g=ShmUctq9叽c>6@v9ms֓O9ڇO}|nsQZ5s_[sܿes}< 6U mvrP'ܐfS-:5%Ÿ1V_cYzYT1_n; u-֡_QRCvZ0'@۾^=:<:57j?nWTPHv|[mv%۪٧ڲ>ZVʻel—7H1O}@9ÈkrL+XCk|[c@]2? 80ִ`@jVZmOT=v46m h.Dt;Kn[Ԫ$WS`;g`ӡvǻ֜}jU}vmKk%|[?ǎW1o5nt/w}ՕZ`|GUPM2ϫWݳv\p}8ӧ_ׯM_~wDr4P: u&|Pj@n;$|$|d̗O嗃XU}d]C3kzr{k;9>>g%eZWM攣iq̴9S.rdl}ί:|9/}6),tZCȾrC}>tq̔K1ɭmLy:_Mg—K1mq5+ >U*e3 ;s;BwlA#C?-ns<֬ӱS|t"K;WlfjWkdf^m"p? _ؗں9'(TuZҭÚ01S%>Jzh:iLlP2[&x0,๳p8wǾl?VU+[ݧ{=^fl;ؾK9 9`lYIR=%;j{Z³mc{[:ަel֫/ ۷,b{6mr3D r;`͜=wʉm٧Ve+٧m3^%/-M7KΥ'2K $ XJ_ǼՀѝ澎yTܺ,c䎱^#i TqԱ %$mkK' f?b9T~n'9oQ`ՔS͚(^Z#5ۢ3.|Y  J+ؖMv4N%Y\5ϸ<uqcD bk.ץ}lh jåx\2w&Cjkf[Vjle _B jf(nL QlUGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHhWi@m,YnhXYU>yC,Mvv{Iv-vIчv~zܘ/K @Or @n߼ @# LKJYƂcT ^P('x1 @%% 91_f>p8,@-'y7ӯ*@C~oJ)ׯU =C}SJ)A4bl'$IENDB`MP3Diags-1.0.12.079/doc/292_config_visible_transf.html0000644000175000001440000001023612040502152021043 0ustar ciobiusers MP3 Diags - Config - Visible transformations
MP3 Diags
Some transformations are unlikely to be needed by most users. In order to reduce the screen clutter, not all transformations are visible by default. Here you can adjust what you want to be visible.
Note that "Reserve space in ID3V2 for fast tag editing" and "Remove extra space from ID3V2" are shown / hidden automatically according to the state of the "Use fast save in the tag editor" option in the "Others" tab.
MP3Diags-1.0.12.079/doc/008_licence.html0000644000175000001440000001150012040502152016074 0ustar ciobiusers MP3 Diags - Licence and acknowledgements
MP3 Diags
MP3 Diags, Copyright © 2009 by Marian Ciobanu, is released under GPL V2
Using Qt Free Edition, released under LGPL 2.1
Using zlib, released under the zlib License
Using Boost Serialization, distributed under the Boost Software License
Using original and modified icons from the Oxygen Project for KDE 4, distributed under LGPL V3
Using web services provided by Discogs to retrieve album data
Using web services provided by MusicBrainz to retrieve album data
MP3Diags-1.0.12.079/doc/310_export.png0000644000175000001440000002535411263115207015652 0ustar ciobiusersPNG  IHDRfK|@bKGD pHYsȥtIME  )y IDATx}pSd[17p ƀ{L &m$2fvwܶ;tg;n;{'m{K(I4M‹Ipm7oؖ aKGѫeѠa~*=- Ȁ\sSqqfd=׮] ڹʼR[YM@82U\0Fs+nӧz߯|c]U+*(ppQXG]JnPyyYεأ7ˎhYiin74),,֬ZK*iumw;K~]|I߭RASNL{~]tEuuKRUs4k/188kڹo]_XXaFeVv۝*++Rz{ЕkdĐa5\wWUky*U/ѕ+[Qaa!#iiҥ+Zn)׵hݺp̹v,f)Lá3f)W444522+I҇.ݼyS7v{TTT"544jo?Zrys:}긚ϜU`Z3~Wle`mlŊUZh.y]n]^ J n3\3g/x]utԩd#cI@N1\XX5~zzjL^/^mv/]rc.F4Ivv0[;bȺ??ҩwU[;+vsީcޱȗ_~-Mqup/yI۞LH3gͿOvE+z!կߨݿ C***&`Sf͛_}Tt}i-ROI$}H4^;t-7֛^y>oW{vnO{t휺STyQoSU>[=W/0<fcո}ˏY>l.}Zb>?W=Azjo;R%OJ+$]&U=(jKbQ>qanx)ƭs]!˪L~BD:~L̺#ʕя:CC*((U(OG7o.G7t12bdud{W/Uxg?}Hhi$"IPAwI*z|yZ ЯˑaccoXheX16nzHKp:522Q5R/@@nު pHݝu 522§e5o/nt &$ܹv} ۥ_qa/ eӹsnGB/]m}c歐V>K'9pkֆ=|ZZϿS9Ẏ?5k[UU\O(vw~lqύA;ڤo7Kw.^{RW׿TPTOU~ǝD0L`2|>z۝@_g$ڱPV!-+e R_[vv,jIo@_^hGYsox*1#j0u=Ujo#r12> |kp߿Iwq^~O[NS#RASwu߻R7n 0F> @>3TYOӍd>I֟tb\(sݚ7o| ҝ& EtgcP>:Z =Xטݮq#Zf$)8Wv`ƄJeΝ3~-tZ4#¯EZj:v tP ~  C05"z<,2In"ݮBٸ`fS/K>/5>m~kz5O:yJ#Kn[cTKW|9q =yáx?sOG?w=*3kv=bKRU: =kHwHR;|yc6$=TWjiiڵ+&^ϛ77\96i{X3Oywt nT،_Xe4F3fE'O6,tQysvuڵ+tq\JdlU0 GkѯBQaa^_Uի~+WFtj'HUd(2004b22ۥsgvӟ^78=r\r\wk~U++nӌA~rM==/MᐳH.Wٳ5T2CA[~񕄞 +蟰.4* -Ђwu+\ڵ+~݅L~ז"X~fϞ#_,fdLIիWu~ 4:za`6ꩧ$uw0RP(P;bpХOzED>1?ڜɓu߻t:*))ǣ"I?b u'~<\#an;qXhSjn;<Y&ԖȲ -ky|8+Mj%PǏ/5p8pOCN9 ؁hΜOW;JKgN(3 nGĈY~;6*(p td$ ՎHfәiGWELH,M ȑ`]7]Oӵ=B+𞛅` %rj+r]_DՖh[U[ bV[!#O豲b 0=Y?m3.tSGꉶ]+1m~ܼjdVg->ID;m{Be#Kf?vZze#gdcNɞ|QOږ̾k@*H$`9V@Ml\Gmm^?y7ӏYdk0,fe0Kd'ډ}F:,}an{*߁lD(c XPG&J$z!x"-\NsWյ_]:Byj laF::DždG"1י$ŸV(E᱂Qح;նYK/-l㭳s?xσ5Ȏ Zl/gR,?vvï0uCy\x9̀k'T;03)G< `F0KJk3Ȃ䇪̻E0Ku ȼ7F̦i8re~VL f /Z"C$XTR699d3f @0 `@0@ L?QP+3BXuu 2fUWׅoǣYjhlY4iDb"ˡz#G.wt43 o0K%}L`vQ]inǎ'sI&2]kn^ aUU_7y,r%E eXrI%t2 ;v<uѮ\y2#]yuh d- ?v/Oe9}@0 `@0 ` 3Y:sEGՙ3-#ǣ>^Yf?k߾742R2 {Ccn$?nUR2C[>u`A>Wuu8ct 3f3f @0 `@0 N֎V0Tqq,2_뢮h]hRoo,UE\~˽ڴi<U]]0zL0 KWC&mܸQN筙-[I/ eаIr82 #|s:jllu@S ̏[-`WOO@ a]'?T(h"Vrԥ_f]]ݪY2a|s:YnVvY0Ty2 #nRz{?Jj?>Ʌ`b~[,dFRBprQ֦2,s9944V͟W~@0PVӜ9ejjj򵐷, v22 C^~o@v>p`}/J=εE''}I9NѶ"כ[Fү }zBK|=:Fẙejjjt ejkkeJJf_VlF l&߳SXKѻU6l~-#׀U_q-]fܲ\q._`Z[ihhH;wp;֪J)K+W>@Q,;ӘDއyϲgҥktq/]&v:ˑ+ܒ?z_={L&gy7bVVӜ9ejjj֭[{n=sjmmUmm~i=ڿ**rU!)]LTkxƺ UI}!r:y/1X[Zjٲʵ-[V--Gme*3;h~2AV6jWdym޼9nxxXoNxG۶m.Π`KdJj趩>o|m% yG,ʎD#C[=fx"H5%ۗy<xb?>ŋk~^ֶm[vy"봸+?_#=CV pY%%3u#i2B'dN+W/I:u-u ~<{HG8Kɓ'夌 Lr!qRyL3k5f@ Vg:Ȑ ·嫪JW/> Im{aUUU0}=%IN3 ׅOnwүk`i ;,'U UN` 3f3d3UUUj׮"vڝ7oS&.?ߔO2s5f3f @0 `@0@* :;:2 Vt#\T&@(̕ъ5\Ƽ;&}E_@0Xd' 8֙l`j/ eLHN~32 @Vّ#Gub;LK#c}3ӂ}>Iڵk7JJׯ` e `uJd*3\I%l2HU:H9;Әz vx2,]$cM#&:n LoY fH Ŵ>'v@0 `@0 ` 3Y:sEGՙ3-.ޏ+gU_mm-qzn4;\=nT:pIZVso*/jӦ x)'7O?<!ssԾrfi /{54lƍt mIDAT۲e⋯ ::s"Le8 :y@6Q{իUZZիW_Vcc֯ߨRޗy)TԔ)9;Swixe՗4p8dFt:S>plA~SN7@ڈY__==544hڱcGxӧ}vݻW7oÇyͣcF˒-kwd.ZX{vK0۰a-%d Z=R.7n,г>kYNjj;cmug<#e H0ѡtlgBA!0nYUaԫޏBF#$*$Z}n{qq VElNffiU\\@/0TSS'ON(S[[+0UR2#c#VJ(^m<;vےOf3eMe.X0_444;wNXp8|GCCCjkkw:)ڽ(29z#CDC&*])l&^| UY1++iΜ2555i֭ڽ{{9VO?~a߿_Q/8OvTr鞦U_y;x``n[*O"ùz=W`zp+s}OnK7UYYi{]vkǎ'm޽hjhhPAAAx:'Ѷm[vYq 3Fڹ[OsdZh=vL`f"v5c- eWG"msIt?fD,`fcFmnJPH7: (|.ho`6/vF&է]YTf =^HZdIsh}j{ ς݋=צL=X^9̖/_{ @Y>d`RY" f @0 `@0 ` iґ#Gub'EUU%Bou΋/5 P ŏ~SIBlϞ_yQl%)pF0䝋;|Q(zj~fouDſЧ1?@$`f c?) i"6@"̇V%}Cl2a>4 >%E(D0SGG@>5dxfO fiiѢ{u™q^pFup̔ f0+v0 @d&NVux{Y1\dץyL~ƫ{V{ˡ~B;}T&)3Ug+uq tid8zϟ ?PCol"gU6ϋ3r8YL&ONGhx>:}J0LPjjVom=1\L\3;uDܰL Ng2b@Ovꬭ]s'"Yd fߧv r3^| e##齝={Lk=V[Fg /Ko^6k;stܒ1K1^9kd#fgrT˖m&Vdץw&O#%iu:s?%`7}J0RN}473xeY>|~a՗nE;>TfB0m(wrOs2 :qCf$u$)ݧNǗ`@ h}CJ3> 'IBDOsO fio\S UUUWzA tFVUU_~63<ﯷ]~$[}p@';D~^x3`,{n@Pf1Pf*@. r!YMgr &)q@21ȑP5f9fʸ GB5f~c3ۗc*$)liyW48x$ǎWcm$-_Pv?hpLIENDB`MP3Diags-1.0.12.079/doc/310_debug.png0000644000175000001440000000560111202745041015406 0ustar ciobiusersPNG  IHDR2(rLbKGD pHYsC2 tIME%L - IDATXř{\}s_sk;f;6`Aqm,F PBZ M*J4$IhqqM qHC1iRoLذ}9cJm+s{/Z.0,;q-JXJqeYSJ5(w 4͏iS@ i|ԎBpm0ƺӶ @' L x7a7llq ;~۶VJMP3JZj}?lyw߆Jx HzK (###[^o4˲=s1ciډ ڙ /K׮pN'yޓK rF5)J-}u?V 'o*ܹ ^Ҟ!.l648j}i0 $a[|'{:wunr G ]ׯk69r"0^h6oqԽw~~Ȯ~3AOEs`ʭ?fzcL ¶B;/\{l~`L'P.qY0훣\۾;tnn.VOrRU^_7mlT_Y}1O2.r|'cR4ڊg]}];է`_ J|PTjttT=jllLw}jddDJrԊjͤ6l'ԛ4{y|^!dzz J3CЅd)#قݤ/t=SBY1۷oT*HdYa`aĉR_%HT*}7}//؊b k-J(jb<6zu@\.Q(&nDT*n#;wPRYFHD)=GRdF\ H0h?r'=3FFCI𶼖fo JxEGXdaN? ,0 W]~rT$*QHСfДm,,k,% ;J9:3߅0TA]gk1SBvÄ,8F ֋ԄX99}gYZ6\r|m۟,kk.}k+h<]]{-g炍"Du(BGqWIcd=nXZ13 ,JT*8c}C q,LlͲlZσHy>Q [CV&q4%[{ ]g̶nY,SujZlZW+m۾:6u:')l;?n񣀪oS$MSf'0%$I9ի&jB ;IH9r۲RVn6O18 > p 8D'oM y)%YqR4E9B꺄9tbaE' =IYe|daTN~j(i:nHթ1*E4es[R2H<D1@E!;d"[m,頕0xʧ?/6bra|Tv9;Wn\>lLmrQpu]4&v"z7dfd*cm|Em'r))? y( i{;4IB R|¸BE,)8N(`4>N#˘7}v[-H]eYn=tf4V6懡 +\ɡwdR% ike!qڶp]vO"m`e!IRBwlJ*J!\8u\$WN0fkGB"%_},lX'%6:,(baPIS6eM t0h!+ VTgOZX6}]qL h=i YƂH,e4<-KZm~=3E6 &`l i\ 5)[6ӳqì?rK}"¶oM}mȱ 9z(?41ˁ-4Y)J૖EG ^x>Riѭᣥ<ݲ===..5~>_uSi- 4fds.],ˢ$a TյKZB\$PVqt^i`xA~L-Ny]hRT(L>C,#_j$I]=D~咩4M-`F)^*cB|׆tV,fCgFA4ͥJRmZ'ze.(寧^R,*E,dMB {}ߺ%z]_Bt?ykDZ]MӼldw 9P:]f4ɒ-yǻ>,J#v`ooíVMSa}Vz MP3 Diags - Config - Ignored notes
MP3 Diags
Not all the notes are relevant in all the cases, and there are many valid reasons to not care about one note or another. You don't want them to clutter your screen begging for attention; you'd rather just not see them at all. Well, here you can choose which notes you want to hide. (Note that some notes are hidden by default.)
MP3Diags-1.0.12.079/doc/310_export_btn.png0000644000175000001440000000266411263116043016513 0ustar ciobiusersPNG  IHDR2(rLbKGD pHYs  tIME  0}#!AIDATX_LSWǿmCRpQ 1كs1+0-8D&>-9m?L%"J-zC:SƓ4}|s 2%R1s(..&,q(b(L㑑ih.@xE~&ȑ#GPYY+V0~ hEK {2$'N`o߾IܼybY=7 .?mkkCuu5===4HvFAuuuLӧrJdEx/= ,j+YۢDmm-3#ׯ_AAAӸ3%bٞߒm~A/1推 .r÷(%nmmŚ5kz5^z ߙ&@Egԥ Fq***bIPRRV2ac[ ֑w< P-pwˤM獀nFN„_Hg[f [)@z8]יJ)(i0fD9v#` UV14|2M&#4`!=84~ޱLъyCj9eFGvχZ]i\SShJTpd؄0<L&1NEEE1Nn5?YזMtDkp jay7{;UULK&a%<<{ԃ kprPz<=Lq*P(dc7~S>.ve 3sPVV0l6lv;"=@cnLoYG)sI}}}̰755w1 R顅! `SnAS--BHFW<+\٩,^s U1u tv 8bhy7q].LE!'OdqELNNg KY[v~QkkJ-fIENDB`MP3Diags-1.0.12.079/doc/230_normalize.png0000644000175000001440000003056411262725705016342 0ustar ciobiusersPNG  IHDRJbKGD pHYsȥtIME *-; IDATx{}'_sttq,B[8vdfƛ v6qQT-ykgR+TMmֻ3vNBb'$xqIl-[&mn$@:B:H}h5Tt>sy{V pv` ܠtw-`M};g,ęgUW^W_=G]n_ KސiظL)^ K+ޭ_>֯_O)qy>/ÇR<矋ٙhZ: |1~g*sŖ-gM\=֯_^;rݛqnmS`nn.qsK.qYַ^\o9_}&~ԓSOL@ yᅗgwmַwN}扫R>Jus'Mgo9'.8-axs>˝t:q[mw+.~y<3m d<\l~q9rrY۷_clڴa17VJ=jg W :~x=z4y5mI 'x"^{XZ:B[7lj' C8W]}MWGo}sOϯw dN TQc%(eMw;o~KloǺW^_^~9"Zmcƍ-qbÆxȫS=?ya[Ui|*CZfK/w8xذaS|~?؁z"{hY`,l=Jc;wG{.ieg^xalW=ɕ˿bDD? su:;;oH6lwpc| ^}hW_r?ߏN'bݺ9zFPfk6 >L,~:ճ#Fe?qpD{sĖ/=#TWF|},eokM6F=r/ĦM'n>ҩ>K]]rYޣOm+"">????goyS|tUT@ԧ0t~x0֕X^=w'sD#q#.PYو?q;"}0@<7WRK/|ݻ7^v{%Xu_}(R[;/M"my*;ƍc~~!{%[Vt:X^DՊ̧bvv6baB[:K(O+,/wF\>/G>/VnQhwD؍={oğr_wgSO':txeLկ>tpoy䭫LRۑR2x;53˱K_oOǡÇg~_ƁՊxrKbyyٕHrLJ?sBҎǣ^x)NPy{'}^qUiE?6wNuZ;Y:=?6m>;z瓿z yWbvv&|>.|E%7oxݮ% /g>;""ŇzByЎ͛7E=\BAiDx{>r2@}uI:۳ 7]-|` Ijaa>ѣN]zapnǦM{~o>7mǰj?x*?Ǜ+⯾cff&NX'L\+cǖY}W(k/(m޼1?ae'kzi!n矻2o&(]EE9nSޤ~Z{Ϡѫ? 07os=q2l̼+yJIo_vٶؼy=EWK b'N?A|>۶mumSA'=333177sщC^'kjk/(1?""{&~"uX J)W>{و{>e÷"f#~8`+Z10HZ3Νo;,,caa!ڹee~KjXNjNo捱NV133OpU|K85?1?SuvFbqyKK1+t`;|8:j̺u1iS8~qd?|GqxHnɫÝwc+wPKKK.amnpɺn߰am~pG{iM6f7h#YXX\xQMΎ6gn'.ED<ˇk_J?xé.yɋ^`Xyeq?6y-//Ǯ]?G_8WnęgnXn]DD?~<9r,// L"utAwLwtZfn߰~u*wuP;zO9ȑW+NJFJ@H''kQ=b~~s""=wK혟_N'ƍb~dn)R]-//ÇCw~將߿RY)֓Վ7ޘj ;˧~<LZ_ujLܬ@sTZzlܸ 9G%?fggN)>(Q6={$%6n6Y_~ԞD% יgV+С+iӆ8_B?8 հtFyk@VP[c֭zXS㮻^=KN'(J (J (L|k/I`"l۶5nnHڱc&¾}""*JAnL={wW)(9G @P kVNg$(Z?l]3mWqZQVz9im1"㑵mKQ&e)۴^X%Ai~Mڇ(eyA[&qb:>uQM2_to˅ךIȡwt|qswRLm3uz~rj|R7Vyx!FWeawֺ3pQ$D^LeSWpk}E둵QLG}\5Yf9R{Rai[opK}^(ea"(r԰|zq>H1.QOmsATuVV*cPf92l= JvnZFSw/s>GfMڶG}>l+ȶ[I\e ڻWs$1 0Ҡ|9 <$o]VCo=meUtJ LM`a>u$0o]UOz Gxm2ZoS˔=1׸@Zz7{NUI>}`sAٶO5;$ DR/Q^QAef 1Q{>S+{^~$ǪNjRZW^֣ƳhvhU[Xf;:䭮 r:_)eֽdI,(H =&eNdZo>m[qX}PuS'ek1*{:^u?2T"SǠ2|<3@PX^ (Jc(5UHy~ߍe8d^+-i>>69Y-[=>e~lsi`Ai~Ѝ{ۼ-ֶ9F_d4%@/&K:8IW#MZhjc;Yܶ9Y?j} "ߣMkՠCކ};uQտlC|󝵮aL9\z1鯗*}Y>Z_tԓ&ƣHuaE2%;“AjCRLC:HT=L{G5>Mac1hOP({fSEJ=ga%Z (@ATSjMMh:ֽE5orZj庪m&:]M/xZeUeSs0# JMN&[ yV&'V7uO­V~mjoJ&P.z8I hRniqlxm.rP{cSWՠ֫MAmUI>丿NMmUM0WƵ}79`MK^R02(e^yUDpʹYʫco/}0̰˅z(ZfRt{\v]R2YWkۨgկ (6iv_ =^7E֝wbyE88eE/ڶ ek1MmU;\g*8GSEzA @PX&0:%A @PX=AiV68]9&kFZMnzeGL,nCPЈ'Ô/k2imKOc\e&Y5M!k=4Gi?i}0~t:Umnyö?:&5G;qN޺lM2z/\]u k砾2>eQDŽE^LeSWxk}Ue,v9loʰݰ>MlucJYavopSz^zC:_e2,n3y8"1h \ŭ}qѿLA!?ʚP+#d7 LYh}Gy=~J煜2-R"c~Lxd3:Ǭk2D);ʛP敝w8=) ?"kwj*["UOUѺԵ {NMGcVAլo +;pN۬ u#pK̨hcVN.Pߠgyٲ+UYG޹!)jjuQl]LcQW7=J \F{P)e:whWJ=]̡j}GyCR41eǪJ]l3UN/!R/@Q-c~￷swF=vklݺ5y{|ر=nIVm714٥m{EGgؽ曒Y\\;Ů];Dո$%A @P%A `tAI=J}QJtt!(J (J (J (J (JJ (J (J (J (JJ (J (J (J (JJ (J (J (J (JJ (J (J (J (JJ (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (J (zsQiZ:Nh(G t>`j~E'0Q%A @PXMս?gzR7 W +ڦ6ު찲j;h#L;`b&ý ?|z2.=).uפ>A `z'lP`K}~x֕r 7/Z:h9rֶп|_ ü IDATcm(SR}0"~A j=&ԩǢLeMSd]&Χ3'eNSڷu!LaMCuΪ߰4oaeԻkHA ju1%>aL }Y{JvױU:S]uk$N p2N8V gEĺ&5 W UkZ'k0Q"2a_){1ֳ̺ʬcRCS8SWkE.5}¸٣)ؼr]e_6ViSq(RNJ_gӫz~[7켨򇵹5}¤k;3[c֭ scǎqMI&L9Y=;>14fϞ/7ߔbuݱt,v%6A 2F`r1A @P%QjVWV5Y? <)Nu4r;щ{UoQymw<X% ^5l~Ф7o1h?9x]ye.;m*2RXH˔Nڒ5YSV_k%cH0loDMLTcy߼eյh&eڔT) UE҆Fm2y/uZ`J Q4;,:Ufщmz:3F5!O[TQnécJ{\*V$ejMB[}$n?ڸ*4յ|y9M;eٺ&£hOo;o&HV٣+Q`+lن]!<*u.SAsHmO꺪eV*r_arE|XK)'/ˌcݪZgXkZo;v{>nغukرc{t-ztDTջI'':ؽ曒Y\\;Ů]ۣkeb%$`8A &\IISy. (Jҽ"ذ6WۏuNB{gu_+a{O{Aʬ{Q=WIYW+HAȚg]zH j`P]'Y*:1%8$eMRMtn+wsM]W˛,R"}7=U_EE0e,&ʬsLA U oQF9Χ3O&eѿlrR.[漵5ah\DZ? (e507^YIهuL9Ö)Rf}Mjs1&.Uy#ޥWyo_VڎDu(%.02wo,;4uܟRfj,Þa{6hs}ծ2crRcbTBqǝnm[nM^{>;vlnEO0l%OYI3&PHcr}_|M,..]wKKb׮Q`uO${;cXL$1r1A @P%A 9. L{أt:TG @P%A @P%A @P%A @P%A @P@P%A .sU޶mkw &Ŷm[nLm۶dnXZ I%A @P%A 9/g#ԓD+~C Jݐww0QJAo`"|>y䛕s%|sMj"" |,Au.;豼RG_ﰶ {2˖)۸`T$< t2[vX)=-[am) ڙR04CRHSIӨ" (5}^tGZ{_R2{oG}ngӠ>My,-6.a9sV b|ayy>ֻluU֡rE: s~)kP?N9-r# *`Rj fߗWnޤjp(Wܬ{"m DuWNJH+\mJ{ (Fu_ءZu}0eF]%/ҠsL*fRKeCs5{zW{hFs.; ,2nIRA841e˫ت&㰻C+hzrA2˦;輥s Vl}RHaj(ܠ~T9G `$= OëTOrMUP̌.8]c{F} M/M=(cbh2:V&C%|+#"z[*c J G&W_Uaj%&s%A @P%=?#2l۶5nB|S-~~UgddDDrXꆤ?y~ۈJaIP1?|8~Egd_Aԧ9~wn\N':e?t}*(0W( J4>77CTٻ;wwscη8XW}O% Jo&?~AK=CLZ;Fg?AӓK.'kR?Y}z%;Wi*}*(0՚pMbXa1\a͓|v{%;u7MΡwԧӱ'%U6AkMaR۾8p{7K|sRu`'\I^Εuog-a{Vv:7c~KiO3lE\]U`Xƴo5[_PWWuowf0}U|NVUyl\}%2(-/$ޟwHWY߼SRG~ZǾUz}eY]lmu$n#"v:{$:NH\vUo#=޿z^sh$]!sc9aSܣT7R&Im老vSYuJ5nu<7oqԺޛw{[6t&OS,e3mqk4(%Qծ~+[jiiGSxۮ/i_~ݓ{c~OkOQ~wi;Ƭ<8REW&iVG :dl_-8^>kk C JӧʼkO>]moVP^CʠzR<ԉ{@vI Qu!uuRƸI޻tbyW\qm| |~(X^>XoYG-qi?{ʠԤސX˫oPA!?YJVЭ{;vXVۻ}0A޽6;ӧwy-ظWqǝnm[n ĺǭޞ3nsߣw[n9:lp38q"UO}:O7>o'/wuw,-]nG s,|`j}:>'(0uAI9q7TP);s؝럴>>KX"o4}OA '&=O'O%}:)}*(0۶m?wwض-L_͏ o{sC/dg,.. J 7\~Jя޲~J IgsJ6,  4ȌrHw J.dI!iw $ J%@H IQ$(BR$(k>$9G QcqqQSkqq19g)s]wݭW5onDD1y=p}cGDΝo#I*VC0:IENDB`MP3Diags-1.0.12.079/doc/170_note_filter.html0000644000175000001440000000734212040502152017015 0ustar ciobiusers MP3 Diags - Note filter
MP3 Diags
You may want to filter out some / many MP3 files, to focus on those that have some specific issues. Here you specify which issues you want to consider.
MP3Diags-1.0.12.079/doc/screenshot3_thumb.jpg0000644000175000001440000002025011304163205017364 0ustar ciobiusersJFIFddExifMM*Created with The GIMPC     C   " ]  !1"AQ3RTUa #2SVcqs5Bbdr$%Dt&48CWe,Q!1Aaq"2 ?gttڒ skqChQ+(Q بev4cV*ݱ;K[abK`3sTٚFBTyeP y/}PiE>dz}36: ak\u'-ߟ q_⟂|p&Zpi-kl7pC| ~O1eKxfAk{at,'/&鹹j*N] UH9,JM_.S]<{7+ g8 c YF'VE>#(t110;"3}rB+fx o5/WŀR$3tl)" G klms-,!\N!rI(.eX(o5/W)~0,{EuTd)rRN56k qla'MJZ]CynIvI R rmjBf']N!.6RBEo_a 9|JSnJ2*9o*\w_/Xr1%EE:oye4B\xeV]O$M'(3KFXo3ː(sߋ6"&Ȱ*P_r1%AA$`?(ףw4Wu&Ȱ*yA$`?(=;ė4Wu^BȰ*yA$`?(=;ė4Wu^BȰ*yA$`?(=;ė4WuYaKj|N*VL x6 U ~bK܃Iz~Qu3ڼlifdG&O">eK$K nk'I(utbFKK6̽:UR骩J|XE._rēvt>ZeRG*D\$ eL(x]: XyAN*[n|E֐V[ն8Q A?wqfh"䀹.oȂ`{RpuaMO>LT7Ҕd"׶i#Zu2j`{\mܶz#L:mTLqRR]@A*9 e k*.“ҭYf~$U'jQԃIZu#"e9=+wP9 -͗=8m'\߫|O裩z(C~EpOȹV"y|O裩z(C~EpOȹV"ymaHJҡ)|!sK7Zj] ~0lVŲN 4!N˜M*jzPH^iu23lYoˬU ]NIԓ.:Kw)-6_x˔(rXX^} ;J[ʅM&]T)vғa)dZ"FH840C~EpOȹV"y_}u ;éI7Ai?"XYTcpiaԃK>xm'\߫ b!gQwчR6$%.%#` $9+閪RdۖE<%M orVdZc}y ?=G+xzj]3Uu3H ZF`Qed.`=tL*reISAKK׎Fk_eM 4r&\u$ɧ=aiCƛRH0.h S˖b<sz KN JTF2)KM,ov磊-wM$A$zҘfs %^fpLH˴> @' ѡaU&>N7޲ 1 -:6RGu I ' SS+YR Zb* m6B Kb켊4͟!s.)DrKg^}v;v/_ZLdeq 16y) BSIEMÒ"tJNȤYeo/5x#[c%M kr;Iy5I_^hMWׅl4v/_T?ҍihEu($yvFkq]d\g%rae( Fk<3J9ImUi66 mxJ$B*ߩ4ԤڛEsʄWj}CF}N-aAm$7RؗyrmX_)*$M!ly ݱ'ǫn؋ՇjO+z_'6b/OVݱ'ǫ~(WjO+l1v^ b/OVQ?~(W cئ\c6Óx`zAfS[b~MkdDbj 1`=˷+P"R77ZPMβŸC uġO:x1O=( r>@LzÏd[Qh3($r?,($n. fl66e*GIZlthzm qࠋr>:zTA SvVٜm[TԐ4Uz #Xܾ})p3YYXK{2ϕ($Ntxl\{uVCъ7hC+O&kf//Q6M~MWpL.@8Ⳮ^بܛ{RcjJ&*iAKw6 sa-5U)yVBԛk B0ºjG[_F?̋2ި_Y7wM$A^tFd>`St@Qb!.*X#쎚8i22[pS Nɫᄌ,-oƴ cR' XG ix3M'2_4;.쏡ämUlFBQ5=gVo#ew/$l xTNm; & wBɿĈ" )&et*J\`A RT)!hmp[aoxo[l%~#b Lv*}Tez1U s> "m f"]~ȝAR!j*"QmM&Ԭ"Q vuװbU2ӤܖHP U,l8 c%, Z$@*vѥ82DO6-+mnQ6NMMpFR[!^JI|a9Z@)X:   d7fTml]e)ķ73y~7oZQ6G \h.JE3 i tf M?7ꓒYm ڭ9Ppj$&!\-ra2TapƓO;A:9Q(t~ nͺ4ے`eQ!+AI`t9!йՃF\,CgF\#yHt.uarCgF\#yHt.uarCgF\#yHt.uarCgF\#yHt.uarCgF\#yHt.uarCgF\#yHt.uar!-8wM7#R Z8l8Leo~^Te$J xk5SSSlwEydAmq"hM"HՙY#UUԺRfg{iԇreŁ g c3&,Φ,/9_%0'f;R qԎunS ؓk_{T%ܮ()xu9*R@6ͯanq m5KX|^_%m6$'2F' gܓ e2DM8De"{a+,l%|e@c܄l$R67nQ'0nk}RT #C2H Ā&Z$؀" ; & wBɿĈ '4e e}WMA*ΤKTB#C**-‚%aW6]i.-͸A mbC*K -oXNJ%0 `q[jeŕM6wrHH&(J EbYdbUq$j3N07'ѩ%dV*&\LlY"7E>Ǟ UB*7HBR9>d#tLV&Q$7u*6p:lx$X|Sjؕ6va5 J،O.yoxż'yoOa'yoOa'yoOa'yoOa'yoOa'yoOa'yoOa'yoOa'4YJ<乖jaĆ 6RF[;)'"aE/4ۅ( ND6:ikHi(7xT/H ; & RXM PTš)D}WծRܼÌHSIR#2R_&|4jGZSz|HRo9c$ƵўJm$:|7[CJi (+X6YKe!AhZR 1&MuMK(l:BҤ.ag$Ƶў&>5ny3L^KJ@: \|pA ruRS13[JZ咖H YEy{k&>5G͛$x<\QmFV$-fO>4.[HQ) @*ɦQݒzFRs<3v#`$_bmmZ׿xtU/ܣ:l}RsUi˛T [mk<|(Ӕc] tz}e-MMJ)*ʮ,@6'jcsmZ@B6@QIk=hZNR0Mw2TN( m.Mcj ii'˲rL|k]AcZZ<yTHe3oKIRL&;hNouix Ri6sH&RBž@A6L|k]AcZZ<$WbU`"ֺ3փ$Ƶў.yi&vWMa$Ƶў $[g Ej>}}}Xj7]eҤvT*))̋.X>˖;(P$) $ asȠM_7ՆPId/̰V%%$(j1כiRuТ%H%Vo"o]xg0)ZQ%)$\XDr2疆 u Z j8Rk a Rʂ2 `b.o"; & w~@4~SA'nݶNԹW%* qVQKmؔn>!G]}x 4tM@:D^ ]}x;%%ss;vS`n*IQV켺 `cSt NSδ%), )EJI$ ;7ZS-oKfZʔRU`*<Ǹ*U86}9T:jn?"̋sa%J+)?m`?MP3Diags-1.0.12.079/doc/130_main_window.png0000644000175000001440000036434611262653211016654 0ustar ciobiusersPNG  IHDR\ϦbKGD pHYsȥtIME 'AL IDATxw`?SvgU,ɲd˽ 9 rᗐp)KK.!ԻRH(&J16wK,ɲ)?xerdkgvgޙy氖F3.W?lھHgq]Zd>{X6o{5 4m_}A>{l?Cm^oFEQPϩexG hY+/=Ϫwf9`Y`"@ #ӻN$no嗩yж&,:r_}M6T]3`=4OP5v99^3h 66g?TӦf2-.κ#I-eOC8K׈i|^  5io/^DhOG $Elq8COeXv%{[x8(** 'Nj͈+Scz ~5 Xv@STTiLPuĺiŘS$hakpι0fX&NY1 Qc6cx 2GuL @ gCpR\C2Syf9b8x6!I/|}'ӡO&4L6i^p0oL9]aIA C;ȲBSS{phUc$:p]̜5qȲ,F)@ `[pI1\~pNz<3'L(.9ڵ\zl4-:@g8!`: :Cw 4y'd0aa(A$dh|V\ u3+*ʎ9OZȦCIty-[tty,2t3Iͦ 6[Qg`Y&vɓ2oB{Ȳ"@  jǗs^ʕwuH+ƱCcj֯kmKfŠ1O!ud;$Tߖr۟>;y.)UBZ8hhƼy3[N )Tijji&i1K.9x? SZZݮvH8VTl6M3QU>_c+=g>]]],}lC#@ @ r.}}X~BK̉Fc'sWSǙɊ3gۏz|#-_u}?Bl3g55)-*CĺXH͆CGw84R_u=Ȉb8b؀u}h~(Xv׳q̼,˸6 ]׉D"BAL@pRsB%I"'p,:d_zi#]Pv~hfg0r4w("0{wS_+ebf&&],E-E @ d(BӒG˵2TG`Ii=>?a۰, ݆nO'b ǏI O ?'5e'e{mݣrm-ZʕGz^J;a[?I$)$Hlϒ$2Z@ @p\DAr^$ ۑ".Ԙ?p!H#xq:a9",QBaP]72Bi.\.'.Yx"yV0 1} *+'2qiZ477F$ Ee YN~$ YN.F#ttto_3#IyNBXX3A!VH=tX4 n 3I2զdZ6M\@>wVe_CHUC~~>cJ>u:'NDȲ̚5k8pE  tzQt=z z#tSNcÆS9>xyM=}e̘1c:R1لG%]󢺋,HУ$L;8;{ ņ̭-,˙iwWWAQT QEA$8Њgy .iR_@{{'^oN UU$6t]vaPP(Fgg/Dx [u$R ClaRRRBm$4xx<"FyȲ *IzX466gO6yfe%0g, 4- `eao! p`+[lְ .G3,kP;pJr` ?*˖K_8a)XbKZذi#sfk.<5wlv-"&Id}2"-d2Z)-sfwLeׁ8_5]U`d9gSŢ6nZry666SZZ¸qTV%?ߏn'D좼m۷sES\Ryn/XS3'ݽ O((?cVxuD"v+Gbᰆf!R_wmBg%1~ /z9w`l"Th}Hk7bi{FŃ>»g<韭r _i?*o {T,kl .`Q0cÆ*OK&5e]cd@ÕS,r^D#0 esرx<#:>={6m2ǡ7 Mi-;9l޼3ea&tٹs'dϞ=l߾t=ix^ 3bSAe0a{?rĖ6B(6 0vTUEUUEATX2@z=D"Q\.)5"8{ #,X}B0/ UPV6qԴ+sQX?";XC nwF8r:)ž]TǗ?C4L4MbX 0۷0NȳH@[w~qia"K&&%cZ)b fcٰllv,YɧK/f©'Y]l9\X=su=Ŗ(uӻ\yLƟ:\|sOQ2{XK/?^篯y{(̞=-m%ϟ z0w<6o8?͊ob999RXXȖlv>Yp!Mnn֭DMMQ+a۾W'|p8vw($ q9 v֬YC~+tmm]=+iH8 z =k)zJ;@ɝW}əgT,]W~ßpx9 ),v%MCCh4JMΛラ?N*MǶm*($Iqnq 姥Nu{/vU}+fs"rݶL_ ǡP$~zB:Ŋ=||<7_ԋ2]udn6+V?n4M.\Hcc#,pҟEɌ31c`,cƌAut]gܸ*V\qwD(~w]K$W>ecN{w=W]u9~O|6\Nb8&R[;0 #@X,F"H$DL]z0p:x OuuNEԀ!=ii%rxxPZhI_[ibPUH$B"HyL T7Ȓi% 9O„ ޗ*nTMUmjJrw@OVt9%k9OEk}_KG2snv5\JBq@D45%σoNxD\rY"*gidž Es8(//scٲ3)Sjݎvf͚AIIy~x,Aoo?kr-H);e˖c[7we¾}bO~?޽D"1OOOO&ĉŲL6m4Aa"эH<7ea $yжfQry:0I4Q(1͇A,S4gĽ^'>+xfR&NdʬI(#л/))CsXt9x^}կ;9Z[ۙ4un#{~׹2tGoܸqgwcS<D8.^|q9K\6'8//MsPSmvŞ={ikk~0Ph4aߢr9q:]xrss)(ȧiӦphq<9NCOO?bCИ4718Nl6ljFDB `&LrĢ纺=y3IuYVUVK4IFdܝ,g$IN;VJ,0hB0 n]rQFp%4Q[7l7{D"NY:t+XXXd v{ml*6{%=J^ۆߟKUuI..v+[~O`5t&-;C[:>op8"{I,CGe_i墋T}믿 0,LjEud?^:Iyg-_"+AGGK>AS~EfSyTVVpues`a㮻>};ooH(K4`b^[իssG}oҶ/ٺuG͕l #~)e Tj:zz_Eqqް۹b>cy_i!?0k,0!%EK#׵RQWa1&8]( < 3 t 稞1'\|Z˖/_ӧOᙥK)`ܩ#疏\5~E?_|peզFNn.˴P>y9G|}BTk &МbdYJTMH%nnАO//k1@[K^d6g6vbO;FeDMCQvjvd(Ly K2|NgW'scժwH$Q Q?3 lݺ#ֲ,x=I"K?Hww7`f*Cޞ^Ə4M{<ЎtDWzyko5~.^@$aeē+v:1{#aa)f \5̊=!~z{.!G3aB6l`֬YFRyNϻ疭GV+/ƟA7 ԷдUҹ™|KZι!Ʋ," QR2CCUAvN'h@@J Oy:n4)Sj48 h4$^o&Iv2R(S.ebI2,IHH6.6=ՒI*($Eni3+qWhňFeĖl%&D_pnj2H^3?zr?p/޾C0ˌ%ݜ`I$#1bDFl-./˟/meӞ _>w7Kuz:&OKy-s%P]]?:)6EXe-g$qʨ$Yv%eLT3(;K-[lOy+L<Yy[\.c,X0}ۇ,K,X0ɓkFO_kز Ohal[2T,)Ғd+f}aX:N D*[N: lU]đQ:7&ף~Oܰa3ůwqҥZ0e#H+*̧oߦnW\y_W~m^Ν(B^^]\رֶN*tuNY5!,;`o3$JrA_^H|+k!f:C&_ ˇdVUUA$Ǯ]0Mh4J(xa;n Ncδjr. xBq1m8&TWx B!0mRUU9jpah4r-IbQjxd{DvIuxEvםa[[;;;Frd Y㱬Gcc3WiɑF(SL qHL',"qH"y{{r=Ӱ0}Jug z#H`HX d%dEJzXXG+y#=[2aE^M@͔ىn j=e;3!R)<_ףٓ/A1,L`:H}N`@HW['O[|)/vœ -B P"7M ѣzjvCq6nVsǓȲL8{U(#߮0- 0M D7 0M r F osU xTT8Nvt%y4 0ia#١g2v߈{{f<z{{I}[p: Oݒ -T"&R*d(YfJа,30Zt RVRp؂ l} M i/ IUS$'0QHt9qDrrsSAGz*JcT޺̘3yleZAp\ڹRpqS_>8x09Xww7}}}gŸn[Y_XNK(IJzIr&lЃlxo'7T6MCQ5lv`&JzusU{ѲFbD;} -}4ZvN#ڡ5,S~8-haymV1M=COD1(SX^C,~XJc-qH_u^r 6 1Dlܸ.U(~ ?6;55tq͚(غ= w&3֭;Ga˖-\|ŔZ] ^Il\\{T \r pEqq񀗱ϩfʨ2P"3ͺ05fx}RFLpY=L^e^y}-|?N$ψ+e% %ƪLL0 G?z^,SPK{{/veA O8te7P]ױ,dxCkkn9*vaN$IE^.7+۴W\^I !vr %pDĴ.ÉCaEu(w %Hc)MǴK1C 훳p#vNқ%% _+EhD{Dq֬YeY)aEUmY"KjM4Mmɽc?]]]ֆiCr Q-a#3i4S-'??FZ[[CRU1I>#IT@eƌTUE";O"2M 1M4X,ɝБ-T`n-GZsy:y\qB̟iX B7M,#4M I$#3kFDٸj6l9]nP;#`TUgƜюC7oƀuMM7} ݋˥q-׍J= ^b˦M[|o%K`1 #xbl6=G܃H9JQ3gfeeWImks 2uLP #j& s2м1wn)3.[Xʖ\= k/ Ew,7߽B&&oj?o~6}q,`9hvgϙ3Ms=_'s Ex4#/߶ sކ=̙7'znòL:::X~WGG6Dqj*™-uRNThb{Cs8YKW-C-\ee!-HXh0hk}iQ9a& A,'c&nal6nRb8f n?JNYEa7P˲]切cHDIIt I*@`0ݮaFdp8,Kb>Mp߆)YL+;Yn2dG<(!EmD[_$|k);2o,%Ţ;(An$ˁ Gee%+V  %ْ #:puAuYa:f>4p]8%d׃]gx/_?$Î #ŵOrQ6&h@6,,+H`6j\4ON70 #W #)B6m~`\g@Lfpy_>NW=ms k H%9z,!KrHGxieOUI5:n+s&ӭGoo"0h;4ӦM;#(6l\'80t?ٸ=.Q Ŗ 6#IqM7q5d½pB<<O޸N{0h@FV6^;4 II .nмG--?ʖG>N}&A ߋxN2~[1n#Z=f_?Iyqb8sϛөr&1ud>q;Nx9Ptٽ{&L"??n.\ ˵M466GؿΎ A㋜DtkuhxtgdLq9A^:4Gć8cƏaio勞/{mn־r\! IaJMq#Xx9ES0 H4A40Mlvoär^ٳyg2e">rs}r:L(JOO~~sBdYVp$&Xsƨ4~KK.~L3=v"#AsF-݀Ȅ`o͔IA;jdb!3,:F:+Si =r,[eft $EAD32Su r}^]TTN" lHEQQ1%%/$6[@(:;9>EFD̖Eww73gԻeb`qbly3Sl1.OϞ],i'KIE$,+9[$̣_)#ƙɰ0SjqCDa4mT nys`re۩= P{!BCP690F҆NGž`e&pF(j$'`YIIQnYfin(fY9T._P?\qiJG_5+/apnjk&1n|-q ţLwvg&6nLr-\s5h6ߓtڴi|37 كWWL Rӟ(((`ɒ%'/<18$b E"ރ%ǙO ^+5|^JJcK菄9!rwU7ɾm+GTpyw]&r7ʆ2^P"ݚzJfDՎ&I^1Y S1Xbq0z b;w62uTƍӘ7L􍤡1*a ܅F~~>6:;;yٗ8]Q ä@Sfzx<ʭގ$ KNwnn+5REQ&=G8JGGcPnc>/nYeƌ)bVN+pLB`EQQi QZ꩐"92dYYd /!L6a]r \pl2ڰ"$en\|cf"L,x[3b5dIh?yfz{H-?rk3g$hǠbKv= }|3,s:D"Dxl43ƅizcIJZ`SP2yt\Lu>M ˔0da躅 D@%lT=@r4AX'"zt3dm8DᮓSv9Q[v KƱٓޗ*XeR IG6~)/XĴy)fJp~\͔J7hm~KD-K~9B}r,q5m}֖t3ںu;ܗÂsG8}eo ؘ 񨬬ŋv" /sϽ-x<,mBqqu~bwb>S[aO|+MӲF0%a6 L2;3_W d|;!HP\\pĢo^TAA2u,YBP\. 3c쇡p6- IDAT06(tv*ttnxHay dv4z{WyyO' 88(?"vKݻwc6?{Wq~ܲU[ )6`J B($B!5&ZBbqŽJ]Il˶d;}=+]ޝ;w3=gSC P? jkkݻ)S1t`2ȾFP %$P"Zkށ(QTуm$AȐ(,7sp> pT5覅YƖґ^?Jjm&//K.$d6 Gu,t:˖.KmlەqPT5iK.[}:[DD  >QU5]]a;[x}^C!ït.(H.dZMEtՋ%m࠸v 4-tMGv=eOA~lþhs];b:u86as˭C*˱F/=1&Nr %`oumn,47X՛hY\h g,匙P,t,~=)BQ=&qW@~=k\1u=rf&㵵u\z5o&ٶ͵_>}z8 ?>w}[;pU⭷Cu Duu =$>"O>Ǐ/7gX3ȶ[_̬Y\61%JzpjA"o$C3{Ųtw-+/ '>aÆ3tͺшHtO JK Rh?jFAEs#J&j B,?^GiH͖VAN껥/_ҥxWx7fdo=J9gܳϱd2Ͽ_X#nr0o<ƍΤIgvV\c}In@RN]3&pq;RVk674P*")pD]_oEQ0LPѱ)%%UTT9pXx ### ^z,jqOryȵR=#, (uDGVr&@[Ǎ$rqӼ8FnƎ6OO1xsQ.cU1(ߋi#x[:%(D)6IK,Ik$]"&I+`+ڔ1kg=Y9'IuyAJJe9mXDŽ#A7>6-_A>P``a^h&IlRv~Q 8Gff&-iomͷ:%-vM+gHHr5n#S%?* "PT%Z MwJ'YĀw8ӖX$'Oc@:{VR?ľOwN䮶~Wio +.m #a*B TZ'!]ͯ$9ҧm;~7,s7:tk-ehj'no ȑݫotW2uT.-ZDaaa[ƌ38կ~a]2!]ÐX68N'$<ħ~LCw)0mwUHUkƻ4Xp) yǝ|.Le.n3bsye1h~}>CQP+9'3?aɒ%{q,Z㏞>(h}F(,`!hNH6& :A w{U{TSt(r9G&7[.T9Q[;䶉i464!qH:iQД&9& LZ1["hIm[wn;iv %)qV_3 1hE6n(voU Ҥ~ d HMA#2@K{ި0VGK 0ZMl)D;L.yhϖu"4ꝴ^i!Ҍ%)-@{6Oʲuq5m /qs(D /-)Пr4'.>E5QDÑSTՓLGsKQUiljt,^v-lz-qKa?~Kv o-+iZMSzj 7V2)9kƦiMd)c X{I|)򨦍a3ϢrKuul.GΗuG† [ />OqI:zW0n+qljGI' (h#R%L?BU0:CÆ3ymmϟJ.el[^dP-n#0mto`彅ug:jki hhj!2|`o hqfw'?w1?rijTZՍJIm '#D*3ac8p_cFE,x.1"hBl6HiuMHqXُ،mtk-yFQkPkh{x(B.nUUHg)ciN#y;[!(,*b 1 JK<E:H _!IiT`.\p>Y;E2{mnذ)g( 5 373jo*7y 7nn-W]u=o.}aL6 UUa NwP YȢQr/xP(ɓ'p6ZÇqqn,Y#G0zht]oW^Ars)S-++KD,6$Kue%M-a A$ 9I\(Cawvpo QAAAAQ5r?J<,ٔ[Ḍ:N6PSDCC#o>-L8dW]u~6zݯOv`WOC{EtIR7UXHTy]sm%;k٤](g|6n\MS$ŋ`z*w<|>7#q0p)%2]Q,?#;;]뮪*5dys0E @b#djǒmKh 8o)"_1<^-X/7nyDtyv$DeI ɺs(yAI%9]1S+((={Y59N)-M4ʹm͛ٶh~ӧ7ׯ?BE8 : vT,EQ^c+lZA(IMݴ\#A=DjƅG}C}I{YK> >> -AV/"%8`@ @ee%999x_mHnYDXR0l"#(誆Whb*iUTSAU4p*.]/)vyώξ~Mxw\vwz㶧U N{ijl4B{v=**&KσL5gM$;!_ma`l0*BCzC$ ,x|Z"&cv+xn֯?Gu>mkZ/^ƒ.|O۷yfϾQFp{?cio߾<L>AjRv2dDZLQ#KƦe>sN(B=t]wn !vI'̙3꫷W^̙3m+뮻7n\;C9 t/Xc=_̯ш6bl!A]6Ab dvnU>Y5MB }qeˈ/߼U[RQO3vUX{EEEѨRQɰ;v,kV-dӛ?_(K'`5Ρ P6)aNfInȂq.딃F#,]6 *3& /Dc(Fª}kY=|OS~_Q]]it \:ܹs~~=CAAYYYlڴ eÆ >syyyVWff&EEE_{zO<O<?1DV}\?`ZC{xyo^@$]Oxxs(ReZ>wK|RKh5vݑGu&ʶ: ~/>#SQ=9?K,n V2 ` <4/?yX9w4]&Fcg:A8)=C˶AJ>Ÿ8뚿 ǰߨ:%Eqrs1MFꨫPK-?mXEU|8liFX"$B8(늢8 Q0b҂Q׭@JJ=I&Dw McmtzxW FLk I)qTqQlo1vh17]|96WP2Y!U薖iǣHIEʲX8Gr014+(1j0@IFI$!5F–x-h*"$E)'E]튾;GqP/B`k u(yFt,ze\c&*x5@8܄PdbfOqXSXM_1eZ&<¡H 5L|.hs[o }99zM8wϾ`֬y'߿>i?7|o{ أOmE( Sc`-ĩZ^!OIkK~'\s5l? IDATذSN9on,333BA=;v,K,iTU_)K[EJɜ9sx L8:jH)xjDy?c~r/Id=eA3 nmh m}tn6^xen6}ɽ޾KOzS's?>OǞIJ,̙É'H^^^]] qfR-ː0C3`ZzW_q׷[luX2-ZĄ G#GdtI5uUU%%%:9Ǫ|deePXXȍ7 7ܰoԑlE% r;*Y}, +̅ 0^Y0E^$VaxZ"8 +Tpm~S9k P #ޢ3Ȝ(ZnoYJu[d{IG %EmYB]9 plRGSSsD0C7o|&B-MlXc1CHϢUN[ZZId"`V^ ]AT 'f%ER!KBZR$ I' iöe%h+d;*pVjHu痃RSMM۶innF4멩ISDMDu(++K:]쌔H㺮SUUEϞ=ի7X߷]דka9Fm紂-)&8XE"т!l];IK#56IBCǕ14Rwea*.LQ(3@x āح>~0.^TMG$EvK8Eм|)w^8G'kߑob lE"!PU (,o[ # ]Mdi\wM3z\s||B0{}7t+mӷo}?0xplwksx7)))o P$Ol1VRx 7t̝;k5kt)ؒN8_vVÇoW&DvvvYigq!k;vmJ?|vF[GI?Eo'hGa|FCsT&VSb=r\aN7 +~y;ˣ悟Ō)#p0BiDQzI}}=յv@+@+nAJ^8(B:-IYҵ'N TZ8e QbhgfH2%A}PId ||+ev[/W_-CK$vw}7@Hx]C"Hxx6%##p8LSSn.۾z|38mi<}\z5|x |>7|3٘[VشDbd#~oiP/䪫%x? =}|Сmrrz7ŋwIfӦMw>kwrtX= ogGhXYgݝl^&NDVMHGaV7)T|]`=yT [#>BU<>+ Z***0n;p%c3`GF0ÎZ9WsfO8-@Ir$v/~m6VFN{fl (pC&wm~cK:n^7] .{AQb63~˲an\2aV-B:eSKFOJ8.@#l&  {^EXD6nLOAAK\sd&#pO(~ί0*{]W۶5貘RLo)%^h4Eu"!m$4 DQi>quӤ46VqݦC$ X,vJBm8(8[1]J'g`؅N"t]۳7͸:1,+@^^i%cMM̘1h4JYYsqߙA ^zk=7F|dy#Fł@J>+>C=Y?˃s\lv{p w)g6㍬Vf Y45pHߘ;tyyPP lZIB5+a.^,h?NbV %OcK+@Aٓbq?".\yvmRɉ'FNNFp8sϝ$_\M3:ׯ]~at]n hּCdy3kyqWdɒn[ƌe]ŋ7n\!CXfMZӰlOii)˖-c̘1ifkK/qKϥ4)fۮq]geؤ2ٝz~Gy2ϛ{ NC w?KwQ[+Kf{߽465{t*6WEI$CxG|<в ϓd >aQX8f3Nt6?m2!ef6sVJnCT~9*S=-Ke>mGB[Om}S)CJ6M͛ˁ1zx<4[Ed*UHd8"AI;H$'$Si' ȸ)IuE2Yw=5e< H GgN)Lڞ%pםG_'AQ&g%%%ifSJqD%H$`K K]7iY0mAݝGX &r$ߤ."rrrX~5vrw/?R&*v8aGeǿÌ5ӻ_? ׃O4Xעd֖+I1nGt r G;s8Щh4jRdg$ufTUsK/9cԛ?i\rqD6eC6i 'NO5#mv]IѤI,9;@oEѫ**V軆u{ef˵\UFm#7|^r-l )@oߵ$y'frɤpࡻڶy+>"ȣRvm9rBUU.BzAp91tPǝ>zӼ0ߘǴ" MÏĪO!![F;nirs.ܘ-/MmbqX=-vCfONg;GWu׭wߟy≿!&MCIIn]1)3̲߭Aq )((`p |gl8q"~-3gdŊ|ߥϘ1?H$gAw'2~JٔǗ{ɧbcL]iGO1n ttW%W\t9K/x* fԩ̙g}.E+G|CCRRb #^[LjgwOeF{uygcgS s՘0ݽmhEffG=7={vXk2s=Ùg;s=iGݼy |r<uG!gNt () dZt.m " -b= `KS_4O`Oii``0&e |z箔hH[kPgEP:wi:T.'ON%2,T4~R?*UUU 6w1MD"Annn2ǩu]G׽N#N#77>AC3H"HlmtS}1Ǵ}򲽻 jD(++㣏OfKG1u-wgR:p<+q DwWo,W Y}KG/@ p$W Gh`+=g=7Kѳ_/ڬB=C'9yꨇy =v>{''F F ޘya5lk({z{@Jwn{{Ҿ΄ mӓ MOvUM6ʕqA#wZV/Wu4M/?BQ=.t;ycl޼`-2T.\NSHFf'}᠃"+0{KӜk1> 34e:>Żͣ"ݓGAMMy{>zrr ׯ|>?{'{/α? WCMG,_u C`,V5="▉͌/4w['ǩ1vM~º[СawL4>55 ,UJ(lQ\q[Hc`4PQ^PMu:|q ncdbo>l%=Qx=_'.x Y+_d|^ Oǧ\)3g#hGQAMM ={0 #((( kW@vkkkEsP~Ȥ:|?BEk%9v`K |I'+#\`G>3>̞XҶUEAJ?g֬+/#+3Cw]«o^Ǐā8@twϷ[\e'ݯڷy\%3;($1l#By XS5 iy˲m+Y~c˻V2$ W+A@s90n~384LW2F30?տH05wHEQ2 IDAT|>~?^׋Iݙ־ʶn ,Z`„ lذgyÇTʡ={6G}4iw]"aBk^ PG8V8DM1̢Sɞr!B}A]Σ0#,X, {/̯pGw hvnxg94 # Fu-"7OrϮew1L.1(3{u fc I v"E5R,9HNnRur|_o;Vb*$v$A{CwZX>;|}lDbpɈZ 2:NfӰct/R)nvj?r+pKp郜xcwHәMZބRޛ8Ӳ6jnɌ ۗ>G#̸7n"9|CٸWTTD{{;˗/u(Zl6륿ؒ-(*@o:wj-ށfl2["d`eF2 Z[<^__G|^?<`vjh幷tkq^^|z3n߁ND foK<  |8dJA|Ǩj4-N-󏆎*u7p*X6 yd\Toio0/H?El7 {"E5˴T_/h4f\vڌd~{\TW nnJ"G:{^~qiav9-jnuiP"C220|ZoyϤ$ .QQTTT>700@uu5qqS9q8\3 Q(T@Fo{Db3{/~6eM|?X5(rqQw# '_|GJȾO --tp֩e t:-L%2c9FP\ :{xNz *LJBdQXxmHM]@gv4&4űhX*A[bЪlb-|E- qd!#XrRD.NrL"7CyfŞ)~~v;vco/HJJ˵ky×}S;g޽;vT+o -xV.﹣Ѓ_CAjZT5Lje&44vܹ!8x:)/ {|Խm(nav懞i|.N8a\NN.׽T]rrj4Q(cއ5X0TWщD"d2lY ~2zٳ'C R#F>u/(Z(){lYi&)MggׄB?th[dR-t3?tZ o_v4xٸ9-]n/zKgqt3iif""h4 TJLu_r\XK4oSȂET*E-L&r%_-[rK%]<"+ahM$RQQѴ 3.t$s~zdM=*%%` y zxJno h;=Of fST. z\n<W, zq,I62&T*2Zq`k*+{ٿ?X= ŀ,5IN'2qDBpeJKC}}]]N""0 ==3g.s{T_}Qg7ևFŪz^l\mde5o`˖`23-DE!Jht 9u8=&@+0}h`w7E`NUZ&|rshL_נ1d$ɢu`W^r||RI]]XY:^A*EͶm\B]]UU6Ξm"(HMR43˗_J%UɇVpJ+GR9wU҆  ԡ?$D7Ţ&?7)-̙F6n "3Bl^1qTõlLii'g6i!3Ӳ@ \( .J4fs2qqz̙Fm;C (~|;72V?mbhԥK-PXAyy/ۇ YFb<aaZRSM\i",L顮)+a`F#C!Ϟ'\.EWP^CII Xa?@ @0ElpyP ֐h`PPSc[q</V`@RR  @G۹z7:B"B:i/:vqv7*V@-.0룧y{6[t6;)/凉y^vf>ǑDK l$-͌ժC"Oii'ׯqV7N )|Zb0%{~~;55}DDh/h2@ @ eP5 ŭ[]vn' @ɤZTE&.NϪUf֭ dJ6v**z((2243(Rm`ݺ92(R´ddaCkb/ ɤB&禡._o#'˗iƍ*+{imcp:{ 뱡PH P` =L\RJG._on2PHg`$K1qf'T߲'@ @ %`pD#>^L&N*+{Q(hd >`hH>Yժ#5ڵ>ev]k*N^P(|FG)2mYHLnI˥ TcHI1ƍ6n Z`P"QVM~~0O7;ꥣÁ 뫹cr%z}ﯤNyy/yy؏OJ5st%$DCBaѤh@ 0L;Kßc/~9aazƍZH>-`_C{%\\BAwЏ4hGuPxj^}}47ϷTz#햠ɈWͦfS۫KݻR< RZFq9tNZ'*܃Lk繰xz衮Fss?==N:;=TUR)hT%"H?""|A- Fr(ÐL60^o 46ٳ R_O[#۷qc0z x<^\i:=k)"@ b{% yM^~~!6~4c֌ig~O̠ 5=Ed\ιs w_cz :b>8j)BBԤS]m7))餺.49r/nC&__LTk_ZE@Xnݍ梽NSS?uu6zQ[KS/sQQ;^V$8XCTU7d [$x}RIZ Ӱn]EE=Hvvmtrh uk())FF儳{%%kW-Μg˖֭ ZA@ &c yBb7c +GZXYhd]HpxWr\#uu}r,wY Z-#4TKH43O?Iuu/7ov ywqx-ny&T3J@OLV+G&! 㢭m>aze7;oC.V2+k#*JGhYV6r {w87Leeee]de5n] [rJlLz;ø|79yXAA1 @ )3 yB|s/7 *:^}5-] ;/^&9JX<@U*) +Vػ7>nhܹF ((h'yp 6|!B!E𥧶X$%ryp뤭NCC?6*+{F[սx$)0X, lV)Pe(cad2 *23-Xa⩧"nܹFnJ.\h"##L VEztص+;w8qUص+\@ !OC`4ؽ;P-VrTVPU/ǰq届?!HPe$'ٲ% 8v~2^ma23C]T*AT0|C--ڨQ_o~|ss[}4*BBDFa$i1U #J0IL4cG(W35?ʕfm eݺ@"#uݴZ9[ŋM?^Gj?@ `^KSSXx=zb'2ҏ kZv$ s՚2a] DžX''"_矖L~Vkʌމ=H3(o2}8;ֱn0aaCF;2eJ"#xVU»QU׾MjPd,[ODt3NsB-vqj {jU*h$d2jJ""\i頽Nc/Lyy/MM}45 pn%%\>'*ʏP-IF[TJ%3͛\QTѣ5dfys0II+ɤTR֮ b cjIM5)XpTV9] apܱ7fb-Kt51cAȤ/55e64lBx*Zjjlr4[`6+[`Æ  lhĉ:[8zvo'HI1Ʌe0 FF` Wm2tu9hl짺FCC6jkhn.g RcjFŋٺ543۷PQ˝;=de5i!3BJ;Bm6.]j&$DZ-\%0@ .ee,t3XFDUU0F $vQQ~kZٽ;-[գш.iѱvm N졢~:;tRTԁDj P egWcٹ36Νk>*'+t3[f&5Hf?:Vň8bx]@yy#Jޣd%o#O ΕW^#{PјǍ(|yqpHFιk\ˋY>tDg هcDÑ}hϸ2rт4,^/e /XZu|I%/6TVV֬ DSNFF*XwKO-A xhmZ_]]}ttV!Kje&t3>g~h>Ng͚@RSE 'ܽ[82/wK1:q:gsR)QOvOh':UʙJ&ۇ~GʋK^0,2e2 qq:Xbcu|q%ܢƾ}{VFjՏNl…&Nnƍ6ngO+Wh#XFHzP ˖q< H IDATeFjh觮*UUimS]m"Kݕ+wQPЎ\.rF}TјDXLs΍iT{oz{|ʡ: ~gQsLS#䥕SRoLZGnk^lә73Sdp*މE`plVkW(!!jF[^.1TlDB 3ǏדPXΝ!lL|A,+YH0`zjP<.ǽeGTVR[kɗݎz۽ݾ{jq8< @0UƠB\3'矽>fY5|L28'N>͔٨}5L^oqUUz/ q$DECY;x;TT$˗QTʈ!=LVV#O7RZMEE//]Ţ])rR"9fzuNo9RG&_Pޒ.۹s/%'43AZe&<\J%1^ ۷ILLԧkMB@ ļ7yj;o~?dhy{B Fk"F^dرtƫd}2Hh3==>:4 .KAF;vk9q?׾fe FPZFJ-kٳMPVFjQ),|Ayeh2f%:֮ pxhi /˗[(*̙F\ie26m "##V.ƃ`ָu+oycю69h*:~'x:hA* ƛcݏݏ=yGk"{PT؉Y[UN1^F~^gtt26,d TJYܟ@Z>ve0""D`{r֬1c͚NhʕV[-Lb/0V--r r^f#V@8۸v7:ѱiS`PH ` . -^phTN[g\PH'>09y5'tLB1ecKnnD1_eJ$f"":T͵k~}h4b`{Jn ")IONq?ڵ6ofV 11:j4kPH bYDII/pjowsNN5~} A$&1b@ б|q%/'֭ xikSTEmS7%%$']\/yS6dddM*0Ez6/8zcꩪ lb! @)6ܧl?L8˖sl3g4Q^KUWػ7u ш,6KBŢ& @ʕFv ʕ6._n IK3Dj +@0tv:q>::L%fsQRW_5BWLBLߌVR+:1Fx,2+tZ4.]45SU3τ'~RJb0 k֘9wsKLժ._nw^ -̈́p&zNNZ?V6qd#99mde5QRŦMALJ?ﲔHOβebbؼ9v._n.Ξm"/23IO7EB `.t,Ks]]N &2UONNGsF'^$O>$20y3+Ox,2GCa"0PIdG8s>{.-X,j1BWaC:֮5WtrH-ׯ֍ѡш%%KFF\ 7rf.NNN+7ntƍAl@L^d6@ Mr<8fr\]8tϷj',Lî]lL\VD"^' BDXR.mmmρaC3eN`)/))WKyyO=LlO2 z=df"'Gϙ3VƶmYc"4TR)ql$&ذN }0n8? X'@0 :VonNrR'6[#dJ%+TUjelO'v[%ᒞGBzz*9YNXL%5\VEz ՃJ%~@CZVFYvnl',òent ""@R^.BJyn$2CLP/:p@ 1\R:;k8}rw Rܹ3Ep7tvVqBҗ'M^]GCUU{TVvys:%aK!/0>\ʩS aD֭ ' @+15m9SW_ݥ۷tuDvm,օF&@0]o3x,K;Z=C[['_^}5qȳwrsJ jim#>SOE{w$))&4ِ~x<\nn.Énw]yxC=xp8hllqy[$yF}y1H]>v\nN'NÁ-Og17rz{Ѵ?rǏږ} '|xex~gNXz^~\LJLo{~;+Wm|i\Z-D"`6kر#-Ñ#\XrB5<ɬXaA)R &uY޽ \PW_ݥO?-%+cV+&1>@ ҏF#'8XLvռIii}V_VQSӃѨb&]KFF Ii˒pH$x}/J}XF{//( so{;v hT.%,LϾ}IddrtpZ=u.^a߾$M >,W NIj3wqj_}uk8wWX,]byXRRU#J `x<^ٜi J]ʪС~}?ʎ>$$"K,)bsUɔVٸ1vo |nJJZWgf-M\[+o cݺpÑ#ܼLYYgVٺJxR>/skj;ezVdϛN=Z7DF >ތϫnȑN,…jΜř3%=Į]lfeٲ ;^{>jLO3uf+RPSC_`?f}\X_ŋ813<8=R1g %e)**҇=ȃڷИKt_O'>̯]gW7VeK^s΍ 2F 55h#7Ggۜ?_EII 7G )kk1T83els&P(dx]\23#XV[$+۷()iС6ob8֬ #8B61;60^ @e(r8Z'=\QYYLta++Xj\>KhnZ*0F=?i}7ӧo۰X͏HH0?${_YǪt 3نih};g8rW뀕IOIN5cDo2(si&Tw2F٬| `X%=[աJ[Zw?'֟#Msl^ D]]/owtzF*|W^Id+zT*ٰ1ܽ;R?%<F%KE͇R8Mܙ0<;QCd ⫯y|Ų?oʇQ0Yǃ',bm8]eQ>:UM9\Ṕ)&ehJvsN31Fgs&m־xQ_5r)))~Wʻ4fټZ=anh/D%b2(Hj@#gز%ÇK9q=OߝefJxf: /Z,S*8u ~>mۢxy;j6-?|@ G^/mm8Q{sZ^JWY6^1K17,X{LWMDF;yv3GYYo PXL%K|[J;a6kع3+,Ñ#~ }t Բ|^9u=ձ<lh}{yX֬ ټZ_yv$SYIHZ>џ%oszryu[dWyC?Tg sHThYpIlAwk4 6n 4To#UIuuwۉ6Nw0@S9w2猧4&G&g߾$M8xґ|'xDM0QEf!(<ˋӹ?M& @/s\'Og-|I1W'پ=HbcMN?gGH-Ǒn;=ٜ=[a׮(^}a«e$"82Z[B4,Xz$&svnjo6+D'?ޱ/qqf _ydg/9|ǑCF^x8RV5k|m.^,Rzw޹JUUe&STx%(-c=7\UB`Nqh>:~4wͭǎy99Sz;^ ~P CMM7}voIh$K $%Q(d2 J%~aƖ W(;;<.n员>l[yx1MНDdLa.V>O>)O;YMK͘d?*L!NL&hh4 ҂6u>Ku3>m嗗;,D4=65=dǩ\D.6o:N,ZP(Vq',_n! @L&9O9S`1`9m=ZF{6Ekɤc0D5i`V+͜8qS*(,lƍ&>ۣyxV %0P+G@  KSS/_~YƯ]@AAMӃPexsƋ^3m`H |+6>]Oz6U]Nt_,mqXaaV+|RLnnoǥK5Hhn=2sRy[W_Oy9_L'|T@|ɤjٺաۗDVV%Ǐߡ?,ԩ ֯g86lj5ȅGa@ Xs\{{?gT_pB5*odp.^G&.p3MxB!cٲ u$$yrs멭W_M%%%B&Z-'%%H֯/dgR\BVV%'eK!!I,=R +7gO.p];\P͊g6+ft:0@ 3\.ǎ?:wؼ9 A%ktJ֯'11͛bN*/ͭgϞxKbPL&P`]{/)II "6\Z\Tŋ5\#ÇKhh%%%_O /ɸaSAae hVnƹ?ٲR#I6Nd?E.ٵGC.^V Y&RLg4%uQ"eٴ)@mС*կz;bxy_`A^X StʜXj=gn# i";G=V`Ŋ{_cs+WHK fǎl"%%Q=%i>>纎uyr/@0g/]]vΜtLs%o^4hD0Y\ ^L.}hۃ?ֹ  F{ >\o&7XŮ]fTu#5J,?g`6m_hn6; o߾$y&Ā^\t04:p:ݴqZ=11rJ׮sP ;wưsg iih˥޶jl1b)@ .{3Q={t1`czƓ\gJLg#iÃ{oZ56vҥ),YB\ϐ}"om^/.c[DF&t<22+iKkIe5+RhǨQ϶W?WMaa;wӣ\%{{[X2o;KyNlaɒO{4%-!!̙&󛨫o{/eʔHf͊cĈ`\qp ɣ4B"s~7_aÆx#?INN^^Nf[aɹ^N7 i +JyxssI_I~y-ڶ!*`ut}eՖ=?<O~æM5]&SP؛UR˓"W92z]_g[n>#Z~9EeMUa„p\"#/SlJ_6emlGRg_ȑ̟رoTTr=3&-[~Juu8;5F qSd|3 cW֨HwDTJ^҈I@ Zկط͛K)/A@++Vi 騇XMGÁw\g1-\*^ $5mtt*MMDG4ֶtr5AiӢ$&ƛ~v  QQーQBJ, ˜ȑr=:x̮]U@?a.3f~XWQgRtrdzr"Os);;6ũS|޽54o0{v< ../ 2+5^M7}+C(`@)=zJY >={s1cƄref ,(4obreXpu<&&훿_FFDo%ۨﺁڮII~_e/}23Kr= $$~]A u}ٖ(֕f bulcHM WYc*5%P &J e/(_MLŜ8ki"]RSPO@HO+'&Mm:@Ǟ=U׿>?@7T/[j >[[?L~6[o1mZ4׿NJĉf=JnphIM i@;ƿ@ [YΝEB/˗hQ2oSlJ)~ä#vL`>ktm #kinzzw}{9;wVRQaO~rի3j̀&3Luzf1ڵYƾ}[MI50ztK$zwy7/[b {\ +[BC=z~)\D^^#'NP_FGNz^<vu@ +]]8qMJ)(hFܹYl>4lda/aR_2)u E5e|s<..RY `s.妳vv6$&Mr?}tG+y0KJveL{1ؐAI˹Ş q{H'OPQqӧX8P|}U0ڗ-Tz|Z^Fjwa4Μ%/cǚϿɆ %=ΝNHx1t9b@ ^5MMwؽ[/tp-KeٲT}Tg\ K ,jkK^k-[Vv 9. ]+2 -<\X 0AOO~vo}k99Q2HG^MWbԾ?r3SD̿ˮ]5cG̞ǂdd栈Ś-C?﻽QWwΜ2AyJe8^C^m +W:F˯S'zv;cesG@ p~7/vyeɓNbժLrr ' eKMM1 Y/)Vl;ŵr%)lj4NNvJ( س[8~44dP_^7Dr*17ʩʬYq3iR$wWQX~w3gژ??^%1gg{}Xg:UbLʽgƴ]f%šQGO1#spHϻqf2mZ4LJ-͔~h9@ B~ز27rY"!Y 0¥Kǫ/IjK+0/6xg6X>]8KU-֮bԨ Mp;١:TUTVޤyyf99Qy jlObLŋ>S>Waf̈!--//apO kʮyeAZ9p  ˉٳOJ>.yg$3fľ`4_ '';RSdܸ0cZΟoZ…INPX `KD'!!Ni5rs9yz&OW " U(0<ĦM;wWW{-KeŊ ƌ AJ 0aE08qtcĈ`܈f:z>uu,[J\vv6+ Rȸq$%1yr$vUľ}u0}z K!n cƄhQ2ǎ5Dy K_̜Kvv(!!ClY<@0<}Kmmo`ǎ ::"&ƛի3Y8pqM 0a"zllTzreQQ^lPB~~M!Y.W^ Mhߕ ӧǐONN{pL۶qB˂̸qa0gN<ǎ5sH7ؽ'5*ٳ;6H/\\x7 uqNneo`֬8V`ҤR.DX#GFxnn @ Gz}H~~/~Ç$$0s+))ik;Õ+~=h~/0BC·%9u _…WY8~+uR;6OO'!$3hw %%ػC)+˵k*ʟ 5*gaq$ӧܺk9ӭ44tq*&2mZ4YY!p@ @p}e߾R._ ˖ųbE#FYMÇ2}zږCΝ+b1/חN xNv(EVKoo==tw?'O:.%%e;17h4d=ƅ}Pׇm8r;\EDDxPTxz:1iR$LgURP'so($aooKp;dgRUu&k\uLk2fL"T@ xʛlZWsCX<9s se ) JZ6;Dϱlmm;E|חp~urui66*\;7@m`*_VM`xpr]Ƕ &DȂ<‘# \cǎ e޼Ǝ #4gg;GpckfbΜiюEXnFQ̀JX=eLݔnL-ׅ bRmʨ;bvf!f<%ڬmg~ƶKV`FaժLƎ z6gL,IW u ؾJe92~^')>Ok(]}J9sk%|llYSee̙q= s`=ϷȔ)QLIB4R+seK;@  Nzz46vkW%~ZNsbbYO]m֬bU\ JÑP}7.={kϫ9YX(#ŋߌcc3GG; qgpJKqX3'OPVv!MWIOe@ iiU|Iuu)Vߙ@0 i +Jyxss։gcJRm sVߖ][# ͔2twwd$.]BL7^ͮ]U44tn]Z}O+U̥}m[--Jeبua$ںɉb׮*)=?dΜg]\\썒TՆ-y}>ꟿ-DFzs}~o@ P[{}j<9c92`wL8MRr@`9>|ʥKWٲ2Sƍ c f̈%0U|!mTuQ/mtt RhKUDRȽNߵR&2MJe&33@7|ٸk?R^~1Ir++w}3]{Ԅyti*+W쩢:_RPLEtVǺYl̳Ȕ5bJAn+5_5۫޽'x{)G4P^~[E03&3cYv:tl6S2O9BC}>"Gp}gRJKĚ5v:"p@0 .Ĥ}wcc7DGp]ccQ] sQ΂\eRewԷw~;86n,`O'9xɩ+Gs*] Um֭b0zJKqp=oBNNf5.0<;LQ rHĐp~w fqLMo_ -k|%&O$6ۨ1Irs‡@  N{)/me|E ׮'==+2??PY M"m^PEED~˳@ ݽ/wg?%dbmzSFwo Ǐ7cGϷ(*j'55WW{sa0Yjtxrcބy0iR$7|{ر&Z[}K!1яӧDZZ~~Z3B CO{d*v쨠QQ^v:K$p2-\\#ա%rYRAS[?~}1y,\Keh3^+LYh rc޼F&7]*Vpa,ѣv],ݗ0lRGK?gbooKx'==tv>bkĉf*+o93ߞ͜9B@Ak6%_@ 4bka g^abQ3eJ$kdx{;@` K ,jkK^_4RMVڷ;馇q t%>ޗp yyM46vtҺE[{F0vX髓1YrBDEybE:cƄ?FJKܹy43uQsXZ[m1S?Rʑۗu=lmmwehF a޼rs9~[|I9'N0vl3f>TSu5vYØuVkhoǗ_ֲqc)UU7 vg$|3턠,JV˻|*Z4 F7y۔c  K b^8_SSF{Nnrca#%V?J[_m4|wFx3g/n j1΍i2ٞ@4){k8pbb1qb%s}]1똔{όi-X3|c66*%%ş_O̙ҥUɱcM,X!ĉjoPYd\݆dD e?[\fZ3bD03^E8Ƶ J*?b0s 1&.՗^:^]}Ig:}CEۙs `Æe۶2X6cu_-xO<<0!D?L/jmdϞj ۙ1#ŋ1"GqoFcc󬿥ԩќ;wCxVΟo'5՟3ɉ"!G1n~Dnn#\LQQ;0 IDATnnV+V3jT.."ܳa׾dTԧ|{]k YSy)鞗%E#)yK96.P78:1j3 II~lTٳm\r.,I!&F8"B8 ٳ b„>v6o.9s7/$?1 DEym$?RZz?&''3bHOI<@ݽbJvX…I{ EbC򤿢6")yʽ~>c꭯}[\ .FEdkdƍ7_ƌ  { cggCD'o+U^6NpaӧR)@.DDxNvv(sƓıcMTWߢ&1yr$Ӧ0rd0ۋ'wt{œc8;P\|_4Ǐ_f RR\quJWøq=xzzpꔚlTѣAvN؈Ɋ@Q̟".Λ{<:Nl *ʙ1ct; vӧ%7;+))Ƒ#wrŁ#3'8섰IWҥ6rT+ wioCU-'0mZ x{;f-ކJ : 99=2k)YŬYqEe42B;Wرc^:/e-癢b蘡-ERgl~r'WVejzzztwwI7]]]C¥w}"'FoKIpΆd?/ILe.\tU2HN[{{[bc}vgԨ:**nRSs3gX8)S" QehGTaaLVnPZz:5ib1"W}PۢHWXH):>-5j0, MΤD@bUd()!*uY{)MWRojXOCȘRdcLT9ymM5͛9r͛Kx*NNvfVepdHYT*jم!z0DR¢EDEy?-źu#4)Bx@\\5*g]{Xf2uj4o+"aggC`ӧ0jTf(/G]:&Md֬8Ǝ #(̈́JWRS?S-4&ntrȹoRkJƆ#5fcrRfjXU[n1}ǘon9 ^^jjn}{9;vT VK) CL sKCnYMhϒ2RNNvdgJL7۶qH--wY" v@+g}cleW0 /lXHQQ;g3~YYAxx8ʶyKi6ru]nU SK똔zjSZ_SF]eSƴݑ 1#SZo…i JSMJ.3n2뙼Al_+[y7vs'KsXFo|y5۶QWwpO|3ŋEK`` .ҳϕ'T/""9)ΔyAm u ]`A"?TV+Iܾ>_ , ,_L ==N~sl|jcCI qRpq'%şի30|:7c.f/֔^:mF]&#BV*u?r?-|2sʜe2,)΃ݜ:ʿk|p.&L?»!%_([aŋR)R8f2LC'Ws+*Z͔)Q+QʓVrRa(M)6\C6*Ø:cd!J7\הC՟Zڵ:Tφ %]ÑNg͚LED`1}45UTKk-ڔu{ACX5oNN39]%W.alͰpuM}eiM7ֶD>˖͆ %8Pdž %@La:Z/s 8KAA+ &1uj„X0h&>Ƥ뿗[ɣyNS  OPUu[/{wo?"55+3??Py8닮:B›꼵$md ձ5GR'ɘ{bLŰp EjP[El7}tV~"fM&#G$V=DFz_p@'OP\|Hx#q tJ3̱ pO/c]]9vK9{ {{[/Nf ƌ Qj)]2ҕ2 S?S('_9eI .RL 5OO'fΌ#4ԃ-[.kW%;vTՙZl9+a2eJwW\xcX4#p_3$A>K ui()]_C뫛!yɭ)a-uI%yFɐSolXK)i޽'qc G6i/'Gg6({] HbHYtvvC E0V .·Kkw@CC'Ǝ Aʰ!4ԃE5*#Gص|a!Mz"g덣d 7חΐC45rp'Ք{d{aj mmwj>= )w@ ŐpJOwYLpYY>W jy qX{TRR̙>ぷbń{PXxPV݅LIz>>ڊ{(^Ri %䰖¢E0Ա9uwGuq]>%>ޅƍܼ)ߖ 7;W$*0BC·%9u fXiX!_~Y\|}$% "X+jwSRr/Fr.?,yf ,g3r󗊱!/"e 6W]1޾u!yy_ŋqqq7X* \\D Kq^OA|O.#oعsE; ejzzztwwI7]]]C¥w}" FoKN(0dZE@+oJT6pH}t۬[Ŕ)Qxxֈ oogL"%ş(vر&o/+̜'"Э8ۚ y,RdY C^ncG{Ts=X*I ) JZ6;DWW&O$,̃$?>FZ[v]^=P1bK`sēɑ[Maa;ENneD̉'!'''\B[1CH GdhH)m0%ģ\9SJr(Nr*qc Zb ZQ1wnۋcۂ3|hGD$Zұ>m@RwOpafU Ʊ#1::/kٴ|y"+V = $)[+CE|\ѡ/]C>$%.QQ)47WJw]zc'}-76E#:]c&kPLQ()C)ʏIKnkkCl3?2).կՙf.}TI9җM}?3cIOԩVVgeÆΞmpPB\S׽56ǖ@ <~ٶ{s1#GfM3g& $3u;DLC_y87E$Ɛpijx)Դѩ/aEbCJR rե ѶВ(+Ej܋Ncro__?~JEMm+sS;$n~3666Z斓}Ttrd##vg|{o{#GcѢ$T*?<.K)e e{n86$7KO yq5iS)EE8;۱lY*Wg2bD,dеG EJY(a"aE񘘴onl,e"eQ- y(x45u*þ \eII3J 第 .lY*z DdZshFn&Od DG/,Y?S۫FRۤ(A,< >\@^oueڵre%]*HU\Sd:.E)q[wR-E6Qoh({Awll: eV1P[.,S-W'~Ku?,n\]$eNۗ-5,a77F {9t#G(+L"/#`2M&By!F'?̦M:,y X΄ xy9 A _/n8Vs\}Ns]:]u)<\ A_.Ň5/66冾- TW_&8؝]~ۂ-"m[s&f{hl1`n9H>ɉ"%şI"ٹSZ {(3g2o^AM(]@0e IDATXUr={ز2DG{[i,^Ll,PDK ՏpZmwt.ϤDZ\MgE;L1i1lBIےG?zK8~ovaj_ uUj|ب rcD.̇/C^DAA+ &<~܃Q @ σ\tMJ9x4)u벘6-ooO  %!!XzbϿr]VJ`[lGā,[Jl76x|A={{84grːĔVy%@gpl5sO?- P- c(poEXFpW8P֭e_ׅ7[o(= ,0 `x1,-\jjIHz|MMI )VMq+rGpJ[< WWt)}FcojSNp;11lZFnn#cKx$< ({LJI̘K..ddr^>7ٳ((hSD{w9ƅjޚL1+|{j:;ʕ̛@p,aaR]}՗tv@0ذ!6֛FŜ?6+Wf3XPT;J\'Gg?̞=Uk,YBff „Z C FCg#bqpe$֮";;77!(@`  X>L|}]X0(/l̾}5lr۬]k,~~.̜Gzz -SͩSlXʅ ̞Ϝ9$&R%`GM}}';wV}{mmwIH孷X hoDg@`= .qr#;;w}ټ2g^]f^ڊI`ΆO.Meg߾ZRSsǛY c86{™3mlTJ^^#jibַF0iRVp 66*""'Oᇅ44tn]Fb/5pp%1яPƏϫ9x :A~~˖2eJ$AAnB&ACo+W5lTJMmBBY4eRILA{ɐpf9A#ӧ͗ٵݻhjb͚,fώ# U|%90jT11L;}5=ȱcM`,IfԨ3A@ X5tsB۶}yܸ0VdƌX]|E X5C%++O?e1ees^уZȑ=xCaa55W9|؛/œJoc{tys1GT^DD8d#&@ 9JWWwxx4P\$5D=h~NZ+n0tǐbIf|]Bgn^K9|{;i ^ZZU\x#Gq3sD0{v"Z@ 'Oz(/Ann_~[=deres&!,40e42B;Wرc^:/@QZzzz~Jww7Ot5t,\JJxw,V~Ē% ?nnLIh^|I9G4vu벘7/`w1Ch;cdž嗵|E שm,^ɑco/ h4n~ĉͬ__™3m8:ڲti +Vd0zt,W]@OZFQ Z)O<\v]B'B@54~>绊=bJ=j5{zӧ<}n<"tҌgm׎o?޿sgt2,\T*j샰C<C ;;}w|P*IMQnqv'##(/&Od߾Zر&JK1qb%3aB8B&<YAK]bbyt/NED)2*b[1uS=̤D}Y[Yn蜿+'ɦM_|zh&c4G_lPi:I)WJ޿.NL)@8̽{47`˖|o`A"bC͔wJ߼-<=@ h4gؼ2yy<}fƌVdH1@0hr>\M#"hm~X_w_Ta#cJM ?Snx@nn#חPTԎ3Ve[i@`Y͎?#  c{?$$2JL i Js+\t- pu...Z124uMr++w}-YYA#2ҋޥ67Hl$0V^Yl̳sj5]]ɉbƌ"6v&7n279zCFTfJ)ߐ%%)23Y(':)Ë^o}{9;wVrY: 'O̭W_8~ [;an]cbҾFCcc9ѩ/\ErJCţ錭T.uQ+:+ӟllTDFzg6-ӧ~TW"z@%Ӛ )XJe(NSNlaϞjNl2y」̝rnlk}V1ƎA9+JO䤕zNpR?w>?~EYsY&qpwwHMIKʖ\rF2&J e/(_ʈMxs毊.n0vhm,uڿ<=~>>dj +;7Wƀ`ڏnkkCp;ox@23/2gNU_󟟢.˗6eKs+KoS2qwyGuy7uzH lL17 L3`'&c{$Ndyb$ c2EPUԅ4< FSsh|?Hs)yNP hhak۲#'׶JK>`d˗' 8x ]Okpa BBy91=ڿ[h aX(#[Kz† YP(I{E=ICXL ڦ܋GRf)F8?7~1c24 C1wϒR8.aN&9]\Fc XңBgN&!%Klgbs1hMK|X/T'|d$ AƮ1|E JcÆ,lݚpxyф Id\<^AmE9Z[,r6cFR]]2zuux1D0_<$&~Zr44 {ߛ;ìY^ۅɤ YX СjTUw;oi⮻U L{ iiز%k֤!:zhc\pw7s17eA3]2c<\16X((Fx/;8~ز%=Hdtq%<IyHNVs:gQ_ߏ͛Nk]p G58z_|рnXu20o^$ۉ b1hj~ Ty11 X2aX<|M ߶c4<@*22Bn_HJ'c6Ra5ccj\؉2|Yj-ǦMX<l'R.fsxS!xz0o^$""|{+pl;چ8BBBvAܤÚ5i Ǘ_6+(--NlHA89޽F`6mƦM ̙Jc9A.ᒛ\9D- 8՞˽PY9$woxzŕdv!_;@fps_E AS8s"! +Vaatu} q8zwjN䗢7Pzɾ yMr{ؓUЈH2A $v_5?ތ/(#vc-X ꥡ1#GaŊ`Y-#t< On.0jujuP5PPK0 $0fT*[YeWJ俓E`©:3at:0Z-t:4 4*j5Gx2w}zFGկt2.eex2YcYo֯A " >!(**CII'ۇQSӇW ##r)H$ĝw!##wݕ믛Q\܎KڵP(N8 P[{w  Ji=8ZL g'^tw7r R. \Jja!TH?lؐ@ȑzwWsxq,(IWMp_w_ 0yg>wo+mX& ݗ`:ъ  pT+v.ʼn-`+W&ayg#d 55J.4\|p=\MbcZ=d&7w1g1ц%[o̅ɤHN?*ŋx lΧX#3JH5lzzʐ9X |RÇpD ʺ7X~zh>t:RĂqpF@2(8lmgYHwtBz pa4oÊt3A\%..c \biib3+ِ2cLׁ6썵k={'mr|y]^3]y`Ѣ`xWph#>+'[ndU˄k \-Tږ5ZfsmkZ â{ף ee] ؼ9ᴴ B GYY 6AseϹzse݇rL [b`lB™0_ˍkI6k&bꐋ0?.zs`|峤E 6%GAA4"#g-ĉ-hiB]]?^zi-h˽ĮKc6OW0(YR>ju|qx䑝8ue8s 7g[43>2X2p g.tLM-]4j'W} k.rYSBې9Ìmo#LLhQUՃw߭ćV E6mRS=N#JݵmpijdֈbkBu0TX.KL/1>׼P%]kjok= mnnR$$bǎ<<6}/qx3^z|r7|2yyĮKK=1'U1C ,B38tWG? (PmӲ44Yoh$#&}r8B7-tc(жWwa|DZcMؽ~OO֬IǶm7/t3AXt:^;D.u*}^Z.fͅchm<2pI ׼k[ge˛Xq=4g?[@wm1qFo.XBpeJ|C\SO݃> . oLd&z01'viCGeЏw*: lؐkӑ{&p\I,bczCCObb֍kY7> S;r$ɍ3N6yT"ǯ-Pg ?m`# 6n_OpJZfZճ3cg~~7/;vᡇ2l\mV|64Ɩ[` -o&j۳뇘y MرF[tw_, 2qW1-:F+VBukmآΌ#}a.WL_:& qٞeTYز%cϞr;ք_3^OcEs{^,WR 䢾hcXŜaOcdcLn*r);_} P?^F\0%#ꐘt ZZ\{U*|裙xLqa}:Oљ08EH|[A( IDAT_Ϟ5b\phZEl?RS_'Ԣq;vR+~7|#B嶗M릎H{G- FHX.sIR\jX|UBS 6ꎘ\AII'uۢys6VJ>t3Ap4X' |rMs|N3$?ø0Ls"N82a oS;{&?\ HN tdr=}3'pХ>(*:ݻKQZڅ^;~lْ`nv͘.s\šWȦ`톸bh mXap@#AcϞrwc,[-[& Aqu\Y%a)B?KƷԑd\jjJ{R,;|n+ÆK|~Ē{uZ%&֔QHm|d#X}L }I5 ۥ]KfO 0)?-X}Unuꖵc{ƛ鎰-jWbJW3xw_ gm+X''WZ)׫KLƛ|=6b-""!طס[O/A mؽ|\(( AGbS:InCavdR{ΝKpa gki\J%EA3A]]?ع+=ڈp_ᥗcx2Â%(&jE} 9(? "LC" $kצ#!!EEnslY<UҥxcF6nT +k6<*decl^Y|9r+V,yMc-]+.>S#e7`iVkVR100p#p)+O?e_Yśo멡"JW &[ oƟ| ؾ=GLJNl  e100ǛgO9NnT*`\,\Y'A3AS+2YxL׮i{w)~FD-AT2wO%n+:ӸhOÅ>@b6={ʱsxySs_.թ 6N6l3?qN>yZ k#leS /2r0SYzsљ. 3]H?c =ڈ!lߞLCdݗ9k Aآ+RiQYك}*^А ؼ9ܓL=BM"fQ>-n?͗?b'7֚%K -10 R!LgrcM]7%501ue"i{szs`|峤E mTL=2Ȯ/z׿^ŋ?PxxȬnomNwک㑐X%kض01> 9}&,,ر&Ss:ᆇmr1wn(D؄]5sSa]i5q oʠb*[g̸%uc\F4ū#2t 61l]Ր`*qc/\ E\=qZ~kVz׮3 wDF.D 63}}-x,V(/DιTچV!X%˵#gt6V3F/.m))ز%k֤#.Ο{&;cln85.qKxKZ#4ҴT|GbMs-]bew1h.)qŐ'OV%5ۻ=s)JCڕq((p =S_'Z,_r>r[bַ~"Y;.rٱ-{c5#|-s#CC8} {\W"`$SLj_B۲uc }v8?~~lߞxyɝ=^}0sN\eKKuKzit:mm?`߾ #:qAjj0gBr觥աq)#\ w6ؿ: 9wuW' i,;Z+Wzwoy;va$zO =;[sv{J^ꖼK8׮ip{V06ƢE1ز%+W& D12{ole7bixbԁ9؊\{; .))9גQWW.bƳDB;Y覘|lQ\_ȜP䌓aww7(a1y%\ceBO!aE}=.eeӾ.f9-uC ð_4%%Ė-9ؼ9abP  k* |4MsoWxd rշ5ǧcMhlBbbR[[v˽\֖`/qsu \iɰNojWdZ^[3cy2;ք7<>H<9bOcuhꞳyC6k1? 5(Xc9C_}>;A8ZTTtG5Cvv6m"2ҏ{& s׸" tp]kt7.Wc L~~`cŋEޯ)Ejj-jjJymhnr绐r1 M&Bj-Tg|w!rb11%mۺOcٲ#==[Ç1 ض-k֤!"deՑLLB'n=nwB8qG6~//9|0 ۶ۢN"e1w`Klŋ.8p .%f_ WW A(iixHN[o%v:lڤ@flؐpZjCBѡ%8P$'aÆ,]@dt3A7:Pox3cRAmU ڵ鈉ݥ8|w;v;NI_\'A8cV̙6f=$'rhQ =hc\ gFx3 l F#"ii!ؿ_݄!<e .c G* 1㣏jgO9jk""6dG3" fB77)Ejj0~N7΢*x"sF)A3k4()ľ}z M`(lߞG=A@\åccl4oj91 ½&#:zV.iO=5wݕ /z&0 Q>\}*PR =oܨ@NN( x*pA).7W#GQ "zƼyT8zTSQ[ҥX8ps# A0hiW_ !h0(. zW=.jzszbz# ;0|BtB\(-p'V 8yo]'[B}{n- >>t'A+,'R=; \GX ~~H<8rVX e2_K׊ϣ`LBt,˜ `Z:Zjj*RVV~.5eoaz '; 8p |p}T!ؑ{M>Mh x*44#))6)C maoun9xXƼALa*oc,|t5]gť<\$ ::41ww7(1{mHK FaaJJ:'P_ߏHM p iȈ ~ہݻKqX4.ǎyX,$pA [cl0 [d 5->S>:3tJ H$vo^Bd<ҳθ'<<QFs -9 em*TNdJ`Y&m[Iu&kr+@RR)Ge, 1._Ejj0r7ޓ0q*h P]ΈFCmU8PF͛n]bcɫ R]]bvd꾥xANN%ƍ $%b2=ڈ7<>lۖ;}B1u244KK|&dp7eD3k~TY ǔLk188'[PTT'[Uغ5w  B̌*uǒ%񈊚`nGS mŚ5if+&&Y2LpIs$9ÃPgӕT $tWW\O}i3b7t طdž Yx9HI AHA|1{=JdR#99oU ص4, &OZMM:' M;&/Fی/׸A̅Wc ۍS.dBSEE8|Z,Zmrreg ll#f&B} BBvm:bb{w)ݥBkI^+k yqm̀aXtuQTTnzaÆ,lؐ" 2RAa3\åccl4oj9A //9.FD/B6c`*. Τ+kXCIC.p~&&ƻVСj]Cvvl "6%==M7~gZ:Zjj*Xb)ð`٩a~W5PTCWW)]X~iǹoZQÃ*{ 5+W%`ɽ XͿ/(=7_7at:0Z-t:4 4*j5Gx2w}zFGկĊK'ݟz俖GA)ųx*pAu\9DAv%1QAYɱ5c]dT\x`MyL-v򉑞F`xXq;**FTղcQ/rs>-mft(=kd_'Eo^Ӥ8䫯>a_{uxxg qqq#BUe(+eM4"awZ|6 -'k?/.u))Aذ! kצ#!!2EN̑#0]<\ؘøp'Ov1 IDAT,dr7$c([xAS<\i/V"tuuɹ7 */8.eex˲xͷ~= A؟0axg s pt+ WMH$lݚEbIJ"%`##j44 .:Չ˗0<X<yK ,wIR{H$0 csut(A ,AA{0=娫Yx9xLqA \|'OvnB!< "9 _X?xz yt::H$7/!]cqÖeMC1䱔,|a;{W>!{~J|I-4X(۷a: `|\ r%%8uJsz: 77 0o^n-11rrs [KyƦd7bhI3`Xfkt`o݉%tk+f]:*ALaX(#:[y`FnAv6L熇UhnJ?ށ> +G~~. âEak} p0;3+Mrm:+A6gԏ1 qQz2֝Fdt!bRiQYك+GVllܨiE= 31BYY::@NN<<]|}}t*NRN `|\ٳp1X8":^^njPTWT-/E!H΅yVPW^N%# y * UP*;"ˢ|.?͗?DGI#}Ɩ7XUrLgV/ҵ$˞7W^k+9ԉX˘2Nm!Pc>b|$ALeYf]3g#ǣfbFϏ;) \oyZtt4^zMr,q-FPR҃nCqq'1Igcٲhdg!(Rm Wѫhl{'wPYQsu|Mx7uZTT$y懈2ϥ=\.M9i2 hjLFc^p4d0֔ĔA^I%F~(#v(D!&TlXW1A1F~{f ['rmJzk:i]qGG4% sqMT8kaڎjaIOEEepAYYϏE3h 8p uuW ~$'A&# n"0o\̛7foa_%jj1:;#˗G#??A"j t:,ˑ17seLo<2 yswsq*r}11.A9'+0<™3mطG6BalݚKELLhT'NtY%,|jU 3􆻻TMpÌÅ  ˳e0,چpP )GmU`͚tlܨ@ff(<W5Ċ~1_BM=.jz9cY zzԨGPWw ZK灬,_dg">5]howvRJZ=ٗY>/.W~C#"AAĔ 04H !udZRA?w,ĽÇnjj9ſNEA[1PnuA alLwqG0_ <]{L cZJbR0 #ZzQW,AY՟R4gpc:V NFJZ >D-^y |*«_+Ntbxah:tZh:jTj KYY%~)hϲ,|-  'I01ᅾpF@BB:O1HrOqo {ojjw|T*^GEE?s=hi˲((EF/B*в!3."H tGZAA:FG`Y)fJ_\L9> c5=\&ò,4hm 8} ee})pa??>euy,r)E6b,^\y MKkɓ7&{ֿ܆,^\ <Ұ7>vjX*Ҙ(F~B3Bex:{L ćeؘd2 =[ oQHt4*A{XduuC8}'Ovʕ~h0k; fcH,X0qq>eu-!C !Ř%66Zc[H:󋴽&h޺ [[,Qc{66bƸ)fL'ejv&Fpe'ćav;0h4r`]E^-ApFL>QTV^ũS8{ CjYcPP DEiC䠺 =\2c ÷\=66lp։3Y&Nd0{[%g;^\<\Q??fzS/, hr ' ÁHt!4T ?!ь ~p@vQQP*z0R,^wݵ_sL&Er? °dI$22 L2ecTWDRDD"5;2wwJG 9+2󜱣RPYYP(,.sc&knl4g8qҿs룩.\Ù0 ύf'Kk!se1'#:kWZ1ک-:4Gս5Fc1x&f[# oBK1巶_ن}f:KDFq/j<=!4Tnxz^# a%99 ? q[455O|18{QXJQPoEHL􃟟R,zWys?QOpPq-42 y1 :;n\3QQQ&㹼KS%$$dZH:Nhl2fjbXXS/&O\^\b2rmBdbhN։5El+K:3f6̥c*-z2ړ=e.4wb=%[7Hbx<$fn&nrY@(F ~̞݁4dh!ByDFF/} `7?Ѿ8wuzft!=TZ9Op_ b{3"{٨0kpᓮ&:y;b ߺs_m29-~1{K)ӄ㞵=JqA=\Oț[R) q_|SΒBEGXr]~mgZb%Eߓ}^rr6 /Úx4И^G g\$m]nkb{YosC^b8u79={W[e">`GS$ăa2mmI( _a2!:<\n4|SS *+on!\Z9y1z/".IYτQ(<& s2*_v¤%66&^xQE"vpF-555eo5][L,M %,חsnq]s' KrY2kRnlYoB`jsP[!U%kcj1b1Υز_kSQvqσ!?${&.pQ5x⥗oohsy葻cNj/^Ew[-Ɩm/2\!˱텟pov?~2̡+Nr9Yho?L&N5<\$_} kpF@BC;g l/k<<іeF\\ ZZP^^nآgΟ`-+ 70 Zt:-ZwR100+a0 kt0fT*[Yj5Va1HRM.z[E`©: 0t`Zt:h4hT*j!je0(˲h4+/CW[+¢T:%FµQx+bIan;˲(.>oh4TV^BkkPdB*m/!!V]G/~s?jiioT*5^|y{TW𺧿f.M  WBad==Q J؇ٳ;g 1=.\ą 'rdG[ '"LHͻiDa///ٷ1N)"  ߝ W7> Dhh' A.BXj5v))p(U(--xU //GBAgh9xtRBOO$àӹwaa\& 9> /c^vh2"?AAq}}hiIA__$$CppBÅ c <:U"h~M-  i H06懎x%at4cjDttF=>?[91 t:^1唢_~Q4 rsCAĴeYPU5#GQY9 \slY 22|F" 8u,^xPռuvvkuJ=Yj  Ac>~Xq$$dzsLJ"¡9rȮδc5s#֟Jd#^Z KDww(JQkn[hJUrW>eS>ғG1m^!y˝yP<(OO|}?S#B2!Ջ8G=_hkBB!D׷=-9Z.nd:rSrO"s!6(*wtU-"TҮ4SH!Չ(p8|/O㡇ۓ7vwadf IDATL:B)!13gdFi*m8t>۽&VTB*>ʤ*ZW:P-)3Mj`0''̌[/•WnAww=4%T/!LLLwa~NN| 4wtbAh*ߩ15 {{6r\_AG099v ]>z΅ .qQo:t>߁i7Ӊro|:wץ+_cLn$BnKuT\D)7&v-v(ObGg$SRtmRJNy(+v糥}Qr#ߍAOzny]ԍz EjO[&&Ǻoޅ>( c?+H[q]ξoi<|Ziߖ.|ί;s,~LMMǏuuu;\%q˨g;oğ8{3Gt x5Lɽ.ӵ[^y7;/S\[\P*??rʕ*ZzGE< |s>z?0B>>|n\~z&nL }w)ύch.p/ Cb.Ï13>Sue+ɃCi7;1#y`wLOϤ<711#Gb``{4JrE .6 )EL9 j9sپUySb}.vRjXZ^qH6Sjqɉ1K4*bjj #ѣYn-03!vx~||KNUpqLMf)xYɩ,'3 .##empIDrҐRbb!݇Qt+gCx  \wv|n =Bj={N)wA[Of;׏ ;v|ݘ?}{zno׮twwb|8=ضmk{o!Up9yrhuoɓCE1R 6vkuwt !WDRXS%!Ʃ-vJum$TH}鞃t۬gjT)4R% ^D# 'z=>7ѨŵnM7tbPBHR46v==[V_L#E<3%3~s!ᰈ~ !p%?᷿=HCB/[]>ӛͿ+<0)\>SjAed(cdy甦j?F$BH,. oG7YB4Wn P/ KYsdeq%dDَ[ ;h4p8H$p8`0`0ArhѨPΕh4`0Ax1==xz]J}5;KQw=8fFD"ÈD"B  kw|^3GN]K&>=;z޹3_u<~{6_.ٟm0t4!RԴۻޓ|wydc]RN AmTmY~x,2PTZj3JםAȑY<<18~l؄o܅kن:h4jBaJቓ .}}2Nҝ9PJO2)2Vdr)]v}ڼ!.\.?^}x]8z b3nq7.Br 044Itvv`04L߅crؼkZwpLMށ;wA=vAG099v Z{w6xY 7,E\ܹߞuj­ ٝ!{CoXӹȽ.]KMjtPLgo.B꒩RnLrZ2(OQ|'鞑Lm_W z&rɥ{QW2r}oyMHi 8sƅ;8{֍ g W]5BBɅַn|wa<J<֮nrߢ?sm8Vڷ _h-{Μ9SSc]]ί+}{ (088={v+"^y{ǝw%?0=<O!BJ0LMiq:D"@WW;wHB!򘞞.\sU!Fa+\b bkB!,DϧĄΙvka0~"`6 pi'B!'W%]sUB!$0{ύtBػ׆kn7@vτB)=ZB!Ն(x=ժç?݃Ν6LB!|p$B!5ʻ0xVQ>-[pU=hiqA\ujkk!BH m֯cDGtumE$"1B!OABlb3gUHDJՅ'8~SS~ttpw@'=Wc}׭ہcFW]Ջ `0hj* }}yv /b~>q/FF<pwNF]FttaFO$´`a`0hө^"B .BHذa`) B'N,gF_M c_܆Vc {4a׮F"|0p:LMq^LO13ؘO/"kP_n@k ==f[cAK6f" !RB(B!bEAxQVW^ك+ݳJVV 45n](B(| `l̋IƼDqNZ(JI"L{ &YgE[$X,ڸ+R-#Q$eH B!"Ck*- 8sf ?8^zi==\}u/>.b܀MVɤn@ FK+aff0ccLOppN\@4  jl47 cAk&45`6kөA !7M@!r;8S#x-Dpu}fhT*t:t:5,-XA afƏi?&'}8w΃Q/ /P$W&U3o݀z=f zM ^kQ$e>on !BF8Ą$ùstvOuuBޠxEZuhm5a&I xBp:01Ȉ>LOt 8~|G"LSӌuCZS_sGcB!)B!144:_A ޽v\{m>V469/0mm&l*Wxa ##^LL03ܜi?tAUl֢Afzz,鱠WňHܞB\} Nٳ6*ڮR- CVbfӣӌ^ -4݌fV-EB!kdKd~ i'1|+_^{mUBH5ahqǻpmhi1rb^j   %e6I "X\ av6sIr8pN,4wFăZ,Zj0Bjآ׌8pॴݘ%^gO[خG r>N/wܱvSMo\$0 ztwJqw09ٳK`f&Y?FF[oY;X8>Fh4ck ciI ;9'w~^ؘËE@UjաÄ,aa׫"$Qg-9.. n1ү2OOz|[R($Аh+BQPƉAu& r'K<- 'p*h*h+QsV zXXbnNǁ$MMq'N,@W 2cݺ:tuiFk$˜HJ0}{GBH]!LpoI9QldkS-\&GWDIa֯w$H>y1:* 1ssFF8uj>Nzׂ.3-D=L&)(Fط=S&dHN6!AVJ#UɵI˩;gze3[(Vl(7\˱e6vφLϰk._2 .v*Uݛ1>~2tԺ7=W,{k- !J [6Kv8+ƶ]ᰈ`Pڞ bv֏i?FF8w΃I N\ѣnՀѨECmm&tu# 0f44H1aZu.`dz~172*/8_;iL6Ss=. (J=/J\ĹL.eJ3/HJp~?єS +O>()l two؉(z˻%Hr~cc'ږjS"/oДBҮ8DZ%e˖z"Bpp8bdăI?fg!ԒԤGsݒ;RoE'(5|o.e#CXUJ1߶ʔo!m{~)o閲|ě\s%S4ӕIgXnJRDEK~j&SŖe_K!""|0<0!$$WQEU}پBr++at4CEB"!' ƼƷa~>i} ZYPr%VBEiauQ=$'\-]>+7RQ2|XL)D u)nJN?o.cצGΪޭ=ޭ睏;;ӳesԶʥ1d*sQ~gKR]J4 D"+/};rvt p8p8"4HKj1Mwkr_-UkuK!ΧOJ__h\).iӉ_3墋._7_]F+-"$_Li;w4)!*C;w3Bl"MeWBHJRss W,,KϯZ Z45IA<ho7ň#vnv'D 0^}>zcc^coJ+dTg:k܇t曎r}>"ke^/(V_Rn{j'mUHϷR\(ɧo2 .r㭼k9ʐJVD߿}-[H.OxeSrky*ծ5Qei) KB.?OKKRܕP( QD؎+z__&= hm5̈́fZu0055jUP!J-:8%ӄ/}i+wVRބjb\'_";tid:8{[CJL%LoOY|'@\nݎUedB&v%d*p᰸ b~^\NSW祕*>_P4_%c2iРnn@s45bDS:X: U B/GpWASw '{?2B֒LT.E[Uҝt]@֯߉3g̙#XnΜ9R%X9G();-7+ IDATtfJ')OuŲ+!kATIt ~RyITYSn7fӣaOctfӣNQNG ![x@[vnFl!BJ&wQp>^x1zy!/嬮3G$N3]-r-Uҝ7\-J+!$D"+?`^o(Pfg锂z:n@vJbbOЍBH5.E)h+BDQE"$J1Tc?6KKOlN ^ Y.s| fiןVITilZ x,/e܈(jB)\("V1WR08*332?S%@QD\ 46[)jl`VPTY4r>t#"R$ ~+1؁/app Mk\gVe+!J,b(Ï9J`0hTCZ  t볠рF=W65X,r !$p#I!$ٳ;.Bdgٿ;mU(F6P(% VB Vij jLZX`(sBQ4܍BH-PKў=9Mh+B(E KAj*a,,H;v p+t:5F ,-hhСň6SB# Y6Rl!RPp!$B>ReiIgv֏핥*"D$QE  f-thhZ[ho7n7IMUIR+*T!R$x&&xZp-p[!T5\!$dAXvKS03#VqXXp8O`h~$EV,RTDA TVRq !v->x r훰gz"R,[8{v$T ]{$aE A|>~ޕ= {EPjhlVX%:l~z@ )`fmBY{ѣ~88ujg>B˺u}x/,(زyF!H\ E"(|(#p#p"X\`a!%"Z,ԤɤͦͦES6VuuXyABBY୷x!eg>cFt|_B)?'O@AKAKLlQT:w:PP!8$T `P`UzUxTXZ|>|>@Ta龘ǎFt" A(bV1c2IzztF#KBIO 8˥B__۶ N=JBH|Y'>Q/Op14twq{^qDQC;JΏR3HM(<na9>I1UBz(T*U|KeIfhnb46J Z0b1U TK!v x1qx<\rI;/a߾f K!0^ ֭+8-łT*Dќ,8JΏ"UARyi)3?\.ssfgp:`KK!aB4VSCWl֢݀v3 hllRlED4*!$xQG'01>І/y iV1!T/A(K(F%GZ%!R)>v|[{7B=-M@' /"E27G`Yl BC(jITYq1ـ hn6MzL&)^/_T!R>nIlyp8N~NMBirK_6ȱ(3!F4**ҖQaxjXSB~@$li4*ZX,Z45In>*VvrZITZu0x*rD>ÄT>&Ձ-`Q<)8\rIرV7!T|gx]хJyq"WD!|x!,.vKLN'^IvbhcACvʮ?F45РC]f&S !F_6;w4繿y@r#̌]։/}i3oAB!4o(ٮ .'5rLUh|v.vjS)ķS{@*MMۏnX^RWsQwQAQd?໡Jq8p`=4Fԁ/}iooB!U9noٳ. @( IJ Tq:8*ʕXPHD$FNժCK zHT$ *Z !$@̙#)\umT2G>Ҏnۄm(BH5ϊ{b+$ߛ=łAs jh|⢴uܜwyO~J%bѢ^z $ן?MMzlbha6kH?`ZB,Μ9r&jX~'Μ9ARIer xq<0fgvۦ- K!kTclS#%SqWR!J4@J/0n !K+Tfgbi)%)J0E4*g^ IZk]zͦ_%j4*T\BQn\8bT/tg+[ӧK7x?(p@JH*?Nsr8$7 K TUbĶG՚Tbk*6JENye>b҆a] *U'ה TcqGNj @'&Ү>KKe \ C"*jjy :XRV#ZZ hm5QMZWvR}RAZS]VA8^zi>z\rILlBdXQ^nL;ixN:x1ɣH?QBUb^ya!t^LT0*}}46بGk*&V]\TT!i'OaAE\N|pYl-Rd޼y6^uN=>߳OWIJ$LdI>^U.E&A8"U!7P\qpzRz𓟜e7`z%<>\ΕcQ+\NxW EXZA]N![rIbK  DA Y Mz ? -t:,QRM>]{%ߓzRNieO~r..-ǖ-\B!8gY[ŬcLf/1jJ)3Q%[Y27'\Ni;e' A"hqQՀz}'1JCxZAR˘*BO~r.aezl\eR)?\؁j% m,"bAjnh~^LSfYv9wV NU6S_Thh/o, *rWBV?;;K/mM7u[!Z$4=&Bb>ss+ggpXZ ZUbT*F46l@sG% (ł"eLB!kS /LVtӊ!B·+\U DI,.JŠ!I;QT(b0HAjڌhhСـl6AYrjUDB!kyIlliǍ7BY#s4?\؁JnD@@b(.$xyF绰nsj~FBȚ,|~H:.CCq5YE)~E F , 5s'v07k3'`0` aj z[lBK6 &4IlFX040hPsKeB!"Es^x8}.r#ѿb !pQTF9711VP`$X%a 7ˮVPl!Bv)>өhKws~ҧ`PK?pY ³( #$D{D{``k2jBk3lvn?a1=F %U%Q*Rԩ(Iۮ=^nu{r(0.nDBHU .[1:zVL;VT GގWٓXpV;p94BB"D{m00YuhCc x ل3ZLҧ.K߁^VFƅ-]*`KYS1ڪW)UHؖ-r[ L-ǮވN7"B!jmW`IQS,;3x9zo~+>-lغޥ 0A)ϳ0ѱn3& hh2Zgeshi B-=1k6/ ocbKսԜjKv;w \buJn-?*f[b,1?s[,aKOXNޥ ,uztk@}vyݷlnB]&fO?|憭%sI6앸$=K6Ow*t YOM|fgeͥ>%혮#w`}_؆< Ǵ+U\hm`R;h7>/}Ro3ш/߃NF+RY,0Htk~'sN}lPkjjj?|VB7"B!ZQK |믢ш:uZeEk63&XpC,`-`-=~Ny W|zFl00sN44bFkV -&|w7V~mUVؒί&^\'b*Pc܏+񙨦6wku-t#"BH .n15)3¡(-̉yD"Z5f-u[hl6!0Od ~!!D4 tj4mY~ػV ~q {so&zzwg IDAT z7ؖK+`ԦLTˍ/SLr% hB= J̧<*ZR>ZIE1\jὰ]Ib ݈! .9 .}kU>s^L.bz| Y>,  #qCUjFKs3Gp'yx*_3a7\ 8SiCʽ/g R{3 (.΅bm%!}7 i|_sl9rBD"Q91>z/D~+q[!RSb"y^|mgoYUrMxW*-%됩PY'.|lB|̷ܶOd ֯- ɳT !Ղb<^_Y,f+ Eplȁ't`2IbKw= K!`qߊ޼]}U@>+5-U2#wEB.l.Vvȭɺ~Q&QR-VQDp?S~H!Gؿ߁=ٴp>? JG!R ^|щ_jpMt4qUs&r*7깺tq%*4ݕ-4s7J}K~_fˇ@;+CDUb)/ؑ7[wlnJ"m!RV#xuz|s[qʖظHB#ٝ#ULdWL+R%\LW>∜t +]N54-C}6|8+mTx=`;}}}o~yF~؁!RsbKѵTn2 _ob2n: wC.* h4&&& px0~&FuW qѥ0[|b!R3TB! EE1Bc abd{?Ѕ[|Ė71R]|kS-rPrͻRlU{fr4[RL/UrgZV'I\ly0AlB!k|ԥ}[ޭ=X~s^~Qx\u]ض:Nu^Nr.iSu1]]S˥da%X2n'֥C`L2!Jzgl!uT}P.[12rlOoVEVQ>>:?˯؈;,dTg$^a90'ŜfꃄBQ1~vO?pnDByRKEQs玦t!WpI\V`o3プ?ߍ_6&;JINʴJKsTD9C.ygzrYJOE0~S|HuryQqVe̷n#Wݑ$7\X&)2#iD", OZgnFBpRTu&eߘmw^nـPU)-hn3@BHCB!$-x6u4qe !R (&|op!v8Oli4[vRl!Bj E<3x7%x#BDD;O:7Xժ'.nmyg;pRL(i96 v8NB nIBZnU{KZҔ@G j|RUZѼ:1`s ~ߘ0v̙Y^5f,8{̬y֚5=/cc<:Rou=Zs 'yy7eٲrWO%<@Jefflp yálvghFɖ;yY.`L-t.@;~jtV6,O>h[K7Cy]SROΜk|d (;cZfٴhe]9c'LAN5!ZRD e3'33׿W|ۈ^P̪5p_%}veW. KFɖ'\r9'r]N IY%u46{|^HY em~w˦O~2]ɴ]boei;$V~%[~l?[-\XW5k.zʀ,׵r]. 軣L|v9Z;BQYe;\m!t?s -ׯe!@$UWhWŘn'9%29+[t{첾iZfq*r+[OI`3L|x- #Gv ZR+WhyLv<߲T tPvmIꖢT_#RY2ytCr{W3#R瘭p ^*yHm*Ii,oF@wT=g i9xp{gRÉUڱjuQUS6ޡ)[6n#mdyl՘)jdjjzg> J0=u8mZXm?d|R_1vLv6"P%-E@[p3\ڈۈ-. Pۈ+ˉ'7O:ϷtH* 5y#A?Z7yݡ:tR_;)\X>ۿsٿ:ũ{Rۺ6n!Ǐ/b9SrYsO&@Nb^ 4$\ffg?)9}K,J(J\z\|O嬳HjjW>}ZƜ[d 17778O^yed Hsa۟JbMʖ_k[_gѿmW6DZm,UNJ][T:fmneVSj)or_/ǏOL:WQ-MRhkSf̯1%[|Y׾Hwqÿ?99 @ו%[-#Ǖm*Zn)[J,Za]VVeVmg~.˷975ZV&m^l>ժ΋qR'vէ͹^6l#SCvh#CۿkݹlkLmn(|}m>luewϦ27r5ڷ1ֶm^Zw~g[âXj6lM9wwXŌo;2ibԙ]׹?T{n#ZdKu[yb>ٞKh:Iu!%[j%yț/45)7.M-84Ω?whC[OD&';\}y/~\|V&[؏[ζoSs}IźLYfymV@_Ġ] Uӗj+!ا._:r|{el-9yYyչdK]=obm-E@@oCsߍQeݺ|gݺ" |CQw |qә^EjLcϪ5εEv45o24jmKu}5TIFuQ9FcǓɝxl -Sѕ![*Oy_חM;=Liڔo)33@SwEO5x@ٶ^^v}yhnѶC3.m껦0[}B!u65! w\mjcmךqissO~2)rWo?~D{o{,9EݷO*J~֯>tT.6\2M5Gu뷇U["w%yejj޽WnF9Jyw[Wٶm[mq=r_Iz;t9ss/.'o,^63bH$n@{M/{Bn盝:uZqo)۹sܹ#ЮACO\(眓v~]Igw#j-oʇ>- E?fĐ~57jy-4O..;ImK̈1~$\@,(+[@%\-HN:<jimD{T.k u7nc~{N^|MyWԩ7dbbL>ru7ҥ#@0^Jekdk19~w?m۞}~%V]"wu_!cX۵e"zolzT:&&<|RnݵeӦrQ>O>(] -Xd|# 7|P>H$-"M=[{n7Y>;M7]"6\!cc?_ .|ֺ$\-j\g|֙VX#眳X;ouրYk?t`o26DK2>>NT#F'/ =_SNw @|%)sO?c9ztNhУdJjtED.A Qe0LO ZF?G@zʷv<%\FffȆ w`0pw8ʦMx/ψ#~s剉.*`09%x}F+ZYp2? h N ~ďz#E@Wp_uggY}{USdlbUv*\ֺ˖bs]הz+> ]Uun6ڎx> -E˪^#Ue]*y}6>jg1{T5]M!K5v֥&,Y$\tq{򫜏wm}1|S EDdbjY*9zuv)RQF&\Fmu96O-v13~$4ӣs6evƲsஓWED䥗~4}4md}[| eFӲmcn|tv/؍.m̗5vR;Q-geog.ЬcY}xRu~a{Tzܲ쁥hliTi:Y:)Z~L-v4ڣ긝?N۞eUǁqt\|uh}rː]{?o V;aХebYp)Lpf]8u[ޘ@¥ AˡC 3˯9SCv~^w} >TmVҠju&\QMmN%r9n덖yH\)aK i9xpp_3op8<3OjzYe*y3Ūl;-軮' 61/[iV عҗh?m)GBꑄ sv=8>$\4ΕB.;8z[5j\4_Gh>!ꈿm5m6)w\AjcI϶i{$e4&,[bp]LY_1L=<].Er4)@`fsIx4KUڲJ'e̲ۧy4Olr1} V;W.]MgٶǾ쾨bmiu.[!tY{ٯ5<߾J2%ЍIPL ]恹+̢jƼ|R퉽뾑;(lJX{1.7۶):ho!}VGIW߾Qc})ѦV%SR<=6Q܂5h7gE\ٮJ] g}/4nU'>?i =i]bWMeپrX~U.mEikh)Ǫ Igj<ۭڴm1_wRWe/oo[Q=Di):{n]T-c"-6tRM᭳M۾z DYM+LNc[b[Mߦ6sq{xK$W1_f|`n_<|~`qжdb.r076 1 ?hp׎}}f[K2 @9!e.ie|c1wZ̓>4}CsrծLq4M 8k=tB,'xbۖS嫉ص}>|HRʥuou\!~K>(c6`jZnYV̶֖~gO˾3v2c^jmY.S+a֊u[BڣO{ gu?1->ڧbmw}u~S lסeAz,1u1/8H"@Ҹ\m-En1 eRHd%b6R[q 2pCHXi]k+eQalʓ-2kZhz*W]-EEo<.e-۶~h.h۪b=wwm M4ۢ* Q6X7hm*U\ѧj9K_ѕ99OLN^dIS|]ILwZڊ`#xNlɹ^5Z.lNPXZ|Tbb|6kݹ.S+Ʊg![.3}:I<"cgb6OլdK6 &m喢DrBеĔMاNVaf驪۪$ -U8t/1_xS1QluUs& zk/kv79ZS:hc tzBUbB\ݞ?Ӷ^ҶLk1C6rE[QUַ}/R8vXOtb{.~*{%C8WHZld3_n^ш1g?/m*-Ed O"/9 ]8h+1ۧ }.}m3[mR6'eefz0d"vW޺اx67h^^q*}g:Nw3jYBb{4XihO ԷC-JǧUXLDu{l2e]y82ʓvi>K+FoJi9G|EuR>y:L^ϩDQ[}.UdS} 5Al}[ۊdJ'u!Zd$Ƿ}S+Nu$%.ַW 4o[7a($ƛb5ScYv}y~} pau6Dm}p[)ʕ_$~u:Lr4#_zk;7M};MJǮؿ7pxۢlo)nR~CN$\¥ t1Mkcb9->Ӵ:}@}׼湹Gӱ}PדZo8m}nOilu?tjy%>.:Io*mx ko[Jʷv:f<-]Lyszqel!eɻ&|u[gPǴi?64oШ66mboGŲzB+RtbG}fۿAT>ӕ2T^[6{8.Nڞ$\M0|/$F3^,c/4dⱮ+;1S7گ^vrk vW6;h!q.q_S}1ۆc3A쇧XDmW S}  $h.5j0D""}r˄T(.n)PF@y\wFi>@ WǓ5\BDd-<"N~lZQ"lCm߿t)eH -i̲iAi>KPڏ<#;#p|JGP+@pK Yx +\f)zPLo7+\}eljt"BМy7Uk/ԃ4a˷u:@8)߱UE5WX/m@,W Cp<C<_Syve "jYul)efS\BeW{m۶l.m(ua~&jWkr[{9}r%+gٿ˦cZNـf]rkmi>%\61o6R5ͥ.l7p^#?ͿeˣFG7IѠ.?p,^vhJT x.+liSUJD.hn p<P&gz稍A#~n.W ^~lu%*\3ƶ!vWt%J*mtYST.33{dÆ;e0xtfCٴAYJue˶4uY1U EnV='*1ڝ2i]pK_jW sWKEigG'le yϲTAi>&lgnMꬻdz-E]zDj*{ieӊm۾šed!RʖeZ}m*UtORdۯѾmh]b &\.y;|e̪1R}52>Jfgˮ\Y>ϲA=pIhh/t s$j_,luuktK OWFAUW{bD JW4Bۋncň\ үb[n5b9rdOsW]n+ʕÇL$Ubv }WK˯CvfgzJeNhuďw i9xpu]W溼i ~%oH@ODM\qZy/usD谐es(je]N1.i]F@ ej 'Nțotos)* 5y#Ao(? HT r_6Oӧ]d E$`t@)sFZMrltq `V+b/bUT~/k˲iNm'_[l~̯l^8r{c՟kYژ 2 vZRug;.vU_R>6PVԯ|pi1%նڎ =6pcJ{y~h a(*[)Y2q֕}fS1AH V@Q(lG6fGy.61:v4ڑqy>f./tYU'@U'U'>Aj6hd|&NBm;Mk\Q~vZO,F[|շZۉQnl{۬.d\-3{l݃u}/'nKwdܵb7t=)ƴ6C7v8q ][Fcn/٩ `RcaWu܆@Ml.ת[-ӖWن t`1FbmǵܩŪKTR4 893|]Z:}U2d7}: ֺ3/uKk' Qk%mjh?¾;M:-lW|~o~yz`@%i+{JSӮ`zºi`|\ v*;66m7Ĕk7؞qk+M-/6lW^5rխtZu2ǘfs|+{kϱ}Fzb=3~6$IHbn/ԩvQU4d9.땓[=ᆵ/̛7?,SS+er7ҥΛ~%[v¿ED-z|[*۶mKv` IE6nG+\!34_Ŭe։oL3==4yazu|6H7~mc̨+bmm 'Q@_|<rh=<ԩr_ֽ轇ߎ[eǎϊ׾Ncí/ۑƲm2_nѺlڷĸ"F3]\wD󪕲檬6}dZ][Smjy-u}?ԿSкJ%`SBhd塚kUy.^lv ND;rOdYru+}A|uyC*o"-.+ۄiRmLNj~.T=Xx_߫VFl'tQ-!~){fͼeK-znU0Uo2ݢn +\ &yɧ %]ETF"yBQBM+)RP޲얭 MÇi0䡹+Wʞj>uf?M ) DĜ0=e>lD@Sxh.2 +\%\-HN:<j@߼R&W2yJ67 YmCgTֶ,yGalxA ~j= €I}h.ۘl2o)ϱgyڲQG7:>6 H˦?]̩Z2P-_~96eTҴ]͗;4VT>\W ӫ=-,G%23G6l.P6mzP֯COEA߶.g]SUuݢSUm*YRԶm:b-E *~ sss?Jg;` 0eH#TW=47-j`ne ]g;ж)ϼZەmBPwYշhn^" {ՍmkR<>S|u->m/v$I7.Z#@$ lקQue#5}_>X[!C+|{`]-Oe -QBNZ|^96 P=pntu=%t[5%˨wgܸ.ČmY]Iׯv UibZwr]UejtU÷m@|!ixt|Em 62lozoܫ,YaJP<$8_?6-kYmvsܦQ5_ehe.gUM ,v[|NH}w֣Zn)Z*9z49 |MZ$MLya1֕JYH/뷂ڮpRQh?PގdKHiG;@zpYb9'ɄK_}BB%^]jW`6m'~+m|U-ڬ+\6@P5o(N2VIDATMLjO0h /FDDVV:?v1s'L]fTՉ:]zo V-S'Ua&jyOMM3lg5.r|۴M<\m)zKQ%kHmR@՚pٿ(y_}7A# Ԅ1j 'Nțotos)* 5y#Ao(? HT r뭟6Mď?PoιٰN CٴAYJݠv`09 j&xi[|EW5MLMەT}JVnvd俓״t+z+FmK [sg}`6Z.S^a>:{1me}c5ƹ8$.Wѣ/${fr׎72Q}@"ίldcTVr4ϥPoU;ܖWLC8e˶ʯoڴ>>r5S׭Ob折1ٯ]Lj=$p%]^zioPt/IlIcD=]Pomi/Z }Y]1,KCgu7zl[ b #G{rrϚ>/v/5Poq{E-qPNXU24!v_g=1*jK̕=QNFKw nM6u{gzv tZMLM17|v m1]?>TtK-mK|EY"I)1{$8Iuފnu =Ny2u-TeӚ򬒺DlVz+nEJ@ i9xpi]E'~ec}sTWw{:,M՛ϭeZVٶ]f3KҲ*I.$cR6h&Cl4۾vyƓ?H6rs2553:,?۫ BJ$jWoCzYv7@oK}jmFMFב܎B庬&ʨ";z ]VЊg}K߿ J#p.@&v $\pPp9qℼI.=Zp^#7?4-R#~t$\֮F֮&h и] ^FPebb\<,˓P=LL[rr,(nݵg grU&'W?7dٲ }|KѺuZ+Fɖ"l]`: dKыHX*JVDmE @%Sg8J 6`7"B`d pl)zD,[v;o^FT-޻E9u4;eeY*"gwʿwGiIENDB`MP3Diags-1.0.12.079/doc/300_config_others.png0000644000175000001440000011037211267003262017155 0ustar ciobiusersPNG  IHDRPbKGD pHYsȥtIME 9\ IDATx{}M݈\A4-KHP$1FL129=QkN"Oɬ-! +sD2ꨉ3c4"(Exn{._]ZEU<<@M'nƔ /oV3F-;F!:tX}}}Z{oOI'O9Mt`^m^{mT LٿGoWgNk-2eN8=skٲ{_ccۏN8I't&Lq۵8ЫEbё8:ᄉ:K?wzks` 3~{f<]}}c5sھjk|46{_CsZ[[2f8>|X}}T,Iu_ӞݻuQQТ555kppPڿzj۶:߯眫K?9mxYm|a 3'7G|1?C9 rijk.ux~}=\N ƏWˉ58nk;知W8Cs >766hFl}xڷ]צNc꫻T(4s@]QGW*w/`_zI}{l'k9gd/#ji) u]|GfS3J/cB0J污A rq jCS0F}fwO>H}GjjjdQv=:?%:Azk4koTh&ΔzvK{:/-/;:o7]?=q֬yJwƫPhNRJ7o$m.<_ꤡCKy|*_Ls,m}y٭~$v]OU- 0D{9N wd2Cַ>965ɇ׺ ʇ-ؿthr2iYK-ut7sOHw-JҔ)$ =@}.<_B.<_O>q=i6<|6N<[>(>q1J}\P?~[w&rQ(_ޡ577eL+lw7TssqĨbѩrQһo|f?o#VIJJŲJҴ {&.SLRPД)'ߍ6 W|T{DyzC5ͽ;ˣ~]t'5nyEO9[M;EރWh=vgX,0,$_\g1Ug=y6-d>Go3jmڿ8V/KcN>W:|W:WI/4y$Mgi9Suygk֬hS ^뙧j4mZ=߾_T==*i߾wu)C"qMЦS'OzrIq}k LY?E--jooSlzLZߤ?cc|7Ҝ?$zᇆ~6^k ͚թmv^{G>xZW)_;ͤhZ&ws^5=G>zN94͚=G{t/y 588N=4;9/)&>,~kTa--͒Χ>u?׏ NÁ qԇ]/m*a%(>V߹h 4z}qﶶk]Q}3ʣi}*7_Kuv9:OÇبFIz{{48XLtt|d@ځy/I[ .B*~$i֬# <ՇI[r9577+o;c6t:aD555:o{Y9Oӧ.I<@wWg͚mۆO~Ha׺QJ=ߐ6INQjlli)Ү5* /ڵOK6m2O7ԩ_Pv~-zm{( /8Iǘ1;4\.F566iPzm6()qf͙3W_@v߿*ϫ!@ Xt\'3ftVzx3'ҳ$8-'j?۶)<|tw o&|ϫCۚujlm*tP3l1}*R{WǦQ4ud;w"Eew.gOAzK>OUssAo?|QMM*jllR[[N֡{}]]K{BP]~w˃n/[R_(4kU(ףn .Ussny禛nU>}7s̙g)'_ッ}tA9GJMMjnkS50U}-֛ھ}yOV?ރ9эq={wұ⹧~Yf tw~S5eʤ˕97˯ZZpd{oKi%QApG--ctɧ'} ~ƎjݺڽkЅ.4551@UλއAG\^'^r956Р~5O41Icq3t:ewi|/ctG@>^cFU54?OPQcJ?ʷPh oNAt?Nиqcc{pg>|p jȶc(z{ߋV[8|>B@};u:67p:::jԮ]|yE? ? T[iܹ١ . `]vIݗ$=JA 꾬g1S[n'= qth~ @[[rGHKߴc?M,S\阧9ry4~2\Jw7rUwaySwayy~d#6=2r?ݫL _|W?slo_î62Aګ~m(}1f?WEӺ7Z=Uw=m_[zL֯]C: %ni;z f>iduddVf|yo1AZh'߹s񍯪R9rW8e5TRImݦA߁~~VپF%w~y2md0F9r+qEzmЯA_wS=CH=/zc]6w%vTe(/Kg+yKMYC%LV+[}K~Ϭt[{p۾TMtҞl.:v'YW#/knxL Ν/7Ν/HRW ^Uͤ9׳&|vtI$ߕ*ٽjiw h8Kw~*Vco[OaE9"ER$~8xe+QQבsZ:&;vl$Gm6WҚetLMf̘W^4bW^٤ιzM5SjjJ? x!l?1𷩷}׾56۾lW%IpVoLjF.xMwWJ<-yQI%T,;cv;{gsgHR3{&yJôMA}<_9.grs(yOC)9@)}!l^ԯ_i9nຈg1̙g.2Tdb1{M~n0]k[n8n]q8hEEV^eE'vN|.ɶ39_[_gQԻAqǟ?°^/kg{ Ayx4{dZlqt|۔߽lXZA/UQZR}Ҵa]zM+ٯGHD[iQnt,MeSWA=Qa:V'q>gaRfz8w7KLܻ'~f^+gs͛׏nv8}2*qRAX:amt~&wX۴G9sε^Mْ,W(l꥚:|'Mޢ#+Һ7o^9s+oslnY=v˴+fsZ$ڼ?qLGfO{Wݜ97UĸOw/wAuNX,IܹXPV6}e;|-r>w[ڼZ:|bE)GVMq"" sU&~vL)6zG9wK<6Jy&#(-++Lq;|ϿMϱ^/_~]AVl=wڴOFwXk>qiْ,WӼ_~>GroNOZi_ZD ..r޴O}0 D;9J̓VݢQ me^pJ]C_xa^XgŋxC t o:ZXg޼eM>ձvP~F_K\}ԯqgbi?o<,mkAsd_uS-%-&Q޸wm4`t=M7ݪBY7p:::Xj/+b{u_H,? HPk}6} ;x!]v%0aBݗuuv-Yr5FڵK˗P-[/Ї1_F } ;?k"lPOCZ8sI @h:@.@;N_gy|Dz_3]@vv~ G&5w?m_k|WJ_@=wT 5pC}NstG  @d: Az6i#hAirP-z)8^cqOT޾[ӌ~i$WKo K]mmP{rwmפnر54}'|]f~黕8ˏiZ.szgO$ұ-Nna1ڴ%m来y΢5aߗA~29,>Mٱcc]l SGGIRX$'x<Ӎ-Ky t'6\?6&?`_E~A߇-<>|ߟD$3rio8ŢZyvmrrnvrH'j-gNvU ڴI)múuOk]-YruGǼZHFر6٬6IZju&-XpA-]Twq$I+Vзi Zreh+(ɹxZwsPl觽NyT?LD>qiA$566qTolD}pG|(&}{}wɶCs ״1n ֦&ۀw;6F8 KӴ?tfۏ3T[A=lvCJK%-Yr(j\.+WQv$i˖-_wuO~Fe07miE]gP6e&DyHK$g}Tqצ@I$RP_h@~RM 4_]]ݞ镦~dw풔b?;@M:|xPoqH 9tR ZDNxP]==Gf[=:Ăٚ6ml;a ?ʏb(I]]tO{NaWyrPH=J L$+QjweVvF}gsE_EMӬA,CQ2p?q488kFK.UX1k9 DLvI#k~VA%#jicֶiAA'{Sh EGwک;خ^;|dfDRjYf?88K;$555iŊ=g?ϟ?KRcccj;Wu%"~m^!bym_a u}i;&_)HEmk&&ہm:ۄ_9*)vVi+m8->lz|1w}6[}z;n?ZπA=^\E;tghbs${~xi{{~~낾,wsV\Fvm-[ u'?IjAwl^w6G01Yau$Z;qS)H?,gێ敮iL8ͦQӉ3o>aۗ㊲ߨ8~˦SOOՏ$|_|4tҘXĽbŭV%jcu-/?(?HMjhz4Qosv$҈:o!YQ-;* _%_%bfRH!IՇÉ*'l$~j/W[}z%wIoۯ״jN<]_J>5aBs" \X,;Έ_6nܨ뮻N+V}OVU"_ S&Gp8eL~굞RI2=64G>4I+=v{wk~$}3LVkk#o``@K.՝w9<[7nvIOTY}*tgyavWef'Y?x30IjX%sZ}iӣl`?gm[kz5Iҥ|Sg5ABԙ>/˩uw]=SkFg;d#Ƀ 9' WUj]Y F4٦JOOz?ZKuFKu^I?z}z=jnzҥg'u*cx/_.iU~7|GUrK*-No'WsRe4)ɐ(uɻ_Pv%ۓ(}yHiw K/oq N:y+8J9klwIdb'OOī$CmذOSїԡŋǤZ՗{nUBnzutt/jj]v%0aѼK\mOұ;;b\.7 Yw߿کW^9YڴdI>ɓ5qb:Ms{`4{M]ymݺj۵k/_#Z{ټ+?8YwW,:zCݺڻ9g.}S4v,FCA EqPwgwȑA}'+_>~3?WzEkּC_<E?u/C=O'X>7MW]աNk!~?ZyMyA͘1^_CN<@EŢ7oV^OM71S^8E5U-o6M^2} :ڹ~?뷿}U}}WfNTKKuiKxogVQS7IKyZ=@)j뮝_Wcc^4}Kk֬655e!~$]HB:1:4ޫ;|EO?Wͺ:{$H1==GïizrJffhڴl_{7;L>{-tÝvxm(k=?P#oփ=Wi Wg⋧9 ߺ mG]>JAD#:q_z>}}.?;w˃?~i1 *k<)Nyl-_qGo/wy"~x_փ,$"}MQ.% xGTɓ~O-uZ2eԴ-C[4u$}`_O;$6Z 32fmC *5%f]݈y9d/2} `wٽ6-2ˇ{ ͏3T?AǴii5C`2tWʗ{zLx%ݠ'gY/?ZdX=|r~ǽ߃^Բ i7&Nzf@M]]ڱccXG\mUu-9=NYrqsqAwq9sosy3di埽˃r6;,OI%7)IG)Izy 6VւZ +׿]p'𻸁/>;o| Ԣ?+Og?E]Uc(sO;iU߽WMfZk>ۺM'ڼ;@;K7I 6]tIԱb2q T~~w!r??@_e&{R;V:FP$UWQ/SYtGr---К'AX]`JM-뮻ٛk?,2/)Q~fQk޽׿Wun<\0J0'< ?@_ʇ=/eߕ>9"HBWp?W',].M*@TQ3w$umbgרɴ~R?w8ӏYgηm e)d$iP&_~^gs|/?" %i30y$33(q|c?@FD{w 8眡G=ٰy~t9{z5k֪HҕW~^/d"?m4iHwvvh hX@y_Y wuu=-j6i,g1YGt/2f zSkJ~\j1W3?i;k[lg~O^խ;6f&ZhZ_GGnL5:tR}9:*U'u|.~'$ذ ~wjK)A)@ɐh!EtÙ e2'} ɲ7ʹͫ5:*߰6-cPLn?LilsQ7l?PLd8Om}Y>>_]MlauOmؓTabzNes~On07(4álvn&kVXQ0C]QNm${?ncUmϦ q_R5ͷmm_oǙӈ1i &d':29E9N$r9O?ՋQ3ԿZ ga˺:xڮ'Fe}I_Rid)RW~`jô3kSgZ46pM~[۟>1NflN@F7LIX5Z֎.q;O?%q쭔LOëU*]-OrLI#%=!t jjn59,Zj;k8'ڵo(ynGe2OY8VJF kHbu]i ዛ+67nDMmDLwAXtiӴ?y ZOyY.nG]m}[L6y F_vqԷmhй^XΟ85Gy[U(4WGG«Ve] &kzf^x:d//Tk:kV]vi?e˾7z$C8PK\ p>@}N |B`?@  t@vޣ>3FӧOӄ wuu7mǎz[Oi$/_: k͚ڿE#Hk֬jzWWiy7gx+Ae +Mau/_@… 8|^x| f20li9hϥzo9u#J9rDWwwޣٳgj=A%R`zʔKܺpFקO P2~|u܆YFF~*/_Ō3F=F'=;5v5;I'8i $/Pӧi˖j800_ޢiNK>0a-N~IӤn9rOЮI&hڵZh|?L`tyJ3vغ64ͻNo[9Fy/IE8.\Oh?骫lm1yṔ6mu&oa'X8r ŁKKAW^X=zIqlG۶mԩ'ꪫP(pVO>>OWwQo;;UW\qiBd] I{{Ҳu T@}z;vlRX?pGwQ__ƌӧi„ve>uuuWT9/DF\TZf?3Ϝ)S&G=&Nl_Bh:a'p '[-\x."~xZvA} 5:ppԪ5kpZhrh"}#i͚=k^J˧@Votj:sus #j=ڷW .8]xz'ӫDQ9wA'KĝW^%K a}_=ܣ//UVwwޣٳgj=U9)xZ IDAT= ;}}}8%Ƿi7=( `sb0bqm9ϖ-[8߄i.M9/Z9mxMb='gLe;R}צ}*g=Z0J1cƨ(ر?h`I{9j;{l=s3g978'r2SY+HV>}l٬z-64N&lNM" y]lzN?8&Oso2~ߛ.72/~i'MVP~Li:ݶDiz+ڭ}6t<(΋Pw'LhפIvZ-Zw\SL }A߹ ZGؼT{Whպ馛e͙3GO}Sz8|QhiipluێH핶:Lt7,}z/P(軰<j/R]~#8ֈRb2;(0I$H :t#(ζL~y 9m2,~#>olG :P&y:N;#ve?Ҩu)~j]R ަl ]<>8R77ΝO!^/:p/7y2c:0#2 ^:w;-kڟ&T=SuVuw"^;Yt̖L0}+<^˓I]kKunK~8J_ ۖLvXloATNN&nAVÖ5Yi9l>%ضG6IϦlk:IZ}>>m~j@xRYhR''ٞa&^+H%Óө;Tl/A˚8i?I@u~{N>!I}Bt^te"OO* O*c$cxkCOW@0w,;t h"@!vpX:B:Yq/n6oѾ}ZpV^%KhÆ :t6lؠ/~uj =(,z}_BN:8?JZ:me kݿ)P>-<{͞}rnFy~볟f>SwQwurAw;n|oaq:VgAJDYzlTޓ.GP7^n Xk~F}'Zk<=/$l^Da}}}89m۶yγe9۴ie(h 5;H@}(?= q5si&O ʛ4jpؔ@6Hc&e'֗酕(f}uvhXƌ9ٳg;n9sqh 㾻PzV~ ^f#FhWDL>M>>jٲel9?^~y/g:A' ; _` +WktMЮI&hڵ+zj7n.{コKkʔjoovuu ;Y꫋}c{8Ku788?ZOŁ'a'asgPʏ .qppPO<_RЕW.c=zRg1[mmѶm[5uꉺ* 8 ՓO{ƎmW\{x! F%`Z _T@u @@?@A@%p@? @UggVZMѪU {+1Z:;;wTV/@? @AggVZMFUVbkԊ,`V1r]࿒`7@? @n;6ҊZ8߱cqw5O[wԣz*@W_~?J4?A?`4uΝ<[D/V7R١ .'%6ұϕ +6?j_o<aɒ}Gç4?U AyyM?ȒF[iPKxdwc9/dV.M*2;@*#۴%m来y΢5GIRX$'xwW㽲|NۑuRUÝ4L4^)M~TӲ֧I%sgg?p/Ir'R;x]]+}[k>42ͫ:>۬׶– ?N&: *i']Wamw[4ƫM'}ޱ?Ps_ sx& JiӈvuBMS>ݦ^o&){Xjo@ee.ʕ+بnMe˖ﯻ:'?1 ~+ߝC4lӉ>MFX}Ei+۠+j;۬3h^ӶϫΒHjZt>JIމ J+( {wzmV>o)pN*Y7qL˗3]wwn9ctǿt_ 4N^gŏR %_q˞f@g,KK>FZ]G֛ƝTY.h^Ӷ N%eRmhS7&װ2hΐw@S;t}wa577QŢAIM4E2FӦ駏tct jmmTSS^| dԩ-ַfjڴZmvPc6s&jFFx~O;wH-- jkkI'ь5sxM6V'4F'hF577 @r4E_І q~}s&IzCھyOoyXo٧_<^دƎmԤI-:qq6m MM9rbuOk]t2Z*5mguv^΍פ}$ߤ;|E;?С]uU.T=ZԡCڿ^v8;i׮}{~x(ɓ[4}XM6VC?81jooVKKu;*\KOt$#Ҷqiק"-r33o6mzxyҼyg(tެO,衇^o~KsX_Z=A=6w.a<c2꺥jEm޶M’J"VUURЮT/* e.5%@nMQnIذ/8 bv\%Y̹=sϹ<\# 9S>?7޸,zQ^{O^{=>?9ZYid%Mpa]+|M/aذK裏~MnݺX%۶= .]߿=m}Qv_'o-l1󫦽g)_YgIeiU>rFͪv䫩+f_ưW/?Soȅ W;:ljH} !u"Ws7.ɫ''O^'E9}?*/pZ3R#7H6$-˵ȢE^/5RWw>P,X`r Ąi*: I I(K'@8@2rMqcN̩G{KΜ;?kd)d2HMMMf̈́Oo_S0<|A^{=y2<|^?'LFkN&实fR#uu'p T^ 28ؗ}Bȴ V/ܵ2sf1$G<&΍7/z^]]%UX-7Hwlջ^=(CC:p{24t^ySgH{{,\ؘʯzş*my+ٹz28qbvvwX 3ފo=銵{Wo%_VәSVeە4krs̜Y+BikG?ӧ[dIs3fdZe:嚥(.]w7߼4y"`h輼Ey2<|!_#HnPۯ9wuvر?9ت᩺ z4|viV_ӿijz]v:)gώɆ 9YrVi7HmmFjkke֬ZYInad?oyY^y }e-ti,Z~AjGGaiOp otp)6smox'Fѣ/EV.BwxJgx*eQ.7! >A4Tt01.:qrXMMM\wlWK{{㏿*cr]yYMgn XQ~\oEe޼zf-FZ3<ry(Lx+}.;'Vێk[cV4#z=~ǯدW͘K_s'?[Ο_C>2sfm47W~ɓdh輼EyKr5lttō2~{$LFGK[[]h;}_W^(##-FhQ- kU[ ?qŢtv^?9̨yXgrAJ㘧gmpNs\uru=n9M_z:?n,=I@pR~IeyV(ơ۱Ns}i9N 5f]oΜ:eȹs/km4ɚ5ӾFph (c2<|A='O=8`C T>/߬z9~/_3yt_*<ܖk>:OYG i{O̝nx3sqkt]-^eU܀X,I}՗@gkhyR#--߽!۷[o]s5Kjj"/^xEΜ߾,/|AɓN_#$| 7̕&fqرO}3ϣ *HkqZ[dago%)^pA{zgKt7\v:rtwQϲ,7fwk'7)'Iki9*Yj|+]2o^<ܹqμY?_#V/-Ӧ5>F嚵nz8+Vh;i:a]]7DØo稏EA]i:Emǎ]eN Jٺ~@9=:Q-wӃe-rˤ^v~SΞo_KKMbʫ5ʩSI.,MM՞ѣ/txk y^%I>qģP^տ4ӣ裏u6_fά;gޒh@zl!|̘Q^OݠՎ-q?^] Yv̚U+u__p_P]6%VUTu~\@(uiS''Oo_;}h47הM]PH6_8MaR5Vv_ٳO^#s椷ӿ\.+;v쒏~tgyVr,={Xߔ KX .hO>QPX)JS^>k^~xP߻7/R_ood}+mAvUv}bR˖$_5ϯ'J2.ӭ| Q,?uʳϾ-=4(OɭfetvCJv4i\ru_KK̝[/O)gΌɝwvȊ$v[)U*YblڴLn='_|{gߒ޻B%?owU.ofy^p[í*KSgn8>'FHYó*#^$ߞM:eѢFyٷ_7˻SI|\yu^GŭNeV\sV 27Deǎ!;+۶w?E^/LTÓ?vWuã񄂱#¨y>M fάO|X!<9u'/_A)+v1W&MMZ'߯ˣw}_6lX*˗Ϣ? rB̕nPnjkdժ92kV̟_/?_"oyII} * |WAyu&q1##K6wtw/ ޖ}7yNún.y9na^>rKuUd22~rKV?w?&΍M7-::}x^6-ԙi@z͚U+B5Vo}N~pBN/~q,^$UUH}/V֭k}|HjeZٱcX~dayq9SjjR zTUR(̑j9FU/^߾,!kΥ?HsG fHGGs2ioݻOO)gΌw/|]k(  2parKV̩ȑwd۶c;O\#sjsɧ?H̩vij VUUF-js2o^1,ٳW;kmd2V/b=Vovw|54?U4knHkk<Ȑwoȏ~4(gώ˭fe1V] VinySӟ~{NVMIwD(_(Ba%&@%7lkl)s<);}h46r ?1o)e}?_5S_,2fY^(*KUUF&;NvO˹s_#gRQIP,C I q1́ 'Nͫ/|a# Ɂg_93&7߼X,? L--5/3kG?[zhPΜߒ%t"T%9xawa^ruPRFzQ?enAn_&_%uY^y)1Pz?$Jٺ~ݻOG\Vz{{ Hrʰ>("B@ ȦMw 6|I}1?@KMPn$3 R7ϯ|pA.i2\xLҲ'vt&6^ @ bN'@D*șOX-$|:MzH;Ƕv5]P:Oryi,+$RC5'=U6'4auSXԟSh_l 2!W$KUtƠb-VK?VqlyVǵ*Ss[gtT?Su*gV~Vgnv˳ qYcWnl~9qq-[-˖6n}k3-@pPq)  /nWv t\eVes,q-t:}.VYUNm VÜj;Yw%ު~]7."y?~`˗O/*]QPJLV!u:'ē&WKqorZ^>vҹJv +Vh;i:a]]7DY7ʪ9\_>\' z&*=u*:-ӭԥ03iIУtUi: =׷OEp@Aά2̭a^AMG`eZ^,OOau56lN'T{WxQ=SwN't秎u=_~X婞ݖ.gÇ_g4qt:GlNsHn!亗kXXauT6EB?q}0?V}pZ;9H:a1s[ZËiҷ(?8nPy0D9s{e)('my"PVOêA!?'$-qުeV׶jR۫<65my I_11N cQ]N2}r?0g6߸TտX,*ҏ$@.a״@7js$teX]UWY(;P*4~Xv kT+zku;L2,DjnY??+*%(ʠ=puùjY.V['d:4<lcoEIU_+M #e-/)_Vco5[/ bJoUw^oQ®u;_Q^xL)_pȊqb(.\9Y$niƳz3}6^)zwqlA-<1Km@[4TpvݢcǮHN.蠯왷r>tGtۙ;z!0ROþ_[Oӝ>=*>X߮~*mG\ۻ[ 3GuimTF/ =/],{AG@ ,éc4K%U+tpP,vs0 I>׶tAscNnxn5)s=}|R橧~UZ7.lVy;w˧?I={Ҹ7Jcdݺu,ttTm{@Nמ~||L{Ν_Gnz? Ȅ*祗Z9iddD266.<㏩W;;Wێw!4jW ue)V@|ckʹ;0ebQVBa%abTE'&&=Ҕq}i8Q> #?11!EDp[Vm`;LV1u~\?銿t?lrYٳIeMY`EpO?e +=""mAvi\.;?l?&? ? ? @rܹT;wK.lyQ-grT\v2#U/(WJ3? ? Oϯz?r]8DV? |@<؊Krl NdI9C @V޷m|a߮<*(nm(v];IMӶ H@U'pVy])_[mڮA ^=iٍU6L' t^,'@Zq/kNH_޽dxxrƍD>6-Tܹ.JooOmY~hQ6Tҁ$F|ۖ/w8ҩDQ\2׶m:qY~~$q2a[mm.2m0t'-5ÿ렗z'Ry*'@iyK.@Uo:kݿ@ZpYDOlItUQj@ٻw PR/Joo 9_ yRDch$d,@E)uQRKm{ωn :I>K '%d,(X{?eϯ)'*cǪʭN4ՏS=uNZݖʓre2)?Ҹ cfNwp@9&Qt@tg@ojNHxc>`(_[潎enxt*P-gXZV[ mhJzTٮp?oXO^Ok464n~yWIDATOWu9NP:-ﲝᵾԭtv?tNmc׶ccPL?A[5;ऺW]NK;G.oVw?օ神tcu*g=-vu{݆i|Ɔy\0civ ӲuWA^ѭ[\=o˱;㋟17eJ݉banx_)4;2Ue盄GZ 6*wPuZ&ez-tA7 hhDx2̮b{[eH˞>χ8e2ew,~W*TB= & Uc>X'?u6oM!i+sm(?Aw?W @oi*) O unS .>Y^ºq$JnNWfb~h4 IlO+6SP^»U'Jl~Vp%m bAS;y㭁Aoa}Z^e\q5:83}Payצs%}-᧍DwV{:З+n3q˸q:ϗy. {tʓ[ӭ|*0Tyi\ݎn a?6|_dn .i̷ ^VOs}EP6~1/KPm(qb $C橧~UZ7.lVy;w˧?I={Ҹ7J+Jí[7Yܹ[֯I֭[}P@zCl{lr˩=F[wp' F/t@GwU{1aC 봯OX4s^˞Ge*e'Tϲcz_#?+̸#%b+SzO:C=k[{vSu iV[:ӭl[wiK˴3s]X]#{| DCWU|tOXo5vӺm؅t;MDt -ʞ=OJWWDd۶$&l@E*9</VE* ?eE@ѹP'#T$*(п~MT={Id'*Z{7MvSgYi׭[GemHd0N8&H|wD(_(Ba%&TL`jr5-Zcl,2Jì^nӺS3RuUdA'+S 7Ky-[ IIGl˪X1SNvJ v*ZXqUq Nӻmʣ:O/μIw~Ya\')e>@p`YUݼl?HPgu7[Hu[JJ]9Wu涎Aԇ8^ꐰ W`,-TRWnx~O\Geg7?څvjOCb;+?A|~097xv)}2;-ӪLePN~*c|j9n]g/3 OG0m t:^Aq(oˁ~cu2(#BTowW,g햫 o: P >̟.z^@u܀dWފnKWUn/B-y>2Rg*'b̏o[cw/Z~l :g'@zUAM'qAq{/La/뤻^ԩ0Le;lǕwz4I TM7"Ajg=)luwN=8hp nhDAk|}EHϸ3rP.ȃۺ} AAuq>Aϗ Xץ /vTq۲l?!(u~pjur:(eFq;pU&T9s|?ۙuRnUFmUw;Vo^uצ|uʐc& jW=9hx6FX*? zOCCo866 +e) yŝaP xeeϞ'"me %J=A@4r@$?![<* rܹΝ%V쓃VՂz{{&W岓1j}rjT:BsrHNS?P,X":N su%?hTBj: N snS?'ut6ʰ&:5UTTejP*<<-P߳*Wi溲89u˖CӖ90pHU20pȶ\v&n(ZSڶnC\Wgfz9q` eNc 3YiqtnBxkEw~n)Ս1۽64<W PDc~?mkps.:%`u4樂5:Uϊ7*t_:F? F}qѣ/ʊ7ѣ/F\xj>k'wu\Rſ-ˉ~KwiwwEDy0^ꩻ{:tf\ΰԌ+T׷Os:mo_Tk\O}}PQ4_e?]>c~\NÂXWV- /S\OVjXu@ġ?Q?iuJXCJ<|bOĄKP>?:MJNí?h0Bc Q S? 4)uJM\Vv%:*3<+\:N;: 222B]=A ATOiuQ]V?x :iTJJ@yko P@\C4(3q8? Q8[=_m~cdd FFFuo׎;JPF8@ٿEgBDD eoKA^x}IENDB`MP3Diags-1.0.12.079/doc/150_main_window_all_notes.png0000644000175000001440000023770211262653331020714 0ustar ciobiusersPNG  IHDR\ϦbKGD pHYsȥtIME (ґ IDATxw`?SvgU,ɲd˽ 9 rᗐp)KK.!ԻRH(&J16wK,ɲ)?xerdkgvgޙy氖F3.W?lھHgq]Zd>{X6o{5 4m_}A>{l?Cm^oFEQPϩexG hY+/=Ϫwf9`Y`"@ #ӻN$no嗩yж&,:r_}M6T]3`=4OP5v99^3h 66g?TӦf2-.κ#I-eOC8K׈i|^  5io/^DhOG $Elq8COeXv%{[x8(** 'Nj͈+Scz ~5 Xv@STTiLPuĺiŘS$hakpι0fX&NY1 Qc6cx 2GuL @ gCpR\C2Syf9b8x6!I/|}'ӡO&4L6i^p0oL9]aIA C;ȲBSS{phUc$:p]̜5qȲ,F)@ `[pI1\~pNz<3'L(.9ڵ\zl4-:@g8!`: :Cw 4y'd0aa(A$dh|V\ u3+*ʎ9OZȦCIty-[tty,2t3Iͦ 6[Qg`Y&vɓ2oB{Ȳ"@  jǗs^ʕwuH+ƱCcj֯kmKfŠ1O!ud;$Tߖr۟>;y.)UBZ8hhƼy3[N )Tijji&i1K.9x? SZZݮvH8VTl6M3QU>_c+=g>]]],}lC#@ @ r.}}X~BK̉Fc'sWSǙɊ3gۏz|#-_u}?Bl3g55)-*CĺXH͆CGw84R_u=Ȉb8b؀u}h~(Xv׳q̼,˸6 ]׉D"BAL@pRsB%I"'p,:d_zi#]Pv~hfg0r4w("0{wS_+ebf&&],E-E @ d(BӒG˵2TG`Ii=>?a۰, ݆nO'b ǏI O ?'5e'e{mݣrm-ZʕGz^J;a[?I$)$Hlϒ$2Z@ @p\DAr^$ ۑ".Ԙ?p!H#xq:a9",QBaP]72Bi.\.'.Yx"yV0 1} *+'2qiZ477F$ Ee YN~$ YN.F#ttto_3#IyNBXX3A!VH=tX4 n 3I2զdZ6M\@>wVe_CHUC~~>cJ>u:'NDȲ̚5k8pE  tzQt=z z#tSNcÆS9>xyM=}e̘1c:R1لG%]󢺋,HУ$L;8;{ ņ̭-,˙iwWWAQT QEA$8Њgy .iR_@{{'^oN UU$6t]vaPP(Fgg/Dx [u$R ClaRRRBm$4xx<"FyȲ *IzX466gO6yfe%0g, 4- `eao! p`+[lְ .G3,kP;pJr` ?*˖K_8a)XbKZذi#sfk.<5wlv-"&Id}2"-d2Z)-sfwLeׁ8_5]U`d9gSŢ6nZry666SZZ¸qTV%?ߏn'D좼m۷sES\Ryn/XS3'ݽ O((?cVxuD"v+Gbᰆf!R_wmBg%1~ /z9w`l"Th}Hk7bi{FŃ>»g<韭r _i?*o {T,kl .`Q0cÆ*OK&5e]cd@ÕS,r^D#0 esرx<#:>={6m2ǡ7 Mi-;9l޼3ea&tٹs'dϞ=l߾t=ix^ 3bSAe0a{?rĖ6B(6 0vTUEUUEATX2@z=D"Q\.)5"8{ #,X}B0/ UPV6qԴ+sQX?";XC nwF8r:)ž]TǗ?C4L4MbX 0۷0NȳH@[w~qia"K&&%cZ)b fcٰllv,YɧK/f©'Y]l9\X=su=Ŗ(uӻ\yLƟ:\|sOQ2{XK/?^篯y{(̞=-m%ϟ z0w<6o8?͊ob999RXXȖlv>Yp!Mnn֭DMMQ+a۾W'|p8vw($ q9 v֬YC~+tmm]=+iH8 z =k)zJ;@ɝW}əgT,]W~ßpx9 ),v%MCCh4JMΛラ?N*MǶm*($Iqnq 姥Nu{/vU}+fs"rݶL_ ǡP$~zB:Ŋ=||<7_ԋ2]udn6+V?n4M.\Hcc#,pҟEɌ31c`,cƌAut]gܸ*V\qwD(~w]K$W>ecN{w=W]u9~O|6\Nb8&R[;0 #@X,F"H$DL]z0p:x OuuNEԀ!=ii%rxxPZhI_[ibPUH$B"HyL T7Ȓi% 9O„ ޗ*nTMUmjJrw@OVt9%k9OEk}_KG2snv5\JBq@D45%σoNxD\rY"*gidž Es8(//scٲ3)Sjݎvf͚AIIy~x,Aoo?kr-H);e˖c[7we¾}bO~?޽D"1OOOO&ĉŲL6m4Aa"эH<7ea $yжfQry:0I4Q(1͇A,S4gĽ^'>+xfR&NdʬI(#л/))CsXt9x^}կ;9Z[ۙ4un#{~׹2tGoܸqgwcS<D8.^|q9K\6'8//MsPSmvŞ={ikk~0Ph4aߢr9q:]xrss)(ȧiӦphq<9NCOO?bCИ4718Nl6ljFDB `&LrĢ纺=y3IuYVUVK4IFdܝ,g$IN;VJ,0hB0 n]rQFp%4Q[7l7{D"NY:t+XXXd v{ml*6{%=J^ۆߟKUuI..v+[~O`5t&-;C[:>op8"{I,CGe_i墋T}믿 0,LjEud?^:Iyg-_"+AGGK>AS~EfSyTVVpues`a㮻>};ooH(K4`b^[իssG}oҶ/ٺuG͕l #~)e Tj:zz_Eqqް۹b>cy_i!?0k,0!%EK#׵RQWa1&8]( < 3 t 稞1'\|Z˖/_ӧOᙥK)`ܩ#疏\5~E?_|peզFNn.˴P>y9G|}BTk &МbdYJTMH%nnАO//k1@[K^d6g6vbO;FeDMCQvjvd(Ly K2|NgW'scժwH$Q Q?3 lݺ#ֲ,x=I"K?Hww7`f*Cޞ^Ə4M{<ЎtDWzyko5~.^@$aeē+v:1{#aa)f \5̊=!~z{.!G3aB6l`֬YFRyNϻ疭GV+/ƟA7 ԷдUҹ™|KZι!Ʋ," QR2CCUAvN'h@@J Oy:n4)Sj48 h4$^o&Iv2R(S.ebI2,IHH6.6=ՒI*($Eni3+qWhňFeĖl%&D_pnj2H^3?zr?p/޾C0ˌ%ݜ`I$#1bDFl-./˟/meӞ _>w7Kuz:&OKy-s%P]]?:)6EXe-g$qʨ$Yv%eLT3(;K-[lOy+L<Yy[\.c,X0}ۇ,K,X0ɓkFO_kز Ohal[2T,)Ғd+f}aX:N D*[N: lU]đQ:7&ף~Oܰa3ůwqҥZ0e#H+*̧oߦnW\y_W~m^Ν(B^^]\رֶN*tuNY5!,;`o3$JrA_^H|+k!f:C&_ ˇdVUUA$Ǯ]0Mh4J(xa;n Ncδjr. xBq1m8&TWx B!0mRUU9jpah4r-IbQjxd{DvIuxEvםa[[;;;Frd Y㱬Gcc3WiɑF(SL qHL',"qH"y{{r=Ӱ0}Jug z#H`HX d%dEJzXXG+y#=[2aE^M@͔ىn j=e;3!R)<_ףٓ/A1,L`:H}N`@HW['O[|)/vœ -B P"7M ѣzjvCq6nVsǓȲL8{U(#߮0- 0M D7 0M r F osU xTT8Nvt%y4 0ia#١g2v߈{{f<z{{I}[p: Oݒ -T"&R*d(YfJа,30Zt RVRp؂ l} M i/ IUS$'0QHt9qDrrsSAGz*JcT޺̘3yleZAp\ڹRpqS_>8x09Xww7}}}gŸn[Y_XNK(IJzIr&lЃlxo'7T6MCQ5lv`&JzusU{ѲFbD;} -}4ZvN#ڡ5,S~8-haymV1M=COD1(SX^C,~XJc-qH_u^r 6 1Dlܸ.U(~ ?6;55tq͚(غ= w&3֭;Ga˖-\|ŔZ] ^Il\\{T \r pEqq񀗱ϩfʨ2P"3ͺ05fx}RFLpY=L^e^y}-|?N$ψ+e% %ƪLL0 G?z^,SPK{{/veA O8te7P]ױ,dxCkkn9*vaN$IE^.7+۴W\^I !vr %pDĴ.ÉCaEu(w %Hc)MǴK1C 훳p#vNқ%% _+EhD{Dq֬YeY)aEUmY"KjM4Mmɽc?]]]ֆiCr Q-a#3i4S-'??FZ[[CRU1I>#IT@eƌTUE";O"2M 1M4X,ɝБ-T`n-GZsy:y\qB̟iX B7M,#4M I$#3kFDٸj6l9]nP;#`TUgƜюC7oƀuMM7} ݋˥q-׍J= ^b˦M[|o%K`1 #xbl6=G܃H9JQ3gfeeWImks 2uLP #j& s2м1wn)3.[Xʖ\= k/ Ew,7߽B&&oj?o~6}q,`9hvgϙ3Ms=_'s Ex4#/߶ sކ=̙7'znòL:::X~WGG6Dqj*™-uRNThb{Cs8YKW-C-\ee!-HXh0hk}iQ9a& A,'c&nal6nRb8f n?JNYEa7P˲]切cHDIIt I*@`0ݮaFdp8,Kb>Mp߆)YL+;Yn2dG<(!EmD[_$|k);2o,%Ţ;(An$ˁ Gee%+V  %ْ #:puAuYa:f>4p]8%d׃]gx/_?$Î #ŵOrQ6&h@6,,+H`6j\4ON70 #W #)B6m~`\g@Lfpy_>NW=ms k H%9z,!KrHGxieOUI5:n+s&ӭGoo"0h;4ӦM;#(6l\'80t?ٸ=.Q Ŗ 6#IqM7q5d½pB<<O޸N{0h@FV6^;4 II .nмG--?ʖG>N}&A ߋxN2~[1n#Z=f_?Iyqb8sϛөr&1ud>q;Nx9Ptٽ{&L"??n.\ ˵M466GؿΎ A㋜DtkuhxtgdLq9A^:4Gć8cƏaio勞/{mn־r\! IaJMq#Xx9ES0 H4A40Mlvoär^ٳyg2e">rs}r:L(JOO~~sBdYVp$&Xsƨ4~KK.~L3=v"#AsF-݀Ȅ`o͔IA;jdb!3,:F:+Si =r,[eft $EAD32Su r}^]TTN" lHEQQ1%%/$6[@(:;9>EFD̖Eww73gԻeb`qbly3Sl1.OϞ],i'KIE$,+9[$̣_)#ƙɰ0SjqCDa4mT nys`re۩= P{!BCP690F҆NGž`e&pF(j$'`YIIQnYfin(fY9T._P?\qiJG_5+/apnjk&1n|-q ţLwvg&6nLr-\s5h6ߓtڴi|37 كWWL Rӟ(((`ɒ%'/<18$b E"ރ%ǙO ^+5|^JJcK菄9!rwU7ɾm+GTpyw]&r7ʆ2^P"ݚzJfDՎ&I^1Y S1Xbq0z b;w62uTƍӘ7L􍤡1*a ܅F~~>6:;;yٗ8]Q ä@Sfzx<ʭގ$ KNwnn+5REQ&=G8JGGcPnc>/nYeƌ)bVN+pLB`EQQi QZ꩐"92dYYd /!L6a]r \pl2ڰ"$en\|cf"L,x[3b5dIh?yfz{H-?rk3g$hǠbKv= }|3,s:D"Dxl43ƅizcIJZ`SP2yt\Lu>M ˔0da躅 D@%lT=@r4AX'"zt3dm8DᮓSv9Q[v KƱٓޗ*XeR IG6~)/XĴy)fJp~\͔J7hm~KD-K~9B}r,q5m}֖t3ںu;ܗÂsG8}eo ؘ 񨬬ŋv" /sϽ-x<,mBqqu~bwb>S[aO|+MӲF0%a6 L2;3_W d|;!HP\\pĢo^TAA2u,YBP\. 3c쇡p6- IDAT06(tv*ttnxHay dv4z{WyyO' 88(?"vKݻwc6?{Wq~ܲU[ )6`J B($B!5&ZBbqŽJ]Il˶d;}=+]ޝ;w3=gSC P? jkkݻ)S1t`2ȾFP %$P"Zkށ(QTуm$AȐ(,7sp> pT5覅YƖґ^?Jjm&//K.$d6 Gu,t:˖.KmlەqPT5iK.[}:[DD  >QU5]]a;[x}^C!ït.(H.dZMEtՋ%m࠸v 4-tMGv=eOA~lþhs];b:u86as˭C*˱F/=1&Nr %`oumn,47X՛hY\h g,匙P,t,~=)BQ=&qW@~=k\1u=rf&㵵u\z5o&ٶ͵_>}z8 ?>w}[;pU⭷Cu Duu =$>"O>Ǐ/7gX3ȶ[_̬Y\61%JzpjA"o$C3{Ųtw-+/ '>aÆ3tͺшHtO JK Rh?jFAEs#J&j B,?^GiH͖VAN껥/_ҥxWx7fdo=J9gܳϱd2Ͽ_X#nr0o<ƍΤIgvV\c}In@RN]3&pq;RVk674P*")pD]_oEQ0LPѱ)%%UTT9pXx ### ^z,jqOryȵR=#, (uDGVr&@[Ǎ$rqӼ8FnƎ6OO1xsQ.cU1(ߋi#x[:%(D)6IK,Ik$]"&I+`+ڔ1kg=Y9'IuyAJJe9mXDŽ#A7>6-_A>P``a^h&IlRv~Q 8Gff&-iomͷ:%-vM+gHHr5n#S%?* "PT%Z MwJ'YĀw8ӖX$'Oc@:{VR?ľOwN䮶~Wio +.m #a*B TZ'!]ͯ$9ҧm;~7,s7:tk-ehj'no ȑݫotW2uT.-ZDaaa[ƌ38կ~a]2!]ÐX68N'$<ħ~LCw)0mwUHUkƻ4Xp) yǝ|.Le.n3bsye1h~}>CQP+9'3?aɒ%{q,Z㏞>(h}F(,`!hNH6& :A w{U{TSt(r9G&7[.T9Q[;䶉i464!qH:iQД&9& LZ1["hIm[wn;iv %)qV_3 1hE6n(voU Ҥ~ d HMA#2@K{ި0VGK 0ZMl)D;L.yhϖu"4ꝴ^i!Ҍ%)-@{6Oʲuq5m /qs(D /-)Пr4'.>E5QDÑSTՓLGsKQUiljt,^v-lz-qKa?~Kv o-+iZMSzj 7V2)9kƦiMd)c X{I|)򨦍a3ϢrKuul.GΗuG† [ />OqI:zW0n+qljGI' (h#R%L?BU0:CÆ3ymmϟJ.el[^dP-n#0mto`彅ug:jki hhj!2|`o hqfw'?w1?rijTZՍJIm '#D*3ac8p_cFE,x.1"hBl6HiuMHqXُ،mtk-yFQkPkh{x(B.nUUHg)ciN#y;[!(,*b 1 JK<E:H _!IiT`.\p>Y;E2{mnذ)g( 5 373jo*7y 7nn-W]u=o.}aL6 UUa NwP YȢQr/xP(ɓ'p6ZÇqqn,Y#G0zht]oW^Ars)S-++KD,6$Kue%M-a A$ 9I\(Cawvpo QAAAAQ5r?J<,ٔ[Ḍ:N6PSDCC#o>-L8dW]u~6zݯOv`WOC{EtIR7UXHTy]sm%;k٤](g|6n\MS$ŋ`z*w<|>7#q0p)%2]Q,?#;;]뮪*5dys0E @b#djǒmKh 8o)"_1<^-X/7nyDtyv$DeI ɺs(yAI%9]1S+((={Y59N)-M4ʹm͛ٶh~ӧ7ׯ?BE8 : vT,EQ^c+lZA(IMݴ\#A=DjƅG}C}I{YK> >> -AV/"%8`@ @ee%999x_mHnYDXR0l"#(誆Whb*iUTSAU4p*.]/)vyώξ~Mxw\vwz㶧U N{ijl4B{v=**&KσL5gM$;!_ma`l0*BCzC$ ,x|Z"&cv+xn֯?Gu>mkZ/^ƒ.|O۷yfϾQFp{?cio߾<L>AjRv2dDZLQ#KƦe>sN(B=t]wn !vI'̙3꫷W^̙3m+뮻7n\;C9 t/Xc=_̯ш6bl!A]6Ab dvnU>Y5MB }qeˈ/߼U[RQO3vUX{EEEѨRQɰ;v,kV-dӛ?_(K'`5Ρ P6)aNfInȂq.딃F#,]6 *3& /Dc(Fª}kY=|OS~_Q]]it \:ܹs~~=CAAYYYlڴ eÆ >syyyVWff&EEE_{zO<O<?1DV}\?`ZC{xyo^@$]Oxxs(ReZ>wK|RKh5vݑGu&ʶ: ~/>#SQ=9?K,n V2 ` <4/?yX9w4]&Fcg:A8)=C˶AJ>Ÿ8뚿 ǰߨ:%Eqrs1MFꨫPK-?mXEU|8liFX"$B8(늢8 Q0b҂Q׭@JJ=I&Dw McmtzxW FLk I)qTqQlo1vh17]|96WP2Y!U薖iǣHIEʲX8Gr014+(1j0@IFI$!5F–x-h*"$E)'E]튾;GqP/B`k u(yFt,ze\c&*x5@8܄PdbfOqXSXM_1eZ&<¡H 5L|.hs[o }99zM8wϾ`֬y'߿>i?7|o{ أOmE( Sc`-ĩZ^!OIkK~'\s5l? IDATذSN9on,333BA=;v,K,iTU_)K[EJɜ9sx L8:jH)xjDy?c~r/Id=eA3 nmh m}tn6^xen6}ɽ޾KOzS's?>OǞIJ,̙É'H^^^]] qfR-ː0C3`ZzW_q׷[luX2-ZĄ G#GdtI5uUU%%%:9Ǫ|deePXXȍ7 7ܰoԑlE% r;*Y}, +̅ 0^Y0E^$VaxZ"8 +Tpm~S9k P #ޢ3Ȝ(ZnoYJu[d{IG %EmYB]9 plRGSSsD0C7o|&B-MlXc1CHϢUN[ZZId"`V^ ]AT 'f%ER!KBZR$ I' iöe%h+d;*pVjHu痃RSMM۶innF4멩ISDMDu(++K:]쌔H㺮SUUEϞ=ի7X߷]דka9Fm紂-)&8XE"т!l];IK#56IBCǕ14Rwea*.LQ(3@x āح>~0.^TMG$EvK8Eм|)w^8G'kߑob lE"!PU (,o[ # ]Mdi\wM3z\s||B0{}7t+mӷo}?0xplwksx7)))o P$Ol1VRx 7t̝;k5kt)ؒN8_vVÇoW&DvvvYigq!k;vmJ?|vF[GI?Eo'hGa|FCsT&VSb=r\aN7 +~y;ˣ悟Ō)#p0BiDQzI}}=յv@+@+nAJ^8(B:-IYҵ'N TZ8e QbhgfH2%A}PId ||+ev[/W_-CK$vw}7@Hx]C"Hxx6%##p8LSSn.۾z|38mi<}\z5|x |>7|3٘[VشDbd#~oiP/䪫%x? =}|Сmrrz7ŋwIfӦMw>kwrtX= ogGhXYgݝl^&NDVMHGaV7)T|]`=yT [#>BU<>+ Z***0n;p%c3`GF0ÎZ9WsfO8-@Ir$v/~m6VFN{fl (pC&wm~cK:n^7] .{AQb63~˲an\2aV-B:eSKFOJ8.@#l&  {^EXD6nLOAAK\sd&#pO(~ί0*{]W۶5貘RLo)%^h4Eu"!m$4 DQi>quӤ46VqݦC$ X,vJBm8(8[1]J'g`؅N"t]۳7͸:1,+@^^i%cMM̘1h4JYYsqߙA ^zk=7F|dy#Fł@J>+>C=Y?˃s\lv{p w)g6㍬Vf Y45pHߘ;tyyPP lZIB5+a.^,h?NbV %OcK+@Aٓbq?".\yvmRɉ'FNNFp8sϝ$_\M3:ׯ]~at]n hּCdy3kyqWdɒn[ƌe]ŋ7n\!CXfMZӰlOii)˖-c̘1ifkK/qKϥ4)fۮq]geؤ2ٝz~Gy2ϛ{ NC w?KwQ[+Kf{߽465{t*6WEI$CxG|<в ϓd >aQX8f3Nt6?m2!ef6sVJnCT~9*S=-Ke>mGB[Om}S)CJ6M͛ˁ1zx<4[Ed*UHd8"AI;H$'$Si' ȸ)IuE2Yw=5e< H GgN)Lڞ%pםG_'AQ&g%%%ifSJqD%H$`K K]7iY0mAݝGX &r$ߤ."rrrX~5vrw/?R&*v8aGeǿÌ5ӻ_? ׃O4Xעd֖+I1nGt r G;s8Щh4jRdg$ufTUsK/9cԛ?i\rqD6eC6i 'NO5#mv]IѤI,9;@oEѫ**V軆u{ef˵\UFm#7|^r-l )@oߵ$y'frɤpࡻڶy+>"ȣRvm9rBUU.BzAp91tPǝ>zӼ0ߘǴ" MÏĪO!![F;nirs.ܘ-/MmbqX=-vCfONg;GWu׭wߟy≿!&MCIIn]1)3̲߭Aq )((`p |gl8q"~-3gdŊ|ߥϘ1?H$gAw'2~JٔǗ{ɧbcL]iGO1n ttW%W\t9K/x* fԩ̙g}.E+G|CCRRb #^[LjgwOeF{uygcgS s՘0ݽmhEffG=7={vXk2s=Ùg;s=iGݼy |r<uG!gNt () dZt.m " -b= `KS_4O`Oii``0&e |z箔hH[kPgEP:wi:T.'ON%2,T4~R?*UUU 6w1MD"Annn2ǩu]G׽N#N#77>AC3H"HlmtS}1Ǵ}򲽻 jD(++㣏OfKG1u-wgR:p<+q DwWo,W Y}KG/@ p$W Gh`+=g=7Kѳ_/ڬB=C'9yꨇy =v>{''F F ޘya5lk({z{@Jwn{{Ҿ΄ mӓ MOvUM6ʕqA#wZV/Wu4M/?BQ=.t;ycl޼`-2T.\NSHFf'}᠃"+0{KӜk1> 34e:>Żͣ"ݓGAMMy{>zrr ׯ|>?{'{/α? WCMG,_u C`,V5="▉͌/4w['ǩ1vM~º[СawL4>55 ,UJ(lQ\q[Hc`4PQ^PMu:|q ncdbo>l%=Qx=_'.x Y+_d|^ Oǧ\)3g#hGQAMM ={0 #((( kW@vkkkEsP~Ȥ:|?BEk%9v`K |I'+#\`G>3>̞XҶUEAJ?g֬+/#+3Cw]«o^Ǐā8@twϷ[\e'ݯڷy\%3;($1l#By XS5 iy˲m+Y~c˻V2$ W+A@s90n~384LW2F30?տH05wHEQ2 IDAT|>~?^׋Iݙ־ʶn ,Z`„ lذgyÇTʡ={6G}4iw]"aBk^ PG8V8DM1̢Sɞr!B}A]Σ0#,X, {/̯pGw hvnxg94 # Fu-"7OrϮew1L.1(3{u k,Lx F $@ iMZ\p;7Vb&Jv/n8NŌ$+Uލdrc\$orTTQքCHl9~USyuϜ3OS4tYu}Vb4X/P ߿7߆#n½rKk] ᅨ7 iW!oG_ Xь㾦>8mlṇkRtR/<>Qɓgi77%:}4fggi&ܾ}{qR˗FFFP(ӟ"T O{p=˗{\0(4!ɖtz)>[khħVc@@OZ,>=33)__>I|Iڵ)۬ꋟ,~sݟfp&n;I|cS O-~}wߏq?@>3 7,4(.Xc{ <hV-#ϋ54!>2ecUB-_mǯ8$k_:{_<֭%ߵy[TC-:j4MK_z-_atwwp=In}}۾zhljbf/[lhtmۯyuJ;u ?|trsgjv߿?ГGg4_S@oP7ѿvӡy1^Z,{MI<ӱ9C꾅ϵ]Z%$pq%-w\uEmmkԗJafdƪB[/8\@nan>[xO(^m:ar9߾Sie5~'Zߎ(4 xpm|dSm\ǃ[к2X\DzBovŰj8uꇁcjӠ-DV,l~w0߹/ck|`n1,[Y)X`mj*eԄFnҚ|nq_jVFꏟw4߅e WOczzmmkn]~46u:޽azŏZo^}_Aa$2QlSaUIl@;xM^bΟڵk… | cX:uG 4ݝm: /`w #+sfsfs%rYz-v7nA%[_эÊ׉ӐвJˋ%DߵO=,,}kJ /w_+wYU wGuBOW2ٿ7"""""""?BuvnQi`""""""""BDDDDDDD$;\$c dR7s'DDDDDDDT_zQX U:[`d08=YSطIhBP(p1j6cxQ otO򷥝[4 +R3Vnc1<tߕrn5D v2>U/m^sxG~J%vD\xv6Em³ )N7~[o^?³ -W24w*csx;˭|"" Ʌ 'u}t2_~b?""".Se˛mɞ~_ |?DVrb /3~ į^b@DD$sR۰abxAFg)?[zs7l祃$j.v6l)YaÖ@/OqY~wIsKp!"駃; #""ۡQl?kF"Wp)~&zpN:MVx*g^o??zW_J )SSW*z.q\"""N.~̰ /J#""~|N_.vήAndgy;sz~:';~nqZ^%R)[x%do]_O&14GQ]q0ھL3OxNˎ[Ks3ָ|K{{dq"3ooHa *m[>Y-^ʰX񳊗x&=سK/;\e(mJӳ ccDž2r;[ā.DDDDDDTS sӳ=;\+aߝ.8t`8p""""""9 3GT1jGT0ZFÅj!!#"N#h۱ v?)/rbxw<;R3#\FGOa߾'i AP,MӠLKfXsVF4L$/7a{,?q3ɈieJobLcOUyEӮN7g8zBDDDD l)pAc\2Vȸi]Ԩx$i>xJWEg]F0$<+neODDDDT3s5:;{˖wvbj\vx9bgzC;.H"T_;ȤӘ81[3)<ݛhljb(TsO)2~)M$6H$6,|N6#&a[5[Et;5շ5*\iHCDKSڽnU2|RYcfٱ<ՕX˞j xqkfi>mػiv&A..){tӼ,|Y/~6~9mk~]:Da\ogy1gF/yIFx<չ593t_udis%-p35\.LR.p[շŋKqZ'y`w\_EÐ9}eA4#VD%O%REӪ #HvY9^Wt;]Hn_f4ΟE#()Ev''O-UzL7n!*<4VKJߺ9asX q'DDDDwk&f*3IeJ_5e:ƋӜjxL|kg'QP-$Ez9\T6r6&U p5oy̭>"42oFJx:S~vsYѽe+Z::,׭L`ݦ>f"Qzˆ [lqZ"!un"*m+1yKo9vKU91ev <:[¾E)su*{""""'&<Գh鈗u c1f"Q-E#NAPp\^'sKH^oor=-IĢA'A묗8ysLF~۪Ie'^'j92S~yʺȨ3^} 'O)tıb11200CFelx9#""""""6z wBP[j._MfODDDDDDQQ7O)Dz'"^Lj(*8…#\H2;;;w*ϴ+WyJQ2ُC -~9r5H{_jxCC"?>xWjxs#G74K_sԗ{JQv~WD"""""" 97lhol~##!#" `nn;:tz ]g2Yi7׶cRzlҺ"_X*6qJ1Mfϼ_Yu[<0O$_h98qWi u9H5kaqA|~9k^WQ(c"""}W'/͗ǭHWcڙ`)Rs\tMN'q}4_fᴟvNۚyecuzYFhIвn'uT~^)VqYAogYeܜNV9Q}ˤxJ:[fj_y\H]boOmc勾{itڮR+Ȉh>D+՝.26|bUڡ✳a^n+_s֨_~6knLOQ <ŒR.Rd|r⫫oqyWW&'O6/Q|b߸oP$(ZVLjZ=JODDD$LqUf"u=i+02~үGDQ4WEĩ$9:jyB-"""f-$Ez6o__TU606&U Avkb}DoQfJGQU":?+Y6m+("""{VttX[ۙM}$E0% n311ZQC؝׹uTL趭~/ǬV/z'?U"/W/09$|^ש72FQDDDTbMMxg/lٻ4b$E0%[Gݝ,Y?>>"v$eA&]ˊmYnyj7aEuK]9&#m2v5˘6Vꡊ(""""?Z;x0q_BKG,Caߝ.8t`;\Ǝ-;.j_""""""jwz ,q V]"EDDDDDDu"},{"#\8…$.sL[rk٪%8t2.Ǒ#Y$y74t,^w77r4pc@5WI}iyE$"""""ȑiai3nˆaG˖;:r<r<2,2 08C׭u}&E:\~Czxm;v-&O)259U[+3t]G>!#"N#h۱k! t,MݝGLK͌p=}i/B={xQ$""""""r55E4躮JTշL:#5Ck[ѽ9Ʀ&fB5"Db#._>Dbc˗Z~4. 1L{Ɩ{ng?[~ -n2~"䫗<-{=: dQ.Q^^duH\9//籗9J"""K|ڱwhL09\.]:S&yY Kr˯0i[FU:D17w 2:?hwU瓌:*c?/y sk~N^^g<=W:D;vyj,"""?[rmc&).wlذvu*o)ro^` m[\ *z'?U"/W/ǰHUU ^?ׇ x2;HSeX~&;=Vᅙg"ǓM^N8XŘ&U 3Kًl'Z0wiZV˰'DDDD_M=bʕeFNFc5M U*txMC jUxvDiWF|!FcDü^ZjMb׸-[ًs%=:.QH 1Fu~FlDAI2QHc)a'T'U[3)7SWIm.\8ddtEWM٣ ֨qVT O P*÷f"Qzˆ [wjhX [7sPm[/^Y̓\zG~)N~D^M-^a.[sFi^\vWUiM9e.ל0˞jK O<,Z:e-{?XHF~K%GP(y= tL(۬dܠMoy)//?h'/qu/?u[9='2%'~ÐQn~'ONMDDDdڙS'pZ:׏e tC26vlqUX лm`[(-]b/&'"^s(*)ETXDT^LjjGp IVS#\fggq]噶r """""""U3O)J&q;e\2ُ#GI{K ohX';J onh~#fkRsO) ݏHDDDDD$#180fVݖ 폖-wOury9ryd2Yd2app't][O?L&t:;~vZJMZRdkX?7r>Vg麎|>=C>G6E6F&ѶcBLX|û;?ٙח2:z = MӔ_ x{HDDDDDDDjjiu]yR39DDDDDDDdO)R0F=NUxadGӴW7Vi1I1ÌxJWVHF0$˂MTHډfpk@tv-ԹLM+[^VK}Q[7*ѱDՁ۵ɤӘ81[3)<ݛhljb(TsO)2~)O$6H$6,|w/~Gn1jlYvv3okdp!)3E:?W/y.ZNiz\UuȬ29H]Rgz~atNϠq]7_zf#]֎FkgHMrҙG79b^Hl\ .V bkNn紭Wv=[#и.2PFO|w_u>ɨ2Oǰ:d"i s/yθ?9ˤxJ:[fj_y\H]boO{y`h2𻯌8qĊD|%2G]tQasO ת>^BDDDn|t]\wczOgfu"哓_]]}%뺺09yST4ddq3rI2QHc)a2|^$Ֆ[3)7SWIm򯺲GDiZS5DC:զvk f"u=n7ۺ5e7f#m r닟F}DQfJGQU"*ODqd̼{VttX[ۙM}$E0% 8nc[n0sPm[ƍcV+$^is*~ӫrtc휑q~"%?VVFQ O<,Z:e-{?XHF~K%GJPq[dB][dVg麎|>=C>G6E6F&ѶcBLX|û;?ٙח2:z = MӔ_ x{HDDDDDDDjjiu]yR39DDDDDDDdO)R0F=NUxadGӴW7Vi1I1ÌIh """R54v4Z; EjzKΔ=i^m4|_`fᴟvNu:n ?z8à ,4zs?e7WO2ꨌS1%秊23ߢ緹SAE=Ȍ5?DsA'A^u[g7DDD]to\Ig LM+/ 19\wu-i \x?d:/_+ h2𻯌8ݯnaSJgѴ"l(6EFc -\s's zz9P]|xWt;]n_f4ΟE#()Ev''O-P(WܸYi!x˅'D!.u>F5>%*qf<5r\3uH]pF._e6ZCiZS5_S*U""""Zׯ'Is85ṭ7;3'h\TSF\#dew |aY'_a7XܯqH'IT:d^ou3 Y˝-vsiQu޲-v&nS3I(p eÆ-MKD mnOe:doyyмp$>Bq')|5"AJ=ǜ&;g 3H܂m&VYiS~ᴭp;xIz[kȿz5LVaZb$[ǒrmq,r|nDDDDDD@S4MScZdTSgHGІ(51=[lH^G4ݶQv:t9y烟SVq9Hi:0r}}5Jb;+ceˌU Y8z m4+s><!sK#7qxVC+.sZ'0HDDDD$K͏p-[ًs%=:o@Ugh޸y?kH}Ո [o~]4nw""""I1qbfRxhm+7'ČQwSM&AYK"/E"dg-gEO|NaXѹ^iq9]7N>yD)Q { _fz/<3^n"""""{W'/͗ǭHWcڙ`)2:z }_~ptc'sɩ齟:;*\_xϾ_cy rcI_;?s bO(^3'.-8ȪI$duգL:7^|]+Y~35}ϰP>tJڱC4jyWW/p)nwKFQ-X5n~?QM'QZuݘx,p\09y#fr֭zia0w@~AWosADDD}fGKL]ebubͅ '˖QA?{TC5_Gn#"""hkiow\&`&)k4n_vE1_zmWahkG%;6IpCDDD]h\3uI Lwlذv `bbԵÅOM_^o)ʸ-doy:iӱauF"""zkjO=xYgϠ1c&)[Gݝ,Y?>>BPqZX-32Qh*$nA6ȠMݶ^oJDDD]kgO&N+ShcC_?b_U #\Ǝ[.3֩mi{KsÊTGV8iYEOc,m7EnȖzKj ,ފt4mb+ר瑌53UKG~lH״뼄_itȨmi)wKSqEkzDDDDDT o+7i.G}:{/)^"ݶ"J"""""""*O!evvwU+WH; ?(AQSncIVH;bx[QudZ~9r5Gr!#"N#h۱k! t,MݝGLR;\FGOa߾'i 8:fC]޼\Vȱ贽:wD[.A'"""""${"\/p4 >!ԌKyV}j$noE7>",Z.ˈE_ML[i%qUU9:|_xʊy]1N"9Vr=t;zyLW*J_U[AΡ}y9?*fprʕ1}NF]5v(eR $:8D;SSd?Uy*\K*; DWmy\rg{*lJ;\:;{h^ًs%=ed|Y&"ChZ"CDDT 24&NL mE$15=EYK"/E"5VۆuKQw[lW~cG%|T]R^no~Gs\$:#znj#yni%""rW'/͗ǭHWcڙ`)pܤ ;\KΔ=J$6Ҟ IDAT3%뭶5/E;[]7n㴝S1@sX$|qq薑 'Rw_~cW^vM׺f3^Gx"lcy[qfg Ȗ7^|nqIzӫ*:\:QܞQSAΫ(n C8; dnĎreuĉpe9]D {N8%""#}8bB[˫;\09yJjFZ5\ADji`m{=N;IQ켬ֺf>9VIDDTnͤL]e&)45u{zceQ1 Q55*q,"T*:tqG%JTK)NeN""kiow\&`&)L{ߡC.6l_yqq 0D~1>^1޲\W(U2By}]N/~h>I\l1N['Υ-SKe&""׽e+Z::pjH LR$=Oߪp(G;Q E:\ rmˋ:;6n[cۥ /[T?1nJo-.v6&9C29xD'|uJӺil ""g&<ԳxqꕒΖAc,~b100໳exxXJ*vKtw'K֍xztX_O11vx! Zםn)cbU?  iz͒1k?e$}2'Y!z+-do%""ڙS'pZ:׏eOe}w Сp;%̼~lxU|sRaG Q}6DDDz wwB#[O)%-mǧU' '""""{þ:[#\d喢rㄸ[qWVaõϱ9 (ϕBDDD%_߲}o ᴽrxj;8yM'Q9\fggq]噶r """""""U3#\~:NhLȑìATX(J{} td]͍ o,9~UR_j)Eaڽq^QT9r; ,Y2۲cؾѲN麎\.|>\.L&L&t:9 u>"Nc~_!=cſŧύŪ~#CfMdmصS:_ϣyv&fF¾}OB4B^Ǟ=(Qit]Wi kي $&Q6Da4V~ OYq33oV햙5TԝUqy2W}Q l)pO;vح[NTo9$2`l8]gZVq}F~1_F{:@DDDDxǶai?/DD~˲#^F#EX/I&ƙc?3~l&LQ, #\>3؈˗"E~^k^8NT~h~cGD%|8٨v:4s}yo YT9 vdG :yo8~@o 8>u9[BTx&J]CYDDDTi-$Ero.?Ha~NXJ]I!_AD~{Gdf%G:j^FF^ö&HfY=Ȭ{VttX[ۙM}$Erh &&F+:iȻy[Gdnۊ~q˿/m۶<|tZDgJ?1ev=?Q|rH8*BqeLlWv ""kjO=xYgϠ1c&).47~N۹M(cD0N$, knѶvzDnC$N^._~skIHudtSz,㜓QDo\͠uGkgO&N+ShcC_?b?(3<_8" srKi#OYDTx#""".,t ADDDDDD2;;;w*ϴ+W昰3hI<(ǡCqd?9\ו'/`tǸ{7o3y74t,^w77r4pc@5WI}ibOΠyV=غu-?%ȳ#Gcppa:ˬ-:-[sdd2H3N]~BuLtwp ص.->װ~n(Vm}<u|z.|>l6l:L&omǮ4ұ2/7/ww~ͳ3/53et{2yD x{Xå8y.MӠLKfXs,򞈈)E Rfc> C'/y[|ucd%+>na]/3NDdGU'2Yh܌ˣp B^<5bY<ރ+Wl1{J;[i* iZ=qȜ yvɊwS,JC+t8Vu-"""""9jf/͝_;;{15udxlY5vVihhXǥZ*NBT>7e'#N0jiTCXX+4IDDTKctt Z[b˖-&fL:#5Ck[ѽ9ƦHܺ6OY}gi:u33װvƯRd2HlgHltZ\Y/AG0Nj.~mXj4?ĶmBe䟗 Nnuɜ8z)qZUAF=U msĩ샜a7EE~/nsA:Tmuz3%""7.L^@*hoo׿D'3 xqkfi>mػiv&*鋓87qR~ Úxw%ʷpemmW6jzKΔ=J$6ҥ3KoKs0i[#Qkkhkkg>Ǐ/;_%/6ȢGz'VA<2;_DE~Y􉜟qqug:DDD޽4Y,ol6LrIƋϕt4r\nͤo_:/qIg 0o}O/ s(4m[SiDz.r}5|ֹ407Fh6o42Vu Y#|&dQFFF13srի=Lr0>:ۦΌ8b81j.>UQ%ՐNמ(_AADDT}RWInͤLU6n]qtE73se}vq~… _3cadd$УeJHU׽((GEͷTKvp渾s8iiow\&l\_9\[]}7֯\yO؆g׀RocEH<\*q3RvQhz"f-[anmg6U>~6Bk:xx㦊o~Nx=ђLL.߰aK0~qwo^4Bt"EmE;T CC y_#x Ct2Mۇ0]й)ӠwbcKu2O*3=Q*QmJ~k'IZ!"" CSS >4Ζ52ĚSϢ cƯ1Ϡ|;_Z .:[~w1~QТ_? lɒ#u]?'5OSӀ6v;OIhO%' *&r]T[cɨ"yuB]/yNAUt-G?w~EٓUNO1:zSSWw`~blڙS'pZ:׏e- 3Q\z-mDzHogg8u \6oBCCr~þ;]pww,$4k/@CơDT35^󉈈'k#l#l*1CnXȻBQFl݆O'.a둊֭[Ln^{Kb/w"Z"""" * srKQg ?ˈGpK iXՊ2;;;w*ϴ+W|8Kㅈj)Ed?z'K&qẮ<|'NO~qQDDDDD{/5cR+5%ǯJK=(L=B]_  o޽{] """""Ϟ}i|s{}_w9=׿G}%SC7/u\|\LLtsss ]סO>"Nc~_!=cſŧύŪ~#CfMdmصS:O%rz_ na]/3NDl+VT:U^HxA IT58%HJ;\+cBˊ;+-\ zRdNj˟Z9*}~{c9pY>|3_|̣&m9¥\&ƙc?3~l&8;|,rK?>@jzK"vy}qg--QbEK{/ϼ6_ jO} ,bSzwsZLk}TTE|6zrUz&6ۍ.:33*JDD؍pY~yf?Z[..sϽK.m.N^/=[33Vcڙx/Nĭk} Úxw%ʷpemmW6j)Ev#.or4qPbkQa~7ć^On!5(ZOGz*;O5.2οSVny.8ZWEv*nvϑ Dfu#LDDmV#\/_c5%Ǿ}_A6-Yǧ-ɤxpЙ7S8 ڷ +^fYnͤo~?Fòe_:/1_Q<'x`zJQcxmCB? /\W\_)vKݭ)A+jU]8TZeŸcܜ^t5iv9U?K<ê;3+[|f 3DD$Se-EH&-SufݘĉQLpe-Nӧ[#\֙;c&' uݺ~tu-t/jBx衇?}GNi#*K>9VUDMЧUS¾.>S8j}DD>.ttر,%fRogڌKѽ%Y\sY?0%7….^ oƇN'p#F*q ײ/QkL((T7z9uIN<(|VsLO;7/_*[9\;_OT6~s,Ŀsuo?"`e͋֯,]Nj72n(@ }.VCeN&îkG,0s`+Cf1]TrX%ϋ.DDTݬFi/]©S˖)EKlEKG庵 Wt ፛*͛m;][O)[71tZwwrqYP(y/Ƒ[)v"ۊ~97W@{x4SZ4EpWÈcXra,7?iTe2?]O] ??{u74Hd@$@hR #%;:$vUwoJ{D+۹[AK.{T*{+t|U"ɢH/H /$fTC==ݧ9}gB3}sg&3G\3jKՇbuQw@u25uMʷͲ }rt#̑?mߓe-_}[4{TMgWS?S'?Zl?HSSSUq2{lyoOoS[?&zlp)ҶmOܹsd˖ǥSBxG~w~[{krŊ}֯Cim v='/BCR ĉdΜdڷR->[wokk ٳ;U20pRC[<gߒ E~}Z25uMdrrJΟ?/6=,bQR;$Ţ5K.˙3#k>Oׯ]o˙i]!-=~7v*WdQ'+̿b(R~]ڵkrmrRd1in!PR$׮]Aimk5cfUsmrR\$ƇeӦ}%ouT*޽)ڵk28xRۤ5k2^ZZ-<˙3#iپG299%[>.i{N&>\-+suy7.fϖ w#|$/kjz=-*_o]sgJC}Kgp!;AX IDAT mt\OO ,m<ط_˓O~踧KgeH[\ RADx{.pfEDJ_~'ep2>>..]Ny>""s7~??w`zz%'Rlu[n<̰̖eZxW'.SSSFǝ>}F~>o)?ņ׋M7hy%==U6BWV|s5V"j~-MxZim]###RWN\͏J!).Jc3/3)zM#_rZ2<|$ռR(bۅa"C*"-Tjm+W'w}-tPȬyٔMu̬Y) 2kV!QzJmwG%#;l<(O\IX>>qzUGYń*<-F2f?;HXy{U;KGm28x0c- dEdv_x!W宵8˾v3Y̪QiYH;p{Kѱcbq- nc],VTE{(V&w:U{TT g,cZ'CCòr 뮻d94I9ܿOFeJYwg4͙׿OFO˒+d;)?߱399)Ӳbrި]>_l"ĉw؋Kv S鄽!Qow/|}LTwLJӡOhaXl'ƤۮiEQŎ1{GI@YӼq9T;Hȑ@>z.I8y'}鲶v*+;^Sǎ=}=Q.]&Odر33ϵ-[Hr2s_];tj͢w|l8T*'ikk_|͊`R/_""r)k׮H S۾[""rv?ׯW|Xl/wr&''婧_}~F?5aG- {E~iPs,Cewy,{#-n)ɇ=AY{pCtMʐi 3W疸m\@Ǿ}}2<|&tɓ-IP> ,fxFNZ};;4$Gjz뀜93mhhXbhS .klGnWmƋC"W˩SW^VK,tH&zC%9/;\.ںu=rpJ%,.u-q꾰{wehdU]ooKC[E4N]v OԢf1b:D-9f1vEFO;peΜ|dpdb˷M=FR=g_o,[lߒٳWMgWS?Öwt|O)gϖ'>./_I1:3\Kɓdժe|ˑnٹ[~l)I\zUΟ_9{(vv~iz{No_8MWoy7FS,/ #;\/MГEywd޼qYKo (6=7Ԕ>Ȉq<}ϫ+rLO_קejLMM䔜?^6mzXb|<5uM&''ҥr̈>Qי޷,de)+2==-ezzZ]&&'ejjJ\OF+걗ޕKdpvc6" .}}eG3R$;v<#_2Hg.P(hvCCḊ+| Zh Bf0˦lcŖb1Yt˕fIG,wxpQ4nwY|}l.񪪏N]蓤5iCʘxg z6<yLp{Gm4.M^hۉuNb+@]kqU_}Y8?gPZLcsӺJ̸;;qٹA!jV/0|Fn,̚ +;Cꅪ=NQX>Oc>`RdhhXV\!wu̝;459)𐴬X)쑦9srUaY|x45;v&''e2<|ZVX.c-O=oOAzzeW;ĉw հܮ^FEwOjXNSޑHt:I:^Uߤo +CTMۘt524cbKzTy &u 2yQT|{uI5I.ZwQw CChoooI꤁btY[|?]U/ߩcGl?'|UGwqyrVʖ-$mmm5b[z{rRسgm۞sȖ-Kgo-YQbQС9 r-]iΜ;~ ?)ٺdwxEodX7ɵkܹq)>aHt%L}1q!`<ܐ=_/'7~BEԾ" .5T)KR,uo_sU9@fOШCsm/+V̓?^>4* ~-4o)aHg7,8ƂK* plY`,Yr̟1Csk>V g˲ehr2W>2kVAff%V(d\J@p[cpٷ_7LtKo] mvTWc}a?""/x6yO5|pKZmHE /тbP(4L}_gb˜9s>~wKvzNV?Y |hnT%XD ~B_ V\hT޾.Slۄq^yl[OT1f%jZ.3%mTPfi)hXH7lƔ.}::nvt6UޱEnܙ|..}So);\oU۟L?c,,~i`X,"#Jw#P_GmE{`ݙ4Kqfv.*ݻGx3""wo'?ٖf?6/QG0tEjCf .'N<&-Tq;ZioBWCDD^}=KK|fX:4afqTߞ8tuݮ;aƪnyLԞ-tW5ڴG/WHe~&y[?Ծ\|KpN殄p~a˞Wz!4-UmTۂW/̔{Swww8;$m~WjO\YQ;`n/UtRk\}FۈTSm +Sض 徺mCskl۰mQ A 4o)ڗ;v`慫vW/w߯kK^fo/GxU)ea}6/U#;\ݯǿ=ѣK#itnp'웋lR"3Ͽz}s}I+~Tq_T[ﹸK'F0}U:ՈA@dF7xQk?1mqUϛYN9r-P,D3\N^]{gc&i@UpKJÅ4.\R‚ h\\zz?/agIzzm /o5|p\l[5ZdK{ F=SoU\n[5RdѮK޻xGV̢ b1\c1\K-E?>@Kzu}H-[u#""]-x-BA[-"(<jCOOon]O_~ټQ) ǖJ%ٱ4 ޚ՝jrUB bi9?PkI5,XTEy?\Xp͢ ܪ;\:;7(3ȗWqj-E& r;VCł .ԥߖ\#$Xpb z5k6}؁Vc湨}n;vlo͚r؁o?o1%/@p6!@\X.y#Gޒ[o#Gު8,zk7@ .\,PSl\{k.Ks}OU[֭Çhd n]Os\0];=^gx Tw:Isоs|yD:~,E.c .,ǜ-;wN\j|@m$d[~Ht$J#$Ք }K#_d/ȦMg w$' .}}eGP([*dǎg_LniqvKPbh|аa~[̝X&'gF.q ?>j~af7ic-TTG|ZmW+}*guɿcEӎn.94\#_]jXĵit* U}b3nngtL\,EoW˦m~&ݴ[?TQMp 6c6ϓۼTǴm$I|Z,/-{_\CU6U;ߦۤwɾpi.9Ǥ}T}"Ӛ;]jmu۞g\ŹE؎w`ma2Lܼ,Z4mKU^g3Hr= L\|sk⓬KFy\4"RJOz[sզxe ?d $U,h~VNQj_&[_rĆzl&9I7be?Ib5,fŶ_JǶ/tqsqy0i[$qfyLKre:dz yKѥK#3oDF0M/`~%nmW2 ʟv@ܾPkyS>W}b;u3MuHIڣ绬ElczƵvs՞G\W؜cmI-j~b4[]ž=?+m̝;Gly\:;;޹nZ? =5xbʡC* v='*{塇M'rrxLA|1[OmF5KGq}drrJn}Bf,TT9x@hK[:Ky>""YB?-ܲ\4;DǴ16 WvxXpɁ 3+υ ù?)˸q|W}s*Kf̫\Wȋ, g .I IDATr㚛o)ɂKOOl}-ӊghMy)ܗY^{i~6AɂK_~ټQ) ǖJ%ٱgδyKH;\ Eㆆi,ŷgVd4/^%'͟*mayOp}h k;jj 62rLռl&ﺞ& 7MeYS=y*?`lmQKq8ԲpYG]\)|B7;"?ex{}##3/dN>"+VL;ǵGBN~kj&mzbڲʟzĈ*ϸC81v|\ dN=L0<[gUō f {m2wٲqН;*֭c_/m_7C=1qAvzN*wl@~W.]"?[y+ ?)ٺtp9xMDDgڀYGU:әV<@͂ԵL+u~qhe*ӊgh\+57l@4' .==ݲs糉?|:?8RM,ݻ_4?Pv~I:N\͏JP0>T*Ɏo2mbHT8åP(X-b HXʴYGn(yZձT:o^K~W9;.2+w0mUJ7ƒėn z._ucR~/n#컨ekz}LS$ORk9Λ}\.ttVxpbMUZW=Ҳ~7,}rEO0`THW+WFaT]\&bǦ]+.JĠ빩y]~oϪ:$9GsaiGj[=RXKKyy^MZ.zn4[rϹYp V,ζjEus2|l~/gk~Rb`,$/izzXpѩG/sB;6FYp6ӼTk<@zSVy+<:?'NS\pckn^&*ۮ*C6ݼutiberHYQeG.(c9Qŵ[Ծfy3;:aiŕU}Lc$lctj`?cX\yT$S:\'nm21U?Gg9Ȥ_uФyd؜\ω~KkKIʣ9ӱkn缤1"LsVy5mP|j[Vk,ƅYmM_ܠNZGJ3]]ů?JU>7*/[=atn3oJ:wx &`U/ݢx̶`xϩ+C&NR`GSرIp+QՏ&j\)6`q3φ=v9f9vr}HztJuΰK6֯459.ߦLyI* sVy5`r!a-kk4E\}7tBu.Ts=m]\Ʋ`YU_pYfǎO.\./ e驶m[7 [ϔ՟[nY[ c{鴵IU}tBg|2*]U]-kqe{/.MbX1ISwGM:뎱qaN47;\֭ÇŋW=660s̶iit.Q,Nڶi&~cce+M vwUeoS[VǪ֩8QN0^9m3NW;[Z:+,N)6q}f:;,qc3\;cJg.Ƕ 4Iqi!I_c+mTJԼS}ug릟ɥ;g5/۰שi\岬Is\Nc1ư79XNz"]^wfr-Qسgm۞sȖ-Kgg;wT֭[+Ǿ&/^g޲LJ+{<1qAvzN|J-]%'"FsOɜ20.7d%G}l#[H3\|3v:-[-g7J9rNи\i5e`\p ;U\ǎeV=f@s ^Xjm]\\k>yQZIPL;Wa1@͂d:?8-Wkn/"".]δYnٹDǟ93ių4dӦ3k2Ԇݻ_pyR(-Jc3/LX,E p) VCC""R,fuhYGn(ɱիcm7%tX}KGYßOv=](|VzmO.Omܚe,p.Yt6^aqW/Rm;e;\ne\x&qpN~/83@wW~/v-JNxLh?:q\t$ :CԾ:xi{3/.Lӱm5LgrѯiI6nmc9!1<̇YiΥ ~|Ñ ҋ|>…oey>&SU1Q]0, J3,ayiߪς+C{_\ߥQGx0$^tUim{ٌCU?qg:5նLj8v76c[wn7ͻc\wm44oRr[FdAG7C`J dbbH;]C3W VFn[-rmz3Iytvۤ QyŵuΤM;TOkܙyIڪ-y7.qf;uχy6yϥňYpsUw.\ڪKgs{^ǸW}^ps)`%KDD֮s湵kOx*?|e|,Z.'~D6XxUqmqܦ[<]>c2D>zx1j!$L5nWxݺ9|/"cc38c1mal/xWjii4W}+i:l_v5-NU0mo#XQ1d|'tb8,OݶظWAҶJ:o'TUƍɼ4lMc܋Ӱ{k:sɘWسgm۞sȖ-Kgg;wT֭[+Ǿ&/^T~}:칉 ks3o=ȅKdtz_#EN]AҥKw#|EپG299%[>ݷ/\,^}?;Z^4^ԤEuL:iE|:/f\mYuk&'WT:u).LŘisWf7iict-MbE1/x.~ǎ>6nGn3)*o?_v*o݋A*mܽhVa-Xc;<҈j7ϟ`[Q\K7.^DҷYЌ*i=Mʥ;ݼƣi&mRcz=mgLp1I3lWnӻ{k6?ර-*{S6ӾӍP#y0?@['M۪҉mIqܧws]s%Kb+^ɴYGS^ u~+j4,͛B`|lT;OmʴyKH;\ EㆆEpcJO^|rŊ?am7,s|y$mOXu['ȉu)c+/|]C[gQy8(踭Ac_WLs\Wz>.ڧ'._-uˬ۶&2Ffڿ`n{2C\86ըU)Oeyzi+ȥIDAT͢5$շ=w;o)*i<6c-#1ωqiִ-J!DžiӦ&oTTmb[U׶}T/1{ωXxyhH+bմݓmm3Uj׸1hIW$W'nS6}АV{ĞMWscj/uUuضI n,!$Ƶɹ)ɵn:p\\g^\?[JP{|Gf姳z{_>ujf˧NUa~ԩcuO<ˎlS7^6-Oiv:Q=>$NM_XՍ6ƴW}f%Txx0ϥq7+:cL5;?U%{ ƢNIƼ:_OܼFؤ:1m:uHN׺&W8kӹtnp?;\Vc'CsMJQS2Sf~jo.oveU>U<$>qQVIsQi?n1[$ s-,G~k`nq1cv=E}hnIub8mƎn-<_ꌍy*>q&:W6`Q[wMa6}kq1w8ƈNǕ~5k6ѣ#WS;J=r;\T^:yR>~UɓǪԪU/HT^uUIYSuYM?CFF}K7X>/V}jce|'퇨~ 6Q<1s1XkֱaqU6~7[ZfY/Mc\gͶ2i 9rvyMjujx3Swqg PwR_p9r䭊mz`1XWLOЧ;:A?Vݤ<>jUEؖUUORVbDa-I~/:^ئ_rUVױc#WMT>^9lE|V_):5]N-do|7՚#xXHƵl4ay;7yiwuUCsÞ+ʴĉIO9F-Jvs P_\+2Մm'Notu-Ml:阴w\yROM˪?XǸ6 [u6u~i/ǺK3i+qe2L/ӲƯI;' 3+{]<Y/U*n m?/Uz2 Vs(0VPDZ1M,د,]D~[3S:"per22?Pr2>>./_1>yLMMex2Ԇyq-;w>/eڀ 24ӟ,i~6 '8Yp/7?*BR$;v<#3mbHT8åP(X-b H) . %"c{.}]04u/fpQǫir6}V:ȢNi#6F]3SyU .78x0(w/Z$o?otNY6/m _q;.qy Imc8tT9Yo>20n 20n腑Œ 4-7ǝ?.?7#$L"",^3,mcTl1MUcԱQǍ\cTyؤ-:eЍ IQeøJ˴Ot_T崉-)I߸gQ5@\VC;тkccr_K66&RioŔ͂kccxg`r_KKY]maeMDe웸o.~uҍ냸2ejǸ򄵍nyLW1ؤC8b3~Fm*{\t?yI7`ZyQ3|\/6z~SҾI:΢ƒi^3z%"[}ulqNTDž=g.MeB/./v~eˬRw[ƸOR=b[֬-83[]\pn9zt*o*՝ȯ-[&Tk./H豪m6}3\T-Gqy䩎6eb:1g{ciٴ.YƄX3j$eMc릙$oc8Jk傋ξ,_.{Ϝy˝,aEU&9cuƂK\ÂI}EDֲǪ%,M~c L7.Emdߨ aǫRt :+M ƀ?Ѥ,qcN$eK2^]O0`I7]tN'v4g'_tj[66w5M>#ǤQmyT<ž=?+m̝;Gly\:;;޹nZ? =5xb>ʡC"Ә v='Qfxue~<./:E(7ccuf^[3XtQ5w?\nb"Y-1*۳hWlŵkPNqhSWc i7ݕQut9Վ8tgZ4潴Σt8]Ow}S+Z-tvnw+`ԓpIj?dI~޼zuLͻիc{=?^8.DnЇ9nTu+oTTy$i{y}^fۿ^Mc:iXc;umؾVcU|ƵNڌNRvIWhTƑM Sv95-yX0ߨyT*LƲm}3Ov ܟjnIrөcNq8[6eRu- Ȱ 3Q'bvi{d?i^ĀI]oǘn]\ğ6cALc6tZn{,j k;eb:Ϙ$c4j֮aYm4+"7^M-*ggq:ۢ~/WqDթyYٶeFKm*:oXrgQlZZ1U\ğ˱;b[0,Ho6*&LƧn'cs1{N"XJ#nkW$e.WkTIƜ5a9*4, .碎UZs$47/KF5)^2mokn^(],I<& ݶ Cq<c?cv>TkZ>mckmLJܠ:7DDB7MƘn``@oLNN֭OozKB~`OW}bN}+rXc=-ܲKv艊6w_0{iF8j߸tGGO(",4*v%VwR䴽񐤭,8_pYfJ _(䧻o5̲\44PR]p9zt"[pRtO3\.1٦DmٲZFy:={ܨ-m.qewU趓˶4p9r䭊 .##f^({@v%,l.Z[הuKNaܪvQ%ߣƤ\1a?\km]S5?ڦ_6L,Qi%#OmȏTpYGxR,c9}ӧ=^bmlzaM stTƥLؤ-t4I:m,X`:NmbڲXpqr>Yq]-ׯO+>yP>att;ƿ=*ozMUw"6u2Iǟ,m{X::j$mg~oaڢ\6z<ju-fs5yoůr.3[./?.p[a MP3 Diags - File renamer
MP3 Diags
This tool allows you to rename or create a new copy of a given MP3 file, based on the ID3V2 field values (artist, album, track number ...)
For the file renamer to work, you need at least a pattern to be defined and your files must have ID3V2 tags.
The patterns are quite similar to the ones in the tag editor, but here you cannot use relative file names (it's either "absolute" or "current directory") and you cannot have nested optional parts.
My main use for this is to have consistent naming for files (my older files have a "-" or a "." between the track number and the track title, while the newer ones don't.)
Another use is to get reasonable names for files taken off some MP3 players.
Another possible use is to add ratings to the file name, so you can tell what the rating of a file is just by looking at the name, without having to search through your MP3 player's library. Then it may be easier to build custom lists with files that you like more. If it's easier or not depends on what MP3 player you use; I guess some already have this kind of functionality.
While the file renamer normally opens one folder at a time, it is possible to get its list populated with all files that are viewable in the main window. To do that, keep CTRL pressed when launching the file renamer.
MP3Diags-1.0.12.079/doc/297_config_colors.png0000644000175000001440000003642311263041657017203 0ustar ciobiusersPNG  IHDRPbKGD pHYsȥtIME 606{ IDATx}'_RK`ċ1 Z$B 0Y|^m]f>ǝ/؋ؿ_7;k8l#m q B+  Z/]TEu^2?|{'ofVPTp]?S?*lR/-1\_z`t71Ν6~ꫯknB11j zԡCxܹsc8vZ>7k㥗^Cőx٧㥗.FFchhHE]^sgǙg.r̝;G+*\?rZX.8sQ,]<1baos}sDDġC/s>yxcdd8U U^|xb͚ Νgg1==777::ǏlgyV{p1oxŗ⥗s>33qgۖL5brxgy 1::Nkx̙3sرc/Cc=qdz:N]yuc166kF2߮rk׮eVěŜW__x1JLOG H.sϏ7͋O>ؿol߾U"?q2gtt$O?4tH,\_qu1oD|߈G?}:r1W =߮rԽˮ=/coq-΋3WMqJ]'޿㹖bΜQ= wg=z=LXΈxzG?xaoDnAę"^~<XrM9G<DžlVswϱ~111?r*իWFDK:-2>ˍpWtWq""▿J\~qƙo6qW ]+~6&)GeV/s8#EyS"b"F|ڈOE,(b;#g}VDxAD֭KǿK#˝2쪫._Sƻ_?۵ Qs~*-CTVn}髕HrBe166=wM E>| 7vKh#GG6O1663NɷuFw-?O}h.{IWE̔D񫿈~"b˿8Vϊ\.g .8x}yWj7[UtŚx`brxg{Goxc-5 'e6'"ⓟ|_XqN\|[Oؽ{o<3Le9> O=̬пb9{xŗ#U}|.8҈_ֈnk~C,X0/-:+-:+֯8,W.{;"N\b>g DD+1=}JǩgYXX|IeLS',*92=hڸߍ .XG_>!>OxE /<IJ> 'sqk˲|>>k'c||,,\n,q9R=m{[=ԉ1<'bUl|Oz#bacl.˗޽Clq,xSnm_`TViY(-OUG+CCC<w;W=mqL?~,FF%V_<GLG>?m1j/X0?9mc|w_?B.sY /$8Έc%\Ď3#nEWWV+'J_OLՕըByʿ_ʘ>9~bll,V(.p a5䙙|? Y}|nex.֯[GD~-Ω-n?8㥽{cxX E}İc' s"˿>361g\js\\zڸ>?EˍRW0NoL眳(~٪p"Ij>%,Ώ\kϙ3sF.7sbbbAű矏o瞎\nUJ{iקSfH9 ?E\.q;Nƒ166cc.u7|5K.eVygMO+ /đC"hP ϙc{ӛ\^8ao< ]mB(_|iq9o}qg͚0|겪Ga8>R^¼Z1>>7=xӛΊ ψ Έ͋W#"xCqソ8qbɁ9sg}>-zSOFFddDB+ծrc166'ZEΌ\.ccs"؜?^iʑ뙙8t`:te¿kd78W_}y޵ƿP%.s'Q~"?ˡ gufSgU2ΉsR䊿_ܹ첵zq ܹW #̈́*Gɿߕ\n|V?q+Xϟ/R̛wzzWO^rޭtOCC&&ir}W?-N?)}lS?ŋ ėaUK@' {_<؁^%KW\fc#^;3"BGK!/\sŊeg> pKϒ%$k5 z@Nt x׿M|3G>|>quDDvgqrQ6=}yyu((}]0וUtEWe?^նigLS^~^ ?M+udX:6Mknz62Mv]~Ӵ5 ?K?nI]qV]zOiXzmlmmZku7_޶iwg>;J?H|9GDƑ#Gz~睙"lЮ@&'_߿3tisњw2 z/^UvWzݎ7mcng沵rTjg^l3R_h[mvo~oҶZZslOEYβ^]F_BixToW[owz[3^=PTV:vIk]7˺lK\Tqu6)/ū2)wֿ\Nu.'οۢ1z$4Ӗ~ѽEV]o4m;ed:GῙ+I{XNtG?MChոhݼl\FҥGw͚GwŒ%ţDt[naog ~ iV_Yor6}jvβMw߱VR~x 'zA3ӴN1 g5D?]tuq.]]4]aI~ gT+_z~Uo>깑,]Y6)`6V}_GiYmۤm2zY~3\mb]jG6tѩ>4Sy_~v%){y$äkF窭G%9^lvJ!~J{Cy Y-Ӵ,D}[mꟼ!,[6i{(;?kgljj~+-SAWiʳgώ^&iƩNi׿RjQi9iA6MLi6_k}mVlVZ[Ȧ}΢>Zqʲ$~[vWZfLn*WYef]\oyewVgyd[3UW{]k#lKUF֡Vyd[\fW,6h{a$'iӬUkVFZVm2z+w,y;u>iot{e7mh~эW+V-G[Z8kHΕv[cV䉤9p??V;r床aw?Mu8a|m-$+w:N=>V]zi-*}H-OK'u>-Ӕ>ݻU.ݻhkw~[v']uUk~9^mSۼ?Kx_3IY4}g2'Nt>2S+~W:lժKN7Yf_>}+ժZ ZQn&]tZZWiGۧ|].MnYW}3n,\En}E*KzmVod;fy6oo4|w5fFUl4/vnE:/BŽdxL\tѥ_'YF|iZyV޵_o<&ve_tѥkׯGr[FM}ikI->,Iߩv]kyGvZL6Z?nklG/Z_t]~U fQW^b;6s6UOYlfڿ6xoawnM+-Ã_|E[uꕽu:z iyV<|ޮ&]>_˩Zֲ^m:7[fۼiٴ24ҿ7Zi׫mV}5RY/Ekn]Y>Zu渶Zl)˶Z^OYlf72I7wſ>Z{/_6UCxeCw71r?/N5[o->/rOWm}/>f6k;ºhv ڝ~;k z>x];~ɟ|\C/}1=}$n w~ݨ+#]۶mЮI{Pv}lqſexL7|Su?źuWzukvל1;_4,qЮ@ }]5Ǝ7c_! lЮ;~^g t@@@kj~^mx7=M&'T^lJڿgLNw:H//MTBL?7$'ze_;?Y*\W_W$WOe^J!T:PүTگ+ʙi˗v>ƭBm8^'G.#I@(:CZy$׃}\m2̷iWZOOW HzydVuA辕E?|/O撄۬uTW3|AFNJts2 Z^'N$}Z?>WɪiV4_!DuyߟoŸYMWvjkv>!ͼYopſٕ5rVtfk灶1V{Nz+{y-_s {X]y5snYFL}dU~8I~H43I3}(+=mlIDAT ? 5ڮMM7ņ un޼%hYO'0XݺŃ~3u &h&۶wu]O'0p7unܸ)"> V/OL ݰؼy|' ? ? ? @\;|rrM& stqϻqDar]s 0@ ' / IZf$]$ˬYV?@/q׻ŷ;`0}tjKWZ^u,֥ڸjdv 0x}A{VHeNs^Y$ó/OՃjW9XvE hTŭ'] i4!:ɿ :7sڸiץU&'|||`^VҪt+=v`N&@JjӕǿAw_$-O2\, @'eN`z?HY<ȮZfiF#uiz[@@@(mׂƍbÆB7oSSk,'nApº} }@Tmv;B.'_8B7n@ +ʝauyOO@@ZdTؿgu°+ /OT>!獎OT }fh5}@kտKO:t5@4@+䛜\S_I+|^izӔ޲|fj/|z[{?b]mz_5F$eJ}Xr[JTiU]t+W{DiҁٿLCB˗hRoM; K\0Pzp?򓖍Yuo|?] BJo>3W:Q>nV.Ibk]w +=myR$Z}d@?%AV Hs]i?7[V2ךߟ6d~ಙQ9x Տ$2Ϋ$IZf] + ? ? ?P4ڮMM7ņ un޼%hYO'0XݺŃ~3u &h&۶wu]O'0p7unܸ)"> V/?;+tÆb-!a011_-; ? ? ?Ȩ*5ΊWR:niK4_wNW;!P|@%nB~?}@m'J^.^4j/n|!׺ i_R E`)=1X+=I0n-=w0B?5?-:vB KnA ~mVW?@+ܒ =?@h[@@@mׂƍbÆB7oSSk,'nApº} }@Tmv;B.'_8B7n@ +ʝauyOO@@ZdTؿgu°+ /OT4H?'*Z>M0H3}҅~Yr(\Mu_j~yH (䛜\S_j'\nﱃW+mՖv/on5: $ <LTz[ X~]ғ׺ڟ4b߫iQ2\jÓλ<*=PڲҌ dڿ,]p=A|<ȯi@5nh  ? i] Z7n  ݼyKLMѲ@O`ukf  L/; >? ? MjSm۷ @O` o ݸqSD}'_8*wF_W [C>abb>Zw@@@hQU~kb Jǯ4t>Sm46SQD_+ܧ9otJ'$/>en] $@oz8dBˇ|XyUV;菘}@አہUZ_^ %Y'} {}CV څz,Io/~@G@'Wޔfu?@p.iU:XOz_/ ?'W{8_V`+]C@@&T{xz՛W f͞Kz[Zp;Axˇ{d7dOV_#}˭ ? ? ?kASSkbMau}]7o5Z V_nm La]}> }>w@@Im}-|=^NUW^yE\U@B߼j6lXDk{oСW:U_}9~?G>?LoOoˍ?Xxqokb…ug>_ѣG9t?W*x<=OsҗG⦛އ⟏+w~Dhv/0ǻg?ڧg?f=b[tu}tWTҥO>]4j$u5=.= Wt1~ӿ/~ΊY\Ss7i̕´YCI?z6O~wc۾?'WLR?>]cpXH/_[|wYVlٲOZ˩6x֥2-o5l&6rڸ?7N;%@B`㎯bTٳ}V,od؞=ۋ*-Z)W:n!֛O2-Yoפۦ}uڏ.}"nkhGV@aNWC=ȶXr]2GWfZ՚goz/_g~ /~0r床5t^kW>i.4HYjm?O._G?jp{ָKb+_>MiX.}_kN$eZjVZֶя;-0?3#gWZ_u4e5}U7T46,:֪HOLuu][2Rv]tiu߬ 4:,"f-e(W:]՗%.Sͣc3uvznrKb۹Wt;wꉂF>+ Z']j՛G|Jǫ]#Sk|'ۅg~࿉}o>E= YտS׃>tC|;>E&_7ŕ]fٰ3'ۅYv_}n}||Ow[5t]?|#sxzmq… |66m/ /uj__ `=سg_|N<́K_rLOnBn+}l9+BEdm?^ vP͕W^Ql+P/gX ? ? ?  ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ?*@@@@@@@@@@@@@@@@@@@@U? ? ? ? ? ? )FxɒqwƊ$dlϞ}d+X [K,.fBo@k?? ?Y {/{쀊bɒqשD?ʨ/+:;N=؁?2G>wTu} MϨN;_?@괝UH6TpS7T.]=:exgIe_7Һjz*KeȢjrrM߿@YYrm_;{y]UNvש ܲeǾ}}5o߃UUmn,Xi}+S9ĵ+}|ػwG:4zX|auV^:t5 Ŋسg{GE՛OnJ{kMWo+u%%#N}jkWkv֩`rxNy-emG&υ^8' .@mG߽{k[ /ݻJYj}J_g9| m˙_j}<xV4zſUuUVAJa?%'%kz0pc%Cs IW8L?ge2wcMߧ͵6rev(qpNW(]խ;_/yVw^t@?kn tmVu\.lSݩquvq}lۥÏ[}n#?`"lhzw}@q6/6mcӡl*`F0ڸMxaieSd89d ./b2ٷifYeY C!ɦoeyfb<mveuޘ҈T?rFݯ H4?$@?$+~ E3pםU(Ҳ0eYx6U ! 爈wKOIENDB`MP3Diags-1.0.12.079/doc/270_config_custom_transf.png0000644000175000001440000016320111262714502020546 0ustar ciobiusersPNG  IHDRhjbKGD pHYsȥtIME -e IDATxwdUU9M =fae1SEEweADuUXqQP 0 HDD;U?nWuuu]USOܓIwslAAAAkTFA-AAAAS}"@d2QTdHrLAAA mv#P %Kn   Bc%& Ɉ\FPS;׮ł餣.:hԨT*(AAA^Z[gܸZ*+s.&VfKJ1 RahZz5L>;Y`N~!TT\?~JNK0vl~nZX  sw0ݑ_ S9t朋V;DMU*EEEGÁ>瓒T@9}Ǐvq:] Ft: :׋㡧~K?q9,Z.vng:AA!/% EKhhń (l8{p[NP JJ0VU5pInfRBRGՠV+*rj>c6+W <G⪫?ɓh`Ћ%   Hժ~9_wv&XTΝ'}ے/6 h4deа.\~{KL%] C0ΣGFF!%\G &}J^}%6ozU~t:0    o,nwD_ϴKav+ eP}Ļ0P=u/f-D7׿9ooaٲ`03)ϟ @ii W/g(O4cncWWZtDM9q8.o襗pQQYEwW~QAAAicoxʿ#RXŊGS}:>? s``,]oy0m-ԅ]j@`#W^`ll8ݛow" RbWhB݇~8n߾{J~$X)))A7٩OR|~T*O14 zɈȑCL:Vz0+AAA{c/sM ^M9IM[ W/D<P\^kk1 Vg'Ov6mj߂q?T)9^G~/"p:9K{Tj5>۷1a6&F˯CQDQNS&AAA)=φn fͪc)#~7sL2obL0֬:o/x$:+Nl7~)_~>${:QVfj-[HY9=(䑄j&O8L(Ct&u{Yl!˖-dic27+W.~GO_'zٲ=T*]% AAAA)//f"x~>uA7"b4)++`'vek\{nR$lqWL҇KKKga``i47 ܔ pF HaBh|B 3SqL4?PT>}oʹ]Ȅ 9{.Vz}x45'MbŸ\N~_dAAA/++.yѨۼ/?^_1L7 PVVT$Br w`L v~0*aâg{\|Hl \iil:RXO=2D#Q|^/mS`ڴ/Yn`p8PhZ4-৿ח-AAA5j)m@p`;+V4`0)ٝ}.n_=4-KHi'N1\.77T,_jHmod9ֵT4 FFCT7H +pj/>3˃l1V~$T*zZG9|ĉTTViq= 8|E1eTj   B(b=~Np׃ϜYKs!K`08"  [<{XN)o5}56Bhy;_f>{~8ٔ)3dXq S)|$!׬Yp3&Sv@pJNEՠyx<9Ҍً^ܹXb/< jF--   9Ce>?xY,=S˜#74`4Xl۷7Xv2CBU++[fzj=3ϠenpRӗ꩘=mQQR6 ,_]`0胳֑$TTWWC[[GT >` tZt:-VGii&׳d xOKgg~pI   Bnm=TL>xAOMM/^ěoM6n|VG]t9 _;"Նł NCU"FgZ9t ےJ颿B_ʦu%f݅ < 3 O2a aEKG=Qt+kߏhbTUUSV^AyYf3b Յja8Ң(:N  tttQSS-Z ϿTqбa]7q]wi;MMۃjb3FNncY|5 I |FJ`dp4wnF#6` pD?R\ŸG +wFcJϏxnj>0h@F5   fޣ zzz>{Tb0u~z%%fzEO&Id|>,~,}nRq7,Xn֬Y{b:rpOG4T*ՠ^JJ5|gLJVFѠjDAA!/ՕixGQb ?&+ [|YY &;F=8/eCAAUBh#@4Pҗb0){}F7AAAF3ݽiegU9Hex&   B~P\lB~k~)*2|q,^S}x|^y5BAύ(a{ oObOm>喴/Jmh>%'F◗d&gdwt\~.VK6_2r9_ W۴DEd7DڲҜ\b'q7җXG );Z 7f>-I[$YI͒% e@w+mᦛ>J-*U߱'dQH -dI]I%m˛9)wgI[89_Y:ͷ~3O@h\ߏQ ̘ {$Cȳ\ȯ3d<~figAʝ|MuQPjﷴ>hTd h/Yr9n-(D0':zt_BxhiR/q6m^o@kWRmgB\x'4ܱhO+o|?\EԋTSs364Lg\Td>Ve,@lB!q׊" u{{ unV>R8~hɦ-&dO'Ue⛏V9Vup :߯9iqϦOϑ#{ޕzQ8"v.ZU&3W,ӣ=R #/?o?m@6X1Q aHrаCvGt0Dx-Zpa<W<܏T7}q7 )"Y$sI@$?<~oL||6Z$Hg@+?j|+Zi/ TڙhcD&~2mVBT۞DXDO6?]5"t?~0^d^x*޳pwE7c+ڻx*L~DƫSM_Xdh(Fh~8/uc=;p)Xq8pٳČS^2GsX p@h)m;yyj;΅ׯHu-(SmVDxmh"b2yl=]2֧xaKnȅT"ct*VzgZGKT2 X\FX޳!O$n_6@dFΞ$w {*"ikbi3,Z'7t|2M2-x23ZiK'ޣH4_[@V,͝4f=wJӍO6j:r_ ];F^d^x*ձVy˿{ɌWGkoo?S ?{2mg&ҭ(;Dx@HC߷1gs.6VkxƳXy˟x I*ȥN;N HFΥ?#v&^7oaum޼ Xu6YtN|2tґ+Zx\╹LXԋ׋\O͛|X\{2ytXe?S&yh6:;VB))&b2J6DTWƌ{;VA㓉o :d iRK >Qa:f+]oclhl-V/il,64`3RN?cٯݻ-\6M~NEvXɦ+^^/^O;;~7OCnl2VM%ɤ-=DPdm$ݻu"a,\*!xq?<~oh|_[G囤+ԥ}T BJٳgJF W7_!8ѣ-rN BH)  $ˬY GHFyϴiZ"+~75b=9ŋdɢn}yv-C{/^ȵ^-! oA- tY$3CodES}w*޽H QH-H-[~ Eҥ%3g_! L@9ޫ_|% 75!=wq+;wB\-[oA8(AAa;zR=ODXߙ@6!cT B.pɜ_Gyg݋qv1Q]]%%OAJcJ^(V;5sd+34h`ܩq *TUWf=>3f,xІ#3j:btf;c|btb4(//#Yn&VBM5p?H1< w.җg\H 2>(“O>˛o맬jjj> :=_&VZVAw0Ҭ+R!D^ g<˥4-U{ÉV:ڻ()-DLS--ƠPRZtsY0e*XIOF(O}QH/}_I@N[2>y Rs^ 7J4:.~y7g>JbL4 6_3^,Wdm1^D߸J*T7+c}N B.]ON>$[~)jozwZ xclٲ[6fqfAO]h ?V؉/Y2&BO)^Qo+^D*]]ݜsjj(/-Ggf# Dfm@I:Ct2cOY {|<6,z4?Q3D/7b!<_)gGC c #/"gk:C8y‰~\y6Kc55Li*5^K[[;],]͛7v{cҸ#=&smhANԔ)QSuNɦ%Q?DOM|E9XA`޼Yc.4SymJD'DϦR)|F*M%I$bPXw6>پ0}Bd㛪gc)B}9O<~\y6K[8ͅɆ76w.&NH}}=̙Ӑat:lwV\%g&N$D&?FEuM9=֨Mjr&♮'.H IDAT%O*+&d)?t$G/2@;:{j0>rdo\7Re|.j~rziـW֛B8vr+W^ N8]hќX&rLV\ E= 2ۉ%DLl޼rN4&¢*Ahaf4EF:&E%[ .>' p B=P2>t)Yg&4ػg7+j~p?O<{/fܸqYK4-~ڹL y!Z$dBƍWVٰuZZZ[k9qGaڴ c"&+lZ7>)ivbJ]}g. .te|~6~ß8qOcFrp89r[nlL hLoL:~Sgj\6J0LĦMbO|R>Kq:]<jcܸa~᱘]Nd<|T>'W6N'*$ζ`2G.W{ޤ~Re|.i~`ǎ=\z}.+"ki7kמXxgˌ(QDC"nMW$=K4퉬IeGLhiJĄ,Qw^9Ȉ/ݴuqnܹ39s:x-9r^˺ugL2 &,dfB)L8-V>G++h||TD>![e# |Re|.K;@cf7a):ygr%dqVR51w?ncӑhx#lhڮfN SDW\2> +V,DDp7nY @0DHbM#ohVgs8 ><>'>y~e 7~S#{?[}\Lf`aTip1:ӧp~X=w9VI=|}>/^+'Ol6r2n3J  xgR~NncJ { w^(,]Gh~v.;WşVk摍KGG'/ĉ8v)'َVt ZO^gmƛ8q ɓ'rkYj_E1kVmmW'w%˖-<x7RRb 1"/x)/Gk#y>|/N8)_6dQ0IUж\~y Z^/#^} &Lc\y:NjQByW;w6/Swmƍ/%Cf=ySz~ʴiy;>iV~ǥ0\?WM}q&O`P\.~ssXhaTI;=V㧼Z[x!S'?^} MSO=γ7Ky/B.ߏ?'~U*7p˖-̙Vm.)Nw(}|aʔR% MV.h*af`!!??я1M?a͚ XIczɰA_5U]M|wY|ws/F_}>_WEFG2T8k<>MtttH {w.87/)\Rڇj7k-..+_/RVVʋ/"%P{+/h*jfnhuX,Vjj5aSg$3!oZu]ʶm,Z4_2Up|^}}Xdd 19pt}]\ʪ跹Xm wnrxB ;M[[vG~MWW7_"B'Os=p_ӂK ?_:iZFoBfb$D,#|ҸHe^J̝Áwqa*f:!#NԀف+b=O% S뿷nm䦛|k_[(u=7ᡇ~V}C2>Q<[8oq %8 i`nAm-xLaj2fSqՋ~ ޢoPfPB# DJ.//{{êUyM\~5;"P~7ظo}vK& gx!(l%k()ׁO{g-Jj̘ <}"D3VxMg7^'ux%Y)'}Dek1h3Cg^b7TT_'o,?S:~^Hn+G=9|s7p㍟'WR#y/ٴDoGSDqEn޳g?s֬92>Y2>'rf dkf~qUzt.zƕu} (3x$nqDL|S7VG>u7;whGD}|>~Gy1<пt1Pt 7َu>s˜<5䉺O4 )? /n34+L}| J߸'|-[aXG|쿓cj8 =I9qEkdwߋeʔN_|7a2~<@&3gFJ,:-FsgzE*tpЎ0S:lZHh]x8>׻G "lڥT_}=o9͚N6!T̖𘨟;b&4?)ELjr8t03"ٌj7c B쿓MOp3hiqD8wgg_|3gL s%HS[ys VopӅҷ(iȹKD4Vr͕#C:L*=6bo]Fu-+zweƌi0a¸Qi hceZpÅ\r?QN!ߧO᪫[AX[[;VFCMMg':O iO7~Tө>o8ΈϾd2cfo g^fMQ^QEG/i,VLgb4-XiG;\~'b(߶u׳̍0WJIéMKyl.a.` #ׅ| AOBCt:Ÿa~?>3.F#cX/_[׬97ղvGd|.) ҵ4VїQf1O9<38R|`{/Xy٪mdDiPyX<0l*v E|/{Gسg/?1%%$/-CMXD eOtoJ=|F}Ϗ~cyg_?/PSSͷ sktL;>ɃJ~w;l zs 6q"e 8l8iQzz}JceQTjT*5j1Kn0+'Sf+~o?xzo,;8tSC_~:E0Θcǎ3/%h'< \'{F mmLF,G}'KYgz8iD}bwA4(z͚Xt1:NNE 4~V#@FEIy̽1^ m/Ud(QRO΂\P58hڨAq|8^/6:;8XKG}5:>马Z5"d 䩀 lټy睷 YP\1Lժ7 8zΝlŁNR__ҥU,]Zܹeՙ0*@R,D7*=}{8:geQH^*τ^>x~^nCwN']]tu9q碿ߍ(VVժGZ-ZƲ~A@xx<><?nNMY^=sA(ܺKǻ>YIVMMjWpٿ-[:ٽ'l>lWO3{v)+WVhQ%3fPV&ILe0I6¨ ~eMO.EVf}. xp}x<>4eMNMqjʯBOmR=&1o^9XB,!Ya^Qց ZۭXul6vw`@7ijV"[,Aދáv";Jvw S@h*Ə/bݺ̘!c\ATgjYٳK 47m['?nNqf8uYJ2`0i dɢ`۫i5]]*NQ_C; q|Lۋb8q5@k67?m6.אJc2i)-Q_oBOe#ee:*+ TU0PRhT|NFT H 7W>E].NxX,CbqV8^v7:6l8lܸ?@KV3 ^EE LujfZ2ٳd,AX۶5rr (FJɤe$-dI$a۶N>'>Kc.9+kO΀;=8SaFxX`nAss?v+ᆙ$!LPy}A!`⢫kvmm6mtt9@W>6щg }YѨAWWVS{:3l/.+ʷ!3{ۏ )78Ko{imo70j JhՂN55l6'ӦUQR`NI"L=QTiCB2>y._v%ǻѨ(/SVcR.hGXxw0孷Zٲo+VT3gN)[Gkͧd8nNeK]8a1~|^Zͅa2g/J~`fs mm߮.{Pv4Uft8JrUQ]m׊pqGjE.~?F!%[@gvExن~켲^bq30p(ݮPy5feMEb-:_ZDɤpl_>[O.` ʾ@(}od|.TbRzzzw] G㋨3qTVVgNvgiaÆ3̚UʹְdI%PUU _1olm{w[+MMtu95Lnfٲj֬eΜ2**bf(t}7շ=X.탳V::+3Y| ZuTUQSSDe"jk.b83uuTV()1Nn!8''^|u.TwOp>Sw\.eVVxwH{]JJhjfLC3ʽOZ4נө14A^Z}̞]ѣ0i/f:r>9LgYSˉ6>'8/o_/۷wkW7'׿d޼rƍ3h2罆jRJn#}87fF #Rb9^z+?h+I,4|>?6+;wv{KOR=Vհzu-KT1eJ1%%,Th 4{VE= 'R#dc5w:S~'tthm}W^:j QL)qf2a61t:Mpf1Pd ;^?ODxcXܼϜ9K-3f,cǎx<~V\ƍvU<38>={>y?38ճlٹl^?~gt*JJJjPRR\b09}$ܬ\hp6>t&^KI")fI17A>~Hv$R̩TC3BoۛXl Z9NJY? ;|a۷wcGǎY<^f,_gƌR** 5x ;H H"Gsh=נ /x&DH|С~6o`vpx2vx.e˪7΄Ѩp3u}w=6\?Bzb6*,~_3^k5heKV졲ឆ"N- bjj-@qA^4Wˆ{c $vLߚɤ[^Hsn|>?3f,f߾AY豓\ {mv.3/ IDATk<>N/pkww&O .=lJq۷PWW^9sKSTw|Q\W fwM~\7՟䭷^`,̫T٫Ta^oJgg_!tjgwq;wNZyg_Q1׿~z-c܀s}/޿ -Krsec…!9OU!TV>{͖̈́-BːLjlLmKxWy={z8u~? V2md<>ܸD[$ٌfS۶kPV 8Z.dҤbi}4L"~}Bwl 8:/?_w=8rl"ϘQIeip_Ǐ7SWg0!ꋩ~߹ЏXzx:0,>>ƍgJ~r \ECn멪 O+)..4]W]1-஫kW_٬TɤdPV3i2)}g?׫Y[|[w*&VÃC:+b{oOl~p~;wxBע(49|8ZZZl\/L嗿 8޻3=\!T@SS})vQ 0u9kµ^٬h?_o;hb+`}Q/s.ygFv9t397ecFwI(-s]v mmEW5){6>ŒWq^: \+,өFH}(u53i0'M4d<)G[]zغnN@Sͬ\Yյ̝[FE82},<ֻ*HPS}e=/6+~[rt^g@pK9>/`v{0LTJUUQPFCwWfu GkC./ {~-̘qPKo<[>tfr?bgg^ `^U56Gp)V`ze*6n| Ō"e;6\{x0wVi*0˗WԕƏ/8$q@&MBal-s?ͧ-x'Xڸ%?o>ᗟ|i֭(p<̚ҥ3jp={zhlbYU?ɓ)*1jBn_'l45uiSw碸XܹeXQ͊441~r=w45ɀ/[ʔv{Vv挲^`=~W2㠿߉áEE:ˍͫ+nWZjH/TS;6{Rf5C+k懬P|\Xʽ>6rŢw:˥LxaJBkj}F zICI1t:t(-ϔ75zz f# +(/QTcJ`0nZ#Wjg߾^6ongp@r9sXE*:Li0Nq# L,_+ z}(T`QL[[A]]c{޵ @Vz3Wp䈕.hnwز L,YRŪU5̝[F] I#aaDd{imsgwP: Sʚ5\Y̙uZy U?týeUpc==m:\8FB`63,~Q,~񠐯lWT Xn̼9dZ0Z.Ev7hj(ۇju*UC+¼bN07a^aT<{^9NCQv^=D=a*h>3/  azZ^MhlbnZZ?~jeR,djO7S^n=W8cǬ~'7wRKTP\3J ?a$Ǖ,Aw=hpjup`RRgڴ *+Mwׯ.bg̓;o dM"MњY{-jF+oZH31ڵƞX-YI]kw36UH&%4$ qwQ]U]GJ*AT2{{:08؎,:;3*>MCKn2Jx ܜdy}8+*JݕϜ^8w&@6@ool}}YlзJ_3+bE^3Lƹgx݂GsLB#9@ޞ֭ؼ;K[38vl?Ʀq4 lܘCGG[*8{v>W_Q.W10xalۖ[oM⮻z9xmBS3/pOm>BovV?7^Jx\^lQ{^{{ LR96Q̛)bu^(B/caff/UG{9 bPdԚcY*F6aMV^|pؿje^_O+$6'c`~>n N5ǁص<gq  x+O'02ҁ>:ԏnF,5+b+8sf?u=:+W##{Į]by93g8Ѝ_sWAPB Ӳ=_/ɫUeO*%wvn]e%7 RGqU)bb$’ϋX7:/D3ө BH''"*ɮ]ض:\qy;'kزE 8xvuchH"?wN>6W'ql˫M{p=8|xҎ$*vj{«B+\Ą?1eeunn  {ooO'{+f³~:;3Rk&tTAAmuf!;[E(/-PRT\^.m.Ek+XZ*ڱ҆ӧVj4dR1@OlN6Ğ::d3{yb^xȗגR 9~`~{N@H̢?{{񋿸Oر)?>Kq\?UѩXIǁ\>XB*a~xx`wу,|DWk"7?_ +7:ܛ  tueiSz{&W}~|{+^J/WVkJ}KK%,.$+1%LO$bf%yp(&VWm⪢@PDBVWWcH$$ fɝx\NVeE_6f3OyܜwBHtȤQEzQ][Fև'&;|d+_&dǧq ֯wًCdǁ6#|Ȕbk 8ujrǎMajjT;vtС{ vBoo'rD[,LM-J|onnE ee?>52ذA6kúukr pϹ2W慅|jBKKebcaA^_^.ci"d](O^^DbGtT*lVނ14Ԏl64SGOOVٲёFWW7~<) {̋{[VeVfpJw׵`6^nP;hϭC^9g9Ew$FB5Aֳ%IŽ񓟼رiV/p?n8p;wv_ 1 *.^\4xcOa~$FGq}5)*}>zeXJ)`zz+Xի ͭ /\KŮ36+!y^74Ԯ8M픙 ^7zl^/oX^.#/*J >|hT*v<.+\J^\*ʽ8Q]葏fP[vɟ_/ڵeqG+2ލ,n7^&Mn2vɽz~Oq|pJ뎟z`x6nX 7kOoL?û̙9|{;zpҎj|/7'q\1~?7>lܘC[IP,9ܫ({gf#fge>Z1=-;[Yp+nۛpb~}'r2(^'_ \(ʼz]_\,ݰ*/PTVWVVW׎A5/ClHhoO#6e؊ёFg6Tt:Vqń?+q=;uA'JS9T߯ċvnp8z8С`4ܫO=?{ilڴQPܘ */^>а8~?5$6ma~<('n]JULOq^{mo9?\$6px`ރ 23f %R_]3_E>_Gcnn/ʕ/_(|RrEe/+04Ԏ :~T_pL+󕊤t mg\*R13SPVޗXX(*NJ'ԩӎ'M f@Xysu800Ş=x챚'gq.\X~p;wv{1:ڏvtwܥ2T(Tp2Nk][obzZ߿sga.tu ,?yh˫-a~&'W09"ff/XY¿?FTQqCxByʣ=f@vUߏE/͘7(fII4@ ecNۓر ##x!|NoLwSƍ9ۋpذ!\.1OV%,.8zt 63g汸XFGG q`?FF:蔱.$ nX]ۏYY-abbSS+?3S‚젯T(ǡ3$R߿9lЉv ʦb/P$f13/Ӊp'Vo# eK7/έ/+^y&5]vnݝ|ww|BՕAoobiٙQ,.P,̓F|ʯ@i bԠsd031jF{u851Jˠ7]#;[oҥ%\^[;oE[חA&CǁZUϗy$xCnQHX =4ĝwb6^T꯮Jk*X^(+eLMݸ?7'_[^^UVb)D{{Y14E->Ͼ͸4 S{̋ M2PT< _W6͗VkNJ#T*6y-ZqO;o׶v-fk /Oe{ek7;7] IDAT;#X=e1unX-K髁17Ӂ'=>'-X]>tvX lҁq ._^©S8vlO?éSs`׮n<؏~lޜ5 && xY$իˈcv<8Ʈ]O^hv%ZŚ8+]ޏ/(`zZVgf(jL&\. R`h( {z쬝$L{|sSSsر/tyO&bPKBw{qX|TQ@^B zo743kj"/ 3{q4|_BSS؏??_| KKX^^JEq'@.`)˦BW;:RMj5{CqJ'VGw/WskK77 e^8!,kfinLH#ppz'S *e>(7{ZBqm$}4 -q'6̙y=:ߖ^vط۶uOEPXŵkt3۲w=mu':ZU2愙~+ | l_,<+ d2 ',KYSkVL O'9(%|Q;7?Ƿ^_Z*) ^2Ŋbb@h$y*LƕR*/ xm꒽wwgz7٧7L1h=A#̾R*օr-t:\.hkW߅B/Le^WO\'B -O2Goov[>8{6ǧq Ο#n `߾>ՍlV17W{$r}}M^^X(caAV=Te\ 8+W}I^IcdCCY ʫn!OkMJzߕbQ _ʊ-\ 򵥥UU,,Q( '{FVg $"nO1fb|{+8aj/yB!:қY@HA @O_j>q{}L&6ǵk93G0>>_Ĺsy<><;֭nqb+8}z?u;&ҎCp}CصYϝU|yeZBTYs'p/,13S __~>_ʊ(aR1Hƍ9{kEWE|+Ҫ oeyRPXU[Z,/˿U"/VY/Oha߼HHHȢMފ Gvwɓmm tt .ǟA[[|LzIT*ܧ5'7+NB>!@t|NC rCcV7F.7xcnZ72ҁ>Yq^>6O/eΖpz+^l k(6lȡ7~ً~WW i4_PT//ayY^q,,TG?q^1P.&cjb[̾/Ч;:olVPg 9!$,~3zى̷; p|\od?h6sFq|C! }^;<*>_ <bll/.;9d[t`߾>ߏn=ǁ$}w ~scǦqzxlA} vFd *P.K(+~|}v8ۛ(`f2 3xӓVrʷtGIյrŪ2!,deZ$1Jt)e>M ёDWWZ3_[fBreBzvٮ̯`;Bϣ4>?i+ZZPau nð3$7ZXLξiS;ΞʸreN8sf/pڅqFFR)-ժU\cǦq,KǡC8p`6NQ*Uq2W05UĄ˦×JU:;({t:(B$`ve/& j|y󱵳cokx^H&W{g裣fkH|O 4rF/L~D _"g066gcƦ]wСqGr_<C")Mקp< ۓؽwه 066_aaAVMھw că//XL6wklVVs$d[6O*/ɵcs2/Z }rGՏӺСӋ߈wޙǛoNĉ|".\XK/]Ν]طwՇ}WV~{ׯT + C5عzb1pqDP^^V/wtgxL^\qNǕpPŤyyuQzBʗM8>oyTV +_Ö,hOcyw׬68elY^;4wi z\ `j5;VmzMH$dW ׫T[DX u` ziӨ5fB!>`fboyֳÝ% h-1Sjnk+FaZ`~zyD^D IfBib1ibZ zaL"Se۶Ez|jdNN߹Y@!B!LwNB!j$BHqk B!BQ}HpД4B!B!h@!B Il}!᧥,b)o .#yݨ [8^]_VaZi |B!֦e,bA|<:0aKhAzLj~Hc$8Xll?J^8f7QHz5G=)ZϙM4WZ)zMLh&<^f7猔_oqRvr{J=ZUڋoƼl{Z(uR?!͍FXkt:i<MQ2n-6m 7N&w=vE\(Fޱ>ws[V뗛:kTn0s _/^=/!B!j%$=177hzw؈ c'ݣT)RixFEM[ZNVO Q;_ ۞4jGv!=aiiYV8zaūⰛf+Y8^wH'l{Mg5V볗f kVzkYULMэ+phuA.Fo%n+#5B[Ϥ(knkvLsiZpsSV ۷_n:|7m݋$Y۵-aju1oR-/yW^>E/vGm^onȷFVjN& 5ZtB[Qﵫ0X;X,L/B6V M"~_+a9e,f3OtL=N$<-'vΖ+ϙQkR~֫vuϫ`ĺm/nm>A6VVY;oQfl~:7sЧs Ǫ_D=AK5zT7a_gڬn'Z_Fnh(N+j䚝NxQn{VP'h ^By 򯷿֯wgعt6:OG4 @#!fǏժ0 lZA"JHX& FGȑ?Kؾ.^ /Z'BL+;#B~po4Эˋ4io5KVzZKi3R~7A+lߍmAIk@'v$#%)w}폑ɤ/ 4 BEJ0p&_ڵ O >ܹ23H /짙!lGX >q={V_p%|DXO)B! S(s-Q;B!HBZaH/h#&8@!BpOOmB!4 y!B!$ !$6J B!B 4TA Fi@!B*Q oaDZB!Py $ !$6J B!B 4TA Fi@!#տ7Ykp²@q;m5DM%YdBi@}γ~ɛ߯5{h>ktgn1mq/گV۵ٶ[ |6m4 BHKb6:@WQ|k3~Gٶ ZB!T9Pza6}$ -slM,8@!P 2mDlum7Q!BZ/zaQ47'Nq{;:E 7VFmٳg4 BHK`fk4H7zV}>/G?m=3l:L_+6w7'!RߵKo'IsD9|S8r9N8hvږ6k5La!B!MFRa&P}x8'ߏ3찔ec^sA!B BؾƑ@,9HҷM#ѧQ*qB!zab3N)OO+k)VWN|7IZ(NJ+(씙V~V{'dYlNVƏK!/ 7lء( Wc Bdf Й)Rzѳzj[/,;V+y}kvҡq_+%nFN}p!P[!ܼ˗e& bY(Y Dn|^߮0WZZ}XI`ϫ*5 rBjUVFFvk^߼6\tEw&&VYxVr?DoyA5BH 9jZx*0p=}㍮F65uu1۷S(,n*@^+=nӪJ<^6}~MwqZ]vΟ?yGobXD!VdvH6"Q(u|#>[5ߝV7 pyRom4a`fbnE^Q,$E4vY/!B *մv 6ڨ<Ҿ]s͊bN|Vu_ybeNJZ o+Qvf;-_EP'WzzX#3X=X=Z;fzT]+z3o +٭VY6JQ{poڗyѯ4!$$⿂`6Uʙ^ZVמּw6LTe=6;owBm(ʴV? ̋4E}sCBj NͨQ=t3 R5jZUaҥC`w/V8z6>{?|oo B! h/jX&'GnLaËwtF0:G,&!6vf}Vk)H''ؾ7/ $$p?!B Bؾ/IڇA!Ĝ*^Fjk5Z~7q:zxjևnvSOVtQ}oZ&rB虌Twۍ~tnf&VⴒZ2 `fl%-Nѽxo3y{0[}vpmwZiIB!Do@ig ^AZuM0t׋tkXIKU, sssl-ԾSEݽl~{J_#IK_~?(zzz#y㍣xQC$=:}]O߆CzV~[Gp݇XA=ƺu y]_f7f& 8{>O[ҥK׿b2- ?bfDnpX\=zӭmÍEi|mfO'?hV$|[ 4 g?믿 _9fql{4m:tL'$mi|$zꋶo@r!Ncժ\: ZZZ`*il~a["$mɉ̧ps1 0A{@| !'¶DHT*H''HK 4! - Bx&B!`'ab'ZDqҙaV?u[~[gf C2;7ذa2 p9Np lٲ##O~N}-C '`! Էȫ4X)à,a?~PSvSvGwfym7M\.'aE_X- ˌ,D!.^9lٍβ&'X7) yniDV ݚ7o .nx:9@<l۶G…S7u7&{N}f%SXg(Xšwڂk6ߨ}5(oPSvSvG( &N3d.\8y^fߍ!ژYݷzͬh6K!zB( `-K}}?Mfz G/ժq7LX/ڂvQνj!zݔݜ;cǝ{qۖid6яKsh "ۘv7\SF=,a?~eLNM N Mz]g ŀDBvpAD};ӻcǝ7| p'lKݔaZF" عsgώkٳֻpM"k@ww 6)BwZmK շ'vb/Qm; \AdJ'SΞΝ7|0>X,͛񻿻 ys;b#i[m NilzB()^9g[fwO,#>Z}7"K`V֙VmGVR-8fֆ$I}6(oPSvSvN"Y_8X ,O BˍxI<=3֭#`'B< -!:|Æ>!9sf@!PvDeR=BH C-¶ B;8B'!lK-q!%BnKHgC&\\.: BX~a["$rő#Ϲz0!l{DE-~a["$lmi|s 0͐| 8xgҦiaXgf(=g"5'etq zk1@Tݶti<ƾ٘}~5=;WAPYQ>k5J?:Wیe,*}_xQA¨W;2 LZ}o,X˲B? IߋroWg3B4l{l?B!8VRT꿋ֽv0J:1K\C+_jvcTݴY'mn[j|?5[iNP| u8M_nQ_v< #ݶ;d?dӺᶝԇaFW_ǫH@!يɲkFڭhv91v6-&\^^&H'`N93/SfLvjeE; z~(é{Gn!كw]9p S]iV^i~|/Vl ʳzm1m_FmE'}H~[?<,8 Zy%PoÖW~LK{9|>fvnN0 ( 3ʓWΛ19=G [ [9MYl !UZV.R[y@YvúV'LcFaGe ڰ Fg[3taLw4c6C3q'l6Figs*-m}HXE3OhFK/}SFt_e(Io>|FдNp ëAxܦɾ?<{2: FWai?A^ Ҹ1BE<^;/5a*Fg$|#v߈:dY`z?gj7dvVҺ5=*vJVXNAa;QZe@ٍVhXmv~*WGٙܰ Wa/ivj8A7F55~wnَǏNc|-NwCAKN9xp?fff̾sASS@N'fprhc1{'eoݔqVN{f봍8n?Nۄ>ʋrse䚛!iaxuWc 7is3pOzio<B5gE@!B!!GRG ccF{#!ĞP`&Boj䚙:+7>!Ĵd !y~!}wNB!B! B!PB!frﭷNk/~o@!B!Pjt_ jaz_B /4uF Wa֗{|wށk׮,|o @iLI`u'mBHT G4ǻCeG}ܔ !B!j !j/PV+|LQڬk7V˟pkneTYW8敕e%-fuG{V`~r,G?@IDI{!GJUckSaFvQw+rkw]lf BH`V13fAe9}a%_kN*ȲvrvZYa1hSz(ooL;4BZn冓Iz$\7q:/7[+Fvm%9B\ ;]_2\/E/\ٗ<^ԝF |/~>| _/Ko"UBB<}Ƌ6:wԓAɸP;FR#'Dz~ "af6=a,kŮi5_oaO{ jUvbPnwg4zrBH 1xv7 sY5lɀ?_󋿌v߆|!J) zBHx̾Z<<0˥KD<8@q%: #$%N9F [Yw ޟg;؋yT** Gʱ0gOi :Op?ixa*5{qs!)&7&_F:Iݴ;?לǏ2 arvS/^9J+·%./_??E2WQQ&gҼ2ٕ[VTnT%,0J\d˖]x Na۶=?~NB50f׬*n8I48ugka,j^{/зn=(b*H)CŝVNW7i[n䨟$N/YdzQ.~sqS!oέ}n,/O9j ˆBؘ#…S8p@!JfA/J?y82y]]ȯQWPMTQITPWQU R1VDBiQDBH'PZ_»mKd?YA%Y3dſ bBRceXs< p C!Sᶡ۰\\U%  HI xB-!p:;qsx*q:cwƁ $TTUy@ȬfyBEf@'BHG† Ho"M`5J(%J('˨@ڧ(+X0īʿ[aWƻ^MJ"m^UfvG  4@0 Mfz~pW*~Q}y*r&+>pi`&u+[y@\!גIAȈ 1{.L>|,0hZBv SEiv 4xmba @=|/ه|7"&NsfP*~_ZBCmd5Pɘa}~oV_zZ@ p~18 u#hM Bq 70{112tj;xWa:$3x_8 ڐ%<<f2}2+*%Ô`N!mGku\)srͫ9;irvV;+۩^x^> W˴5,-۷'ٹ"能D>ܫqKc< : 9 NB\ 7߽Uz8;K+in٫8mͪk74c%$2ݯ{J85>Nu#gëqEdؘIWM/B!p埐֣ٶTք>!BlB埐֣ޛ>}(B6׌uOq7N!ٶEZB j1tk93_a}O?e6qgTA~9>?]wS_g{;B~~aI~1njfdWGK@)~sFa^gN b@%QAG"@<ν;ہ/|_G~ 1!]O`_!eppc3?Yd[  z&]~m bېWufPUڼ~F> *żY e IDAT?]]o)HHxG6OΛ\kdv_EAГnò40lu7lTrgm2$NͽO~!n+]#60r2U p``NM^wp녊Q+azNꯗ))!_##!%OUWHTذar~o/7gia+'vNiz)yYe{}BHA2u' cy䥵O5/[ek5L BHA Bӳ4EH1@RFB5UjbET]byb + X(,ZCw`|.9 |!$j>Ғ M\(b +qė  UHy *8ns7&BLs< p? '!$!Ve/$J@ψ\MIذ_y_1 !B! 21y `m;k'ttw"! _H$?B!@!P AB<e%U+ɚӍTNmxp^O5:=<%9Ǝi{QQ; tT !pJW[Jwnۈ8RWᶊU Jdv'G01΋bozdž߶;F#TC~ cFF齢Vl2X]>? !$ʲrį8VTQQH!Di%v ^Qc-Va<3rg!DRN!}A?ߺ2xȭ@ЯI BH:~/u"86^8 sy!N/=n6{@zģwV5am %]wrc'/ZtS-$8v˪2(ylG;v5'inU BHnrKOvڑNi'rԯ15^8 FjZBZj`]k}V:m;$F mS/\8{轷YrVYy!e~Ҫt;N01V*fȎq^7ˎzY/p8yキ8"@Ŗ! !fB"=R !V{ zZBHHY¼cB6agFA B!B!'!B!!B!29Rg{pF5Oi#?azcD_W A1VCҢB!PF]d k2B!B! W nC&sW_{if׌²:N{eVi'.kjڵrU9m/4z^7ډܵ+WWc,39TZMl?veWcB!% FxFߍvYFaY GՇd/0'yo' M޸yG'F!QBKYCdڮܵ+ݎ ܌NJvZ](3;! F:f׫ڋx_A{쾓~}!/ww Wg , /FW v*\;B4X#¯we%izvM!OiO!!ϝlRr[~d?-!DCgf(OCJl^7Zτ}y\rbה?,M受טB9#g<͞Ahqd c%y%v݇iT9.,)! 4ϩ﫿蚞ppifk8fVtYIkک7ҌJ} T~ە[V߯ޫzcI ۱1W8>l!$ʽ;r+yI_YwpzͫtYMӲSNz,77y6D-K{؋vW2ׯ:vB!B!B!B!B!B!B!4X^.xf.ƌ%:Bѽ8r9L- ccc'8_!Bį0@g["ěD BHˠ>GU U3`"=ip1b|$|UOO0 !ZBZ-Hɷ}> ʮ9q@P?n\^fʳV_7o땿Ԉ+N@N$ 10jZ3B1E,@olKYڊzU3 ǫ<)<tbG'Y<갍KѳnW\}v(vkB!~WG=4K?lsop%;aYKl+{w$Yy3%/ջB (2pr I9W#T(*g3܅rW@({%J^[7N!2;ߦ{v駟yfiڇRQndd$t']gYL@(A^Ԏ0tA;gt>dΡ5Ro zSJ'1qK&7`a'>r 2 F6B:r9 !IsbվF(k00Aew Xi_L(_[~m.QvSoS8|S!v;^˪-s⎋M;8/}@[5k{k[h04gqڟ8Fira׋I g>@^~^sε(e`z-q; ¤g4p[/l\kd\ieaq9-Wuk5/u(nQvgx.PA_~ [XCc Io~nqiFN# T3=Y(c?AGgulIk\1/O#ҪG1Z"]ȸzrIƣ.Bۅ ^ 3Q#!l\NkFh s}A#jLH*A^6F8҅:pM9X:^cMiF@/w{-_ą$w\,h~&{GGsT,MrW׿>:fW4ڵ=6D2Ԩj)i$d, k.8Uap~k~.W}<@};: [UvalAA ߰˂kp\>yܮn뵬6~uuyɿ i]aa41\T߀7/CO? kwo[Ճ0Y-~{Hl40hya8(Q{\&ᘜKaM#6n (04'M3n doBxm<aoDsqugH 'ì͋9nj6*3}<3 `p2 x7< wYF!/ q7[J8?L"#?lsRƵ, I^̤爂f<its|sy lXmMײFw~|֭ۮCf |pg5 /~Mwq|^ayQ~D {~M8# _cѿU=M)1O-?^Lg8Q) F߇/͘ \G|N[F> FFFBwڵK{jxEݾI26@F$qy;# 2_՞@sv=(=r &o# 9^CE뇓֯$0_qf.s[Qxwq{kGlr ws-s-m︯ga!l]U#kҪD6ikvwvydq[Q8 { Q$(CWw~%Zm!s-=~ Op鞵Glr 6^ ^]⺞݇I+"iu?Zn &aDI5Z71qIVO#| {ѹ% (,t[^k^kf++o^_ߙs@z^5c(k0,ƵGگ!5?DzF\f\"yZw Ky.[2Fd&8>^kE$]GFN$Η<4 2[K#&Yjv^z # 2I it'\L6qzM2&L_OiE, e/\_._ޱ+8ga!u++I=J5m[ mYѣ~B$ܠᘬY!}y\^L h>/ʏs40Yӽh>~?lIOs% s&u'm^^LtVC6 3 m]sL3-cNqm48 sJ8ᴎer~WNZ^0NOZ;+Lgw\HN]viϞۣ>SG%@^L`qxt(j#bv62[]?.rk80bYnzuY֯ߡC, ))Y,Kv_\Jm]5ky`ÆNZrV\`_U%y 99PɟX7lQUlO􁽚+9WY5$'n .ڿӾSH.ЉHN]viϞۣ }BT+sZ:]MNNɺC?pluZnn\归^4vq.-ݴA35ˆ| ~X%A@c@X_m6ʔ'%OT9r$G{M{@種ZQ{EQsSJ?SUGZ>pz˞:Fmn]ݮǍTOpukDڪ6\kxYw~C [ {no&3U;uqU*AC:%;yoiG=Wl!6htֺ]ۡaOI~H# ~`^!.ӂ'..Oh`*bFWi:/;-grIvz׿,T+׌~Թne]:z4`|=5Wܩ#U"ww iQ=/g$Y%ٕ2HS4{ʯO7~Zȱ5U野_[嫮\ؑgՇ|rnFJ ai ɟ~Cu]}$6)G*u}RW?Fh BA/j~.2S>ࢵr*%-9Sљcҏ_t_\_?ImaRulIRQ%y瀞j vM `rs"NF'Yy$b+n]w~+~@KA]lT* IDAT:Ud6y]lզO=IJMJ/Ryb¤?6S@ _7L:߱4ڧIQ8~qC ^QG@_mkzrN3+ s8eu/Sk5Уo-jUÚ诪ovv&/>?{Eob_0nP}Lnv0sGs9vD'U:{ZYTRnu-[UYe?];:WRq٠^.GO:ֵ/,_3< |IDss[.4_ 'U.ZHKջqMbhSx#@V^NZ"{N`RqQ?0%]~8}:}t$I:ϵǑ/  ]}՝wl[o%7'?OWtK<u_ĹU2 DZU~:wv_)h;o˲dvx }yufFeI\QV[#@VnYYL;xzN=H]++'~[/ۧݣVdrRN3USE2էFqJ/*t`jҭt;?e|^׾{={NڴkJwיgtIKgW{X~ݿbGw]i/< DOF[18t nstEڸUjUv;p%&pcpmgz,a߾$ W,_ԼRVm@1m~ MLZG/Q ݲ443. =RT:%ͽTOc/ջ~/e̫ K#j6gk[uA1oc mn\6N~F 0ǐT{?ke$4~e5@Xrt ehReV=&4}B'@#e:~2sաb1Vk?&v8VDzN6HDZx[l]pMÉ+Vo,mFRVۯjWG^W@Xz1ozmsHsM?Jo ]2WnMkmw*n֬ Un֝4;wLύFw,VDzd,/,˴'{~+:WHTtvdJjL}*^v4ERIEVމLA>Xd#@z*S*tt))ͽ}E+Ye7C^=WqIҔ:z-E]΍]%o066=9FTٳ5u}5ܟpnީgTR q-ء˷h~K=bKG14)K@9YNu \U+3x E]]%=;W>΃FsX%۶c=Ox˫ O,ˊ%q*e)W(bUr*%ٕ҅?]27GU8)$f>k2?eg'{ vi erمu}z۟[~(^iVlE:heReW)\~&ck,BW]#/:\I?V:-|~?N byuϓcH-RZxߩ5}栬~JK[6-_~OjKtaQ%y瀞jH`pps7Ûkî.p%6I4\IzVsJ4IZ,w\eZ~/Ƕ53{ace,[%J'y-;~^Wl|%_SjҺR싇T]*-|mӁ3xmRVε-˺o}8՘ Uݗ[?HܛOwY2 +sJYu@ lggdWp_UתciVU]kv_myݚ챗eϕ>W,w w\ :zYjciPiCm5s~ۙ&I$\p U,GUj###irqMNisT둺wYzYz˲p\N]*.T2.MUevTs3̄.KUn֝f8ι(vv=[Y2,eFYeޅow _~GҜ99%uluuJ=z:ގ.fXuYY:Nin:֮ݦ:*QD&ѠJ{ICi=f4<(*c_p]47gΪ W8' qlMO*yQ&Y LXJzH8#4YǭΔt0j:A~eL'_믜̹S(wnix~גh~jfҙu-YH;$Im_nݺ:tXq 35 'Fw;۬tm[?IY؆$bY2 +s|YS#@|S(Vo֦.G7H8zе_{.TѺUHKջ,Gað _5L-c+ptqp߈(+Ka=(<Ἅ-WmuҊ;*ӛwOF3g=g^?׊ בzDW@@]zmg^I}ޡ{"DZkJ/SSOT]OcW Sx=tr!9r:ϪTtUd`.;_ ]Њ┖LNʩ{jjW|иV UVK6 %,洫wNN:œJIO/U:RzճVg~΂rI]3Sꘚ=;Rfuc׼dM`*h{ƾճRs*izoӧOkzz&#t":\5No ꞙc=/-W>ˮ6vxxDoxx}a2e sXk&~ =a>7hb_ݚ,׆VG;nz ,%F*Z7UWZѡRFX:zU0 h~G50xp5ѽ;d\qGEz+ F T|{WEߓΎsEG* /.]NY"*F߳evyAǏܗWr|Zy؄4oT{qQVM0dvVuۤ+&I8<-G%UTu4+nRڞ j2\+J]˔ ӊum_|d#@ sgg|ax\n.Tuy`8S'~(qi[iQW-^ᵿY8IIbY2IyCYc DE*_ګ i~C8 3X^7gIY+K&a7+yPt賾4dL*qVk6% f㎣3&ci]$OV(KIהUʪP14\54eG /F-[?78#1! JKY2Mfşںe9^f%ߙTމlV:$hy1 o򿝏DYm粚§ ]4$|2ۮȶ+ڍ˯v:ݼ-.YmBuHjuyPu©Z?mna knQ^  &]:(K)JRVWV#Lte2X{~Awk4 kݠqZ֨hQ"ǑIoZs5je5? FIuM+~wD nzIT=3>z.Q¤q[V(K~$t*tINNHͪfk%+iR8 ;natFih]q?I㬗y%o(լަx(t24w& A-7Zd a:LLŠ+΍& q5aQ#J\9>e)l,iۡA:@֑#Zrhm{>z\ diּ 3`ڟ= 96Dhm@ LG>LNhիxGOt_U:q'/St祗,ZK-o<bgrQ_deYG^ܨ߯4>eDhGI@n ?rd_SRB ,˺ WPw^kYm8n  'y}Cm}m-s[# h8t&bvZMÉ+\:x4 dYZfv.k@"8?-v2[(AԲ%~@R{>c?Ho@y2u|\S}`sQ\h5L Kkn#$D16@9ΗHfY!ZAG#Ն HI ={FIg\w'N?kill% U68;MMrKu1j}ݴ#$q[cxM  +]?ʹuw/>qWAΉTRkt~aynE=$|ueݺ:|Ky3Zv~3^^f1m∣S \\7#F%x goIs#2R%L/k池5i__C=݄67M©Ow,ZVfk,z@t-lűNV2c}IC2aio[Lω8QwW A:xp4W3'ViS_ckm(L@"/]2QW}~oa⍶wc+Nq{4\{nqG:Ü;^W{4g;Z +qΦı&FMMF8%]~mf.o9wiuww鮻>AJ2 ֮FE;B IM ˚Im6Q?M(I.IrYߖz=jZUyY}C84M%i||\Y͕O#@| *AVG<=7MިI9MSp6o޵ǝts~NgͻO.~˖7g\xymt4+Mݎ/ly%VepMt@QBc;DZ4Ot]oں@#m,@@ogş6Oڴr qEiSNn۲8ҞGIͰ!Mt@Fdqڱ́{l@d13f@Ҕ^iCf%M@@~ӆ4M6m1)Df M$J4+iJ444mo{+G$Mkl87.4ݠi~YU_ڗr : j'IiZ7jڵZfV:hƿct:h?s @6@4b|| Cǵr劅۷{?KЂ:/I+'Q-,IںRlzblKIENDB`MP3Diags-1.0.12.079/doc/030_users_guide.html0000644000175000001440000002056612040502152017017 0ustar ciobiusers MP3 Diags - User's guide
MP3 Diags
Notes about the documentation
There are enough features and options that more than 100 printed pages would be needed to describe them all in detail. Currently I have no plans to document everything, but I hope that the interface is intuitive enough to allow most users to easily figure out what can be done and how to do it, especially if they read the limited documentation that is available. However, if I receive questions about how to do one thing or another, it's quite likely that I'll add the answer to the appropriate place in the documentation.
Given that a picture is worth a thousand words, I figure that some 20 pictures with plenty of words in them should be worth a lot. So the approach to documentation is to mainly use annotated screenshots. I think you should look at the screenshots and read some of the text before trying to use MP3 Diags.
Besides being available online, the documentation can be downloaded to your computer from this link.
F1 Help is available. In most cases pressing F1 will bring up the "right" documentation page. The files are first searched on the local computer and, if not found there, the page is loaded from SourceForge. If the documentation isn't installed (which is the default for all the binaries that I distribute) and you want to use local files, you need to download the documentation manually and copy the files to the appropriate folder. These folders are searched for .html and .png files:
On Windows
  • a folder called "doc" located in the same folder as the executable
On other systems
  • /usr/share/mp3diags-doc/html
  • /usr/share/doc/mp3diags/html
  • /usr/share/doc/mp3diags-<VER>/html, where <VER> should be replaced with the actual version of the program
Contents
MP3Diags-1.0.12.079/doc/120_first_scan.png0000644000175000001440000002703411262645577016501 0ustar ciobiusersPNG  IHDRjbKGD pHYsȥtIME  3: IDATxi_]U:[:aZRKA 0`{ >{lxY̚XAhwll̼XE0aql|`16f1؀ cK-Y HjIU;Ky<|*W> kpι薠[w+&0{–nݭ6mOhƌD Rt9rLGڵ4=IVw M42rX4iӦiڴN8I?]W_AhZo֛o}{U(@ؿM~|͙3+s6O4~YWӺg\.ybQRYӒ%O~Y:E:3uƙg*qP{أ?ک]vP+@6sAٳW+W-[^s5{voQV52rXkra"bQ'Or5 7{\~B͚5G3{uzCnjuu͞=Gk`E_\{/z\ܯbȕ66g^-]HG]ҥm33s(O=\.ӧR(ĉ:v옎=ZFOB^.ܱCǏW:rJ:yN8! jU.XG7koS56R' bQojV=մU.ҥ3ROÇul-ժU)S\VWw*ə3#ڵoW!7i^ԡ|~lJc.7{XВ>͜٣ ^ڦ?'7v\.qe `&jQg6Wz埿[ݻhg38CsVGf6mz&TE|IR)g:i}#Z}(qvfBB0ӈ3uW{#GR):=D#qQwmI}]8`w[by1LܺF?xX **ڻw\Nz]Z]\N߹ JEUU4ZիnӢE*j jzSRwH_Ǎ߿GGK_,JfK~?g"*J?Kii``-[;M:thDU9eI/m;N50y4a˖-6رQ-[X9_k_X~u87[zVR|^ZMm~FK묷7v!}?ѶWI;kѢ%j<M=`?I9,=$^{mϤ풬>wLH9g^|qP4Gt,]Ei瓧q`ˤ%=xaϞ ,Rn -[cF'] tЈq}ݙ]M 6U7k{;q38]=R.S$޶Pu+VhO+/7}QPol;'T(>qBI"QhDkY=IЂ~Pw$G6ْTQ\2GDm?w//Z|}ҊKOSF; Zn}YW_0aٱcTJX>҄DdppWhdwfu”lIbO^?z{H{|rvzΙYerk3'AW r]WKgy-_臺kW|^'Ot  y-<, \pFGk_ @n-X>R)IJ?QbMH,K &{fœi>rYW_и&jpXSr;S4Y'ja+'=A *=gv\J=ыJ^ݒs?'?hKuE/7A]ǎS>WXTPTסCud-3ky35{&IG^ 0uh$j&O;tGwoPOM DS ֹS&^E=n+wlkT\6nɄOeeU* Nm٫s'$(:^N%\܄$jrrVoow#_{MU.+~p3(&U.7ݍG_r*<8vގVbx,r9J%ر]CCTZOQWWQǏБ#mep>{$O}hDue588gݦ"\or*K#cchm^S|R֭/yvU'm -fsYuj/)KּyycӦ_7}B-i۽rJ6njwiuSs* :'NWuruT*iŊuɥ?_|^B@eV7X%uˋ[9wKSRڼyH裿5\8>컆ʜ9ZpezspP KccGw_9f/_ 5˺cO08ڱcvHZY i7"'ia:O}°kyǤdͤmGg,TT_#WǺ*\XROOz[.R۷O޷wn˥:+Y$ͱcJ;MrYW_J=66>xJJ%{nƇ_|.=Gg?]ӫU:Qq)SKO;M'fLJY~]۶M1nt:CF~r4i=&6VFqرmec 6VlْFݬ+gPϝtYF\JܸG/.AvYӸSv$4~Bv\ΚY5cL cW$i߾}:ֈ~ pa3fRKt =zTZ61 1T2'%jVs|ZfST$kjme:,\.)5yZ%(N^:&cL>~u?GжWmK5j\e~B!H I@uŬ\.TRTJ5I7oJ.uJ]Ri,o SjFFidP*z"y=2&?qYu0z\g9ʼn>LީǒWוM|O.SWPPX ADm9O3'3(v?mӦu饫&M{2ieCB~JZQͪBQ\qYJ!@'̙3b[ǯ|2]5٩&3)ݸzzfjiG/$k5c)S5Ș O}\fha_[l@G%j~, ÊZ+tzZ mZL1 J8%}skZ}g)I$41 , yK@\vf_)AWx笗s(S|ﵯvLLI %7j,8>I%?ޟ۾[8D9~Q`sk~ @(8O?Ԧ*)^9!Q%5=+L=/LDGS툁%kQ۬fp,LnDz[!d>Q3 ii Ӻ"F2|j2*)ih+< ~mVGv-ٜS,=H$j@ QD N˓+j1\QLIY.wCsE 2D H$j@ Q ]^Ot\ƿLKlXcD ey\*R9 SSsf+b }D aݠz?An' ښbh96Ex%Nem{++7.ֳoܿWYaGoPn _dt~E:I32[Տ^W”LfL ǼGm79'/zg>I*f~uIXd~0ݰɃI]L뵍IYam߀?L}9̾MCx]'1:mY(~8fo}%\Q;~e߇(QKRv5ZY?IҘ&U+AAm3is䄍S$+ZqQɱ{Ll6L? ]6-{1>֌%T^ۛ|m>mi3|mhhK"_i\Vu⌁MVJ6(RF4:Ov<͌׀2LR,71p 38A 2oغ]u0$YKMa61L~sGi,7%̶ioc&}%FW>[qCunU\Қ57/RAnWuܖ-wKNvlܿI]fz SuEwcھB?GnyETZ6UZy%n DnLgԹm'I4-@BL-gDIr7'# 2sZ~ю )HԚp"ij@{HD,&AYOܒM4DmR$Eg|:cd-dį~$^)[|@;|_/|M/M2IZG 1odͨCS:Eپi??/2tH4X罁 n0L[{ >w[W[,6sߠv rI}A69Aʠ_6aV{}+h(R?V54pro`o]Q1[6x$Ni/hgz|M}XmG_51 ۞(s'gA=j@#>>-OzQD´-F۾I_ {4~`}"Lco%RWM ()NAML^ӥڥaK[[9*(JZuV1iEjV{ޓAǰYg6Dpx ^ܖ7+qS,:$٦4cլ}x)Ӿ漺+NZ'KvDmoغ:3[^ulib_Qγ׫_܊/hA߽D94{ gtySx܏W[8m:/m^N/Yi}=v:VQI]$ݦàn;aeN{Լ8ou&ֲqKH}Z?(f}O sJcqG1tfuZ iMG9sJ^ ZϹk&ڧ_ƱY0ZǚFdvoSm$!N2qE͞8Lpkʠ>´!N“TDLD- kZzV2TӉ _ 5fk%i8Qs&m OodhD-HV'in&IƉZ{Òi=HF1V?xa W`jk{ٕ^;=pAn:5iFGkڰaf"-Z4D?Z^8Qc !VC I$F|y!AǕ'49QTŸXnHJ8-¾N~}>YIҬ{:a"xäA}5s4 "e9*۴Nn˝I52eGuÖg{P2v~%nu7u~WܒV$A .D94oV@о\?eh[ZSe}."3p ߧw.fR׌Euuue55k7w{^=2Muk?~_C|[L~OiFtr$naʨΤ>a' 5mW'oŖSMʕtZhf*; 8B* IDAT֜Ea:$^ް1Z/(Y臹R4]8,ݟ^MɱOߐ|~硜-g>ӯμyO2M Q4-zscS$ifG;+@%qIT4C@ɭΫI|wiLcN✓<71O\fym7OP+cdQSwwWGq_Qkʼnd CmM?fD$!+0GP4-3+ ^%>[Nv96׊sl'vqSO=M <\qτ駟}K[n=z+W^vx%Ra$=row_7coǨe$8uAAdxS!M㜪V[r&IC!YYw~q195o`R0l;8džO;'>%8Y/|&_]b%k8OJk[dԓ_{LܨIGLQUY'tYmK($9sas`mLr״\XF>n;>J#i;W99jsKNLSOFF _m뿾8Q۾}X#>>ɏ{;ޘ4t:A&=0f`^^XfL+~oDO"Q~$ig$[qbf߻-7zxmUVUxcRI,U.JV;ٗW܎q;^Iy5ιzz?X1ۿ{Բ07;k^Ml֠1kWC+aAZy_ cL=Az۠w:=؆X1EzY:449lZY$90{ߌ:I7.78_ñiEV׵q=$6V<_Q#i&$NINb>{etƽ j&ܯNAPyW|8*v$]e%8=I>}1ΊGԤD-6n|nݭ*KZf߿%\'ICC[ڶ CpmnZ&Rޒ%_}ukƨZt_1Z 7|&-^˳>댷Zڵ=j ͚}Z?b.Y2vxdocJ mkR]B!^mGn"|2m*N}wORN Im ߟ״;@As^獟| ˃~w.(N#zLL^ 'w5Ir+jj\ 7,'k?\Q; +7/[jM *3 +Yf^Wwm}Y8F;{$Iɚۓ4-Y *+2byTÔ=Qk ;Jt4~nOÍ8kQëQ=:/Q'?+Dv,o(N#{Smb` H~0y-o76ML7l(uk澼ô{">Nsr95er'ߝ˲TF>SRP4P񏿕 L,=ЉK/=/܏$ +Y5+nζ._~фx$uv;! h~$U1L|W$KM1?-4I F>Τ-FQ74~Q`ݑinne߷\NsdV7cqeB!ٳK3bEk]蛩WX_K_s|mg^TQKc>{Uĩקah2="&B ~6is$+ʘ~M_Ղ;J{ۤu76lw+:$uGʂr߉3|u?q7>FcO[C?&Ѓ~HD0e&?@ȯMQ&e$u>5)?lܶ59aSؤ6n|nݭ*KZf߿r0$Vm8<7%}|kV^}FLb#Sxa_Q]{K2S,QwC0<]q/^ܧ}o+ I-^g%D ?HFZq2q6x'VL ܹsHUshM&Yf 8Is'<к$m&5hx?0KQ0IsW@zI5hi54Q%inI CI8IsGD Z-Y20Iq07< MP3 Diags - Querying Discogs or MusicBrainz
MP3 Diags
There are several sites where album information and / or album art can be downloaded from. MP3 Diags currently has interfaces for Discogs and MusicBrainz. The screenshot above is for Discogs, but MusicBrainz is quite similar. Going to one of these sites it the preferred method for getting album info. If you don't find what you are looking for on one site, you should try the other; keep in mind that adjusting the query manually may give you better results. If you can't find your album on either site, you may want to search the internet for the track list; if you find it, chances are you can import your data by simply pasting the text from the clipboard (that is, provided that you defined appropriate patterns.)
Besides the different database, there are some other differences in dealing with Discogs and MusicBrainz:
Discogs MusicBrainz
One edit box for both artist name and album name Separate edit boxes for artist name and album name
Cannot give track count as search criteria (which is no big deal, because you can use the "Track count" filter, at the bottom of the screen) Track count is among the search criteria
Has genre information
Has style information
Has composer information
Has extra album information
Has link to the album's page on Amazon.com
MP3Diags-1.0.12.079/doc/260_config_ignored_notes.png0000644000175000001440000014717211262713205020525 0ustar ciobiusersPNG  IHDRhKRbKGD pHYsȥtIME  ⣥ IDATxy|řkyE Ld$Cdd!$Ld2odCHLq!a&mƖd[w[IZTu9zꩧV` / B!B47t?2rzijB!Bq@ڷ:6𩧞FQQc())!B! :::ٍ.\pWwyyJ-B!B!hkk8eEEE(*/A-ToZϡ=8N:P"B!qy?~u:cƌᕾ(޾̾.++A4~B!D"Q ^ScAYy%&M1ca V>uG‘# @B!BΝkɓ1oLiFa*|'G<G{{V| B z >cƌGepUܹ8 O@2BUU 6LyaZ >}ZϟE(8!B!'OFMdtuuNf2wrBq%\Q#+$ׇntuu"LҒǎۋxh ppD}}}8w,ظ=8,oa9 N!B釪zkPJm6`eŸqP"с{8(F!6b88Չ#Guo +Jj? bXj={sľ&|w8}g !B!YszΕ3˗\?~.t>-Yر>k>JlݺYZ5kۿ+EL6뮻ƬD˯Dь̹1 " Bo/eX*~yhV~'~xk_BUp8B!`f{{{ #t׌/7cWjk׾>؟GyyшgJI5w @yyj1.$iϜ9h4@ ox2N:{ơC\ z֬y\{ gNAUc&B!:?l0<.{aUS7yx=+Qb~L ;;0jHn\#x睭ۙc {2Nwy9,ӧA_|+8LF'QVVH$ӧSW"T( ~" " !VCO5ai8q8"dsB!B%Tsz~=X)1GL d5hFJO8>3۫w4wxπFЦ/notL[}nƬH&xn38upۇ>ƽPP~L<do'B!dH_܇P[;Oݍ8vsP?رؽε !|, pK^] ۀKV;WRTUDUH,Z4gfȁ찑#9jHL8vtӼq͎iYh>-ӧx.>7 DZuۘ3w.'V?я݅~?hm= EQpʋ7!B!VU=jރetr?8m8ޣEPQQh4",Z\ӥc >rwa` O~ySˠ/-.//Pv1,ωF>} gI83`uEE|1 ZyJFQ}|+G`kW^q&`YxwŏH$H! ` ;!zzPդC!B!|(KcճYs뭗xF1zt**2ηr@ft_Tpo6 ;Fdz]k[;Fy9%-yl3^(QN?_= LR-_ NEww7BmmH$EB!28od yo {Ē%5F#Rw?[-ԝU}8@04^Z ևܹ3Ӌ 8/\r,Oߩa2Oԋli7_hz9 |@$-@8OΔK[  4i|f,UJ&=qOc>z^飨]]+p8P(p8>׈DcHf%߼@ `0B!mɤcFZ>󻦦 XMC]]3M7-<*>.F"}DTXዓѭS[YIcԨKǹGL2+GX,ҹx';z\UUbE3vPr  (t !B!Nȑ]ee⤜oVEEQ,Y2x L EE!`0pqFA!BɎ~Y|6"t9X?;;!B!d(PVVgϣuZ.t\V|-gH=wݲoB!B!AQ *//Eqq}!B!^!#oB!B!$W7<ЃV!B!gB!B!$&B!B|B!B!t !B!BB!BM!B!&B!BoB!B!7!B!BB!B! .iBE)Sl*B!B{:+VBe䙵kpB!BF񮬬2Lmm mM!B˵I6Xj5@ST$5B#ʉ18ߛ6mGE UUo0;v)l1\2}g`N}YS6}׿Hd;.l>|: (?!;x9 x-[ڶmXrjk7ڝ~P_[W)oӟst|@(BOOϐS޴iܼe3K&ldP^ж m-$z{{-WM:evTW2<Ҳ;n -^Ʀ6$3?+m/}mnP֬տhsRlmno}zU\п4t6-=N~ʔ9lz͹M7[*؏o2ֿx.+'ۅۅۨj6FBNe>_M{ϗeFɂ-SيoMhno8[nt>L{6-䔕'}L?-"L^5Sb߾~׀)S`߾Ol=W\>:|_1r;x嫞} F[FoV}Qe_µ;+MuvF}>l{>lwv xP2N:4ԩs3yfaruwsjEµǍ5r1߭O{\η7x\2jj%om:G^vAx553VatD\̷Mُh;;ۻw[&L&i٨Q>ɤ*];)~Z>rV[׮޳Qٶm3}xcBȶݻm@^noԏYsZn oE>8sIVVrٍnl՝Ҷ1's_em,N&|VU={ם47mgR3GٲC{LJ%εK*]F-x2KNnaNE;kضYh؇Si}-]lm;'}S]Yvy3f\f[~E!Rt9^^ 2uG{rRnU ||ܱkvrƌ ^ݻχYcD]SB^flsѻFf].Lټ,v߉n;OF/^5nl۬|ÍlNyfͺwS1..iwngeteΝ^zQV^Oc.wzQԍ:Ͼpe'6U;wn5 5qsIf|͎=ܦsΜlBGԖγ]}Ѹ̙X8_ѲyY#۷չ۾ƍm}8M9׼5;nz췋|ٝ.+[پzK {;vsj~*۾ʦ(ە{$'/\KWȖ6TpߪĜ9 aˬeNyvZu<"8IƦ[C0gb44l6-Y&]W4_ѲyY.sev#,{8mhهV^&W>rakTwnEvEN?v74l6A/te ;\zQVzK^9Ց+[fyUn>.;߾}]9}&lw(LxYՇ˕<7t/͵}ܹK}&nk}&̟L(_Qy.QFr٭OҦmb;I[#dݢEba|fe6pBhۅ֭ozڝ|?.arL;N"mBhkvGX,K||ze̛7ֈ\~B׿->S!d ]m-8߫V.h%|K_%e˖֯ R5a{ sÔ)%/M[+Vކd1c:A!BH>ڵ3>J^[\};h[B!|S[[{\9B!B.t !B!:߄B!BoB!B!&B!B|B!B!t !B!BB!BM!B!&B!BoB!B!ηӦͣ !3mڼ~wB!zB! qyGM?}L!7!B|x1r !R@ηv9vP3͖™%lIF)Bn4y5nsl&2X sN]7F3=-y!a4y5nsl&2Ųs%n^s !?B!ocy ! BXBf9B~XͱB,A*O.m#2XDZBHŲ\,8_B!N{X q,L!m[;|DfyWK^X6B!Wy>̈́B| vHK(G? 8N ʗBH;L.(݌Ӆ6r|'c#|M|y;/o;WdR#GN ʗBH; \u !8鿝8p⦅sϽ84o uiRBP8B!Ht98B!t9B|B!B!pG'r;]]= Ҳ7Wڋm a;1dG|cٹW*g2Tv9ɓg8B;! 4=qC{|sp&.Emʔ9l+NhBrB2rgO8--D盃3!} ?u~qǵ'NhBܐ^vne "ay} zB!p&ęg$;!~'mn}BBț;1.|sp&Λfgiؖф+;w;76nc["7wB8F)d K;߻ = ф8`JLҰS!^ۦIwom|BNhBdYp{Enܸih8߹޳}Oeq2I[3ksBE!|s|'9F3q]} :u:0HC"B{B E9vr./o΄BoRp9v-ZU~Sy2B!B!g7!_8M!7o΄BoRpp7!B;!,ÙoΜ9.󊋋\|K!pюF:Bߜ͇pF!K!pI&s>:BdBƆ /˗_~÷667Wl IDAT_B]?_իS;mڗ/7nܸq+mڗԺ7ǥ|l=…s]nkYmڗkYF/k׾67p֭׿UGhկ~!=oߪ._~a˪aSO=h4zŽUb-[[[mp_(7 TUŏ~<ʜYy?曯-&B!RcGU]we}oa,_~zzzrw$uo܏=(JJGBHϢ8Fj ?'mW{<̳{rη(PUUz;|*=~3on,lݪdwdC6eM^S{ lFy-~͍[:-fixh:Mamlvuh׈IVqf܀1op/ԝO@Tlt5> U|̅ܵ^"R^{ŀȓN`^loSxz73el @BM;VxV%+Eٖo2nhBPglUf\Vʞs6MU4;p<>n.Q|Ȫ?(M9C_8fa"zuZee:Ϩ>N[DGNl̍ݺ +Z'哱cxNO/) |YGv>^͂?KE¬2ZFk'ee-S6llC&UF$k232299W>|BeqR7"fzr7'v]]#;=k7[z<GfqElaVKoz٪B tZVdeɗ֞=dJ3߲˕el7H;=O1_/+gm-`x8[e Z͙okgA/> '^\{!G't?Eewc[gY#;ŅnGϦS%~vT:^|}6mVEaϧ^+A2mζf}L޹^U͙oaz]Dg~[gKtX1:W$+YEq#lClNd6iէSc'e=̷ri b'8Vr[!f 7ztZ/u*ȋܦ#[62>l\q6#ŷ( ׌NN6줝dSo:lSO#ࡇDuuɫVƊR(nmm mk|}}};vkּo||`~?!N#BS8vTUڵq}wZ&v; 7\"OOt7rC֬yoFc[zrP[.& B߷QW3߫VǏO|6ޫ޽MRyKK yY=X\vNP' ԩN&UI"O8u*Cx;wcϞn|š"~(mx>÷1ۦ؆ ѷSHMd'ݝ@ww݇:;pmm}hoCGGxoh4{h?ڳw,o''6v΋䂾x''ݡKNuOO}}Ip!29ڑLv+ hmE[[ʑǓL9]] iGL~z!Zv0/lmFq./&S"zt*!2<tvedRE<|:+B B(* aذ(()I9G1lXQ?ނc+svye(.(NO˰qi(ӷs"Nv_Ɓ0rmv`evӒqdR^+XoYթLlë|DlD.Wh&uc{NYdeңrWoN'sQWN9=;&FY'Xet?a{QHNԦؘu[tĉSNDQQj wUU"<(#`**"(*J9ݩS}[=zq <18t2s63K["UQ-hZ^+Yre.[^#m8^C6E^Ey*⤽LN3CSĹ s7΅nfODm8Mөm:U6eBfk7+5y~O'hėu(+ $rY!b Rԩgr2B|S-iy %v!yVʭuk3WπT8n[kɔݩn]'N궼h+N۾W+.؉9MٷB3s* \4)|)w0r )%yZB\8ޅ~[֑ &2b>ټOIDq۶Rn=m*LdT)[`s<<^.;,QR{:Yq#,\Yg9MGF#.3heSVF:Ӟ#$,[vo|^^y~.E^z۸ٲbE+ĕfKE"׳~*v]]#;=k|< hY*tvT.|;;Oe.;;OeWy&hyFӧNJ8DtʣOS2a26"1<(Vvu,"YՁԭ~g݌drӎg@ϲ?ɠu2N7}ѯhf-7?s׳xܥKSowzgƊ\[^zk.[$}2ۥշZ2_7eуh\7NQ^-:mVy:Շg=ș6m^]9p8^g'Der;Txu$&rɤ$?'n:W4/*˦3zhkAYY{ 턧ټ l._.s$|T"Gnv"o6LVdKwSԩɜ#;7m+m ֏Ӷͺ;yٯۅ̷O6;xB 23NgsY[{ѬweYz)p<]m?nf/vo;'١P_F?~3.Ȇ^~.Kzy:!${m P(L8['3 -U:nt)j@FFI?oO7ODMM%JJCΡO{F3~g0˶Iaە[˯I?vӋo}Q=վ;cvKE1reґI:vrCV'"iɉ'g9aqpxL\X_p7]G"ymfNBH0Çǰyq|[oۋbQr !<ǎx}ېE32x><^q$I1GP_­N׏ĉDT 3߄Rx6g 6B!Cy˗OO,wנ8^;-xq`;zzZ-pB BE))WwCQkXG$W|30wy!̙3/O,>6 EEA_f<&~9r}}I*w o0'wqtNAջF_oŋG{kQZڵ-xC(/'n)x q~ɓH$gB?3ظ v}B!C0n۷Mx9sj,&L(èQXx4}ُ֬c&lz_?+VTc* E >e=&"=뭟Z,Y&ݾ[Yju G6¼O}EыԟUYF4oB2~| gGC<|#D"ALT|G.x?A=6n<|IgNJ~3}m\}taYviXI!$6gqsQ m.@ih\p"scݺ9S-D{r+ChO>;;^8iҡM\bowtG]]c|ѢEXtu<8wV 죨S+֋YlnvNd3 _{={asx&L\qJ-) c2W_=twanTUbRqz[zT{ Bosx9Unq:3-*>Cf7Cn*x{!n:ҋfKEdt30W_u]Sb{aү,Z4 w]+-3ggzfEQP^%Q[; : v/ MM@{,_>W]U J9o/p.3F !$v!|;VxȤc.|ܤ ˶#'B-/ݍechnnJK#^k378u}i$Q `ذ(./yk<ʀ| x47!OxD:˖+ԋYp&ww[Z:]0ϜcM.}\t䡏 7ˣ8Ƹ*lLd/癕ϪlM}Xl̀أl9e. +"a6|kB,wƌ Yu+&L(>UVlۖ٤I PY9% M;ͧ}9̟? :W^Yѣo=ށ;Bs3mݲspse[Ն)U<~|1"+,LΉtyK^iyeT޼Ʃ n]4LƎڵ<]{q%éS5SHeW^X9$Cw5 a̟?w= aaLz,pq)Iy;7<_>UU1BN+?;[0e4:G8P "59n'&Bo .;'xEz@ӓ@ss+:;{1eJ9Ə/Ro.:,- ['ܹ8;v\~> bWgaʹЇ& Tk wac8v}}Iᴻzkl= _We;j|B)~&xf'V(zCSS+.Cyyu:.g>3VڋqJ0qbܠ `~ fͪGeialrKVaqXx=4܏`Jv/IMl=M!${6g BzϳlPtxToC4ԩ9 PP(ŋG{4W_m7˗׎F<+Ƴ–-c>j:|_7^3ju •bp;B .o:߄'I_1"+:)绫͓5m#G@<ޓ-G}0s!_o;W6lxY}ꩧFCZUVcŊ[PYY)۶5Viaڱfͫx䑯\QS W]WψOwᩧ`H|`J*$I1|[g9|5x衅ygF`ᄏlر.bb _PQqBHI$H֛ IDATO&5XXThh؅[9…PZZJ##"ȑ\9?78~xy^=mӴgE<ރ+3߄/::zwy LPãT So?xz1gpw_-JJ®ӏF<ɤ@3'o0|H,_qDI$D-egyv}| !o(/c9KS4?7űBjj*>]EOii˗OB})>^݌9sF`ɒQyl@xm?`8y"H( $3oS_pMUUG?%R !&7!{s-tPBUU;ց#G:PQ镈Dw0aB {GC^݄K1~|vݵxb+G[w$η@O wE8}mu,Ӱݨݞc6L&vr[ыȖ+=6ƾDmOזkrQBo;^ϙoB!&܊ӧ0yr9&M*l֔d`0 Ggڵ-7o>V0ttz{N5bɌ%PBJ%]NSNwRÌãI|ؕ=y~x^Y]=_|2;(>}Ȧy}mccm}8/;qR^ȗN[Uլ`BTUճz.o^鹤|lf =n_4mcE'[n;Y.;3 45"O`ʔrUDeev$|;ǯ~Մ~3F@g366ХtGA_^$I$IVrjؕq^y 8󝣻%~ȷbZ[sO֦v4֣tT~t2Xh&L/Uvz!/q@Ei() V KOcǎ3x&LPcK;%e{ !YD4LA,jD,d,z; Db9iQsd43kgNVr/'xNeIӦե>LD%}ٽkߪ.ب "7."aV+eVYƫ6)M >s:P+|+*yWI/ӧqhB.G4R P(|*~mx̟?TbUp$y ǹG"C@ - e"a';2eN>*mF7߭3sص28ѱ]מg(߿3IU>v2\Wz)Yu7ӓѹ6(VbV2h .vmd^aEH^+]l30z3Cs+©z#BE"ām8vÆE1iR)B!)P¸j44+1}z-*h8|ytFnuk }'i/BzNYiZ9p^3u!*l:^ڀ4;'WVh"vD>;iGVmZC2eE13C:CE94PA 463gVbؒ~։x(.ýNGcc+N=Yz( k3z$ˆz.5脇;`ᮢ(o#hv5H!6ͩSZ?u\[݄e߾~:.qZFYJەLVtu:D已tdlT&Lju{?8?4E쿕\nۢW}>g~q= o=pv. L^n x(sO ~mX IynQu_p!؆^^/:⡔y.UvP!X5ϧ9|Ѫ,VrGu/si,\Co;e7Moy04:vΩp-M/qN¾}DI So?8w.^h]|ڈ)'_Z'KQI }ztJ(ɑIAqzz+[&m\'Y쿐.'HۄM4Α|ϟ?b~}tap4TUf\#d_OT/2eџ^ɤCqx'bʔrB ms0aB mvgGCQ?=>â1M  ,ܙB_vܼisS"1nn>sw`ڴye6Ӈ]i9Jת ҵ4ӦP"u,Aٵ?:퇼H;|B1%O=첑0{&Ro?=gqc+?(W}1'cP{+#. EӶISŮ)&bٳؿ PSV8L B&N,w`v];ۋa~u$$5B񊦦oB3gΠKz+..B UUqx'Dqq&ރ`0/ 7T" :>󊆢XuӿCnB/E*AV!x耧7/9\ ^tuƍ[Rʗ28Sgqei*fs8vLźuGBMM,s VCKqy !px_9+֓9K|pTOB(t/#S1G]}h (v8_>q1ztvo*h4_>0}oB)LwG|߁oBOOHmB UU$QZڎPJ f.ܹ@]]~ sT' pV2%dR*C"g^A$ޢѨ*77ߌ5G$`&[e7Y9qs6tV^ &0b LÆD `-sJYYg\3 gKgO+I;|lɳvyu^n˔hK'eѦm;W[.뭐/l/:C܎v!^{ŀ1op/BϋuQYQ&+9 mo DEYC `mϫsCe%LDSSv8 ƌ)|0u~51:~13g^>x?+y)SZ&V}fM>ꭐl:Uئ%UN)W7 HV/βŞ6#E'H"L@Qxe8.|d ^{z$ꇴSθ~I`Hs^+cE̋9iGhݒx-7hɽfb+ 9DҶzi/!?("ݾ礍iwnDۯH/sCYY74W^Y{f!_/?Yܼr9ԩsܼ4] \{(n̙@siӳ`'αҍѾl"ӗH.rY`s}ܔ_D7*ylemZLN(ks^غ]_"+:WUw;N>7vk Nmny,YMk/tzۋ"iͨ\스#WVV+yddҕVs+l#*=QVƦݶ-z{uͺa"v>)&FKןK/ĨQ1[<Ǿm7k"U7kW]&Uퟦ>?^)/^ي;δܹU(M8fiʆy)"y՞?>{"ٳc%N*Soyg "eG4c7becnlέGdWvbU^/rɜ˙oLY"/(gUsé."ײɜ緷؃ozϦmk^^QZ7Ů]nQ!L^s!P\LV5MsG)55Դ0 tET-Ui6ܹs Y9s|o/jϮ0+9Uiyd3gynT c$~;Q. !.WKp>᥎dͷٖ-=џjl-8T_ ( Ə/ƝwNDccfyƌ[q!r%xݟs~K;~g9.;M3an%gCÖ~}4o/jϪz]Xi7 ͝_ιs=N`'U\;sks^٠H\/dm2ډ];Cًh\Cv+dWb9[zyKYs-˴ryx]NtmZMe f[2: B?/ Xh>(* bÆx{{{05ǐHf%55ظM2yi]"Q4&*vy.ܱc3];6{\+zgU~+L:anHXdḽ؁eS&7νB[v.mţ ³?{_njfv+RF%"ŒZ4Du+"`#toeu4L&?ۖ6V2m2έB?)+ [ZnQYc7ًd$~ ŏCT8}46ns Ś7oi2ر) nkӴ8-6M-\m%UrWF/:M༮ev W.m}=E^-ԋvkT"eKm?ލFٰeF4C=jWZ+nAeePlրnXLZp85k^osE=أַ27=qB7cGU]w$~$~Gt⮻YQRm|Oދ` P0uxkӛ翍E/L&v;|RzgA?{֬y O?2ln}17J {GZH =z<5twwK{I<܋'߰=woxnFKK yY=Xa|^BHG'?mĆ 0{v%n}b `m]m(ΫER|g=.޽Bi[og,۶mNP$$vvG丟 z1!~kǰf!̚U3+ -~F@#݅{gh8O`p\mۻX~Η2ЂWJmxjr3'3BHFCEĉ%&С<؁'1}zyj;@[oE[ " qw~? =.>w ׿ږmA|B!'QSS`P I5ъDP " jKq>/³}dz1 .%†3߄B4kD"h4ĦB hK!D0}A7őb|]UB ! !0M!H$ p递۔Rw @/zSNx8S?~߾8g !8۩wX]}uQ>|WƊ"ox͍[:trf![ Ev)j @P*$}#ޛq޿>gvmK,/F- I`^" yy@ yr_B} cl%/ZFlfl3KUuv9USOU駟js# 0<1a]a2C':uWV萑:v#1y֛`YINIf7#YwB4~ye>W "` 'M`,#&r9\ \z%kzyz-znUWO=H*왵qⴝ>oX%s !k!הf(Ok[UJVȽ +/?]wOI]ůC;CheU?z$mГwܦ`:^֮{϶j-}zqED쨪3׶h}*WtLq_^2}&;~Ǜj mL`F1|'abnxU͆{7~9$kYnI,˳~:˫~~vEu^}SW7cQ;ԷQ_Ps@H7Iu] |3ܢN;MVL^yW{y9naeF̰cC|֏r2SX=D:$uΥ\K5`ps@.yh5+YTUzm;De8usѓO|Z=ݫ:l!+G~7vNv:XԎN]6n#$ɛzmM]Fq'WFPu^=rxp!;g]6p;n\[1}.s!Nf+|=Î<,;|s[w\s#kyXb{@ye/V_g 9jm o92e뿠1?qګ1884vRp5 Etrhm~YYa<1#%;8mo]m +P3ߕ9Eo^̽VOK3Wҵf/5׼vz/ ڭBWsۮl]mIS 4?;aVƁH_Gt: oܢQѸdFd^'g8i84ONG-J3 s!J&>@{맽)Zo:O-{;Rږ-wܩ{P˅jaVHv2)3%/jZ6r\Yej[}2UU&2|Ȝʜ[Eo۸m;`w:0{|^X-NC? u߯wfn9pK6]zʈe g`9?uZ}e;6QVUu;HHLgq 8{D|~-?C,[L=;nftvv ]z%vދ[_ٳg:U۹==[A g8Vqfژ4aѢя?~A|/(8 IDATQBfsW\$w{wlÇ> f1|{?hhhs._{0uHGǟٳg%{NBHr[ofVv8߆O@k'1/ѱ;7ܰEi+BB4W~21 D"ӴyXyryD%նk!7oބuvC9A7B!$166[}9IK!㩝v+M!qzz{KDڜTBkW/+{9kN9qB! 7ox(z !?WFo&>}fzv9tB;]~QSYQGe(l5?݃a˲cx[%fN;'caӦ 8}rӫNx'ఊ ^)&4Gtقǃ4cرi{s|ϴRzUӽU_.qWwUh=q_f|WBe&=IsVDNvm^B!DaMJ'/D4…zWgrfi<m3_xM*UZ6-LE]Qt:+=2uNmA}گA=FEg^}<$)Au^ǃRUcT,NFř--u{`&O\:TSMgDIBu 1*-j [YtYUYH|dT;agAjWWa ݎۖ">AꫠuTNJ.{*"ua ?<ʱBꋪC,2RtkH rU;ڳG\PUmqkLɔAyeTq/dtu|{i8u[I6|3z+iwQ6L0/\e.B]Wi >Maꉳς$Dڡ!?]!RGHzdd.dӬrZZP,8.R\%3ϗ\/NeuznhyreD9M7pq]}ƆGq|YJ}K+H|[FY5::"ͪIut֡KU9i죴8NyVmrWo5P,5M<]A ׋Vy:K?grU ŭΠeDl֦ Tl,oY<.ګ/t񲟎[Y=e :1$kr|7nXqJO.:.c xٮzxl{Ȇ#Wā*J9nv)tߍFG7jɯoT/qQN36>x V=- g)纣Ym)?*]G:czӞaCirɲCSt ˋNjo'j(&lG2cHeI}o }+s+"S5M$JȪ j~2t!ܬxq'LEaKg}el2cOoU!4Uⲅ茍zyBDž qwja^rସ+"3(-i;4NY]v9.EmxICeVηaԇu,v$xJ"D Cc3:-0-Ud+ӑ&#CǢiaC*cW1"t'^[}BiipuKsoOL\hOL +ۅSlU~vVcOG[鴠SVo:Ell-_?G~ɯ~[uMvQA5K-x۝j_!Ұ7!B+֣otdyLN'l7!BBf 8x~i!M-* SB|~V܀vKt?!ȑ աυ!ͪUqn4]~]/8yBI==q)}_6!"Xgɶo yLcmwi|t !ڋI7ufm`uDu+ǫneԜB,~-ӞeieӏV^pMe6B!yfe{ΝK;fG۶cowen 8B!lvt,;ߙV,%B;wTv7oތ{:v'+d4YnF !=6vƙvwC!DFC2L3M!D$"IEERsYO!9kA527!B3kbBsm\x)'boKx{dgB!r0Mwv|nι4|N!tTq%Gێ⸓=穎-~F5;/~iiéA?74dolKTeQTjȦʌ/tʑwOc-y"FN΋]Ji؋ ߪiNeSыnr[X:ade6v2밝 {Kϣ:8פFC/_nC{CE\cc"u%%cr^`blt.NVs^/)/Ž45i6_~i^Ɏ;$GAruhnDc8"at\2hhiq9sDa(&3^ c0yu~:Ǭ&c FC:}}{jq6woC*$&sTG:msܥ$Fru\TF1sdjrNGLfڹ.$z{8]mNqW #ߚ|9 YK9: ::atbK~*ne|۷9_W.1 j;7ʑ_ck|!Em 3ڐX#z].2X' HqT7^ިvQ>"㮞LJF3|Ϟ##9##/:t0η])̞Dᗹ@)_թj["6;딵eP}6[ґ槛uÌ0ve~G=.Dm: F'&i{ٳGy1Ξ=uQ6]7Ξ=:#mWyK&ڎ:etPqWUW}QG6-LGu,ɌנITt:"v_:t\ گQȷb^݃{W/ܜ24պd@d~^ae}+Gi0v":d1.t#2Kjl:kk~V(M'AQqQ-zVkOs'ռraF5t ?"In#ձtLCOTmQȷ}OcDhOzKu!RZBHչv:}~iYB[G٠ mm:Dӂ\{)#WDW~QAaSIS-Tk]v?ǀ}܉'ێ4:v.:13g3nFB!2~o' B! F#SOv=^( E!L42hz(!$cQzm7oB!$ϳXbᄒ=K00rş׶3$ 9ҲЮk:]|ӑ%B+֣oO>[z؋?mB! #B.7kVG;oBiTV܀~$! #=|;T'U"TBHU6Be|B #1eՉ8IK!$4M۪-_g&d%AB.^2 Y'Bz{``tY˲cݸ馭t.BidVvߋ{]..ٶKLմFV6ձ N+F | `LӔ.wDO^Nx71}Dqw\\X;6ymFQؿ7TS$BH}ȷ#fL1z+:tLky$X`S_MwyFLEd*[jt j~M ců\] ӧvqAHR0O}K/vAvZ".S):2eq&9!ꎷ;ȩWE_^2*ial#Qu F5\H.[vo,8 .}4g3gLuncOǯ Ψ'}DTH$MVfX[_i%:^tuU"ǚX#^nZ%GREuưyuihv6OEˈ/*7I| sa?Eu+tDUmHn.ʱ4:nj"kgv'q:2\3GjƙJ_ N'KF_Yv8_7bU떱};hUn7u>Lゐ$`;lwZ>,׆|/Zt)N~TݶUOT#ߺNOXܮvw+WM.2OPm\R4Yaƾ]e5~DDW0Zc,:iAggY7HL2(]/.z'R z K(q9mv .;c]˹7Tk֛vre^:fѧAt!Iw?+֣oO-zA+,s@wݢr/+޿xqR9uu-tF^{U槛ʸGQ8Wc-F ٷÖs)#ZUov+-m8avqf|[/dcNE:oK,ԩCXNo/YN[>~mVMsǯ\Tη>2rd.x?o; dƁWkD?H2U4![ec@}}j7}!3.x`[O}ժ+7L[r [:uF/MW: ]vB}ڬ#O7g g0*F5jŸac-KcFvysqG[qFOvl^݃{]ONi?q`N8 /\)$+]}W94?"UhNYvtǯ:t 5q_aƦD5.T:8HjBogo,BHV`[㟺Wr"T/,SM++x}B2E*>B!w$نƴ!ioM /S9zK^|ٺl!y166[}4:!i|T#>Sm#"OOz{}ԻsgoBoxB ||DtN^B!1.zqBH7#߱8ń"G9!wo azMcݸWgBHr0-FGǤ͚(qBqc8{7}-.YppZaĺcScŋ+/vMU_.qWV}i;ԭW֬I:VuFr0@OzsϷC?{l"TBWw|a}_~f}w_Amч#61^sݾsZy&|iFlڴ1qBv=]{݉^z Y?c|o;jdhԩ~0^BxHY|eBH6, wW]SgOM}{_~%ŒKpjŋ]VLn{sq۶ˑ[ ŭhessTm+b㴏ɸ37#7&BvƋo8>h504:* O ~~Fn2m2OȋMreu_@WezVMsPkWi/rqEi.zV7^mVd|B!Z>ý x[0j3Q1+܈ބ(̂JU@sSvBI9^:;O:zkv}ԡY~륟WSaɒB2!&^7lW!zlm۬IQ;IT>"=3M!m~oxmXr?UM&ݶ -YTJ%bL9iziVS%7,Y*3K$ՎxstcrL꩟aB!, _+NpۭTPiX,p20+Jh`0LCK3<ԃ~ߢepLC,GpNk\6*.*g=j6xhΝJw57|B!)7?9qUU-bVPO~̼96*016+fJfy2^6ʰjέSݽfg=ye ̠ n]~ӛinDDV7UA2DW upG*KƶiQ9-z- IDAT 7|B!D'>qнd9,^!T+4M>=wD%7|w^1bn׾<('ͱ4Y@E7裣QOFh=2en1rQaBIF !֦V>ȗp@KK+08hL}rNx&GO; sx^5VmākʮZq);vTJYBH0M!߰n<rVٚ|{jzp45w Wo'}^d~{K/K/=/FLdFQ:;Fn;!0M!mܱv\h ه0(N'[@y}Xrh>b8yŲ=ӎ{dL~t5r~i~N;b:[F~ @"#߄BʮϷ܇;!8gdL`&\9͝=L20PrMere:?Y/MǍaeƱ jQ q?BZ;.#BOkS+uxۑoE `o[:oAَ͋q`':u^;qWo۩]y&rvlC?ۈ3MF6,ÏbΝJw57|B!0 ŵWS~m͓uOl6^:7d2VK[I-|wŊ {fz{uAط2/_h/]ۖeF&'תxQi?i_ !33߄B܆]kp/?MK@|Z6\;w}[.XyE4~=];p`oմvcժv/M4sLv+VlnL6"#GwQE2>M!Yյ?;_ŇzY6%~{gfdf*ݷ{7}[G_ e]fL~2+Vnm S/!F ! M?NOe'Tq<}5Χ}ۙ߾#/_2rD^q暶_q g?v]dmWV^B?|B!$$3H[[w }33u WlU>wӺL~,V^mW !3aB!DDw~bnD+9Ӝr6nkg~/=$>2vcQ:KOeX^?nܸw?!0M!̓L;|O?ӏn{ɵӽd9#Mw{~/g/}yǢɒm>϶|`&BQ M|fԗ~&BHigDt|a>L #߄B! 0-,?2mgBHzaB!cc ]|BI?|B!DçmhmNIOz{}g={RB #߄BQK›ǻk״zncI"B fB!J ~p?Gp{ϭi}x?|?7ݪ]=ؾ.[-ŽwcmoMI,.G!$6bMw su_z'^9}%kj>~it׹:Q~Τ#'BvN!0wqWțy*9,[ wt݁ qYe?>޳7ee.Ǒ#[}8UGV;U۝\? 9vrg?Dľaگ}A}׷aW^Nـ4 !\(0TByVy+MjPiy#G[n_p]7tw^-z/l sdfoL;~w 쒄}2^7iP&B&L2F+y~ySη5rsdt<ǫ O;|?Ƕ|X}}{eI_|݌};I95 9mJ.I8ipvN#߄BQW60b ̙0 c2#לCSiyokry`rrAjSlx-.Aۖ~P;ԩ?4a)F !0XD\(M}S 1a 7Cn" ֐sD{S;(8߫Vmā (7v.uÑr.*; mEQgWVF:tʞ脑oB!(aDyQnc@o˲P1+*iUr%قoȝի{r;10U2Wy ߔGDž0V'bjH8klv4{u¸w|_Oc9!$0M!E&Fn_y5:lss6[a:|M_AkS. /LB@"9v!۰3riN?`N\[[߁m:q}!vܩxW#q7!;g ol`EZ,sz2]PTL cztSL!$0M!%LșK @KN-PLͥf,,/FD;9U监oB!ioB!9&f`N4R\p7.<ԆM7hknզFGbkY|B!psB!99F9 /BɴpGx E( x7/Vzz{{{zc&b%vN!5۰ЙoGےi'V}oSNK0::+U/8IK!$oB!(_GOyװzi/£/4w0n:Xvn}3!akBHJĚbAn5~p?X`Oondw0`flG6Ν\:8wnd:fU8gH' !6wt]YY7uvv );;RqtePm7n;>;>wP nN9]ֹ-tdd|>Z-QLlgnjFoB!ԅKeYX|CjCG]u׫GkՈ8ڄL|B!+֣oϴסotspźuDMӦOJ!i#kM!mʕp35^E%RH"2{q\7Wh݂ꖱcϼy I#3U,˳~gfUd,u&BHC:߫Vmā:~knN2qɩn׃>28ueed~?ݴ $0M!sWŽno7};^Qж_yQ~RP>DLGFGL?ɧMF !P5p;=}v&mw~҈0M F !P /L3DCS IF !PwRo<}6i&BoB!$bα!|!BTعs]| #߄Ba``c7kVN!D>M!ӳD=C9z !|B!(dD$%7!B2Kol~ ÈN˲cXqB!0M!LcLӌcǎ:;]W_ᴩuNq裣>zm-#=H: v> W;'B8O;7㓤.:o"c u4&9vsl !y 0B!ioB!bSg+[3wP9:ʊ륛L?DU-W^}T_ɶKwvȕQDƁjz<䕵e {ވF !y=-|yHh9݂?Nt'\SOd;HOv*vGe##o9.[%[.y#J&B8{^h哹` sq[?=u)hwZL\ljl3Uֹ-b;2I(`B!|2ҹP.nuO\* dʊMx% GI'M!@Nsڥ(ehc{sɗU`'=tI89pIڞY{7B!de'H4-Nn3I.Qq2ϖ$#%q^cB!u|ݽfg];u\eTNvTòϘGdl=#zt["مmw\6JO%M=n¾ZUbOtM!PtwLWyO3MiսX[۲,\&cc][ԋU+):Oal2tPx7u- FvN!#3mСSɽs'\,fRpsB!<,@WIfi[Ѽ5Mz@qg !ytDdk2Yz]Aw<'68DjBihVX=;!7|B!Ga+V?^|B>M!peYj#=~B!$ |B!:q"^ǖn>i]Q4?^`B!G&Jzuϴng^%y~Wv[WZ8.r*Xѳ&QjBi(NJzQs %dvN!̣'N}}/\i^:E}B^kwv 5~Jt,QB#߄B!&}wNVSJ{tKOνڗG'7~B #߄B<>E^})"7Dʥod֧jcBF !B2LtP4oЂpr[9!!ko:߄BA#mnS-FHfi֝Qmh=߄B 绑\ueGMNRd3h$G}+X!Y&B0~[V+2%]]ߺw#1rK{ |B!$4s7Qv.3FH٨.S] YV}b BW;'B!LéބD#߄B<&:T{BW;'B!DIe!0M!Lߏh !H7!B2KOz{}{ꉇisRB #߄B! ,ٲ5;z !?3M!ۻ۷0bӲ,q7ߴ-6sq9B&Y|UcB0 cj~q&9i&n(4bw:ܹSF|B!$̮gg|ԅΖ 2Q:YoB!d˲bB!*0M!@MewNvTΫN2SEڬ+-26ʧڇy7 /n9Tm$:HS :qsB!dFH;/*W2m;ͭni~#f]iz]{#LL&:galr HqJ,r:E@7!BŰޢAd.<Ϊ2u9j=Qc*v8fu)ʵD{m[vne|B!$YlqTJ_F}aAgq(.v2eu8˜שC4oB!rXS$e.V$`=kCcYGƼ1sL9vN!.ZEɴ%9aJSΨ˖j|薫:e-zMzIǬv7!B\ol>P 3E>mڥHZu; WAE0"V]F^iQkJ8+Ku.3߄Bi(p\<~;jiyv sk:-@OLWeu'(4a]/eG> W}RpWuEՎu9q&c#HǵT}{P(Z0nqM@5fQm^;km +*+mg4}etW.ek'VWݶKw`[Š I|B!D0{~XEͺۖ oc~ӓ%e_/zsoX _ ]m;~oVE?ȷA#Ҿ73(H4lTmLH|B!DJg~9 G~vpanB 0 E#hj\n`֪m~9{NXWٯ}ckwݜ :ɾԽ1J8jB@a}=gZCE8} 4yZ1ϣmZ%,N3v`j842D\v#E$4Ψ6M! /YYDep.j *O*a0E"B f17)?49+]G8|sڹ#+zqs=h$G}U$F !"YU.FmK` fŶ0~ JGPoFKb.Ze "c~?6`igӽD-*יWdJl7'TD - GV~q92cLE=aAH{ !"aVR0M}W 9|3@q9rs m+6cyis:K<}iKe a rTtױW"eu߶] YV}b BB!D-`V"L*4~/FH -|]x:O:'zqufS ;hhBLp7!psB!Hbª84X QĖMxÆ[!H6zfa=!90M!a'416>L`b \Fns|㫱x/l+߿a /@ip|r;ilRwNj:ն&$XaB!cw4\@ji hw1k.گcFyG68a^;0~:.N_t/4gPX;zz33 >-silAldiv.%)+mɺƍX-7!BXxJl ,YWYʣS 3'_eu``bh LktY@yCMR)8BΛը[՛=|7!BZv;~x[ c{ /} O|#-h*]=w2NCk:-+%+K4v:᧻WnzhyQ~ye\DOQƞh?o~yTWi9TK<([F7|7!BXvblB.Zf, ߏElCk~]xƻH9#xu.SG.(g͠mg^N)&rUNDWKDn݂U)~?:m{'|n\gʌQ]c$kǜJAP}vy"cXF 0WIR4HcCnT묖$(߂+nu}]\yopզXV<<oV@09?^v|t *#"3zE#xv'3+-K:ʎ(׭㰥c7cNG0 ǜoBuhK-R?45;#bt_?Gǰ}ۀ"򭮏xOs؁q\u79|yf::(AnTM0}45#C9!B΢=Xt~y9k#Aԯ-ny2d( X-3^G'$EEG#_@/7s3pW@ebH}'RxMoM)&]e״(fQ+)j8֠x4:v^ΤsHeF/S:秗S%KtI4;+wBa:0~zXrۤ>𨿜R\;= ߣmEqFrz|s:GuA.E)H~I>2*o%sQEDXoB9A2ݢQ#秣_WG>A=A},"_mqB`Gqv/J x 0j . ;ڑoopiVh8@^[}BiaכD.j F9>n_)'h!0igʐ@W^2i"R 3^dWgh3:WU*cNWt/H9&D 0uuI:! Hp!Q01 9o#ϣT1R#aU8:ڑk\Lʹ:Q^;\ GNwuu_ZZQYk!eґ&[V/rSmNDd.f.Ӯ:Wf[Um/Sg\TǁL]t"=c-vuYq6JݲEExCӜW-{3&.&FeMk>Zк - `]ף|٧amx[%9th}UnHiE19!Χ=-0L~oӶ1Vi26m=)@Do>MH nFa<01Ƹ+U_:7+VG_@_ߞim; ~ BH7!$V&$+ǪZdz 8x>3CnTz'ƁoB!4jF8[[:ۿ2!dvN!(?I4~|*|EzѢB!邫B!D 3 ^93O9_WEEL`t̅[`\|oգD4xWG{^[Pik[ӾB>M!q'R0<<r LGqaʍz Zx@T̹l5g'0N}`-{'\=& {9ت7!쑵g9BIJg~/Q9^Ayvt67܄k0 aF`S~s.7_ۆ`=t'̑n XVl`zۿyMYJqE!<|B!D s|.9 ?žMhY0r c b?7~m NuN/;MKMst9ݝB&j!qkB ,, Eh=>4kVo纭Bug s b۵x5u-SPWw:nN_0ܜ}B!3aB!reX"`Ѷ`Vl Y@Ϡtz!ft.F뢅h[vrG؄}3Fs 9!oPݨJf8aL1r0g`⸅s*D=ۂWlƬ`Ӳtpx/cӶ?]im6͜B<|7!B$J f,´"Jg1n~܅Ï^8|gǹ]aJ8)kЏJqLkzzB{ !" R~۪0zv? {d!~DZmjJx!_?B V dci'G[6uه n}qn-fOKԡF|B!D416^¼JirԜRh.#dpWc3_xVoo'y:?3o.~Q4?Ng\T_^Bi4oB!c&F (MO=UBh_t cy,j.w}n7uta;>ǽǏ -tEBH]g !"eY,`!?a- ׂ 2w 1o|]4/ٌe(U9TƋLL~J( Jg !>M!?%hBX@*V?rМ3 5[hkڛZչc|qϿ^(FK<BH]g !"eokRa4c0k}¬I! L ebt0Txl&h8 " M!) N>9qOP?O{cu["EJ)F ʚ(iRa &MpCPAj4C A_PHFaDiT@ AT M{%Ғ%Qelڤۇtw̝?g޹sΙognm{/FĬyo8w)"qG}ٳj>}2zcp c.W47Pɗ?;{w8@"ï}'x}PqŞ'v.m]{{8K=zh7P-I{k"~=o}c]˙돾xnGںʷwT[VV.//D=x[䇏?K>pk?z-3߸GI(n~oYu3#NJgiiοo?<韬g-lV=zk 1l/W潟h3@%K;wDZGQ;ciGw.݈3{?u[@?zոc7M#"}O7v# ד.z}N|@zG.Qs3vz~-Fqo?'~TnOS>9wYgWǬK,׳%sy䭛1)*kw10kl]m&Ui/Wiw>}ql@uK;xs?n?{n]M'}bbq슝1X[[׮x^Z]Ǝ9h?nX_`D, S]vۦhruKbS&)ULt*OqKuH`)v,ly"/c?k;~(n;pW9x <>$n߈[Nxpdɢ$2}u5]cey]]bۊaߟF $w=DHDD"^cK9&T[^*edM@ՖeU̶}zY5.eLfKqyZ>=AV9]b鋲TwT ZLwF~*M&*aku_WAIVOvV\iKoe6w3E3!ƀXt|7{٬oec }?bQZ6% 3y7}72cqX=NmoۜUك7?vzxI6gW}\6Mڳ(e|Q(ѿqq8ꦟM?ݟu꟞ͻXbߨ[<&LKU|%Y Z[b$;m3 ],oKoȻTxuN7u޿eT5e?[fYWE.ۦm rX7U`}̾d~ճuѦYWgڇvs-DhH߫WvDzuTm_]YUwxl~j&cILo٦qh2ƺiYhGSwəo2}w09 sry&Em䙲)ͣe׍m?*53ݳ? t9>O)bg}( g*g9/ AsRuYϐϜEiihg%-$8L5[xݳ}IRƢv֔\ܺ^uԽ#eCJ1u… 3g'?i{]vl1;BR:U'y&3:X7Mw]')sxĻv9V|\w3xuFg,eT2ufc;m_v*qކ˪ƻJ[봭ʛdbC{^WU_23ߒo2u)f*lm=ecU˚LVN2W7un2Ʊn[T1:hkNulвv.Ex|U|g5Ιoh32ge|7{w[湹E5Y%.uۡ_9RK}[TߢgC;9@cG.ZbYO?uݼ6v5N5m ohg%@{:^h4q… 3g'?i{]v42D:M/wޢ>ڨsϫ2ZԯMxOE4m{r3ƤN;]ޢq껠wUO=Q<|tx_9yvFMf?]W޲veۤ2Zgh{5E;,k2_:s|5)'Eۛ[%1;H[ǖ IDATƭjXg+?670xu&N;z/lL5Z ھ?qYuM/u~] jU䀹gTNzIJ̺){x%.Mۖ{"3t 6^$f+g4u u4>'>g3̷M2ښ:uuFvH36w{|M̼9'C7봽=}r E9؇<#;e{}䩾'R9UرS疑UV{'/KDM-λY:nkكT1l&#U9)^TcVejjku»V^}8vԖf-Kq:V˚ԑ"NM϶I Sո*nձRu,eVs) [MmÔ l2뮻gcebN>9JYNW|\J='%tOv|2u~SOKk:!temmm| |@С#[Wz v&m.}1xuC>I'2f8^F~:O/[[Iǝ,Rw8j^RLշq1=oRP{Ӳ{y^.00DZFkq}f.7>3/v7@AѬeM.[?>-zWoVYEmnkAu޳vgm_Q]JL,KmyחUWٶL&W ycN[E1-2Q2mҐ~)+f~f$%ȼeYq٪Izg'ҢYEL籝ގ6꛾j[0em1-oM&e6nF=]vPYP³IyWVWu멺<ɺSN9)or]y&u.b|Wg-i"&rU&;jkb6ʝӼ:싮'2 _{:N_֋ZsOvqpZt_6Ϋ bZ>Ԕ}Uڊ뼶6*ʼ}JSmΆFAeSm$ӗϚlmn,[vtχNN>6N?;)XVW`7@F<̲*gg$.:smjCQ9Em.L)s͔ۨ]7Hzrb:fgO>O=tu}970_Ye&ʛ{V9ye)l{:iXxQlRneU⚺: o1Og}luI\ʎ}k++粮E}Zk'y>1ʘ}o 3ǺPG[ d0С#y+so|0{kkx˙|gFo>9{P;mgӴgmؙ)Z^yٶEڿļ{m7^޴7^޴| yr¨!<:s*(3vfxO ) C3mNWW_[͓3񸳟'I3X=чj+W.es:ug.SVm_VXܺIf^[[fY^e+5Du8hi&Bݱ3U'^3/.;4]Z۴}uǎU$ߒo){>}0~n'XR8s>iFAS lljpV[fa"lձ4صV]?>}2xя~zO=t>}2}97<ۼ=]`HqSNIܶllc=djç:O?:k4K䓿>ؿ>xx%l<8|x9Ν;v~++/=il [q>4_J_HWWWTܸq3~Ywg:y zmcwDlx&ީtzsgqc}ӃNvH@ H@ o@ o؆v5Yx//,W^//>wFC`>%^O6{@ o@ o|o||`H{|@8|x9Ν;+s|+1E1MS70h0]`po?]:Q1|7c< DA|t1|!Ĵco`pID1m-c*$Cb#o%GʕK[OWfY?jҴ )B#xw|=z2^{▤nv]{t41uL%B$]/lѓq [IƬ͊Ƌmxw}滨e;v*^}9u1*g:ǎڴl:f'7kYy\$ >'&/taK/]x u1*3q}u{:iqaxF|_ly3կ~iuD^͟gۊUQ?t MSeYW170K.形^t5ӱKljgK.*wV@q?mWѲL'cUx)6qz]e)bQcL70# %vO?H%%++G 3}X؈i_b*$b#F .(FHL{S7 8yӾT [x䑿*9$^9ȑ*ܹzĴ9r">w}@ ;\"]YOHx9L9!6K%b-ĉ{=ro8|@=ru7VWWE&>{ׅ'>)Qv]bDDܸqS4 /}B?'NWD qs?%IENDB`MP3Diags-1.0.12.079/doc/310_sessions_btn.png0000644000175000001440000000562611202745071017043 0ustar ciobiusersPNG  IHDR2(rLbKGD pHYsII#aGtIME%_` #IDATXõYKl=o~ ?IJ!m˲-GQ,Bq,( @ltdU^YtgpiY%@"(B\0#J&%4")%IP2x {KE`9y4}P(y>|< ("ږejiիW8 @|p8H$i!N#eYPopߦiR`yyY$_,ҥK7(Ǡ w…K/sV妦@QhB~p]w oU_ɍ70Bp.,,|xمh4d2`7w{u}@}' J!DO_:u7oެ~ Brʯggg6??4M5A8y gΜyG` zw?;;V>60d2Fџ̵kזŋ gϞS,?&//ǁmO|z۲,A"R7on YXXxS4MB|zAOR?= im(2/›>H(6MmxӒ^`,˂a/DQ4۶@LEQ8[=4 ~@t]e/!$jZ dY@44 bް%C˶m ˲`6z;F^#J=SOWToӪp뺩H$Vd2fW{Oр(T*ɁXEud2t]q a/4v1::E$Ij` a"Ο?].Ã,u( @$AXDqaY&`ccj0A –eAQ!NÇ{.DQ(j`iψhۇ8`}}<$o0.ydYT VVV+jAF!p @Q t_h`ll L<"mggdY?;OنanRѣGhfZajfa67 ֊(cll E, Yt0 b*߿@ A|݅PUi"J!JAUU3(id2FxQlNj"fffP*@i0 /b^qk4t:> ,p^mqDom0 ?L'&&ŰY,u]o߆ hF^$Inމ{4M ,(Jh6d2G Zq@ Zqi躎fZ;wȑ#0Moѫ.]199鑊00]׉sss( >0`&!mjaooϯ#1EQ݅m i$ p>,t]2<Fh4MuacggFZ DQ xYUh0@QLq3ϠX,B4_ #(I'Ot:{."4.,󠷙2 &EQj1;;x<UUCQqB!470h4T*H"O?E:fggaY8C\ M ˲{s}! `&8C@XD\$IyHDFI;v kkkvEяm躎Qp'N 兕{ ޞllBQZSN^'#t4g{<߿za|KeY>QT*I]v]׿=>G\. 'qP*055-TUhز'$ANambwwT ssse+++E`v{y` wy=H܎X]]E(177fb-MK{}7m>D(e ""Na?XJ>rð, @,u]Z-4MTU4 (P(qbxʕ+tCpnݺEy2d<چB!a I MP3 Diags - Config - Colors
MP3 Diags
Here you can adjust the background color for each note category, by clicking on the corresponding rectangle. Use "Custom colors" to easily set the same color to several categories.
MP3Diags-1.0.12.079/doc/015_changelog.html0000644000175000001440000005172412040502152016433 0ustar ciobiusers MP3 Diags - Changelog
MP3 Diags
Change log:
---------------------------------------------------------------------------

20.10.2012 - 1.0.12.079
- Discogs fix

---------------------------------------------------------------------------

11.05.2012 - 1.0.11.076
- made program compilable with GCC 4.7

---------------------------------------------------------------------------

31.12.2011 - 1.0.10.065
- updated Discogs API calls to current version

---------------------------------------------------------------------------

10.09.2011 - 1.0.09.063
- made Discogs queries work again, after a Discogs API change
- added close button for windows on Gnome 3

---------------------------------------------------------------------------

28.05.2011 - 1.0.08.053
- fixed crash when trying to save after error at startup
- added branch support to build process

---------------------------------------------------------------------------

29.12.2010 - 1.0.07.052
- fixed crash in folder filter dialog
- made project compilable on Fedora 13 and 14

---------------------------------------------------------------------------

04.07.2010 - 1.0.06.051
- fixed crash caused by invalid Lyrics tag
- fixed assertion failure when opening the folder filter in Windows

---------------------------------------------------------------------------

17.03.2010 - 1.0.05.050
- fixed issue #23 (assertion failure)

---------------------------------------------------------------------------

07.03.2010 - 1.0.04.049
- fixed crash triggered by invalid frame lengths in ID3V2
- fixed crash that occured when the backup directory couldn't be created

---------------------------------------------------------------------------

29.01.2010 - 1.0.03.048
- fixed crash triggered by GEOB frames containing UTF-16 text

---------------------------------------------------------------------------

12.01.2010 - 1.0.02.047
- fixed crash triggered by trying to repair broken ID3V2 tags that contain
    images
- fixed crash that occurred when changing file names manually in the file
    renamer, without defining a pattern
- fixed crash caused by unsynchronized ID3V2.4.0 frames that end with 0xff

---------------------------------------------------------------------------

11.12.2009 - 1.0.01.046
- fixed crash that occurred when running on Qt 4.6
- fixed crash that occurred when changing song info in the tag editor if
    songs had images stored as BMP or anything else besides JPG or PNG

---------------------------------------------------------------------------

29.11.2009 - 1.0.00.045
- wording changes to reflect non-beta status
- pressing CTRL+C when viewing full-size images in the tag editor or in
    "Tag details" in the main window copies the image to the clipboard
- added "Rating" and changed field order in "Tag details" to match the Tag
    editor

---------------------------------------------------------------------------

04.11.2009 - 0.99.06.044

- fixed a crash in folder filter
- fixed bug causing non-normalized files having any TXXX frame to appear
    normalized
- case is ignored for file extension, so .Mp3 or .mP3 files are recognized
- better support and more consistent handling for TXXX and text frames in
    ID3V2
- reduced number of locales by eliminating redundant ones
- disabled CTRL+A selection in the main window
- static link for serialization
- added trace details for web downloads

---------------------------------------------------------------------------

27.10.2009 - 0.99.06.043

- "Simple view" in file configuration
- fixed crash on empty text frames in ID3V2
- generic binaries for Linux
- BuildMp3Diags.hta detects VS version
- documentation updates

---------------------------------------------------------------------------

20.10.2009 - 0.99.06.042

- better support for binary frames in ID2V2.4.0
- fixed bug resulting in crash when files were modified in external tools
- fixed bug resulting in crash when renaming files if a filter is applied
- fixed bug resulting in crash when going to "Tag details" for files using
    Unicode in USLT (issue 40)
- added option to include styles in Discogs info
- added case-change option to the tag editor
- better detection and notification for changed files before applying
    transformations or saving from the tag editor
- file renamer allows file names to be changed manually
- file renamer can use "duplicate" label for unrated songs
- images shown for Lyrics tags
- improved case-change transformation
- removing images from the tag editor now works even for non-cover images

---------------------------------------------------------------------------

09.10.2009 - 0.99.06.041

- brought documentation up to date
- added test for ReplayGain info stored inside Id3V2
- failing to read text frames from files no longer causes crashes
- fixed bug resulting in crash when 2 ID3V2 tags are present and
    "Discard invalid ID3V2 data" gets called
- XML export now works when names contain double quotes
- locale in export dialog
- locale lists are now sorted
- long text frames are now truncated when shown in the "File info" area
- changed names and order for tabs under Config/Files
- made transformation options work correctly in MSVC

---------------------------------------------------------------------------

30.09.2009 - 0.99.06.040

- "Various Artists" support
- all pictures are shown and can be viewed in full size in "Tag details"
- all pictures from a file are shown in the tag editor
- patterns in the tag editor may now be disabled
- export as M3U or XML
- better handling of text frames containing null characters
- auto-size for the tag editor's "current file" area
- better column widths in the tag editor
- improved HTA for Windows build

---------------------------------------------------------------------------

23.09.2009 - 0.99.05.038
- fixed bug introduced in 0.99.05.037 causing crashes when finding empty
    ID3V2 frames
- new build process for Windows
- 4th custom transf list now defaults to a "fix-all" approach

---------------------------------------------------------------------------

17.09.2009 - 0.99.05.037
- fixes on right-click
- UTF-8 strings recognized in ID3V2.3.0
- fixed bug 35 (assertion failure)
- faster tracer
- code compilable with VS 2008 (port by Sebastian Schuberth)

---------------------------------------------------------------------------

07.09.2009 - 0.99.05.034
- drive labels shown in Windows
- mp3gain can be started now if it's in a directory containing spaces
- configurable invalid characters and replacement for file renamer
- automatic check for new versions
- text inside square, curly, and angle brackets removed from web queries
- improved tracing code
- no longer rescan the files if exiting tag editor without changes
- replace non-alphanumeric chars with spaces in web queries (issue 2)
- better sorting in the tag editor for albums with unusual track numbers
- a default .ini name is generated in most cases
- (probably) fixed an assert (not sure because couldn't reproduce it)
- tracks without a track number are put at the end in the tag editor
- let the user know about reporting support notes and about patterns
- better detection of exceptions in threads
- exceptions that propagate from slots are now caught
- default "actions to be taken" no longer shown when applying transforms
- file info for StreamWriter

---------------------------------------------------------------------------

02.09.2009 - 0.99.05.033
- fixed crash in Windows when checking a whole drive
- fixed crash when saving data from the tag editor
- improved trace speed on Windows
- fixed potential crash at startup
- fixed crash when changing a file that is being used by other program
- more details and better formatting in assert messages and trace files
- MPEG2 Layer3 streams no longer show Support note
- improved temporary file generation, which can result in faster transforms
- F1 help now works for the first session dialog
- smaller TABs in the "Tag details" area make "Other info" more readable
- better HTML paragraph formatting

---------------------------------------------------------------------------

23.08.2009 - 0.99.05.032
- new Qt (4.5.2) and MinGW (3.4.5) for the Windows version
- restructured crash detector
- fixed Windows issue with rectangles being shown instead of letters
- Lyrics partial support
- warning that may corrupt data
- note about how to change selected files
- HTML clean up

---------------------------------------------------------------------------

18.08.2009 - 0.99.05.031
- crash detection
- fixed small memory leak in config dialog
- fixed small memory leak in the tag editor
- content is shown for GEOB frames
- .ID3 files are now loaded in addition to .MP3
- made the counter shown when applying transforms increment on new file
    (until now it was incremented for each transform)
- "Various artists" no longer set as "artist" when downloading track
    info from MusicBrainz
- fixed "current cell" in the tag editor (until now, when dragging the
    mouse to select several cells, the current cell was wrong, leading to
    setting values incorrectly
- fixed a bug that didn't allow removal of the track number
- slightly improved the normalizer, so a "busy" cursor is shown when the
    connection to the underlying process is lost (the program seems frozen,
    but it resumes after about 30 seconds)

---------------------------------------------------------------------------

28.07.2009 - 0.99.05.030
- fixed a bug that caused the tag editor to reserve more space than needed
    even if the "fast save" option was turned off
- fixed a bug that prevented removal of elements from lists
- fixed a bug in the ID3V2 tag writer that prevented "Discard invalid ID3V2
    data" and other transformations to properly work with ID3V2.4.0 tags
    that contain UTF8-encoded strings, resulting in a broken ID3V2.3.0 tag
- file renamer now accepts patterns with no directory separators, in which
    case the renamed files are placed in the source directory
- pattern dialogs now show the current line and column
- fixed an assertion in the code that determines the file list
- added tooltips for all the notes in the main file table
- improved speed for "Discard invalid ID3V2 data" when no changes are done
- transformation name included in the dialog that shows which file is
    currently processed
- broken ID3V2 streams get removed when saving from the tag editor
- the tag editor no longer triggers an assertion failure if non-default
    settings in the file section of the configuration dialog; (e.g. until
    now saving from the tag editor while original files weren't deleted
    resulted in this assertion failure)
- fixed a bug in the "Change case for ID3V2 text frames" that resulted in
    a program crash if some fields were missing from the ID3V2 tag

---------------------------------------------------------------------------

26.07.2009 - 0.99.05.029
- improved paste in tag editor (it is possible to paste to multiple cells
    or to paste file names copied from file browsers)
- configurable max image size
- button to remove image files
- fixed loading images from current dir
- fixed a bug in tag editor patterns that prevented patterns ending with a
    static text from working
- Windows only: fixed pasting image file that was copied from Windows
    Explorer

---------------------------------------------------------------------------

23.07.2009 - 0.99.05.028
- fast save in the tag editor

---------------------------------------------------------------------------

21.07.2009 - 0.99.04.027
- file renamer can work with the list of visible files instead of the
    current album if the user holds CTRL down when pressing the button
- new transform for keeping a single image, as front cover
- new transform for removing ID3V1
- configurable visible transformations
- tooltips for the transformations menu
- use of backslash for path separator on Windows
- fixed some bugs in the directory filter
- made F1 work on Windows
- fixed normalization status on Windows
- directory filter no longer shows some directories that don't make sense
- more checks + fixed error reporting in file renamer
- "sessions" button visible by default for second and later sessions

---------------------------------------------------------------------------

17.07.2009 - 0.99.04.026
- size grip on most dialogs
- F1 help

---------------------------------------------------------------------------

15.07.2009 - 0.99.03.025
- restructured Unicode stream classes
- Lyrics inside ID3V2 are now shown

---------------------------------------------------------------------------

15.07.2009 - 0.99.03.024
- switched to fstream_utf8

---------------------------------------------------------------------------

13.07.2009 - 0.99.03.023
- tag editor now looks at filter
- files changed in the tag editor no longer show up in the main window if
    a filter is applied and they don't match the filter
- better alignment for text in note column header on Ubuntu
- replaced C / POSIX calls with Qt calls

---------------------------------------------------------------------------

09.07.2009 - 0.99.03.022
- configurable colors

---------------------------------------------------------------------------

09.07.2009 - 0.99.03.021
- 2-letter labels
- gradient grouping of notes
- more consistent font handling
- detecting files changed by external tools
- tooltips are shown for the column headers in the file table

---------------------------------------------------------------------------

05.07.2009 - 0.99.02.020
- added sysinfo to "about" dialog
- more details in sysinfo
- made file renamer work on Windows
- file renamer now replaces invalid characters in file names
- made logger work on Windows 7 (and probably Vista)

---------------------------------------------------------------------------

29.06.2009 - 0.99.02.019
- downloaded images are no longer lost when saving in the tag editor
- duration is now shown for audio streams
- fixed assertion caused by files with too many streams
- assertion instructs reports to be made on forum instead of email
- number of files that might get changed is shown before processing
    multiple files
- assert message includes more info about the OS
- multiple ID3 stream remover no longer included by default in second list
- some changes to .spec file in the hope it will work on Mandriva

---------------------------------------------------------------------------

24.06.2009 - 0.99.02.018
- made -mt suffix default for Boost Serialization

---------------------------------------------------------------------------

24.06.2009 - 0.99.02.017
- always use multithreaded libraries
- improved assert dialog; now it has more data, which can be copied and
    even emailed directly
- the tag editor shows a warning in some cases when a user action would
    result in discarded images

---------------------------------------------------------------------------

21.06.2009 - 0.99.02.016
- fixed an assertion failure that was triggered by an unsupported text
    encoding in APIC
- added support for UTF8 text encoding in APIC
- made the documentation look slightly better on IE6

---------------------------------------------------------------------------

20.06.2009 - 0.99.02.015
- made compilable on Fedora 11 and added Fedora 11 build
- copying missing ID3V1 fields to ID3V2 no longer part of the default
    custom transformation list 2

---------------------------------------------------------------------------

18.06.2009 - 0.99.02.014
- the tag editor loads albums much faster than before; this is most visible
    when navigating to the next / previous album

---------------------------------------------------------------------------

16.06.2009 - 0.99.02.013
- Windows-only: new Boost Serialization library, compiled with
    multithreading support
- Windows-only: new install script, so now the setup has a more modern look
    and allows the user to run the program when the install completes

---------------------------------------------------------------------------

14.06.2009 - 0.99.02.012
- added support for UTF8 in ID3V240
- added maximize button to most windows in Windows (but could not get this
    to work with Gnome)
- removed "What's this" button from most windows
- now the main window shows the session name if more than 1 session was
    defined
- now the main window shows up maximized in Gnome and Windows if it was
    maximized when it was closed
- changed documentation links to point to new site, at SourceForge
- minor documentation improvements

---------------------------------------------------------------------------

06.06.2009 - 0.99.02.011
- added dependency to guarantee that SVG icons can be displayed on non-KDE
    desktops
- fixed an assertion in "Sessions / Save as"
- doc comment changes to prepare for moving to SourceForge

---------------------------------------------------------------------------

04.06.2009 - 0.99.02.010
- fixed a bug that could result in removal of audio data when using the
    "Remove inner non-audio" transformation
- first Windows version
- fixed incorrect handling of the option to keep a single image in an
    ID3V2 tag

---------------------------------------------------------------------------

03.06.2009 - 0.99.01.009
- added scripts for Ubuntu builds
- made compilable on Windows
- added some Windows-specific icons, to replace those that are displayed
    incorrectly
- improved ColumnResizer
- switched text in SVGs to "path", to avoid issues related to missing fonts
- fixed Config / Files so it's no longer possible to only to uncheck all
    radio buttons
- better handling of light background colors in the Notes table
- fixed a bug that could result in erased files when the disk becomes full
- change header / footer layout in the documentation

---------------------------------------------------------------------------

25.05.2009 - 0.99.0.008
- increased cell width for notes, to look OK with more fonts
- added an #include so gcc 4.4 can compile the project
- now using black instead of "selection" color for notes if the contrast
    with the background is too low
- improved the workaround that is needed for multiline text, so now it can
    handle all fonts (previously a message used to show up telling the user
    to change the font)
- added horizontal scrollbar to directory trees
- install.sh now exits errors

---------------------------------------------------------------------------

22.05.2009 - 0.99.0.007
- first public version; most of the 1.0 features implemented and functional
    (what's left is an option to write ID3V2 tags "in place", to be used if
    the tag editor seems too slow; this may lead to data loss in cases of
    program / computer crash)
MP3Diags-1.0.12.079/doc/035_suggested_usage.html0000644000175000001440000002444512040502152017664 0ustar ciobiusers MP3 Diags - Suggested usage
MP3 Diags
First of all you should get familiar with the program, especially if you intend to make any changes to your MP3 files. (MP3 Diags can be useful even if you don't, but would rather change them with some other tool, because you can see all sorts of details about your files.)
MP3 Diags is not meant for daily use, but rather for cleaning up large, rather static, collections. Sure, you can use it on a daily basis, but some parts of the functionality might not be best suited for such use.
MP3 Diags is supposed to be the only tool that makes changes to MP3 files. It does everything I need. Now, it obviously doesn't do everything everybody else needs, so using several tools in parallel might be required (though I would suggest making sure that that's the case; MP3 Diags can do many things, although it may not be immediately obvious how.) However, there may be some issues when using other tools, especially if both programs are running at the same time or if both are configured to not alter a file's "changed time" / "mtime" as they change it.
To familiarize yourself with the program:
  • create temporary copies of some of your files to try various changes on them without any fear of data loss
  • read the documentation
  • go to the configuration dialog and see what settings you might want to change
  • when using the program remember that you can press F1 to open the documentation page corresponding to the current window
  • right-click on the circles corresponding to notes or on the corresponding column headers to see what fixes might be available, then apply those fixes to see what happens; remember, though, that sometimes a note is just a side-effect of another note, and fixing that other note is what should really be done; also, sometimes it is possible to make a note go away by applying some transformation even though that transformation isn't listed when you right-click
  • enable the creation of temporary and comparison files in "Configuration dialog / Files / Temporary files", then run custom transformation lists and examine those files; (note that comparison files are generated only for a handful of transformations that change the audio, so in many cases they won't get created)
  • export the file list as XML or TXT before and after applying transformations and compare those files to see what changes were made
  • apply filters by various notes and export the file list as M3U, then open the M3U in your favorite player and see if the issues reported by MP3 Diags seem to matter in that player; perhaps also try some other player
Once you think you know enough about the program, you may want to start processing your collection, AFTER creating a backup (well, or at least set up MP3 Diags to create backups when changing a file.)
Here's what I do to process files in my collection:
  1. I create a full backup on another drive; the built-in backup only copies files that are about to be changed, but I'd rather have everything in one place
  2. I have several sessions, for various tests; however, one is enough for "real" files, so I open it
  3. I do the processing in batches of several thousand files at a time, so when I want to start a new batch I have to change the directories; this is mostly to give me some incentive to do tests on real files from time to time, to make sure that nothing too serious is broken as I release new versions; another reason to limit these to several thousand files at a time is that it's just fewer files to rescan if the program crashes
  4. I look at the "All notes" note list and if I see anything unusual I apply a filter by those notes to take a closer look at the files having them, then perhaps apply some transformations
  5. I run the first custom transformation list; (even if the list has several elements, suggesting that plenty of changes would be done to every single file, most of the time nothing gets changed, because transformations only change a file if it makes sense)
  6. I look again at the "All notes" note list
  7. I run the second custom transformation list
  8. I look again at the "All notes" note list
  9. I make sure that the "Use fast save in the tag editor" option is enabled, then I run "Reserve space in ID3V2 for fast tag editing"
  10. I go to the tag editor and get the tags right; this is the most time-consuming operation; I usually do a combination consisting of a track list taken from some place and album cover taken from another; opening the tag editor now makes sure that data in all the tags is available, including the second or third copy of ID3 V1 or V2 tags (which would be removed by the third custom transformation list)
  11. I run the third custom transformation list
  12. now very few notes remain, and even if they are there for valid reasons, I usually choose to ignore them
  13. sometimes I do an in-place file renaming
  14. if I'm sure that I'm done with the tag editor, I run "Remove extra space from ID3V2"
Some may be reluctant to use transformation lists on whole collections, and would rather look closely at each and every note and decide what to do. I feel that giving each note an individual treatment stops working if you have several hundred files or more. It's just too time consuming. Therefore I recommend making a backup and actually use the lists, perhaps after tweaking them. Then if something got messed up you can restore the original file from the backup, but that shouldn't be needed. I don't need it, and if you find yourself needing it you should probably file a bug report, so MP3 Diags is improved and you no longer need it as well.
Non-default settings that I use:
  • Transformation params - Keep original modification time when changing a file - enabled
  • Transformation params - Keep a single image for a file - enabled
  • Colors - different background for ID3V2-related notes: ID3V2, APIC, ID3V2.3.0, ID3V2.4.0
  • Others - Use "fast save" in the tag editor - enabled
  • Others - If a field's value is different from that in the ID3V2 tag when exiting an album - Discard
  • Others - Show "Export" button, Show "Debug" button, Show "Sessions" button - enabled
  • In the Debug dialog: Log transformations - enabled, so I can get a list with all the changes that were applied to a file
MP3Diags-1.0.12.079/doc/screenshot2.png0000644000175000001440000025343411304161450016204 0ustar ciobiusersPNG  IHDRѷRXbKGD pHYsȥtIME -0tEXtCommentCreated with The GIMPd%n IDATxwx?{UҝzeMraWz(CIh$Z-_(jcL1ƖlY-[8$dIly-3ww$tB@ @ ]32t$P^^ʚ˩`0@  QZZNvvon1ݛq]H ֺKDLL 5P v4M\IC)*,0- F UU TUUR%7w>#F1clټm[d2^~@  ;|{/;b^Gݟ{`71:x*աy I(f3F Krj\n`\6o(*Iw` A|I 7&RYYA\}}{89pf@ ~bˎ;=;w./oUfݺ4h= ֵ>2{ʔX,q~-- mRZ'接5p"m|~3NTEAQב8l2sYx!W}ϸཷu0 *@ Iӳn*-/3\Pr΅\0CR6Bg%^rK0z0vf/*vQ߸qkoMg1[_~I*Ǯf{ȮeUͦbw9ٽBn}Ӧ>d$&%SYQ[D@ @Ek-:~^{Nպ--ֵdG \J|=N%ޜ#Lxc?fST1^SSנW7-- ͥ>7n o] !ۉ(1afs{E41Å@ @EjΰaYM>vrPi:Ҏ@:T@ή]TUմڎ6 ( VYm]Bp:d3dȀ1͈]S?R왉bjW7$SSƍ^3ΘHmZA ԠisK ! -y\@X UQmLMM99}oP>ii kd:y5nLjh ˆ+,O~^^~_RSSE||"Yz%"SYYAB @ ]H7Fzztut>}_}Co6IOO%>։bd~ /~[[_I^s ȞH!9>1!٘1呂yap{bEbRF?$/w7G&+7,h@ A-{g¿sr  _>؎Ppu'_]#ۼ> lݡ`hb%f6?2=R \ gee=$#IOO=t}.entQ{ިC.Gʦq#G[8'8!C;fı3<|n#i͹j5/IFAhT ۗ&A3f8>CdYFQdqW@  4=V!-]PǐԨ1dg[Z1^/:'J|l4b1''m1s0yy{ذa]:8|PDZ0B%8F6&R5zaߜ0mr5god>!Aný99}CYY`-PYE+أ"Zю%rƍo2 ݈V-uJFLSOH$!>ظ8%PQQڵ+),(h4_ @ 8UD,!zh,oIvoV/44yf 55 ٌdDuL[&SP{Ŏ6kQQ}NxSi9m[mۜ-;q⩬\4 6zۑv,[k꼎Gs A#I2eF$ EQ0!@ L짤$ed`cvD싓XfƎn6Vs<'=@ ~b=W/;"zl͖9r(n@ @ h-jb9:g}ԥ=ǙlSFF/: <wz{졲wJssaĈ^YY.REQիvU?~ߧ{ w(FTȗ ,c}\?$ ]ww])&b?fig޽Έ#Tޣ5$DC*({M E}/&itb^1!a1*}* 8Pͥ=A0%It>\Ybꏅ R .#9TcsaY,~s&'Ȓ(.*V+cǎ_PPi}O>s.d2yVfGdbj|/O_|7|ܹs2dqW_eٲeYS'6lX~~~!UU5Pf>0a„q(h46qCjj,m[Ϫi3;a;5cW3-g ZFa /|yHtߎAMON䭿Fs2;1ƥPOL:{﹗ 6~ڵ2tb0M(Xn5w}[Dx!P~HL:]ٿ?۷oG$zl@m<a]A`f@Bڄ{'}h֤Zl) nf|3яb6P^6f%-Ļ_W3RF UxUZ;X̦{YIW9s.^~+1?rETWWsE#f͚upyd??;y'_r%/cƌ9nbi6lELLLo9묳P%h믿СCɡ7q"k9?,kN;Wb4U}Ϯ׋|MgrѹI(ؚLg oVM’x|/_|og?v3e:,x=3u<Gݻ 66ٌlp=PUUc_uJYvoL^~Y}EQ•,pHXF jc'phwy:Rl>\s~$910ed秿:6_vRT%x=\9k3gf0.p9 ľ@ *eAX2zpϭi,b=~|=xLjdWGul8}wǜ$I|;cݺ ,Zͻ˔QII) ~$ }.!>ᄏ} =)Ō5 $IǸ8ztFСCX,X,pZR6l¬Yg?oMdS2TuX+|gCz lϤqu0(2 [x0{K~~>qv;FíëLƘ@gdL:c\~Pz{KK.cH.[\^U) Oquh~k׮'?@AӧO/ƍan.7.O]c蟝`ݮrnӟ?]o_.F/a˥lݶUyJVV7~s˯RVrA&jYa>cZmKYY9>]v1]| Xr .ф5$JQdNŹ=[nHZ_/cw5I-[4111t:[ճlٲ MӰX, >X4 QsdX7yٱu%xdƻbɨ_lg=Y{7UR8 ?3 ic}FF:~ ㉳䓏뮻ګ<ÇK4h(TnW ϋQ#{eYBE-UGW4 tP6VU#Ӈא5Ţk ac!Ns64$*ԮB}ł%tX~!?u q7βe_tx=\^_xYbzv6_?{a`V(.j̈́ Q#_|?,0씳2j̦Xkc1ǒw 7t7f*,f]ݗ 6J=|f={cۙ硇K0ΐEaǎjzj [7+/0_j f0HDSh￧d~4cXoIuu(J|V23 7"FqqIMM ɀQ6aduw-m 6:E¯ؼq)^92הH<{&ONgTz1eni|',:jbD'}cq->\ʲe7XCԧ`_iVǀou3ef?O܍֐lM }lr/OGrjv/:5M%%pY9\žddeJ IDAT#)ھ?nݻIOKA$~\-zA5xHLLQ[Gee%E O3_Qᠺ}{iUGff)r5?vޝ4M#11Aodz͵55м]@]I~C稡n.Ӆ٪#ᯭ/0Y'(DZ ۀ1KCI=t_?+lE>8Uǭ׌G[xei>x {px}3%ɓ޳wχyow\E( QWW\"=aCտ HL8uϗ1D h #Bb_4nv~?Ӊ$4ɣq/i?C/$s^]qWI( JlTC'J7f :v#a$Qg஻c쭤d ;aunO~TS9b$."Oj0u6oYy/_>\Bm#bD|YMyypxJJ2 ?s\|\2҆m8}{f/}V G]-aQ9$%i#.ݯlY}w{*㒁d߯p5כ%$wľ``\&La|'aVXEIIik)--2#,6lȤoߵ$7w.W5iiyGmr>|ɺ,]M>R7xhhߑ4W/"g%_w<ĕ%k:KRϨ(T.e}dI&J ۟?_-~eE80IHθ!e$l$/x2SNbuɆIB$$IGd:j[?`h6Mdi(RËF3b=2ּc[GOg&'Z=>ؒ=IG~t,yZmUm:F6)c:Y3Pd4M%{}3C]IˆO;+Rby~~6ڸ~fw曟?y1,L؏Y0xVȿkάY]+̲e 6X(cIL v{Xtqyg7=fSkݷCfpЏShS3]W?5g3/qyUl8EzPT¯j 3=XLmv³[n?l_G># M7U:TWqp)ݺw[crrC4>x!uǭxFMz!l[Y˾frGmm^͍7Z+3<_InNYY^ziX`Ax(;G/-}=~KVwB lge\un -yݕEp>:Z35Mb |y]z/bm ~{pP9RQ)t5dX r=S1GW\5k;vh..I=^>|>~m*++!G&l߾ZΝ6f*.\ؠgqhА4Aٖ ؄n63,Wnaɶ]ԖQ{9i47fD,s3y/xSaG+nѸH>oI$Yd>vA'aӫջj蠁hZMS4YO:{wW٫s5:8z xΟ o|Sqءh.Ih4 ]UQ{~R&b_k.hF#Mws}z|y<>/'cŰin=uy4HWcxE"~Cs1axzj>+/K1y5l*Yiٛ~}Ƅg E$`[~5Nq1E!tgԍҁV^} Όs/C!ru-hˌF?uuxkkq8(++b1$sGdwobdz_3ό[a2\pAOJKݤ['hlT1Աי CLϽgpԠVb U)L\ٟ+*x2nQuEb@Ql0Y @S1ΨQ1M̛w7OqF&.Όmdg琞?}{5f$,J A5ظq]]W7][BW%cP# !s!u$%(cHbKgk;S2[R)Ɇ!a%NKII2s`}q@d2'ȪPґeIsh%`woRT5j@ @"ʋO|vlD: g܃e$` (C>)+䲄,-Mzno4)'9j.s5JYg NgŊ<6nOWØ1AWtu/'===3۲e+q`P)SF7۫xy䑿pYSn>W/ǘ8rΝu+׽A&v;8ppCN9+pu3檳z:.f5땳ygY!?%Lk񧫆pc 4ػ7}>ͷ. MҲ?/`̘݋ طo?7ocȖD{C~}v1HJJwsp{'MJ3ͼi(JO[778pł#?7o˖-7>nf.6cDG_#E֜Ώy/3g{9 8U7矷}H?SO=Ō3x7$r.bv.]v1zN>j}U!w Fⴛ`J6 k~(>< ɂ@Q8Ö}z #= !>_[ֹ0nA\wn^z ׋ۭa6{''g TVV2n8^y5N=4.B (((rs@ee;QSqt]'%%޽{"4Wi"UݻwZ5=@ؗ@%, j ~_cЅ ŋ?vyD H?IRvb`1}i~VXbέG{ZMx~ Wt ]e a,Rq_GQC@phv5Dk:IsTh-Ѧ+-ݣv,#˰5;Z뱺%FҞHwc-Ӷ\ѦlnǏb1h() RYI<p}ւ.^B_TTUl1pT)Z~,, Nj>L2+c׭UWMaȐ`tZ2;vֲ~}F`„Sq=|w,Z]II3c@\jj|',X)uu. $E͠w~uy|}>d`nT0q f>wYʕ>\=1?ӦM$11fQ}ߌyQZ*-'!>Y_9=1bظy!q)+/$g >HL'@J|qdΔfn>?˧fҢ< K]d`6zA?^})=(q=ℊ}׋dVc8u|7,^1$q>S/>:x0t`VTknvxoكS'wxZeNxر)եȲŜsNhi" /$hd5"=,ZÇ3m4vyڮKYj'NW__JBBB'}[ș|xЭAR-^@ _#z Ŀ :; ),*B׍Ę<]!CkL0!tpPWWn!'gӧ)/ƟK/DRRRJ-h-m 뮻Z%\n0c1! itYB1ŠĠju(5T,zue ~%&n#/ױ[!P[NDjZ(p_ްwI1<;MSW] Hh((J98v_#8~AOk&ހ@@'U~18~Os""-bm獏ch\ڼSuzzn[-(F;bّyD;:yj*.LJ&a0H(:(k(i/z%UCӏxCOUU9 SƧwp8գǑy|wA60p`OVǧnh1>`?^`AdF`"{nX_̬c>n2ۘ{\5۶՛O>ϕk2r ƍ_2f?ڲ ljn ykppT4huI$IѱjNJBR!zWd 4lhT*NWLe[(K8]&!7{Ѓ hT?%to !ѐMTkWuNB*]SͻM21,6뫽so*.(HR~Ȁ$Rp*z ZQ7YpRYϋ{<n/8~LGZN]UUÁ~'c`ՋdY qP)Z|iM>odcЋOm)4<5_uNwgi1\|=6uUԔ3cV$sm7sɥsxwٲe+g'''7r0 \&D. NE*YDVVVߚ٤09ytќ~KD|5tUG4Uts"]еup`\;׏A 5@/IH m֏හL|_ƩvzYz74]QXjº1?Nǣtv9tzxO f#66ł9I^ݠ~Ϗ&|}^dYZV#!:h'~KXֺyuja8AQ$%Lmpnyuy?)(i>N'{9l昰 tzۃ/X]c|.\߯ߠn9d% ޺kΟ};v{*_~}Ɛ|l?}L3jgpY W24$ˋ򗫇b6ʤě?0 kcļ"p3fTٶ`'wMFNvvZVݻwkc=EQ$zh$W\IҘB. ]P EQQeIX}rZ c:7%x<^~ M+Cuu558/^)7xn[n(gWCj|աv{|N3f ӫ?^cy2bP\/LX-vqo%=[ç3ZG9&g㣪>wfMVNH$K@V punZXj}}J] hQPQѢlH–ad2˽3wf}?$3s<9Y#'3E9ͨm o,Z͘PE9ڃ8t ϼ ^|&>T ф3Ԕ3m,[@kHv;Ə=rTヌݮ%''K/믿 IᮻĉhmmS%~6n(ӓ#{omۆZ/ 6!C`ѢE; .o~TUUĉ$ r tasO-Z;/6nI`Xp}E4[jv"ͳX\+)ȼ@}}Z"L],x*/JWf|13X7w`ge-_0 # 0ncwVkM| ]1Ps6_>1b8oM#\z qxut됝w+ )G|%~粲fsꫨ]7鞄q^yEox>bn׊GQ_M8jtT;Yf];:ݧ;=H@kC 8~ xHII‘#4q ~TДtcی>*Y픫V{L9 rk[M1kfdmwJcH,/h"=,"!xg׾J$DkZj$X ',0H6 0mbt80 0D 3EQt5I!JټOFmJ6 5L%慒V04~N=j[j2S+HMD)G죫p::~a pS״$ML-n sjts[+3LNp]si믯ҥp-7Cjj`6a0n}3Onehm`@rr2Z[-~#?FFƛxύ4i(f͚&+ hkkk >n4hnkva֌0^:9=@B{G+&1G'ӾĤa=pՆxI$XlfwwT4'܈҃O۔yBSS3*+rN1`@?L499٪g@G}ү08t06n܂I7{l8JJJ| *WMŠHe= G.cjd\==ptVP?}@N$iv |=pX['цҟÜDd xkU±3#^s:x86,LFך|Q\;r]&I&RR$UZSQ8pzJ4߼Bt"t8;~h`hh`2`4Op2opS6RS :WϚf@k{3mz}zYISt}*8hոqG4"))sCC3ر8㌱HMMEff6 ƶ+xw=p]AF;#@uu5:zT6 6l-;_s'%ai~~c?bp:oֿ k+\a\DoO,6'M62VYW+SNXǏPԴ p#!LpJ[Oȡ۝;mv'lnn0rt1{X[)S ID{5  ͆vXښ`0Dy蛚{}Z N:F!pEvG[tVVv?aB=NÿO&qihkBEqֶtbŊOpd3z.h-VA[ֶgހb|qwNKij'O6k»nG]]B,YvI9\.g谴b~5%x]י}P\}F/7v"d-#׍܎0סy虝i7D̙s>O? 'n(?cU1L}ϛ7& +W?Fyy9>NF Yh6ӓEIZB7܃$;?|=:l^߷fs6֬Y[6"͜d3p7oᦛEk}$F s"'d1q! {bVdO{GvM<ȑ#OD Fkл{ν lAiUECa@Ld Q-{`_Xv#aERS+)o6`⤉0jh+O,Kêҝ4i8u.TftnXڟ7 FDcLII0\IN$KNtKg2&$Q9X ,Éfk'}݆#z8kGSk%H"MNMo1Xqh9.w^w 1]ܳ8ze|.@AA/̝;eeMhm] hk!##1o^UWz;o6ƎQ[[l0LZ7p%\tt`c? TW^ m4kömGpg(,܅VLFٰfwocϑ5"6| Ihνkї+ -tYpHy):0n>_l=_\?w+dŅ D>Ղ((/߃#^-[.~{ޛٳkֆ>W\qKyw'qc)X:mkaa!;ft"==2Ul6G?v#N<T9~ SX,XV<لVj ΁0g>o߾.<#]?쳝r}Æ Cyyy{F8s = |-RѺc/dcȘ@Ntwho ٵ={Ŋ˱sN_Uh]w6lW\q1RYw/~-_.Ŵ:Iv c1aHV1s &iv=nMյl܊oJW* pF 1ew`@jol+WgM#N,11Q73c/Fۘb욞tnwn&$ ((bx 薙gc.x?} &ԨٸstN`8V;s0at~p>tp֬ 4([߫Wnm~5ضlN7OÔ)1|P47K߿d%ĵ^~طo;F 7|3njTWCS۶UdJ嗟S@cc-~)mFMM#jja2YaGR 6 5~DW =-uZdM3|bpsmv'~r)jpHWf|WػwߩQ}횽{+bpY3Ы:ر 5KW^ի-{v1~۫d^xIXh::X*!{7v܉<"qcʔ)]:SY4X,X,9ԂB ߷/233`mmBjjRչ(B,ZgݎTowD Ly߾}/ kÁհ;0s.v1;; vUxЫg9 IR{ XdW }nVdO}IѶؘ"%_k0n@$ktVp F.@u[U|_ɓ OlW:ct>x`Cxz DVݕN Qb! A`0`2]=NI:kt`0<ف攘Œ#)IƏ qqH4Lڌ.55]s-1Æ Avv6rv܍͛a˖0󐗗1cZlG_}e& fc8zNgˌӱ+ t v:U;q Oug#ֈ.'NPvL. bx3??7V62g(Y2'wqyjڵUU5 ]Nm;pBnnQFr\|\M> Yhl<߄];gxvÔ)Kj> 3go{_ZΒ6ܾ03MRSٳ шf45Յ+2;v ?"[ngy&ZE1=oaZQ[[e[Q\TldfdW^̄$I~ѣ!HKJ/CYvp9?Erqzv;Xv"ŜzzZ>p`JS$ p8p~yȘkYKK^ѣ5HJIBuU5:ڭxP]]!CFFwcgwW_?z聥K_Wss ;fLS$ ZbN$ !k%4 ܣr97UAU4TU׈32Q+Imۃb Nq3ّEFRt,H0ܽ !D D{ 6l[nEA^τ 2;r6ƍ+1x;p ?AtM۵^iol:ΟyaL 7n5xp IDATx6P6=IsBA ehub\yU~yZM=%Kݻv[Z$X|'A4l8#9Y#~g7rHW@p%9!4n8uDJ8TX`i?#Gw},'T3AnclHqݵk?&MݻwdцǎdcNdggc=dwmK2LЉCv8l"gٰw`9狧ak?Xӆšpw5Ѐ:gWs콯5Xޛ)UsG姏cО0SV=90eѫLMAy=Ex?c¼kÕIuM2I7!D ѣ);+{1gl>x0fny.L)Bmm::l¤I#0hP{ )1#fWcw6\wyfr9*ŭw݌1}s@=Vl3 ;}>\n|5Rݸ)G-Z]H8XvW]u92ޛn=h4O޸ޟtf2!"^yOxWn!"f͚o)x_ǟBssK-[btqn݊FUjzߪ*8q?tqRPRRb܉jǗ_~s믿yc,]'p܈89w:%l@F3[nNjCӉVςցd1{TAļ0Rh8Ҍ$\;}c8'5"ɩݝHlw1Σ袹1]mm-{?ϝ{po xOZZ*.w]ݮҥ/z1ݎsJhiiĦM]+**ºuj 7֮^:q{̌4fNiA ݅O^?lpr<#x/cMxG{f[l,׿s&_T|p V\uk#1dH_ +^w 1=s"55;6 A^##7vGyO. R KMHn#= ^c y|4mz@R^0o&#RDJ^p;`əKމ+GMfFpSpp247b܄1H`T\ؓE8w_|kѯmm7ذi: .FP{T HhoG9)q93N7'Iӏ ?}~Mpm2(d3BIL=vTm@aNq.0dp\tToBkn՝bЈꪘϡCRPWw-- X|9nsv߾}x7){/'@v\HCKf~W'Oޝ:OEQ1) ) IIhhls'3'믡zap%RS{fa3!c}5ģ t.9'vnFʠ bտ_l޼ 9p:]KxZ[;a& V x?1|u;`΀jSFCDȱr* o ĤIaԾR6XOlԴh$C,zM3EQ}B"3-1=+ɖ31}>_c'a"|!!  ]'_&d ot-~qRWq /'$&Nc ރ1hl\|AƄI݉e N݌¼;KT͗Ln2 P}>dff<Nl6+[ӧG4#FÍ7? cރر,^;%XvXV89,Ksa9 z埐 ` 1:DU *qiiݻC]]=ۃytvͥHi)EJV$Nt,V ljΝ>[%=.TVVx=A!c?QjJXtuC9)}/>v+9sU ϞGt-B!B!D_'B!BB!B!>!B!BB!B!>!B!BB!B!nᄏۘB!B Ϗvo B!BT$?,g/^e&d̩w IP`aE6,l0{ލ?[lUg,ybv˰pȂ$ K,U%$^ID`eгl4wex=ϫZ өJX5 x%uveG(;^dCϲ6>L{~ޅ5\~G[ξ#D*\BD ^dCϲ6 Hp8bn:2̈́eG(;>ϴ1,W:B!B g_>G#KAWVrw?9Q[ F(Nj%_y.5l[_/㯌±kz+`N~pQk˘kƛ>f-BYmu:}tw'w| 4we!?xn2wg3};|7%FM;rgƫ龜R"סN:woe3-@PE4@MJ:IcL~i(|Ɏ\==_>6Gz /y1Pxď& J*E9r T)5OUr_SIюng?Q}׊]ZO%F4"?ZNs8."l4ދQ( _鯨(9{aᘀy?/P㗈;ݳ `eWX8gS01.zWi(<ԾnW%iYCYv](w{˳L*m6_|-4+ib{**PX8&j2}Pi Kg Űطo[Xh0\B팓p+xc8g9*ueϰ=<ǣp[v tI\]طo[<69Hw(jC=:mm}u>#7O+533ʎf|Ju#6Y4;Srkc)%:l($?)޽[U x\gx4Xe Nq.y^\vҭTw/X=+O쫡j}rDh:J޽[JdkERKrq:#>߇-SJxj?@x _yϰ Zҥ<pV;O|oϞR3%-ƟX~ ӶnG޶MNjWC?a0ٔ[W+Iw$$ZOsmP 32L^Ew GI+ɡPL57K )С%#+<-ŏ(w}+4g"Pwub?~*;r%_gFC?}ɍ;ՊmzQ:@mP`aFsyGBd ~];m9ُ,[u_~͗-;\e{x/_K|7HD={?mu;Xz0{Z$7OՖ 9$Ol(uu@&é} ސ+:2XڶΣ`VkZt ai&,;B!,x =6(b ؽ{sb.kexBzgOZL3a43>!4L3a}Bhpf²#Bggژf;՜:VZZjD%$^ID`eгl4wFgd ~U#VR2Tx%uveG(;гl4yWZZ|*i쳥K/@UREE 7\-/xU,_/iƌ)__߯K})H4erѧlYRqxxϥ#RccOYw?xnV*K/f>[Uggp@vGc=wK.…BU: $I’%K1gx{5DŋƜ9*k֬L4erѧlYQo]i4!=tg GO<*J/bbѢ[/N*aUW}BN/(3B!" M/tqz=fΜޯ^廯=/9aS)EI<#pPJ~Zw{6/A;F;mާF||͐F]|V3$F<Gs3~z`γHn82J<#JR/+j^|̔,=4A($U޽+蝒r?U#$p;" +uw5?5Bӳ_ͼVz %ҹhsjs{(kd?ZN9`Zig }(qW@{-( l+YoX+V5j5y9:ΚP}lZ#w:$zNZaDI Puڽh?]j~,9sjGmgYTvj3䳹 IDATBwB߽{s˩˄nB!%D|~(OŽHS !Bڄ AԦ!Gqd?BaF'$`!B!$&~}}=ZZZUi__B!Bggp@Ï=$o߉ŋLՈAzz:KB!BH\nCb*zѣxwцG'lee%`XhуW9sSJ9Ś5+N'1,;B١\)zmyhÐno U2,\x+AP%R$aɒXB!B!\W9NUªaB!B!v,lY( g?\8T3}q,[zD G3]ާF||w4 FUvCQJOnTfrzT;.$U޽+蝒pwv6Rݿ(JM4 S8S}"4ՐxOV~1'z(;ʎ^A՟D}5Q-8ʞ}bc:s FrWkû튏H/z.O:}º.x9Bw9pzsJsJIwxe)Zry_YIh)G6L|9)t!\=|0]Q5Wuk=ewg|}ՍC@ig?J*29H:ޯy9%Tj KogޟT"G0?5ke'ܶ :7-u t3:ξ*=Vъs@N^cekMx6擜gb8PZhFh_ eDŚp7f\iˁ{~=Q:w ǠLs=lt2sjT*>IlGszөE]w}}PvV@sQ:D'~QX۷-a}_yt>X4֐ Ԅq}}PvX]m {Z|֓SOgxݚp~4zި~"O4c}(*y&Ss:ZD}$P?-$CKgOiDt)>/USC:@᫵ܲ-'[/6&Z|iAi_ e'qe'P] Veŋv}Oč?lNߓ-u&Ƚ<6 pQpnڕKg\-^_55L UO-{qRH#iO$GI\ gcPE; jU V:K>+}'zt޽9B!B!ć/gBN}$B!z> ([E!#'B!Bb.ףM4J!B!Kgd zk+)5kV uveG(;гl'fzOd fΜ BeCϲm1:OcqTqKK˰p᭝Z$IXd),B!B!1qUNSkX2B!B]lJHdS"wx*/е`(M[8F*O7qTZyzr鏶EZ|t4̾Wf9"s3Rꎓe2zP+gv1hԣIw!$"^AOw_~~.F@הtZ5>0PJrLr׊ï2&_:}%ᔁR]fyO=!A՟E=wĻ/ܓ8t FrWkûч@_T1&u)'Bzj]Ip>r B;_|V:=cw@~wNqT}xį? 56V:H|$އ#3ȤZT2/&x=Vբ #r!D f_jJF< kjL t_0BM8p=z""t"vL"pG E],ʖQW=لPdF 'j]L);-9ѶijZ::C(xa(uL#Qurt;kԊ+{==\y6L,\iёDulODY)V+HןEʕxN}u-Og]o9HXyN$;SWƉUu{(2-Yt]C[?;(]8`̔FVٓL${ZkZ8ѾҾƗDC"]z?~:=]K)i9ZOQgN+٣셒pvY% /u!@J%3hLYV:8Og'@ɆΜCKgOiD}_SmVN t_F*P1 Gt垄'Hӑŗ{_+l\$t^e߲.NԑZ?vѢv%u˷`В.˷d}-{nJ)PxyG%RU CzkuEGh_iB 5.9Q#jZicSM<کv:K>+}'~ԩ wM;{f6\!B!$ѩ2PeBaFO!B!hsɟ2esڦJXfs%B!BH=<%ch:ifeOгl'neXF{|JwU2,\xk"I,Y ((B!B(hd!1FZ4-퉞+ގ`h/( 7*3 Dng9#IJa@/6}z n 6&M:@j!'5`l{_}+,5wy_<Oi>=T+X?Je+Yn*/FJh_c_ɯPjS$lB0P3 $v/#x=Vբvnp <*"bȄ9MKP$;I{C~hۊp'X{>kD rP:Fy,eJyi :7Bb4i: =.}"r ŸDc g<i PډQK9LSX[h_윷DBvCy.xFJWqҳ)ո-Sye4QTz2)qA/Ô?CvG^9i'm)~8j-cUnzxD{2TV)WSOqJ=k/OPqG@B4@e官U"WB@)'BH80žF@5=I9zVI$cn;_FJ {Ԗɵl֨e_IbEW9;u[$ǿ|K3h Kk>>I$tA< 숪-Dà6ɗc_@i32ni s&%=g;%rNBꦒX$uGm*T|&ĭ{wF#fH']lDQ5S=(Gr@iUnUKyEpp=X0"].Ih9e] 2oLO9_#-:N$,PӚn}-t<=A 8m {Kk%B0tsOkq}%Jd/TփD8hCv#Dw~*9C_u= @ q Y%scq\G;#Dј6eĦGҡ/gSo*]ThŻQV6Q;}$^+=Q||.;t@vL}jSPz.qS;ZKb֑Z?O)y=ڭzb8[0thIk[T1@l<&'J6=XrޡD] W^Z(JjCԶU$G橡wj˚xj]uO5]J='9vރ}'$n}ؽ{3eB!B}B8B!D'-!-B!u!q{7}B!B!DgףM4 !B!Kgd zk+)5kV uveG(;гl'fzOG9s泄0fPvX. =vQ'N26<\̛Iꢣ,Y,M <[fj+'ؿv[Ә<7QfisA6K8ã^FQh{s_^:IsկShC{zƴU-~Tjrk׾;w<냀q8(Fqfy))6NUăals$Ohi9{~'(Ԩ?u5>{5qz0#rEĻy̛LSVb9 6UQ82q^R#{={moowziǗٟ`@;L=&0yv a>ad s~r|ڶˈTzG<Ŧ9}t$Awj?Wݢɽy>aq6} ZtXNerL~vF$ܑjm__6yv3-]:n>a3Gb9jQg]^;EW_91ɫ|ڻyh4kIcǙn,(;L/oo>yGՃA?={$֤dIlד&mG$}Y?'QZ5$}Vc}'((((sc+QQEQEGWN *ʅ(}(jQEQEQEQm쯬&NgAkFQEQEQEQؿy͛75(8mB֝h̋l̳l1mmʾMIoJlSMwֺSTvTv^S6YOƜmLJY`"[wh+aI) (((U1Ɖ<?ҚQEQEQEQ6x#٢(0V;um 6pF}Nݻsvve8z\e{+yhmp1n֞7G)$ua=NYWzq~u}"Hcܶ~$Ov{w]Wf_TMˈO 헏>OOƽo1JL&hw2;ʴõdzz;^mumZү'MLMc=Zϻm?X 8^ߝVyAqA}IIr u; w;LΘV7կ_SLMz<3n>'''r9z=H?2Orgeҗʷ_rϸvc?;.*(((^{o1csUB>fe֭|L$S)%?VAQEQEQEQNs/"'?HCQEQEQE9h4 F<+{gk;='㼣2?LJORzvTW:Iկl4d &jaLp~pVϽdF9y}co\g;SUOlmkNϝ+=9N?-Iδ=ώ~U>&󔇓Z[:o 7d3+W|{~ʕNue_BsוEQ(rro1i{wͭlk]y{au^{q4QNZ}D'9Nx?">cÓPWB4(Jm{¿03uw4Q9yL[gaг_]M3;y]6.]GMjU9=8r=<Nml{ܱ(ٿ{gןv&,GyIػ|^ׁۨi=jھGs2W׻t('Oj|}I?wұBٯ.uU_y,Oؿ~w~ڵkSII(viT*7!]F7km4D?Au'w7)/cw ߞ]c75lQE9,oU9.8< Ϲi٠I@e63o+7)nuÉ 7+:i7YQNGG:vwƹg`xG=giѯ돣8zOjk}+)ygo >?֭xğ\vrmyswZI;~yT&+g'ݵ[~u7 w佌Q7Ad 1qxV2rwҙ#gܯv*(ןMҞo7oND$Ԥ7[ߠ}ӚHQNur?{vwaIԻY;c}V?1>;*!EQEQEQEm5>5EQN((L؏|~/o}hREQOWů|wTGQEQEQEQN:1b 1Ol~' no"tT*EQEQEQͦݻ?;f"͛7xhn޼#EilEe^dcetQnkWF0$ַ~OCQ)&N;k)*;*;Z/),ۧwrcCnև%g|*((((d.VE'?RPEQEQEQN4؇=yy^{]=wzIN?S*q0e|YL#ݣQAIhoѦTǪF^ra9Hms|F㨫f~}ttwP/iNF51K(qAnyQ0Ae$tt15nTMO֧;FMwܶ1S{tQFs0eqض9xlϟgve>$kߘy; &yDN6}9}{`?yIAG!' FQ9}œ~:dYl|iʂ2YxRϘ} *W$^,sqves-7Mqy'Wi}YPMLNA:kߓ2;v:o|yR: pTr4?+j+'xキ>4:r:O)N'vf!'ձcgEw+dSZWI?үl/xm|ݓeEG3r?՝򽗫NFq/iv:y>Ovv::HqF֧uQ ձj =r: y{mZnG>=^z˟Gm}Dz_7?VJW0Yv<&>as&ݙ=vl/؞ĻT?=5%cpGKm'TNG;z: 97qxk֠'G#G6O>5w֯l?uwiO7y՛[70hN=G 5zIacR[pȃw2T67j&!KcUNKLF>&%&'r9q(w/1>k߻s^-gcwV2Өۛ(((d'w65#1eQWwPGEQEQeFWb+*(}(jQEQEQEQa쯬&NgABQEQEQE9-7oby?T:eMкSTvyy9F^Ӟ?0}?_r ~򓿙 cZ|[R(۔iky;F1x[!-}Io~'b_տJE?G5W^ĭ[oqZ(((2>Sn}޽{?R'V7u- EQEQEQE;qh7;t&EQEQEQEF@QEQEQEQWEQEQEQE}EQEQEQEQWEQEQEQE}EQEQEQEQڵoh *'g^{Z((((((n(((ƾ((((j+(((ƾ((((M7q'ʣO3GVR9޻A0rsEH!0ւ˨*˒"Y > mϜ!!+X u\~E0r1v,:dA1XcX{vA 30Eň@X[%ڄ2H 1¯|s,u^REsX V'Ow1βtkɳEQEQEQ5wč[/x$ot5N }V׬J^wn t+_.6`K|!?(((́/̙>GV *"!!1Fj_޽%ʳ]e`!F0,#%le9u?{2'Ȭ!7DAUU#ԁ)8G5)$3iFx [8Ow aT*.}mo~(((2gƾK^\|# T'uE&XùsX]}!"og-^)yW18pBM,`Pbĵ"E`P ~Ek%^>!s{͵B$ }D@Ē$X~y>)6bιn(e eɓ*-m#">x1cIQۿ HDBHh֒b@*ObQq;+((̩e:>:H+C5&&Z.5^B^F WɛDJ Ҭ#Y ApM$*"C[=ub[BH<~DDJ陟 䣙$|w`GdH0>Ja+} '8Rs_H l br1UUc:Ok-Zʲ"DeM%[KJ&a !bP@vڣEQEQEQN_VAnwҙ3ݿ{b:ءqbmV%xe' 3ާuXG"Rk+:xu=+٭M#}1/Õ@ "}VJ$$%VzVchFDBm1$I]ѪEb:!\,9Cx4y!ȳkN((({C\˟Cr"YSYo447f% V g9uM`mϠh | 䁓HL/4H`e3d߅mi˨163RァӶ5)" M~b`e$(m g3"ɲ kok:벭yNz[-ԾbI!:$3{L$`18#qq/J}<b[)f@ 4شEa 9#@  P@a2z}:[aqBlqO DNA6{@D S ؝r3؞+((rcߊ`0<~)#ǀ !e#!Ԟ,3UIq}\o+L&het$1$C_ i@Hd.o IZKM@[udkAJXi!yv?Ju<$c0`3) 1@E2$&\npBjBlQ=UUaL?Hg0wp2!4b(((n&kq߄Gh\󴵢SBRlc$ƈu B58|L@2j"[E62eBJp.o>5{7 <3vs2l#n'5C#EU%֑h:EUɥH( DWTeGTUE"YL8[mʲ*dpF%(((f!I`1(Mc#&ƀD|Ep.#g,3%#0=kV?1,.-"+Xn /,X' +P)&}Jf>6fpRˆ<=N Cv C$DCC?1E! {! bJ3k}+b-N ,#Bc}Q4QZ0F%YeV2Xb1? +((/_ٗ%C$An1 BFL3i 4of/ECL MhH CR֖UK3ydH2δ=Ehl <>AӸ3 uz`O==(}H(j *OqG6=60<ފI"wI~U!!yƍ?!4\O~BH"N l4; "qx|_Y{BUحz)GF"16 ˽N,Ð CQXrEQEQEQ9bn?e."g)% FȬk"%%ҥ˯`03Bݬ;h`Y(rZ>^Q= {%.õU:m.]XbE[< q-!DLL IDATI\Hla92,9(Eb"$!%3V"e IzYeOVHL,d2kXH'""àk /-wѵ<cs{B#7}b>Lx`O">5#+># "V{azoyzuMP8 wKm (((j@cxK_%"<π&f:1Ƶ<,{1ŇD^䘔nTT>bغgH {'}^xϟ_W&e$zuHH8$3dЯ Iva8`XX0Z D :PXc-BHjVcF7u_cpSB0f|Ե1oXX(! DYLpր4q <`dwϟ<ןQ9EQEQEQ߅krÅ͙ cpc" ϩ)HI8c1R-vc,=UMHkRq"—..R=`*}\}R5)S@BX"sK#f~,}Kw=@`: HJXiμgm?HZO)bs}g-Oy^|mB1C]WdYSNE)#E! H1}X6GIߍ'C{7y#}Rz(((j=V,vxƻH$rk ]EN qi;c >y\s]` C$:!8 uoV*u &3I8khe(&BsV&\(,_\nBYHҬHr۰>T^`!? o{͑|n$B8c165m<0`m`0qV-r ʦjkOLͱEExF5EQEQEQGO)^X{b{?<i>4+1c{W{RJЬ#^Y _NMqwN8M%ZC"|͙eˋgZʡXȚɈ&%|)pv&NÕqK$lO A## dP o׾5En $ "EYF,w9,/xN{Ξu:Ww+(((g+Xj_1bFo#m" W#Y$!0Q 1>EQEQEQ7HqXl1lHCcD6bRj5{#%bݲ&$> uO,b!,^FK-!Yq E]jJ#E^3zb8O;/G52 `eGuͨu}\)((v&_Ur@QcȆ+qx^?<~nx,˷& 5fCPՁD.`:GN=gZdmNB ܿLfrCAY !Hjd0HC& "9gZ0X^">&|jo7!D4Gn~'薁l"G|BH8 4 o~o/d\hwZі(((XkyLLD"DHf1 "M&!rDn#"DcceqV"JRl+]Ui^ȅg "g@e0bm "*BYzbu+~o@q뤀#F!HHg- r<.. `@,miGZayiNQd&,'dѲޫxhlĴ,뀏i2B X+ؘ,g‹jeAGm߷;blIU䚣|L8Km k@_ZZCmV}d9ї; G2-%(((;!&͚!f[%Ĉ9g`~)m )6+ܽAZGe eJdp+5H@Y89K, /mжm  c1X`X|hvY_ pµu@U *ʓ|0.34F}D-a9^\nA/26_Yto~ O=C(C@Oؒ `22SHo&_J2,EQEQEQ5wX8{niK !XD!dӶ~@Y 'xZV0V3Kf1!F1Pr+g5}Q}l$B m]$H +On VKvO#n!$c0!jCF:f 2((((sc[gIE2O1~lBl.$bBcw,.$^EyGz8JhI/XZIBTcq=6A5{ gm I양io`DٻhˮsK^UBYd Gf âM4,fM3@cI8!˒qP%TUիn<ǹI#f$95u^Ww|7?k>s$I$I$Id<*{hd:~q-e!F:LqNLkCGNSMcieAcZۼ!Pdlig ݶ{Y R)ofl56;:ʐ.׬~UѲ5KK;Kz FhДXaP7߯355C`3wB&om3ψ Pp(QL&l+fKj2Qd{s_+ۏ}^z$I$I$I[#hWpy:!u l[X`y":Y^UwsWlG%P2zanڀ*D1BnAiYKayUTz6kTxrbYK258 Lrres/ayV^QM@b%,mɥ(cT Fk$(,́W{aAqz@?bmf050FT81?[2.8l>eX92NH$I$I$IW93sLsLQE t;F@mfhyz33\Z8G5q\xѤ@P%"k,V"\Duday[ŜDcqa%gW<1%/,,"پkvoP2dm]޳#3KJٜ *h!#+(6Du4!D21,!h*=j"1t[BNtH#&_|q)k$I$I$I('ee}NV FLP5 4UQvncvfPMޯ2u'Nax?f83 mC,G*e\ yV* vL+;?C;PrNFk!kvNr~/xa +d\l!CA Uq䔡$FALj` >PgFa|ow#y 0]g@44k 86ԥ Ƕ !@Ȝ2Ke ؿVf$I$I$I$f./py;k8~b 9QdBf6>zvo_`'C^+g.\费pyT+0C=8!FL͸b zc6lYhBsY[`0aNA59'D%T5~8!+bPTuSZ_@H 4ͬ 0-o&7_71"C}Uב|.<7L@Yy q9˫ƕj&qM $I$I$IGG JmbUi1b`ri1\ǧ4u]Q|T2k *!;* IDATIŸ:ġuky;}۽_$I$I$I~=K;˙]ƙsƲ6:\}p/h]wCm 9.Z9W7(t9WKz3\<ɐlKkPWۀUK& XT,ea3Ŷ[-JGX  5UY1QNJy48b*uėjB@(cM\5HGDDrLAc C 1*LWAi&7:FTV5BfJ1(O 8:9~ݹ@ޮ!bx=)O$I$I$nQ RP/ȡ\8뮿q9vM5YW E xeeeW!h851F@"LaY:fHg/\qYfN0 c h*QqECd}ur Bc4VWԵ*&D4(o>4߰,'edN"ƀfjZù| 1*#9Ќ:d %`̗O># GK7B$I$I$?%x{O\ĉqamŹƄƈ~޽9y ~7 Te9'Oٌu>6G1VNJfgo(9/9:0C73X'!8 Ӳw1 #Ο[7e 7쫺C35?F!4q @ IX=Qcs2-o>nڳ V NxhS_O{QBlF4_."Qbf0!wpzXv)wsn$I$I$Ix3 `eu+b,M+D(Ze <?~Vr5;1Ǭ厽{b73Xgb.z.ulv΋s`sJc͞z+( ٦*@":D,h33]ڝ0Lq dks瘙wn;zirǡqΞYf4'HE=q*#jF [AE5llJڰd}Tm oPB 9b 5ulzU vŚ 2K5IsОhԭzf-G QdB v˟gzs,(ϐBY\F;19N]F/cǎixܔ c)ͬ\v2UWVY0>. <1Vpi1#oAv8|1Fe9D.B}kgƑ0evà?$*DQٵ[3w/&fhOO~]8n}i\V<V*@dڗj:RPHxЮ{5 y_5ƁaIG(f:=b}!l%rYlVЛennϟsVԥئ 2BLb$I$I$IR .&3]!3??UH :̾=;_hqyfyO]N`˫X$@>"gff~O22opFe1||s@aKj_+z^>xR3#c𡤪kB;CU4(~zIzDQOĠ9ihS Q,Jj23ڽ{sdS&O{YG*l*MkL,K$I$I$I71;ww)&S-B[sIuDQVW/cmNSxk}Y8~0hg&cbl&O4 HYS8vpQ,U SMySX )oIُ56&3q1Q`D@!oBi=ƈijU1Pi˃>:g܅ ȸcňU1 1x& Bt'$I$I$I`#6Uog%VWW ojՃeNvTU:!Ffgg2 007pL9D#%8{g+<-+t{͵6VWnLȲҗxI+㒢eh:T1!h :|DX^pqT)dQ% ?oZϧCh<(+V)ePq+X2a`3iI$I$I$):O}ҍ|Sɤ"D8G]V[ 1{T-,nK!uUeum TѤ""<1DZX\Tf=s*M:Ǿ˟\2ZV UUbaRʨcZ9CAc ԑ7ICJU)U 5T:+i~"B|4sbY#(8+Մz *uq^bۜ̓ͭ I$I$I$?`_xcelMh X;cA>>+X ʎ8w~u:NA k|TBP')rl 3lZ6A|^uA|)'s_0L\7Q?@Pi2*TA>"T5L*NlLIãƠb@" 1j0b}1D Ef"FD n>}ׯ#td`:T ٬yTDX숃O:fYXXdnvVWY___NI$I$I$yW_+T=u]c[^b ͛N&emm cKft:=lk#FvXi 8+QƟ|0wD+l=bi F jL8bRՔ'(!POk4Dbkc\0@*m MbQJTFȴo} Q}nu~vg hFRkM-<8|瑇 +^w0.njFCNW^`Xw?_$I$I$Ig;u 7A2GHPáÇP,b34DI!XcNGU ȳvCP،^;'F[O1M0,' fkq:hTD 4Y6Jή sJD k+ gލ1XkA4xlw0b3GUG5[A9ySUc0F"07;Oof_ߋ7b \u%3Z{>gΜc׮Ӟ\dt ? T=i^k/*F ꠰]P֊ɲ&5HrzešۦZa3iJ'u30MV~sdh3c H@Á8' n bbBċ @,YA4;sgy_^KZs`><9ǟgyj`'Ofa._>϶msNK$I$I$y4qԱ #kk0@ u{sѣқ~=.Q##ՋT|+隺F哷|a>/~os` n֛?M&}ym0,cG߅0\ rr_ "k~ mp=P8 xNF‡o;¥0Ix g}Xrdyݧ:6X8.˱d.'ˊinBMn(PmzU+ LӇoIk,L3 q:'0Lr(rsc,nZ-Bh2 732!r0X@;LYuӒ$I$I$I}c7^_~zMnYEskK}Oy*KwSz#D"xș9𘧱8'%*(8'\s`gVMCd߾}[HEQ:CBYZc?)h N_eopbA4[/ITJx,k>e9fNK$I$I$y4ɄmdY#T5:Jyg>y|F::h;y €>w7ϡqO|*EN &ԨBPO׼_om(U9!(L@G3΀Fb D.2 J!c`/iv#lijxm~1 k&@>Ʀ@ot{]N>.*M7cauu &gEUh,9r߽ܴgm~G+X .N8{,U=IwY$I$I$ɣ=7b&ڌJ<{(: 9s_?"" Д뫁>z|9\) >15hyZbX>F-_ͪ(TZݯx%A5ݯx:E U1P^&&T""mWq{wkL[ {ߡ!.sꀶrv]^Ů.ήqf8bd3!%V6[ eE)װ>6Az *y7SYUPXg12d4*kWll\飈Y/oo~3o|OQ&I$I$I$`r$NֹEʫ< m5rg>ʅdb/~1Ůmϝ_'Oc$[<ø.1iɻ|3JDݞO{{p9>{߰^2=x5L$XzԗCP^bqlۉ۱G%aNWؾ cT&< IDAT8y?3\ X…dfپc4WbP.^@Bİk>k5}ưA`eaa;k;Gll03;uU2?7|\щ`m߯CDcnks~;E~7v-Xm I$I$I$GGfc Xgx^?GM>vvۿV*~M/ 5C~?{R%<ȯFr}5Gx ^̿ɟeq҃ atEnema\ h|"y鏐n'T \gljM뾟n;P#;k"O̿%/}%ie?1(7i~ٷo?z0;o\滿TU U/E&1yőwc0Y*fQ&Z˳Tn+ʯ oxۉ9$I$I$Ixz,'l_\icX!_"`HO&qo{ U9!bЇ?ȭ|V9̟}UԩSM/ _2~Wm۷s_vNrPf{YQ:ĿID2n6Q]7n~=Y?u'3wzp]Cxl rOq=/^\♯z g;'8\^>He/}%q[&b s=o'#b47  cdmm_|r j|˯R#B K_ƟCEQ˿^rs?N]_տAE L@?=X{ܵt:->Ͳ1Jw`$I$I$ɣ!XbĚ LhT|K 'cN˗KNg.*kVxֳo"J೷go4 ^" x;vl{ u>~'n0F2D!xO[K.%4l1 JwՈ*g%tpiE\.bac Yڙ( K;_Bf r޵>7ؽ n|SP}P AC,F5hpui2C=v_gzzODTջ2{G?_пw?l<:N * kWyZ|aY:1;U^~[uiY aFEJ"/D _o w3o O !L_*0bukxݬ]srMkOQ؟]fr':;1NƟ˜?M6=ͩSgOo=8K~ܺ}n00pё &a„< =~/G~?8}u 8;GL(AFIٷ{B=qDǴwt#?śǏӃ GO58yӷ4PdteddxL~RZLJ~_e0w?}|_%/> yoK/ݻ~WǿWøb{/WcO|'083?]ǿxȷؿ/]2q2Nяб&@g33;kȥ#\}%jߗXe'tl>n{o,øvFO{&vAغ\A^zu6<c>ާ(Z{+♿CtwŐ>+ݗOٻ` |Stunru~cx?BRSaMedx8w tujOy,<'.1ضu+ǖ={pܾy7nq1:5`ml޸=;w >?@c߷BGy-[_kwu}ݫ7Pš{'oӹis#<_-\u2z_d \d'1Qo~/K)%={? 6mL< {CZϥ 7pβy:"gYۮ=ADDDDD!ݗF:2_XO$YG> R>)(Q/AH :x24p/οU0p-їC{ԡl_=TnwnL\_靫 0ai i10\+s۱\z_mE֟ƫplٹkWnbʣ_O?KT_5֬ź .P)~,fMΝ9/g0b}~cX˼yܾxgπK`||coe||bBgݪU\r4xJiGƳv*2Ȳ*W , g-!˰6Be>%d [ }>JXkYN8cPEÆNDk+]}"rU$w+bR׋ft.׹pm Chf:H!KJW.dy:ӄO2Z6(WoSz@q1 }N\a&O oh-O'0xn.vNF1zsc c8rQ(wQfDDDDDDg'Ms$|uC : !@G@VVoa s6?N·A` ]†vVncYWHe"6@ΕEG[ Y6ə8Sl_gΞo6ʶ[XDTTJt1xgb_=}=بqU)Qy2,c=>\kwמxmJQxGصogΝڍ|o}.Oʇ~=F~=[fнu?I$#rF@B (r"G(::s<z8)]h# ˘|;e g;)y)M&#LFhf<'Kd6P)YIlwC֑z#IBE$YD`px,Q,] """"""^lyjVj- m|Y. F+|H(XsE`׬^ *ӧ248޽0Gش\1Z`d6/~T%3 G^}@\#ض; \=vx )2yS+H}F9\o~cHjD΅]Mrj)1F)5 W@ omrAY7 !&8(@8hYM:C"IDQD4Ms5*ʲ-^oC6DDDDDDVJ_x=E8;rw=6_úΈuEՄdpY6lFoѿm/dY (Gs8WPR'rex >ξAy,cz#$ǧ0:^XS(8_æu,Xu%nbBnn\Й/PR;5R#QA{?L|J1$b4^RN?&~c/"""""R¾5[L ƲJ<sWp޺[Xf#n O63֒,b[6_3x\! OqIݬW߹HQq/ͯyV_ϗUmc/y3gO0y9Vw;l[Ŗ=tIU8Ps $".'Kgݛ)߫YF!u`"7 0L'iZZὧV)Yf-$7NˋWP/G3c3ì_m;h1:: gqܩ)K$I¦ 1PŞGw ;ve|wJ䢘YEV^XZ3>^,GdIB^?7ƹK#lǺ,#WGO 'IIjpT2VŇd=Xꍩ?F)Mkz3.@Z%-iN|;#\$anӽy}e2|0z??QxV{J op81<ĺu{e{'j_\"%6o~(`ny"K W/vl탱ą"?)(`)7"²mcD!!K/J¡wѣlXa?G5j-\ͨ ՚RKȂV(% y+~mm 'cL:Ʀ} WSF!s 6u~=͗7Bkvuyr>@ s 9 QdhÛl{7jO9/B)A=lg0}""""""+&Ȳ YKXƵ$9-ۨTna>1_^)A=\_+苈om^w`ɼ'ش/iFy8HϚȼ'U"ja7h`F8Ѕɧdv#$mBfPފ EP+TG^%rlņ[J*:u6o͖;)6Q˨T\rbiH2K)W/etxgSCRո38EWI?1` :3m9}LHӔ8WPi c j?m{gy'OG|/N 2OgXu""""""+-,I6Qچugp02r$NR RV{|B!TG:޾ _y4\[`RB@c|5zEm\͐ėbL'>峯zzi %vENuO)A\eOpJ! \g,bLՄD rTi)O(0h=Qtfqc! )BZZoT+d>#d$IB?i|}/GDD8? k~J'CY9aڌZZާZDyw:S/s!|y,nz p۶2~u6nXC\;(vV%.g5kVq+)EE$C8X,EQ\x>9G>ú@9; XΉk5Bc|~!g'#fbR)'0>"-mm}w2p`y.|DiͿ;c{ """"""+:8Gj!Xؗ&$5wHTn~ %FGV(P󗰾ܢr=UOmhTڔ8 D.{ i|"fjeBr뤣U:yp f\gz[X]E[qdXr}bާ:`ik ،8Iݜ~,~z%1TYoVMLxRT㘤|y cQT_b nY([?m>+D+-Z- FOeq6JdiLeLJQ:MBx,,KUҡՄL1ȍq!g!1cmBtumc9s޶66ZCW{;7qn}ޞ.zb{WZd &ˈLb@H={fXSP4Vpoo0ffiCeM c,>xB}dx2::F/v,_Og{Hbe""""""+= D0Lpip%qr>`cg3ں( k5+gɢ2U604:,Ś|(d]xLFlg(]ܔ8nD5| #O X"Bf\\HP$M::.8~ 汷}jL0![Ȣ^RۍD'#s]$֐*5N@zpT5bVm$u0Q՝;\L|TAop׵h=ġPt`ӛXsb\&qvUkރ۶LgŶGYk'۫psX$iHݴGy>Z 2yɲl@9G7P.$!r>&W>dv_!ڻDDDDDDommvu>dQXCu0BZq.LT"VB- 83*2I>5Y y5 ^e18FuD0U<(Nv 042`hp˗)( di}>c &/O!%quþq򷵵aBxI[gߺTɁ)6ƘGeE\C?% үP=KDDDDDZӌś"76cƐzyrM|K2JCൿ"P$@l E)տbC/΀ >G:vzNjdpb'bxLukދ%Ԩ\3|{/1~BBɵ[8{k{6sg4pP)c2,L= !`!XCR՟`>IXW(&)gk;vsEO7!rFqT``@h?5,:KQG3Z&ϓFd6U""""""[7֑-w;l|B>xhqZ@ G@ g4B>$`C,!x\!Zd%70ɇoX|dkxb6 g/N{jcS8H<2B}}<CDyҴx>gՃ3iY .Qo>2~,&77<80O p'D2q$QNj(y^m/c׸s,㣣tM,rEI18Y/ePÅK,G"ZGǓ7LB_G3!?RLGB>2vHCU:Ȓe >3C/,8 iNi9: 3}̔'GDQ4yV>ԇ|M_&h!D6f}oN᭳,?1?Y=m>H{:ʃj*Y:q&>cM=TW+5(S:Ȳ8cvJM/oM(HӴ>b?8@6q~X`ϲ2jjFVZQTjj-\\.7"rq5vOY.GfwQN6޻X7]D؎udIS)Q\_G./Wd1IvC3Ճmu$rElzAP?{O0XS#;QDbYp!"U6vra =D.] Qĸ84dՌ;wS ϝ:G=xS2 4aUW 7+8oP6MAh||90q1 _Gc s1j!Vuӟgoq ʛL154 *k (ol,=QйI3E"  """"""rnm}Q}Q})ݿתAO<ՠHe""""""" """""""/""""""" """""""/""""""" """"""" """""""/""""""" """""""/"""""""uѽ6]PM,;w=~#ٳK!""""""N< pO~#c8rZdPmdGkw*BDDDZW~Ñ#GyOcQ4 !PmdG}e&W\Umd"""" ag\Dm?DDDDDa_T?jQy@DDDDDD3~϶mp55?̵ٖm1JiVnޯfʾ1S-w_۾_WBQWӼxg۷?2<\-d[w;ӷo֨'ʲ2Noיy;X&jz[QW(;wܹc;wlr7ݎN~>͵rV CwxtEiYbBmbB~gQW_KR!׎gϾlay~Ξ}uӖϴg;v<:;Ows!ߣŒen|߹zw r{j[ڱվw]3Q/mXH.|n~YDDDDVHיW?=#|)?ϴֹsAΜ9:wo[smCgW~9W.,3/)\璘{:t2m"""" Kvkyӧ_c׮8}kR7iǕwz hj ӗ]ʰ\݄ʾz1,$W¾}?i݇8uջN ӎ+1:}rwK盷M+{+\YZvﭿ媟uϴݻqs-;yȔf[\ l:km3wi|:h.,dyv>4g{?w\O[B^ϴֱO=9<ɓGkB=:9lj^lN_eb]mӪ魴,滄&h[w_h,.5S~ϴ?-8 {\fz߂}GA}XSmEf)TC+"""/(?|e{7|ֳ˪_ Da uvtf~62FCDDDDE}}Qۈ¾H ;wP*UMڊQXCDDDDs?| _6g@6?DDDD>}۳$>zh5/<1Mͻ1>W^Rh@!"""~/[#9r4J?9YVKvf^5ʕYan-[:ҥKV-[.z}~LfF?DDDDDa ŋ'_oݺo|7k^f)3SnxpANm#""""a~c)ֽm~.\xsBBC==cG854>kin^lo۶mfZP6!"""" -ܹcرQΝ;iӚݘomʹA/"""""" Kg_L4>o3c(䋈cg;wP`yݘ3GkDDDDDDDa)]qkS/47۹uLyӷ3""""""a݇6݇8uWV]/"""""" O<2O<ž='7Ok)7;yȲͥ Am#""""m}i3|y\zRxpNm#""""""""""" """""""/""""""" """"""" d``jI{{*ADDDDDDVf?| U͋/hQjK/<Ȱ/s{晏Z4mZm>2Uh!""""9s}cjI>1xUM\Jegre!ye]n)bo{KQcw2mZmZ=mٲe r}c ! KYu~mDCCDDDd%[z6^ֽmm9g5BXm#""""r3~߶m'ݶm?gӛ7?r]?ٴti|g>}?3Gú̙Sռ ͗N8Y&W&IDDDDa>ӯ][׷s)l~/ImIo׮8u:?`~3o,3Ӵ.l:x/ً͈Y^}?|.3ڦ5ۦH+k3o}'m'{O<2e}k0L>s-7e6j"""" Oxe5OĉWe;}#n`,tn13ؽݖi1eW۬i!"""/""""""" rw?[6!"""" +]m#""""" """"""" `|mަJ>?E,u/"Zڦȃ 2g*Eڦ.Q"""" aȑ<ܧ'G?9}Vu!""""""+,CR{h+WDDDDDDd}oٲwi.`˖\tbegc欫O~b1< Y^\)fe]yŋ'_oݺo/\ 1z{V)fe]yb3}~| ۷?o}#l۶ߘqc9 s]:_@KY.6+mZ%(싈¾(싈¾/FDDDDDDdeÇQ9Kݼ i9!"""" þg>JhѠi9pT,C?r(=i1&!s<7AgsWNrRΥ*iۿ66@CCDDDd%iGmݺe^.^<>V#jYTٗ{K9Wj6+ w?DDDDdʹޕEDDDDDDz؟iZmm)zr3g)/_.{^{-K7k)iV!""" Zr1B;wܹcnyyiY׳aQ.B/SΥF6G۴JWPQ_ĺz^ֿZrmY]ع |3g.:VA8cزru/mK6<[CCDDDDaOvz?azs9r\F#m6+1RN:S^go60r7|n*k+'l-wfu8ݻM>y䴓'L6}9]};3merf6""""  8ʜhLoĉW,lӧokG|-BrKٖmi!"""/""""""" """""""/""""""" """"""" `|mަJ>?E,u/"Zڦȃ 2g9Jh0wLт^z6PmDDDDd#GyOcQ6 !gO!""""""++cޫF\rU """""".ByEMo'"""""" Gͷ[qqlŋ""""""ߊa…7ٺu.i۶…7ZgEDDDDDDaE|ۛ¾|/Y8gIDATw۷?2ܹc3i~ݳ/""""""}fm.~ 3g3gsAΜ9:Y;`2EDDDDDD[0O>ݵ1VNʮ]qԫ߽Д/""""""߂amW'N2e7~}QQWQ/FDDDDDDdeÇQ9KݼQUDzT jQؗ{晏ZЋ/iylۼ y@_vt{Զ<;{:ڶ'ד@?d?mvt}ؖ'幹3:.>̾@$;; GU.\Ll)Oϟy/D@?dkH}ɤD@_q\^\<>'D&kaq|kڲ~z݇$col=?-(N*> dd_}>Ljpp^N&9FRyibLz{ Ǻ`z}]FD_ߌs,<57 !_[[ׯ(Ң f3ܸIvM[Pd?( /_Ԣ ϟoBmϞmLD}37?~2?9UV[EQ$7̜ CxN~QGmfgOKn{ڟ/ޞg_)O99g}Pd?inL}ؖk6*J"}\.ٟ?۶ogA9;;.y c?'7N['N,P6O+3o}[[+I@Ru_{aaܡ ӧZs&IKK1Hy7'kaqmsˤdSQH{^]⻾UBw;OIظWgPb$v> ɾd~d{ŋh‘#j///7oi͜YY!ƔYw 0dbW~4ѿtIߌ8\}pG!"-l6Ík״5KC!K-&!kǎٳ2fNe~!?| ޾9?o @-{;>.'WN{}>3sm̩#-ph[rz[:nuJ=^NM O>ُ΄݇ð/븬f6ܙCvv&rֻ=$%mowY=SK_Z9~% ?2?ЗW&]~a\Neq>~Ϸonx>lneM+).HKظt玷M:o^ASpv> $ ٗ&ŋh‘#j///7oi͜YY!ꪾ7}zpFC++ҥ5Ę&Uc<ބJ_(DQEfqpe@B(|R&<F~codnlx '9/Nc S̤=k{'?q TsNH┍iJ~833Z¡mq 0Y:}}lZ~?7w&>lm=vw݇}lz9svtMȀPdn̡m;;ZY.ڗ>6kygA?8D>`Ka{{P'zJ{0&*OںNX [[[Z-?| 3N^"x(&0ݺZ7ZZX\<h}q|\k;&Nֳc'׋b5~'f3DQ0'0Lc8w[LKnO#/fU&S?1 'O<:II?:H+rpp^N&9FRyiu 1VWok}sLfV~f&C7k`bwWօi#Iㄿߋ&> $d޽ֵ$,//7< ,a"d?Ӓǿ !Na|_#X^o)K8"- )׮"ܺM&}|__c1>O`NH}LYk6Z<7옓`dFI}>>}==z^|eTQgڪW'/b|coz :z4wm[fY8zFxl#=흎z6vSU=۲-ޖzז>}Σ,m]}W4F171Gw}ƨ"veqOW'/bLT5'{)\?T7)` k2ye?~2?9(]tά}eRN*g^mPu%ƨ;c{Wq-?*c]*\U/\s\&#oO埴Ue;cge廭kc}0^>wt[7@}ʢU+\Sݪj\Cx(g/61^1>9r0;*%{}tH*;l@۩*A%3wԻܷ`(7[L8S̩hE^ ?rU>,mOot[|Q?UYϷaއL1~pH{@5agAd"T6΃07w&ΗWϪl"TEEq;_9b/.ۿp᫯'x9]…(ڶ;{*Ν9wѵZksmQQ܇LO;o&e/$!~)/W;zB6Q5?i>)^p.u  _}*>wQR.FuD*ڮ-%d~pLu_Ce3c$emx[޵ϟ=tL7;ωKqYSnڡ9zWvC/?ƫ#?^s ; ^k9o;b,|^o6?647<ߚ7,siߟ~90}wgxTǓ<ƘE?&Ɖo)IJJ`K`}><70a K>Lx/'f&,74 - #h4k\f0oC@}G!Psw|_:ٳ<=IENDB`MP3Diags-1.0.12.079/doc/010_getting_the_program.html0000644000175000001440000001531612040502152020524 0ustar ciobiusers MP3 Diags - Getting MP3 Diags
MP3 Diags
You may want to look at the change log here, especially if you installed an older version before.
The development for the version 1.0 is basically frozen. There are several outstanding bugs that can't be fixed due to lack of user feedback: I can't reproduce the bug and I can't make a reasonable guess as to what's causing it, so I need more details from the reporter, but the reporter doesn't provide those details. After a while the bugs will be closed and 1.0 declared finished. In the meantime I'll fix any bugs that are found and reported, provided that I can reproduce them or at least have a good idea about what might be causing them. To some extent I'm also willing to add support for some of the various things that are currently unsupported, if such support is requested and the changes would be small and pretty isolated.
So nothing major is going to follow for a while. However, from time to time you may want to check the MP3 Diags blog, where announcements about new releases are made. Then you can decide based on what changed in a given release if you want to upgrade or not. (If you use an RSS reader, you can add that page to it, so you see the notifications automatically.)
You can also look at change log at the project's site, to see what changed since you installed your version
There are both source files and binaries, for several Linux platforms, as well as for 32bit Windows. More details can be found at the main MP3 Diags download page.
MP3Diags-1.0.12.079/doc/130_main_window.html0000644000175000001440000002037112040502152017007 0ustar ciobiusers MP3 Diags - Main window
MP3 Diags
After scanning completes, you see the main window, having a table with files (and quite likely "notes") in the upper part of the screen and tables with the "notes" and "streams" of the current file in the lower part.
A "note" is a message about an MP3 file, usually describing something that is wrong with the file. There are 3 kinds of notes, based on their severity: error, warning, and support, though the distinction between errors and warnings isn't always clear-cut. You probably want to fix the errors and think about warnings. The color of a note's label tells its severity: black for warnings, red for errors, and blue for support. The "support" notes simply indicate that a valid feature of an MP3 file is recognized as such, but the current version of MP3 Diags can't use it. There is nothing to do about them, except request for the feature to be supported. The main reason for not supporting a feature is that although I've found documentation about that fature, I don't have any file that uses it, so I don't know if my understanding is correct, and also if anybody actually needs that feature.
The notes in the file table are grouped according to these categories:
Audio
Xing and LAME
VBRI
ID3V2
APIC
ID3V2.3.0
ID3V2.4.0
ID3V1
Broken streams
Truncated streams
Unknown streams
Lyrics
Ape
Others
A note has a two-letter label, which is used for convenience, to make it easy to track notes from one part of the UI to another, or to report bugs / ask questions. The first letter of the label identifies the category, while the second letter identifies a note within its category.
By default all note groups use the same background color, but the colors are configurable individually. Throughout this documentation, ID3V2-related groups (ID3V2, APIC, ID3V2.3.0, and ID3V2.4.0) use a different color, to make it easier to see what can be fixed in the tag editor.
Notes may have addresses, which allow them to be connected to particular streams. (If you don't know what an address is, just ignore them.)
MP3 Diags has its own, rather rigid, idea about how an MP3 file should look like, and it will show errors or warnings for non-compliant files. A "good" file should contain these streams:
  • an ID3V2 tag that meets the criteria described in the tag editor (this may also be located at the end of the file, if it's V2.4.0)
  • a LAME or Xing header; optional if the audio is CBR
  • audio data
  • optional ID3V1 tag
  • optional Lyrics tag
  • Ape tag containing normalization undo data
There are further restrictions on the order of the streams:
  • the LAME / Xing header is right before the audio
  • ID3V1 and Ape tags are after the audio
You may want to ignore some notes, because they are irrelevant in your particular situation. This can be achieved via the configuration dialog . Several notes are ignored by default. For example, fields in an ID3V1 tag are supposed to be padded with zeroes to the right to fill their fixed-size allocated space, but some tools use spaces instead (well, there are also other sites saying that padding should be done with spaces.) All the tools that I looked at don't really care about this requirement, and work equally well whether the padding is done with spaces or with zeroes. For this reason, several notes about zeroes in ID3V1 tags are ignored by default. If you have a tool that cares about zeroes, you should remove those notes from the "ignored" list.
You can do useful things with MP3 Diags even if you don't know what an address is or how to read the hex number that represents an address. However, in these cases you're more likely to mess things up, so you should be extra careful.
MP3Diags-1.0.12.079/desktop/0000755000175000001440000000000012040502151014123 5ustar ciobiusersMP3Diags-1.0.12.079/desktop/MP3Diags36.png0000644000175000001440000000107312040502151016352 0ustar ciobiusersPNG  IHDR$$sRGBbKGDnArS pHYs  tIME%cvIDATX׽jQߙF"~@F҈7`M\-m6TИ&z,fVg'1ffòg9}gknwX D1iI1{g}]`ad;b@Xa5C>bK<+Ɠ\ȸ[kXq 5sxhaDi f|`VݍFX}yk& H.z@]?[7%FX9sCՍM=HI0oH,6.M}eu0m´k>͏kڷAд&_$=[וKKjHakF;[U Aq}x8j!)cɬq1rx"K38cܗ;>m1xyz/wf/"ηIENDB`MP3Diags-1.0.12.079/desktop/MP3Diags32.png0000644000175000001440000000110412040502151016341 0ustar ciobiusersPNG  IHDR szzsRGBbKGDnArS pHYs  tIME"4eIDATXֿjQlE!DV}B,WL^ XXY 6 Xh Ө(bfdYn̽s~=܏ &8`D}B?,`pe vO|7|N6OXOW:*3YQ~S%ۏR<Ǔ^Anp39&.ٔ!Og_&ǰu1v^X2L:VEy-.j1`Oj}~DMXk?ȗci L촚&[ZEq$ARjVۣ&#GEak8gJD*gHTHbI#:-YlO>b'RxgX[a'\ .tr3eLU0+mVMWI*=b"g%\ )(V-7~ox i}>*IENDB`MP3Diags-1.0.12.079/desktop/MP3Diags16.png0000644000175000001440000000053012040502151016345 0ustar ciobiusersPNG  IHDRasRGBbKGDnArS pHYs  tIME6,1*IDAT81JQ /Z ڈט L/^B 63>awU /T'&H9y 7)gy  !k& .spscK=UC{QkvU:z]LV9++*QSL6 Ms}~q8N9Ip}bk9/xJnǟl'{Rd3IENDB`MP3Diags-1.0.12.079/desktop/MP3Diags40.png0000644000175000001440000000117612040502151016351 0ustar ciobiusersPNG  IHDR((msRGBbKGDnArS pHYs  tIME'4IDATXj`Xi ZZ\*V MHō2i{ ^i\t%EKUa P$d:t2Tr ÛINTRg[J3hR}hpM0 p<pe L  *",MIo 8^ rS:x!s#¸z(xPZ5Խ9~P5{Sr\QPcMc㙽`UTmq'5T6/sy~(W%ݣ &^Zxgq9`` 5 } %s 8,>*/3iH"IENDB`MP3Diags-1.0.12.079/desktop/MP3Diags24.png0000644000175000001440000000072212040502151016347 0ustar ciobiusersPNG  IHDRw=sRGBbKGDnArS pHYs  tIME+_rRIDATHձJ\Qo"$`ha"w X n*;_Р.؄!BbY׻k4f033ϙ#QtL  <( rq_#ؗn j;V f\;k4>ɻtx[O!XMw/.Sf,mԯE4c]6EnlWIYjOv˲(Q#IFm=Zg2wOg,yaQ5np$6'N*4k<x `wG }iۧO?t,IENDB`MP3Diags-1.0.12.079/desktop/MP3Diags48.png0000644000175000001440000000135612040502151016361 0ustar ciobiusersPNG  IHDR00WsRGBbKGDnArS pHYs  tIME1nIDATh?hSQmEt vJu)F8ISP4SqppwQE`JqH$yMCo{99򾀇6$sҁlPp08(:TgXVCkkdYP1x/X0>K[Ȃ NI7@_K}42XD٬"Y(Ua %jU)Xl =sZi&4LSe*p 8рVNO-(Zmy='9-}Կ 4(ѸgDߨh/Zÿs QXiXbVX7cٺY$\?h&' 3YH&UcXzjqvS>v5y}&5FUgj|xOJ YU׼WT*opYp`TV]  L`kN.3(t(e`mBZf6A0 03أ=qi 﫳]1x |0ig%TWRidAfa*NkU ~s`xeZν e<<<<<<sIIENDB`MP3Diags-1.0.12.079/desktop/MP3Diags22.png0000644000175000001440000000066512040502151016353 0ustar ciobiusersPNG  IHDRĴl;sRGBbKGDnArS pHYs  tIME.o\{5IDAT8jSA\.%)7]lMl^ຯ pݔB7.ŒhNInw3w~3sߤx?0e4ru%Tk.4 Dm Z͝ 4Ycx֖LHEIg.V%K'O:@Cz3[rz\EۊmRn*|5;9[U71,G Build-Depends: debhelper (>= 4.1.16), libqt4-dev, zlib1g-dev, libboost1.35-dev Package: mp3diags Architecture: any Depends: ${shlibs:Depends}, libqt4-svg Description: Tool for finding and fixing problems in MP3 files; includes a tagger Finds problems in MP3 files and helps the user to fix many of them. Looks at both the audio part (VBR info, quality, normalization) and the tags containing track information (ID3.) . Has a tag editor, which can download album information (including cover art) from MusicBrainz and Discogs, as well as paste data from the clipboard. Track information can also be extracted from a file's name. . Another component is the file renamer, which can rename files based on the fields in their ID3V2 tag (artist, track number, album, genre, ...) MP3Diags-1.0.12.079/package/deb/MP3Diags.dsc0000644000175000001440000000053512040502151016644 0ustar ciobiusersFormat: 1.0 Source: mp3diags Version: 1.0.12.079 Binary: mp3diags Maintainer: Marian Ciobanu Architecture: any Build-Depends: debhelper (>= 4.1.16), g++, libqt4-dev, zlib1g-dev, libboost1.35-dev Files: d57283ebb8157ae919762c58419353c8 133282 MP3Diags-1.0.12.079.tar.gz 2fecf324a32123b08cefc0f047bca5ee 63176 MP3Diags.diff.tar.gz MP3Diags-1.0.12.079/package/deb/debian.rules0000644000175000001440000000614512040502151017103 0ustar ciobiusers#!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 # This is the debhelper compatibility version to use. export DH_COMPAT=4 CFLAGS = -g ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 else CFLAGS += -O2 endif build: build-stamp build-stamp: dh_testdir # Add here commands to compile the package. mkdir build_dir # pwd # if cd build_dir ; then echo "Changed"; else echo "Some Errors"; fi # pwd # cmake -D CMAKE_BUILD_TYPE="Release" -D NNFW_CONFIG="" -D CMAKE_INSTALL_PREFIX=/usr . # make all ./AdjustMt.sh STATIC_SER qmake make strip bin/MP3Diags touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp # Add here commands to clean up after the build process. rm -rf build_dir dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/gentoo. #make install DESTDIR=$(CURDIR)/debian/mp3diags pwd mkdir -p $(CURDIR)/debian/mp3diags/usr/bin cp bin/MP3Diags $(CURDIR)/debian/mp3diags/usr/bin mkdir -p $(CURDIR)/debian/mp3diags/usr/share/applications cp desktop/MP3Diags.desktop $(CURDIR)/debian/mp3diags/usr/share/applications mkdir -p $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/16x16/apps cp desktop/MP3Diags16.png $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/16x16/apps/MP3Diags.png mkdir -p $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/22x22/apps cp desktop/MP3Diags22.png $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/22x22/apps/MP3Diags.png mkdir -p $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/24x24/apps cp desktop/MP3Diags24.png $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/24x24/apps/MP3Diags.png mkdir -p $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/32x32/apps cp desktop/MP3Diags32.png $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/32x32/apps/MP3Diags.png mkdir -p $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/36x36/apps cp desktop/MP3Diags36.png $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/36x36/apps/MP3Diags.png mkdir -p $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/40x40/apps cp desktop/MP3Diags40.png $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/40x40/apps/MP3Diags.png mkdir -p $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/48x48/apps cp desktop/MP3Diags48.png $(CURDIR)/debian/mp3diags/usr/share/icons/hicolor/48x48/apps/MP3Diags.png # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot # dh_installdebconf dh_installdocs dh_installexamples dh_installmenu # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_installinit dh_installcron dh_installman dh_installinfo # dh_undocumented dh_installchangelogs dh_link dh_strip dh_compress dh_fixperms # dh_makeshlibs dh_installdeb # dh_perl dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install MP3Diags-1.0.12.079/package/deb/debian.changelog0000644000175000001440000004002512040502151017673 0ustar ciobiusersmp3diags (1.0.12.079) testing; urgency=low * Discogs fix -- Marian Ciobanu Sat, 20 Oct 2012 22:00:00 +0200 mp3diags (1.0.11.076) testing; urgency=low * made program compilable with GCC 4.7 -- Marian Ciobanu Fri, 11 May 2011 22:00:00 +0200 mp3diags (1.0.10.065) testing; urgency=low * updated Discogs API calls to current version -- Marian Ciobanu Sat, 31 Dec 2011 22:00:00 +0200 mp3diags (1.0.09.063) testing; urgency=low * made Discogs queries work again, after a Discogs API change * added close button for windows on Gnome 3 -- Marian Ciobanu Sat, 10 Sep 2011 22:00:00 +0200 mp3diags (1.0.08.053) testing; urgency=low * fixed crash when trying to save after error at startup * added branch support to build process -- Marian Ciobanu Sat, 28 May 2011 22:00:00 +0200 mp3diags (1.0.07.052) testing; urgency=low * fixed crash caused by invalid Lyrics tag * fixed assertion failure when opening the folder filter in Windows -- Marian Ciobanu Wed, 29 Dec 2010 22:00:00 +0200 mp3diags (1.0.06.051) testing; urgency=low * fixed crash caused by invalid Lyrics tag * fixed assertion failure when opening the folder filter in Windows -- Marian Ciobanu Sun, 04 Jul 2010 22:00:00 +0200 mp3diags (1.0.05.050) testing; urgency=low * fixed issue #23 (assertion failure) -- Marian Ciobanu Wed, 17 Mar 2010 22:00:00 +0200 mp3diags (1.0.04.049) testing; urgency=low * fixed crash triggered by invalid frame lengths in ID3V2 * fixed crash that occured when the backup directory couldn't be created -- Marian Ciobanu Sun, 07 Mar 2010 22:00:00 +0200 mp3diags (1.0.03.048) testing; urgency=low * fixed crash triggered by GEOB frames containing UTF-16 text -- Marian Ciobanu Fri, 29 Jan 2010 22:00:00 +0200 mp3diags (1.0.02.047) testing; urgency=low * fixed crash triggered by trying to repair broken ID3V2 tags that contain images * fixed crash that occurred when changing file names manually in the file renamer, without defining a pattern * fixed crash caused by unsynchronized ID3V2.4.0 frames that end with 0xff -- Marian Ciobanu Tue, 12 Jan 2010 22:00:00 +0200 mp3diags (1.0.01.046) testing; urgency=low * fixed crash that occurred when running on Qt 4.6 * fixed crash that occurred when changing song info in the tag editor if songs had images stored as BMP or anything else besides JPG or PNG -- Marian Ciobanu Fri, 11 Dec 2009 22:00:00 +0200 mp3diags (1.0.00.045) testing; urgency=low * wording changes to reflect non-beta status * pressing CTRL+C when viewing full-size images in the tag editor or in "Tag details" in the main window copies the image to the clipboard * added "Rating" and changed field order in "Tag details" to match the Tag editor -- Marian Ciobanu Sun, 29 Nov 2009 22:00:00 +0200 mp3diags (0.99.06.044) testing; urgency=low * fixed a crash in folder filter * fixed bug causing non-normalized files having any TXXX frame to appear normalized * case is ignored for file extension, so .Mp3 or .mP3 files are recognized * better support and more consistent handling for TXXX and text frames in ID3V2 * reduced number of locales by eliminating redundant ones * disabled CTRL+A selection in the main window * static link for serialization * added trace details for web downloads -- Marian Ciobanu Tue, 04 Nov 2009 22:00:00 +0200 mp3diags (0.99.06.043) testing; urgency=low * "Simple view" in file configuration * fixed crash on empty text frames in ID3V2 * generic binaries for Linux * BuildMp3Diags.hta detects VS version * documentation updates -- Marian Ciobanu Tue, 27 Oct 2009 22:00:00 +0200 mp3diags (0.99.06.042) testing; urgency=low * better support for binary frames in ID2V2.4.0 * fixed bug resulting in crash when files were modified in external tools * fixed bug resulting in crash when renaming files if a filter is applied * fixed bug resulting in crash when going to "Tag details" for files using Unicode in USLT (issue 40) * added option to include styles in Discogs info * added case-change option to the tag editor * better detection and notification for changed files before applying transformations or saving from the tag editor * file renamer allows file names to be changed manually * file renamer can use "duplicate" label for unrated songs * images shown for Lyrics tags * improved case-change transformation * removing images from the tag editor now works even for non-cover images -- Marian Ciobanu Tue, 20 Oct 2009 22:00:00 +0200 mp3diags (0.99.06.041) testing; urgency=low * brought documentation up to date * added test for ReplayGain info stored inside Id3V2 * failing to read text frames from files no longer causes crashes * fixed bug resulting in crash when 2 ID3V2 tags are present and "Discard invalid ID3V2 data" gets called * XML export now works when names contain double quotes * locale in export dialog * locale lists are now sorted * long text frames are now truncated when shown in the "File info" area * changed names and order for tabs under Config/Files * made transformation options work correctly in MSVC -- Marian Ciobanu Fri, 09 Oct 2009 22:00:00 +0200 mp3diags (0.99.06.040) testing; urgency=low * "Various Artists" support * all pictures are shown and can be viewed in full size in "Tag details" * all pictures from a file are shown in the tag editor * patterns in the tag editor may now be disabled * export as M3U or XML * better handling of text frames containing null characters * auto-size for the tag editor's "current file" area * better column widths in the tag editor * improved HTA for Windows build -- Marian Ciobanu Wed, 30 Sep 2009 22:00:00 +0200 mp3diags (0.99.05.038) testing; urgency=low * fixed bug introduced in 0.99.05.037 causing crashes when finding empty ID3V2 frames * new build process for Windows * 4th custom transf list now defaults to a "fix-all" approach -- Marian Ciobanu Wed, 23 Sep 2009 22:00:00 +0200 mp3diags (0.99.05.037) testing; urgency=low * fixes on right-click * UTF-8 strings recognized in ID3V2.3.0 * fixed bug 35 (assertion failure) * faster tracer * code compilable with VS 2008 (port by Sebastian Schuberth) -- Marian Ciobanu Thu, 17 Sep 2009 22:00:00 +0200 mp3diags (0.99.05.034) testing; urgency=low * drive labels shown in Windows * mp3gain can be started now if it's in a directory containing spaces * configurable invalid characters and replacement for file renamer * automatic check for new versions * text inside square, curly, and angle brackets removed from web queries * improved tracing code * no longer rescan the files if exiting tag editor without changes * replace non-alphanumeric chars with spaces in web queries (issue 2) * better sorting in the tag editor for albums with unusual track numbers * a default .ini name is generated in most cases * (probably) fixed an assert (not sure because couldn't reproduce it) * tracks without a track number are put at the end in the tag editor * let the user know about reporting support notes and about patterns * better detection of exceptions in threads * exceptions that propagate from slots are now caught * default "actions to be taken" no longer shown when applying transforms * file info for StreamWriter -- Marian Ciobanu Mon, 07 Sep 2009 22:00:00 +0200 mp3diags (0.99.05.033) testing; urgency=low * fixed crash in Windows when checking a whole drive * fixed crash when saving data from the tag editor * improved trace speed on Windows * fixed potential crash at startup * fixed crash when changing a file that is being used by other program * more details and better formatting in assert messages and trace files * MPEG2 Layer3 streams no longer show Support note * improved temporary file generation, which can result in faster transforms * F1 help now works for the first session dialog * smaller TABs in the "Tag details" area make "Other info" more readable * better HTML paragraph formatting -- Marian Ciobanu Wed, 02 Sep 2009 22:00:00 +0200 mp3diags (0.99.05.032) testing; urgency=low * restructured crash detector * fixed Windows issue with rectangles being shown instead of letters * Lyrics partial support * warning that may corrupt data * note about how to change selected files * HTML clean up -- Marian Ciobanu Sun, 23 Aug 2009 22:00:00 +0200 mp3diags (0.99.05.031) testing; urgency=low * crash detection * fixed small memory leak in config dialog * fixed small memory leak in the tag editor * content is shown for GEOB frames * .ID3 files are now loaded in addition to .MP3 * made the counter shown when applying transforms increment on new file (until now it was incremented for each transform) * "Various artists" no longer set as "artist" when downloading track info from MusicBrainz * fixed "current cell" in the tag editor (until now, when dragging the mouse to select several cells, the current cell was wrong, leading to setting values incorrectly * fixed a bug that didn't allow removal of the track number * slightly improved the normalizer, so a "busy" cursor is shown when the connection to the underlying process is lost (the program seems frozen, but it resumes after about 30 seconds) -- Marian Ciobanu Wed, 19 Aug 2009 22:00:00 +0200 mp3diags (0.99.05.030) testing; urgency=low * fixed a bug that caused the tag editor to reserve more space than needed even if the "fast save" option was turned off * fixed a bug that prevented removal of elements from lists * fixed a bug in the ID3V2 tag writer that prevented "Discard invalid ID3V2 data" and other transformations to properly work with ID3V2.4.0 tags that contain UTF8-encoded strings, resulting in a broken ID3V2.3.0 tag * file renamer now accepts patterns with no directory separators, in which case the renamed files are placed in the source directory * pattern dialogs now show the current line and column * fixed an assertion in the code that determines the file list * added tooltips for all the notes in the main file table * improved speed for "Discard invalid ID3V2 data" when no changes are done * transformation name included in the dialog that shows which file is currently processed * broken ID3V2 streams get removed when saving from the tag editor * the tag editor no longer triggers an assertion failure if non-default settings in the file section of the configuration dialog; (e.g. until now saving from the tag editor while original files weren't deleted resulted in this assertion failure) * fixed a bug in the "Change case for ID3V2 text frames" that resulted in a program crash if some fields were missing from the ID3V2 tag -- Marian Ciobanu Tue, 28 Jul 2009 22:00:00 +0200 mp3diags (0.99.05.029) testing; urgency=low * fast save in the tag editor * file renamer can work with the list of visible files instead of the current album if the user holds CTRL down when pressing the button * configurable visible transformations * new transform for keeping a single image, as front cover * new transform for removing ID3V1 * button to remove image files * improved paste in tag editor (it is possible to paste to multiple cells or to paste file names copied from file browsers) * configurable max image size * tooltips for the transformations menu * more checks + fixed error reporting in file renamer * "sessions" button visible by default for second and later sessions * directory filter no longer shows some directories that don't make sense * fixed loading images from current dir * fixed a bug in tag editor patterns that prevented patterns ending with a static text from working * fixed some bugs in the directory filter -- Marian Ciobanu Sun, 26 Jul 2009 22:00:00 +0200 mp3diags (0.99.04.026) testing; urgency=low * non-ASCII file names can now be seen on Windows * tag editor now looks at filter * USLT Lyrics inside ID3V2 are now shown * better alignment for text in note column header on Ubuntu * size grip on most dialogs * F1 help * files changed in the tag editor no longer show up in the main window if a filter is applied and they don't match the filter -- Marian Ciobanu Sat, 18 Jul 2009 22:00:00 +0200 mp3diags (0.99.03.022) testing; urgency=low * 2-letter labels * gradient grouping of notes * configurable colors * app no longer crashes when files are changed by external tools * tooltips are shown for the column headers in the file table * more consistent font handling -- Marian Ciobanu Fri, 10 Jul 2009 22:00:00 +0200 mp3diags (0.99.02.020) testing; urgency=low * file renamer now replaces invalid characters in file names * duration is now shown for audio streams * fixed assertion caused by files with too many streams * multiple ID3 stream remover no longer included by default in second list -- Marian Ciobanu Sun, 05 Jul 2009 22:00:00 +0200 mp3diags (0.99.02.018) testing; urgency=low * made -mt suffix default for Boost Serialization -- Marian Ciobanu Wed, 24 Jun 2009 22:00:00 +0200 mp3diags (0.99.02.017) testing; urgency=low * always use multithreaded Boost libraries (single-threaded ones may lead to crashes) * improved assert dialog; now it has more data, which can be copied and even emailed directly * the tag editor shows a warning in some cases when a user action would result in discarded images -- Marian Ciobanu Wed, 24 Jun 2009 15:00:00 +0200 mp3diags (0.99.02.016) testing; urgency=low * fixed an assertion failure that was triggered by an unsupported text encoding in APIC * added support for UTF8 text encoding in APIC * made the documentation look slightly better on IE6 -- Marian Ciobanu Sun, 21 Jun 2009 10:00:00 +0200 mp3diags (0.99.02.015) testing; urgency=low * made compilable on Fedora 11 and added Fedora 11 build * copying missing ID3V1 fields to ID3V2 no longer part of the default custom transformation list 2 -- Marian Ciobanu Sat, 20 Jun 2009 10:00:00 +0200 mp3diags (0.99.02.014) testing; urgency=low * the tag editor loads albums much faster than before; this is most visible when navigating to the next / previous album -- Marian Ciobanu Thu, 18 Jun 2009 10:00:00 +0200 mp3diags (0.99.02.012) testing; urgency=low * added support for UTF8 in ID3V240 * added maximize button to most windows in Windows (but could not get this to work with Gnome) * removed "What's this" button from most windows * now the main window shows the session name if more than 1 session was defined * now the main window shows up maximized in Gnome and Windows if it was maximized when it was closed * changed documentation links to point to new site, at SourceForge * minor documentation improvements -- Marian Ciobanu Sun, 14 Jun 2009 10:00:00 +0200 mp3diags (0.99.02.011) testing; urgency=low * added missing dependency for SVG icons * fixed a bug in "Save as ..." -- Marian Ciobanu Sat, 06 Jun 2009 10:00:00 +0200 mp3diags (0.99.02.010) testing; urgency=low * fixed a bug that could cause removal of audio data * fixed a bug that prevented single-image-saving from working -- Marian Ciobanu Thu, 04 Jun 2009 10:00:00 +0200 mp3diags (0.99.02.009) testing; urgency=low * Ubuntu binaries * minor UI tweaks -- Marian Ciobanu Wed, 03 Jun 2009 10:00:00 +0200 mp3diags (0.99.02.008) testing; urgency=low * improved font handling * minor UI tweaks -- Marian Ciobanu Mon, 25 May 2009 10:00:00 +0200 mp3diags (0.99.02.007) testing; urgency=low * initial version -- Marian Ciobanu Tue, 19 May 2009 10:00:00 +0200 MP3Diags-1.0.12.079/package/rpm/0000755000175000001440000000000012040502151014643 5ustar ciobiusersMP3Diags-1.0.12.079/package/rpm/MP3Diags.spec0000644000175000001440000005243212040502151017074 0ustar ciobiusersSummary: Tool for finding and fixing problems in MP3 files; includes a tagger %define version 1.0.12.079 %define branch %{nil} License: http://www.gnu.org/licenses/gpl-2.0.html Group: Applications/Multimedia Name: MP3Diags%{branch} #Prefix: /usr #Provides: MP3Diags Release: 1 Source: MP3Diags%{branch}-%{version}.tar.gz URL: http://mp3diags.sourceforge.net/ Version: %{version} BuildRoot: %{_tmppath}/%{name}-%{version}-build Packager: Ciobi #BuildRequires: libqt4-devel #BuildRequires: boost-devel # ??? ttt0 %if 0%{?suse_version} > 0000 Requires: libqt4-x11 BuildRequires: zlib-devel boost-devel libqt4-devel BuildRequires: update-desktop-files %endif %if 0%{?fedora} || 0%{?fedora_version} Requires: qt-x11 #BuildRequires: qt-devel qt-config #BuildRequires: qt-devel zlib-devel boost-devel-static gcc-c++ BuildRequires: qt-devel zlib-devel boost-devel boost-devel-static gcc-c++ %endif # this breaks the build for mandriva 2009.1: parseExpressionBoolean returns -1 %if 0%{?mandriva_version} >= 2009 #%if 0%{?mdkversion} >= 200900 BuildRequires: kdelibs4-devel #BuildRequires: libboost1.37.0-devel #BuildRequires: libboost-devel libboost-static-devel BuildRequires: boost-devel boost-static-devel BuildRequires: zlib-devel Requires: qt4-common %endif # related but probably something else: https://bugzilla.novell.com/show_bug.cgi?id=459337 or https://bugzilla.redhat.com/show_bug.cgi?id=456103 %description Finds problems in MP3 files and helps the user to fix many of them. Looks at both the audio part (VBR info, quality, normalization) and the tags containing track information (ID3.) Has a tag editor, which can download album information (including cover art) from MusicBrainz and Discogs, as well as paste data from the clipboard. Track information can also be extracted from a file's name. Another component is the file renamer, which can rename files based on the fields in their ID3V2 tag (artist, track number, album, genre, ...) %prep %setup -q %build ./AdjustMt.sh STATIC_SER #%if 0%{?mandriva_version} > 2006 #export PATH=/usr/lib/qt4/bin:$PATH #export QTDIR=%{_prefix}/lib/qt4/ #%endif %if 0%{?suse_version} qmake %endif %if 0%{?mandriva_version} >= 2009 #export PATH=/usr/lib/qt4/bin:$PATH #export QTDIR=%{_prefix}/lib/qt4/ #ls /usr/lib/qt4/bin #/usr/lib/qt4/bin/qmake qmake %endif %if 0%{?fedora} || 0%{?fedora_version} qmake-qt4 %endif make strip $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/bin/MP3Diags%{branch} %install # ttt1 perhaps look at http://doc.trolltech.com/4.3/qmake-variable-reference.html#installs and use INSTALLS += ... echo mkdir $RPM_BUILD_ROOT%{_bindir} mkdir -p $RPM_BUILD_ROOT%{_bindir} cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/bin/MP3Diags%{branch} $RPM_BUILD_ROOT%{_bindir} mkdir -p $RPM_BUILD_ROOT%{_datadir}/applications cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags%{branch}.desktop $RPM_BUILD_ROOT%{_datadir}/applications mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/16x16/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags16%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/16x16/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/22x22/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags22%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/22x22/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/24x24/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags24%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/24x24/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/32x32/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags32%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/32x32/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/36x36/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags36%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/36x36/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/40x40/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags40%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/40x40/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags48%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps/MP3Diags%{branch}.png #mkdir -p $RPM_BUILD_ROOT%{_bindir} #cp $RPM_BUILD_DIR/MP3Diags-%{version}/bin/MP3Diags $RPM_BUILD_ROOT%{_bindir} #mkdir -p $RPM_BUILD_ROOT%{_datadir}/applications #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags.desktop $RPM_BUILD_ROOT%{_datadir}/applications #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/16x16/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags16.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/16x16/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/22x22/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags22.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/22x22/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/24x24/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags24.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/24x24/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/32x32/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags32.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/32x32/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/36x36/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags36.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/36x36/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/40x40/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags40.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/40x40/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags48.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps/MP3Diags.png %if 0%{?suse_version} > 0000 %suse_update_desktop_file -n MP3Diags%{branch} #echo ================ SUSE ================ SUSE ================ %endif #error with suse_update_desktop_file -in MP3Diags , perhaps try suse_update_desktop_file -n -i MP3Diags %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %dir %{_datadir}/icons/hicolor %dir %{_datadir}/icons/hicolor/16x16 %dir %{_datadir}/icons/hicolor/16x16/apps %dir %{_datadir}/icons/hicolor/22x22 %dir %{_datadir}/icons/hicolor/22x22/apps %dir %{_datadir}/icons/hicolor/24x24 %dir %{_datadir}/icons/hicolor/24x24/apps %dir %{_datadir}/icons/hicolor/32x32 %dir %{_datadir}/icons/hicolor/32x32/apps %dir %{_datadir}/icons/hicolor/36x36 %dir %{_datadir}/icons/hicolor/36x36/apps %dir %{_datadir}/icons/hicolor/40x40 %dir %{_datadir}/icons/hicolor/40x40/apps %dir %{_datadir}/icons/hicolor/48x48 %dir %{_datadir}/icons/hicolor/48x48/apps %{_bindir}/MP3Diags%{branch} %{_datadir}/applications/MP3Diags%{branch}.desktop %{_datadir}/icons/hicolor/16x16/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/22x22/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/24x24/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/32x32/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/36x36/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/40x40/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/48x48/apps/MP3Diags%{branch}.png #?datadir (=/usr/share) #/usr/share/applications %changelog * Sat Oct 20 2012 Marian Ciobanu 1.0.12.079 - Discogs fix * Fri May 11 2012 Marian Ciobanu 1.0.11.076 - made program compilable with GCC 4.7 * Sat Dec 31 2011 Marian Ciobanu 1.0.10.065 - updated Discogs API calls to current version * Sat Sep 10 2011 Marian Ciobanu 1.0.09.063 - made Discogs queries work again, after a Discogs API change - added close button for windows on Gnome 3 * Sat May 28 2011 Marian Ciobanu 1.0.08.053 - fixed crash when trying to save after error at startup - added branch support to build process * Wed Dec 29 2010 Marian Ciobanu 1.0.07.052 - fixed crash in folder filter dialog - made project compilable on Fedora 13 and 14 * Sun Jul 04 2010 Marian Ciobanu 1.0.06.051 - fixed crash caused by invalid Lyrics tag - fixed assertion failure when opening the folder filter in Windows * Wed Mar 17 2010 Marian Ciobanu 1.0.05.050 - fixed issue #23 (assertion failure) * Sun Mar 07 2010 Marian Ciobanu 1.0.04.049 - fixed crash triggered by invalid frame lengths in ID3V2 - fixed crash that occured when the backup directory couldn't be created * Fri Jan 29 2010 Marian Ciobanu 1.0.03.048 - fixed crash triggered by GEOB frames containing UTF-16 text * Tue Jan 12 2010 Marian Ciobanu 1.0.02.047 - fixed crash triggered by trying to repair broken ID3V2 tags that contain images - fixed crash that occurred when changing file names manually in the file renamer, without defining a pattern - fixed crash caused by unsynchronized ID3V2.4.0 frames that end with 0xff * Fri Dec 11 2009 Marian Ciobanu 1.0.01.046 - fixed crash that occurred when running on Qt 4.6 - fixed crash that occurred when changing song info in the tag editor if songs had images stored as BMP or anything else besides JPG or PNG * Sun Nov 29 2009 Marian Ciobanu 1.0.00.045 - wording changes to reflect non-beta status - pressing CTRL+C when viewing full-size images in the tag editor or in "Tag details" in the main window copies the image to the clipboard - added "Rating" and changed field order in "Tag details" to match the Tag editor * Wed Nov 04 2009 Marian Ciobanu 0.99.06.044 - fixed a crash in folder filter - fixed bug causing non-normalized files having any TXXX frame to appear normalized - case is ignored for file extension, so .Mp3 or .mP3 files are recognized - better support and more consistent handling for TXXX and text frames in ID3V2 - reduced number of locales by eliminating redundant ones - disabled CTRL+A selection in the main window - static link for serialization - added trace details for web downloads * Tue Oct 27 2009 Marian Ciobanu 0.99.06.043 - "Simple view" in file configuration - fixed crash on empty text frames in ID3V2 - generic binaries for Linux - BuildMp3Diags.hta detects VS version - documentation updates * Tue Oct 20 2009 Marian Ciobanu 0.99.06.042 - better support for binary frames in ID2V2.4.0 - fixed bug resulting in crash when files were modified in external tools - fixed bug resulting in crash when renaming files if a filter is applied - fixed bug resulting in crash when going to "Tag details" for files using Unicode in USLT (issue 40) - added option to include styles in Discogs info - added case-change option to the tag editor - better detection and notification for changed files before applying transformations or saving from the tag editor - file renamer allows file names to be changed manually - file renamer can use "duplicate" label for unrated songs - images shown for Lyrics tags - improved case-change transformation - removing images from the tag editor now works even for non-cover images * Fri Oct 09 2009 Marian Ciobanu 0.99.06.041 - brought documentation up to date - added test for ReplayGain info stored inside Id3V2 - failing to read text frames from files no longer causes crashes - fixed bug resulting in crash when 2 ID3V2 tags are present and "Discard invalid ID3V2 data" gets called - XML export now works when names contain double quotes - locale in export dialog - locale lists are now sorted - long text frames are now truncated when shown in the "File info" area - changed names and order for tabs under Config/Files - made transformation options work correctly in MSVC * Wed Sep 30 2009 Marian Ciobanu 0.99.06.040 - "Various Artists" support - all pictures are shown and can be viewed in full size in "Tag details" - all pictures from a file are shown in the tag editor - patterns in the tag editor may now be disabled - export as M3U or XML - better handling of text frames containing null characters - auto-size for the tag editor's "current file" area - better column widths in the tag editor - improved HTA for Windows build * Wed Sep 23 2009 Marian Ciobanu 0.99.05.038 - fixed bug introduced in 0.99.05.037 causing crashes when finding empty ID3V2 frames - new build process for Windows - 4th custom transf list now defaults to a "fix-all" approach * Thu Sep 17 2009 Marian Ciobanu 0.99.05.037 - fixes on right-click - UTF-8 strings recognized in ID3V2.3.0 - fixed bug 35 (assertion failure) - faster tracer - code compilable with VS 2008 (port by Sebastian Schuberth) * Mon Sep 07 2009 Marian Ciobanu 0.99.05.034 - drive labels shown in Windows - mp3gain can be started now if it's in a directory containing spaces - configurable invalid characters and replacement for file renamer - automatic check for new versions - text inside square, curly, and angle brackets removed from web queries - improved tracing code - no longer rescan the files if exiting tag editor without changes - replace non-alphanumeric chars with spaces in web queries (issue 2) - better sorting in the tag editor for albums with unusual track numbers - a default .ini name is generated in most cases - (probably) fixed an assert (not sure because couldn't reproduce it) - tracks without a track number are put at the end in the tag editor - let the user know about reporting support notes and about patterns - better detection of exceptions in threads - exceptions that propagate from slots are now caught - default "actions to be taken" no longer shown when applying transforms - file info for StreamWriter * Wed Sep 02 2009 Marian Ciobanu 0.99.05.033 - fixed crash in Windows when checking a whole drive - fixed crash when saving data from the tag editor - improved trace speed on Windows - fixed potential crash at startup - fixed crash when changing a file that is being used by other program - more details and better formatting in assert messages and trace files - MPEG2 Layer3 streams no longer show Support note - improved temporary file generation, which can result in faster transforms - F1 help now works for the first session dialog - smaller TABs in the "Tag details" area make "Other info" more readable - better HTML paragraph formatting * Sun Aug 23 2009 Marian Ciobanu 0.99.05.032 - restructured crash detector - fixed Windows issue with rectangles being shown instead of letters - Lyrics partial support - warning that may corrupt data - note about how to change selected files - HTML clean up * Wed Aug 19 2009 Marian Ciobanu 0.99.05.031 - crash detection - fixed small memory leak in config dialog - fixed small memory leak in the tag editor - content is shown for GEOB frames - .ID3 files are now loaded in addition to .MP3 - made the counter shown when applying transforms increment on new file(until now it was incremented for each transform) - "Various artists" no longer set as "artist" when downloading track info from MusicBrainz - fixed "current cell" in the tag editor (until now, when dragging the mouse to select several cells, the current cell was wrong, leading to setting values incorrectly - fixed a bug that didn't allow removal of the track number - slightly improved the normalizer, so a "busy" cursor is shown when the connection to the underlying process is lost (the program seems frozen, but it resumes after about 30 seconds) * Tue Jul 28 2009 Marian Ciobanu 0.99.05.030 - fixed a bug that caused the tag editor to reserve more space than needed even if the "fast save" option was turned off - fixed a bug that prevented removal of elements from lists - fixed a bug in the ID3V2 tag writer that prevented "Discard invalid ID3V2 data" and other transformations to properly work with ID3V2.4.0 tags that contain UTF8-encoded strings, resulting in a broken ID3V2.3.0 tag - file renamer now accepts patterns with no directory separators, in which case the renamed files are placed in the source directory - pattern dialogs now show the current line and column - fixed an assertion in the code that determines the file list - added tooltips for all the notes in the main file table - improved speed for "Discard invalid ID3V2 data" when no changes are done - transformation name included in the dialog that shows which file is currently processed - broken ID3V2 streams get removed when saving from the tag editor - the tag editor no longer triggers an assertion failure if non-default settings in the file section of the configuration dialog; (e.g. until now saving from the tag editor while original files weren't deleted resulted in this assertion failure) - fixed a bug in the "Change case for ID3V2 text frames" that resulted in a program crash if some fields were missing from the ID3V2 tag * Sun Jul 26 2009 Marian Ciobanu 0.99.05.029 - fast save in the tag editor - file renamer can work with the list of visible files instead of the current album if the user holds CTRL down when pressing the button - configurable visible transformations - new transform for keeping a single image, as front cover - new transform for removing ID3V1 - button to remove image files - improved paste in tag editor (it is possible to paste to multiple cells or to paste file names copied from file browsers) - configurable max image size - tooltips for the transformations menu - more checks + fixed error reporting in file renamer - "sessions" button visible by default for second and later sessions - directory filter no longer shows some directories that don't make sense - fixed loading images from current dir - fixed a bug in tag editor patterns that prevented patterns ending with a static text from working - fixed some bugs in the directory filter * Sat Jul 18 2009 Marian Ciobanu 0.99.04.026 - non-ASCII file names can now be seen on Windows - tag editor now looks at filter - USLT Lyrics inside ID3V2 are now shown - better alignment for text in note column header on Ubuntu - size grip on most dialogs - F1 help - files changed in the tag editor no longer show up in the main window if a filter is applied and they don't match the filter * Fri Jul 10 2009 Marian Ciobanu 0.99.03.022 - 2-letter labels - gradient grouping of notes - configurable colors - app no longer crashes when files are changed by external tools - tooltips are shown for the column headers in the file table - more consistent font handling * Sun Jul 05 2009 Marian Ciobanu 0.99.02.020 - file renamer now replaces invalid characters in file names - duration is now shown for audio streams - fixed assertion caused by files with too many streams - multiple ID3 stream remover no longer included by default in second list - some changes to the .spec file in the hope it will work on Mandriva * Sun Jul 05 2009 Marian Ciobanu 0.99.02.020 - file renamer now replaces invalid characters in file names - duration is now shown for audio streams - fixed assertion caused by files with too many streams - multiple ID3 stream remover no longer included by default in second list - some changes to the .spec file in the hope it will work on Mandriva * Wed Jun 24 2009 Marian Ciobanu 0.99.02.018 - made -mt suffix default for Boost Serialization * Wed Jun 24 2009 Marian Ciobanu 0.99.02.017 - always use multithreaded libraries (single-threaded ones may lead to crashes) - improved assert dialog; now it has more data, which can be copied and even emailed directly - the tag editor shows a warning in some cases when a user action would result in discarded images * Sun Jun 21 2009 Marian Ciobanu 0.99.02.016 - fixed an assertion failure that was triggered by an unsupported text encoding in APIC - added support for UTF8 text encoding in APIC - made the documentation look slightly better on IE6 * Sat Jun 20 2009 Marian Ciobanu 0.99.02.015 - made compilable on Fedora 11 and added Fedora 11 build - copying missing ID3V1 fields to ID3V2 no longer part of the default custom transformation list 2 * Thu Jun 18 2009 Marian Ciobanu 0.99.02.014 - the tag editor loads albums much faster than before; this is most visible when navigating to the next / previous album * Sun Jun 14 2009 Marian Ciobanu 0.99.02.012 - added support for UTF8 in ID3V240 - added maximize button to most windows in Windows (but could not get this to work with Gnome) - removed "What's this" button from most windows - now the main window shows the session name if more than 1 session was defined - now the main window shows up maximized in Gnome and Windows if it was maximized when it was closed - changed documentation links to point to new site, at SourceForge - minor documentation improvements * Sat Jun 06 2009 Marian Ciobanu 0.99.02.011 - added missing dependency for SVG icons - fixed a bug in "Save as ..." * Thu Jun 04 2009 Marian Ciobanu 0.99.02.010 - fixed a bug that could cause removal of audio data - fixed a bug that prevented single-image-saving from working * Wed Jun 03 2009 Marian Ciobanu 0.99.02.009 - Ubuntu binaries - minor UI tweaks * Mon May 25 2009 Marian Ciobanu 0.99.02.008 - improved font handling - minor UI tweaks * Tue May 19 2009 Marian Ciobanu 0.99.02.007 - initial version MP3Diags-1.0.12.079/package/rpm/MP3Diags-Mandriva_2009.1.spec0000644000175000001440000005112012040502151021435 0ustar ciobiusersSummary: Tool for finding and fixing problems in MP3 files; includes a tagger %define version 1.0.12.079 %define branch %{nil} License: http://www.gnu.org/licenses/gpl-2.0.html Group: Applications/Multimedia Name: MP3Diags%{branch} #Prefix: /usr #Provides: MP3Diags Release: 1 Source: MP3Diags%{branch}-%{version}.tar.gz URL: http://mp3diags.sourceforge.net/ Version: %{version} BuildRoot: %{_tmppath}/%{name}-%{version}-build Packager: Ciobi #BuildRequires: libqt4-devel #BuildRequires: boost-devel # ??? ttt0 # this breaks the build for mandriva 2009.1: parseExpressionBoolean returns -1 #%if 0%{?mandriva_version} >= 2009 #%if 0%{?mdkversion} >= 200900 BuildRequires: kdelibs4-devel #BuildRequires: libboost1.37.0-devel #BuildRequires: libboost-devel libboost-static-devel-1.38.0 BuildRequires: boost-devel boost-static-devel BuildRequires: zlib-devel Requires: qt4-common #%endif # related but probably something else: https://bugzilla.novell.com/show_bug.cgi?id=459337 or https://bugzilla.redhat.com/show_bug.cgi?id=456103 %description Finds problems in MP3 files and helps the user to fix many of them. Looks at both the audio part (VBR info, quality, normalization) and the tags containing track information (ID3.) Has a tag editor, which can download album information (including cover art) from MusicBrainz and Discogs, as well as paste data from the clipboard. Track information can also be extracted from a file's name. Another component is the file renamer, which can rename files based on the fields in their ID3V2 tag (artist, track number, album, genre, ...) %prep %setup -q %build ./AdjustMt.sh STATIC_SER #%if 0%{?mandriva_version} > 2006 #export PATH=/usr/lib/qt4/bin:$PATH #export QTDIR=%{_prefix}/lib/qt4/ #%endif #%if 0%{?mandriva_version} >= 2009 #export PATH=/usr/lib/qt4/bin:$PATH #export QTDIR=%{_prefix}/lib/qt4/ #ls /usr/lib/qt4/bin #/usr/lib/qt4/bin/qmake qmake #%endif make strip $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/bin/MP3Diags%{branch} %install # ttt1 perhaps look at http://doc.trolltech.com/4.3/qmake-variable-reference.html#installs and use INSTALLS += ... echo mkdir $RPM_BUILD_ROOT%{_bindir} mkdir -p $RPM_BUILD_ROOT%{_bindir} cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/bin/MP3Diags%{branch} $RPM_BUILD_ROOT%{_bindir} mkdir -p $RPM_BUILD_ROOT%{_datadir}/applications cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags%{branch}.desktop $RPM_BUILD_ROOT%{_datadir}/applications mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/16x16/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags16%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/16x16/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/22x22/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags22%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/22x22/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/24x24/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags24%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/24x24/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/32x32/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags32%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/32x32/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/36x36/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags36%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/36x36/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/40x40/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags40%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/40x40/apps/MP3Diags%{branch}.png mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps cp $RPM_BUILD_DIR/MP3Diags%{branch}-%{version}/desktop/MP3Diags48%{branch}.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps/MP3Diags%{branch}.png #mkdir -p $RPM_BUILD_ROOT%{_bindir} #cp $RPM_BUILD_DIR/MP3Diags-%{version}/bin/MP3Diags $RPM_BUILD_ROOT%{_bindir} #mkdir -p $RPM_BUILD_ROOT%{_datadir}/applications #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags.desktop $RPM_BUILD_ROOT%{_datadir}/applications #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/16x16/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags16.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/16x16/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/22x22/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags22.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/22x22/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/24x24/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags24.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/24x24/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/32x32/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags32.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/32x32/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/36x36/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags36.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/36x36/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/40x40/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags40.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/40x40/apps/MP3Diags.png #%dir $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps #cp $RPM_BUILD_DIR/MP3Diags-%{version}/desktop/MP3Diags48.png $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps/MP3Diags.png %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %dir %{_datadir}/icons/hicolor %dir %{_datadir}/icons/hicolor/16x16 %dir %{_datadir}/icons/hicolor/16x16/apps %dir %{_datadir}/icons/hicolor/22x22 %dir %{_datadir}/icons/hicolor/22x22/apps %dir %{_datadir}/icons/hicolor/24x24 %dir %{_datadir}/icons/hicolor/24x24/apps %dir %{_datadir}/icons/hicolor/32x32 %dir %{_datadir}/icons/hicolor/32x32/apps %dir %{_datadir}/icons/hicolor/36x36 %dir %{_datadir}/icons/hicolor/36x36/apps %dir %{_datadir}/icons/hicolor/40x40 %dir %{_datadir}/icons/hicolor/40x40/apps %dir %{_datadir}/icons/hicolor/48x48 %dir %{_datadir}/icons/hicolor/48x48/apps %{_bindir}/MP3Diags%{branch} %{_datadir}/applications/MP3Diags%{branch}.desktop %{_datadir}/icons/hicolor/16x16/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/22x22/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/24x24/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/32x32/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/36x36/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/40x40/apps/MP3Diags%{branch}.png %{_datadir}/icons/hicolor/48x48/apps/MP3Diags%{branch}.png #?datadir (=/usr/share) #/usr/share/applications %changelog * Sat Oct 20 2012 Marian Ciobanu 1.0.12.079 - Discogs fix * Fri May 11 2012 Marian Ciobanu 1.0.11.076 - made program compilable with GCC 4.7 * Sat Dec 31 2011 Marian Ciobanu 1.0.10.065 - updated Discogs API calls to current version * Sat Sep 10 2011 Marian Ciobanu 1.0.09.063 - made Discogs queries work again, after a Discogs API change - added close button for windows on Gnome 3 * Sat May 28 2011 Marian Ciobanu 1.0.08.053 - fixed crash when trying to save after error at startup - added branch support to build process * Wed Dec 29 2010 Marian Ciobanu 1.0.07.052 - fixed crash in folder filter dialog - made project compilable on Fedora 13 and 14 * Sun Jul 04 2010 Marian Ciobanu 1.0.06.051 - fixed crash caused by invalid Lyrics tag - fixed assertion failure when opening the folder filter in Windows * Wed Mar 17 2010 Marian Ciobanu 1.0.05.050 - fixed issue #23 (assertion failure) * Sun Mar 07 2010 Marian Ciobanu 1.0.04.049 - fixed crash triggered by invalid frame lengths in ID3V2 - fixed crash that occured when the backup directory couldn't be created * Fri Jan 29 2010 Marian Ciobanu 1.0.03.048 - fixed crash triggered by GEOB frames containing UTF-16 text * Tue Jan 12 2010 Marian Ciobanu 1.0.02.047 - fixed crash triggered by trying to repair broken ID3V2 tags that contain images - fixed crash that occurred when changing file names manually in the file renamer, without defining a pattern - fixed crash caused by unsynchronized ID3V2.4.0 frames that end with 0xff * Fri Dec 11 2009 Marian Ciobanu 1.0.01.046 - fixed crash that occurred when running on Qt 4.6 - fixed crash that occurred when changing song info in the tag editor if songs had images stored as BMP or anything else besides JPG or PNG * Sun Nov 29 2009 Marian Ciobanu 1.0.00.045 - wording changes to reflect non-beta status - pressing CTRL+C when viewing full-size images in the tag editor or in "Tag details" in the main window copies the image to the clipboard - added "Rating" and changed field order in "Tag details" to match the Tag editor * Wed Nov 04 2009 Marian Ciobanu 0.99.06.044 - fixed a crash in folder filter - fixed bug causing non-normalized files having any TXXX frame to appear normalized - case is ignored for file extension, so .Mp3 or .mP3 files are recognized - better support and more consistent handling for TXXX and text frames in ID3V2 - reduced number of locales by eliminating redundant ones - disabled CTRL+A selection in the main window - static link for serialization - added trace details for web downloads * Tue Oct 27 2009 Marian Ciobanu 0.99.06.043 - "Simple view" in file configuration - fixed crash on empty text frames in ID3V2 - generic binaries for Linux - BuildMp3Diags.hta detects VS version - documentation updates * Tue Oct 20 2009 Marian Ciobanu 0.99.06.042 - better support for binary frames in ID2V2.4.0 - fixed bug resulting in crash when files were modified in external tools - fixed bug resulting in crash when renaming files if a filter is applied - fixed bug resulting in crash when going to "Tag details" for files using Unicode in USLT (issue 40) - added option to include styles in Discogs info - added case-change option to the tag editor - better detection and notification for changed files before applying transformations or saving from the tag editor - file renamer allows file names to be changed manually - file renamer can use "duplicate" label for unrated songs - images shown for Lyrics tags - improved case-change transformation - removing images from the tag editor now works even for non-cover images * Fri Oct 09 2009 Marian Ciobanu 0.99.06.041 - brought documentation up to date - added test for ReplayGain info stored inside Id3V2 - failing to read text frames from files no longer causes crashes - fixed bug resulting in crash when 2 ID3V2 tags are present and "Discard invalid ID3V2 data" gets called - XML export now works when names contain double quotes - locale in export dialog - locale lists are now sorted - long text frames are now truncated when shown in the "File info" area - changed names and order for tabs under Config/Files - made transformation options work correctly in MSVC * Wed Sep 30 2009 Marian Ciobanu 0.99.06.040 - "Various Artists" support - all pictures are shown and can be viewed in full size in "Tag details" - all pictures from a file are shown in the tag editor - patterns in the tag editor may now be disabled - export as M3U or XML - better handling of text frames containing null characters - auto-size for the tag editor's "current file" area - better column widths in the tag editor - improved HTA for Windows build * Wed Sep 23 2009 Marian Ciobanu 0.99.05.038 - fixed bug introduced in 0.99.05.037 causing crashes when finding empty ID3V2 frames - new build process for Windows - 4th custom transf list now defaults to a "fix-all" approach * Thu Sep 17 2009 Marian Ciobanu 0.99.05.037 - fixes on right-click - UTF-8 strings recognized in ID3V2.3.0 - fixed bug 35 (assertion failure) - faster tracer - code compilable with VS 2008 (port by Sebastian Schuberth) * Mon Sep 07 2009 Marian Ciobanu 0.99.05.034 - drive labels shown in Windows - mp3gain can be started now if it's in a directory containing spaces - configurable invalid characters and replacement for file renamer - automatic check for new versions - text inside square, curly, and angle brackets removed from web queries - improved tracing code - no longer rescan the files if exiting tag editor without changes - replace non-alphanumeric chars with spaces in web queries (issue 2) - better sorting in the tag editor for albums with unusual track numbers - a default .ini name is generated in most cases - (probably) fixed an assert (not sure because couldn't reproduce it) - tracks without a track number are put at the end in the tag editor - let the user know about reporting support notes and about patterns - better detection of exceptions in threads - exceptions that propagate from slots are now caught - default "actions to be taken" no longer shown when applying transforms - file info for StreamWriter * Wed Sep 02 2009 Marian Ciobanu 0.99.05.033 - fixed crash in Windows when checking a whole drive - fixed crash when saving data from the tag editor - improved trace speed on Windows - fixed potential crash at startup - fixed crash when changing a file that is being used by other program - more details and better formatting in assert messages and trace files - MPEG2 Layer3 streams no longer show Support note - improved temporary file generation, which can result in faster transforms - F1 help now works for the first session dialog - smaller TABs in the "Tag details" area make "Other info" more readable - better HTML paragraph formatting * Sun Aug 23 2009 Marian Ciobanu 0.99.05.032 - restructured crash detector - fixed Windows issue with rectangles being shown instead of letters - Lyrics partial support - warning that may corrupt data - note about how to change selected files - HTML clean up * Wed Aug 19 2009 Marian Ciobanu 0.99.05.031 - crash detection - fixed small memory leak in config dialog - fixed small memory leak in the tag editor - content is shown for GEOB frames - .ID3 files are now loaded in addition to .MP3 - made the counter shown when applying transforms increment on new file(until now it was incremented for each transform) - "Various artists" no longer set as "artist" when downloading track info from MusicBrainz - fixed "current cell" in the tag editor (until now, when dragging the mouse to select several cells, the current cell was wrong, leading to setting values incorrectly - fixed a bug that didn't allow removal of the track number - slightly improved the normalizer, so a "busy" cursor is shown when the connection to the underlying process is lost (the program seems frozen, but it resumes after about 30 seconds) * Tue Jul 28 2009 Marian Ciobanu 0.99.05.030 - fixed a bug that caused the tag editor to reserve more space than needed even if the "fast save" option was turned off - fixed a bug that prevented removal of elements from lists - fixed a bug in the ID3V2 tag writer that prevented "Discard invalid ID3V2 data" and other transformations to properly work with ID3V2.4.0 tags that contain UTF8-encoded strings, resulting in a broken ID3V2.3.0 tag - file renamer now accepts patterns with no directory separators, in which case the renamed files are placed in the source directory - pattern dialogs now show the current line and column - fixed an assertion in the code that determines the file list - added tooltips for all the notes in the main file table - improved speed for "Discard invalid ID3V2 data" when no changes are done - transformation name included in the dialog that shows which file is currently processed - broken ID3V2 streams get removed when saving from the tag editor - the tag editor no longer triggers an assertion failure if non-default settings in the file section of the configuration dialog; (e.g. until now saving from the tag editor while original files weren't deleted resulted in this assertion failure) - fixed a bug in the "Change case for ID3V2 text frames" that resulted in a program crash if some fields were missing from the ID3V2 tag * Sun Jul 26 2009 Marian Ciobanu 0.99.05.029 - fast save in the tag editor - file renamer can work with the list of visible files instead of the current album if the user holds CTRL down when pressing the button - configurable visible transformations - new transform for keeping a single image, as front cover - new transform for removing ID3V1 - button to remove image files - improved paste in tag editor (it is possible to paste to multiple cells or to paste file names copied from file browsers) - configurable max image size - tooltips for the transformations menu - more checks + fixed error reporting in file renamer - "sessions" button visible by default for second and later sessions - directory filter no longer shows some directories that don't make sense - fixed loading images from current dir - fixed a bug in tag editor patterns that prevented patterns ending with a static text from working - fixed some bugs in the directory filter * Sat Jul 18 2009 Marian Ciobanu 0.99.04.026 - non-ASCII file names can now be seen on Windows - tag editor now looks at filter - USLT Lyrics inside ID3V2 are now shown - better alignment for text in note column header on Ubuntu - size grip on most dialogs - F1 help - files changed in the tag editor no longer show up in the main window if a filter is applied and they don't match the filter * Fri Jul 10 2009 Marian Ciobanu 0.99.03.022 - 2-letter labels - gradient grouping of notes - configurable colors - app no longer crashes when files are changed by external tools - tooltips are shown for the column headers in the file table - more consistent font handling * Sun Jul 05 2009 Marian Ciobanu 0.99.02.020 - file renamer now replaces invalid characters in file names - duration is now shown for audio streams - fixed assertion caused by files with too many streams - multiple ID3 stream remover no longer included by default in second list - some changes to the .spec file in the hope it will work on Mandriva * Sun Jul 05 2009 Marian Ciobanu 0.99.02.020 - file renamer now replaces invalid characters in file names - duration is now shown for audio streams - fixed assertion caused by files with too many streams - multiple ID3 stream remover no longer included by default in second list - some changes to the .spec file in the hope it will work on Mandriva * Wed Jun 24 2009 Marian Ciobanu 0.99.02.018 - made -mt suffix default for Boost Serialization * Wed Jun 24 2009 Marian Ciobanu 0.99.02.017 - always use multithreaded libraries (single-threaded ones may lead to crashes) - improved assert dialog; now it has more data, which can be copied and even emailed directly - the tag editor shows a warning in some cases when a user action would result in discarded images * Sun Jun 21 2009 Marian Ciobanu 0.99.02.016 - fixed an assertion failure that was triggered by an unsupported text encoding in APIC - added support for UTF8 text encoding in APIC - made the documentation look slightly better on IE6 * Sat Jun 20 2009 Marian Ciobanu 0.99.02.015 - made compilable on Fedora 11 and added Fedora 11 build - copying missing ID3V1 fields to ID3V2 no longer part of the default custom transformation list 2 * Thu Jun 18 2009 Marian Ciobanu 0.99.02.014 - the tag editor loads albums much faster than before; this is most visible when navigating to the next / previous album * Sun Jun 14 2009 Marian Ciobanu 0.99.02.012 - added support for UTF8 in ID3V240 - added maximize button to most windows in Windows (but could not get this to work with Gnome) - removed "What's this" button from most windows - now the main window shows the session name if more than 1 session was defined - now the main window shows up maximized in Gnome and Windows if it was maximized when it was closed - changed documentation links to point to new site, at SourceForge - minor documentation improvements * Sat Jun 06 2009 Marian Ciobanu 0.99.02.011 - added missing dependency for SVG icons - fixed a bug in "Save as ..." * Thu Jun 04 2009 Marian Ciobanu 0.99.02.010 - fixed a bug that could cause removal of audio data - fixed a bug that prevented single-image-saving from working * Wed Jun 03 2009 Marian Ciobanu 0.99.02.009 - Ubuntu binaries - minor UI tweaks * Mon May 25 2009 Marian Ciobanu 0.99.02.008 - improved font handling - minor UI tweaks * Tue May 19 2009 Marian Ciobanu 0.99.02.007 - initial version MP3Diags-1.0.12.079/license.lgpl-2.1.txt0000644000175000001440000005664411203001247016107 0ustar ciobiusersGNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: * a) The modified work must itself be a software library. * b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. * c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. * d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: * a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) * b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. * c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. * d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. * e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: * a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. * b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. MP3Diags-1.0.12.079/license.boost.txt0000644000175000001440000000247211203001725015770 0ustar ciobiusersBoost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. MP3Diags-1.0.12.079/Uninstall.sh0000755000175000001440000000101411570446137015000 0ustar ciobiusers#!/bin/bash # #ttt1 only works for one user, but it's likely that this is the case when it's most needed BranchSlash=`cat branch.txt` BranchDash=`echo "$BranchSlash" | sed 's#/#-#'` exe=MP3Diags$BranchDash /usr/local/bin/$exe /u sudo rm /usr/local/bin/$exe rm ~/.config/Ciobi/$exe.conf echo echo "If other users started MP3 Diags as well, they will have to remove their configuration file manually (it\'s ~/.config/Ciobi/Mp3Diags.conf)" echo "Sessions files (.ini and associated .dat) can only be removed manually" echo MP3Diags-1.0.12.079/Install.sh0000755000175000001440000000072511570446123014440 0ustar ciobiusers#!/bin/bash # # Tested on several systems only # ttt1 Quite likely this needs changes to work with other distros and / or versions bash ./AdjustMt.sh #exit 1 QMake=qmake if [ -f /etc/fedora-release ] ; then QMake=qmake-qt4 fi $QMake if [ $? -ne 0 ] ; then exit 1 ; fi make if [ $? -ne 0 ] ; then exit 1 ; fi BranchSlash=`cat branch.txt` BranchDash=`echo "$BranchSlash" | sed 's#/#-#'` exe=MP3Diags$BranchDash strip bin/$exe sudo cp bin/$exe /usr/local/bin MP3Diags-1.0.12.079/AdjustMt.sh0000755000175000001440000000206611506601662014565 0ustar ciobiusers#!/bin/bash # # corrects src/src.pro, so it uses the right serialization library # if $1 is STATIC_SER, it tries to do link Boost Ser statically; if it can't, it reverts to dynamic linking #if lib $1 exists changes src/src.pro and terminates the script function tryLib { rm -f -r tstMt mkdir tstMt echo "int main() {}" > tstMt/a.cpp g++ tstMt/a.cpp -l$1 -o tstMt/a.out 2> /dev/null libExists=$? #echo $noMt rm -f -r tstMt if [ $libExists -eq 0 ] ; then cat src/src.pro | sed 's%.*boost_serialization.*% -l'$1% > src/src.pro1 mv -f src/src.pro1 src/src.pro echo Serialization Library set as $1 exit 0 fi echo Serialization Library $1 not found #return $libExists } if [[ "STATIC_SER" == $1 ]] ; then tryLib :libboost_serialization-mt.a tryLib :libboost_serialization.a # ttt0 not sure if this should be considered tryLib boost_serialization-mt tryLib boost_serialization else tryLib boost_serialization-mt tryLib boost_serialization fi echo Boost Serialization not found MP3Diags-1.0.12.079/BuildBz2.sh0000755000175000001440000000213612040502151014430 0ustar ciobiusers#!/bin/bash # # Builds MP3 Diags linking Boost Serialization statically, for creation of "generic" binaries # # Tested on several systems only # ttt1 Quite likely this needs changes to work with other distros and / or versions bash ./AdjustMt.sh STATIC_SER #cat src/src.pro | grep 'lboost_serialization' > /dev/null #if [ $? -eq 0 ] ; then # we don't want to change a file that was already changed # cat src/src.pro | sed -e 's%lboost_serialization-mt$%l:libboost_serialization-mt.a%' -e 's%lboost_serialization$%l:libboost_serialization.a%' > src/src.pro1 # mv -f src/src.pro1 src/src.pro # echo "switched to static linking" #else # echo "static linking already set up" #fi #exit 1 QMake=qmake if [ -f /etc/fedora-release ] ; then QMake=qmake-qt4 fi $QMake if [ $? -ne 0 ] ; then exit 1 ; fi make if [ $? -ne 0 ] ; then exit 1 ; fi BranchSlash=`cat branch.txt` BranchDash=`echo "$BranchSlash" | sed 's#/#-#'` exe=MP3Diags$BranchDash strip bin/$exe Cpu=`uname -m` cd bin NewName=$exe-Linux-$Cpu-1.0.12.079 mv $exe $NewName tar -c $NewName | bzip2 > $NewName.tar.bz2 mv $NewName $exe cd .. MP3Diags-1.0.12.079/license.gplv2.txt0000644000175000001440000004235211107241710015700 0ustar ciobiusersGNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. MP3Diags-1.0.12.079/CMake-VS2008-Win32.cmd0000644000175000001440000000040111256451406015670 0ustar ciobiusers@echo off : (Re-)create an empty output directory. rmdir /s /q VS2008-Win32 2> nul mkdir VS2008-Win32 2> nul : Generate the project files in the output directory. pushd VS2008-Win32 cmake -G "Visual Studio 9 2008" .. if errorlevel 1 pause popd MP3Diags-1.0.12.079/license.lgplv3.txt0000644000175000001440000001645411107241731016064 0ustar ciobiusersGNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, “this License” refers to version 3 of the GNU Lesser General Public License, and the “GNU GPL” refers to version 3 of the GNU General Public License. “The Library” refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An “Application” is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A “Combined Work” is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the “Linked Version”. The “Minimal Corresponding Source” for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The “Corresponding Application Code” for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: * a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or * b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: * a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. * b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: * a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. * b) Accompany the Combined Work with a copy of the GNU GPL and this license document. * c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. * d) Do one of the following: o 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. o 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. * e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: * a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. * b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
If you didn't already, it's probably a good idea to take a look at the MP3 introduction; while it won't turn somebody who knows nothing about MP3s into an expert (BTW, I'm not seeing myself as an MP3 expert), it puts things into MP3 Diags' perspective.