From 02b5d8b4b7e204e046d435a188eb00ea0bf4649e Mon Sep 17 00:00:00 2001 From: Nils <> Date: Sun, 24 Mar 2019 01:00:16 +0100 Subject: [PATCH] commit as backup --- .gitignore | 1 + CHANGELOG | 2 + LICENSE | 674 + configure | 5 + desktop/desktop.desktop | 13 + desktop/icon256x256.png | Bin 0 -> 680 bytes desktop/icon32x32.png | Bin 0 -> 680 bytes documentation/LICENSE | 430 + documentation/README.txt | 7 + documentation/build-documentation.sh | 18 + documentation/english.part.adoc | 5 + documentation/german.part.adoc | 5 + engine/__init__.py | 31 + engine/api.py | 2314 ++++ engine/block.py | 331 + engine/config.py | 56 + engine/cursor.py | 142 + engine/graphtracks.py | 1347 ++ engine/items.py | 2812 ++++ engine/lilypond.py | 142 + engine/main.py | 1070 ++ engine/oldmidi.py | 52 + engine/resources/LICENSE | 1 + engine/resources/lilypondTemplate/default.ly | 105 + engine/resources/lilypondTemplate/minimal.ly | 17 + engine/resources/normal.wav | Bin 0 -> 133692 bytes engine/resources/stressed.wav | Bin 0 -> 106120 bytes engine/track.py | 1161 ++ laborejo2 | 9 + midiinput/stepmidiinput.py | 103 + qtgui/__init__.py | 0 qtgui/conductor.py | 635 + qtgui/constantsAndConfigs.py | 177 + qtgui/cursor.py | 242 + qtgui/designer/clefs.ui | 49 + qtgui/designer/mainwindow.py | 956 ++ qtgui/designer/mainwindow.ui | 1675 +++ qtgui/designer/tickWidget.py | 99 + qtgui/designer/tickWidget.ui | 266 + qtgui/designer/trackWidget.py | 491 + qtgui/designer/trackWidget.ui | 868 ++ qtgui/graphs.py | 571 + qtgui/items.py | 920 ++ qtgui/mainwindow.py | 200 + qtgui/menu.py | 570 + qtgui/resources.py | 10728 ++++++++++++++++ qtgui/resources/aboutlogo.png | Bin 0 -> 11560 bytes qtgui/resources/buildresources.sh | 4 + qtgui/resources/euterpe.license.txt | 94 + qtgui/resources/euterpe.ttf | Bin 0 -> 50864 bytes qtgui/resources/icon.png | Bin 0 -> 942 bytes qtgui/resources/resources.qrc | 55 + .../resources/svg/accidentalsDoublesharp.svg | 58 + qtgui/resources/svg/accidentalsFlat.svg | 31 + qtgui/resources/svg/accidentalsFlatFlat.svg | 31 + qtgui/resources/svg/accidentalsNatural.svg | 31 + qtgui/resources/svg/accidentalsSharp.svg | 31 + qtgui/resources/svg/blockEnd.svg | 62 + qtgui/resources/svg/clefAlto.svg | 55 + qtgui/resources/svg/clefBass.svg | 56 + qtgui/resources/svg/clefBass_8.svg | 61 + qtgui/resources/svg/clefPercussion.svg | 55 + qtgui/resources/svg/clefTreble.svg | 56 + qtgui/resources/svg/clefTreble^8.svg | 61 + qtgui/resources/svg/clefTreble_8.svg | 61 + qtgui/resources/svg/dot.svg | 55 + qtgui/resources/svg/flag128.svg | 55 + qtgui/resources/svg/flag128i.svg | 55 + qtgui/resources/svg/flag16.svg | 55 + qtgui/resources/svg/flag16i.svg | 55 + qtgui/resources/svg/flag32.svg | 30 + qtgui/resources/svg/flag32i.svg | 55 + qtgui/resources/svg/flag64.svg | 55 + qtgui/resources/svg/flag64i.svg | 55 + qtgui/resources/svg/flag8.svg | 31 + qtgui/resources/svg/flag8i.svg | 55 + qtgui/resources/svg/noteheadsBlack.svg | 56 + qtgui/resources/svg/noteheadsBrevis.svg | 55 + qtgui/resources/svg/noteheadsHalf.svg | 31 + qtgui/resources/svg/noteheadsLonga.svg | 55 + qtgui/resources/svg/noteheadsMaxima.svg | 55 + qtgui/resources/svg/noteheadsWhole.svg | 56 + qtgui/resources/svg/numbers.svg | 82 + qtgui/resources/svg/rest1.svg | 56 + qtgui/resources/svg/rest128.svg | 31 + qtgui/resources/svg/rest16.svg | 55 + qtgui/resources/svg/rest2.svg | 56 + qtgui/resources/svg/rest32.svg | 31 + qtgui/resources/svg/rest4.svg | 56 + qtgui/resources/svg/rest64.svg | 31 + qtgui/resources/svg/rest8.svg | 56 + qtgui/resources/svg/restBrevis.svg | 55 + qtgui/resources/svg/restLonga.svg | 55 + qtgui/resources/svg/restMaxima.svg | 55 + qtgui/resources/svg/scriptsStaccato.svg | 31 + qtgui/resources/svg/svg.license.txt | 678 + qtgui/resources/translations/config.pro | 2 + qtgui/resources/translations/de.qm | Bin 0 -> 425 bytes qtgui/resources/translations/de.ts | 11 + qtgui/resources/translations/update.sh | 5 + qtgui/scoreview.py | 253 + qtgui/structures.py | 1214 ++ qtgui/submenus.py | 601 + qtgui/timeline.py | 492 + qtgui/trackEditor.py | 441 + template | 2 +- 106 files changed, 35314 insertions(+), 1 deletion(-) create mode 120000 .gitignore create mode 100644 CHANGELOG create mode 100644 LICENSE create mode 100755 configure create mode 100644 desktop/desktop.desktop create mode 100644 desktop/icon256x256.png create mode 100644 desktop/icon32x32.png create mode 100644 documentation/LICENSE create mode 100644 documentation/README.txt create mode 100755 documentation/build-documentation.sh create mode 100644 documentation/english.part.adoc create mode 100644 documentation/german.part.adoc create mode 100644 engine/__init__.py create mode 100644 engine/api.py create mode 100644 engine/block.py create mode 100644 engine/config.py create mode 100644 engine/cursor.py create mode 100644 engine/graphtracks.py create mode 100644 engine/items.py create mode 100644 engine/lilypond.py create mode 100644 engine/main.py create mode 100644 engine/oldmidi.py create mode 100644 engine/resources/LICENSE create mode 100644 engine/resources/lilypondTemplate/default.ly create mode 100644 engine/resources/lilypondTemplate/minimal.ly create mode 100644 engine/resources/normal.wav create mode 100644 engine/resources/stressed.wav create mode 100644 engine/track.py create mode 100755 laborejo2 create mode 100644 midiinput/stepmidiinput.py create mode 100644 qtgui/__init__.py create mode 100644 qtgui/conductor.py create mode 100644 qtgui/constantsAndConfigs.py create mode 100644 qtgui/cursor.py create mode 100644 qtgui/designer/clefs.ui create mode 100644 qtgui/designer/mainwindow.py create mode 100644 qtgui/designer/mainwindow.ui create mode 100644 qtgui/designer/tickWidget.py create mode 100644 qtgui/designer/tickWidget.ui create mode 100644 qtgui/designer/trackWidget.py create mode 100644 qtgui/designer/trackWidget.ui create mode 100644 qtgui/graphs.py create mode 100644 qtgui/items.py create mode 100644 qtgui/mainwindow.py create mode 100644 qtgui/menu.py create mode 100644 qtgui/resources.py create mode 100644 qtgui/resources/aboutlogo.png create mode 100644 qtgui/resources/buildresources.sh create mode 100644 qtgui/resources/euterpe.license.txt create mode 100644 qtgui/resources/euterpe.ttf create mode 100644 qtgui/resources/icon.png create mode 100644 qtgui/resources/resources.qrc create mode 100644 qtgui/resources/svg/accidentalsDoublesharp.svg create mode 100644 qtgui/resources/svg/accidentalsFlat.svg create mode 100644 qtgui/resources/svg/accidentalsFlatFlat.svg create mode 100644 qtgui/resources/svg/accidentalsNatural.svg create mode 100644 qtgui/resources/svg/accidentalsSharp.svg create mode 100644 qtgui/resources/svg/blockEnd.svg create mode 100644 qtgui/resources/svg/clefAlto.svg create mode 100644 qtgui/resources/svg/clefBass.svg create mode 100644 qtgui/resources/svg/clefBass_8.svg create mode 100644 qtgui/resources/svg/clefPercussion.svg create mode 100644 qtgui/resources/svg/clefTreble.svg create mode 100644 qtgui/resources/svg/clefTreble^8.svg create mode 100644 qtgui/resources/svg/clefTreble_8.svg create mode 100644 qtgui/resources/svg/dot.svg create mode 100644 qtgui/resources/svg/flag128.svg create mode 100644 qtgui/resources/svg/flag128i.svg create mode 100644 qtgui/resources/svg/flag16.svg create mode 100644 qtgui/resources/svg/flag16i.svg create mode 100644 qtgui/resources/svg/flag32.svg create mode 100644 qtgui/resources/svg/flag32i.svg create mode 100644 qtgui/resources/svg/flag64.svg create mode 100644 qtgui/resources/svg/flag64i.svg create mode 100644 qtgui/resources/svg/flag8.svg create mode 100644 qtgui/resources/svg/flag8i.svg create mode 100644 qtgui/resources/svg/noteheadsBlack.svg create mode 100644 qtgui/resources/svg/noteheadsBrevis.svg create mode 100644 qtgui/resources/svg/noteheadsHalf.svg create mode 100644 qtgui/resources/svg/noteheadsLonga.svg create mode 100644 qtgui/resources/svg/noteheadsMaxima.svg create mode 100644 qtgui/resources/svg/noteheadsWhole.svg create mode 100644 qtgui/resources/svg/numbers.svg create mode 100644 qtgui/resources/svg/rest1.svg create mode 100644 qtgui/resources/svg/rest128.svg create mode 100644 qtgui/resources/svg/rest16.svg create mode 100644 qtgui/resources/svg/rest2.svg create mode 100644 qtgui/resources/svg/rest32.svg create mode 100644 qtgui/resources/svg/rest4.svg create mode 100644 qtgui/resources/svg/rest64.svg create mode 100644 qtgui/resources/svg/rest8.svg create mode 100644 qtgui/resources/svg/restBrevis.svg create mode 100644 qtgui/resources/svg/restLonga.svg create mode 100644 qtgui/resources/svg/restMaxima.svg create mode 100644 qtgui/resources/svg/scriptsStaccato.svg create mode 100644 qtgui/resources/svg/svg.license.txt create mode 100644 qtgui/resources/translations/config.pro create mode 100644 qtgui/resources/translations/de.qm create mode 100644 qtgui/resources/translations/de.ts create mode 100644 qtgui/resources/translations/update.sh create mode 100644 qtgui/scoreview.py create mode 100644 qtgui/structures.py create mode 100644 qtgui/submenus.py create mode 100644 qtgui/timeline.py create mode 100644 qtgui/trackEditor.py diff --git a/.gitignore b/.gitignore new file mode 120000 index 0000000..68fd69a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +template/gitignore.template \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..7d84390 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,2 @@ +2019-04-15 Version 2.0 +Initial Release diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/configure b/configure new file mode 100755 index 0000000..c9734e4 --- /dev/null +++ b/configure @@ -0,0 +1,5 @@ +#!/bin/bash +program=exampleClientCboxQtNsm #MUST be the same as engine/config.py shortName +cboxconfigure="--without-fluidsynth --without-libsmf" + +. template/configure.template #. is the posix compatible version of source diff --git a/desktop/desktop.desktop b/desktop/desktop.desktop new file mode 100644 index 0000000..d5beba3 --- /dev/null +++ b/desktop/desktop.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Type=Application +Name=Laborejo +GenericName=Sequencer +Comment=MIDI sequencer based on classical music notation. +Comment[de]=MIDI-Sequencer mit Musiknoten +Exec=laborejo2 +Icon=laborejo +Terminal=false +StartupNotify=false +Categories=AudioVideo;Audio;X-Recorders;X-Multitrack;X-Jack; +X-NSM-capable=true +Version=2.0 diff --git a/desktop/icon256x256.png b/desktop/icon256x256.png new file mode 100644 index 0000000000000000000000000000000000000000..f4b5c0124691e7026bb156a2b6a87b9844abfcb7 GIT binary patch literal 680 zcmV;Z0$2TsP)1DkQh>zA69!02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00Iz6L_t(o!|j*PYZFlr$3HLG z?50gMHYP?SQj1_{kV1tXJV>P;RC+FYk%ET^;vXRX2|e^Ci1sLY@S-AklOAo5RxB;m zN{UUe5+X%x^JBBS<3SS%ZS6KJDMG$53p;P-?T2A@9#07f2Phv0tPVg2;6DJ^oW`+j zq*gsFcC1Ld^uL29C{}OvYn?`2~D-4y9=*T}K%PpQ}}vn}-kYAh!rk z0sI;$AC*XCe*eL<_3?m6{(*>yJTDf-)t-OMT@So30@>ZypVeUM zHn4;p4)3b~nyaWE0HuG&OgYH-3x>W8Ac+JjpZ5?z8jqcIeUL3jnV%MrMG6A0or&GrFYNhTqeYx1=f;N!*y$;Ace1(Ih#JC6AM?Hk3b zg#ug{fwLp<>Js2!8Ah9XpspuNU_9bv)@m)^)x^4ih`il>64q@L`JQpREYNf8;o#%wz6aSsdxfWE&~i^s83spgow{V?_r&+a^u%nT>8Spq&2qFr$6G^kzx4y~x~ZeX$tCV%z*%KzwDzHGtalUNCqJ ztSDI4Z!=BAG*RU;@DsveID8aBJ)rA2Mi=VSs_Vl@buK0yfDXVx1N;J(;UohY#s6&p O00001DkQh>zA69!02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00Iz6L_t(o!|j*PYZFlr$3HLG z?50gMHYP?SQj1_{kV1tXJV>P;RC+FYk%ET^;vXRX2|e^Ci1sLY@S-AklOAo5RxB;m zN{UUe5+X%x^JBBS<3SS%ZS6KJDMG$53p;P-?T2A@9#07f2Phv0tPVg2;6DJ^oW`+j zq*gsFcC1Ld^uL29C{}OvYn?`2~D-4y9=*T}K%PpQ}}vn}-kYAh!rk z0sI;$AC*XCe*eL<_3?m6{(*>yJTDf-)t-OMT@So30@>ZypVeUM zHn4;p4)3b~nyaWE0HuG&OgYH-3x>W8Ac+JjpZ5?z8jqcIeUL3jnV%MrMG6A0or&GrFYNhTqeYx1=f;N!*y$;Ace1(Ih#JC6AM?Hk3b zg#ug{fwLp<>Js2!8Ah9XpspuNU_9bv)@m)^)x^4ih`il>64q@L`JQpREYNf8;o#%wz6aSsdxfWE&~i^s83spgow{V?_r&+a^u%nT>8Spq&2qFr$6G^kzx4y~x~ZeX$tCV%z*%KzwDzHGtalUNCqJ ztSDI4Z!=BAG*RU;@DsveID8aBJ)rA2Mi=VSs_Vl@buK0yfDXVx1N;J(;UohY#s6&p O0000. +""" + +import logging; logging.info("import {}".format(__file__)) + +#This file only exists as a reminder to _not_ create it again wrongly in the future. + +#from .api import * #Do not star-import here! +#This leads to uncontrollable behaviour because importing _any_ file from engine will first import this init file, which would trigger the api to start its session. +#Instead use explicit import to get the api. + +#No!: import engine.api as api #This loads the engine and starts a session. diff --git a/engine/api.py b/engine/api.py new file mode 100644 index 0000000..305afa0 --- /dev/null +++ b/engine/api.py @@ -0,0 +1,2314 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2018, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), +more specifically its template base application. + +The Template Base Application 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 . +""" + +import logging; logging.info("import {}".format(__file__)) + +#Python Standard Library +import sys +import random + +#Third Party Modules + +#Template Modules +import template.engine.api #we need direct access to the module to inject data in the provided structures. but we also need the functions directly. next line: +from template.engine.api import * +from template.engine.duration import DB, DL, D1, D2, D4, D8, D16, D32, D64, D128, D256, D512, D1024, D_DEFAULT, D_STACCATO, D_TENUTO, D_TIE +import template.engine.pitch as pitchmath +from template.helper import flatList, EndlessGenerator + +#Our Modules +from . import items +from . import lilypond +from .graphtracks import TempoItem +from .track import Track + +apiModuleSelfReference = sys.modules[__name__] + +#New callbacks +class ClientCallbacks(Callbacks): #inherits from the templates api callbacks + def __init__(self): + super().__init__() + + self.setCursor = [] + self.setSelection = [] + + self.tracksChanged = [] + self.tracksChangedIncludingHidden = [] + self.updateTrack = [] + self.updateBlockTrack = [] + + #self.playbackStart = [] + #self.playbackStop = [] + self.playbackSpeedChanged = [] + self._cachedTickIndex = -1 + + self.updateGraphTrackCC = [] + self.graphCCTracksChanged = [] + self.updateGraphBlockTrack = [] + + self.updateTempoTrack = [] + self.updateTempoTrackBlocks = [] + self.updateTempoTrackMeta = [] + + self.prevailingBaseDurationChanged = [] + self.metronomeChanged = [] + + #self.recordingStreamNoteOn = [] + #self.recordingStreamNoteOff = [] + #self.recordingStreamClear = [] + + def _dataChanged(self): + """Only called from within the callbacks. + This is about data the user cares about. In other words this is the indicator if you need + to save again. + + The data changed when notes are inserted, track names are changed, a CC value is added etc. + but not when the cursor moves, the metronome is generated or the playback tick advances. + """ + session.nsmClient.announceSaveStatus(False) + self._historyChanged() + + def _setCursor(self, destroySelection = True): + """set a new cursor position. + Only do destroySelection = False if you really modify the + selection. If in doubt: destroy it. """ + if destroySelection or session.history.doNotRegisterRightNow or session.history.duringRedo: + session.data.cursorWhenSelectionStarted = None + + if self.setCursor: + ex = session.data.cursorExport() + for func in self.setCursor: + func(ex) + + """Exports a tuple of cursors. This is to indicate a GUI to + draw a selection rectangle or so. Not for processing. Because: + The exported top left item is included in the selection. + The exported bottom right item is NOT in the selection. + But for a GUI it looks like the rectangle goes to the current + cursor position, which appears to be left of the current item.""" + ex = session.data.selectionExport() + for func in self.setSelection: + func(ex) + + def _updateChangedTracks(self): + """Determines which tracks have changed in the step before + this callback and calls an update for those""" + changedTracks, currentItem = session.data.currentContentLinkAndItsBlocksInAllTracks() + for track in changedTracks: + self._updateTrack(id(track)) + + def _updateTrack(self, trId): + """The most important function. Create a static representation of the music data which + can be used by a GUI to draw notes. + track.staticRepresentation also creates the internal midi representation for cbox. """ + if self.updateTrack: + ex = session.data.trackById(trId).staticRepresentation() + for func in self.updateTrack: + func(trId, ex) + self._updateBlockTrack(trId) + + def _updateBlockTrack(self, trId): + if self.updateBlockTrack: + ex = session.data.trackById(trId).staticBlocksRepresentation() + for func in self.updateBlockTrack: + func(trId, ex) + + self._updateTempoTrack() #The last Tempo Block reacts to changing score sizes. + self._dataChanged() + + def _updateGraphTrackCC(self, trId, cc): + """No cursor, so it always needs a graphTrack Id. + Also handles a GraphBlock overview callback, + for extra block view or background colors.""" + + #For simplistic reasons we just update all of this CC in all tracks. + #Makes things much simple with content links across tracks. + #We will see how that turns out performance wise. + + #We keep the trId parameter but don't use it. + + for track in session.data.tracks: + if cc in track.ccGraphTracks: + graphTrackCC = track.ccGraphTracks[cc] + trId = id(track) + ex = graphTrackCC.staticRepresentation() + for func in self.updateGraphTrackCC: + func(trId, cc, ex) + + ex = graphTrackCC.staticGraphBlocksRepresentation() + for func in self.updateGraphBlockTrack: + func(trId, cc, ex) + + def _updateSingleTrackAllCC(self, trId): + """Used on CC-Channels change. No own callback list.""" + for cc, graphTrackCC in session.data.trackById(trId).ccGraphTracks.items(): + ex = graphTrackCC.staticRepresentation() + for func in self.updateGraphTrackCC: + func(trId, cc, ex) + + + def _graphCCTracksChanged(self, trId): + """CC graphs of a track deleted or added""" + #TODO: moved? + if self.graphCCTracksChanged: + ex = list(session.data.trackById(trId).ccGraphTracks.keys()) # list of ints from 0 to 127 + for func in self.graphCCTracksChanged: + func(trId, ex) + self._dataChanged() + + def _tracksChanged(self): + """Track deleted, added or moved. Or toggled double/non-double. + This callback is relatively cheap because it does not generate + any item data.""" + session.data.updateJackMetadataSorting() + + if self.tracksChanged: + ex = session.data.listOfStaticTrackRepresentations() + for func in self.tracksChanged: + func(ex) + + if self.tracksChangedIncludingHidden: + exHidden = session.data.listOfStaticHiddenTrackRepresentations() + for func in reversed(self.tracksChangedIncludingHidden): + func(ex + exHidden) + self._dataChanged() + self._metronomeChanged() #because the track name is sent here. + + def _updateTempoTrack(self): + """Sends the block update as well. + staticRepresentations also updates midi. + + Of course the order is: track meta, then blocks first, then items. + This must not change! The GUI depends on it.""" + + if self.updateTempoTrackMeta: + ex = session.data.tempoTrack.staticTrackRepresentation() #only track metadata, no block information. parses all items. + for func in self.updateTempoTrackMeta: + func(ex) + + if self.updateTempoTrackBlocks: + ex = session.data.tempoTrack.staticGraphBlocksRepresentation() #block boundaries and meta data. Does not parse items therefore cheap to call. + for func in self.updateTempoTrackBlocks: + func(ex) + + if self.updateTempoTrack: + ex = session.data.tempoTrack.staticRepresentation() #export all items. performance-expensive. + for func in self.updateTempoTrack: + func(ex) + + #TODO: We need blocks before items, but also blocks after items. This is a cheap call though. + if self.updateTempoTrackBlocks: + ex = session.data.tempoTrack.staticGraphBlocksRepresentation() #yes, we need to regenerate that. That is the problem. #TODO. + for func in self.updateTempoTrackBlocks: + func(ex) + + self._dataChanged() + #since the exported cursor also has a tempo entry it needs updating as well + #TODO: but this also leads to centerOn cursor in the gui after every mouse click in the conductor. + #self._setCursor(destroySelection = False) + + def _playbackStart(self): + for func in self.playbackStart: + func() + + def _playbackStop(self): + for func in self.playbackStop: + func() + + def _playbackSpeedChanged(self, newValue): + for func in self.playbackSpeedChanged: + func(newValue) + + def _prevailingBaseDurationChanged(self, newPrevailingBaseDuration): + for func in self.prevailingBaseDurationChanged: + func(newPrevailingBaseDuration) + + def _historyChanged(self): + """sends two lists of strings. + the first is the undoHistory, the last added item is [-1]. We can show that to a user to + indicate what the next undo will do. + + the second is redoHistory, same as undo: [-1] shows the next redo action.""" + undoHistory, redoHistory = session.history.asList() + for func in self.historyChanged: + func(undoHistory, redoHistory) + + def _metronomeChanged(self): + """returns a dictionary with meta data such as the mute-state and the track name""" + #Check if the actual track exists. This handles track delete of any kind. + #session.data.metronome.currentMetronomeTrack is not a calf box track but our Laborejo track that HOLDS the current cbox metronome track + return #TODO + if not session.data.metronome.currentMetronomeTrack or not (session.data.metronome.currentMetronomeTrack in session.data.tracks or session.data.metronome.currentMetronomeTrack in session.data.hiddenTracks): + session.data.metronome.currentMetronomeTrack = None + session.data.metronome.useTrack(session.data.currentTrack()) + + for func in self.metronomeChanged: + func(session.data.metronome.staticRepresentation()) + + def _recordingStreamNoteOn(self, liveChord): + """One dict at a time""" + trId = id(session.data.currentTrack()) + for func in self.recordingStreamNoteOn: + func(trId, liveChord) + + def _recordingStreamNoteOff(self, liveChord): + """One dict at a time""" + trId = id(session.data.currentTrack()) + for func in self.recordingStreamNoteOff: + func(trId, liveChord) + + def _recordingStreamClear(self): + for func in self.recordingStreamClear: + func() + +#Inject our derived Callbacks into the parent module +template.engine.api.callbacks = ClientCallbacks() +from template.engine.api import callbacks + + +_templateStartEngine = startEngine +def startEngine(nsmClient): + _templateStartEngine(nsmClient) + + #Send initial Data etc. + session.data.tempoMap.isTransportMaster = True #always true for Laborejo. + callbacks._tracksChanged() # This creates the frontend/GUI tracks with access through track ids. From now on we can send the GUI a trId and it knows which track needs change. + for trId in session.data.listOfTrackIds(): + callbacks._updateTrack(trId) #create content: music items + callbacks._updateTempoTrack() # does everything at once + callbacks._graphCCTracksChanged(trId) #create structure: all CC graphs, accessed by CC number (0-127) + for cc in session.data.trackById(trId).listOfCCsInThisTrack(): + callbacks._updateGraphTrackCC(trId, cc) #create content: CC points. user points and interpolated points. + + for track in session.data.hiddenTracks: #After loading a file some tracks could be hidden. We want midi for them as well. + track.staticRepresentation() #that generates the calfbox data as a side effect. discard the other data. + + callbacks._setCursor() + + global laborejoEngineStarted #makes for a convenient check. stepMidiInput uses it, which needs to know that the gui already started the api. + laborejoEngineStarted = True + +#General and abstract Commands + +def playFromCursor(): + playFrom(ticks=session.data.cursorExport()["tickindex"]) + +topLevelFunction = None +def simpleCommand(function, autoStepLeft = True, forceReturnToItem = None): + """ + simpleCommand demands that the cursor is on the item you want to + change. That means for scripting and working with selections + that you can't simply iterate over block.data, which is a list. + Well you can, but then you don't get the context data which is in + track.state. + + Recursive commands are not allowed""" + global topLevelFunction #todo: replace with a python-context + if not topLevelFunction: + topLevelFunction = function + + if autoStepLeft and session.data.currentTrack().state.isAppending(): + session.data.currentTrack().left() + function() #<-------- The action + session.data.currentTrack().right() + else: + function() #<-------- The action + + if forceReturnToItem: + curBlock, curItem = forceReturnToItem + session.data.currentTrack().toItemInBlock(curItem, curBlock) #even works with appending positions (None) + + if function == topLevelFunction: + callbacks._updateChangedTracks() #works with the current item @ cursor. + callbacks._setCursor() + topLevelFunction = None + +def insertItem(item): + orderBeforeInsert = session.data.getBlockAndItemOrder() + moveFunction = _createLambdaMoveToForCurrentPosition() + if session.data.currentTrack().insert(item): + def registeredUndoFunction(): + moveFunction() + _changeBlockAndItemOrder(orderBeforeInsert) + session.history.register(registeredUndoFunction, descriptionString=f"Insert {item}") + simpleCommand(nothing, autoStepLeft = False) #for callbacks + callbacks._historyChanged() + +def insertItemAtTickindex(item, tickindex): + #session.data.currentTrack().goToTickindex + + """ + Das ist eine conversion in der session. keine api befehle benutzen. + hier weiter machen. Der Cursor muss in Ruhe gelassen werden. Oder aber ich resette ohne callback? das erscheint mir erstmal simpler. + Ich brauch aber eine Funktion goToTickindex im Track die Pausen erstellt wenn man da nicht hinkommt. Jetzt wünsch ich mir ich hätte die Noten nicht in ner liste sondern in einem dict mit tickindex. welp... + vielleicht brauch ich eine komplette parallelwelt. das midi modul sollte auf jeden fall nicht die keysig suchen müssen. kontext wird in der api hergestellt, nicht im midi + """ + +def _createLambdaMoveToForCurrentPosition(): + """for undo only""" + def moveTo(trackIndex, blockIndex, localCursorIndexInBlock, pitchindex): + try: + session.data.goTo(trackIndex, blockIndex, localCursorIndexInBlock) + session.data.cursor.pitchindex = pitchindex + except: #the worst that can happen is wrong movement. + pass + trackIndex, blockIndex, localCursorIndexInBlock = session.data.where() + moveFunction = lambda trIdx=trackIndex, blIdx=blockIndex, curIdx=localCursorIndexInBlock, pitchIdx=session.data.cursor.pitchindex: moveTo(trIdx, blIdx, curIdx, pitchIdx) + return moveFunction + +#The following function is not neccesary. A selection is a user-created thing, not something you need for internal processing, especially not for undo. +#Leave it as reminder. +#def _createLambdaRecreateSelection(): +# """for undo only +# Call it when you still have a selection, right after you do the +# processing you want to undo. +# +# A valid selection implies that the cursor is on one end +# of the selection. It doesn't matter which one but for the +# sake of consistency and convenience we make sure that we end up with +# the cursor on the bottomRight position. +# It is entirely possible that the selection changed +# the duration and the dimensions. The bottom right item might not +# be on the same tickindex nor does it need to exist anymore. +# Only the topLeft position is guaranteed to exist and have the same +# tickindex. The item on that position however may not be there +# anymore. +# """ +# def recreateSelection(moveToFunction, topLeftCursor, bottomRightCursor): +# session.data.cursorWhenSelectionStarted = None #take care of the current selection +# moveToFunction() +# session.data.goTo(topLeftCursor["trackIndex"], topLeftCursor["blockindex"], topLeftCursor["localCursorIndex"]) +# session.data.setSelectionBeginning() +# session.data.goTo(bottomRightCursor["trackIndex"], bottomRightCursor["blockindex"], bottomRightCursor["localCursorIndex"]) +# +# assert session.data.cursorWhenSelectionStarted #only call this when you still have a selection +# createSelectionFunction = lambda moveTo=_createLambdaMoveToForCurrentPosition(), tL=session.data.cursor.exportObject(session.data.currentTrack().state), bR=session.data.cursorWhenSelectionStarted, : recreateSelection(moveTo, tL, bR) +# return createSelectionFunction #When this function gets called we are back in the position that the newly generated data is selected, ready to to the complementary processing. + + +def _updateCallbackForListOfTrackIDs(listOfChangedTrackIds): + for trackId in listOfChangedTrackIds: + callbacks._updateTrack(trackId) + +def _updateCallbackAllTracks(): + _updateCallbackForListOfTrackIDs(session.data.listOfTrackIds()) + +updateCallbackAllTracks = _updateCallbackAllTracks + +def useCurrentTrackAsMetronome(): + track = session.data.currentTrack() + session.data.metronome.useTrack(track) + callbacks._metronomeChanged() #updates playback as well + +def enableMetronome(value): + session.data.metronome.enabled = value #has side effects + callbacks._metronomeChanged() #updates playback as well + +def isMetronomeEnabled(): + return session.data.metronome.enabled + +def toggleMetronome(): + enableMetronome(not session.data.metronome.enabled) #handles callback etc. + +def _changeBlockAndItemOrder(dictWithTrackIDsAndDataLists): + """A helper function for deleteSelection, paste and other... + This makes it possible to undo/redo properly. It registers + itself with complementary data as undo/redo.""" + orderBeforeInsert = session.data.getBlockAndItemOrder() #save the current version as old version. as long as we keep this data around, e.g. in the undo stack, the items will not be truly deleted + moveFunction = _createLambdaMoveToForCurrentPosition() #the goTo function for the cursor is not exactly in the right place. It may end up on the "other" side of a selection. Which is close enough. + def registeredUndoFunction(): + moveFunction() + _changeBlockAndItemOrder(orderBeforeInsert) + session.history.register(registeredUndoFunction, descriptionString="change order") + + #Replace old data with new parameter-data. + listOfTrackIDs = session.data.putBlockAndItemOrder(dictWithTrackIDsAndDataLists) + + #Make changes visible in the GUI + _updateCallbackForListOfTrackIDs(listOfTrackIDs) + callbacks._setCursor() + +def cutObjects(): + copyObjects() + _deleteSelection() + +def _deleteSelection(backspaceParamForCompatibilityIgnoreThis = None): #this is so special it gets its own command and is not part of the single delete() command. + orderBeforeDelete = session.data.getBlockAndItemOrder() + moveFunction = _createLambdaMoveToForCurrentPosition() + + listOfChangedTrackIDs = session.data.deleteSelection() + if listOfChangedTrackIDs: #delete succeeded. + def registeredUndoFunction(): + moveFunction() + _changeBlockAndItemOrder(orderBeforeDelete) + session.history.register(registeredUndoFunction, descriptionString="delete selection") + + #Make changes visible in the GUI and midi + for trackId in listOfChangedTrackIDs: + callbacks._updateTrack(trackId) + callbacks._setCursor() + +def copyObjects(): #ctrl+c + session.data.copyObjects() + #The score doesn't change at all. No callback. + #no undo. + +def pasteObjects(customBuffer = None, keepCursorState = False, overwriteSelection = True): #ctrl+v + """api.duplicate overrides default paste behaviour by providing its own copyBuffer + and not destroying the selection/keep the cursor at its origin position + """ + dataBefore = session.data.getBlockAndItemOrder() + moveFunction = _createLambdaMoveToForCurrentPosition() + listOfChangedTrackIDs = session.data.pasteObjects(customBuffer, overwriteSelection) + if listOfChangedTrackIDs: #paste succeeded. + def registeredUndoFunction(): + moveFunction() + _changeBlockAndItemOrder(dataBefore) + session.history.register(registeredUndoFunction, descriptionString="paste") + + #Make changes visible in the GUI + for trackId in listOfChangedTrackIDs: + callbacks._updateTrack(trackId) + + if keepCursorState: + goTo() + callbacks._setCursor(destroySelection = False) + else: + callbacks._setCursor() + +def duplicate(): #ctrl+d + """Duplicate a single object and put it right of the original. Duplicate the entire selection + and put the copy right of the last selected note. + Basically a special case of copy and paste that does not touch the clipboard.""" + if session.data.cursorWhenSelectionStarted: + #startPos = session.data.where() #we cannot use where() since we don't know if a content linked block before our current position gets new items in the duplication process + #TODO: when duplicating with content links or at least inside a content link the selection gets lost completely. Maybe this cannot be avoided, but review that in the future. + + customBuffer = session.data.copyObjects(writeInSessionBuffer = False) + if customBuffer: + session.data.goToSelectionStart() + pasteObjects(customBuffer = customBuffer, keepCursorState = True, overwriteSelection = False) + else: + item = session.data.currentItem() + if item: + insertItem(item.copy()) + + +#Score +def transposeScore(rootPitch, targetPitch): + """Based on automatic transpose. The interval is caculated from two pitches. + There is also tranpose. But no transposeTrack, this is just select track and transpose.""" + session.data.transposeScore(rootPitch, targetPitch) + session.history.register(lambda r=rootPitch,t=targetPitch: transposeScore(t,r), descriptionString="transpose score") + _updateCallbackAllTracks() + +#Tracks +def insertTrack(atIndex, trackObject): + moveFunction = _createLambdaMoveToForCurrentPosition() + newTrackId = id(trackObject) + session.data.insertTrack(atIndex, trackObject) #side-effect: changes the active track to the new track which can be used in the next step: + def registeredUndoFunction(): + moveFunction() + deleteTrack(newTrackId) + session.history.register(registeredUndoFunction, descriptionString = "insert track") + callbacks._tracksChanged() + callbacks._updateTrack(newTrackId) + callbacks._setCursor() + +def newEmptyTrack(): + """Append an empty track and switch to the new track""" + newIndex = len(session.data.tracks) + newTrack = Track(session.data) + insertTrack(newIndex, newTrack) #handles callbacks and undo + return (id(newTrack)) + +def deleteTrack(trId): + """Can not delete hidden tracks because these don't implement undo. + A hidden track is already considered "deleted" by the program. + Therefore you can only delete visible tracks.""" + trackObject = session.data.trackById(trId) + assert trackObject not in session.data.hiddenTracks #enforce docstring. + trackIndex = session.data.tracks.index(trackObject) + didDelete = session.data.deleteTrack(trackObject) #may or may not change the trackindex. In any case, logically the cursor is now in a different track. + if didDelete: #score.deleteTrack does not delete the last remaining track + def registeredUndoFunction(): + trackObject.sequencerInterface.recreateThroughUndo() + insertTrack(trackIndex, trackObject) + session.history.register(registeredUndoFunction, descriptionString = "delete track") + callbacks._tracksChanged() + callbacks._setCursor() + callbacks._metronomeChanged() + +def deleteCurrentTrack(): + deleteTrack(id(session.data.currentTrack())) + +def hideTrack(trId): + """For the callbacks this looks like a delete. But there is no undo. + The track still emits playback. + + hide and unhide track register in the history. deleteItem depends on the item to be in a visible + track so it may possible to insert an item, hide the track and then undo which would try to + delete an item in a hidden track. Therefore hide and unhide register. + """ + trackObject = session.data.trackById(trId) + result = session.data.hideTrack(trackObject) + if result: #not the only track + session.history.register(lambda trId=trId: unhideTrack(trId), descriptionString = "hide track") + callbacks._tracksChanged() #even if there is no change the GUI needs to be notified to redraw its checkboxes that may have been enabled GUI-side. + callbacks._setCursor() + +def unhideTrack(trId): + trackObject = session.data.trackById(trId) + session.data.unhideTrack(trackObject) #always succeeds, or throws error. + session.history.register(lambda trId=trId: hideTrack(trId), descriptionString = "unhide track") + callbacks._tracksChanged() + callbacks._updateTrack(trId) + #the cursor is uneffected + +def listOfTrackIds(): + return session.data.listOfTrackIds() + +def listOfHiddenTrackIds(): + return [id(track) for track in session.data.hiddenTracks.keys()] + +def rearrangeTracks(listOfTrackIds): + if len(session.data.tracks) <= 1: + return + session.history.register(lambda l=session.data.asListOfTrackIds(): rearrangeTracks(l), descriptionString = "rearrange tracks") + session.data.rearrangeTracks(listOfTrackIds) + callbacks._tracksChanged() + callbacks._setCursor() + +def setTrackName(trId, nameString, initialInstrumentName, initialShortInstrumentName): + trackObject = session.data.trackById(trId) + session.history.register(lambda i=trId, n=trackObject.name, lyN=trackObject.initialInstrumentName, lySN=trackObject.initialShortInstrumentName: setTrackName(i, n, lyN, lySN), descriptionString = "change track name") + trackObject.name = nameString # this is a setter. It changes calfbox as well. + trackObject.initialInstrumentName = initialInstrumentName + trackObject.initialShortInstrumentName = initialShortInstrumentName + callbacks._tracksChanged() + +def setTrackUpbeat(trId, upbeatInTicks): + trackObject = session.data.trackById(trId) + session.history.register(lambda i=trId, u=trackObject.upbeatInTicks: setTrackUpbeat(i, u), descriptionString = "change track upbeat") + trackObject.upbeatInTicks = upbeatInTicks + callbacks._updateTrack(trId) + +def setDoubleTrack(trId, statusBool): + """It does not touch any important data because it is more or less + a savefile-persistent visual convenience feature. + So we don't need undo/redo""" + trackObject = session.data.trackById(trId) + trackObject.double = statusBool + callbacks._tracksChanged() + callbacks._updateTrack(trId) + callbacks._setCursor() + +def setTrackSettings(trId, dictionary): + """We need to create a new playback of the track to update the midi data.""" + trackObject = session.data.trackById(trId) + previousSettings = trackObject.staticTrackRepresentation() + clean = True + + for key, value in dictionary.items(): + #this assumes keys are the same as track export. Will give a key error at least if not. + if not previousSettings[key] == value: + clean = False + break + + if not clean: + trackObject.initialMidiChannel = dictionary["initialMidiChannel"] + trackObject.initialMidiBankMsb = dictionary["initialMidiBankMsb"] + trackObject.initialMidiBankLsb = dictionary["initialMidiBankLsb"] + trackObject.initialMidiProgram = dictionary["initialMidiProgram"] + trackObject.ccChannels = dictionary["ccChannels"] + trackObject.midiTranspose = dictionary["midiTranspose"] + trackObject.durationSettingsSignature.defaultOn = dictionary["duration.defaultOn"] + trackObject.durationSettingsSignature.defaultOff = dictionary["duration.defaultOff"] + trackObject.durationSettingsSignature.staccatoOn = dictionary["duration.staccatoOn"] + trackObject.durationSettingsSignature.staccatoOff = dictionary["duration.staccatoOff"] + trackObject.durationSettingsSignature.tenutoOn = dictionary["duration.tenutoOn"] + trackObject.durationSettingsSignature.tenutoOff = dictionary["duration.tenutoOff"] + trackObject.durationSettingsSignature.legatoOn = dictionary["duration.legatoOn"] + trackObject.durationSettingsSignature.legatoOff = dictionary["duration.legatoOff"] + + trackObject.dynamicSettingsSignature.dynamics["ppppp"] = dictionary["dynamics.ppppp"] + trackObject.dynamicSettingsSignature.dynamics["pppp"] = dictionary["dynamics.pppp"] + trackObject.dynamicSettingsSignature.dynamics["ppp"] = dictionary["dynamics.ppp"] + trackObject.dynamicSettingsSignature.dynamics["pp"] = dictionary["dynamics.pp"] + trackObject.dynamicSettingsSignature.dynamics["p"] = dictionary["dynamics.p"] + trackObject.dynamicSettingsSignature.dynamics["mp"] = dictionary["dynamics.mp"] + trackObject.dynamicSettingsSignature.dynamics["mf"] = dictionary["dynamics.mf"] + trackObject.dynamicSettingsSignature.dynamics["f"] = dictionary["dynamics.f"] + trackObject.dynamicSettingsSignature.dynamics["ff"] = dictionary["dynamics.ff"] + trackObject.dynamicSettingsSignature.dynamics["fff"] = dictionary["dynamics.fff"] + trackObject.dynamicSettingsSignature.dynamics["ffff"] = dictionary["dynamics.ffff"] + trackObject.dynamicSettingsSignature.dynamics["custom"] = dictionary["dynamics.custom"] + trackObject.dynamicSettingsSignature.dynamics["tacet"] = dictionary["dynamics.tacet"] + trackObject.dynamicSettingsSignature.dynamics["fp"] = dictionary["dynamics.fp"] + trackObject.dynamicSettingsSignature.dynamics["sp"] = dictionary["dynamics.sp"] + trackObject.dynamicSettingsSignature.dynamics["spp"] = dictionary["dynamics.spp"] + trackObject.dynamicSettingsSignature.dynamics["sfz"] = dictionary["dynamics.sfz"] + trackObject.dynamicSettingsSignature.dynamics["sf"] = dictionary["dynamics.sf"] + trackObject.dynamicSettingsSignature.dynamics["sff"] = dictionary["dynamics.sff"] + + session.history.register(lambda trId=trId, previousSettings=previousSettings: setTrackSettings(trId, previousSettings), descriptionString = "change track settings") + callbacks._tracksChanged() + callbacks._updateSingleTrackAllCC(trId) + callbacks._updateTrack(trId) + +def resetDynamicSettingsSignature(trId): + trackObject = session.data.trackById(trId) + previousSettings = trackObject.staticTrackRepresentation() + trackObject.dynamicSettingsSignature.reset() + session.history.register(lambda trId=trId, previousSettings=previousSettings: setTrackSettings(trId, previousSettings), descriptionString = "reset track dynamic settings") + callbacks._tracksChanged() + #We only need this for midi changes. callbacks._updateSingleTrackAllCC(trId) + callbacks._updateTrack(trId) + +def resetDuationSettingsSignature(trId): + trackObject = session.data.trackById(trId) + previousSettings = trackObject.staticTrackRepresentation() + trackObject.durationSettingsSignature.reset() + session.history.register(lambda trId=trId, previousSettings=previousSettings: setTrackSettings(trId, previousSettings), descriptionString = "reset track duration settings") + callbacks._tracksChanged() + #We only need this for midi changes. callbacks._updateSingleTrackAllCC(trId) + callbacks._updateTrack(trId) + +#Blocks +def appendBlock(trackid = None): + """ + Has dynamic behaviour: + If we are at the end of track appending a Block switches into + that new block. + On any other position it just appends a block and the cursor + stays where it is. This gives a better typing from left-to-right + experience.""" + if trackid: + tr = session.data.trackById(trackid) + else: + tr = session.data.currentTrack() + block = tr.appendBlock() + if tr.state.isAppending() and len(tr.blocks)-2 == tr.state.blockindex: #end of track? + moveFunction = _createLambdaMoveToForCurrentPosition() + def registeredUndoFunction(): + moveFunction() + deleteBlock(id(block)) + session.history.register(registeredUndoFunction, descriptionString = "append block") + session.data.currentTrack().right() + else: + session.history.register(lambda blId = id(block): deleteBlock(blId), descriptionString = "append block") + callbacks._updateTrack(id(tr)) + callbacks._setCursor() + +def splitBlock(): + tr = session.data.currentTrack() + if tr.state.isAppending() and len(tr.blocks)-1 == tr.state.blockindex: #end of track? Yes len-1 here and len-2 in append() is correct. I don't know why :( + appendBlock() + else: #a real split + dictOfTrackIdsWithListOfBlockIds = session.data.splitCurrentBlockAndAllContentLinks() #do the split. We get the current state as return value for undo + if dictOfTrackIdsWithListOfBlockIds: + rearrangeBlocksInMultipleTracks(dictOfTrackIdsWithListOfBlockIds) #handles undo and callbacks for redrawing + callbacks._setCursor() #cursor is still on the same item. But the item might be further to the right now when additional block boundaries have been introduced to the left through contentLinks + +def joinBlockWithNext(blockId): + """written for the GUI which can join blocks with the mouse""" + track, block = session.data.blockById(blockId) + session.data.goTo(session.data.tracks.index(track), track.blocks.index(block), 0) + joinBlock() + +def joinBlock(): + """Opposite of splitBlock (but not undo) + Take the current block and join it with the one after it. + Does the same automatically for all content linked blocks. + If there is no next block this will do nothing. + + It only works on content linked blocks if ALL content linked blocks have a different + content linked block after them. So a block A needs always to be followed by block B. + Joining those will result in one big new content linked block in the whole track. + It is exactly the same as splitting a content linked block which will result in two new + content links.""" + where = session.data.where() #just for the user experience. + + dictOfTrackIdsWithListOfBlockIds = session.data.joinCurrentBlockAndAllContentLinks() + if dictOfTrackIdsWithListOfBlockIds: + rearrangeBlocksInMultipleTracks(dictOfTrackIdsWithListOfBlockIds) #handles undo and callbacks for redrawing + + session.data.goTo(*where) #just for the user experience. + callbacks._setCursor() + +def deleteBlock(blockId): + track, block = session.data.blockById(blockId) + oldBlockArrangement = track.asListOfBlockIds() + parentTrack, deletedBlock = track.deleteBlock(block) + if (parentTrack and deletedBlock): #not the last block + #Blocks are never truly deleted but a stored in the Block.allBlocks dict. This keeps the reference to this deleted block alive and it can be added through rearrange, which gets its blocks from this dict. + session.history.register(lambda i=id(track), l=oldBlockArrangement: rearrangeBlocks(i, l), descriptionString = "delete block") + callbacks._updateTrack(id(track)) + callbacks._setCursor() + +def deleteCurrentBlock(): + currentBlockId = id(session.data.currentTrack().currentBlock()) + deleteBlock(currentBlockId) #handles callbacks and undo + +def deleteEmptyBlocks(): + """whole score""" + dictOfTrackIdsWithListOfBlockIds = session.data.removeEmptyBlocks() + if dictOfTrackIdsWithListOfBlockIds and all(l for l in dictOfTrackIdsWithListOfBlockIds.values()): + rearrangeBlocksInMultipleTracks(dictOfTrackIdsWithListOfBlockIds) #handles undo and callbacks for redrawing + callbacks._setCursor() + +def duplicateCurrentBlock(): + currentBlockId = id(session.data.currentTrack().currentBlock()) + duplicateBlock(currentBlockId, 1) #handles callbacks and undo + +def duplicateContentLinkCurrentBlock(): + currentBlockId = id(session.data.currentTrack().currentBlock()) + duplicateContentLinkBlock(currentBlockId, 1) #handles callbacks and undo + +def duplicateBlock(blockId, times = 1): + track, block = session.data.blockById(blockId) + session.history.register(lambda i=id(track), l=track.asListOfBlockIds(): rearrangeBlocks(i, l), descriptionString = "duplicate block") + for i in range(times): + track.duplicateBlock(block) + callbacks._updateTrack(id(track)) + callbacks._setCursor() + +def duplicateContentLinkBlock(blockId, times = 1): + track, block = session.data.blockById(blockId) + session.history.register(lambda i=id(track), l=track.asListOfBlockIds(): rearrangeBlocks(i, l), descriptionString = "content link block") + for i in range(times): + track.duplicateContentLinkBlock(block) + callbacks._updateTrack(id(track)) + callbacks._setCursor() + +def moveBlockToOtherTrack(blockId, newTrackId, listOfBlockIdsForNewTrack): + """First move the block to the new track and then + rearrange both tracks + + It is by design only possible that a block will be copied/linked + in the same track, next to the original block. + If you want the dual action of "copy this block to a new track" you need to do it in two steps. + First copy. It can be moved later by this api function.""" + oldTrack, block = session.data.blockById(blockId) + assert oldTrack + assert block + + if len(oldTrack.blocks) == 1: + return False #it is not possible to move the last block. + + session.history.register(lambda blId=blockId, trId=id(oldTrack), l=oldTrack.asListOfBlockIds(): moveBlockToOtherTrack(blId, trId, l), descriptionString = "move block to other track") + newTrack = session.data.trackById(newTrackId) + newTrack.appendExistingBlock(block) + newTrack.rearrangeBlocks(listOfBlockIdsForNewTrack) + #We don't need to check if deleting succeeded because we already checked if there are more than 1 blocks in the track above. + oldTrack.deleteBlock(block) #It is important that we delete the block at exactly this point in time, not ealier. Otherwise the reference for undo will go away. + block.parentTrack = newTrack + + callbacks._updateTrack(id(oldTrack)) + callbacks._updateTrack(newTrackId) + callbacks._setCursor() + +def rearrangeBlocks(trackid, listOfBlockIds): + track = session.data.trackById(trackid) + oldBlockOrder = track.asListOfBlockIds() + track.rearrangeBlocks(listOfBlockIds) + + moveFunction = _createLambdaMoveToForCurrentPosition() + def registeredUndoFunction(): + moveFunction() + rearrangeBlocks(trackid, oldBlockOrder) + session.history.register(registeredUndoFunction, descriptionString = "rearrange blocks") + callbacks._updateTrack(trackid) + +def rearrangeBlocksInMultipleTracks(dictOfTrackIdsWithListOfBlockIds): + """dictOfTrackIdsWithListOfBlockIds is [trackId] = [listOfBlockIds]""" + forUndo = {} + for trackId, listOfBlockIds in dictOfTrackIdsWithListOfBlockIds.items(): + track = session.data.trackById(trackId) + oldBlockOrder = track.asListOfBlockIds() + track.rearrangeBlocks(listOfBlockIds) + forUndo[trackId] = oldBlockOrder + + moveFunction = _createLambdaMoveToForCurrentPosition() + def registeredUndoFunction(): + moveFunction() + rearrangeBlocksInMultipleTracks(forUndo) + session.history.register(registeredUndoFunction, descriptionString = "multi-track rearrange block") + + for trackId in dictOfTrackIdsWithListOfBlockIds.keys(): + callbacks._updateTrack(trackId) + callbacks._setCursor() + +def changeBlock(blockId, newParametersDict): + """for example "name" or "minimumInTicks" """ + track, block = session.data.blockById(blockId) + moveFunction = _createLambdaMoveToForCurrentPosition() + def registeredUndoFunction(): + moveFunction() + changeBlock(blockId, block.getDataAsDict()) + session.history.register(registeredUndoFunction, descriptionString = "change block") + block.putDataFromDict(newParametersDict) + callbacks._updateTrack(id(track)) + callbacks._setCursor() + +def unlinkCurrentBlock(): + currentBlockId = id(session.data.currentTrack().currentBlock()) + unlinkBlock(currentBlockId) + +def unlinkBlock(blockId): + track, block = session.data.blockById(blockId) + newData = block.getUnlinkedData() + assert newData + _setBlockData(block, newData) #handles undo and callbacks + +def _setBlockData(block, newData): + session.history.register(lambda bl=block, old=block.data: _setBlockData(bl, old), descriptionString = "set block data") + block.data = newData + #no callbacks needed. + + +#Cursor +def left(): + """move the currently active tracks cursor one position to the left. + Can be directly used by a user interface""" + session.data.currentTrack().left() + callbacks._setCursor() + +def right(): + """move the currently active tracks cursor one position to the right. + Can be directly used by a user interface""" + session.data.currentTrack().right() + callbacks._setCursor() + +def selectLeft(): + session.data.setSelectionBeginning() #or not, if there is already one. + session.data.currentTrack().left() + callbacks._setCursor(destroySelection = False) + +def selectRight(): + session.data.setSelectionBeginning() + session.data.currentTrack().right() + callbacks._setCursor(destroySelection = False) + +def measureLeft(): + session.data.currentTrack().measureLeft() + callbacks._setCursor() + +def measureRight(): + session.data.currentTrack().measureRight() + callbacks._setCursor() + +def selectMeasureLeft(): + session.data.setSelectionBeginning() + session.data.currentTrack().measureLeft() + callbacks._setCursor(destroySelection = False) + +def selectMeasureRight(): + session.data.setSelectionBeginning() + session.data.currentTrack().measureRight() + callbacks._setCursor(destroySelection = False) + +def measureStart(): + session.data.currentTrack().measureStart() + callbacks._setCursor(destroySelection = True) + +def selectMeasureStart(): + session.data.setSelectionBeginning() + session.data.currentTrack().measureStart() + callbacks._setCursor(destroySelection = False) + + +def blockLeft(): + if session.data.currentTrack().currentBlock().localCursorIndex == 0: + session.data.currentTrack().left() + session.data.currentTrack().startOfBlock() + session.data.currentTrack().left() + callbacks._setCursor() + +def blockRight(): + if session.data.currentTrack().currentBlock().isAppending(): + session.data.currentTrack().right() + session.data.currentTrack().endOfBlock() + session.data.currentTrack().right() + callbacks._setCursor() + +def selectBlockLeft(): + if session.data.currentTrack().currentBlock().localCursorIndex == 0: + session.data.currentTrack().left() + session.data.setSelectionBeginning() + session.data.currentTrack().startOfBlock() + session.data.currentTrack().left() + callbacks._setCursor(destroySelection = False) + +def selectBlockRight(): + if session.data.currentTrack().currentBlock().isAppending(): + session.data.currentTrack().right() + session.data.setSelectionBeginning() + session.data.currentTrack().endOfBlock() + session.data.currentTrack().right() + callbacks._setCursor(destroySelection = False) + +def head(): + session.data.currentTrack().head() + callbacks._setCursor() + +def tail(): + session.data.currentTrack().tail() + callbacks._setCursor() + +def selectHead(): + session.data.setSelectionBeginning() + session.data.currentTrack().head() + callbacks._setCursor(destroySelection = False) + +def selectTail(): + session.data.setSelectionBeginning() + session.data.currentTrack().tail() + callbacks._setCursor(destroySelection = False) + +def trackUp(): + session.data.trackUp() + callbacks._setCursor() + +def trackDown(): + session.data.trackDown() + callbacks._setCursor() + +def trackFirst(): + session.data.trackFirst() + callbacks._setCursor() + +def trackLast(): + session.data.trackLast() + callbacks._setCursor() + +def selectTrackUp(): + session.data.setSelectionBeginning() + session.data.trackUp() + callbacks._setCursor(destroySelection = False) + +def selectTrackDown(): + session.data.setSelectionBeginning() + session.data.trackDown() + callbacks._setCursor(destroySelection = False) + +def selectTrackFirst(): + session.data.setSelectionBeginning() + session.data.trackFirst() + callbacks._setCursor(destroySelection = False) + +def selectTrackLast(): + session.data.setSelectionBeginning() + session.data.trackLast() + callbacks._setCursor(destroySelection = False) + +def selectAllTracks(): + shortestTrack = sorted(session.data.tracks, key = lambda track: track.duration())[0] + trackIndex = session.data.tracks.index(shortestTrack) + session.data.goTo(trackIndex, 0, 0) #the position in the track doesn't matter. we just want into the track. + tail() + tickindexShortestTrack = session.data.currentTrack().state.tickindex + #assert session.data.currentTrack().state.tickindex == tickindexShortestTrack == shortestTrack.duration(), (session.data.currentTrack().state.tickindex, tickindexShortestTrack, shortestTrack.duration()) + session.data.trackFirst() + session.data.currentTrack().head() + #Create Selection + session.data.setSelectionBeginning() + session.data.trackLast() + session.data.currentTrack().goToTickindex(tickindexShortestTrack) + callbacks._setCursor(destroySelection = False) + +def selectTrack(): + head() + selectTail() + +def selectMeasureColumn(): + measureStart() + trackFirst() + measureStart() + selectMeasureRight() + selectTrackLast() + +def toTickindex(trackid, tickindex, destroySelection = True): + """Was implemented for mouse clicking in a GUI Score""" + if tickindex < 0: + tickindex = 0 + session.data + trackObject = session.data.trackById(trackid) + session.data.trackIndex = session.data.tracks.index(trackObject) + trackObject.goToTickindex(tickindex) + callbacks._setCursor(destroySelection) + +def selectToTickindex(trackid, tickindex): + session.data.setSelectionBeginning() + toTickindex(trackid, tickindex, destroySelection = False) + +def up(): + session.data.cursor.up() + callbacks._setCursor(destroySelection = False) + #this does not create a selection if there was none. + #You need to call setSelectionBeginning() to start a selection. + #However, this does modify an existing selection since the cursor value changes + +def down(): + session.data.cursor.down() + callbacks._setCursor(destroySelection = False) + +def upOctave(): + session.data.cursor.upOctave() + callbacks._setCursor(destroySelection = False) + +def downOctave(): + session.data.cursor.downOctave() + callbacks._setCursor(destroySelection = False) + +def _delete(backspace = False): + def undoDelete(deletedItemCopy): + """We need to go back one position after insert""" + insertItem(deletedItemCopy) + left() #sets the cursor + + if backspace: #this is not in backspace() itself because it disturbs _deleteSelection() when we go left before deleting. + session.data.currentTrack().left() #does not trigger a callback. + + moveFunction = _createLambdaMoveToForCurrentPosition() + deletedItemCopy = session.data.currentTrack().delete() #this is obviously _not_ track-delete but item delete + if deletedItemCopy: #and not None / appending position + if backspace: + def registeredUndoFunction(): + moveFunction() + insertItem(deletedItemCopy) + session.history.register(registeredUndoFunction, descriptionString = "delete item") + else: + def registeredUndoFunction(): + moveFunction() + undoDelete(deletedItemCopy) + session.history.register(registeredUndoFunction, descriptionString = "delete item") + callbacks._updateChangedTracks() + callbacks._setCursor() + +def backspace(): + """Callback and Undo are done via delete""" + delete(backspaceForSingleItemDelete = True) + +def delete(backspaceForSingleItemDelete = None): + """Choose wether to delete a single item or a selection. + Delete selections is tricky thats why this is done not + in the usual apply-function-to-selection way""" + if session.data.cursorWhenSelectionStarted: + _deleteSelection() + else: + _delete(backspaceForSingleItemDelete) + +#Chose prevailing durations + +def prevailingLonga(): + pass #TODO +def prevailingBrevis(): + pass #TODO +def prevailing1(): + session.data.cursor.prevailingBaseDuration = D1 + callbacks._prevailingBaseDurationChanged(D1) +def prevailing2(): + session.data.cursor.prevailingBaseDuration = D2 + callbacks._prevailingBaseDurationChanged(D2) +def prevailing4(): + session.data.cursor.prevailingBaseDuration = D4 + callbacks._prevailingBaseDurationChanged(D4) +def prevailing8(): + session.data.cursor.prevailingBaseDuration = D8 + callbacks._prevailingBaseDurationChanged(D8) +def prevailing16(): + session.data.cursor.prevailingBaseDuration = D16 + callbacks._prevailingBaseDurationChanged(D16) +def prevailing32(): + session.data.cursor.prevailingBaseDuration = D32 + callbacks._prevailingBaseDurationChanged(D32) + + +##Chords and duration modification + +def insertChord(baseDuration, pitchToInsert): + duration = items.Duration(baseDuration) + #duration.dots = session.data.cursor.getPrevailingDot() + duration.dots = 0 + + #audio Feedback as callback? #TODO + chord = items.Chord(duration, pitchToInsert) + insertItem(chord) + +def insertCursorChord(baseDuration): + """Insert a new chord with one note to the track. + The intial note gets its pitch from the cursor position, to scale""" + keysig = session.data.currentTrack().state.keySignature() + pitchToInsert = pitchmath.toScale(session.data.cursor.pitchindex, keysig) + insertChord(baseDuration, pitchToInsert) + +def addNoteToChord(pitchToInsert): + """Utilized by midi-in""" + #TODO: in the past this was possible with prevailing duration as well. But it got too complex with undo. Just pitch for now. + _applyToItem("addNote", parameters = [pitchToInsert]) + +def addCursorNoteToChord(): + if session.data.cursorWhenSelectionStarted: + return False + else: + keysig = session.data.currentTrack().state.keySignature() + pitchToInsert = pitchmath.toScale(session.data.cursor.pitchindex, keysig) + _applyToItem("addNote", parameters = [pitchToInsert]) + +def deleteCursorNoteFromChord(): + if session.data.cursorWhenSelectionStarted: + return False + else: + _applyToItem("removeNoteNearPitch", parameters = [session.data.cursor.pitchindex]) + + +def insertBrevis(): + pass #TODO +def insertLonga(): + pass #TODO +def insert1(): + insertCursorChord(D1) +def insert2(): + insertCursorChord(D2) +def insert4(): + insertCursorChord(D4) +def insert8(): + insertCursorChord(D8) +def insert16(): + insertCursorChord(D16) +def insert32(): + insertCursorChord(D32) +def insert64(): + insertCursorChord(D64) +def insert128(): + insertCursorChord(D128) + +#and so on + +functionType = type(lambda: print()) #not a built-in function or method, just +def _applyToItem(functionAsString, parameters = []): + """ + see history.py / undo docstring + + This is the entry point. Further undo and redo are done by + _applyToItemCircularUndoRedo() + + Internal functions that do something but do not return an undoFunction + are considered broken. Not returning an undo function is assumed + as "nothing happened, nothing changed". + + """ + #TODO: If getattr with string turns out to be a performance problem we must change that to a lambda function as only parameter and the api function has to get the item itself. Then we can use _applyToItemCircularUndoRedo directly (and rename it) + def do(): + i = session.data.currentItem() + if not i: return None #Appending Position or otherwise no item. + undoFunction = getattr(i, functionAsString)(*parameters) #Get the real function, execute it and take the return as undo function. Each function returns an undo function (if it supports undo. see below) + if undoFunction: #the command was supported by the item. e.g. rests don't support shiftUp. + assert type(undoFunction) is functionType + + moveFunction = _createLambdaMoveToForCurrentPosition() + def registeredUndoFunction(): + moveFunction() + _applyToItemCircularUndoRedo(undoFunction) + + session.history.register(registeredUndoFunction, descriptionString = functionAsString) + simpleCommand(do) + + +def _applyToItemCircularUndoRedo(function): + """called by _applyToItem and by itself. + Function must be a command that can precisely undo itself: + see history / undo docstring + + Toggles (e.g. bools) are not suitable undo functions. + For example beamGroups. They are just True and False, so at first glance you could think that + "do" is toggle so undo is toggle as well. But "do" can also be "removeBeams" in a selection. + A precise function is a function that stores or restores the exact old state as lambda parameter + or similar. + """ + def do(): + undoFunction = function() + moveFunction = _createLambdaMoveToForCurrentPosition() + def registeredUndoFunction(): + moveFunction() + _applyToItemCircularUndoRedo(undoFunction) + session.history.register(registeredUndoFunction, descriptionString = function.__name__ ) + simpleCommand(do) + + +def _applyToSelection(itemFunctionAsString, parameterListForEachSelectedItem = []): + """ + Apply a function to a selection and undo. + The function must not rely on track.state, especially not on + the current keysignature etc. + + Even if the functions add or remove the content (like api.split does) it will work. + + There is an optional parameter which is a list of parameter-iterables. + The top level list must have exactly the len() as items in selection. + + It was written for undo because you know the number of items + exactly here. This function itself creates this list for undo/redo. + + Format of parameterListForEachSelectedItem. In this example we already know + that we apply to a selection with 3 items.: + + Our function expects two parameters, float and bool. + parameterSet_One = [parameterValue=3.1415, parameterVerbose=True] + parameterSet_Two = [parameterValue=42.42, parameterVerbose=False] + parameterSet_Three = [parameterValue=100.001, parameterVerbose=False] + parameterListForEachSelectedItem = [parameterSet_One, parameterSet_Two, parameterSet_Three] + _applyToSelection("doFunction", parameterListForEachSelectedItem) + + You also can use a len of one for the parameterListForEachSelectedItem. It will be + applied to all items in the selection. + onlyParameterSet = [parameterValue=42.0, parameterVerbose=True] + parameterListForAllSelectedItem = [onlyParameterSet] + _applyToSelection("doFunction", parameterListForAllSelectedItem) + + + Or, a typical case, just one parameter, the same, for each item in + the selection. The parameter itself can be a list itself as well. + For example a duration.tuplets, which is list of tuples(!) + theParameter = [[(2,3)]] #This is a tuplet with only one fraction, triplet. It is for a notelist with only one note. + #theParameter = [ [(2,3), (4,5)], [(4,5), (1,2), (3,4)] ] #notelist of 2 with a double-nested tuplet for the first and a triple nested tuplet for the second note. + onlyParameterSet = [theParameter] + parameterListForAllSelectedItem = [onlyParameterSet] + _applyToSelection("setTuplet", parameterListForAllSelectedItem) + + Now look how that would look written out, especially since there is only one parameter. + It is crazy, but neccessary. + _applyToSelection("setTuplet", [[[[(2,3)]]]]) + """ + + def _replaceMagicStringParameters(listOfParameters, cachedTrackState): + """ + Replaces the magic strings in our parameterlist + with the actual values saved for this moment by + score.listOfSelectedItems() + + listOfParameters is a list with parameters for the + called function. This function is sometimes another list. + For example a parameter for each note in a chord. + """ + result = [] + for param in listOfParameters: + if type(param) is list: + result.append(_replaceMagicStringParameters(param, cachedTrackState)) + else: + if param in cachedTrackState: + result.append(cachedTrackState[param]) + else: + result.append(param) + return result + + withMagicString = any(type(elem) is str for elem in flatList(parameterListForEachSelectedItem)) + + validSelection, topLeftCursor, bottomRightCursor, listOfChangedTrackIds, *selectedTracksAndItems = session.data.listOfSelectedItems(removeContentLinkedData = True) + if validSelection: + if len(parameterListForEachSelectedItem) == 1: #only one value. Use it for all function calls. This is expected most of the time when we get a value from the user directly. Like "make all notes quintuplets!". + parameterGenerator = EndlessGenerator(parameterListForEachSelectedItem[0]) + else: + parameterGenerator = (iterable for iterable in parameterListForEachSelectedItem) #we make a generator because that works across tracks in the nested for loop. zip() does not. + + cursorWasAtSelectionStart = session.data.goToSelectionEnd() #Moves the cursor to the bottom right end of the selection. This alone will make the selection correct at the end of processing if the duration was changed. But it is still not enough for functions that change the number of items in the selection, e.g. split + #We may be in a different track now. + trackIndex, blockIndex, localCursorIndexInBlock = session.data.where() #localCursorIndexInBlock is unreliable... + itemRightOfTheSelection = session.data.currentTrack().currentItem() #so we replace it with an item. Since the selection ends left of the current item (current one not included) it cannot be affected by the process below. it is safe to remember as marker. + + undoFunctions = [] + for track in selectedTracksAndItems: + for item, cachedTrackState in track: #cachedTrackState is a selected set of cached track.state values, specifically designed to assist apply to selection + listOfParameters = next(parameterGenerator) if parameterListForEachSelectedItem else () + assert listOfParameters.__iter__ #will not throw an assert but an AttributeError. But who cares. + if withMagicString: + listOfParameters = _replaceMagicStringParameters(listOfParameters, cachedTrackState) + undoFunction = getattr(item, itemFunctionAsString)(*listOfParameters) #ACTION! + + if undoFunction: #the command was supported by the item. e.g. rests don't support shiftUp. + assert type(undoFunction) is functionType + undoFunctions.append(undoFunction) + + moveFunction = _createLambdaMoveToForCurrentPosition() + def registeredUndoFunction(): + moveFunction() + _applyToSelectionCircularRedoUndo(undoFunctions, listOfChangedTrackIds) + session.history.register(registeredUndoFunction, descriptionString = "selection: {}".format(itemFunctionAsString)) + + #Go to the end of the selection + all new items and durations. + session.data.goToItemInCurrentBlock(itemRightOfTheSelection) + _updateCallbackForListOfTrackIDs(listOfChangedTrackIds) + + #The selection now has the right boundaries. Now we return the cursor where it was for the user. + if cursorWasAtSelectionStart: #we were at the selection start before processing. returning... + session.data.goToSelectionStart() #keeps the selection as it is, just switches the cursor position from one end of the S. to the other. + + callbacks._setCursor(destroySelection = False) + +def _applyToSelectionCircularRedoUndo(functions, listOfChangedTrackIds): + """ + Functions are a list of functions which don't need any parameters. + They are defined as lambdas with preset parameters. + + We don't need a selection for actually making applyToSelection undo. + All affected tracks, items, methods and values are already known. + + Functions must not be be apply-to-selection functions. To avoid + callback confusion best practice is to use no api function at all + in the functions list. + + When this was written there were only score/track/item functions + possible at all. Keep it that way. + """ + session.data.cursorWhenSelectionStarted = None #better safe than sorry. It will be destroyed by setCursor below anyway. + undoFunctions = [f() for f in functions] #side effect: make undo happen. + moveFunction = _createLambdaMoveToForCurrentPosition() + def registeredUndoFunction(): + moveFunction() + _applyToSelectionCircularRedoUndo(undoFunctions, listOfChangedTrackIds) + session.history.register(registeredUndoFunction, descriptionString = "selection stuff") + _updateCallbackForListOfTrackIDs(listOfChangedTrackIds) + callbacks._setCursor() + +def augment(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("augment") + else: + _applyToItem("augmentNoteNearPitch", parameters = [session.data.cursor.pitchindex]) + +def diminish(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("diminish") + else: + _applyToItem("diminishNoteNearPitch", parameters = [session.data.cursor.pitchindex]) + +def dot(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("toggleDot") + else: + _applyToItem("toggleDotNearPitch", parameters = [session.data.cursor.pitchindex]) + +def triplet(): + """ + From anything (empty, other tuplet) to triplet + and back to empty""" + if session.data.cursorWhenSelectionStarted: + _applyToSelection("toggleTriplet") + else: + _applyToItem("toggleTripletNearPitch", parameters = [session.data.cursor.pitchindex]) + +def quintuplet(): + """ + Make it a quintuplet, no toggle + !setTuplet has a different parameter format than setTupletNearPitch! + """ + if session.data.cursorWhenSelectionStarted: + tupletListForDuration = [[[[(4,5)]]]] #see docstring for _applyToSelection + _applyToSelection("setTuplet", parameterListForEachSelectedItem = tupletListForDuration) + else: + tupletListForSingleNoteDuration = [(4,5)] + _applyToItem("setTupletNearPitch", parameters = [session.data.cursor.pitchindex, tupletListForSingleNoteDuration]) + +def tie(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("toggleDurationKeyword", parameterListForEachSelectedItem = [[[D_TIE]]]) + else: + _applyToItem("toggleDurationKeywordNearPitch", parameters = [session.data.cursor.pitchindex, D_TIE]) + +def tenuto(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("toggleDurationKeyword", parameterListForEachSelectedItem = [[[D_TENUTO]]]) + else: + _applyToItem("toggleDurationKeywordNearPitch", parameters = [session.data.cursor.pitchindex, D_TENUTO]) + +def staccato(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("toggleDurationKeyword", parameterListForEachSelectedItem = [[[D_STACCATO]]]) + else: + _applyToItem("toggleDurationKeywordNearPitch", parameters = [session.data.cursor.pitchindex, D_STACCATO]) + +def split(newparts): + """ + Split a chord into two or more. + This is only for chords. + Technically this works with rests as well. + However, there is little musical meaning in splitted rests. + And it does not make sense for further editing. + """ + + #TODO: Test this for the whole selection before doing something. And as always: test first, not during performing the changes. + #if currentItem.durationGroup.hasTuplet() and not newparts in (2,4,8): + #return False #no further splitting + + if session.data.cursorWhenSelectionStarted: + _applyToSelection("split", parameterListForEachSelectedItem = [[newparts]],) #chord.split does not expect a list as parameter. just one parameter. + #Split introduces more items. The selection needs extension. + + else: + _applyToItem("split", parameters = [newparts]) + for i in range(newparts): + right() + +#Pitch modifications +def sharpenNote(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("sharpen") + else: + _applyToItem("sharpenNoteNearPitch", parameters = [session.data.cursor.pitchindex]) + +def flattenNote(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("flatten") + else: + _applyToItem("flattenNoteNearPitch", parameters = [session.data.cursor.pitchindex]) + + +def stepUp(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("stepUp", parameterListForEachSelectedItem = [[["keySignature"]]]) + else: + _applyToItem("stepUpNoteNearPitch", parameters = [session.data.cursor.pitchindex, session.data.currentTrack().state.keySignature()]) + up() + + +def stepDown(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("stepDown", parameterListForEachSelectedItem = [[["keySignature"]]]) + else: + _applyToItem("stepDownNoteNearPitch", parameters = [session.data.cursor.pitchindex, session.data.currentTrack().state.keySignature()]) + down() + +def stepUpOctave(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("stepUpOctave") + else: + _applyToItem("stepUpOctaveNoteNearPitch", parameters = [session.data.cursor.pitchindex]) + upOctave() + +def stepDownOctave(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("stepDownOctave") + else: + _applyToItem("stepDownOctaveNoteNearPitch", parameters = [session.data.cursor.pitchindex]) + downOctave() + +def transpose(rootPitch, targetPitch): + """For the cursor position. Based on automatic transpose. The interval is caculated from + two pitches. + There is also tranposeScore. But no transposeTrack, this is just select track and transpose.""" + if session.data.cursorWhenSelectionStarted: + _applyToSelection("intervalAutomatic", parameterListForEachSelectedItem = [[rootPitch, targetPitch]]) + else: + _applyToItem("intervalAutomatic", parameters = [rootPitch, targetPitch]) + #no cursor movement. + + + +def toggleBeam(): + """Place a beam at each end of the selection if all durations are <= D8""" + if session.data.cursorWhenSelectionStarted: + validSelection, topLeftCursor, bottomRightCursor, listOfChangedTrackIds, *selectedTracksAndItems = session.data.listOfSelectedItems(removeContentLinkedData = True) + if validSelection and len(listOfChangedTrackIds) == 1 : + #a valid selection has >=2 items. + filteredList = [item for item, props in selectedTracksAndItems[0] if type(item) in (items.Chord, items.Rest)] #only music items of the only track, which are themselves tuples (item, propertiesLikeKeysigs) + #oneDur = filteredList[0].durationGroup.baseDuration + #correctDurations = oneDur <= D8 and all(item.durationGroup.baseDuration == oneDur for item in filteredList) + correctDurations = all(item.durationGroup.baseDuration <= D8 for item in filteredList) + if correctDurations: + first = filteredList[0] + last = filteredList[-1] + if type(first) is items.Chord and type(last) is items.Chord: + removeBeam() #clean up before setting a new boundary + first.toggleBeam() + last.toggleBeam() + callbacks._updateTrack(*listOfChangedTrackIds) + return True + + return False #all branches except the only True one end here. + else: + _applyToItem("toggleBeam") + +def removeBeam(): + """Get rid of all beams in the selection. This is meant as clean-up tool for the user + but also utilized in toggleBeam""" + if session.data.cursorWhenSelectionStarted: + _applyToSelection("removeBeam") + else: + _applyToItem("removeBeam") + +#Rests +def insertRest(baseDuration): + duration = items.Duration(baseDuration) + #duration.dots = session.data.cursor.getPrevailingDot() + duration.dots = 0 + + #audio Feedback? + rest = items.Rest(duration) + insertItem(rest) + +def insertRest1(): + insertRest(D1) +def insertRest2(): + insertRest(D2) +def insertRest4(): + insertRest(D4) +def insertRest8(): + insertRest(D8) +def insertRest16(): + insertRest(D16) +def insertRest32(): + insertRest(D32) +def insertRest64(): + insertRest(D64) +def insertRest128(): + insertRest(D128) + +def insertMultiMeasureRest(numberOfMeasures): + """MultiMeasureRests get calculated on export""" + assert int(numberOfMeasures) == numberOfMeasures and numberOfMeasures > 0 + if session.data.currentTrack().state.metricalInstruction().oneMeasureInTicks > 0: + insertItem(items.MultiMeasureRest(numberOfMeasures)) + +#Clefs +def insertClef(clefString): + clef = items.Clef(clefString) + insertItem(clef) + +#Slurs +def insertLegatoSlur(): + """no open and close. The context and order determines what + type of slur we insert, even export. Dynamically adjusts""" + slur = items.LegatoSlur() + insertItem(slur) + + +#Key Signatures +def insertKeySignature(root, scheme): + keysig = items.KeySignature(pitchmath.plain(root), scheme) + insertItem(keysig) + +def commonKeySignaturesAsList(): + """For the GUIs convenience so they can populate their + drop down lists. + Yes, we could use the dict from insertCommonKeySignature but + we want a special order which is not the same as the alphabetical. + So a bit of redundancy is ok.""" + return [ + "Major", + "Minor", + "Dorian", + "Phrygian", + "Lydian", + "Mixolydian", + "Locrian", + "Hollywood", + ] + +def insertCommonKeySignature(root, scheme): + """example: + insertCommonKeySignature(P_C, "Major") + """ + schemes = { + "Major": [0,0,0,0,0,0,0], + "Minor": [0,0,-10,0,0,-10,-10], + "Dorian": [0,0,-10,0,0,0,-10], + "Phrygian": [0,-10,-10,0,0,-10,-10], + "Lydian": [0,0,0,+10,0,0,0], + "Mixolydian": [0,0,0,0,0,0,-10], + "Locrian": [0,-10,-10,0,-10,-10,-10], + "Hollywood": [0,0,0,0,0,-10,-10], #The "Hollywood"-Scale. Stargate, Lord of the Rings etc. + #TODO: MOAR! + } + insertKeySignature(root, schemes[scheme]) + +def insertCursorCommonKeySignature(scheme): + """Root note is generated from the cursor pitch position and takes the previous keysig + into account.""" + root = pitchmath.plain(session.data.cursor.pitchindex) + + keysig = session.data.currentTrack().state.keySignature() + pitchToInsert = pitchmath.toScale(session.data.cursor.pitchindex, keysig) + + insertCommonKeySignature(pitchToInsert, scheme) + + + +#def insertTimeSignature(demoniator, nominator): #upper/lower. +# """example: +# insertTimeSignature(4, 210*2**8) #4/4 +# """ +# insertItem(items.TimeSignature(demoniator, nominator)) + + +#Metrical Instructions +def insertMetricalInstruction(treeOfInstructions, lilypondOverride = None): + item = items.MetricalInstruction(treeOfInstructions) + if lilypondOverride: + item.lilypondParameters["override"] = lilypondOverride + insertItem(item) + +def commonMetricalInstructionsAsList(): + """for musical reasons 5/4 and 7/8 and other a-symetrical + metrical instructions cannot be in here since it is unknown which + internal version the user wants.""" + return [ + "off", + "4/4", + "3/4", + "6/8", + "2/4", + "12/8", + "6/4", + "3/8", + "1/1", + ] + +def insertCommonMetricalInstrucions(scheme): + """A metrical instruction requires a lilypond override. You can use them without of course but + they will not work when exported.""" + schemes = { + "off" : (), + "2/4" : (D4, D4), + "3/4" : (D4, D4, D4), + "4/4" : ((D4, D4), (D4, D4)), + "6/8" : (int(D4*1.5),int(D4*1.5)), #aka 2/4 with triplet sub-level + "12/8" : ((D8, D8, D8), (D8, D8, D8), (D8, D8, D8), (D8, D8, D8)), #aka 4/4 with triplet sub-level + "6/4" : ((D4, D4, D4),(D4, D4, D4)), + "3/8" : (D8, D8, D8), + "1/1" : (D1,), + } + lilypond = { + "off" : "\\mark \"No meter\" \\cadenzaOn ", + "2/4" : "\\cadenzaOff \\time 2/4", + "3/4" : "\\cadenzaOff \\time 3/4", + "4/4" : "\\cadenzaOff \\time 4/4", + "6/8" : "\\cadenzaOff \\time 6/8", + "12/8" : "\\cadenzaOff \\time 12/8", + "6/4" : "\\cadenzaOff \\time 6/4", + "3/8" : "\\cadenzaOff \\time 3/8", + "1/1" : "\\cadenzaOff \\time 1/1", + } + insertMetricalInstruction(schemes[scheme], lilypondOverride = lilypond[scheme]) + +#Velocity and Dynamic Signatures +def insertDynamicSignature(keyword): + dynSig = items.DynamicSignature(keyword) + insertItem(dynSig) + +def insertDynamicPiano(): + insertDynamicSignature("p") + +def insertDynamicForte(): + insertDynamicSignature("f") + +def insertDynamicTacet(): + insertDynamicSignature("tacet") + +def insertDynamicRamp(): + """Crescendo or Decrescendo. Determined automatically""" + dynRamp = items.DynamicRamp() + insertItem(dynRamp) + + +def setNoteDynamic(noteId, value): + listOfTracks, note = session.data.noteById(noteId) + session.history.register(lambda nId=noteId, v=note.dynamic.velocityModification: setNoteDynamic(nId, v), descriptionString = "set note dynamic") + #todo: better undo? + note.dynamic.velocityModification = value + for track in listOfTracks: + callbacks._updateTrack(id(track)) + +def clearNoteDynamic(noteId): + listOfTracks, note = session.data.noteById(noteId) + session.history.register(lambda nId=noteId, v=note.dynamic.velocityModification: setNoteDynamic(nId, v), descriptionString = "clear note dynamic") + #todo: better undo? + note.dynamic.velocityModification = 0 + for track in listOfTracks: + callbacks._updateTrack(id(track)) + +def setNoteMods(noteId, valueOn, valueOff): + """ + value is a float that is added as percentage of the original value + (without mods) + + Is used for a specific note, not the cursor position. + """ + listOfTracks, note = session.data.noteById(noteId) + session.history.register(lambda nId=noteId, on=note.duration.shiftStart, off=note.duration.shiftEnd: setNoteMods(nId, on, off), descriptionString = "fine tune note duration") + #todo: better undo? + note.duration.shiftStart = valueOn + note.duration.shiftEnd = valueOff + #we can't use callbacks._updateChangedTracks() here because that depends on the cursor position and checks for linked content for the currentBlock. the note can be anywhere + for track in listOfTracks: + callbacks._updateTrack(id(track)) + +def clearNoteMod(noteId): + """see setNoteMods""" + listOfTracks, note = session.data.noteById(noteId) + session.history.register(lambda nId=noteId, on=note.duration.shiftStart, off=note.duration.shiftEnd: setNoteMods(nId, on, off), descriptionString = "clear note duration fine tuning") + #todo: better undo? + note.duration.shiftStart = 0 + note.duration.shiftEnd = 0 + for track in listOfTracks: + callbacks._updateTrack(id(track)) + + +#Cursor Variants of the above +def moreVelocity(): + """Increase the relative velocity modficator for the note + nearest to the cursor. With selection/single support.""" + if session.data.cursorWhenSelectionStarted: + _applyToSelection("moreVelocity") + else: + _applyToItem("moreVelocityNearPitch", parameters = [session.data.cursor.pitchindex]) + +def lessVelocity(): + """Opposite of moreVelocity""" + if session.data.cursorWhenSelectionStarted: + _applyToSelection("lessVelocity") + else: + _applyToItem("lessVelocityNearPitch", parameters = [session.data.cursor.pitchindex]) + +def moreDuration(): + """Increase the duration modficator for the note + nearest to the cursor. With selection/single support. + For simplicity reasons this only shifts the right end, the ending, + of the note. The beginning needs the full command setNoteMods""" + if session.data.cursorWhenSelectionStarted: + _applyToSelection("moreDuration") + else: + _applyToItem("moreDurationNearPitch", parameters = [session.data.cursor.pitchindex]) + +def lessDuration(): + """Opposite of moreDuration. But still for the ending of the note, + not the beginning""" + if session.data.cursorWhenSelectionStarted: + _applyToSelection("lessDuration") + else: + _applyToItem("lessDurationNearPitch", parameters = [session.data.cursor.pitchindex]) + +def resetDurationVelocity(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("resetVelocityAndDurationMods") + else: + _applyToItem("resetVelocityAndDurationModsNearPitch", parameters = [session.data.cursor.pitchindex]) + +#Graphs. Tempo and CC +def getListOfGraphInterpolationTypesAsStrings(): + return ["linear", "standalone"] + + +#CC user points +#TODO: no undo here for various reasons. Many functions auto-delete hidden or overlapping cc-graph items with no way of currently remembering them. +#history.py say "Better no history than a wrong history." so we clear it. + + +def newGraphTrackCC(trId, cc): + """add a new CC Path for CC to the given Track. + Do nothing if already existent.""" + track = session.data.trackById(trId) + track.newGraphTrackCC(cc) + session.history.clear() + callbacks._graphCCTracksChanged(trId) #create structure: all CC graphs, accessed by CC number (0-127) + callbacks._updateGraphTrackCC(trId, cc) + +def _addExistingGraphTrackCC(trId, cc, graphTrackObject): + """For undo deleteGraphTrackCC""" + track = session.data.trackById(trId) + track.addExistingGraphTrackCC(cc, graphTrackObject) + session.history.clear() + callbacks._graphCCTracksChanged(trId) #create structure: all CC graphs, accessed by CC number (0-127) + callbacks._updateGraphTrackCC(trId, cc) + +def deleteGraphTrackCC(trId, cc): + track = session.data.trackById(trId) + deletedGraphTrackObject = track.deleteGraphTrackCC(cc) + session.history.clear() + callbacks._graphCCTracksChanged(trId) #this should delete any GUI cc track + +def addGraphItem(blockId, positionInTicksRelativeToBlock, newCCValue): + """blockId includes the track as well as the CC""" + graphItem = GraphItem(newCCValue) + _addExistingGraphItem(blockId, positionInTicksRelativeToBlock, graphItem) + +def _addExistingGraphItem(blockId, positionInTicksRelativeToBlock, graphItem): + """blockId includes the track as well as the CC""" + trId, cc, graphBlock = session.data.graphBlockById(blockId) + session.history.clear() + graphBlock.insert(graphItem, positionInTicksRelativeToBlock) + callbacks._updateGraphTrackCC(trId, cc) + +def removeGraphItem(graphItemId): + trId, cc, graphBlock, graphItem = session.data.graphItemById(graphItemId) + tickPositionRelativeToBlockStart = graphBlock.find(graphItem) + graphBlock.remove(tickPositionRelativeToBlockStart) + session.history.clear() + callbacks._updateGraphTrackCC(trId, cc) + +def changeGraphItem(graphItemId, moveInTicks, newCCValue): + trId, cc, graphBlock, graphItem = session.data.graphItemById(graphItemId) + session.history.clear() + currentTickPositionRelativeToBlock = graphBlock.find(graphItem) + graphBlock.move(currentTickPositionRelativeToBlock, currentTickPositionRelativeToBlock + moveInTicks) + graphItem.ccStart = newCCValue + callbacks._updateGraphTrackCC(trId, cc) + +def changeGraphItemInterpolation(graphItemId, graphType): + """graphType is "linear" or "standalone" """ + trId, cc, graphBlock, graphItem = session.data.graphItemById(graphItemId) + session.history.clear() + graphItem.graphType = graphType + callbacks._updateGraphTrackCC(trId, cc) + +def changeGraphBlockDuration(graphBlockId, newDurationInTicks): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + session.history.clear() + graphBlock.duration = newDurationInTicks + callbacks._updateGraphTrackCC(trId, cc) + +def appendGraphBlock(trId, cc): + """Append a small duration block to the current cc track""" + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + newBlock = ccTrack.appendGraphBlock() + session.history.clear() + callbacks._updateGraphTrackCC(trId, cc) + +def rearrangeCCBlocks(trId, cc, listOfBlockIds): + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + session.history.clear() + ccTrack.rearrangeBlocks(listOfBlockIds) + callbacks._updateGraphTrackCC(trId, cc) + +def moveCCBlockToOtherTrack(graphBlockId, newTrackId, listOfBlockIdsForNewTrack): + """Modified copy of api.moveBlockToOtherTrack. + This only moves to the same CC value. not from volume to modwheel.""" + + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + oldccTrack = session.data.trackById(trId).ccGraphTracks[cc] + newGraphTrack = session.data.trackById(newTrackId).ccGraphTracks[cc] #we assume this track has this CC already activated. + + if len(oldccTrack.blocks) == 1: + return False #it is not possible to move the last block. + + newGraphTrack.appendExistingGraphBlock(graphBlock) + newGraphTrack.rearrangeBlocks(listOfBlockIdsForNewTrack) + oldccTrack.deleteBlock(graphBlock) #It is important that we delete the block at exactly this point in time, not ealier. Otherwise the reference for undo will go away. + graphBlock.parentGraphTrack = newGraphTrack + + session.history.clear() + callbacks._updateGraphTrackCC(trId, cc) + callbacks._updateGraphTrackCC(newTrackId, cc) + + +def changeCCBlock(graphBlockId, newParametersDict): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + session.history.clear() + graphBlock.putDataFromDict(newParametersDict) + callbacks._updateGraphTrackCC(trId, cc) + +def duplicateCCBlock(graphBlockId, times = 1): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + session.history.clear() + for i in range(times): + ccTrack.duplicateBlock(graphBlock) + callbacks._updateGraphTrackCC(trId, cc) + +def duplicateContentLinkCCBlock(graphBlockId, times = 1): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + session.history.clear() + for i in range(times): + ccTrack.duplicateContentLinkBlock(graphBlock) + callbacks._updateGraphTrackCC(trId, cc) + +def unlinkCCBlock(graphBlockId): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + newData, newDuration = graphBlock.getUnlinkedData() + assert newData, newData + assert newDuration, newDuration + _setCCBlockData(graphBlock, newData, newDuration) #handles undo and callbacks + +def _setCCBlockData(graphBlock, newData, newDuration): + """For undo and redo. + newDuration is the original list with a single integer that may be content linked. + Thats why we get and set the block._duration parameter directly instead of using the setter + .duration.""" + session.history.register(lambda bl=graphBlock, old=graphBlock.data, dur=graphBlock._duration: _setCCBlockData(bl, old, dur), descriptionString = "set CC block data") + graphBlock.data = newData + graphBlock._duration = newDuration + #no callbacks needed. + +def deleteCCBlock(graphBlockId): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + oldLayout = ccTrack.asListOfBlockIds() + deletedBlock = ccTrack.deleteBlock(graphBlock) + if deletedBlock: #not the last block + #Blocks are never truly deleted but a stored in the GraphBlock.allBlocks dict. This keeps the reference to this deleted block alive and it can be added through rearrange, which gets its blocks from this dict. + session.history.clear() + callbacks._updateGraphTrackCC(trId, cc) + +def extendLastCCBlockToTrackLength(trId, cc): + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + lastCCBlock = ccTrack.blocks[-1] + session.history.clear() + lastCCBlock.extendToTrackLength(ccTrack) + callbacks._updateGraphTrackCC(trId, cc) + +def splitCCBlock(graphBlockId, positionInTicksRelativeToBlock): + """tick position is relative to block start""" + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + success = ccTrack.splitGraphBlock(graphBlock, positionInTicksRelativeToBlock) + session.history.clear() + callbacks._updateGraphTrackCC(trId, cc) + +def mergeWithNextGraphBlock(graphBlockId): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + positionForSplit = ccTrack.mergeWithNextGraphBlock(graphBlock) + session.history.clear() #TODO: merging deletes hidden items in the first block without remembering them for undo + callbacks._updateGraphTrackCC(trId, cc) + +#Tempo Track + +#TODO: no undo here for various reasons. Many functions auto-delete hidden or overlapping tempo items with no way of currently remembering them. +#history.py says "Better no history than a wrong history." so we clear it, for now. + +def addTempoItem(blockId, positionInTicksRelativeToBlock, unitsPerMinute, referenceTicks, graphType = "standalone"): + """blockId includes the track as well as the CC""" + tempoItem = TempoItem(unitsPerMinute, referenceTicks) + tempoItem.graphType = graphType + _addExistingTempoItem(blockId, positionInTicksRelativeToBlock, tempoItem) #handles undo and callbacks + return tempoItem + +def _addExistingTempoItem(blockId, positionInTicksRelativeToBlock, tempoItem): + tempoBlock = session.data.tempoTrack.tempoBlockById(blockId) + tempoBlock.insert(tempoItem, positionInTicksRelativeToBlock) + session.history.clear() #TODO: overwriting a tempo item does not remember the old one + callbacks._updateTempoTrack() + +def removeTempoItem(tempoItemId): + tempoBlock, tempoItem = session.data.tempoTrack.tempoItemById(tempoItemId) + tickPositionRelativeToBlockStart = tempoBlock.find(tempoItem) + tempoBlock.remove(tickPositionRelativeToBlockStart) + session.history.clear() # no redo (add item) + callbacks._updateTempoTrack() + +def moveTempoItem(tempoItemId, tickPositionAbsolute): + """Figures out the target block automatically""" + blockId, blockPosition = session.data.tempoTrack.tempoBlocKByAbsolutePosition(tickPositionAbsolute) + new_positionInTicksRelativeToBlock = tickPositionAbsolute - blockPosition + tempoBlock, tempoItem = session.data.tempoTrack.tempoItemById(tempoItemId) + tempoBlock.remove(tempoBlock.find(tempoItem)) + _addExistingTempoItem(blockId, new_positionInTicksRelativeToBlock, tempoItem) + +def removeCurrentTempoItem(): + """remove the tempo item which is at the tickindex of the cursor or left of it""" + tempoItem = session.data.tempoTrack.tempoAtTickPosition(session.data.currentTrack().state.tickindex) #This returns the leftmost item of the tick position + removeTempoItem(id(tempoItem)) #undo and callback + +def changeTempoBlockDuration(tempoBlockId, newDurationInTicks): + tempoBlock = session.data.tempoTrack.tempoBlockById(tempoBlockId) + oldDuration = tempoBlock.duration + tempoBlock.duration = newDurationInTicks + session.history.clear() #resizing to a position of a tempo item in the previous block deletes that tempo item (otherwise there would be 2 items in the same spot). This is not remembered. + callbacks._updateTempoTrack() + +def appendTempoBlock(): + newBlock = session.data.tempoTrack.appendTempoBlock() + session.history.clear() + callbacks._updateTempoTrack() + +def rearrangeTempoBlocks(listOfBlockIds): + session.history.clear() + session.data.tempoTrack.rearrangeBlocks(listOfBlockIds) + callbacks._updateTempoTrack() + +def changeTempoBlock(tempoBlockId, newParametersDict): + tempoBlock = session.data.tempoTrack.tempoBlockById(tempoBlockId) + session.history.clear() + tempoBlock.putDataFromDict(newParametersDict) + callbacks._updateTempoTrack() + +def duplicateTempoBlock(tempoBlockId, times = 1): + tempoBlock = session.data.tempoTrack.tempoBlockById(tempoBlockId) + session.history.clear() + for i in range(times): + session.data.tempoTrack.duplicateBlock(tempoBlock) + callbacks._updateTempoTrack() + +def duplicateContentLinkTempoBlock(tempoBlockId, times = 1): + tempoBlock = session.data.tempoTrack.tempoBlockById(tempoBlockId) + session.history.clear() + for i in range(times): + session.data.tempoTrack.duplicateContentLinkBlock(tempoBlock) + callbacks._updateTempoTrack() + +def unlinkTempoBlock(tempoBlockId): + tempoBlock = session.data.tempoTrack.tempoBlockById(tempoBlockId) + newData, newDuration = tempoBlock.getUnlinkedData() + assert newData, newData + assert newDuration, newDuration + _setTempoBlockData(tempoBlock, newData, newDuration) #handles undo and callbacks + +def _setTempoBlockData(tempoBlock, newData, newDuration): + """For undo and redo. + newDuration is the original list with a single integer that may be content linked. + Thats why we get and set the block._duration parameter directly instead of using the setter + .duration.""" + session.history.register(lambda bl=tempoBlock, old=tempoBlock.data, dur=tempoBlock._duration: _setTempoBlockData(bl, old, dur), descriptionString = "set tempo black data") + tempoBlock.data = newData + tempoBlock._duration = newDuration + + #no callbacks needed. + +def splitTempoBlock(tempoBlockId, positionInTicksRelativeToBlock): + """tick position is relative to block start""" + success = session.data.tempoTrack.splitTempoBlock(tempoBlockId, positionInTicksRelativeToBlock) + if success: + session.history.clear() + callbacks._updateTempoTrack() + +def mergeWithNextTempoBlock(tempoBlockId): + positionForSplit = session.data.tempoTrack.mergeWithNextTempoBlock(tempoBlockId) + session.history.clear() #TODO: merging deletes hidden items in the first block without remembering them for undo + callbacks._updateTempoTrack() + +def deleteTempoBlock(tempoBlockId): + tempoBlock = session.data.tempoTrack.tempoBlockById(tempoBlockId) + oldLayout = session.data.tempoTrack.asListOfBlockIds() + deletedBlock = session.data.tempoTrack.deleteBlock(tempoBlock) + if deletedBlock: + session.history.clear() + callbacks._updateTempoTrack() + +def insertTempoItemAtAbsolutePosition(tickPositionAbsolute, unitsPerMinute, referenceTicks, graphType): + blockId, blockPosition = session.data.tempoTrack.tempoBlocKByAbsolutePosition(tickPositionAbsolute) + positionInTicksRelativeToBlock = tickPositionAbsolute - blockPosition + addTempoItem(blockId, positionInTicksRelativeToBlock, unitsPerMinute, referenceTicks, graphType) + +def insertTempoChangeDuringDuration(percentageUnitsPerMinuteAsFloat): + """Instead of a fermata this sets a tempo change which start- and end-point are derived + from the current items duration + + To enable the user to compare the tempo values we keep the original referenceTicks. + The new units per minute value is given as percentage parameter. The reasoning behind that is + that the user should think 'I want that duration to be double as long as normal = half tempo = 0.5' """ + + if percentageUnitsPerMinuteAsFloat <= 0: + raise ValueError("Give a float value bigger than zero. 1.0 is no modification. 0.5 is half tempo, 2.0 is double tempo") + + curItem = session.data.currentItem() + if curItem: # not appending(None) + dur = curItem.logicalDuration() + if not dur: #not a clef + return None + startTick = session.data.currentTrack().state.tickindex + endTick = startTick + dur #we don't need to worry about the next note starting on that value or not. midi tempo changes can happen between note on and note off. + tempoItem = session.data.tempoTrack.tempoAtTickPosition(startTick) + #originalUnitsPerMinute, originalReferenceTicks = session.data.tempoTrack.tempoAtTickPosition(startTick) + newUnitsPerMinute = tempoItem.unitsPerMinute * percentageUnitsPerMinuteAsFloat + insertTempoItemAtAbsolutePosition(startTick, newUnitsPerMinute, tempoItem.referenceTicks, graphType = "standalone") + insertTempoItemAtAbsolutePosition(endTick, tempoItem.unitsPerMinute, tempoItem.referenceTicks, graphType = "standalone") + session.history.clear() #TODO: This registers two times undo + + +#Toolbox +#High Level commands + +def pedalNotes(pedalDuration): + """Split the chord so that it consists of all *pedalDuration*s and use the cursor as a pitch + for all but the first, which keeps its original notelist. + + Since the cursor note is in the current keysig only it will be used even if applied to multiple + tracks. E.g. treble clef middle line in Track 1 has F-Major and will input a Bes but if Track 2 + is in C-Major it will still use Bes as the pedal note, and not B. + + This is a musically unlikely corner case so we accept the inaccuracy. + """ + #TODO: To iron out the corner case in the docstring we would have to look at each notes cached keysig. + def replaceWithPedalNotes(self): + if not type(self) == items.Chord: + return False + + newParts = int(self.durationGroup.baseDuration / pedalDuration) + if not newParts >= 2: + return False + originalPitches = self.notelist #keep the actual list, not only the contents + keysig = session.data.currentTrack().state.keySignature() + pitchToInsert = pitchmath.toScale(session.data.cursor.pitchindex, keysig) + pedalNote = self.notelist[0].copy(self) + pedalNote.pitch = pitchToInsert + self.notelist = [pedalNote] + undoSplit = self.split(newParts) #split uses the temporary note + targetDuration = self.durationGroup.minimumNote.duration.copy() + + + #Restore the first note to original pitch, but keep the new duration, at least in the mininumNote + self.notelist = originalPitches + self.durationGroup.cacheMinimumNote() + #self.notelist[self.notelist.index(self.durationGroup.minimumNote)] = + self.durationGroup.minimumNote.duration = targetDuration + self.durationGroup.cacheMinimumNote() + + items.Item._replaceWithPedalNotes = replaceWithPedalNotes #this happens each time api.pedalNotes gets called, which is good because the "duration" parameter changes each time. + + if session.data.cursorWhenSelectionStarted: + _applyToSelection("_replaceWithPedalNotes") + else: + _applyToItem("_replaceWithPedalNotes") + session.history.clear() + callbacks._historyChanged() + +def mirrorAroundCursor(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("mirrorAroundCursor", parameterListForEachSelectedItem = [[session.data.cursor.pitchindex]]) + else: + _applyToItem("mirrorAroundCursor", parameters = [session.data.cursor.pitchindex]) + +#All the random inserts work on prevailing duration. +def _randomPitch(lowest, highest, mode = "inScale"): + """ + returns a pitch integer + + Does depend on the track state and cursor. This is a function that is supposed to be called (indirectly) + by the user and not suited for a script where the cursor stays at the beginning. + + lowest is a pitch value like 1420 + Modes: + -1 = full spectrum, reserved for microintervals + 0 = enharmonic spectrum. + 1 = without double-b and x + 2 = in Scale, default""" + + note = random.randrange(lowest, highest, 10) #step-size 10 + keysig = session.data.currentTrack().state.keySignature() + if mode == "inScale": + return pitchmath.toScale(note, keysig) + elif mode == "chromatic": + #A conversion to midi is just an abstract frequency and back to the current keysig + return pitchmath.fromMidi(pitchmath.toMidi[note], keysig) + elif mode == "enharmonic": + return note + elif mode == "microintervals": + raise NotImplementedError + else: + raise ValueError("Mode unknown: {}".format(mode)) + +def insertRandomChromaticInClefRange(): + clef = session.data.currentTrack().state.clef() + insertChord(session.data.cursor.prevailingBaseDuration, _randomPitch(clef.rangeLowest, clef.rangeHighest, mode="chromatic")) + +def insertRandomFromScaleInClefRange(): + clef = session.data.currentTrack().state.clef() + insertChord(session.data.cursor.prevailingBaseDuration, _randomPitch(clef.rangeLowest, clef.rangeHighest)) + +def insertRandomFromScaleAuthenticModeCursor(): + insertChord(session.data.cursor.prevailingBaseDuration, _randomPitch(session.data.cursor.pitchindex, session.data.cursor.pitchindex + 350, mode = "inScale")) + +def insertRandomFromScaleHypoModeCursor(): + insertChord(session.data.cursor.prevailingBaseDuration, _randomPitch(session.data.cursor.pitchindex - 3*50, session.data.cursor.pitchindex + 4*50, mode = "inScale")) + +def insertRandomFromClipboard(): + """Only the pitch, not the duration""" + #TODO: After real world testing decide if this works with the clipboard or if we need a separate buffer + #TODO currently the pool is created each time a note is requested. This could easily moved into the copy function. + if session.data.copyObjectsBuffer: + pool = set(flatList(session.data.copyObjectsBuffer)) #set to remove content links + pool = [i for i in pool if type(i) is items.Chord] + if pool: #all chords + item = items.createChordOrRest(session.data.cursor.prevailingBaseDuration, random.choice(pool).copy().pitchlist()) + insertItem(item) + +#Midi only + +def instrumentChange(program, msb, lsb, instrumentName, shortInstrumentName): + change = items.InstrumentChange(program, msb, lsb, instrumentName, shortInstrumentName) + insertItem(change) + +def channelChange(value, text): + change = items.ChannelChange(value, text) + insertItem(change) + +def midiRelativeChannelPlus(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("midiRelativeChannelPlus") + else: + _applyToItem("midiRelativeChannelPlus") + +def midiRelativeChannelMinus(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("midiRelativeChannelMinus") + else: + _applyToItem("midiRelativeChannelMinus") + +def midiRelativeChannelReset(): + if session.data.cursorWhenSelectionStarted: + _applyToSelection("midiRelativeChannelReset") + else: + _applyToItem("midiRelativeChannelReset") + +def exportLilypond(absoluteFilePath): + lilypond.saveAsLilypond(session.data, absoluteFilePath) + +def showPDF(): + lilypond.saveAsLilypondPDF(session.data, openPDF = True) + +#Debug +def printPitches(): + track = session.data.currentTrack() + for block in track.blocks: + for chord in block.data: + print ([note.pitch for note in chord.notelist]) + +def highStaccatoLowTenuto(): + """ + How to apply to selection without changing the item in the code? + + An example command. Normally this would be in an extra-package + because of its high level nature and non-standard purpose. + + First we add new methods to the Chord class. + At least during the current session this will allow undo and redo. + The inserted note however does not need these methods anymore. + Even if we remove this function forever the data will remain. + + This function is noteworthy because undo and redo get a notelist + with different duration values which need to be remembered + separately. + """ + def _stacAndTen(self): + if len(self.notelist) == 2: + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + + self.notelist[0].duration.toggleDurationKeyword(D_TENUTO) #lower note + self.notelist[1].duration.toggleDurationKeyword(D_STACCATO) #higher note + return lambda: self._setDurationlist(oldValues) + items.Chord._stacAndTen = _stacAndTen + + if session.data.cursorWhenSelectionStarted: + _applyToSelection("_stacAndTen") #This is now a chord-instance method. diff --git a/engine/block.py b/engine/block.py new file mode 100644 index 0000000..62a63d6 --- /dev/null +++ b/engine/block.py @@ -0,0 +1,331 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from weakref import WeakSet +from weakref import ref as weakref_ref +from .items import * #loading from file needs all items. + +class Block(object): + #allBlocks = WeakValueDictionary() #key is the blockId, value is the weak reference to the Block + allBlocks = {} #key is the blockId, value is the Block. This is a one way dict. It gets never deleted so undo can recover old blocks. Since blocks are unique this is no problem. + #NEVER!! iteratre over allBlocks if you don't know what you are doing. This contains deleted blocks as well. + firstBlockWithNewContentDuringDeserializeToObject = dict() #this is not resetted anywhere since each load is a program start. + + def __init__(self, track): + self.data = list() + self.name = str(id(self)) + self._minimumInTicks = [0] # if this is bigger than the actual duration-sum of the content this will be used instead. Advice: best used in the form of x*210 (multiple of real base-durations) #is content linked, thats why it is a mutable list of len==1. + self.linkedContentBlocks = WeakSet() #only new standalone blocks use this empty WeakSet. once you contentLink a block it will be overwritten. + self._secondInit(parentTrack = track) + + def _secondInit(self, parentTrack): + """see Score._secondInit""" + self._parentTrack = weakref_ref(parentTrack) #a block can only be in one track. + self.localCursorIndex = 0 + self.linkedContentBlocks.add(self) + self.rememberBlock() + + @property + def minimumInTicks(self): + return self._minimumInTicks[0] + + @minimumInTicks.setter + def minimumInTicks(self, newValue): + """Keep the mutable list at all cost""" + listId = id(self._minimumInTicks) + self._minimumInTicks.pop() + self._minimumInTicks.append(newValue) + assert len(self._minimumInTicks) == 1 + assert listId == id(self._minimumInTicks) + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + if serializedObject["data"] is None: #Found a content linked block which already has one member of its group in the score + firstBlock = Block.firstBlockWithNewContentDuringDeserializeToObject[serializedObject["contentLinkGroup"]] #block with the same contentGroup. This is the one with the real data. + self.data = firstBlock.data + self._minimumInTicks = firstBlock._minimumInTicks + self.linkedContentBlocks = firstBlock.linkedContentBlocks #add self to this is in _secondInit + else: #found a stand-alone block or the first one of a content link group + self.linkedContentBlocks = WeakSet() + self.data = [eval(item["class"]).instanceFromSerializedData(item, parentObject = self) for item in serializedObject["data"]] + Block.firstBlockWithNewContentDuringDeserializeToObject[serializedObject["contentLinkGroup"]] = self + for item in self.data: + item.parentBlocks.add(self) + self.name = serializedObject["name"] + self._minimumInTicks = [int(serializedObject["minimumInTicks"])] #saved as int, used as list + self._secondInit(parentTrack = parentObject) + return self + + def serialize(self): + """Return a serialized data from this instance. + Used for save and load. + + Can be called in a chain by subclasses with super().serialize + + The main difference between serialize and exportObject is that + serialize does not compute anything. I just saves the state + without calulating note on and off or stem directions, + for example. + """ + #result = super()._serialize() #call this in child classes + result = {} + result["class"] = self.__class__.__name__ + result["name"] = self.name + result["minimumInTicks"] = self.minimumInTicks + + #We only save the data if this is the first content-linked block in a sequence. + contentLinkGroupId = id(self.data) + result["contentLinkGroup"] = contentLinkGroupId + + for block in self.parentTrack.parentData.allBlocks(): + blockId = id(block) + dataId = id(block.data) + if dataId == contentLinkGroupId: + if blockId == id(self): #first block with this dataId found. + result["data"] = [item.serialize() for item in self.data] + else: #content linked, but not the first. Block already serialized. + result["data"] = None #we don't need to do anything more. The rest is handled by load and instanceFromSerializedData + break + #else: + #loop ran through. This never happens. + return result + + def rememberBlock(self): + oid = id(self) + Block.allBlocks[oid] = self #This is on the score level, or a global level. That means we don't need to change this, even if the track gets moved to a new track by the api. + #weakref_finalize(self, print, "deleted block "+str(oid)) + return oid + + @property + def parentTrack(self): + if self._parentTrack: + return self._parentTrack() #return the real parentTrack + else: + assert self._parentTrack is None + return self._parentTrack + + @parentTrack.setter + def parentTrack(self, newTrack): + if not self._parentTrack: #because it was None/not in a track + self._parentTrack = WeakSet() + if newTrack: + self._parentTrack = weakref_ref(newTrack) + else: + self._parentTrack = None + + def copy(self, newParentTrack): + """Return an independet copy of this block. + It will not be inserted into a track here but in the parentTrack + + It is by design only possible that a block will be inserted + in the same track, next to the original block. + It can be moved later by the api module which will reset + the parentTrack. But at first the parentTrack stays the same.""" + new = Block(newParentTrack) + assert newParentTrack + + #Do not change new.linkedContentBlocks! Copy creates a stand alone copy. + assert len(new.linkedContentBlocks) == 1 + + for item in self.data: + copyItem = item.copy() + new.data.append(copyItem) + + copyItem.parentBlocks.add(new) #parentBlock was empty until now + if self in copyItem.parentBlocks: #TODO: investigate + copyItem.parentBlocks.remove(self) + + if self.name.endswith("-copy"): + new.name = self.name + else: + new.name = self.name + "-copy" + new._minimumInTicks = self._minimumInTicks[:] #mutable + return new + + def getUnlinkedData(self): + """Set and handled for undo/redo by the api""" + newData = [] + newParentBlocks = WeakSet() + newParentBlocks.add(self) + + for item in self.data: + copyItem = item.copy() + newData.append(copyItem) + copyItem.parentBlocks = newParentBlocks + + assert len(newData) == len(self.data) + return newData + + + def getDataAsDict(self): + return { "name" : self.name, + "minimumInTicks" : self.minimumInTicks, + } + + def putDataFromDict(self, dataDict): + """modify inplace. Useful for a gui function. Compatible with + the data from getDataAsDict""" + self.name = dataDict["name"] + self.minimumInTicks = dataDict["minimumInTicks"] + + def contentLink(self): + """Return a copy where only certain parameters + like Content are linked. Others can be changed. + It will not be inserted into a track here but in the parentTrack + + It is by design only possible that a block will be inserted + in the same track, next to the original block. + It can be moved later by the api module which will reset + the parentTrack. But at first the parentTrack stays the same. + """ + assert self.parentTrack + new = Block(self.parentTrack) + new.linkedContentBlocks = self.linkedContentBlocks + new.linkedContentBlocks.add(new) + new.data = self.data #mutable. Will change in all blocks together. + new.name = self.name #immutable. Will change independently but we start with the same name. + new._minimumInTicks = self._minimumInTicks #mutable + #Add the new block to the parentBlocks set but don't delete self from it, as in copy(). The items are now in more than one block simultaniously + for item in new.data: + item.parentBlocks.add(new) + return new + + def linkedContentBlocksInScore(self): + """filters linkedContentBlocks to only include + those currently in the score. Not those in the undo repository + """ + return (block for block in self.linkedContentBlocks if block.parentTrack) + + def duration(self): + """The first block might have an upbeat. We check that here and not in the track.""" + + actualBlockDuration = 0 + for item in self.data: + actualBlockDuration += item.logicalDuration() + + if actualBlockDuration >= self.minimumInTicks: + return actualBlockDuration + else: + return self.minimumInTicks + + def staticExportEndMarkerDuration(self): + actualBlockDuration = 0 + for item in self.data: + actualBlockDuration += item.logicalDuration() + if actualBlockDuration >= self.minimumInTicks: #this also guarantees that the substraction below is > 0. + return 0 + else: + return self.minimumInTicks - actualBlockDuration #this is the difference to self.duration() + + def position(self): + """the position of the subcursor in this block""" + return self.localCursorIndex + + def left(self): + if self.localCursorIndex > 0: + self.localCursorIndex -= 1 + return True + else: + return False #Already at the start. + + def right(self): + if not self.isAppending(): + self.localCursorIndex += 1 + return True + else: + return False #Already at the end. + + def head(self): + self.localCursorIndex = 0 + + def tail(self): + self.localCursorIndex = len(self.data) #eventhough len counts from 1 and the cursorIndex from 0 we want exactly to be after the last item in data. + + def goToItem(self, itemInstance): + if itemInstance: + self.head() + while self.right(): + item = self.currentItem() + if item is itemInstance: + return True + else: + raise ValueError("Item not in this block. ", self, itemInstance) + elif itemInstance is None: + self.tail() + else: + raise ValueError("You must go to an item or None, not to: ", itemInstance) + + + def currentItem(self): + """Can be used with goToItem""" + if not self.isAppending(): + return self.data[self.localCursorIndex] + else: + return None + + def previousItem(self): + """Can be used with goToItem""" + if self.localCursorIndex > 0: + return self.data[self.localCursorIndex-1] + else: + return None + + def nextItem(self): + """Can be used with goToItem""" + if self.localCursorIndex+1 >= len(self.data): #one before appending or appending itself + return None + else: + return self.data[self.localCursorIndex+1] + + def insert(self, item): + self.data.insert(self.localCursorIndex, item) #we do not need to check if appending or not. list.insert appends if the index is higher then len() + #self.localCursorIndex += 1 #we don't need to go right here because track.insert() is calling its own right() directly after insert, which triggers block.right() + item.parentBlocks.add(self) + + def delete(self): + """The commented out is the immediate garbage collector which + made sure that deleted item are not in the allNotes weakref + dict any more. However, this does not happen any more since + we introduced undo which keeps a saved version. + For consitency reasons we chose not to save a copy in the undo + register (return ...copy()) but the real item. + + If this ever leads to problems with the weakref dict we must + reintroduce the copy""" + if not self.isAppending(): + result = self.data[self.localCursorIndex] + del self.data[self.localCursorIndex] + #we don't need to delete self from item.parentBlocks. It is automatically deleted in all contentLinked blocks, of course including its parentBlocks WeakSet() + return result + + def isAppending(self): + if self.localCursorIndex == len(self.data): #len counts from 1 and the cursorIndex from 0. So if they are the same we are one cursor position right of last item + return True + else: + return False + + def lilypond(self): + """Called by track.lilypond(), returns a string""" + return " ".join(item.lilypond() for item in self.data) + diff --git a/engine/config.py b/engine/config.py new file mode 100644 index 0000000..ac9eba6 --- /dev/null +++ b/engine/config.py @@ -0,0 +1,56 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +#Do not change these during runtime! + +METADATA={ + #The pretty name of this program. Used for NSM display and Jack client name + #Can contain everything a linux file/path supports. Never change this or it will break the + #session, making your file unable to load and destroying saved Jack connections. + "name" : "Laborejo", + + #Set this to the name the user types into a terminal. + #MUST be the same as the binary name as well as the name in configure. + #Program reports that as proc title so you can killall it by name. + #Should not contain spaces or special characters. We use this as save file extension as well + #to distinguish between compatible program versions. In basic programs this will just be e.g. + #patroneo. But in complex programs with a bright future it will be "laborejo1" "laborejo2" etc. + "shortName" : "laborejo2", + + "version" : "2.0", + "year" : "2019", + "author" : "Laborejo Software Suite", + "url" : "https://www.laborejo.org/laborejo", + + "supportedLanguages" : {"German":"de.qm"}, + + #Show the About Dialog the first time the program starts up. This is the initial state for a + #new instance in NSM, not the saved state! Decide on how annoying it would be for every new + #instance to show about. Fluajho does not show it because you add it many times into a session. + #Patroneo does because its only added once. + "showAboutDialogFirstStart" : True, + + #If your program handles very small duration with n-tuplets you should increase D4. + #This will not be visible to the outside jack world + "quarterNoteInTicks" : 53760, + + #How many audio outputs do you want? must be pairs. These are just unconnected jack outputs + #that need to be connected internally to instrument outputs like fluidsynth + "cboxOutputs" : 2 * 0, + + #Various strings for the README + #Extra whitespace will be stripped so we don't need to worry about docstring indentation + "description" : """ +Laborejo (Esperanto: Workshop) is a MIDI sequencer based on classical music notation. +Its main purpose is to compose and produce "traditional" music, such as instrumental pieces, +soundtracks and other music normally played back by samplers. +""" + "\n" + """ +Unlike other notation editors Laborejo is not meant primarily to print out sheets of notation but +to create music within your computer: You get all the tools you know from other midi sequencers for +maximum fine control to get exactly the music you want! +""" + "\n" + """ +Working in Laborejo is very fast and efficient by using a combination of midi input and typing.""", + + "dependencies" : "\n".join("* "+dep for dep in ("A Brain", "Linux" )), + +} diff --git a/engine/cursor.py b/engine/cursor.py new file mode 100644 index 0000000..e3fb00c --- /dev/null +++ b/engine/cursor.py @@ -0,0 +1,142 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2019, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), +more specifically its template base application. + +The Template Base Application 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 . +""" + +import logging; logging.info("import {}".format(__file__)) + +#Standard Library Modules + +#Third Party Modules + +#Template Modules +import template.engine.pitch as pitch +import template.engine.duration as duration + +#Our modules +class Cursor: + """There is only one cursor in the program. + Each track has its own state with its own gap, tickindex etc. + but the cursor is unique. + Used for pitch and states which apply to all tracks, like + "insert next note with dot?" + + The cursor moves 'on stafflines' not through the keysig. Adaption to the keysig is done + by the api like in insertCursorCode or insertKeysignature + """ + def __init__(self, score): + self.score = score + self.pitchindex = pitch.ly2pitch["c'"] + self.prevailingBaseDuration = duration.D4 + self.persistentPrevailingDot = False #For the sake of simplicity this is only a bool. No "two prevailing dots" + self.oneTimePrevailingDotInverter = False #effects persistentPrevailingDot + + def up(self): + """Move the cursor/pitchindex up, +50. + The cursor always goes up and down the c major scale. + Call with Cursor.up(). Class method """ + self.pitchindex += pitch.STEP + self.correctPitchindex() + + def down(self): + """Move the cursor/pitchindex down, -50. + The cursor always goes up and down the c major scale. + Call with Cursor.down(). Class method""" + self.pitchindex -= pitch.STEP + self.correctPitchindex() + + def upOctave(self): + """Move the cursor/pitchindex up, +350. + Call with Cursor.upOctave(). Class method""" + self.pitchindex += pitch.OCTAVE + self.correctPitchindex() + + def downOctave(self): + """Move the cursor/pitchindex down, -350. + Call with Cursor.downOctave(). Class method""" + self.pitchindex -= pitch.OCTAVE + self.correctPitchindex() + + def correctPitchindex(self): + if self.pitchindex >= pitch.MAX: + self.pitchindex = pitch.MAX + elif self.pitchindex <= pitch.MIN: + self.pitchindex = pitch.MIN + else: + self.pitchindex = pitch.toWhite[self.pitchindex] + + def getPrevailingDot(self): + """0 or 1. + Also toggles oneTimePrevailingDotInverter""" + if self.persistentPrevailingDot: + if self.oneTimePrevailingDotInverter: + self.oneTimePrevailingDotInverter = not self.oneTimePrevailingDotInverter + return 0 + else: + return 1 + else: + if self.oneTimePrevailingDotInverter: + self.oneTimePrevailingDotInverter = not self.oneTimePrevailingDotInverter + return 1 + else: + return 0 + + def distanceInDiatonicStepsFromTrebleB(self): + return pitch.distanceInDiatonicSteps(pitch.ly2pitch["b'"], self.pitchindex) #offset from the middle line in treble clef h', which is 0. c'' is -1, a' is +1 + + def asDotOnLine(self, clef): + return self.distanceInDiatonicStepsFromTrebleB() + clef.asDotOnLineOffset + + def exportObject(self, trackState): + """Every time the cursor moves this will be called. + + return a dict which is a good layout + export basis. For example for GUI frontends. They don't have to + parse and calculate their own values in slow pure Python then. + + This is for GUIs etc. not for saving to JSOn. The cursor is not + saved. + """ + tempoItem = trackState.track.parentData.tempoTrack.tempoAtTickPosition(trackState.tickindex) #TODO: maybe get that from a cached version. + item = trackState.track.currentItem() + block = trackState.track.currentBlock() + + return { + "type": "Cursor", + "trackIndex": trackState.index(), + "track" : trackState.track, + "cboxMidiOutUuid" : trackState.track.sequencerInterface.cboxMidiOutUuid, #used for midi throught. Step midi shall produce sound through the current track. + "trackId" : id(trackState.track), + "position" : trackState.position(), + "tickindex" : trackState.tickindex, + "dotOnLine": self.asDotOnLine(trackState.clef()), + "pitch" : self.pitchindex, + "lilypondPitch" : pitch.pitch2ly[self.pitchindex], + "position" : trackState.position(), + "appending" : trackState.isAppending(), + "blockindex" : trackState.blockindex, + "block" : block, + "localCursorIndex" : block.localCursorIndex, + "itemId" : id(item), + "item" : item, + "tempoUnitsPerMinute" : tempoItem.unitsPerMinute, + "tempoReferenceTicks" : tempoItem.referenceTicks, + "tempoGraphType" : tempoItem.graphType, + } diff --git a/engine/graphtracks.py b/engine/graphtracks.py new file mode 100644 index 0000000..e906e42 --- /dev/null +++ b/engine/graphtracks.py @@ -0,0 +1,1347 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +import logging; logging.info("import {}".format(__file__)) + +#Standard Library Modules +from weakref import WeakValueDictionary, WeakSet + +#Third Party Modules + +#Template Modules +import template.engine.duration as duration +from template.engine.duration import D1, D4, D1024 +from template.helper import pairwise + +#Our modules + +class GraphItem(object): + """We use 'CC' here as synonym for whatever int value between 0 + and 127, typical 7bit midi values""" + + def __init__(self, ccStart): + self.ccStart = ccStart #int + self.graphType = "linear" #options: linear, standalone + self._secondInit(parentBlock = None) + self.lilypondParameters = {} + + def _secondInit(self, parentBlock): + """see Score._secondInit""" + #ignore parentBlock + pass + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.ccStart = int(serializedObject["ccStart"]) + self.graphType = serializedObject["graphType"] + self.lilypondParameters = serializedObject["lilypondParameters"] + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = {} + result["class"] = self.__class__.__name__ + result["ccStart"] = self.ccStart + result["graphType"] = self.graphType + result["lilypondParameters"] = self.lilypondParameters + return result + + def copy(self): + new = GraphItem(self.ccStart) + new.graphType = self.graphType + new.lilypondParameters = self.lilypondParameters.copy() + return new + + def linearRepresentation(self, ccEnd, tickStart, tickEnd): + """ + the variable is taken from the standard formula: f(x) = m*x + n + m = (x2-x1) / (y2-y1) + x1 = tick start + y1 = CC start + x2 = tick end + y2 = CC end + + tickStart and tickEnd are absolute values for the complete track + This means we can directly export them to calfbox. + + result is tuples (ccValue, tickPOsitionOfThatCCValue) + """ + + assert 0 <= self.ccStart < 128 + assert 0 <= ccEnd < 128 + + result = [] + if ccEnd == self.ccStart: #there is no interpolation. It is just one value. + result.append((self.ccStart, tickStart)) + return result + + m = (tickEnd - tickStart) / (ccEnd - self.ccStart) #we need to calculate this after making sure that ccend and start are not the same. Else we get /0 + #From here on: We actually need interpolation. Let the math begin. + if ccEnd > self.ccStart: #upward slope + iteratorList = list(range(self.ccStart, ccEnd)) #20 to 70 results in 20....69 + else: #downward slope + iteratorList = list(range(ccEnd+1, self.ccStart+1)) #70 to 20 results ins 70...21 + iteratorList.reverse() + + #Calculate at which tick a given ccValue will happen. value = m * (i - y1) + for ccValue in iteratorList: + result.append((ccValue, tickStart + int(m * (ccValue - self.ccStart)))) # int(m * (ccValue - self.ccStart)) results in 0 for the first item (set by the user). so the first item is just tickStart. that does not mean tickStart for the first item is 0. We just normalize to tickStart as virtual 0 here. + assert result + assert result[0][1] == tickStart + return result + + def staticRepresentation(self, ccEnd, tickStart, tickEnd): + if self.graphType == "standalone" or tickEnd < 0 or ccEnd < 0: + result = [(self.ccStart, tickStart)] + elif self.graphType == "linear": + result = self.linearRepresentation(ccEnd, tickStart, tickEnd) + else: + raise ValueError("Graph Type unknown:", self.graphType) + assert result + return result + +class GraphBlock(object): + """Basically a variant of structures.Block, but not for Item type, + but for GraphItem. + + Relative to the blocks beginning tick position, handled by the + GraphTrack, in self.data there are: + key = tick position + value = GraphItem + + GraphBlocks have a fixed duration. The user has to align them + manually. + """ + + firstBlockWithNewContentDuringDeserializeToObject = dict() #this is not resetted anywhere since each load is a program start. + allBlocks = {} #key is the blockId, value is the Block. This is a one way dict. It gets never deleted so undo can recover old blocks. Since blocks are unique this is no problem. + + def __init__(self, parentGraphTrack): + + self.data = {0:GraphItem(0)} #content linked, mutable. + self.name = str(id(self)) + self._duration = [D1*4] #len is always 1. Value is always >= D1*4. Duration is content linked, thats why it is a mutable list of len==1. + #self.duration = 0 #triggers the setter. in reality this is set to a standard minimum value in def duration + self.linkedContentBlocks = WeakSet() #only new standalone blocks use this empty WeakSet. once you contentLink a block it will be overwritten. + self._secondInit(parentGraphTrack) + + def _secondInit(self, parentGraphTrack): + """see Score._secondInit""" + self.linkedContentBlocks.add(self) + self.rememberBlock() + self.parentGraphTrack = parentGraphTrack + + @property + def duration(self): + return self._duration[0] + + @duration.setter + def duration(self, newValue): + """Keep the mutable list at all cost""" + if newValue > 0 and newValue < D1*4: + newValue = D1*4 + listId = id(self._duration) + self._duration.pop() + self._duration.append(newValue) + assert len(self._duration) == 1 + assert listId == id(self._duration) + + def rememberBlock(self): + oid = id(self) + GraphBlock.allBlocks[oid] = self #This is on the score level, or a global level. That means we don't need to change this, even if the track gets moved to a new track by the api. + #weakref_finalize(self, print, "deleted block "+str(oid)) + return oid + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.parentGraphTrack = parentObject + + if serializedObject["data"] is None: + firstBlock = GraphBlock.firstBlockWithNewContentDuringDeserializeToObject[serializedObject["contentLinkGroup"]] #first block with the same contentGroup. This is the one with the real data. + self.data = firstBlock.data + self._duration = firstBlock._duration + self.linkedContentBlocks = firstBlock.linkedContentBlocks #add self to this is in _secondInit + else: #Standalone or First occurence of a content linked block + self.data = {int(position):GraphItem.instanceFromSerializedData(item, parentObject = self) for position, item in serializedObject["data"].items()} + GraphBlock.firstBlockWithNewContentDuringDeserializeToObject[serializedObject["contentLinkGroup"]] = self + self.linkedContentBlocks = WeakSet() + self._duration = [int(serializedObject["duration"])] #this is just an int, minimumBlockInTicks or so. Not Item.Duration(). For save and load we drop the list as mutable value. + + self.name = serializedObject["name"] + self._secondInit(parentObject) + return self + + def serialize(self): + result = {} + result["class"] = self.__class__.__name__ + result["name"] = self.name + result["duration"] = self.duration #this is just an int, minimumBlockInTicks or so. Not Item.Duration(). For save and load we drop the list as mutable value. + + #We only save the data if this is the first content-linked block in a sequence. + contentLinkGroupId = id(self.data) + result["contentLinkGroup"] = contentLinkGroupId + + for block in self.parentGraphTrack.blocks: + blockId = id(block) + dataId = id(block.data) + if dataId == contentLinkGroupId: + if blockId == id(self): #first block with this dataId found. + result["data"] = {int(itemTickPosition):item.serialize() for itemTickPosition, item in self.data.items()} + else: #content linked, but not the first. Block already serialized. + result["data"] = None #we don't need to do anything more. The rest is handled by load and instanceFromSerializedData + break + else: + raise StopIteration("self block not found in graphTrack.blocks") + #loop ran through. This never happens. + + return result + + def getDataAsDict(self): + return { "name" : self.name, + "duration" : self.duration, + } + + def putDataFromDict(self, dataDict): + """modify inplace. Useful for a gui function. Compatible with + the data from getDataAsDict""" + self.name = dataDict["name"] + self.duration = dataDict["duration"] + + def copy(self): + """Return an independet copy of this block.""" + new = type(self)(parentGraphTrack = self.parentGraphTrack) + + assert len(new.linkedContentBlocks) == 1 #even a copy of a linked block becomes a stand-alone copy + + for itemTickPosition, item in self.data.items(): + new.data[itemTickPosition] = item.copy() + if self.name.endswith("-copy"): + new.name = self.name + else: + new.name = self.name + "-copy" + new._duration = self._duration[:] #mutable + return new + + def contentLink(self): + """Return a copy where only certain parameters + like Content are linked. Others can be changed""" + new = type(self)(parentGraphTrack = self.parentGraphTrack) + new.linkedContentBlocks = self.linkedContentBlocks + new.linkedContentBlocks.add(new) + new.data = self.data + new.name = self.name + new._duration = self._duration #mutable + return new + + def getUnlinkedData(self): + """Set and handled for undo/redo by the api""" + newData = {} + linkedContentBlocks = WeakSet() + linkedContentBlocks.add(self) + + for itemTickPosition, item in self.data.items(): + copy = item.copy() + newData[itemTickPosition] = copy + copy.linkedContentBlocks = linkedContentBlocks + + return newData, self._duration[:] #mutable. the api uses the list directly as well because we want to undo/restore the old original list, which may be content linked. + + def linkedContentBlocksInScore(self): + """Named for compatibility with structures block. + Added a safety net to make sure only blocks which are actually in the timeline will be + returned. Not those in the undo buffer. + + The return is sorted to be in the actual track order. + """ + assert len(self.linkedContentBlocks) >= 1 + blocksInTrack = [block for block in self.linkedContentBlocks if block.parentGraphTrack] + ordered = sorted(blocksInTrack, key = lambda block: self.parentGraphTrack.blocks.index(block)) + return ordered + + def insert(self, graphItem, tickPositionRelativeToBlockStart): + self.data[tickPositionRelativeToBlockStart] = graphItem + return True #cannot fail, for now. the api still waits for a positive return code + + def find(self, graphItem): + """find a relative tick position by graphItem. + We already know that the graphItem is in this block. Now we + need to find the position.""" + assert graphItem in self.data.values() + for position, item in self.data.items(): + if item is graphItem: + return position + else: + raise ValueError("graphItem not found in this block", graphItem, self) + + def remove(self, tickPositionRelativeToBlockStart): + if not tickPositionRelativeToBlockStart == 0: #don't allow the first item in a block to be deleted. Since the 0 item can't be moved this will always be the 0 item. + assert tickPositionRelativeToBlockStart != min(self.data.keys()) #this can't be the first item in this block. + del self.data[tickPositionRelativeToBlockStart] + return True + return False + + def move(self, tickPositionRelativeToBlockStart, newPosition): + """we don't allow the first item to be moved. Makes + things easier and clearer for the user""" + if tickPositionRelativeToBlockStart > 0 and not tickPositionRelativeToBlockStart == newPosition: #otherwise it would just delete the complete item because old and new are the same and there would be no duplicate item to delete. + self.data[newPosition] = self.data[tickPositionRelativeToBlockStart] + del self.data[tickPositionRelativeToBlockStart] + + def deleteHiddenItems(self): + if self.getMaxContentPosition() > self.duration: + toDelete = [pos for pos in self.data.keys() if pos > self.duration] #must be list, not generator, because we need the positions in advance to delete them later. A generator would delete from the dict while it is still generated. + for delPos in toDelete: + del self.data[delPos] + + def exportsAllItems(self): + """Does the current self.duration prevent GraphItems from + getting exported?""" + if max(self.data) > self.duration: + return False + else: + return True + + def getMaxContentPosition(self): + value = max(sorted(self.data.keys())) + return value + + def staticRepresentation(self): + """list of (tickPositionRelativeToBlockStart, GraphItem) tuples. + Only exports items which fit into this blocks duration.""" + sortedListOfTuples = [] + for tickPosition, graphItem in self.data.items(): + if tickPosition <= self.duration: + sortedListOfTuples.append((tickPosition, graphItem)) + sortedListOfTuples.sort() + return sortedListOfTuples + + def extendToTrackLength(self, myParentCCTrack): + """This is a user-called command intended for the last block + in a track + + Why not extend the last block automatically? + First these are too many updates so performance goes down. + Second it confuses the user when he/she attempts to split + or append. Especially append. + """ + assert self is myParentCCTrack.blocks[-1] + + plainScoreDuration = myParentCCTrack.score.duration() + durationWithoutLastBlock = myParentCCTrack.durationWithoutLastBlock() + #print ("score:", plainScoreDuration, "allOther", TempoBlock.tempoTrack.durationWithoutLastBlock()) + + if plainScoreDuration > 0 and plainScoreDuration > durationWithoutLastBlock: + self.duration = plainScoreDuration - durationWithoutLastBlock + +class GraphTrackCC(object): + """A track for midi Control Changes. + There is no cursor and no state. Just a sequence of blocks. + The actual CC value comes from the track.""" + def __init__(self, cc, parentTrack): + firstBlock = GraphBlock(parentGraphTrack = self) + self.blocks = [firstBlock] #there is always at least one block. + self.cc = cc + self._secondInit(parentTrack = parentTrack) + + def _secondInit(self, parentTrack): + """see Score._secondInit""" + self.parentTrack = parentTrack + self.score = parentTrack.parentData + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.cc = int(serializedObject["cc"]) + self.blocks = [GraphBlock.instanceFromSerializedData(block, parentObject = self) for block in serializedObject["blocks"]] + self._secondInit(parentTrack = parentObject) + return self + + def serialize(self): + result = {} + result["class"] = self.__class__.__name__ + result["cc"] = self.cc + result["blocks"] = [block.serialize() for block in self.blocks] + return result + + def durationWithoutLastBlock(self): + result = 0 + for block in self.blocks[:-1]: #returns empty list when only one block in self.blocks. So no loop will happen and this function returns 0 + result += block.duration + return result + + def asListOfBlockIds(self): + """Return an ordered list of block ids""" + result = [] + for block in self.blocks: + result.append(id(block)) + return result + + def appendGraphBlock(self): + """A simple method to add a new GraphBlock at the end of the + current track. Basically you can do the same with split and + resize, but this is much more easier.""" + new = GraphBlock(parentGraphTrack = self) + return self.appendExistingGraphBlock(new) + + def appendExistingGraphBlock(self, graphBlock): + self.blocks.append(graphBlock) + return graphBlock + + def splitGraphBlock(self, graphBlock, positionInTicksRelativeToBlock): + """The new block will be right of the original content. If the new block will be empty + or has no real start value the last prevailing value will be used + as the blocks start-point""" + #TODO: refactoring. This is bascially a copy of splitTempoBlock except the block is not an id here. And the name. + block = graphBlock + assert block.duration > positionInTicksRelativeToBlock + + hasPointAtZero = False + toDelete = [] + modelNewBlock = GraphBlock(parentGraphTrack = self) #will not be used directly, but instead content links will be created. + for pos, item in block.data.items(): + #Determine if a ccPoint gets to move to the new block + if pos >= positionInTicksRelativeToBlock: + if pos == positionInTicksRelativeToBlock: + hasPointAtZero = True + modelNewBlock.data[pos - positionInTicksRelativeToBlock] = item + toDelete.append(pos) + #else: ccPoint stays in the old block + + for pos in toDelete: + del block.data[pos] + + #Since every block comes with a value at position 0 we need to check if this was already replaced or if we need to adjust it to the real tempo at this point in time. + if not hasPointAtZero: + realStartCCPoint = block.data[block.getMaxContentPosition()] #only the remaining items. + modelNewBlock.data[0] = realStartCCPoint.copy() + + #Now the original block and all its content links have fewer items than before + #For every of the content-linked blocks in the tempo track we need to create a new block and insert it right next to it. + + for bl in block.linkedContentBlocksInScore(): + index = self.blocks.index(bl) + link = modelNewBlock.contentLink() + self.blocks.insert(index +1, link) + + #duration is mutable. All content links change duration as well. + link.duration = block.duration - positionInTicksRelativeToBlock + block.duration = positionInTicksRelativeToBlock + + del GraphBlock.allBlocks[id(modelNewBlock)] #Clean up the model block since it was never intended to go into the TempoTrack + + return True + + def mergeWithNextGraphBlock(self, graphBlock): + """see structures block (the music block) for an explanation about merging content linked + blocks. + + Hidden items (after the current duration value) of the original block + will be deleted. Hidden items of the follow-up block will be merged, but stay hidden. + """ + #TODO: refactoring. This is bascially a copy of splitTempoBlock except the block is not an id here. And the name. + + block = graphBlock + + if len(self.blocks) == 1: + #print ("only one block in the track") + return False + + blockIndex = self.blocks.index(block) + + if blockIndex+1 == len(self.blocks): + #print ("not for the last block") + return False + + nextIndex = blockIndex + 1 + nextBlock = self.blocks[nextIndex] + + firstBlock_endingValue = block.data[block.getMaxContentPosition()].ccStart + nextBlock_startingValue = nextBlock.data[0].ccStart + + startDurationToReturnForUndo = block.duration + + if len(block.linkedContentBlocksInScore()) == 1 and len(nextBlock.linkedContentBlocksInScore()) == 1: #both blocks are standalone. no content-links. This also prevents that both blocks are content links of each other. + block.deleteHiddenItems() + + if firstBlock_endingValue == nextBlock_startingValue: #remove redundancy + del nextBlock.data[0] + + for pos, item in nextBlock.data.items(): + assert not pos + block.duration in block.data + block.data[pos + block.duration] = item + + block.duration += nextBlock.duration + self.deleteBlock(nextBlock) + + return startDurationToReturnForUndo + + elif len(block.linkedContentBlocksInScore()) == len(nextBlock.linkedContentBlocksInScore()): #It is maybe possible to build pairs from the current block and all its content links with the follow up block and all its content links. + #Further testing required: + for firstBlock, secondBlock in zip(block.linkedContentBlocksInScore(), nextBlock.linkedContentBlocksInScore()): + if firstBlock.data is secondBlock.data: #content link of itself in succession. Very common usecase, but not compatible with merging. + #print ("content link follows itself") + return False + elif not self.blocks.index(firstBlock) + 1 == self.blocks.index(secondBlock): #all first blocks must be followed directly by a content link of the second block. linkedContentBlocksInScore() returns a blocklist in order so we can compare. + #print ("not all blocks-pairs are next to each other") + return False + + #Test complete without exit. All blocks can be paired up. + #print ("Test complete. Merging begins") + + block.deleteHiddenItems() + + if firstBlock_endingValue == nextBlock_startingValue: #remove redundancy + del nextBlock.data[0] + + for pos, item in nextBlock.data.items(): + assert not pos + block.duration in block.data #this includes pos==0, if not deleted above. + block.data[pos + block.duration] = item + + + def deleteBlock(self, graphBlock): + """at least one block. If you want to delete the track + use api.deleteGraphTrackCC""" + if len(self.blocks) > 1: + graphBlock.parentGraphTrack = None + self.blocks.remove(graphBlock) + return graphBlock + + def duplicateBlock(self, graphBlock): + index = self.blocks.index(graphBlock) + copy = graphBlock.copy() + self.blocks.insert(index +1, copy) + + def duplicateContentLinkBlock(self, graphBlock): + index = self.blocks.index(graphBlock) + linked = graphBlock.contentLink() + self.blocks.insert(index +1, linked) + + def blocksAsDict(self): + """Key is the block id, value the block instance""" + result = {} + for block in self.blocks: + result[id(block)] = block + return result + + def rearrangeBlocks(self, listOfBlockIds): + """Reorder the blocks in this track. + Achtung! Not including a block will delete this block + This is not allowed so we check for it.""" + #blocksDict = self.blocksAsDict() + newBlockArrangement = [] + + for idLong in listOfBlockIds: + #newBlockArrangement.append(blocksDict[idLong]) + newBlockArrangement.append(GraphBlock.allBlocks[idLong]) #all blocks includes deleted blocks in the undo memory. + + #a block is a unique unit in Laborejo2. Let's make sure there are no duplicates. + #http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order + seen = set() + seen_add = seen.add + self.blocks = [ x for x in newBlockArrangement if x not in seen and not seen_add(x)] + assert self.blocks + + def staticRepresentation(self): + typeString = "" + sumOfBlocksDurationsWithoutCurrent = 0 + result = [] + pblob = bytes() # Create a binary blob that contains the MIDI events for CC tracks + self.cleanBlockEdges() + for blockIndex in range(len(self.blocks)): + block = self.blocks[blockIndex] + assert len(block.data) > 0 + l = block.staticRepresentation() #this takes care that only user items which fit in the block.duration are exported. + for itemIndex in range(len(l)): #range starts from 0 so we can use this as index. + #l has tuples (tickPositionFromBlockStart, GraphItem) + thisPosition = l[itemIndex][0] + thisGraphItem = l[itemIndex][1] + + #Check if we reached the last item in this block. + if itemIndex is len(l)-1: #len counts from 1, itemIndex from 0. + assert thisGraphItem is l[-1][1] #l[-1] is a tuple (tickPositionFromBlockStart, GraphItem) + #Is there another block after this one? + if block is self.blocks[-1]: #this was the last block? + #there is no nextGraphItem and subsequently no interpolation. + typeString = "lastInTrack" # also a switch for later. + nextPosition = -1 #doesn't matter + #this is checked later in the loop, before we create the exportDict + else: #there is still a block left after the current + #The nextGraphItem can be found in the next block. + nextBlock = self.blocks[blockIndex+1] + nextBlockL = nextBlock.staticRepresentation() + nextPosition = nextBlockL[0][0] + block.duration #Instead of itemIndex we just need [0] for the first in the next block. + nextGraphItem = nextBlockL[0][1] #Instead of itemIndex we just need [0] for the first + else: #default case. Next item is still in the same block. + nextPosition = l[itemIndex+1][0] + nextGraphItem = l[itemIndex+1][1] + + #We now generate a chain of items from the current position to the next, + #at least one, depending on the interpolation type (like linear, none etc.) + + if typeString == "lastInTrack": + userItemAndInterpolatedItemsPositions = thisGraphItem.staticRepresentation(-1, thisPosition, -1) #-1 are magic markers that indicate a forced standalone mode. no interpolation, we just get one item back. + else: + assert thisPosition >= 0 + assert nextPosition >= 0 + typeString = "user" #interpolated, lastInTrack + userItemAndInterpolatedItemsPositions = thisGraphItem.staticRepresentation(nextGraphItem.ccStart, thisPosition, nextPosition) + + for ccValue, generatedTickPosition in userItemAndInterpolatedItemsPositions: #generatedTickPosition is relative to the block beginning. + if typeString == "user" or typeString == "lastInTrack": #interpolated items can be anywhere. We don't care much about them. + assert generatedTickPosition <= block.duration + + assert 127 >= ccValue >= 0 + assert generatedTickPosition >= 0 + + exportDictItem = { + "type" : typeString, + "value": -1*ccValue, #minus goes up because it reduces the line position, which starts from top of the screen. For a tempo this is a bpm value for quarter notes. + "position" : sumOfBlocksDurationsWithoutCurrent + generatedTickPosition, #generatedTickPosition is relative to the block beginning. + "id" : id(thisGraphItem), + "blockId": id(block), + "minPossibleAbsolutePosition" : sumOfBlocksDurationsWithoutCurrent, #If you want to move this item to the left or right, this is only possible within the current block. + "maxPossibleAbsolutePosition" : sumOfBlocksDurationsWithoutCurrent + block.duration, #If you want to move this item to the left or right, this is only possible within the current block. + "lastInBlock" : len(block.data) == 1, + } + result.append(exportDictItem) + typeString = "interpolated" #The next items in userItemAndInterpolatedItemsPositions are interpolated items. Reset once we leave the local forLoop. + + if self.parentTrack.ccChannels: + for channel in self.parentTrack.ccChannels: + blob = cbox.Pattern.serialize_event(exportDictItem["position"], 0xB0 + channel, self.cc, ccValue) #position, status byte+channel, controller number, controller value #TODO use channel of the parent note track at that moment in time. + pblob += blob + else: + blob = cbox.Pattern.serialize_event(exportDictItem["position"], 0xB0 + self.parentTrack.initialMidiChannel, self.cc, ccValue) #position, status byte+channel, controller number, controller value #TODO use channel of the parent note track at that moment in time. + pblob += blob + + + #Prepare data for the next block. + sumOfBlocksDurationsWithoutCurrent += block.duration #the naming is only true until the last iteration. Then all blocks, even the current one, are in the sum and can be used below. + + if sumOfBlocksDurationsWithoutCurrent > 0: + if self.calfboxTheWholeTrackAsPattern: + self.calfboxTheWholeTrackAsPattern[0].delete() + self.calfboxTheWholeTrackAsPattern = None + self.calfboxTheWholeTrackAsPattern = (cbox.Document.get_song().pattern_from_blob(pblob, sumOfBlocksDurationsWithoutCurrent), sumOfBlocksDurationsWithoutCurrent) #sumOfBlocksDurationsWithoutCurrent now even includes the current one. See above. + assert self.calfboxTheWholeTrackAsPattern + self.clearCalfboxTrack() #does NOT clear calfboxTheWholeTrackAsPattern + trackAsMidiData, trackPlainLengthInTicks = self.calfboxTheWholeTrackAsPattern + self.calfboxTrack.add_clip(0, 0, trackPlainLengthInTicks, trackAsMidiData) #pos, offset, length(and not end-position, but is the same), pattern + + self.score.session.playbackNeedsUpdate = True + #Before calfbox converts this python data into C data we need to call cbox.Document.get_song().update_playback(). This is done when playback starts and checks if self.score.session.playbackNeedsUpdate. + return result + + def staticGraphBlocksRepresentation(self): + """Return a sorted list""" + result = [] + tickCounter = 0 + for block in self.blocks: + result.append({"type" : "GraphBlock", "id":id(block), "name":block.name, "duration":block.duration, "position":tickCounter, "exportsAllItems":block.exportsAllItems()}) + tickCounter += block.duration + return result + + def staticTrackRepresentation(self): + result = {} + if type(self) is TempoTrack: + mini, maxi = self.getMinimumAndMaximumValues() + result["minimumAbsoluteTempoValue"] = mini + result["maximumAbsoluteTempoValue"] = maxi + return result + + def graphItemById(self, graphItemId): + for graphBlock in self.blocks: + for tickPosition, graphItem in graphBlock.staticRepresentation(): # a list of tuples + if id(graphItem) == graphItemId: + return graphBlock, graphItem + else: + raise ValueError("graphItemId not found in this track", graphItemId) + + def cleanBlockEdges(self): + """If a first block has an item at tick 300 and a second block is resized to begin at + tick 300 as well then the last item and the start-item are in the same spot. + The last item needs to go away.""" + for block in self.blocks: + if block.getMaxContentPosition() == block.duration: + block.remove(block.duration) + +class TempoItem(object): + """A tempo Item exports to Lilypond. + It also interpolates to the next tempo item, but the steps + in between show only up in the playback representation, + not in lilypond""" + + allTempoItems = WeakValueDictionary() #key is the id, value is the weak reference to the tempo item + #tempoTrack = the only tempo track. set by tempo track init, which happens only once in the program. + + def __init__(self, unitsPerMinute, referenceTicks): # 120 quarter notes per minute is unitsPerMinute=120, referenceTicks=D4 + self.unitsPerMinute = round(unitsPerMinute) + self.referenceTicks = round(referenceTicks) + self.graphType = "standalone" #options: linear, standalone + self.lilypondParameters = {"tempo":""} #for example 'Allegro' or 'Ein bischen schneller'. Only strings are allowed. + self._secondInit(parentBlock = None) + + def _secondInit(self, parentBlock): + """see Score._secondInit""" + #ignore parentBlock + self.rememberTempoItem() + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.unitsPerMinute = int(serializedObject["unitsPerMinute"]) + self.referenceTicks = int(serializedObject["referenceTicks"]) + self.graphType = serializedObject["graphType"] + self.lilypondParameters = serializedObject["lilypondParameters"] + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = {} + result["class"] = self.__class__.__name__ + result["unitsPerMinute"] = self.unitsPerMinute + result["referenceTicks"] = self.referenceTicks + result["graphType"] = self.graphType + result["lilypondParameters"] = self.lilypondParameters + return result + + def rememberTempoItem(self): + oid = id(self) + TempoItem.allTempoItems[oid] = self + #weakref_finalize(self, print, "deleted tempoItem "+str(oid)) + return oid + + def copy(self): + new = TempoItem(unitsPerMinute = self.unitsPerMinute, referenceTicks = self.referenceTicks) + new.graphType = self.graphType + new.lilypondParameters = self.lilypondParameters + return new + + def asAbsoluteTempo(self): + """Return an absolute tempo value which can be compared. + quarter = 120 will be lower/slower than dotted-quarter=120. + It is quite simple: the more ticks per minute, the faster. + We can just multiplicate the unitsPerMinute with the + referenceTicks. + """ + return round(self.referenceTicks * self.unitsPerMinute / D4) #normalize for a quarter note + + def __lt__(self, other): # self < other + return self.asAbsoluteTempo() < other.asAbsoluteTempo() + def __le__(self, other): # self <= other + return self.asAbsoluteTempo() <= other.asAbsoluteTempo() + + #defining __eq__ makes the class unhashable and membership tests like if tempoItem in dict.values() will fail! + #def __eq__(self, other): # self == other + # return self.asAbsoluteTempo() == other.asAbsoluteTempo() + + def __ne__(self, other): # self != other + return self.asAbsoluteTempo() != other.asAbsoluteTempo() + def __gt__(self, other): # self > other + return self.asAbsoluteTempo() > other.asAbsoluteTempo() + def __ge__(self, other): # self >= other + return self.asAbsoluteTempo() >= other.asAbsoluteTempo() + + def linearRepresentation(self, endAbsoluteTempoFromTheNextItem, tickStart, tickEnd): + """ + the variable is taken from the standard formula: f(x) = m*x + n + m = (x2-x1) / (y2-y1) + x1 = tick start + y1 = AbsoluteTempo start + x2 = tick end + y2 = AbsoluteTempo end + + tickStart and tickEnd are absolute values for the complete track + This means we can directly export them to calfbox. + + result is tuples (asAbsoluteTempo, tickPositionOfThatTempoValue) + """ + result = [] + startTempo = self.asAbsoluteTempo() + + assert 0 < startTempo + assert 0 < endAbsoluteTempoFromTheNextItem + + if endAbsoluteTempoFromTheNextItem == startTempo: #there is no interpolation. It is just one value, the one of the current TempoItem. Basically the same as graphType == "standalone" + result.append(((self.asAbsoluteTempo(), self.unitsPerMinute, self.referenceTicks), tickStart)) + return result + + m = (tickEnd - tickStart) / (endAbsoluteTempoFromTheNextItem - startTempo) #we need to calculate this after making sure that endAbsoluteTempoFromTheNextItem and start are not the same. Else we get /0 + #From here on: We actually need interpolation. Let the math begin. + if endAbsoluteTempoFromTheNextItem > startTempo: #upward slope + iteratorList = list(range(startTempo, endAbsoluteTempoFromTheNextItem)) #20 to 70 results in 20....69 + else: #downward slope + iteratorList = list(range(endAbsoluteTempoFromTheNextItem+1, startTempo+1)) #70 to 20 results ins 70...21 + iteratorList.reverse() + + #Calculate at which tick a given tempoValue will happen. value = m * (i - y1) + for tempoValue in iteratorList: + result.append((tempoValue, tickStart + int(m * (tempoValue - startTempo)))) # int(m * (tempoValue - startTempo)) results in 0 for the first item (set by the user). so the first item is just tickStart. that does not mean tickStart for the first item is 0. We just normalize to tickStart as virtual 0 here. + assert result + assert result[0][1] == tickStart + result[0] = ((result[0][0], self.unitsPerMinute, self.referenceTicks), result[0][1]) #this will be used later in the track static generation to inform the receiver what the original tempo data was. + return result + + def staticRepresentation(self, endAbsoluteTempoFromTheNextItem, tickStart, tickEnd): + if self.graphType == "standalone" or tickEnd < 0 or endAbsoluteTempoFromTheNextItem < 0: + result = [((self.asAbsoluteTempo(), self.unitsPerMinute, self.referenceTicks), tickStart)] + elif self.graphType == "linear": + result = self.linearRepresentation(endAbsoluteTempoFromTheNextItem, tickStart, tickEnd) + else: + raise ValueError("Graph Type unknown:", self.graphType) + assert result + return result + +class TempoBlock(GraphBlock): + """A tempo block holds many different things. + First of all the tempo changes and its interpolations. + + The duration of a tempo block is fixed and does not depend + on the content + """ + + #allTempoBlocks = WeakValueDictionary() #key is the blockId, value is the weak reference to the Block + allTempoBlocks = {} + firstBlockWithNewContentDuringDeserializeToObject = dict() #this is not resetted anywhere since each load is a program start. + #tempoTrack = the only tempo track. set by tempo track init, which happens only once in the program. + + def __init__(self, parentGraphTrack): + super().__init__(self) + #self.parentGraphTrack = parentGraphTrack + self.data = {0:TempoItem(120, D4)} #default is quarter = 120 bmp. + self.name = str(id(self)) + self._secondInit(parentGraphTrack) + + def _secondInit(self, parentGraphTrack): + """see Score._secondInit""" + self.linkedContentBlocks.add(self) + self.rememberTempoBlock() + self.parentGraphTrack = parentGraphTrack + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentGraphTrack): + """see Score.instanceFromSerializedData.""" + #TODO: this is nearly the same as the GraphBlock method with the same name. During development it made sense to write to different functions. But this can be simplified by calling super().instanceFromSerializedData + + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + if serializedObject["data"] is None: + firstBlock = TempoBlock.firstBlockWithNewContentDuringDeserializeToObject[serializedObject["contentLinkGroup"]] #first block with the same contentGroup. This is the one with the real data. + self.data = firstBlock.data + self._duration = firstBlock._duration + self.linkedContentBlocks = firstBlock.linkedContentBlocks #add self to this is in _secondInit + else: #Standalone or First occurence of a content linked block + self.data = {int(position):eval(item["class"]).instanceFromSerializedData(item, parentObject = self) for position, item in serializedObject["data"].items()} + TempoBlock.firstBlockWithNewContentDuringDeserializeToObject[serializedObject["contentLinkGroup"]] = self + self._duration = [int(serializedObject["duration"])] #this is just an int, minimumBlockInTicks or so. Not Item.Duration(). For save and load we drop the list as mutable value. + self.linkedContentBlocks = WeakSet() + + #No super() deserialize call here so we need to create all objects directly: + self.name = serializedObject["name"] + self._secondInit(parentGraphTrack) + return self + + def serialize(self): + result = super().serialize() + return result + + def getDataAsDict(self): + return { "name" : self.name, + "duration" : self.duration, #For save and load we drop the list as mutable value. + } + + def putDataFromDict(self, dataDict): + """modify inplace. Useful for a gui function. Compatible with + the data from getDataAsDict""" + for parameter, value in dataDict.items(): + if parameter == "name": + self.name = value + elif parameter == "duration": + self.duration = value + else: + raise ValueError("Block does not have this property", parameter, value) + + def getMinimumAndMaximumValues(self): + sort = sorted(self.data.values(), key=lambda x: x.asAbsoluteTempo()) + return sort[0].asAbsoluteTempo(), sort[-1].asAbsoluteTempo() + + def rememberTempoBlock(self): + oid = id(self) + TempoBlock.allTempoBlocks[oid] = self + #weakref_finalize(self, print, "deleted tempoBlock "+str(oid)) + return oid + +class TempoTrack(GraphTrackCC): + """The Tempo Track is Laborejos own independent structure that sends data to + template.sequencer.TempoMap which handles the actual midi/cbox tempo map """ + + def __init__(self, parentData): + firstBlock = TempoBlock(parentGraphTrack = self) + firstBlock.name = "Default Tempo" + self.blocks = [firstBlock] + self.parentData = parentData + self._secondInit() + + def _secondInit(self): + """see Score._secondInit""" + pass + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentData): #parentData is the score, not a track, like for CCTracks + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.parentData = parentData + self.blocks = [TempoBlock.instanceFromSerializedData(block, parentGraphTrack = self) for block in serializedObject["blocks"]] + self._secondInit() + return self + + def serialize(self): + result = {} + result["class"] = self.__class__.__name__ + result["blocks"] = [block.serialize() for block in self.blocks] + return result + + def getMinimumAndMaximumValues(self): + allValues = (bl.getMinimumAndMaximumValues() for bl in self.blocks) + mini, maxi = zip(*allValues) + return min(mini), max(maxi) + + def appendTempoBlock(self): + """A simple method to add a new GraphBlock at the end of the + current track. Basically you can do the same with split and + resize, but this is much more easier.""" + new = TempoBlock(parentGraphTrack = self) + self.blocks.append(new) + return new + + def duplicateBlock(self, tempoBlock): + index = self.blocks.index(tempoBlock) + copy = tempoBlock.copy() + self.blocks.insert(index +1, copy) + + def duplicateContentLinkBlock(self, tempoBlock): + index = self.blocks.index(tempoBlock) + linked = tempoBlock.contentLink() + self.blocks.insert(index +1, linked) + + def splitTempoBlock(self, tempoBlockId, positionInTicksRelativeToBlock): + """The new block will be right of the original content. If the new block will be empty + or has no real start value the last prevailing tempo will be used + as the blocks start-point""" + block = self.tempoBlockById(tempoBlockId) + if not block.duration > positionInTicksRelativeToBlock: + return False + + hasPointAtZero = False + toDelete = [] + modelNewBlock = TempoBlock(parentGraphTrack = self) #will not be used directly, but instead content links will be created. + for pos, item in block.data.items(): + #Determine if a tempo point gets to move to the new block + if pos >= positionInTicksRelativeToBlock: + if pos == positionInTicksRelativeToBlock: + hasPointAtZero = True + modelNewBlock.data[pos - positionInTicksRelativeToBlock] = item + toDelete.append(pos) + #else: tempoPoint stays in the old block + + for pos in toDelete: + del block.data[pos] + + #Since every tempo block comes with a default D4=120 value at position 0 we need to check if this was already replaced or if we need to adjust it to the real tempo at this point in time. + if not hasPointAtZero: + realStartTempoPoint = block.data[block.getMaxContentPosition()] #only the remaining items. + modelNewBlock.data[0] = realStartTempoPoint.copy() + + #Now the original block and all its content links have fewer items than before + #For every of the content-linked blocks in the tempo track we need to create a new block and insert it right next to it. + + for bl in block.linkedContentBlocksInScore(): + index = self.blocks.index(bl) + link = modelNewBlock.contentLink() + self.blocks.insert(index +1, link) + + #duration is mutable. All content links change duration as well. + link.duration = block.duration - positionInTicksRelativeToBlock + block.duration = positionInTicksRelativeToBlock + + del TempoBlock.allTempoBlocks[id(modelNewBlock)] #Clean up the model block since it was never intended to go into the TempoTrack + + return True + + def mergeWithNextTempoBlock(self, tempoBlockId): + """see structures block (the music block) for an explanation about merging content linked + blocks. + + Hidden items (after the current duration value) of the original block + will be deleted. Hidden items of the follow-up block will be merged, but stay hidden. + """ + self.cleanBlockEdges() #only one tempoItem per tick position, even if they are in different blocks. #TODO: remember this when creating undo for merge! + + block = self.tempoBlockById(tempoBlockId) + + if len(self.blocks) == 1: + #print ("only one block in the track") + return False + + blockIndex = self.blocks.index(block) + + if blockIndex+1 == len(self.blocks): + #print ("not for the last block") + return False + + nextIndex = blockIndex + 1 + nextBlock = self.blocks[nextIndex] + + firstBlock_endingTempo = block.data[block.getMaxContentPosition()].asAbsoluteTempo() + nextBlock_startingTempo = nextBlock.data[0].asAbsoluteTempo() + + startDurationToReturnForUndo = block.duration + + if len(block.linkedContentBlocksInScore()) == 1 and len(nextBlock.linkedContentBlocksInScore()) == 1: #both blocks are standalone. no content-links. This also prevents that both blocks are content links of each other. + block.deleteHiddenItems() + + if firstBlock_endingTempo == nextBlock_startingTempo: #remove redundancy + del nextBlock.data[0] + + for pos, item in nextBlock.data.items(): + assert not pos + block.duration in block.data + block.data[pos + block.duration] = item + + block.duration += nextBlock.duration + self.deleteBlock(nextBlock) + + return startDurationToReturnForUndo + + elif len(block.linkedContentBlocksInScore()) == len(nextBlock.linkedContentBlocksInScore()): #It is maybe possible to build pairs from the current block and all its content links with the follow up block and all its content links. + #Further testing required: + for firstBlock, secondBlock in zip(block.linkedContentBlocksInScore(), nextBlock.linkedContentBlocksInScore()): + if firstBlock.data is secondBlock.data: #content link of itself in succession. Very common usecase, but not compatible with merging. + #print ("content link follows itself") + return False + elif not self.blocks.index(firstBlock) + 1 == self.blocks.index(secondBlock): #all first blocks must be followed directly by a content link of the second block. linkedContentBlocksInScore() returns a blocklist in order so we can compare. + #print ("not all blocks-pairs are next to each other") + return False + + #Test complete without exit. All blocks can be paired up. + #print ("Test complete. Merging begins") + + block.deleteHiddenItems() + + if firstBlock_endingTempo == nextBlock_startingTempo: #remove redundancy + del nextBlock.data[0] + + for pos, item in nextBlock.data.items(): + assert not pos + block.duration in block.data #this includes pos==0, if not deleted above. + block.data[pos + block.duration] = item + + block.duration += nextBlock.duration + + for bl in nextBlock.linkedContentBlocksInScore(): + self.deleteBlock(bl) + + return startDurationToReturnForUndo + + else: #The blocks across the track can't be paired up, this cannot possibly work cleanly. + #print ("blocks can't be paired up") + return False + + + def tempoBlockById(self, tempoBlockId): + return TempoBlock.allTempoBlocks[tempoBlockId] + + + def expandLastBlockToScoreDuration(self): + """This can lead to unexpected behaviour if the last block is content-linked and will resize + automatically when the score-duration gets longer. All the other content links will resize + as well. + This is expected behaviour and there is a note in the users manual to prevent that confusion""" + block = self.blocks[-1] + plainScoreDuration = self.parentData.duration() + durationWithoutLastBlock = self.durationWithoutLastBlock() + if plainScoreDuration > 0:# and plainScoreDuration - durationWithoutLastBlock > block.duration: + block.duration = plainScoreDuration - durationWithoutLastBlock + return block.duration + else: + block.duration = D1*4#plainScoreDuration - durationWithoutLastBlock + return block.duration + + + def tempoBlocKByAbsolutePosition(self, tickPositionAbsolute): + """The staticBlockRepresentation is in correct, ascending, order. + We reverse it for testing >= so we can check directly in a for-loop for the current value. + Each tempo-block start position has a higher tickindex except the block we are searching for + + Without reversing we would have to test if the for-loop tempo block is bigger than our + given position and then return the _previous_ block. + + (Alternative: loop forward but use position+duration for the test. But why...) + """ + #Remember: this function gets called by the cursor at every change. + for dictExportItem in reversed(self.staticGraphBlocksRepresentation()): + if tickPositionAbsolute >= dictExportItem["position"]: #block start + if not dictExportItem["position"] <= tickPositionAbsolute <= dictExportItem["position"] + dictExportItem["duration"]: #make sure the point is really in this block. It is guaranteed that the tempo track is always at least as long as the music tracks. + raise ValueError("position {} is not within the tempo tracks boundaries".format(tickPositionAbsolute)) + return dictExportItem["id"], dictExportItem["position"] + else: + raise ValueError("no block found") + + def tempoItemById(self, tempoItemId): + tempoItem = TempoItem.allTempoItems[tempoItemId] + assert tempoItemId == id(tempoItem) + for block in self.blocks: + if tempoItem in block.data.values(): + return block, tempoItem + else: + raise ValueError("Block not in the TempoTrack") + + def tempoAtTickPosition(self, tickPositionAbsolute): + """Return unitsPerMinute and referenceTick of the tempo at the given tick positon. + if there is no tempo item at this position search to the left until you find one. + + We don't use self.staticRepresentation because that also gives us all interpolated points. + Interpolated points have no units * and reference factors but just a combined value for + midi or a GUI. + """ + + blockId, blockStartPos = self.tempoBlocKByAbsolutePosition(tickPositionAbsolute) + block = self.tempoBlockById(blockId) + tickPositions = sorted(block.data.keys()) # tick:tempoItem + tickPositions = reversed(tickPositions) #for an easier search. see tempoBlocKByAbsolutePosition docstring + + x = tickPositionAbsolute - blockStartPos + + for pos in tickPositions: + if x >= pos: #pos is the tempoItem left of our position. in other words: the tempo currently active at our position. + tempoItem = block.data[pos] + return tempoItem #tempoItem.unitsPerMinute, tempoItem.referenceTicks + + + def staticGraphBlocksRepresentation(self): + """Return a sorted list""" + result = [] + tickCounter = 0 + for block in self.blocks: + result.append({"type" : "GraphBlock", "id":id(block), "name":block.name, "duration":block.duration, "position":tickCounter, "exportsAllItems":block.exportsAllItems(), }) + tickCounter += block.duration + return result + + def staticRepresentation(self): + """see structures.Track.staticRepresentation""" + self.expandLastBlockToScoreDuration() + + typeString = "" + sumOfBlocksDurationsWithoutCurrent = 0 + result = [] + pblob = bytes() # Create a binary blob that contains the MIDI events for CC tracks + for blockIndex in range(len(self.blocks)): + block = self.blocks[blockIndex] + assert len(block.data) > 0 + l = block.staticRepresentation() #this takes care that only user items which fit in the block.duration are exported. + for itemIndex in range(len(l)): #range starts from 0 so we can use this as index. + #l has tuples (tickPositionFromBlockStart, GraphItem) + thisPosition = l[itemIndex][0] + thisGraphItem = l[itemIndex][1] + + #Check if we reached the last item in this block. + if itemIndex is len(l)-1: #len counts from 1, itemIndex from 0. + assert thisGraphItem is l[-1][1] #l[-1] is a tuple (tickPositionFromBlockStart, GraphItem) + #Is there another block after this one? + if block is self.blocks[-1]: #this was the last block? + #there is no nextGraphItem and subsequently no interpolation. + typeString = "lastInTrack" # also a switch for later. + nextPosition = -1 #doesn't matter + #this is checked later in the loop, before we create the exportDict + else: #there is still a block left after the current + #The nextGraphItem can be found in the next block. + nextBlock = self.blocks[blockIndex+1] + nextBlockL = nextBlock.staticRepresentation() + nextPosition = nextBlockL[0][0] + block.duration #Instead of itemIndex we just need [0] for the first in the next block. + nextGraphItem = nextBlockL[0][1] #Instead of itemIndex we just need [0] for the first + else: #default case. Next item is still in the same block. + nextPosition = l[itemIndex+1][0] + nextGraphItem = l[itemIndex+1][1] + + #We now generate a chain of items from the current position to the next, + #at least one, depending on the interpolation type (like linear, none etc.) + + if typeString == "lastInTrack": + userItemAndInterpolatedItemsPositions = thisGraphItem.staticRepresentation(-1, thisPosition, -1) #-1 are magic markers that indicate a forced standalone mode. no interpolation, we just get one item back. + else: + assert thisPosition >= 0 + assert nextPosition >= 0 + typeString = "user" #interpolated, lastInTrack + userItemAndInterpolatedItemsPositions = thisGraphItem.staticRepresentation(nextGraphItem.asAbsoluteTempo(), thisPosition, nextPosition) + + + for ccValue, generatedTickPosition in userItemAndInterpolatedItemsPositions: #generatedTickPosition is relative to the block beginning. + additionalData = {} + if typeString == "user" or typeString == "lastInTrack": #interpolated items can be anywhere. We don't care much about them. + assert generatedTickPosition <= block.duration + ccValue, additionalData["unitsPerMinute"], additionalData["referenceTicks"] = ccValue #additional data is not for interpolated items + + assert generatedTickPosition >= 0 + + exportDictItem = { + "type" : typeString, + "value": -1*ccValue, #minus goes up because it reduces the line position, which starts from top of the screen. For a tempo this is a bpm value for quarter notes. This is meant for a gui which needs only one combined value to order all items graphically on an axis. + "position" : sumOfBlocksDurationsWithoutCurrent + generatedTickPosition, #generatedTickPosition is relative to the block beginning. + "positionInBlock": generatedTickPosition, + "id" : id(thisGraphItem), + "blockId": id(block), + "minPossibleAbsolutePosition" : sumOfBlocksDurationsWithoutCurrent, #If you want to move this item to the left or right, this is only possible within the current block. + "maxPossibleAbsolutePosition" : sumOfBlocksDurationsWithoutCurrent + block.duration, #If you want to move this item to the left or right, this is only possible within the current block. + "lastInBlock" : len(block.data) == 1, + "graphType" : thisGraphItem.graphType, + "lilypondParameters" : thisGraphItem.lilypondParameters, + } + if additionalData: #additional data is not for interpolated items + exportDictItem.update(additionalData) + result.append(exportDictItem) + typeString = "interpolated" #The next items in userItemAndInterpolatedItemsPositions are interpolated items. Reset once we leave the local forLoop. + + #Prepare data for the next block. + sumOfBlocksDurationsWithoutCurrent += block.duration #the naming is only true until the last iteration. Then all blocks, even the current one, are in the sum and can be used below. + + #We duplicate the last exportItem and set it as interpolated tempo point on the last tick. + #This is after the one marked as "lastInTrack". + virtualLast = { + "type" : "interpolated", + "value": exportDictItem["value"], + "position" : self.parentData.duration(), + "positionInBlock": self.parentData.duration() - sumOfBlocksDurationsWithoutCurrent, + "id" : exportDictItem["id"], + "blockId": exportDictItem["blockId"], + "minPossibleAbsolutePosition" : exportDictItem["minPossibleAbsolutePosition"], + "maxPossibleAbsolutePosition" : exportDictItem["maxPossibleAbsolutePosition"], + "lastInBlock" : exportDictItem["lastInBlock"], + "graphType" : exportDictItem["graphType"], + "lilypondParameters" : exportDictItem["lilypondParameters"], + } + virtualLast.update(additionalData) + #Add this to the result AFTER we calculate the midi data. Otherwise it will result in conflicts. + + #send tempo information to cbox. + blocksAsDict = self.blocksAsDict() + offsetForBlock = {} + + offsetCounter = 0 + for block in self.blocks: + offsetForBlock[block] = offsetCounter + offsetCounter += block.duration #after this block is over how many ticks have gone by? + + sendToSequencerTempoMap = {} #pos:value + for staticItem in result: #static item is a tempo change as exportDictItem from above. + value = float(abs(staticItem["value"])) #exportItems have negative values. calfbox wants a float. + tempoBlock = blocksAsDict[staticItem["blockId"]] + absoluteBlockStartPosition = offsetForBlock[tempoBlock] + pos = staticItem["positionInBlock"] + absoluteBlockStartPosition + sendToSequencerTempoMap[pos] = value + + self.parentData.tempoMap.setTempoMap(sendToSequencerTempoMap) + + result.append(virtualLast) + return result + + #not in use. + def groupItems(self, ranges, exportItems): + """this is kind of a waste. All we are doing is + reverse engineering which item was in which tempo-block + ... or do we? Alternate Endings give us ranges which + are not block based.""" + ranges = list(set(ranges)); ranges.sort() #make unique # ranges = [(start, end), ...] + result = {} + + for tup in ranges: + result[tup] = [] + + for item in exportItems: + for start, end in ranges: + #print (start, end, item["position"]) + if start <= item["position"] < end: + result[(start,end)].append(item["position"]) + break + else: + raise ValueError("tempo item does not match any range, which should be impossible") + + return result + + + def rearrangeBlocks(self, listOfBlockIds): + """Reorder the blocks in this track. + Achtung! Not including a block will delete this block.""" + #blocksDict = self.blocksAsDict() + newBlockArrangement = [] + + for idLong in listOfBlockIds: + #newBlockArrangement.append(blocksDict[idLong]) + newBlockArrangement.append(TempoBlock.allTempoBlocks[idLong]) #all blocks includes deleted blocks in the undo memory. + + #a block is a unique unit in Laborejo2. Let's make sure there are no duplicates. + #http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order + seen = set() + seen_add = seen.add + self.blocks = [ x for x in newBlockArrangement if x not in seen and not seen_add(x)] + assert self.blocks + + + def lilypond(self): + """Based on the static export""" + def _ly(tempoItem, nextTempoItem): + if tempoItem["graphType"] in ("standalone", "linear"): + ramp = "" + if not tempoItem["graphType"] == "standalone": + #Accelerando and Deccelerando + if nextTempoItem["value"] < tempoItem["value"]: #value is y-reversed + ramp = '^"accel" ' + elif nextTempoItem["value"] > tempoItem["value"]: + ramp = '^"rit" ' + elif nextTempoItem["value"] == tempoItem["value"]: + ramp = "" + + positionInD1024Skips = int((nextTempoItem["position"] - tempoItem["position"]) / D1024) + + skipString = "s1024*{}{}".format(positionInD1024Skips, ramp) + if tempoItem["referenceTicks"] == _ly.lastItem["referenceTicks"] and tempoItem["unitsPerMinute"] == _ly.lastItem["unitsPerMinute"]: + _ly.lastItem = tempoItem + return skipString + else: + _ly.lastItem = tempoItem + return "\\tempo {} {} = {} {}".format(tempoItem["lilypondParameters"]["tempo"], duration.baseDurationToTraditionalNumber[tempoItem["referenceTicks"]], str(tempoItem["unitsPerMinute"]), skipString) + + raise NotImplementedError + _ly.lastItem = {"referenceTicks":"", "unitsPerMinute":""} + + onlyStandalone = list(sorted((tempoItem for tempoItem in self.staticRepresentation() if not tempoItem["type"] == "interpolated"), key=lambda i: i["position"])) + onlyStandalone = onlyStandalone + [onlyStandalone[-1]] #for pairs + pairs = pairwise(onlyStandalone) + result = " ".join(_ly(tempoItem, nextTempoItem) for tempoItem, nextTempoItem in pairs) + return result diff --git a/engine/items.py b/engine/items.py new file mode 100644 index 0000000..c5601c1 --- /dev/null +++ b/engine/items.py @@ -0,0 +1,2812 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" +import logging; logging.info("import {}".format(__file__)) + +#Standard Library Modules +from collections import deque +from fractions import Fraction +from weakref import WeakSet, WeakValueDictionary +from warnings import warn + +#Third Party Modules +from calfbox import cbox + +#Template Modules +import template.engine.pitch as pitchmath +import template.engine.duration as duration +from template.engine.duration import DM, DB, DL, D1, D2, D4, D8, D16, D32, D64, D128, D256, D512, D1024, D_DEFAULT, D_STACCATO, D_TENUTO, D_TIE +from template.helper import EndlessGenerator, flatList + +########################## +## Part of other items ## +########################## + +class Note(object): + """A note cannot be inserted in a track directly. It relies on a Chord structure. + + A note is not the level of operation. All note operations go through the notes parent Chord + item. This is not only a design but is actually needed for undo. Only the Chord methods return + their reverse operation for the undo system to register. + + for example note.octaveUp just sets self.pitch an octave up and returns None.""" + + allNotes = WeakValueDictionary() #key is the noteId, value is the weak reference to the Note. AND NOT CHORDS + + def __init__(self, parentChord, duration, pitch): + self.pitch = pitch #a value from constants.py with octave modifier + self.duration = duration #a Duration instance + self.dynamic = Dynamic() + self._secondInit(parentChord) + + def _secondInit(self, parentChord): + """see Item._secondInit""" + self.parentChord = parentChord + self.rememberNote() + + @property + def pitch(self): + if self._pitch < 20: + warn("Pitch {} lower than the lowest note detected. Exported normalized non-destructively to lowest possible note. Please raise pitch again manually before further editing.".format(self._pitch)) + return 20 + elif self._pitch > 3140: + warn("Pitch {} higher than the highest note detected. Exported normalized non-destructively to highest possible note. Please raise pitch again manually before further editing.".format(self._pitch)) + return 3140 + else: + return self._pitch + + @pitch.setter + def pitch(self, value): + self._pitch = value + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self._pitch = int(serializedObject["pitch"]) + self.duration = Duration.instanceFromSerializedData(serializedObject["duration"], parentObject = self) + self.dynamic = Dynamic.instanceFromSerializedData(serializedObject["dynamic"], parentObject = self) + self._secondInit(parentChord = parentObject) + return self + + def serialize(self): + result = {} + result["class"] = "Note" + result["duration"] = self.duration.serialize() + result["pitch"] = self._pitch + result["dynamic"] = self.dynamic.serialize() + return result + + def rememberNote(self): + oid = id(self) + Note.allNotes[oid] = self + #weakref_finalize(self, print, "deleted note "+str(oid)) + return oid + + def copy(self, newParentChord): + new = Note(newParentChord, self.duration.copy(), self._pitch) + new.dynamic = self.dynamic.copy() + return new + + def __lt__(self, other): # self < other + return self.pitch < other.pitch + def __le__(self, other): # self <= other + return self.pitch <= other.pitch + def __eq__(self, other): # self == other + return self.pitch == other.pitch + def __ne__(self, other): # self != other + return self.pitch != other.pitch + def __gt__(self, other): # self > other + return self.pitch > other.pitch + def __ge__(self, other): # self >= other + return self.pitch >= other.pitch + + def asDotOnLine(self, clef): + return pitchmath.distanceInDiatonicStepsFrom1720[self.pitch] + clef.asDotOnLineOffset + + def accidental(self, keysig): + """-20, -10, 0, +10, +20 + and just 1, which is Natural""" + diff = pitchmath.diffToKey(self.pitch, keysig) + + #If there is a variation to the keysig. We need to find out if a white note has to get an accidental or an already altered noted (from the keysig) gets a natural sign. + if diff and self.pitch == pitchmath.toWhite[self.pitch]: + return 1 #natural + elif diff == 0: #This just means it is the same as the keysig. + return diff + else: #it is different to the keysig. Traditionally the accidental shows the difference to white, not to the keysig. eis in C-minor is #e not Xe/##e + return self.pitch - pitchmath.toWhite[self.pitch] + + #Inplace pitch modifications + def sharpen(self): + self.pitch = pitchmath.sharpen(self.pitch) + + def flatten(self): + self.pitch = pitchmath.flatten(self.pitch) + + def intervalAutomatic(self, rootPitch, targetPitch): + """Change the notepitch with the same interval that is between + rootPitch and targetPitch""" + self.pitch = pitchmath.intervalAutomatic(self.pitch, rootPitch, targetPitch) + + def mirrorAroundCursor(self, cursorPitch): + self.pitch = pitchmath.mirror(self.pitch, axis=cursorPitch) + + #def toWhite(self): + # self.pitch = pitch.toWhite[self.pitch] + + #def mirror(self, keysig, axis): + # """Wants two pitches""" + # self.pitch = pitch.mirror(self.pitch, axis) + # self.toScale(keysig) + + def octaveUp(self): + self.pitch = self.pitch + 350 + + def octaveDown(self): + self.pitch = self.pitch - 350 + + def toScale(self, keysig): + self.pitch = pitchmath.toScale(self.pitch, keysig) + + def stepUpInScale(self, keysig): + self.pitch += 50 + self.toScale(keysig) #adjust to keysig. + + def stepDownInScale(self, keysig): + self.pitch -= 50 + self.toScale(keysig) #adjust to keysig. + + def exportObject(self, trackState): + dur = self.duration.completeDuration() + on, off = self.duration.noteOnAndOff(trackState, dur) + result = { + "type" : "note", + "id" : id(self), + "accidental" : self.accidental(trackState.keySignature()), + "dotOnLine" : self.asDotOnLine(trackState.clef()), + "dots" : self.duration.dots, + "tuplets" : self.duration.tuplets, + "notehead" : self.duration.notehead, + + "completeDuration" : dur, + #"leftModInTicks" : self.duration.startModInTicks(trackState), #only for gui. midi is in self.noteOnAndOff + "leftModInTicks" : on, + #"rightModInTicks" : self.duration.endModInTicks(trackState), #only for gui. midi is in self.noteOnAndOff + "rightModInTicks" : off - dur, + + "tieDistanceInTicks" : dur, #because technically that is right. This note sounds until this value. + "tie" : "", #empty, first, notFirst . notFirst is the end of a tie-sequence as well as a middle tie: c ~ [c] ~ c + + "manualOverride" : bool(self.duration.shiftStart or (self.duration.shiftEnd and not self.duration.durationKeyword == D_TIE)), + "durationKeyword" : self.duration.durationKeyword, #an int. We internally use constants through module constants.D_KEYWORD + "velocity" : self.dynamic.velocity(trackState), #int + "velocityManualOverride" : bool(self.dynamic.velocityModification), + "endTick" : trackState.tickindex, #for ties. + "dynamicKeyword" : self.dynamic.dynamicKeyword, #int/"enum", defined in constants. One-time Dynamic Signature for sfz, fp and accents. + } + + #Handle tied notes. + if self.pitch in trackState.EXPORTtiedNoteExportObjectsWaitingForClosing: + result["tie"] = "notFirst" + if not self.duration.durationKeyword == D_TIE: #this was the last tied note, not a middle. + trackState.EXPORTtiedNoteExportObjectsWaitingForClosing[self.pitch]["rightModInTicks"] = trackState.tickindex - trackState.EXPORTtiedNoteExportObjectsWaitingForClosing[self.pitch]["endTick"] + result["rightModInTicks"] + trackState.EXPORTtiedNoteExportObjectsWaitingForClosing[self.pitch]["tieDistanceInTicks"] = trackState.tickindex - dur - trackState.EXPORTtiedNoteExportObjectsWaitingForClosing[self.pitch]["endTick"] + trackState.EXPORTtiedNoteExportObjectsWaitingForClosing[self.pitch]["completeDuration"] + + del trackState.EXPORTtiedNoteExportObjectsWaitingForClosing[self.pitch] #delete this pitch from the dict. Obviously this does not delete the exportObject. + elif self.duration.durationKeyword == D_TIE: #since we already made sure this pitch is not waiting for a closing/middle tie but we are a tie we can be sure to be the first in a sequence. + result["tie"] = "first" + trackState.EXPORTtiedNoteExportObjectsWaitingForClosing[self.pitch] = result + + self._cachedExportObject = result + + return result + + def lilypond(self): + """Called by chord.lilypond(), See Item.lilypond for the general docstring. + Returns two strings, pitch and duration. + The duration is per-chord or needs special polyphony.""" + return pitchmath.pitch2ly[self.pitch], self.duration.lilypond() + +class Dynamic(object): + """dynamic means velocity midi terms. + (but not volume and not expression). + + Absolute velocity can never go over 128 or below 0. 0 means mute. + + This is not a Dynamic Item which can be inserted into a track. + + Only notes have a working dynamic attribute. + """ + def __init__(self): + self.velocityModification = 0 #signed int which will simply get added to the current dynamic signatures value. + self.dynamicKeyword = 0 #TODO One-time Dynamic Signature for sfz, fp and accents. + + def _secondInit(self, parentNote): + """see Item._secondInit""" + pass + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.velocityModification = int(serializedObject["velocityModification"]) + self.dynamicKeyword = int(serializedObject["dynamicKeyword"]) + self._secondInit(parentNote = parentObject) + return self + + def serialize(self): + result = {} + result["class"] = "Dynamic" + result["velocityModification"] = self.velocityModification + result["dynamicKeyword"] = self.dynamicKeyword + return result + + def copy(self): + new = Dynamic() + new.velocityModification = self.velocityModification #int, needs no special copy + new.dynamicKeyword = self.dynamicKeyword #int, needs no special copy + return new + + def velocity(self, trackState): + #todo: if keyword. see init + base = trackState.dynamicSignature().baseVelocity(trackState) + if trackState.dynamicRamp: #maybe override the baseVelocity. + vel = trackState.dynamicRamp.getVelocity(trackState.tickindex - trackState.track.previousItem().logicalDuration() ) #TODO: The tickindex is already ahead of the current item. Somehow in the whole program that doesn't matter except for DynamicRamps. this is really strange. I don't know if this is a design error or one of the few exceptions. Actually, a rather prominent "exception" is the exportObject for every item which is state.tickindex - item.logicalDuration() and even has a comment. So I guess it is alright. + if not vel is None: #0 is good. None means there is a DynamicRamp but not a target velocity. So we ignore it for now. + base = vel + + value = int(base + self.velocityModification) + if value < 0: + return 0 + elif value > 127: + return 127 + else: + return value + +class Duration(object): + """Don't be confused by the amount of durations in the score. + Each item has a duration. A clef has a duration, including the default one in TrackState. + A chord has a null-duration itself, because it is an Item, and also each note in the chord + has its own duration. These are the real durations. + + There are multiple concepts of "duration" in the program: + + baseDuration: The note without dots, tuplets or other modifications. This is the basic note + on a sheet of paper. + + completeDuration: baseDuration with dots and tuplets. But no shifting(staccato, manual mod etc.) + + noteOnAndOff: the final tick value for midi export. complete duration with all + expression modifications like staccato, slurs or tenuto and user fine control + + logicalDuration: Value used to calculate the order and spacing of items. aka. determines how + many ticks the cursor advances when parsing the item or how many pixels space are needed in a + GUI before the next item. For normal chords this is the same as completeDuration. + But this also includes values for MultiMeasure Rests and other special cases. + Note that this is not the sounding duration from noteOnAndOff but the "original" duration + without any interpretation or expression based modifications. + + The duration of a chord is called "durationGroup", which is it's own class. Why the name + mismatch? Because all the data that matters to the outside gets exported to a static dict. + + For chords the logicalDuration is the shortest logical note. Example: A chord consists of + a half note with staccato and a quarter note which is extended by quite a bit through manual + shifting. The sounding quarter note is longer than the sounding half note. + noteOnAndOff(half note) < noteOnAndOff(quarter). + But the logical duration is still the completeDuration where a half note is always longer than + a quarter note. + """ + + def __init__(self, baseDuration): + self._baseDuration = baseDuration #base value. Without dots, tuplets/times , overrides etc. this is the duration for all representations + self.tuplets = [] # a list of tuplets [(numerator, denominator), (,)...]. normal triplet is (2,3). Numerator is the level of the notehead. 2^n Each is one level of tuplets, arbitrary nesting depth. [2,3] for triplet # Tuplet multiplication is used for all representations and gets auto-merged on lilypond output to tuplet groups (if its in a chord). This is a list and not tuple() because json load will make it a list anyway. + self.dots = 0 #number of dots. + self.durationKeyword = D_DEFAULT + #The offsets shift the start and ending to the left and right or rather: earlier and later. positive values mean later, negative values mean earlier. + self.shiftStart = 0 # in ticks + self.shiftEnd = 0 # in ticks + self._secondInit(parentItem = None) #see Item._secondInit + + def _secondInit(self, parentItem): + """see Score._secondInit""" + #discard parentItem + self.genericNumber = self.calcGenericNumber() + self.notehead = self.calcNotehead() #depends on self.genericNumber + #self.cachedCompleteDuration = None + + def __setattr__(self, name, value): + #print ("change!", self, name, value) + super().__setattr__(name, value) + super().__setattr__("cachedCompleteDuration", None) + + + @classmethod + def createByGuessing(cls, completeDuration): #class method. no self. + """Return a new Duration. A constructor class method. + Take one absolute tick value and guess what is the best + duration combination (base, tuplets, dots...) for it. + + createByGuessing exists to distinguish between dotted notes and fractions. + This means that the duration must be somehow musical precise and without fuzzyness. + You can't shove arbitrary live-recorded duration values in here. It is not a quantizer""" + + def _closest(num, datalist): + """only for positive numbers""" + if num in datalist: + return num + else: + positions = len(datalist) + tmplist = [0] + sorted(datalist) + tmplist.reverse() + #Loop over all positions except the last 0. + + for x in range(positions): + if tmplist[x+1] < num < tmplist[x]: + return tmplist[x] + else: #the highest value in datalist was smaller + return None + + durList = [D1024, D512, D256, D128, D64, D32, D16, D8, D4, D2, D1, DB, DL, DM] + guessedBase = _closest(completeDuration, durList) + + if guessedBase: + if completeDuration in durList: #no need for guessing + new = cls(completeDuration) + elif completeDuration/1.5 in durList: #single dot + new = cls(completeDuration/1.5) + new.dots = 1 + elif completeDuration/1.5/1.5 in durList: #double dots + new = cls(completeDuration/1.5/1.5) + new.dots = 2 + else: #tuplet. That means the value is below a standard "notehead" duration. We need to find how much much lower. + new = cls(guessedBase) + #ratio = completeDuration / guessedBase #0.666~ for triplet + newRatio = Fraction(completeDuration, guessedBase).limit_denominator(100000) #protects 6 or 7 decimal positions + new.tuplets = [(newRatio.numerator, newRatio.denominator)] + else: + #the base could not be guessed. In this case we just create a non-standard note. + warn("non-standard duration generated") + new = cls(int(completeDuration)) #210, minimum base duration value. + + return new + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self._baseDuration = int(serializedObject["baseDuration"]) + self.tuplets = serializedObject["tuplets"] #TODO: make sure the types are correct? + self.dots = int(serializedObject["dots"]) + self.durationKeyword = int(serializedObject["durationKeyword"]) + self.shiftStart = int(serializedObject["shiftStart"]) + self.shiftEnd = int(serializedObject["shiftEnd"]) + self._secondInit(parentItem = parentObject) + return self + + def serialize(self): + result = {} + result["class"] = "Duration" + result["baseDuration"] = self._baseDuration + result["tuplets"] = self.tuplets + result["dots"] = self.dots + result["shiftStart"] = self.shiftStart + result["shiftEnd"] = self.shiftEnd + result["durationKeyword"] = self.durationKeyword + return result + + @property + def baseDuration(self): + return self._baseDuration + + @baseDuration.setter + def baseDuration(self, value): + """implement limits""" + if value < D1024: + value = D1024 + elif value > DM: + value = DM + self._baseDuration = value + + def copy(self): + new = Duration(self.baseDuration) + new.tuplets = self.tuplets.copy() + new.dots = self.dots + new.genericNumber = new.calcGenericNumber() + new.notehead = new.calcNotehead() + new.durationKeyword = self.durationKeyword + new.shiftStart = self.shiftStart + new.shiftEnd = self.shiftEnd + return new + + def augment(self): + self.baseDuration *= 2 + self.genericNumber = self.calcGenericNumber() + self.notehead = self.calcNotehead() + + def diminish(self): + self.baseDuration /= 2 + self.genericNumber = self.calcGenericNumber() + self.notehead = self.calcNotehead() + + def calcGenericNumber(self): + """A number for humans and lilypond. 4 = quarter, 2 = half""" + return duration.baseDurationToTraditionalNumber[self.baseDuration] + + def calcNotehead(self): + """What classical notehead would be used + to express baseDuration""" + if self.genericNumber >= 4: + return 4 + else: + return self.genericNumber + + def completeDuration(self): + """Ticks with dots and tuplets. But not leftMod rightMod + x = basic note value , n = number of dots: 2x - x/2^n + + This function doesn't seem to be much. Why all the optimisation? + Because it is called very very often. many times or so for a single note. + """ + if not self.baseDuration: + return 0 + + if self.cachedCompleteDuration: + return self.cachedCompleteDuration + else: + value = 2 * self.baseDuration - self.baseDuration / 2**self.dots + for numerator, denominator in self.tuplets: + value = value * numerator / denominator + + if not value == int(value): + raise ValueError("Only integers are allowed as durations. {} is not {}.".format(value, int(value))) #TODO: leave this in until real world testing. We *could* live with floats for very complex tuplets, but let's see where this leads us. + + value = int(value) + super().__setattr__("cachedCompleteDuration", value) + return value + + def noteOnAndOff(self, trackState, completeDuration): + """For GUI and Midi + return a tick value, the offset from an imaginary + starting point on the tick/time axis, which needs to be + added later. Think t=0 during this function. + + We do not export the actual duration since this function + is intended for midi which only needs start and end points + and calculates the duration itself.""" + on = self.startModInTicks(trackState)(completeDuration) + off = completeDuration + self.endModInTicks(trackState)(completeDuration) + if on > off: + warn("Your calculation resulted in a note off before note on. Please change it manually. Forced to standard note on/off.\n{}\n{}".format(self.startModInTicks(trackState), self.endModInTicks(trackState))) + return 0, completeDuration + else: + return (on, off) + + def startModInTicks(self, trackState): + """Modifications have different priority. A user created mod + is always highest priority. + Contexts like slurs or other instructions are next. + Then follow individual duration keywords. There can only be one + keyword at a time.""" + if self.shiftStart: + return lambda x: self.shiftStart + elif trackState.duringLegatoSlur: + return trackState.track.durationSettingsSignature.legatoOn + elif self.durationKeyword == D_DEFAULT or self.durationKeyword == D_TIE: + return trackState.track.durationSettingsSignature.defaultOn + elif self.durationKeyword == D_STACCATO: + return trackState.track.durationSettingsSignature.staccatoOn + elif self.durationKeyword == D_TENUTO: + return trackState.track.durationSettingsSignature.tenutoOn + else: + raise ValueError("Duration Keyword {} unknown".format(self.durationKeyword)) + + def endModInTicks(self, trackState): + """see Duration.startMod""" + if self.shiftEnd: + return lambda x: self.shiftEnd + elif trackState.duringLegatoSlur: + if self.durationKeyword == D_STACCATO: #slur plus staccato cancels each other out + return trackState.track.durationSettingsSignature.defaultOff + else: + return trackState.track.durationSettingsSignature.legatoOff + elif self.durationKeyword == D_DEFAULT or self.durationKeyword == D_TIE: + return trackState.track.durationSettingsSignature.defaultOff + elif self.durationKeyword == D_STACCATO: + return trackState.track.durationSettingsSignature.staccatoOff + elif self.durationKeyword == D_TENUTO: + return trackState.track.durationSettingsSignature.tenutoOff + else: + raise ValueError("Duration Keyword {} unknown".format(self.durationKeyword)) + + def toggleDurationKeyword(self, keywordConstant): + """Activate a keyword for a note. If the note already has one, + overwrite it. Except it already has the same keyword, then + remove it""" + if self.durationKeyword == keywordConstant: + self.durationKeyword = D_DEFAULT + else: + self.durationKeyword = keywordConstant + + def toggleDot(self): + if self.dots == 1: + self.dots = 2 + elif self.dots == 0: + self.dots = 1 + else: + self.dots = 0 + + def toggleTriplet(self): + if self.tuplets == [(2,3)]: + self.tuplets = [] + else: + self.tuplets = [(2,3)] + + def lilypond(self): + """Called by note.lilypond(), See Item.lilypond for the general docstring. + returns a number as string.""" + n = self.genericNumber + if n == 0: + return "\\breve" + elif n == -1: + return "\\longa" + elif n == -2: + return "\\maxima" + else: + return str(n) + self.dots*"." + +class DurationGroup(object): + """Holds several durations and returns values meant for chords. + Always up to date since notelist is a mutable data type. + + Is compatible to Duration() methods and parameters. + + For the representation and calculation always the minimum + note duration counts for the whole chord.""" + def __init__(self, chord): + self.chord = chord + self.group = True + self.minimumNote = None + self.cacheMinimumNote() #the shortest note. set inplace. + + def cacheMinimumNote(self): + work = [] + for note in self.chord.notelist: + work.append((note.duration.completeDuration(), note)) + self.minimumNote = min(work)[1] #a list of tuplets (duration, note). The minimum is the one with the lowest duration, [1] is the note + + def templateDuration(self): + """for chord addNote we need some template""" + return self.minimumNote.duration.copy() + + def completeDuration(self): + """Complete Musical Duration of this item.""" + return self.minimumNote.duration.completeDuration() + + def hasTuplet(self): + """Return true if there is any tuplet in any note""" + return any(note.duration.tuplets for note in self.chord.notelist) + + @property + def baseDuration(self): + return self.minimumNote.duration.baseDuration + + @property + def genericNumber(self): + return duration.baseDurationToTraditionalNumber[self.baseDuration] + + +############################################## +## Items ## +############################################## + + +def createChordOrRest(completeDuration, pitchlist, velocityModification): + """Return a Chord or Rest instance. + The complete duration is the absolute duration after + dots, tuplets etc. e.g. generated by midi in. + Pitchlist can also be empty then it generates rests. But you + have to explicitely set it to empty. + + This is used by the pattern generator which supports both + rests and chords and works by absolute durations. + """ + + durationObject = Duration.createByGuessing(completeDuration) + dynamic = Dynamic() + dynamic.velocityModification = velocityModification + if pitchlist: #chord + new = Chord(firstDuration=durationObject, firstPitch=pitchlist[0]) + for pitch in pitchlist[1:]: + new.addNote(pitch) + for note in new.notelist: + note.dynamic = dynamic.copy() + else: + new = Rest(durationObject) + + return new + +class Item(object): + + pseudoDuration = Duration(0) #any item has a duration. But we don't need a new pseudo duration instance for every clef and keysig. + + def __init__(self): + self.duration = self.pseudoDuration + self.notelist = [] + self.parentBlocks = WeakSet() #this is filled and manipulated by the Block Class through copy, split, contentLink etc. this takes also care of Item.copy(). Don't look in this file for anything parentBlocks related. + #self._secondInit(parentBlock = None) #Items don't know their parent object. They are in a mutable list which can be in several containers. + self.lilypondParameters = { # Only use basic data types! Not all lilypond parameters are used by every item. For clarity and editing we keep them all in one place. + "visible" : True, + "override" : "", + "explicit" : False, + } + + + def _secondInit(self, parentBlock): + """see Score._secondInit""" + + def deserializeDurationAndNotelistInPlace(self, serializedObject): + """Part of instanceFromSerializedData. + Any Item has a notelist and a duration, even if they are + empty or never read. + + Needs a self, so + the instance needs to be created. Call after + self = cls.__new__(cls)""" + self.parentBlocks = WeakSet() #inserted by the parent load method + self.duration = Duration.instanceFromSerializedData(serializedObject["duration"], parentObject = self) #needs to be implemented in every childclass because we do not call Item.instanceFromSerializedData + self.notelist = [Note.instanceFromSerializedData(note, parentObject = self) for note in serializedObject["notelist"]] + self.lilypondParameters = serializedObject["lilypondParameters"] + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData. + This does not get called by a child class so you need to + reimplement self.duration and other common parameters in + every child class!""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentTrack = parentObject) + return self + + def serialize(self): + """Return a serialized data from this instance. Used for save, load + and undo/redo. + Can be called in a chain by subclasses with super().serialize + + The main difference between serialize and exportObject is that + serialize does not compute anything. I just saves the state + without calulating note on and off or stem directions, + for example. + """ + #result = super().serialize() #call this in child classes + result = {} + result["class"] = self.__class__.__name__ + result["duration"] = self.duration.serialize() + result["notelist"] = [note.serialize() for note in self.notelist] + result["lilypondParameters"] = self.lilypondParameters + return result + + def _exportObject(self, trackState): + """Implement this in every child class, return a dict. + + Base class function to return a dict which is a good layout + export basis. For example for GUI frontends. They don't have to + parse and calculate their own values in slow pure Python then + + midiBytes is a list with pblob/binary data generated by + cbox.Pattern.serialize_event(position, midibyte1 (noteon), midibyte2(pitch), midibyte3(velocity)) + Items with duration, like chords, will most like need to create + at least two pblobs, one for the start (e.g. note on) and one + for the stop (e.g. note off) + """ + raise NotImplementedError("Implement _exportObject() for this item type!") + + #And for documentation and education here a template exportObject + duration = 0 + return { + "type" : "", + "completeDuration" : duration, + "tickindex" : trackState.tickindex - duration, #we parse the tickindex after we stepped over the item. + "midiBytes" : [], + "UIstring" : "", #this is for a UI, possibly a text UI, maybe for simple items of a GUI. Make it as short and unambigious as possible. + } + + def exportObject(self, trackState): + exportDict = { + "id" : id(self), + "lilypondParameters" : self.lilypondParameters, + } + + exportDict.update(self._exportObject(trackState)) + return exportDict + + + @property + def parentTracks(self): + return [block.parentTrack for block in self.parentBlocks] + + def _copy(self): + """return an independent copy of self""" + raise NotImplementedError("Implement _copy() for this item type!") + + def copy(self): + new = self._copy() + new.lilypondParameters = self.lilypondParameters.copy() + return new + + def copyParentBlocks(self, oldItem): + """Move the oldItems parentBlocks to the new item""" + self.parentBlocks = oldItem.parentBlocks + + def logicalDuration(self): + return 0 + + def deserializeInplace(self, serializedObject): + """Change this instance values to the values in the + serialized object. Part of the undo/redo system""" + return + + #Empty methods that allow for apply to selection and other iterators to work with items that cannot respond to a command. e.g. stepUp on a rest. + #Api functions must react to these function returning None. For example Undo will not register anything when no undo-function is returned by an item-method. + #We don't use functions(self, *args) and then a bunch of function1 = function2 = function3 because this way it is easier to see what methods are available (and what arguments they need) when creating new classes from Item. + + def sharpenNoteNearPitch(self, pitch): pass + def flattenNoteNearPitch(self, pitch): pass + def stepUpNoteNearPitch(self, pitch, keysig): pass + def stepDownNoteNearPitch(self, pitch, keysig): pass + def stepUpOctaveNoteNearPitch(self, pitch): pass + def stepDownOctaveNoteNearPitch(self, pitch): pass + def augmentNoteNearPitch(self, pitch): pass + def diminishNoteNearPitch(self, pitch): pass + def toggleDotNearPitch(self, pitch): pass + def toggleTripletNearPitch(self, pitch): pass + def setTupletNearPitch(self, pitch, tupletListForDuration): pass + def toggleDurationKeywordNearPitch(self, pitch, keywordConstant): pass + def moreVelocityNearPitch(self, pitch): pass + def lessVelocityNearPitch(self, pitch): pass + def moreDurationNearPitch(self, pitch): pass + def lessDurationNearPitch(self, pitch): pass + def resetVelocityAndDurationModsNearPitch(self, pitch): pass + + def sharpen(self): pass + def flatten(self): pass + def augment(self): pass + def diminish(self): pass + def toggleDot(self): pass + def toggleTriplet(self): pass + def setTuplet(self, durationTupletListForEachNote): pass + def toggleDurationKeyword(self, listOfKeywordConstants): pass + def stepUp(self, keysigList): pass + def stepDown(self, keysigList): pass + def stepUpOctave(self): pass + def stepDownOctave(self): pass + def intervalAutomatic(self, rootPitch, targetPitch): pass + def split(self, newparts): pass + def addNote(self, pitch): pass + def deleteNote(self, note): pass + def removeNoteNearPitch(self, pitch): pass + def moreVelocity(self): pass + def lessVelocity(self): pass + def moreDuration(self): pass + def lessDuration(self): pass + def resetVelocityAndDurationMods(self): pass + + def toggleBeam(self): pass + def removeBeam(self): pass + + def midiRelativeChannelPlus(self): pass + def midiRelativeChannelMinus(self): pass + def midiRelativeChannelReset(self): pass + + def mirrorAroundCursor(self, cursorPitch): pass + + def lilypond(self): + if self.lilypondParameters["override"]: + return self.lilypondParameters["override"] + else: + return self._lilypond() + + def _lilypond(self): + """called by block.lilypond(), returns a string. + Don't create white-spaces yourself, this is done by the structures. + When in doubt prefer functionality and robustness over 'beautiful' lilypond syntax.""" + return "" + +class TemplateItem(Item): + """Use this with copy and paste to create a new item class""" + + def __init__(self, itemData): + """Either init gets called, by creation during runtime, or instanceFromSerializedData. + That means everything in init must be matched by a loading call in instanceFromSerializedData.""" + super().__init__() + raise NotImplementedError("Implement __init__() for this item type!") + self.itemData = itemData #matches instanceFromSerializedData and serialize + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """After creating a new item during runtime or after loading from a file this gets called. + Put every calcuation that depends on values that could be changed by the user. + see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + raise NotImplementedError("Implement instanceFromSerializedData() for this item type!") + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.itemData = serializedObject["itemData"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + raise NotImplementedError("Implement serialize() for this item type!") + result = super().serialize() #call this in child classes + result["itemData"] = self.itemData + return result + + def _copy(self): + """return an independent copy of self""" + raise NotImplementedError("Implement _copy() for this item type!") + new = TemplateItem(self.itemData) + return new + + + def _exportObject(self, trackState): + """Implement this in every child class, return a dict. + + Base class function to return a dict which is a good layout + export basis. For example for GUI frontends. They don't have to + parse and calculate their own values in slow pure Python then + + midiBytes is a list with pblob/binary data generated by + cbox.Pattern.serialize_event(position, midibyte1 (noteon), midibyte2(pitch), midibyte3(velocity)) + Items with duration, like chords, will most like need to create + at least two pblobs, one for the start (e.g. note on) and one + for the stop (e.g. note off) + """ + raise NotImplementedError("Implement _exportObject() for this item type!") + + #And for documentation and education here a template exportObject + duration = 0 + return { + "type" : "", + "completeDuration" : duration, + "tickindex" : trackState.tickindex - duration, #we parse the tickindex after we stepped over the item. + "midiBytes" : [], + "UIstring" : "", #this is for a UI, possibly a text UI, maybe for simple items of a GUI. Make it as short and unambigious as possible. + } + + def _lilypond(self): + """called by block.lilypond(), returns a string. + Don't create white-spaces yourself, this is done by the structures. + When in doubt prefer functionality and robustness over 'beautiful' lilypond syntax.""" + return "" + +class Chord(Item): + """Duration and firstPitch are for the first note. + You must only modify the notelist through Chord methods. The chord methods keep + the list sorted and also keep track what is the shortest and longest note, and other meta-data. + Replacing .notelist or using list methods like .append directly will break the whole program. + Especially the lowest and shortest notes are used multiple times on every item export! + """ + + def __init__(self, firstDuration, firstPitch): + super().__init__() + firstNote = Note(self, firstDuration, firstPitch) + self.notelist = [firstNote] + self._beamGroup = False # Works a bit like legato slurs, only this is a property of a note, not an item. self.beamGroup is a @property that self-corrects against errors. + self._secondInit(parentBlock = None) #see Item._secondInit. + self.midiChannelOffset = 0 #from -15 to 15. In reality much less. Expected values are -3 to +3 + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + self.durationGroup = DurationGroup(self) #durationGroup is a dynamic data type and therefore does not need serialize. The serialized durations are in the notelist. + self._cachedClefForLedgerLines = None + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._beamGroup = bool(serializedObject["beamGroup"]) + self.midiChannelOffset = serializedObject["midiChannelOffset"] + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["beamGroup"] = self._beamGroup + result["midiChannelOffset"] = self.midiChannelOffset + #durationGroup is a dynamic data type and gets its values from its parent chord: self. + return result + + def logicalDuration(self): + """Return the logical duration that is used to calculate + the space and subsequent position of items.""" + #TODO: this gets called pretty often. 6 times per note insert on a previously empty track. Why?! + return self.durationGroup.completeDuration() + + def _copy(self): + new = Chord(Duration(0), 0) + + new.copyParentBlocks(self) + new._beamGroup = self._beamGroup + new.notelist = [] + for note in self.notelist: + new.notelist.append(note.copy(new)) + new.durationGroup.cacheMinimumNote() + return new + + def pitchlist(self): + return [note.pitch for note in self.notelist] #needs to be subscriptable + + def whitePitchlist(self): + result = [] + for note in self.notelist: + result.append(pitchmath.toWhite[note.pitch]) + return result + + def _setNotelist(self, notelist): + oldNotelist = self.notelist.copy() + self.notelist = notelist + self.durationGroup.cacheMinimumNote() + return lambda: self._setNotelist(oldNotelist) + + def addNote(self, pitch): + """The notelist gets sorted after insert. + Each white note is only allowed once in each chord. + That means gis and ges are not allowed in the same chord. + And not two times the same note. + + We use the template duration from the group. That means the new + note has the same main-properties as the existing notes. + """ + note = Note(self, self.durationGroup.templateDuration(), pitch) + if pitchmath.toWhite[pitch] in self.whitePitchlist(): + return False #only one of each base note in a chord. no cis, ces and c in the same chord. + else: + oldNotelist = self.notelist.copy() #only copies the order, not the items itself. Which is what we need. + self.notelist.append(note) + self.notelist.sort() + self.durationGroup.cacheMinimumNote() + return lambda: self._setNotelist(oldNotelist) + + def deleteNote(self, note): + """Delete the exact note, an instance. + No search for the pitch or crap like "highest first". + Notelist remains sorted after delete.""" + if len(self.notelist) > 1: + oldNotelist = self.notelist.copy() + self.notelist.remove(note) + self.durationGroup.cacheMinimumNote() + #No need for sorting. + return lambda: self._setNotelist(oldNotelist) + + def removeNoteNearPitch(self, pitch): + note = self.getNearestNote(pitch) + return self.deleteNote(note) + + def getNearestNote(self, pitch): + """Return the note which is nearest. + The behaviour if two notes of the same pitch are in this chord + is undefined. Whatever cython/python finds first will get + returned. It really shouldn't matter.""" + listOfTuples = [] + for note in self.notelist: + listOfTuples.append((abs(pitch - note.pitch), note)) + note = min(listOfTuples)[1] #[1] of the tuple (pitch,noteinstance) + return note + + #def Note getHighestNote(self): + #def Note getLowestNotes(self): + + + #Direct functions. Do not need a context, don't need a state. + #Meant for undo. + + def _setNotePitch(self, note, targetPitch): + """A direct setter for an exact note, + not just near a pitch. + Mostly for undo""" + oldValueForUndo = note.pitch + note.pitch = targetPitch + self._cachedClefForLedgerLines = None + return lambda: self._setNotePitch(note, oldValueForUndo) + + def _setNoteDuration(self, note, durationInstance): + """see setNotePitch.""" + assert not note.duration is durationInstance + oldValueForUndo = note.duration.copy() + note.duration = durationInstance + self.durationGroup.cacheMinimumNote() + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def _setNoteDynamic(self, note, dynamicInstance): + """see _setNoteDuration.""" + assert not note.dynamic is dynamicInstance + oldValueForUndo = note.dynamic.copy() + note.dynamic = dynamicInstance + return lambda: self._setNoteDynamic(note, oldValueForUndo) + + def _setNoteDynamicAndDuration(self, note, durationInstance, dynamicInstance): + assert not note.duration is durationInstance + oldDurationValueForUndo = note.duration.copy() + note.duration = durationInstance + self._cachedClefForLedgerLines = None + + assert not note.dynamic is dynamicInstance + oldDynamicValueForUndo = note.dynamic.copy() + note.dynamic = dynamicInstance + + return lambda: self._setNoteDynamicAndDuration(note, oldDurationValueForUndo, oldDynamicValueForUndo) + + + #Nearest Note: + #Pitch modifications + def sharpenNoteNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.pitch + self.notelist.sort() + note.sharpen() + return lambda: self._setNotePitch(note, oldValueForUndo) + + def flattenNoteNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.pitch + self.notelist.sort() + note.flatten() + return lambda: self._setNotePitch(note, oldValueForUndo) + + def stepUpNoteNearPitch(self, pitch, keysig): + note = self.getNearestNote(pitch) + oldValueForUndo = note.pitch + note.stepUpInScale(keysig) + self.notelist.sort() + self._cachedClefForLedgerLines = None + return lambda: self._setNotePitch(note, oldValueForUndo) + + def stepDownNoteNearPitch(self, pitch, keysig): + note = self.getNearestNote(pitch) + oldValueForUndo = note.pitch + note.stepDownInScale(keysig) + self.notelist.sort() + self._cachedClefForLedgerLines = None + return lambda: self._setNotePitch(note, oldValueForUndo) + + def stepUpOctaveNoteNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.pitch + note.octaveUp() + self.notelist.sort() + self._cachedClefForLedgerLines = None + return lambda: self._setNotePitch(note, oldValueForUndo) + + def stepDownOctaveNoteNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.pitch + note.octaveDown() + self._cachedClefForLedgerLines = None + return lambda: self._setNotePitch(note, oldValueForUndo) + + #Duration modifications + def augmentNoteNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.duration.copy() + note.duration.augment() + self.durationGroup.cacheMinimumNote() + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def diminishNoteNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.duration.copy() + note.duration.diminish() + self.durationGroup.cacheMinimumNote() + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def toggleDotNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.duration.copy() + note.duration.toggleDot() + self.durationGroup.cacheMinimumNote() + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def toggleTripletNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.duration.copy() + note.duration.toggleTriplet() + self.durationGroup.cacheMinimumNote() + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def setTupletNearPitch(self, pitch, tupletListForDuration): + note = self.getNearestNote(pitch) + oldValueForUndo = note.duration.copy() + note.duration.tuplets = tupletListForDuration + self.durationGroup.cacheMinimumNote() + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def toggleDurationKeywordNearPitch(self, pitch, keywordConstant): + note = self.getNearestNote(pitch) + oldValueForUndo = note.duration.copy() + note.duration.toggleDurationKeyword(keywordConstant) + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def moreDurationNearPitch(self, pitch): + """If you change the function don't forget the chord version""" + note = self.getNearestNote(pitch) + oldValueForUndo = note.duration.copy() + note.duration.shiftEnd += D64 + if not note.duration.shiftEnd: #to avoid weird behaviour where you add duration and the note off actually jumps back because shiftEnd got 0 and the default note off kicked in (which is less than 0). You can only reset to truly "0" by using the reset command. + note.duration.shiftEnd += D64 + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def lessDurationNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.duration.copy() + + if not note.duration.shiftEnd: #only happens when never touched by human hands. prevents a jump in the wrong direction because the user expects a change from the current value, not from 0. + note.duration.shiftEnd = note._cachedExportObject["rightModInTicks"] + + note.duration.shiftEnd -= D64 + if not note.duration.shiftEnd: #see moreDurationNearPitch. never return to 0 to let the default keyword kick in again. + note.duration.shiftEnd -= D64 + return lambda: self._setNoteDuration(note, oldValueForUndo) + + def moreVelocityNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.dynamic.copy() + note.dynamic.velocityModification += 1 + return lambda: self._setNoteDynamic(note, oldValueForUndo) + + def lessVelocityNearPitch(self, pitch): + note = self.getNearestNote(pitch) + oldValueForUndo = note.dynamic.copy() + note.dynamic.velocityModification -= 1 + return lambda: self._setNoteDynamic(note, oldValueForUndo) + + def resetVelocityAndDurationModsNearPitch(self, pitch): + note = self.getNearestNote(pitch) + if note.dynamic.velocityModification == 0 and note.duration.shiftStart == 0 and note.duration.shiftEnd == 0: + return None + oldDurationValueForUndo = note.duration.copy() + oldDynamicValueForUndo = note.dynamic.copy() + note.dynamic.velocityModification = 0 + note.duration.shiftStart = 0 + note.duration.shiftEnd = 0 + return lambda: self._setNoteDynamicAndDuration(note, oldDurationValueForUndo, oldDynamicValueForUndo) + + #Whole Chord/All Notes. Typically used with selections + #REMEMBER that function-parameters are lists because it is possible + #to give one parameter for each note in the chord. + + def _createParameterGenerator(self, notelist, parameterForEachNote): + """Check and choose if there is a correct parameter list with + enough values for each note in the notelist or choose the only + given parameter for each note. + + Most of the time we want all parameters set to the same value + so we receive only one argument in the listForEachNote. + However, Undo from the api really sends us the original values, + which could be a different one for each note. + + So we expect a list with len()==1 or equal length to notelist. + + If we only have one note it does not matter at all.""" + + if len(parameterForEachNote) == 1: + gen = EndlessGenerator(parameterForEachNote[0]) + else: + assert len(self.notelist) == len(parameterForEachNote) + gen = (param for param in parameterForEachNote) + return gen + + def _setDurationlist(self, durationlist): + """see _setPitchlist. Only for durations. + The durations are standalone versions, most likely created + through duration.copy() (in case of undo). + + Since this is never called twice (score.selectedItems() filters + out content-links) on content-linked data no links + get broken.""" + assert len(self.notelist) == len(durationlist) + oldValues = [] + for note, newDuration in zip(self.notelist, durationlist): + oldValues.append(note.duration.copy()) #no content-links get broken this way because score.selectedItems() only gets one instance of every item, no matter how many links exist. + note.duration = newDuration + self.durationGroup.cacheMinimumNote() + return lambda: self._setDurationlist(oldValues) + + def _setDynamiclist(self, dynamiclist): + """see _setDurationslist. Only for dynamics.""" + assert len(self.notelist) == len(dynamiclist) + oldValues = [] + for note, newDynamic in zip(self.notelist, dynamiclist): + oldValues.append(note.dynamic.copy()) #no content-links get broken this way because score.selectedItems() only gets one instance of every item, no matter how many links exist. + note.dynamic = newDynamic + return lambda: self._setDynamiclist(oldValues) + + def _setDynamicAndDuration(self, omnilist): + """omnilist is a list of tuples (duration, dynamic) + Function written for clearVelocityAndDurationMods""" + assert len(self.notelist) == len(omnilist) + oldValues = [] + for note, (newDuration, newDynamic) in zip(self.notelist, omnilist): + oldValues.append((note.duration.copy(), note.dynamic.copy())) #no content-links get broken this way because score.selectedItems() only gets one instance of every item, no matter how many links exist. + note.dynamic = newDynamic + note.duration = newDuration + return lambda: self._setDynamicAndDuration(oldValues) + + def _setPitchlist(self, pitchlist): + """This is for undo. We rely on the fact that undo is linear + and the pitches we set match exactly the order of notes we + already have. + We don't need tests for valid values or a matching number of + notes""" + assert len(self.notelist) == len(pitchlist) + oldValues = [] + for note, newPitch in zip(self.notelist, pitchlist): + oldValues.append(note.pitch) + note.pitch = newPitch + self._cachedClefForLedgerLines = None + return lambda: self._setPitchlist(oldValues) + + def sharpen(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.pitch) + note.sharpen() + return lambda: self._setPitchlist(oldValues) + + def flatten(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.pitch) + note.flatten() + return lambda: self._setPitchlist(oldValues) + + def split(self, newparts, _existingCopies = []): + """ + This is only for chords. + Technically this works with rests as well. + However, there is little musical meaning in splitted rests. + And it does not make sense for further editing. + + Undo works by remembering which original note spawned which + child notes. + + There is an optional parameter _existingCopies. This is used + by the internal undo/redo system. The api does not need to call + it. It will be used instead of making new copies. + Reason: + If you split a note and split one of the newly spawned notes + again it works fine. Two times Undo will delete those notes and + keep only the original note with its original duration. + If you now do redo with a normal split it will work the first + time and split the original note again. But the resulting notes + are NOT the ones from the first round. So we can't find use + them in our undo philosophy, which works with specific instances. + + In other words: only redo needs _existingCopies. + """ + + assert newparts >= 2 + + #First change the current duration in place so we only have to make copies later. + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #we don't actually need a copy since we create a new one. But better safe than sorry. This matches also the behaviour of the other duration change functions. + newTicks = note.duration.completeDuration() / newparts + note.duration = Duration.createByGuessing(newTicks) + + #Now we have one note with the duration the user wants to have. Make n-1 copies- + spawnedNotes = [] + for block in self.parentBlocks: #weakrefs are not iterators and not iterable. So next() does not work and [x] does not work. for loop has to do. + currentIndexInBlock = block.data.index(self) + for i in range(newparts-1): + if _existingCopies: #this is redo. + c = _existingCopies[i] + else: + c = self.copy() + + spawnedNotes.append(c) + block.data.insert(currentIndexInBlock+1, c) #add each new item after the original one. + break #we only need one block since the data is the same in all blocks. + + def _undoSplit(): + #Reverse order. First remove the spawned notes + for spawn in spawnedNotes: + block.data.remove(spawn) + + #Then restore the original note durations + self._setDurationlist(oldValues) + + return lambda: self.split(newparts, _existingCopies = spawnedNotes) + + self.durationGroup.cacheMinimumNote() + return _undoSplit + + def augment(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + note.duration.augment() + self.durationGroup.cacheMinimumNote() + return lambda: self._setDurationlist(oldValues) + + def diminish(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + note.duration.diminish() + self.durationGroup.cacheMinimumNote() + return lambda: self._setDurationlist(oldValues) + + def _setRelativeMidiChannel(self, value): + oldValue = self.midiChannelOffset + self.midiChannelOffset = value + return lambda: self._setRelativeMidiChannel(oldValue) + + def midiRelativeChannelPlus(self): + return self._setRelativeMidiChannel(self.midiChannelOffset+1) + + def midiRelativeChannelMinus(self): + return self._setRelativeMidiChannel(self.midiChannelOffset-1) + + def midiRelativeChannelReset(self): + return self._setRelativeMidiChannel(0) + + def toggleDot(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + note.duration.toggleDot() + self.durationGroup.cacheMinimumNote() + return lambda: self._setDurationlist(oldValues) + + def toggleTriplet(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + note.duration.toggleTriplet() + self.durationGroup.cacheMinimumNote() + return lambda: self._setDurationlist(oldValues) + + def setTuplet(self, durationTupletListForEachNote): + """ + parameter format: + [ + [(2,3)], #note 1 + [(4,5), (2,3)], #note 2 + [(3,4)], #note 3 + ] + """ + gen = self._createParameterGenerator(self.notelist, durationTupletListForEachNote) + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + note.duration.tuplets = next(gen) + self.durationGroup.cacheMinimumNote() + return lambda: self._setDurationlist(oldValues) + + def toggleDurationKeyword(self, listOfKeywordConstants): + gen = self._createParameterGenerator(self.notelist, listOfKeywordConstants) + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + note.duration.toggleDurationKeyword(next(gen)) + return lambda: self._setDurationlist(oldValues) + + def stepUp(self, keysigList): + """We get a list as parameter but we already know it is not + possible to get more than one keysig for a chord. We play along + for compatibility""" + gen = self._createParameterGenerator(self.notelist, keysigList) + oldValues = [] + for note in self.notelist: + oldValues.append(note.pitch) + note.stepUpInScale(next(gen)) + self._cachedClefForLedgerLines = None + return lambda: self._setPitchlist(oldValues) + + def stepDown(self, keysigList): + gen = self._createParameterGenerator(self.notelist, keysigList) + oldValues = [] + for note in self.notelist: + oldValues.append(note.pitch) + note.stepDownInScale(next(gen)) + self._cachedClefForLedgerLines = None + return lambda: self._setPitchlist(oldValues) + + def stepUpOctave(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.pitch) + note.octaveUp() + self._cachedClefForLedgerLines = None + return lambda: self._setPitchlist(oldValues) + + def stepDownOctave(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.pitch) + note.octaveDown() + self._cachedClefForLedgerLines = None + return lambda: self._setPitchlist(oldValues) + + def intervalAutomatic(self, rootPitch, targetPitch): + oldValues = [] + for note in self.notelist: + oldValues.append(note.pitch) + note.intervalAutomatic(rootPitch, targetPitch) #TODO: possible optimisation is to calculate the interval once instead of every time. + self._cachedClefForLedgerLines = None + return lambda: self._setPitchlist(oldValues) + + def mirrorAroundCursor(self, cursorPitch): + oldValues = [] + for note in self.notelist: + oldValues.append(note.pitch) + note.mirrorAroundCursor(cursorPitch) + self.notelist.sort() + self._cachedClefForLedgerLines = None + return lambda: self._setPitchlist(oldValues) + + def moreDuration(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + note.duration.shiftEnd += D64 + if not note.duration.shiftEnd: #see moreDurationNearPitch + note.duration.shiftEnd += D64 + return lambda: self._setDurationlist(oldValues) + + def lessDuration(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.duration.copy()) #see _setDurationlist + if not note.duration.shiftEnd: #only happens when never touched by human hands. prevents a jump in the wrong direction because the user expects a change from the current value, not from 0. + note.duration.shiftEnd = note._cachedExportObject["rightModInTicks"] + note.duration.shiftEnd -= D64 + if not note.duration.shiftEnd: #see moreDurationNearPitch + note.duration.shiftEnd -= D64 + return lambda: self._setDurationlist(oldValues) + + def moreVelocity(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.dynamic.copy()) + note.dynamic.velocityModification += 1 + return lambda: self._setDynamiclist(oldValues) + + def lessVelocity(self): + oldValues = [] + for note in self.notelist: + oldValues.append(note.dynamic.copy()) + note.dynamic.velocityModification -= 1 + return lambda: self._setDynamiclist(oldValues) + + def resetVelocityAndDurationMods(self): + oldValues = [] + unmodified = [] + for note in self.notelist: + oldValues.append((note.duration.copy(), note.dynamic.copy())) #no content-links get broken this way because score.selectedItems() only gets one instance of every item, no matter how many links exist. + unmodified.append(note.dynamic.velocityModification == 0 and note.duration.shiftStart == 0 and note.duration.shiftEnd == 0) + note.dynamic.velocityModification = 0 + note.duration.shiftStart = 0 + note.duration.shiftEnd = 0 + if all(unmodified): + return None + else: + return lambda: self._setDynamicAndDuration(oldValues) + + @property + def beamGroup(self): + """toggleBeam only works on D8 or smaller. But a D8 can get augmented and then still + have the beam flag. So every time the beamStatus gets accessed we take this as a chance + to test if this Chord still has the rights for a beam instruction. This happens at least + every Gui or Midi static export. So very very often and always when it matters. + TODO: test performance and maybe put this test in the duration itself""" + if self.durationGroup.baseDuration > D8: + self._beamGroup = False + return self._beamGroup + + def _setBeam(self, beamBool): + """for undo""" + oldValue = self._beamGroup #it is not guaranteed that this is the opposite of beamBool. It doesn't need do be. + self._beamGroup = beamBool + return lambda: self._setBeam(oldValue) + + def toggleBeam(self): + if self.durationGroup.baseDuration > D8: + assert self._beamGroup == False + return None + else: + undoFunction = self._setBeam(not self._beamGroup) + return undoFunction + + def removeBeam(self): + return self._setBeam(False) #return undo function + + #Export functions + + def calcFlag(self): + """What classical flag would be used + to express baseDuration""" + if self.durationGroup.genericNumber <= 4: #no flag. Quarter, Half or bigger duration. + return 0 + else: + return self.durationGroup.genericNumber + + def calculateLedgerLinesForLayoutExport(self, clef): + if self._cachedClefForLedgerLines and clef == self._cachedClefForLedgerLines: + return self._cachedLedgerLines + else: + self._cachedClefForLedgerLines = clef + lowestNote = self.notelist[0] + highestNote = self.notelist[-1] + + below = lowestNote.asDotOnLine(clef) + above = highestNote.asDotOnLine(clef) + + if below >= 6: + below = int(below/2) - 2 + else: + below = 0 + if above <= -6: + above = int(abs(above)/2) - 2 + else: + above = 0 + + self._cachedLedgerLines = (below, above) + return (below, above) + + def _exportObject(self, trackState): + clef = trackState.clef() + dotOnLineList = [] + for note in self.notelist: + dotOnLineList.append(note.asDotOnLine(clef)) + + highestPitchAsDotOnLine = min(dotOnLineList) #it is min because the higher pitch go in the minus direction. Qt Convention. Think Rows/Columns of a table/pixels on screen + lowestPitchAsDotOnLine = max(dotOnLineList) #it is max because the higher pitch go in the minus direction. Qt Convention. Think Rows/Columns of a table/pixels on screen + + baseDur = self.durationGroup.baseDuration #duration is a DurationGroup so we get the minimmal note value from the notelist + dur = self.logicalDuration() #duration is a DurationGroup so we get the minimmal note value from the notelist + + #Stems. in staffline coordinates (dots on lines): [starting point, length, 1|-1] 1 stem is on the right or -1 left side of the note. + if baseDur < D1: + if trackState.track.double and len(self.notelist) == 1 and 7 <= highestPitchAsDotOnLine <= 11 : #The break is between the h and c' (treble-clef) + forceDownStem = True + else: + forceDownStem = False + + x = abs(highestPitchAsDotOnLine - lowestPitchAsDotOnLine) #difference between the two numbers + if (not forceDownStem) and sum(dotOnLineList) >= 0: #stem goes up. + stem = (lowestPitchAsDotOnLine - 1, -1 * (x+5), 1) #-1 excludes the note height/gap itself + else: #stem goes down + stem = (highestPitchAsDotOnLine + 1, x+5, -1) #+1 excludes the note height/gap itself + else: + stem = tuple() + + flagResult = self.calcFlag() + if flagResult: + assert stem + flag = flagResult * stem[2] #1 or -1 for up or down. + else: + flag = 0 + + #Calfbox + midiBytesList = [] + exportNoteList = [] + logicalStartingTick = trackState.tickindex - dur #minus duration because we are RIGHT of an item after parsing it in structures.staticRepresentation + for note in self.notelist: + velocity = note.dynamic.velocity(trackState) + midipitch = pitchmath.toMidi[note.pitch] + onOffset, offOffset = note.duration.noteOnAndOff(trackState, dur) + + if note.pitch in trackState.EXPORTtiedNoteExportObjectsWaitingForClosing: #this is the last or the middle in a tied note sequence (but not the first). + exportNoteList.append(note.exportObject(trackState)) + if not note.pitch in trackState.EXPORTtiedNoteExportObjectsWaitingForClosing: #AGAIN! if this changed after exportObject it means this was the last note in a tied sequence + #Export the missing note off (see below in this loop) + midiBytesList.append(cbox.Pattern.serialize_event(logicalStartingTick + offOffset - 1, 0x80+pitchmath.midiChannelLimiter(trackState.midiChannel()+self.midiChannelOffset), pitchmath.midiPitchLimiter(midipitch, trackState.midiTranspose), velocity)) #-1 to create a small logical gap. This is nothing compared to our tick value dimensions, but it is enough for the midi protocol to treat two notes as separate ones. Imporant to say that this does NOT affect the next note on. This will be mathematically correct anyway. + continue + + else: #this is a real note with its own note-on. Set it. + midiBytesList.append(cbox.Pattern.serialize_event(logicalStartingTick + onOffset, 0x90+pitchmath.midiChannelLimiter(trackState.midiChannel()+self.midiChannelOffset), pitchmath.midiPitchLimiter(midipitch, trackState.midiTranspose), velocity)) + if not note.duration.durationKeyword == D_TIE: #First tied note in a row: no note off. these are set by the last in a sequence tied note (see above) + midiBytesList.append(cbox.Pattern.serialize_event(logicalStartingTick + offOffset - 1, 0x80+pitchmath.midiChannelLimiter(trackState.midiChannel()+self.midiChannelOffset), pitchmath.midiPitchLimiter(midipitch, trackState.midiTranspose), velocity)) #-1 to create a small logical gap. This is nothing compared to our tick value dimensions, but it is enough for the midi protocol to treat two notes as separate ones. Imporant to say that this does NOT affect the next note on. This will be mathematically correct anyway. + #Export Dict needs to be the last step because ties depend on the first/notFirst flags not set. + exportNoteList.append(note.exportObject(trackState)) + + #Ledger Lines + ledgerLines = self.calculateLedgerLinesForLayoutExport(clef) + if trackState.track.double and not 6 in dotOnLineList and ledgerLines[0] <= 6 : #The "middle" Ledger line in a double stuff is not needed if there is no note on it. + ledgerLines = (ledgerLines[0] -6, ledgerLines[1]) + + + assert dur == int(dur) + assert trackState.tickindex == int(trackState.tickindex) + return { + "type" : "Chord", + "notelist" : exportNoteList, #a list of dicts with notehead paramters like accidentals, noteheads and dots on lines. + "dotOnLineList" : dotOnLineList, + "highestPitchAsDotOnLine" : highestPitchAsDotOnLine, + "lowestPitchAsDotOnLine" : lowestPitchAsDotOnLine, + "completeDuration" : dur, + "baseDuration" : baseDur, #this is from a durationGroup, so we get the minimal one. Duplicated in NoteList but handy for calculating beams. + "ledgerLines" : ledgerLines, + "tickindex" : trackState.tickindex - dur, #because we parse the tickindex after we stepped over the item. + "stem" : stem, #stem means in staffline coordinates (dots on lines): [starting point, length, 1|-1] 1 stem is on the right or -1 left side of the note. + "flag" : flag, #0 os no flag, 8 is eighth flag upwards, -8 is downwards. 16 is 16th note etc. + "beamGroup" : self.beamGroup, #bool + "midiBytes" : midiBytesList, + "midiChannelOffset" : self.midiChannelOffset, + "beam" : tuple(), #decided later in structures export. Has the same structure as a stem. + } + + def _lilypond(self): + """Called by block.lilypond(), returns a string. + See Item.lilypond for the general docstring.""" + pitches, durations = zip(*(note.lilypond() for note in self.notelist)) + onlyOneDuration = durations.count(durations[0]) == len(durations) + if onlyOneDuration: + return "<" + " ".join(pitches) + ">" + durations[0] + else: + #TODO: Cache this + + # < \\ { 4 } \\ { 2 } >> + #Here is how it's done: We group the same duration together and create normal chords which are placed each in its own automatic voice through the lilypond syntax << { } \\ { } \\ etc. >> + #Lilypond default is to take the longest note as overall duration. However, Laborejo uses the shortest duration as logical duration. So we scale all other to logical shortest duration + #See http://lilypond.org/doc/v2.18/Documentation/notation/writing-rhythms#scaling-durations + table = {} + for note in self.notelist: + pitch, duration = note.lilypond() + ticks = note.duration.completeDuration() + if not (ticks, duration) in table: + table[(ticks, duration)] = list() + table[(ticks, duration)].append(pitch) + + substrings = [] + minimumTicksInChord = self.durationGroup.completeDuration() + for (ticks, lilydur), lst in table.items(): + #factor = Fraction(ticks, minimumDurInChord).limit_denominator(100000) #protects 6 or 7 decimal positions + #dur = lilydur + " * {}/{}".format(factor.denominator, factor.numerator) #lilypond requires the 1/x syntax + assert int(ticks) == ticks, ticks + assert int(minimumTicksInChord) == minimumTicksInChord, minimumTicksInChord + assert minimumTicksInChord <= ticks + dur = lilydur + " * {}/{}".format(int(minimumTicksInChord), int(ticks)) #lilypond requires the x/y syntax, even if it is 1/x + substrings.append("\\\\ { <" + " ".join(lst) + ">" + dur + " }" ) + result = "<<" + " ".join(substrings) + ">>" + return result + +class Rest(Item): + def __init__(self, duration): + super().__init__() + self.duration = duration + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + + @property + def durationGroup(self): + """For compatibility with Chords""" + return self.duration + + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.deserializeDurationAndNotelistInPlace(serializedObject) + self.lilypondParameters = serializedObject["lilypondParameters"] + self._secondInit(parentBlock = parentObject) + return self + + def _copy(self): + new = Rest(self.duration.copy()) + new.copyParentBlocks(self) + new.lilypondParameters = self.lilypondParameters.copy() + return new + + def logicalDuration(self): + """Return the logical duration that is used to calculate + the space and subsequent position of items. + Does include the base, dots and tuplets but not modifications for finetuning or phrasing.""" + return self.duration.completeDuration() + + # Commands issued by the user. Support undo. + # They get the same parameters, like pitch, as a Chord. This is only for compatibility + + def _setDuration(self, newDuration): + """A setter which supports undo""" + assert type(newDuration) is Duration + oldValue = self.duration.copy() + self.duration = newDuration + return lambda: self._setDuration(oldValue) + + def augmentNoteNearPitch(self, pitch = None): + oldValue = self.duration.copy() + self.duration.augment() + return lambda: self._setDuration(oldValue) + + def diminishNoteNearPitch(self, pitch = None): + oldValue = self.duration.copy() + self.duration.diminish() + return lambda: self._setDuration(oldValue) + + def toggleDotNearPitch(self, pitch = None): + oldValue = self.duration.copy() + self.duration.toggleDot() + return lambda: self._setDuration(oldValue) + + def toggleTripletNearPitch(self, pitch = None): + oldValue = self.duration.copy() + self.duration.toggleTriplet() + return lambda: self._setDuration(oldValue) + + def setTupletNearPitch(self, pitch, tupletListForDuration): + oldValue = self.duration.copy() + self.duration.tuplets = tupletListForDuration + return lambda: self._setDuration(oldValue) + + #Apply to selection gets called by different methods. We can just create aliases for Rest + augment = augmentNoteNearPitch + diminish = diminishNoteNearPitch + toggleDot = toggleDotNearPitch + toggleTriplet = toggleTripletNearPitch + + def setTuplet(self, durationTupletListForEachNote): + """ + parameter format compatible with Chord + [ + [(2,3)], #note 1 + [(4,5), (2,3)], #note 2 + [(3,4)], #note 3 + ] + """ + oldValue = self.duration.copy() + self.duration.tuplets = durationTupletListForEachNote[0] + return lambda: self._setDuration(oldValue) + + def calcFlag(self): + """What classical flag would be used + to express baseDuration, even if this only a rest""" + if self.duration.genericNumber <= 4: #no flag. Quarter, Half or bigger duration. + return 0 + else: + return self.duration.genericNumber + + def _exportObject(self, trackState): + dur = self.logicalDuration() + return { + "type": "Rest", + "rest": self.duration.genericNumber, + "baseDuration": self.duration.baseDuration, + "completeDuration" : dur, + "dots" : self.duration.dots, + "tuplets" : self.duration.tuplets, + "tickindex" : trackState.tickindex - dur, #because we parse the tickindex after we stepped over the item. + "midiBytes" : [], + #for compatibility with beaming groups: + "flag" : self.calcFlag(), + "stem" : (0,0,0), + "lowestPitchAsDotOnLine" : 0, + "highestPitchAsDotOnLine" : 0, + + } + + def _lilypond(self): + """Called by block.lilypond(), returns a string. + See Item.lilypond for the general docstring.""" + if self.lilypondParameters["visible"]: + return "r{}".format(self.duration.lilypond()) + else: + return "s{}".format(self.duration.lilypond()) + +class MultiMeasureRest(Item): + def __init__(self, numberOfMeasures): + super().__init__() + self.numberOfMeasures = numberOfMeasures + self._secondInit(parentBlock = None) #None is filled in later by item insert. #see Item._secondInit. + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + self._cachedOneMeasureInTicks = 0 + + @property + def numberOfMeasures(self): + return self._numberOfMeasures + + @numberOfMeasures.setter + def numberOfMeasures(self, newValue): + if newValue <= 0: #this allows 0.5 and 0.25 + newValue = 1 + self._numberOfMeasures = newValue + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.deserializeDurationAndNotelistInPlace(serializedObject) #creates parent blocks. + self._secondInit(parentBlock = parentObject) + self.numberOfMeasures = int(serializedObject["numberOfMeasures"]) + self.lilypondParameters = serializedObject["lilypondParameters"] + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["numberOfMeasures"] = self.numberOfMeasures + return result + + def _copy(self): + new = MultiMeasureRest(self.numberOfMeasures) + new.lilypondParameters = self.lilypondParameters.copy() + new.copyParentBlocks(self) + return new + + def logicalDuration(self): + """Return the logical duration that is used to calculate + the space and subsequent position of items. + Cursor movement uses this. + + This gets called before exportObject gets called. + """ + if not self._cachedOneMeasureInTicks: + for block in self.parentBlocks: + self._cachedOneMeasureInTicks = block.parentTrack.state.metricalInstruction().oneMeasureInTicks + break + + return self._cachedOneMeasureInTicks * self.numberOfMeasures + + def _exportObject(self, trackState): + self._cachedOneMeasureInTicks = trackState.metricalInstruction().oneMeasureInTicks + self._cachedMetricalInstruction = trackState.metricalInstruction() #for lilypond export + dur = self.logicalDuration() + return { + "type": "MultiMeasureRest", + "numberOfMeasures": self.numberOfMeasures, + "completeDuration" : dur, + "tickindex" : trackState.tickindex - dur, #because we parse the tickindex after we stepped over this item. + "midiBytes" : [], + "lilypondParameters" : self.lilypondParameters, + } + + def _setNumberOfMeasures(self, numberOfMeasures): + """For undo and redo""" + oldValue = self.numberOfMeasures + self.numberOfMeasures = numberOfMeasures + return lambda: self._setNumberOfMeasures(oldValue) + + def augmentNoteNearPitch(self, pitch): + """Don't double the duration but simply add one more measure""" + oldValue = self.numberOfMeasures + self.numberOfMeasures += 1 + return lambda: self._setNumberOfMeasures(oldValue) + + def diminishNoteNearPitch(self, pitch): + """Don't half the duration but simply add one more measure""" + oldValue = self.numberOfMeasures + self.numberOfMeasures -= 1 + return lambda: self._setNumberOfMeasures(oldValue) + + #Selected MM rests do *2 and /2 like other durations. + def augment(self): + oldValue = self.numberOfMeasures + self.numberOfMeasures = self.numberOfMeasures * 2 + return lambda: self._setNumberOfMeasures(oldValue) + + def diminish(self): + oldValue = self.numberOfMeasures + self.numberOfMeasures = self.numberOfMeasures / 2 + return lambda: self._setNumberOfMeasures(oldValue) + + def _lilypond(self): + """Called by block.lilypond(), returns a string. + See Item.lilypond for the general docstring.""" + lyduration = "{}/{}".format(self._cachedMetricalInstruction.nominator, duration.baseDurationToTraditionalNumber[self._cachedMetricalInstruction.denominator]) + + if self.lilypondParameters["visible"]: + return "R1*{}*{}".format(self.numberOfMeasures, lyduration) + else: + return "\\skilp1*{}*{}".format(self.numberOfMeasures, lyduration) + +class KeySignature(Item): + """Examples: + C Major: KeySignature(20, [0, 0, 0, 0, 0, 0, 0]) #c, d, e, f, g, a, b/h + F Major: KeySignature(170, [0, 0, 0, 0, 0, 0, -10]) + G Major: KeySignature(220, [0, 0, 0, 10, 0, 0, 0]) + Indian Scale ?: KeySignature(220, [0, -10, -20, 0, 0, -10, -20, 0]) #c, des, eeses, f, g, aes, beses, c + + The input deviationFromMajorScale is transformed to an absolute + keysig, compatible with Lilypond, in init. + + The result is saved permanently in self.keysigList in the following + form: + [(0, c), (1, d), (2, e), (3, f), (4, g), (5, a), (6, b)]) + where each note can be , -20, -10, 0, +10, +20 + for double flat to double sharp. + + Attention! the order of items is important. + + Example 2. G Major with correct order of accidentals: + [(3,10), (0,0), (4,0), (1,0), (5,0), (2,0), (6,0)]) + + Example 3. F Major with correct order. + [(6,-10), (2,0), (5,0), (1,0), (4,0), (0,0), (3,0)]) + + So it is possible to rewrite the keysignature manually. It is a + public parameter. + + + Eventhough a dict might seem convenient for this kind of data + structure the order is important. + """ + + def __init__(self, root, deviationFromMajorScale): + super().__init__() + assert root < 350 #really a plain note? + assert pitchmath.plain(root) == root + self.root = root + self.deviationFromMajorScale = deviationFromMajorScale + self._secondInit(parentBlock = None) #see Item._secondInit. + self.lilypondParameters["explicit"] = False + + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + rootIndex = pitchmath.pillarOfFifth.index(self.root) #which position in the pillar has the root note? + distance = rootIndex - 15 #distance from C. This is not the same as pitchmatch.tonalDistanceFromC! It is the index distance and not the tonal distance as interval. + + transposedMajorScale = self.transposeMajorScale([(3,0), (0,0), (4,0), (1,0), (5,0), (2,0), (6,0)], distance) #the number list is the major scale. + transposedMajorScale = self.rotateToRoot(sorted(transposedMajorScale), pitchmath.tonalDistanceFromC[self.root]) #Ordered by pitch, rotated to have the root note in front + + #Modify the transposed major scale with our modificator pattern. + self.keysigList = [] + for maj, mod in zip(transposedMajorScale, self.deviationFromMajorScale): + self.keysigList.append((maj[0], maj[1] + mod)) + + self.keysigList = self.sortKeysig(self.keysigList) + + #Now fill a list with offsets from the middle line in treble clef h', which is 0. c'' is -1, a' is +1 + self.keysigListAsDistanceInDiatonicStepsFrom1720 = [] #the basis for exportObject for GUIs. Need to be modified dynamically with a clef, see exportObject() + for index, accidentalMod in self.keysigList: + if accidentalMod: + if index == 0: #c + index = -1 + elif index == 1: #d + index = -2 + elif index == 2: #e + index = -3 + elif index == 3: #f + index = -4 + elif index == 4: #g + index = -5 + elif index == 5: #a + index = 1 + elif index == 6: #h/b + index = 0 + else: + raise ValueError("Accidental indices for KeySignatures must be 0-6") + self.keysigListAsDistanceInDiatonicStepsFrom1720.append((index, accidentalMod)) + + self.keysigList = tuple(self.keysigList) #from list to tuple for hashing and caching + + def hash(self): + return self.keysigList + + def _set(self, root, deviationFromMajorScale): + """Circular for undo""" + oldValues = (self.root, self.deviationFromMajorScale) + self.root = root + self.deviationFromMajorScale = deviationFromMajorScale + self._secondInit(parentBlock = None) #see Item._secondInit. + return lambda ov=oldValues: self._set(*ov) + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.root = int(serializedObject["root"]) + self.deviationFromMajorScale = serializedObject["deviationFromMajorScale"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["root"] = self.root + result["deviationFromMajorScale"] = self.deviationFromMajorScale + #Only the two init values are saved. That means that any manual changes to the keysig cannot be saved. Keysigs are damned to get deleted and recreated. It is the same for copy. + return result + + def _copy(self): + new = KeySignature(root = self.root, deviationFromMajorScale = self.deviationFromMajorScale) + + return new + + def intervalAutomatic(self, rootPitch, targetPitch): + undo = self._set(root = pitchmath.intervalAutomatic(self.root, rootPitch, targetPitch), deviationFromMajorScale = self.deviationFromMajorScale) + return undo + + def transposeMajorScale(self, cMajorScale, stepsInPillar): + """Transpose a list of positions/modifications like a keysig + Pillar Of Fifth Steps. + Sadly the method only works for the Major Keysig""" + counter = 0 + if stepsInPillar > 0: + modificator = 10 + else: + modificator = -10 + cMajorScale.reverse() + + transpose = [] + for pos, accidental in cMajorScale: + if counter == abs(stepsInPillar): + transpose.extend(cMajorScale[counter:7]) #append the missing notes to the return list. + break + else: + transpose.append((pos, accidental + modificator)) + counter += 1 + if stepsInPillar <= 0: #Return as it came in. Most likely the return list will be sorted anyway later, but this here is more correct. + transpose.reverse() + return transpose + + def sortKeysig(self, keysig): + wip = sorted(keysig) + new = [wip[3], wip[0], wip[4], wip[1], wip[5], wip[2], wip[6],] + if wip[6][1] == -10: #Bes included? Then use flat order. + new.reverse() + return new + + def rotateToRoot(self, transposedMajorScale, pos): + """pos is the first number of a keysig tupet. + Use to rotate a root note to the front""" + r = deque(transposedMajorScale) + while not r[0][0] == pos: + r.rotate(1) + return list(r) #this is not simply creating a list but converting to a list. don't replace with [r] + + def asAccidentalsOnLines(self, clef): + result = [] + for onLineIndex, accidentalMod in self.keysigListAsDistanceInDiatonicStepsFrom1720: + result.append((onLineIndex + clef.inComparisonToTrebleClefOffset, accidentalMod)) + return result + + def _exportObject(self, trackState): + """Usual dotsOnLine syntax. 0 for middle line, + -n to go higher, +n to go lower. + + accidentalsOnLines is a dict with key = linePosition and value + can be filled with + bb, b, natural, #, ## + which is: + -20, -10, 0, 10, 20 + """ + return { + "type": "KeySignature", + "completeDuration" : 0, + "tickindex" : trackState.tickindex, + "root" : self.root, + "accidentalsOnLines" : self.asAccidentalsOnLines(trackState.clef()), + "midiBytes" : [], + + } + + def _lilypond(self): + def build(step, alteration): #generate a Scheme pair for Lilyponds GUILE interpreter + if alteration == -10: + return "(" + str(step) + " . ," + "FLAT)" + elif alteration == 10: + return "(" + str(step) + " . ," + "SHARP)" + elif alteration == 20: + return "(" + str(step) + " . ," + "DOUBLE-SHARP)" + elif alteration == -20: + return "(" + str(step) + " . ," + "DOUBLE-FLAT)" + elif self.lilypondParameters["explicit"] and alteration == 0: + return "(" + str(step) + " . ," + "NATURAL)" + else: + return "" + + #G Major ((3, 10), (0, 0), (4, 0), (1, 0), (5, 0), (2, 0), (6, 0)) + #`((0 . ,NATURAL) (1 . ,NATURAL) (2 . ,NATURAL) (3 . ,SHARP) (4 . ,NATURAL) (5 . ,NATURAL) (6 . ,NATURAL)) + + schemepairs = " ".join(build(x[0], x[1]) for x in self.keysigList) + schemepairs = " ".join(schemepairs.split()) # split and join again to reduce all whitespaces to single ones. + subtextRoot = "\\once \\override Staff.KeySignature #'stencil = #(lambda (grob) (ly:stencil-combine-at-edge (ly:key-signature-interface::print grob) Y DOWN (grob-interpret-markup grob (markup #:small \"" + pitchmath.pitch2ly[self.root].strip(",").title() + "\")) 3)) " #3 is the space between keysig and text + lyKeysignature = subtextRoot + "\\set Staff.keySignature = #`( {} )".format(schemepairs) + return lyKeysignature + +class Clef(Item): + """A clef has no direct musical logical meaning. But it gives some hints: + Voice range. A typical musical voice in a polyphonic setup has between one and two octaves range + so seeing the clef hints at what voice it is. Therefore we can use a clef a basis for random + note generation or even range checking and warnings. """ + + offset = { + #the offset of the middle line. Basically: After the clef, how many diatonic steps (gaps/line) is the middle line away from b'/h' (1720)? + #7 steps is one octave + #negative goes up, positive goes down. + #5 lines as basis for the comments. + "treble" : 0, #Standard G Clef + "treble^8" : 7, + "treble_8" : -7, + "bass" : -12, #F Clef on the second highest line + "bass^8" : -5, + "bass_8" : -17, + "french" : 2, #G Clef on the lowest line + "baritone" : -10, #C Clef on the highest line + "tenor" : -8, #C Clef on the second highest line + "alto" : -6, #C Clef on the middle line + "mezzosoprano" : -4, #C clef on the second lowest line + "soprano" : -2, #C clef on the lowest line + "varbaritone" :-10, #F Clef on the middle line + "subbass" : -14, #F Clef on the highest line + #"midiDrum" : -12, #Percussion clef in the middle for layout, but bass clef in reality. Used for Midi. + "percussion" : -6, #Percussion clef in the middle, for lilypond. Needs midi transposition, a special case checked for when doing midi export. + } + + #regardles of the actual octave, what is the easiest way to display a pitch in another clef. for example F in treble is two lines down in bass. + #This offset method is used for keysignature + inComparisonToTrebleClef = { + "treble" : 0, #Standard G Clef + "treble^8" : 0, + "treble_8" : 0, + "alto" : 1, #C on the middle line. + "bass" : 2, #F Clef on the second highest line + "bass^8" : 2, + "bass_8" : 2, + #"midiDrum" : 2, #Same as Bass + "percussion" : 1, #Same as Alto + } + + + centerPitch = { clefString:offset*50+1720 for clefString, offset in offset.items() } + + def __init__(self, clefString): + super().__init__() + self.clefString = clefString + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + self.asDotOnLineOffset = Clef.offset[self.clefString] + self.inComparisonToTrebleClefOffset = Clef.inComparisonToTrebleClef[self.clefString] + self.rangeCenter = Clef.centerPitch[self.clefString] + self.rangeLowest = self.rangeCenter - 6*50 #the center is always the pitch on "middle line" + self.rangeHighest = self.rangeCenter + 5*50 + + def __hash__(self): + """Since we implemented __eq__ we need to make Clef hashable again""" + return id(self) + def __eq__(self, other): # self == other + return self.clefString == other.clefString + def __ne__(self, other): # self != other + return self.clefString != other.clefString + + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.clefString = serializedObject["clefString"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["clefString"] = self.clefString + #The other values are generated from clefString + return result + + def _copy(self): + new = Clef(self.clefString) + + return new + + def _exportObject(self, trackState): + return { + "type": "Clef", + "completeDuration" : 0, + "tickindex" : trackState.tickindex, + "clef" : self.clefString, + "midiBytes" : [], + + #Thats it. A GUI does not need to know anything about the clef except its look because we already deliever note pitches as dots on lines, calculated with the clef. + } + + def _lilypond(self): + return "\\clef \"{}\"".format(self.clefString) + +class TimeSignature(Item): #Deprecated since 1750 + """Meter information. Nominator is how many notes in one measure and + denominator is notes of which type in ticks. + Eventhough Time Signatures are logically only valid at the beginning + of a measure it is still possible to add them anywhere because + Lilypond allows it as well. And it is much easier to program this + way. + Dumb users will always find a way to put stuff in the wrong place. + If they want timesigs in the middle of a bar, let them have it... idiots. + + Do not edit a timesig. Delete and recreate.""" + + def __init__(self, nominator, denominator): + raise RuntimeError("Use items.MetricalInstruction") + super().__init__() + #examples for 4/4 or 4/(210*2**8) measures + self.nominator = nominator #example: 4. Upper number + self.denominator = denominator #example: 210*2**8. Lower number + + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + self.oneMeasureInTicks = self.nominator * self.denominator + + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.nominator = serializedObject["nominator"] + self.denominator = serializedObject["denominator"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["nominator"] = self.nominator + result["denominator"] = self.denominator + return result + + def _copy(self): + new = TimeSignature(self.nominator, self.denominator) + return new + + def _exportObject(self, trackState): + return { + "type": "TimeSignature", + "completeDuration" : 0, + "tickindex" : trackState.tickindex, + "nominator" : self.nominator, + "denominator" : duration.baseDurationToTraditionalNumber[self.denominator], + "midiBytes" : [], + + } + +class MetricalInstruction(Item): + def __init__(self, treeOfInstructions, isMetrical = True): + """Don't edit. Delete and create a new one""" + super().__init__() + for value in flatList(treeOfInstructions): + if not type(value) is int: + raise ValueError("Only integers are allowed in a metrical instruction. You used {}. Cast to int if you are sure your float is x.0, e.g. in a dotted quarter note created by D4*1.5".format(value)) + + self.treeOfInstructions = treeOfInstructions #if you skipped the docstring. this is a 4/4: ((D4, D4), (D4, D4)) . If empty no barlines will get drawn + self.isMetrical = isMetrical #If False all dynamic playback modifications based on the metre will be deactivated but barlines will still be created. This is forced to become false when the treeOfInstructions is 0 ticks. + self._secondInit(parentBlock = None) #see Item._secondInit. + + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + i = sum(flatList(self.treeOfInstructions)) + assert i >= 0 #stop your shennenigans! + self.oneMeasureInTicks = i #even if i is 0. + + if i == 0: + self.isMetrical = False #protection against a wrong combination + self.nominator = None + self.denominator = None + else: + self.nominator = len(list(flatList(self.treeOfInstructions))) #for compatibility with lilypond etc. + self.denominator = self.oneMeasureInTicks / self.nominator #for compatibility with lilypond etc. + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.treeOfInstructions = eval(serializedObject["treeOfInstructions"]) #we really want to keep the tuples and not mutable lists. + self.isMetrical = serializedObject["isMetrical"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["treeOfInstructions"] = self.treeOfInstructions.__repr__() #we really want to keep the tuples and not mutable lists. + result["isMetrical"] = self.isMetrical + return result + + def _copy(self): + new = MetricalInstruction(self.treeOfInstructions, self.isMetrical) + return new + + def _exportObject(self, trackState): + return { + "type": "MetricalInstruction", + "completeDuration" : 0, #it has no duration of its own. + "tickindex" : trackState.tickindex, + #"instruction" : #TODO, + "isMetrical" : self.isMetrical, + "oneMeasureInTicks" : self.oneMeasureInTicks, + "midiBytes" : [], + "treeOfInstructions" : self.treeOfInstructions.__repr__(), + } + + def _lilypond(self): + """Since metrical instruction can get very complex we rely entirely on the lilypond override + functionality. The common api signatures already include these.""" + raise RuntimeError("This metrical instruction should have a lilypond-override") + +class BlockEndMarker(Item): + """Cannot be inserted into the real blocks. It is added + dynamically and automatically as exportObject + only during track. static representation""" + + def __init__(self): + super(BlockEndMarker, self).__init__() + + #does not need a serialize or copy method since it gets dynamically created only for export + + def _exportObject(self, trackState): + return { + "type": "BlockEndMarker", + "completeDuration" : 0, + "tickindex" : trackState.tickindex, + "midiBytes" : [], + + } + +class DynamicSignature(Item): + """The class for "piano", "forte" and so on""" + def __init__(self, keyword): + assert keyword in ["ppppp", "pppp", "ppp", "pp", "p", "mp", "mf", "f", "ff", "fff", "ffff", "tacet", "custom"] + super().__init__() + self.keyword = keyword + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.keyword = serializedObject["keyword"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["keyword"] = self.keyword + return result + + def _copy(self): + new = DynamicSignature(keyword = self.keyword) + return new + + def baseVelocity(self, trackState): + return trackState.track.dynamicSettingsSignature.dynamics[self.keyword] + + def _exportObject(self, trackState): + return { + "type": "DynamicSignature", + "completeDuration" : 0, + "tickindex" : trackState.tickindex, + "keyword" : self.keyword, + "midiBytes" : [], + } + +class DynamicRamp(Item): + """The class for "cresc", "decresc" and so on. + It takes the current trackState as starting point and + interpolates to the next DynamicSignature. + If there is no DynamicSignature right of this item + then the ramp goes to 127 or 0. The latter is probably useful for + a fadeout. + + Setting the interpolation type to "standalone" effectively switches + the interpolation off for this item. This is useful if you want + the score marker (e.g. for Lilypond) but not the midi, for example + because you do dynamics with the expression CC. + + Cresc or Decresc is set automatically. + + A note gets its velocity through + + note.dynamic.velocity(trackState) + """ + + def __init__(self): + super().__init__() + self.graphType = "linear" #options: linear, standalone + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + #The cached valueas are set during export. + self._cachedTargetVelocity = -1 #0 is valid as well. Test for >0 + self._cachedTargetTick = -1 #0 is valid as well. Test for >0 + self._cachedTickIndex = -1 #0 is valid as well. Test for >0 + self._cachedVelocity = -1 #0 is valid as well. Test for >0 + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.graphType = serializedObject["graphType"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["graphType"] = self.graphType + return result + + def _copy(self): + new = DynamicRamp() + new.graphType = self.graphType + + return new + + def _linearVelocityValue(self, tickindex): + """ + the variable is taken from the standard formula: f(x) = m*x + n + + We want to know the velocity value for a tickindex x. + f(x) is that velocity. + m is the gradient (steigung) + """ + x = tickindex - self._cachedTickIndex + n = self._cachedVelocity + divider = (self._cachedTargetTick - self._cachedTickIndex) + if not divider: #there is a chance that this gets 0 but only while editing is in an intermediate sate. + divider = 1 + m = (self._cachedTargetVelocity - self._cachedVelocity) / divider + return int(m*x+n) + + def getVelocity(self, tickindex): + """Get the complete velocity for a tickindex, without the base + velocity from the dynamic Signature""" + if self._cachedVelocity >= 0 and self._cachedTargetVelocity >= 0 and self._cachedTargetTick >= 0 and self._cachedTickIndex >= 0: + assert tickindex <= self._cachedTargetTick + #assert tickindex >= self._cachedTickIndex #this creates problems with patterns which modify the tickindex while exporting. + + if self.graphType == "linear": + return self._linearVelocityValue(tickindex) + elif self.graphType == "standalone": + return self._cachedVelocity + else: + raise ValueError("GraphType unknown:", self.graphType) + + else: #this is the case when a dynamic ramp has no final dynamic signature. note.dynamic.velocity checks for None and chooses the normal velocity instead. + return None + + def _exportObject(self, trackState): + """The keyword is dyn-ramp if there is either no follow-up + Dynamic Signature or if the same dynsig follows again""" + + keyword = "dyn-ramp" + if self._cachedVelocity >= 0 and self._cachedTargetVelocity >= 0 and self._cachedTargetTick >= 0 and self._cachedTickIndex >= 0: + #print ("from {} to {} in {} ticks".format(self._cachedVelocity, self._cachedTargetVelocity, self._cachedTargetTick - self._cachedTickIndex )) + if self._cachedVelocity > self._cachedTargetVelocity: + keyword = "decresc" + elif self._cachedVelocity < self._cachedTargetVelocity: + keyword = "cresc" + #else it stays dyn-ramp. + return { + "type": "DynamicSignature", + "graphType" : self.graphType, + "keyword" : keyword, + "completeDuration" : 0, + "tickindex" : trackState.tickindex, + "midiBytes" : [], + + } + +class LegatoSlur(Item): + def __init__(self): + super().__init__() + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + + def _copy(self): + new = LegatoSlur() + return new + + def openOrClose(self, trackState): + """This function gets called by exportObject where + the trackState is already after the current item, which is + LegatoSlur. + This means if trackState.duringLegatoSlur is False we just + closed a slur. + """ + if trackState.duringLegatoSlur: + return "open" + else: + return "close" + + def _exportObject(self, trackState): + return { + "type" : "LegatoSlur", + "slur" : self.openOrClose(trackState), + "completeDuration" : 0, + "tickindex" : trackState.tickindex, + "midiBytes" : [], + } + +class InstrumentChange(Item): + """Includes program change, both bank changes and the lilypond instrument name and short name change""" + def __init__(self, program, msb, lsb, instrumentName, shortInstrumentName): + """Either init gets called, by creation during runtime, or instanceFromSerializedData. + That means everything in init must be matched by a loading call in instanceFromSerializedData.""" + super().__init__() + assert -1 <= program <= 127, program #-1 means Laborejo will not send the program change, if this is the initial change. + assert 0 <= msb <= 127, msb #a CC value + assert 0 <= lsb <= 127, lsb #a CC value + self.program = program + self.msb = msb + self.lsb = lsb + self.instrumentName = instrumentName + self.shortInstrumentName = shortInstrumentName + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """After creating a new item during runtime or after loading from a file this gets called. + Put every calcuation that depends on values that could be changed by the user. + see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.program = serializedObject["program"] + self.msb = serializedObject["msb"] + self.lsb = serializedObject["lsb"] + self.instrumentName = serializedObject["instrumentName"] + self.shortInstrumentName = serializedObject["shortInstrumentName"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["program"] = self.program + result["msb"] = self.msb + result["lsb"] = self.lsb + result["instrumentName"] = self.instrumentName + result["shortInstrumentName"] = self.shortInstrumentName + return result + + def _copy(self): + """return an independent copy of self""" + new = type(self)(self.program, self.msb, self.lsb, self.instrumentName, self.shortInstrumentName) #all init parameters are immutable types and copied implicitly + return new + + def _exportObject(self, trackState): + duration = 0 + tickPosition = trackState.tickindex - duration #minus duration because we are RIGHT of an item after parsing it in structures.staticRepresentation + #change this trackState.midiProgram = self.value + assert tickPosition == 0 or self.program >= 0 + + _msbStr = " msb" + str(self.msb) if self.msb > 0 else "" + _lsbStr = " lsb" + str(self.lsb) if self.lsb > 0 else "" + _nameStr = self.shortInstrumentName if self.shortInstrumentName else self.instrumentName + _nameStr = _nameStr + " " if (self.shortInstrumentName or self.instrumentName) else "" + return { + "type" : "InstrumentChange", + "completeDuration" : duration, + "tickindex" : trackState.tickindex - duration, #we parse the tickindex after we stepped over the item. + "midiBytes" : [cbox.Pattern.serialize_event(tickPosition, 0xC0 + trackState.midiChannel(), self.program, 0), + cbox.Pattern.serialize_event(tickPosition, 0xB0 + trackState.midiChannel(), 0, self.msb), #position, status byte+channel, controller number, controller value + cbox.Pattern.serialize_event(tickPosition, 0xB0 + trackState.midiChannel(), 32, self.lsb), #position, status byte+channel, controller number, controller value + ], + "instrumentName" : self.instrumentName, + "shortInstrumentName" : self.shortInstrumentName, + "UIstring" : "{}[pr{}{}{}]".format(_nameStr, self.program, _msbStr, _lsbStr), #this is for a UI, possibly a text UI, maybe for simple items of a GUI. Make it as short and unambigious as possible. + } + + def _lilypond(self): + """called by block.lilypond(), returns a string. + Don't create white-spaces yourself, this is done by the structures. + When in doubt prefer functionality and robustness over 'beautiful' lilypond syntax.""" + if self.instrumentName or self.shortInstrumentName: + raise NotImplementedError("Implement _lilypond() with correct instrument change syntax") + return str + else: + return "" + +class ChannelChange(Item): + def __init__(self, value, text): + """Either init gets called, by creation during runtime, or instanceFromSerializedData. + That means everything in init must be matched by a loading call in instanceFromSerializedData.""" + super().__init__() + #self.itemData #matches instanceFromSerializedData and serialize + assert 0 <= value <= 16, value + self.value = value + self.text = text + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """After creating a new item during runtime or after loading from a file this gets called. + Put every calcuation that depends on values that could be changed by the user. + see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.value = serializedObject["value"] + self.text = serializedObject["text"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + result = super().serialize() #call this in child classes + result["value"] = self.value + result["text"] = self.text + return result + + def _copy(self): + """return an independent copy of self""" + new = type(self)(self.value, self.text) #both init parameters are immutable types and copied implicitly + return new + + def _exportObject(self, trackState): + duration = 0 + tickPosition = trackState.tickindex - duration #minus duration because we are RIGHT of an item after parsing it in structures.staticRepresentation + #the new midi channel for the cursor, and all following export items, is handled by the track state and left/right parser + return { + "type" : "ChannelChange", + "completeDuration" : duration, + "tickindex" : trackState.tickindex - duration, #we parse the tickindex after we stepped over the item. + "midiBytes" : [], + "text" : self.text, + "UIstring" : "ch{}".format(self.value), #this is for a UI, possibly a text UI, maybe for simple items of a GUI. Make it as short and unambigious as possible. + } + + def _lilypond(self): + """called by block.lilypond(), returns a string. + Don't create white-spaces yourself, this is done by the structures. + When in doubt prefer functionality and robustness over 'beautiful' lilypond syntax.""" + if self.text: + raise NotImplementedError("Implement _lilypond() with correct instrument change syntax") + return self.text + else: + return "" + +class RecordedNote(Item): + """An intermediate item that gets created by the live recording process. + It has no Duration instance but a simple tick duration instead. + Also it has a fixed position in tick-time and cannot be edited with the cursor and the other + methods. It lives in a special per-track buffer. + + Is is saved and gets loaded. """ + + def __init__(self, itemData): + """Either init gets called, by creation during runtime, or instanceFromSerializedData. + That means everything in init must be matched by a loading call in instanceFromSerializedData.""" + super().__init__(positionInTicks, durationInTicks ) + self.positionInTicks = positionInTicks + self.durationInTicks = durationInTicks + + self._secondInit(parentBlock = None) #see Item._secondInit. + + def _secondInit(self, parentBlock): + """After creating a new item during runtime or after loading from a file this gets called. + Put every calcuation that depends on values that could be changed by the user. + see Item._secondInit""" + super()._secondInit(parentBlock) #Item._secondInit + + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """see Score.instanceFromSerializedData""" + raise NotImplementedError("Implement instanceFromSerializedData() for this item type!") + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + self.itemData = serializedObject["itemData"] + self.deserializeDurationAndNotelistInPlace(serializedObject) + self._secondInit(parentBlock = parentObject) + return self + + def serialize(self): + raise NotImplementedError("Implement serialize() for this item type!") + result = super().serialize() #call this in child classes + result["itemData"] = self.itemData + return result + + def _copy(self): + """return an independent copy of self""" + raise NotImplementedError("Implement _copy() for this item type!") + new = TemplateItem(self.itemData) + return new + + def _exportObject(self, trackState): + """Implement this in every child class, return a dict. + + Base class function to return a dict which is a good layout + export basis. For example for GUI frontends. They don't have to + parse and calculate their own values in slow pure Python then + + midiBytes is a list with pblob/binary data generated by + cbox.Pattern.serialize_event(position, midibyte1 (noteon), midibyte2(pitch), midibyte3(velocity)) + Items with duration, like chords, will most like need to create + at least two pblobs, one for the start (e.g. note on) and one + for the stop (e.g. note off) + """ + raise NotImplementedError("Implement _exportObject() for this item type!") + + #And for documentation and education here a template exportObject + duration = 0 + return { + "type" : "", + "completeDuration" : duration, + "tickindex" : trackState.tickindex - duration, #we parse the tickindex after we stepped over the item. + "midiBytes" : [], + "UIstring" : "", #this is for a UI, possibly a text UI, maybe for simple items of a GUI. Make it as short and unambigious as possible. + } + + def _lilypond(self): + """absolutely not""" + return "" diff --git a/engine/lilypond.py b/engine/lilypond.py new file mode 100644 index 0000000..b82c433 --- /dev/null +++ b/engine/lilypond.py @@ -0,0 +1,142 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +"""Use generated music data and build a complete lilypond file from it""" + +import os.path +from datetime import date +import subprocess +from tempfile import gettempdir +da = date.fromordinal(730920) # 730920th day after 1. 1. 0001 + +def saveAsLilypond(score, absoluteFilePath = None): + #absoluteFilePath = self.absoluteFilePath + ".ly" if (not absoluteFilePath) else absoluteFilePath + assert absoluteFilePath.endswith(".ly") + result = score.lilypond() + if result: + with open(absoluteFilePath, "w", encoding="utf-8") as f: + f.write(result) + return absoluteFilePath + +def saveAsLilypondPDF(score, openPDF = False): + tempfile = os.path.join(gettempdir(), str(id(score)) + ".ly") + exportedLilypond = saveAsLilypond(score, tempfile) + ret = subprocess.call("lilypond --output={} {}".format(exportedLilypond, exportedLilypond), shell=True) #suffix to output added by lilypond + if ret == 0 and openPDF: + subprocess.Popen("xdg-open {}.pdf".format(exportedLilypond), shell=True) + +def stringToCharsOnlyString(string): + def num2word(n): + """Take a number, return a str. + Lilypond does not allow numbers in variable names""" + return ''.join(chr(ord(c)+17) for c in str(n)) + + def num2wordForIterations(stringOrNum): + if stringOrNum in [1,2,3,4,5,6,7,8,9,0] or stringOrNum in "1234567890": + return num2word(int(stringOrNum)) + elif stringOrNum in ("-", "_"): + return "" + else: + return stringOrNum + + string = string.replace(" ", "_") + return "".join([num2wordForIterations(c) for c in string]) + +def lilyfy(string): + return string + + +def fromTemplate(session, templateFile, data, meta, tempoStaff): + """Returns a string built from already ly-exported track data and a lilypond template. + Called by score.lilypond(), which is called by session.lilypond(). + A template is either one of the built-ins "foo.ly" or + if the templateFile is None/"" the current filename+ly is used: "bar.lbj.ly" + + Laborejo Markers in the template have the syntax %$$DATE$$ . That is pretty unique and additionaly a lilypond + comment. + """ + #Load the template + templatePath = findTemplate(session, templateFile) + with open(templatePath, 'r') as f: + templateString = f.read() + + templateString = templateString.replace("%$$DATE$$", da.today().strftime("%A %d. %B %Y")) #The current date + templateString = templateString.replace("%$$FILENAME$$", session.absoluteFilePath) + templateString = templateString.replace("%$$HEADER$$", processMeta(meta)) + templateString = templateString.replace("%$$SUBTEXT$$", lilyfy(meta["subtext"])) + voicesString, structureString = processData(data) + templateString = templateString.replace("%$$VOICES$$", voicesString) + templateString = templateString.replace("%$$STRUCTURE$$", structureString) + templateString = templateString.replace("%$$TEMPOSTAFF$$", tempoStaff) + + return templateString + +def findTemplate(session, templateFile): + """returns a path. checks for existence. + see fromTemplate""" + if not templateFile: + path = session.absoluteFilePath, ".template.ly" + assert path.endswith(".lbj.ly") + else: + path = os.path.join(session.applicationDirectory, "laborejomodule", "templates", templateFile) + assert path.endswith(".ly") + + if os.path.exists(path): + return path + else: + raise FileNotFoundError(templateFile) + +def processData(data): + """returns two strings. the first actual music data, VOICES, the second the structure and order, + STRUCTURE""" + def voice(track, lilypondTrack): + """ tgliHJuGCFAIICICBEHBJABHIJE= { \key c \major 4 4 4 4 \bar "|."} """ + return "{} = {}".format(stringToCharsOnlyString(track.name), "{ " + lilypondTrack + " }") + + def structure(track, lilypondTrack): + """ \new Staff = "tgliHJuGCFAIICICBEHBJABHIJE_Staff" << \\new Voice = "tgliHJuGCFAIICICBEHBJABHIJE" \tgliHJuGCFAIICICBEHBJABHIJE >> %EndTrack """ + name = stringToCharsOnlyString(track.name) + instruments = '\\with {{ \n instrumentName = #"{}" \n shortInstrumentName = #"{}" }}'.format(lilyfy(track.initialInstrumentName), lilyfy(track.initialShortInstrumentName)) + mergeTempo = "\\new Voice = \"Tempo\" \\tempoStaff" + return """\\new Staff = "{}_Staff" {} << {} \\new Voice = "{}" \{} >> %EndTrack""".format(name, instruments, mergeTempo, name, name) + + voices = "\n ".join(voice(track, lilypondTrack) for track, lilypondTrack in data.items() if lilypondTrack) + structure = "\n ".join(structure(track, lilypondTrack) for track, lilypondTrack in data.items() if lilypondTrack) + + return voices, structure + + +def processMeta(meta): + """returns a string with lilypond header data like title and composer""" + + def valueMarkup(value): + value = value.strip() + if value: + if value.startswith("\\markup"): + return value + else: + return "\"{}\"".format(value) #results in "value" + else: + return "##f" + + metaString = "\n ".join(key + " = " + valueMarkup(value) for key, value in meta.items()) + + return metaString diff --git a/engine/main.py b/engine/main.py new file mode 100644 index 0000000..ffe0e0d --- /dev/null +++ b/engine/main.py @@ -0,0 +1,1070 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2018, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), +more specifically its template base application. + +The Template Base Application 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 . +""" + +import logging; logging.info("import {}".format(__file__)) + +#Standar Library + +#3rd Party + +#Template +import template.engine.sequencer +from template.engine.metronome import Metronome + +#Our modules +from .block import Block +from .track import Track +from .cursor import Cursor +from. graphtracks import TempoTrack + + +class Data(template.engine.sequencer.Score): + + def __init__(self, parentSession): + super().__init__(parentSession) + self.tracks = [Track(parentData = self)] #this is the track order and all visible tracks. For getting a specific track use Track.allTracks with a track id. + self.hiddenTracks = {} #track-instance:original Position. The value can exist multiple times. These still create a playback representation but are read-only and do not react to editing or GUI requests because you can't access them except through Track.allTrack (which is exactly the same for deleted tracks). Hidden tracks are saved though, deleted ones not. + self.tempoTrack = TempoTrack(parentData = self) #The tempoTrack is a Laborejo class. TempoMap is a template.sequencer class that is used by TempoTrack internally + + #Metadata has only strings as keys, even the numbers. + self.metaData = {key:"" for key in ("title", "subtitle", "dedication","composer","subsubtitle","instrument","meter","arranger", "poet","piece","opus","copyright","tagline", "subtext")} + + self._processAfterInit() + + def _processAfterInit(self): + self.cursor = Cursor(self) + self.trackIndex = 0 #a temp variable. + self.cursorWhenSelectionStarted = None #A cursor dict, from self.cursorExport(). Is None when there is no selection. Can be used for "if selection:" questions. Gets changed quite often. + self.copyObjectsBuffer = [] #for copy and paste. obviously empty after load file. Also not saved. + self.cachedTrackDurations = {} #updated after every track export + self.metronome = Metronome(parentData=self) #Purely dynamic structure. No save/load. No undo/redo + + def duration(self): + """Return the duration of the whole score, in ticks""" + #TODO: use cached duration? How often is this used? + result = [] + for track in self.tracks: + result.append(track.duration()) + return max(result) + + def currentTrack(self): + tr = self.tracks[self.trackIndex] + return tr + + def trackById(self, trackId): + try: + ret = Track.allTracks[trackId] + except: + print (sys.exc_info()[0]) + print (trackId, Track.allTracks, self.tracks, self.hiddenTracks, self.trackIndex) + raise + return ret + + def noteById(self, noteId): + """A note, and its parent Chord/Item, can be in multiple tracks. + But only ever in one block""" + return Note.allNotes[noteId].parentChord.parentTracks, Note.allNotes[noteId] #this returns the actual instances, not the weak references. + + #def itemById(self, itemId): + # """An item can be in multiple tracks. Return all those""" + # return self.allItems[itemId].parentTracks, self.allItems[itemId] #this returns the actual instances, not the weak references. + + def allBlocks(self): + """return all blocks in all tracks in order from top left + to bottom right, thinking in score-layout.""" + for track in self.tracks + list(self.hiddenTracks.keys()): + for block in track.blocks: + yield block + + def blockById(self, blockId): + """A block (not it's content!) is unique. There is + exactly one instance with this id, in one track""" + return Block.allBlocks[blockId].parentTrack, Block.allBlocks[blockId] #returns the actual instances, not the weak references. + + def currentTrackId(self): + trId = id(self.currentTrack()) + return trId + + def currentBlock(self): + """There is always a block, this is guaranteed""" + return self.currentTrack().currentBlock() + + def currentItem(self): + return self.currentTrack().currentItem() + + #def currentItemAndItsTrack(self): + # curItem = self.currentItem() + # if curItem: + # return curItem.currentItem.parentTracks, curItem + # else: + # return None + + def currentContentLinkAndItsBlocksInAllTracks(self): + curBlock = self.currentBlock() + trackList = list(set([block.parentTrack for block in curBlock.linkedContentBlocksInScore()])) #for this list(set( it doesn't matter that the trackList will not be in order. + return trackList, curBlock + + def insertTrack(self, atIndex, trackObject): + """This is also newTrack. the api creates a track object for that. + atIndex inserts the track before the item currently + in this position. If atIndex is bigger than the highest current + index it will be appended through standard python behaviour + + We don't use the template-function addTrack. + """ + assert trackObject.sequencerInterface + assert trackObject.parentData == self + self.tracks.insert(atIndex, trackObject) + self.trackIndex = self.tracks.index(trackObject) + assert atIndex == self.trackIndex + + def tracksAsDict(self): + """used by rearrangeTracks + Key is the track id, value the track instance""" + result = {} + for track in self.tracks: + result[id(track)] = track + return result + + def asListOfTrackIds(self): + """Return an ordered list of track ids""" + result = [] + for track in self.tracks: + result.append(id(track)) + return result + + def rearrangeTracks(self, listOfTrackIds): + """Reorder the tracks. + Achtung! Not including a track will delete this track. This is + not the right place to delete a track. So we check for that case""" + startTrack = self.currentTrack() #we will return later to this track + originalLength = len(self.tracks) + tracksDict = self.tracksAsDict() + newArrangement = [] + + for idLong in listOfTrackIds: + newArrangement.append(tracksDict[idLong]) + + seen = set() + seen_add = seen.add + self.tracks = [ x for x in newArrangement if x not in seen and not seen_add(x)] + + assert originalLength == len(self.tracks) + assert self.tracks + self.trackIndex = self.tracks.index(startTrack) + + + def deleteCurrentTrack(self): + if len(self.tracks) > 1: + nowInTicks = self.currentTrack().state.tickindex + result = self.currentTrack(), self.trackIndex #return to the API for undo. + + super().deleteTrack(self.currentTrack()) + #self.currentTrack().prepareForDeletion() #remove calfbox objects + #self.tracks.remove(self.currentTrack()) + + if self.trackIndex+1 > len(self.tracks): #trackIndex from 0, len from 1. + self.trackIndex -= 1 + self.currentTrack().head() + self.currentTrack().goToTickindex(nowInTicks) #that is already the new current track + return result + + def deleteTrack(self, track): + if track == self.currentTrack(): + return self.deleteCurrentTrack() #redirect. This way we have no problems with cursor positions etc. + + if len(self.tracks) > 1: + #We need to know if the old current track was AFTER the deleted one. In this case the trackindex needs to get subtracted by one (before the track is actually deleted) + result = self.currentTrack(), self.trackIndex #so undo has something to save + if self.trackIndex > self.tracks.index(track): #there is only > or <. == is ruled out above. + self.trackIndex -= 1 + + super().deleteTrack(track) + #track.prepareForDeletion() + #self.tracks.remove(track) + return result + + def hideTrack(self, track): + """This track cannot be edited while hidden. + We don't delete any calfbox data here, contrary to delete Track. + That means we don't need to touch anything and the playback + version will remain correct. + Also make sure we are in the right track afterwards since + hideTrack changes the trackIndices""" + assert track in self.tracks #track is visible so it should be in the list of visible tracks + assert not track in self.hiddenTracks #track is visible so it should not be in the list of hidden tracks + if len(self.tracks) > 1: #same rules as for delete. do not hide the last visible track + self.hiddenTracks[track] = self.tracks.index(track) + if self.trackIndex == self.tracks.index(track): #the track with the active cursor gets hidden + self.tracks.remove(track) + self.trackIndex = 0 + else: + currentTrack = self.tracks[self.trackIndex] + self.tracks.remove(track) + self.trackIndex = self.tracks.index(currentTrack) #find out where the current track is now. + return True #succesful + + def unhideTrack(self, track): + assert not track in self.tracks #track is hidden so it should not be in the list of visible tracks + assert track in self.hiddenTracks #track is hidden so it should be in the list of hidden tracks + currentTrack = self.tracks[self.trackIndex] + self.tracks.insert(self.hiddenTracks[track], track) + del self.hiddenTracks[track] + self.trackIndex = self.tracks.index(currentTrack) #find out where the current track is now. + return True + + def trackUp(self): + if self.trackIndex > 0: + #there is still a track above. At least index 0. + nowInTicks = self.currentTrack().state.tickindex + self.trackIndex -= 1 + self.currentTrack().goToTickindex(nowInTicks) + return True + + def trackDown(self): + if self.trackIndex < len(self.tracks)-1: + #there is still a track below + nowInTicks = self.currentTrack().state.tickindex + self.trackIndex += 1 + self.currentTrack().goToTickindex(nowInTicks) + return True + + def trackFirst(self): + nowInTicks = self.currentTrack().state.tickindex + self.trackIndex = 0 + self.currentTrack().goToTickindex(nowInTicks) + + def trackLast(self): + nowInTicks = self.currentTrack().state.tickindex + self.trackIndex = len(self.tracks)-1 + self.currentTrack().goToTickindex(nowInTicks) + + def cursorExport(self): + try: + return self.cursor.exportObject(self.currentTrack().state) + except ValueError: #debugging without callbacks + warn("cursor export did not work. If this was during debugging without callbacks it is allright.") + return {} + + def _cursorExportTrackTick(self, track, tickPosition): + originalPosition = track.state.position() + track.goToTickindex(tickPosition) + exportCursor = self.cursor.exportObject(track.state) + track.toPosition(originalPosition) #has head() in it + return exportCursor + + def setSelectionBeginning(self): + if self.cursorWhenSelectionStarted: + return False #because we did nothing + else: + self.cursorWhenSelectionStarted = self.cursorExport() #There was no selection before. setSelectionBeginning is called by selection-creating functions. So this was the first step of shift+right or so. + return True #because we did something + + def goToSelectionEnd(self): + """Keeps the selection alive. + Written for processing functions like apply to selection. + Or maybe as a user command. + Is not used in the internal score selection commands because + we want to keep everything original.""" + + result = self.checkSelectionOrder() + if not result: + raise RuntimeError("called score.goToSelectionEnd without a selection") + else: + topLeftCursor, bottomRightCursor = result + + #The cursor when selection started is always the opposite of the current cursor position. except if the selection has zero width, which is ruled out by the test above. + if self.cursorWhenSelectionStarted == topLeftCursor: #already at the end + return False + else: #self.cursorWhenSelectionStarted == bottomRightCursor: + self.cursorWhenSelectionStarted = topLeftCursor + self.goTo(bottomRightCursor["trackIndex"], bottomRightCursor["blockindex"], bottomRightCursor["localCursorIndex"]) #does not work if the number of items change. e.g. split + return True + #else: This fires when the selection goes from bottomLeft to topRight or reverse. Make the "elif" above the new "else". + #raise ValueError("Cursor was neither at the start nor the end of the selection but a selection was present. This is a serious error. Only selections with the cursor on either end are allowed") + + def goToSelectionStart(self): + result = self.checkSelectionOrder() + if not result: + raise RuntimeError("called score.goToSelectionEnd without a selection") + else: + topLeftCursor, bottomRightCursor = result #one of these is always the current cursor, not a cached value. You don't need to test if the current cursor is actually one of these two. + + #The cursor when selection started is always the opposite of the current cursor position. except if the selection has zero width, which is ruled out by the test above. + if self.cursorWhenSelectionStarted == bottomRightCursor: #already at the beginning + return False + else:# self.cursorWhenSelectionStarted == topLeftCursor: + self.cursorWhenSelectionStarted = bottomRightCursor + self.goTo(topLeftCursor["trackIndex"], topLeftCursor["blockindex"], topLeftCursor["localCursorIndex"]) #contrary to goToSelectionEnd this works always. No duration or number change can affect this position. + return True + #else: This fires when the selection goes from bottomLeft to topRight or reverse. Make the "elif" above the new "else". + # raise ValueError("Cursor was neither at the start nor the end of the selection but a selection was present. This is a serious error. Only selections with the cursor on either end are allowed") + + def checkSelectionOrder(self): + """Return the correct order of the selection boundaries + (topLeft, bottomRight) + Returns empty tuple if we don't have a selection or + a selection of size 0.""" + if self.cursorWhenSelectionStarted: #is None if we don't have a selection at all. Otherwise a cursor export object like self.cursorExport() + current = self.cursorExport() + if self.cursorWhenSelectionStarted["tickindex"] == current["tickindex"]: + #The only time this should happen is after a selection modification by the user which results in having no selections. e.g. "select right", "select left". + #A special case if a selection changes direction, or "inverts". + #Note that we don't reset self.cursorWhenSelectionStarted. The selection process is still going on. + return tuple() + + #we have a selection with dimensions > 0. + if self.cursorWhenSelectionStarted["trackIndex"] < current["trackIndex"]: #selection order GUI-view: top to bottom + if self.cursorWhenSelectionStarted["tickindex"] < current["tickindex"]: #selection order left to right + result = self.cursorWhenSelectionStarted, current + else: #selection order right to left. Both topLeft and bottomRight are not created by the user directly. We have to guess what start item the user wants which can be hard if zero-duration items are involved. + #There is no other way to go the tickindex of the real first item and force a cursor export. + topLeft = self._cursorExportTrackTick(self.cursorWhenSelectionStarted["track"], current["tickindex"]) #yes, the tickindex of the other track + bottomRight = self._cursorExportTrackTick(current["track"], self.cursorWhenSelectionStarted["tickindex"]) #yes, the tickindex of the other track + return topLeft, bottomRight + + elif self.cursorWhenSelectionStarted["trackIndex"] > current["trackIndex"]: #selection order GUI-view: bottom to top + if self.cursorWhenSelectionStarted["tickindex"] > current["tickindex"]: #selection order left to right + result = current, self.cursorWhenSelectionStarted + else: #selection order right to left. Both topLeft and bottomRight are not created by the user directly. We have to guess what start item the user wants which can be hard if zero-duration items are involved. + #There is no other way to go the tickindex of the real first item and force a cursor export. + bottomRight = self._cursorExportTrackTick(self.cursorWhenSelectionStarted["track"], current["tickindex"]) #yes, the tickindex of the other track + topLeft = self._cursorExportTrackTick(current["track"], self.cursorWhenSelectionStarted["tickindex"]) #yes, the tickindex of the other track + return topLeft, bottomRight + + else: #in the same track + assert self.cursorWhenSelectionStarted["trackIndex"] == current["trackIndex"] #anything else is logically impossible. + if self.cursorWhenSelectionStarted["position"] <= current["position"]: + result = self.cursorWhenSelectionStarted, current + else: + result = current, self.cursorWhenSelectionStarted + return result + else: + return tuple() + + + def selectionExport(self): + """The boundaries of the selection as two cursor export + objects. So not the selected items. + The selectionExport is sorted. + See api.callbacks _setSelection for more documentation + + For the sake of simplicity a selection is only valid + if the start-tick and end-tick in all tracks are the same. + An invalid selection does not prevent the extension or + modification of a selection itself but it prevents + processing its content. + """ + #TODO: If this is a performance problem it has the potential to get cached. Functions like listOfSelectedItems can then use the cached value. + result = self.checkSelectionOrder() + if not result: + return result #empty tuple + + topLeft, bottomRight = result + startTick = topLeft["tickindex"] + endTick = bottomRight["tickindex"] + tracksWithSelectedItems = [track for track in self.tracks[topLeft["trackIndex"]:bottomRight["trackIndex"]+1]] #slice does not include the last value, so +1 + + for track in tracksWithSelectedItems: + originalPosition = track.state.position() + track.goToTickindex(startTick) #includes track.head() which resets the state + if (not track.state.tickindex == startTick): + break + track.goToTickindex(endTick) + if (not track.state.tickindex == endTick): + break + track.toPosition(originalPosition) + + else: #not executed if break. Means everything was all right. + return (True, topLeft, bottomRight) + #We only get here through a for-loop break, which means the selection is invalid. But we still export the selection boundaries for the GUI + #Reset the last track + track.toPosition(originalPosition) #has head() in it + return (False, topLeft, bottomRight) + + def listOfSelectedItems(self, removeContentLinkedData): + """ + validSelection, topLeftCursor, bottomRightCursor, listOfChangedTrackIds, *selectedTracksAndItems = returnedStuff + + Most important is the data, which is in selectedTracksAndItems and has this format: + + [ + [(object, {"keySignature": keysigobject}), (object, {"keySignature": keysigobject}), (object, {"keySignature": keysigobject}), ...], #track 1 + [(object, {"keySignature": keysigobject}), (object, {"keySignature": keysigobject}), ...], #track 2 + ] + Please note that the 2nd in the tuple, the cached track state, will be taken out by copyObjects. + If you want to create a buffer by hand (like the midi module does) just use a list of track-lists with items in it + + + Block boundaries are ignored. Just the content. + We keep the relative position to each other and the relative + tracks. + + Eleminates duplicate items. That means content-linked block.data + is only in here once. + Use this for processing, not for analysis. + Also don't depend on len() or use a for item in ... loop as + counter. + + You can deactivate this removal by setting the parameter + removeContentLinkedData to False. self.copyObjects() does this. + + There is no processing in this function. All items stay the same + and subsequently have the same durations, positions and + tickindices. + When it gets to processing you need to be careful because those + values change. The only value which is constant is the topLeft + tickindex and position. + We take care of duration-changed content linked items left of the selection as well. + """ + t = self.selectionExport() #is there a selection at all? + if not t: + return [False, None, None, [], []] #mimickes the true result. the api can use this to decide to do nothing instead of processing the selection + else: + selectionValid, topLeft, bottomRight = t + if not selectionValid: + return [False, topLeft, bottomRight, [], []] #mimics the result format. the api can use this to decide to do nothing instead of processing the selection + startTick = topLeft["tickindex"] + endTick = bottomRight["tickindex"] + seenItems = set() #keep duplicate items, aka. content link block data, out of the result. + tracksWithSelectedItems = [track for track in self.tracks[topLeft["trackIndex"]:bottomRight["trackIndex"]+1]] #slice does not include the last value, so +1 + #listOfChangedTrackIds = set([id(track) for track in tracksWithSelectedItems]) #this is not the same as tracksWithSelectedItems. It gets more ids than the initial ones here. A content-linked note outside a selected track will still be affected. We start with the trackIds we already know. + listOfChangedTrackIds = set() + finalResult = [selectionValid, topLeft, bottomRight, listOfChangedTrackIds] #listOfChangedTrackIds is mutable. It will change in the loop below + + firstRound = True + for track in tracksWithSelectedItems: + originalPosition = track.state.position() + result = [] + + if firstRound: #first track must be accurate. The user selected a specific item, find that, not the tick position which may include zero duration items + track.toItemInBlock(topLeft["item"], topLeft["block"]) + firstRound = False + else: #all other tracks are only approximations + track.goToTickindex(startTick, skipOverZeroDurations = False) #includes track.head() which resets the state + + while track.state.tickindex <= endTick: #we must use the tickindex here because we do not know the end items of the tracks + r = track.right() + if r == 1: + # the item we want is already left of the cursor. So we want the previous item. + if track.state.tickindex <= endTick: #yes, it is correct that the state in the parameter is ahead by one position. Why is it that way? Because everything that matters, like new dynamics will only be parsed afterwards. The trackState is always correct except for the tickindex when exporting after parsing. Thats why exportObject sometimes substracts its own duration for finding its starting tick. + item = track.previousItem() + if (not removeContentLinkedData) or (not item in seenItems): + result.append((item, {"keySignature" : track.state.keySignature()})) #The keysig is needed for undo operations after apply to selection + seenItems.add(item) + for parentBlock in item.parentBlocks: #TODO: just be naive and add them all for now. Performance can be improved later. + listOfChangedTrackIds.add(id(parentBlock.parentTrack)) + else: + continue + elif r == 2: #block end. Again, this is already the previous state. right now we are in the next block already. + continue + else: #When does this happen again? + break + + track.toPosition(originalPosition) #has head() in it + finalResult.append(result) + #finalResult[4:] is only lists(tracks) with items + return finalResult + + #The next two functions have "Objects" in their name so copy gets not confused with block.copy or item.copy. This is Ctrl+C as in copy and paste. + #Cut is done in the api module + + def copyObjects(self, writeInSessionBuffer = True): + """This is Ctrl+c + + Only works with valid selections. + We can assume the same tick-duration in all tracks. + We can also assume that tracks and objects are continuous. + There are no gaps in the data. + + for external functions: len(result) gives the number of tracks. + + You can just return the buffer without overwriting the clipboard if you set writeInBuffer + to False. api.duplicate uses this. + """ + #selectedItems = self.listOfSelectedItems(removeContentLinkedData = False) #list of tracks with selected objects. no block data, just the objects. + validSelection, topLeftCursor, bottomRightCursor, listOfChangedTrackIds, *selectedTracksAndItems = self.listOfSelectedItems(removeContentLinkedData = False) + result = [] + if validSelection: + for track in selectedTracksAndItems: + result.append([item.copy() for item, cachedTrackState in track]) + if writeInSessionBuffer: + self.copyObjectsBuffer = result + return result + else: + #self.copyObjectsBuffer = [] #maybe that is a bit harsh. If you press Cltr+C by accident, without a selection, you loose your copied data. This is especially bad for cut and paste + return [] + + def pasteObjects(self, customBuffer = None, overwriteSelection = True): + """This is ctrl+v + + Rules: + + If you have copied n tracks you need at least n-1 tracks below + the current. In other words: The number of tracks you copied + is the number of tracks you paste. + + There needs to be a cursor position, aka slot, at exactly the + current tickindex in all tracks you are going to paste to. + Since the copied area is always a 'rectangle' with the same + tick-duration in each track we want this to be a perfect + paste as well: everything starts and ends at the same position. + """ + if (not self.copyObjectsBuffer) and (not customBuffer): + return False + + if customBuffer: + workBuffer = customBuffer + else: + workBuffer = self.copyObjectsBuffer + + #First do a few tests if we are allowed to paste + ######################################################## + tickStart = self.currentTrack().state.tickindex + trackIndexStart = self.trackIndex + startPosition = self.where() #trackIndex, blockindex, localCursorIndexInBlock + startItem = self.currentItem() + #Check if there are enough tracks below + if len(workBuffer)+trackIndexStart > len(self.tracks): + #not enough tracks + broken = True + #Don't leave this function here because we need to return to the start position below. + else: + broken = False + + if not broken: + #Check if all tracks have a slot at our tickindex + for track in workBuffer: + curTrack = self.currentTrack() + curTrack.goToTickindex(tickStart) + if not curTrack.state.tickindex == tickStart: #no slot + #not the same tick positions + broken = True + break + self.trackDown() + else: + broken = False + + #return + #while not self.trackIndex == trackIndexStart: + # self.trackUp() + #self.currentTrack().goToTickindex(tickStart) + self.goTo(*startPosition) #has assertions as test within + + if broken: + return False + #Up to this point no modifications were made. The cursor is in the same position as it was before. + + ######################################################### + + #We are ready to paste. There are enough tracks and an empty slots at exactly the tickindex we need. + + if self.cursorWhenSelectionStarted and overwriteSelection: + listOfChangedTrackIdsFromDelete = self.deleteSelection() + #TODO: check if the cursor is still in the correct position after delete selection + + listOfChangedTrackIds = set() + + for number, track in enumerate(workBuffer): + curTrack = self.currentTrack() + #Here comes an additional condition. Most of the time pastes are single-track. If so, or we simply are in the starting track, we want to paste at the actual position, not the tickindex. This circumvents problems with block boundaries and zero-duration items. + #TODO: In the future add a "smart paste" that checks if the cursor starts at the beginning or at the end of zero duration items or a block boundary and try to match that position in the other tracks, eventhough we can't be certain if these conditions actually match + if self.trackIndex == trackIndexStart: + self.goTo(*startPosition) #has assertions as test within + else: + curTrack.goToTickindex(tickStart) + + #assert curTrack.state.tickindex == tickStart #does not work with overwrite selection + for item in track: + newItem = item.copy() + curTrack.insert(newItem) #eventhough copyObjectsBuffer is already a copy of the original notes we don't want every paste to be the same instances. + for parentBlock in newItem.parentBlocks: #TODO: just be naive and add them all for now. Performance can be improved later. + listOfChangedTrackIds.add(id(parentBlock.parentTrack)) + if not number+1 == len(workBuffer): #enumerate from 0, len from 1. + #we have to prevent the track going down one too far in the last step and messing with the tick index though. + self.trackDown() + + #once again, return to the start track and go to the final tick index. Make the cursor ready to paste again in succession. + finalTickIndex = self.currentTrack().state.tickindex + while not self.trackIndex == trackIndexStart: + self.trackUp() + assert self.trackIndex == trackIndexStart == startPosition[0] + assert self.currentTrack().state.tickindex == finalTickIndex #this is not enough to pinpoint the real location. + self.goTo(trackIndex=startPosition[0], blockindex=startPosition[1], localCursorIndexInBlock=0) + self.goToItemInCurrentBlock(startItem) #we actually want to be at the same item where we started, not just the tick index which gets confused with block boundaries and zero duration items + + try: #overwrite? + assert listOfChangedTrackIds == listOfChangedTrackIdsFromDelete + except AssertionError: + pass + except UnboundLocalError: + pass + return listOfChangedTrackIds + + + def deleteSelection(self): + """Mortals, Hear The Prophecy: Delete Selection is notoriously tricky. It was hard in Laborejo 1 and it is still hard + here. Please use as many asserts and tests as you possibly can. The next bug or regression + WILL come. And it will be here.""" + + validSelection, topLeftCursor, bottomRightCursor, listOfChangedTrackIds, *selectedTracksAndItems = self.listOfSelectedItems(removeContentLinkedData = True) + #selectedTracksAndItems format: [track1[(item, itsKeysig), (item, itsKeysig), (item, itsKeysig)], track2[(item, itsKeysig), (item, itsKeysig), (item, itsKeysig)]] + + if validSelection: + numberOfTracks = len(selectedTracksAndItems) + firstSelectedItem = selectedTracksAndItems[0][0][0] + lastSelectedItem = selectedTracksAndItems[-1][-1][0] + + #We need to find the topLeft selected item. This is NOT goToSelectionStart() which would be the actual starting point of the user, which includes bottomRight. + + #go to first selected track, starting tick position. selections are always top left to bottom right + while not self.trackIndex == topLeftCursor["trackIndex"]: + self.trackUp() + #self.currentTrack().goToTickindex(topLeftCursor["tickindex"], skipOverZeroDurations = False) + self.currentTrack().toItemInBlock(topLeftCursor["item"], topLeftCursor["block"]) #includes track.head() which resets the state + + #print ("start deleting from", topLeftCursor["item"], "to BEFORE this item", bottomRightCursor["item"]) + + assert topLeftCursor["track"] is self.currentTrack(), (topLeftCursor["track"], self.currentTrack()) + assert topLeftCursor["block"] is self.currentTrack().currentBlock(), (topLeftCursor["block"], self.currentTrack().currentBlock()) + assert topLeftCursor["item"] is self.currentTrack().currentItem(), (topLeftCursor["item"], self.currentTrack().currentItem()) + assert topLeftCursor["itemId"] == id(self.currentTrack().currentItem()), (topLeftCursor["itemId"], id(self.currentTrack().currentItem())) + if topLeftCursor["item"]: + assert topLeftCursor["item"] is firstSelectedItem, (topLeftCursor["item"], firstSelectedItem) + #else: yet unknown set of scenarios. One known is that the selection was from right to left, included normal duration items but ends on a block split which is at the tracks beginning. most likely a leftover from some deletion. + + #NO! bottomRight is not the last selected item but the first item that is not selected anymore!! assert bottomRightCursor["item"] is lastSelectedItem, (bottomRightCursor["item"], lastSelectedItem) + + assert self.currentTrack().currentBlock().localCursorIndex == topLeftCursor["localCursorIndex"], (self.currentTrack().currentBlock().localCursorIndex, topLeftCursor["localCursorIndex"]) + + firstRound = True + + for number, selectionTrack in enumerate(selectedTracksAndItems): + curTrack = self.currentTrack() + + if firstRound: #In the first track the user selected a specific item, which may be zero duration or not. We must delete this, not more not less. All other tracks are approximations and can work with the tickindex. + self.currentTrack().toItemInBlock(topLeftCursor["item"], topLeftCursor["block"]) #includes track.head() which resets the state + firstRound = False + else: + curTrack.goToTickindex(topLeftCursor["tickindex"], skipOverZeroDurations = False) + + assert curTrack.state.tickindex == topLeftCursor["tickindex"], (curTrack.state.tickindex, topLeftCursor["tickindex"]) + + #We delete always from the same cursor position. After one deletion the rest items gravitate left to our position. Except block boundaries, those will not be crossed so we have to check for them: + for item, cached6State in selectionTrack: + if item is bottomRightCursor["item"]: + break #without this the program will delete the first non-selected item, if zero duration, as well + + endOfTrackBreaker = False + while curTrack.currentBlock().isAppending(): #Block end, or even track end + if not curTrack.right(): #end of track. + endOfTrackBreaker = True + break + + if endOfTrackBreaker: + break + + assert curTrack.currentItem() is item, (curTrack.currentItem(), item) #since listOfSelectedItems already removed all duplicate items this will work. + curTrack.delete() # side effect: delete the actual item. returns none on block boundary. + + #Don't go down if we are already in the last track of the selection + if not number+1 == numberOfTracks: #enumerate from 0, len from 1. + self.trackDown() + + #assert curTrack.state.tickindex == topLeftCursor["tickindex"] We cannot be sure of this. The selection could have started at a content-linked item that got deleted and the tickindex has no item anymore + #return [id(track) for track in self.tracks] #TODO: only for debug reasons. the GUI will draw everything with this! Either this function or the api has to figure out the tracks that really changed. we could do a len check of the blocks data. + return listOfChangedTrackIds + + def getBlockAndItemOrder(self): + """ + Docstring for getBlockAndItemOrder and putBlockAndItemOrder. + + getBlockAndItemOrder creates a complete snapshot of + the whole score. Since saving tracks and blocks in the + usual musical order of magnitude is no performance-problem + for python. + + It can be put back in the score with putBlockAndItemOrder. + + We use this for undo/redo of deleteSelection and paste. + + Even after items got deleted deleteSelection, + they are still avaible to get re-inserted as long as the data + was kept around somewhere, for example in the undo/redo stack. + Effectively we discard any additional items introduced by paste + or restore lost items through deleteSelection. + This is only the order of items, not the state of the items, + but since undo/redo works lineary there can be no changes + to the items left. They would have been undone before this + step was possibly at all. + + It is very important to be aware of content-linked blocks data. + If there is such a block in the given data all tracks with its + link must be in dictWithTrackIDsAndDataLists as well, with + the data already linked again. + + This is easy when we save a complete snapshot instead of + selectively choosing tracks. However, the api callbacks + must only update tracks that really changed, not the whole + score. This would be far too expensive for a GUI. + + Other functions do not need to filter the dict when using + putBlockAndItemOrder. It looks for true changes itself + and returns a list of trackIDs that need callback updates. + + + No blocks will be deleted or replaced with this because + deleteSelection leaves empty blocks and paste is not capable + of creating new blocks. + """ + result = {} #track id, blockAndItemOrder + seen = {} # originalDataId : sliceCopy. Takes care of content linked blocks data. + + for track in self.tracks: + newWorldOrder = [] + for block in track.blocks: + blockDataId = id(block.data) + if not blockDataId in seen: + seen[blockDataId] = block.data[:] + newWorldOrder.append(seen[blockDataId]) + + result[id(track)] = newWorldOrder + return result + + def putBlockAndItemOrder(self, dictWithTrackIDsAndDataLists): + """see getBlockAndItemOrder for documentation""" + + for trackId, listWithBlocksData in dictWithTrackIDsAndDataLists.items(): + assert len(self.trackById(trackId).blocks) == len(listWithBlocksData) #paste and delete selection never delete or create blocks. So the len is always the same. we can zip + for block, parameterBlockData in zip(self.trackById(trackId).blocks, listWithBlocksData): + block.data = parameterBlockData + + return [id(track) for track in self.tracks] #TODO: only for debug reasons. the GUI will draw everything with this! Either this function or the api has to figure out the tracks that really changed. we could do a len check of the blocks data. + + def listOfTrackIds(self): + """Mostly used for the initial callback sweep after loading + a new file in the api.""" + #return Track.allTracks.keys() #this does contain deleted tracks (in the undo stack) as well. It is only valid when the program starts up. The undo stack is empty then. + #assert len (Track.allTracks) == len(self.tracks) #make sure to only call this function when it is correct. If we ever use this for non-startup reasons change to the list comprehension below. + #return Track.allTracks.keys() + return [id(track) for track in self.tracks] #tracks in the score, not in the undo stack. + + def listOfStaticTrackRepresentations(self): + """A list of tracks""" + result = [] + for track in self.tracks: + static = track.staticTrackRepresentation() + static["hiddenPosition"] = None + result.append(static) + return result + + + def listOfStaticHiddenTrackRepresentations(self): + """A list of hidden tracks. Mutually exclusive with + listOfStaticTrackRepresentations """ + + result = [] + for track, originalPosition in self.hiddenTracks.items(): + static = track.staticTrackRepresentation() + static["hiddenPosition"] = originalPosition + result.append(static) + return result + + + def graphBlockById(self, blockId): + for track in self.tracks: + for cc, graphTrackCC in track.ccGraphTracks.items(): + for graphBlock in graphTrackCC.blocks: + if id(graphBlock) == blockId: + return id(track), cc, graphBlock + else: + raise ValueError("graphBlock with this id not in any track") + + def graphItemById(self, graphItemId): + for track in self.tracks: + for cc, graphTrackCC in track.ccGraphTracks.items(): + try: + graphBlock, graphItem = graphTrackCC.graphItemById(graphItemId) + return id(track), cc, graphBlock, graphItem + except ValueError: #raised when not in thie cc/track + pass + else: + raise ValueError("graphItem with this id not in any track") + + def goTo(self, trackIndex, blockindex, localCursorIndexInBlock): + self.trackIndex = trackIndex + self.currentTrack().toBlockAndLocalCursorIndex(blockindex, localCursorIndexInBlock) + assert self.where() == (trackIndex, blockindex, localCursorIndexInBlock) + + def where(self): + """return the data needed by self.goto""" + return self.trackIndex, self.currentTrack().state.blockindex, self.currentTrack().currentBlock().localCursorIndex + + def goToItemInCurrentBlock(self, itemInstance): + """Can also be None for the next block-end/appending """ + self.currentBlock().goToItem(itemInstance) + + #Deprecated + #def goToItem(self, itemInstance): + # """aka search for item. Item instances are unique across a session""" + # this is quite expensive. Most of the time we already know the track and block. Use score.goTo with localCUrsorIndexInBlock=0 + + def allItems(self, hidden = True, removeContentLinkedData = False): + seenItems = set() + if hidden: + what = Track.allTracks.values() #this includes hidden tracks + else: + what = self.tracks + + for track in what: + for block in track.blocks: + for item in block.data: + if (not removeContentLinkedData) or (not item in seenItems): + seenItems.add(item) + yield item + + + def transposeScore(self, rootPitch, targetPitch): + """Based on intervalAutomatic""" + for item in self.allItems(removeContentLinkedData=True): + item.intervalAutomatic(rootPitch, targetPitch) + + def joinCurrentBlockAndAllContentLinks(self): + """This is in score and not in track because it works on content links across tracks as well + + Take pairs of blocks current+next and all its content links in the score and join them + together. The blocks will get the meta-information of the first block. + + a) Every content linked block to the current one is followed by + a block which is content-linked itself to all other follow-ups. + b) The current block has no content links. This is really just + special case of a) + + All content links that are followed by their own link are caught as well. + Logic dictates that at least one of the content links will have either no follow up + (end of track) or a different follow up. Both are cases that will prevent a join from + happening. + + This function does not actually join the blocks but creates new blocks that will replace + the old pairs. We then return a data structure that api.rearrangeBlocksInMultipleTracks + can use to create the new order. The old blocks are kept for undo and redo. + + dictOfTrackIdsWithListOfBlockIds is [trackId] = [listOfBlockIds] + """ + startItem = self.currentTrack().currentItem() + startBlock = self.currentTrack().currentBlock() + + workingList = [] #pairs of (block, followUpBlock) + try: + startFollowUpBlock = startBlock.parentTrack.blocks[startBlock.parentTrack.blocks.index(startBlock) +1] #the follow up for the current block. + except: + #current block already without follow up + return False #already no follow up. Leave. + + #Get the blocks which are actually in the score and not just a reference and compare their lengths. + if not len([True for strtblk in startBlock.linkedContentBlocks if strtblk._parentTrack]) == len([True for flwupblk in startFollowUpBlock.linkedContentBlocks if flwupblk._parentTrack]): + #startBlock and FollowUp content link registers do not have same length + return False + + for block in startBlock.linkedContentBlocks: #all linked blocks in all tracks, including currentBlock. All blocks are unique. The content is not. + blockIndex = block.parentTrack.blocks.index(block) + try: + followUpBlock = block.parentTrack.blocks[blockIndex +1] + except IndexError: #there is no follow up block. This violates our two requirements. + #block without follow up found + return False + else: #the block is there. continue: + if not followUpBlock in startFollowUpBlock.linkedContentBlocks: + #not all follow up blocks are the same content + return False + else: + workingList.append((block, followUpBlock)) + + #we now have made it clear that the requirements from the docstring are met. + dictOfTrackIdsWithListOfBlockIds = {} + + protoBlock = startBlock.copy(newParentTrack = self) + protoBlock.data += startFollowUpBlock.data + + for firstBlock, secondBlock in workingList: + parentTrackId = id(firstBlock.parentTrack) + + if parentTrackId in dictOfTrackIdsWithListOfBlockIds: + blockOrder = dictOfTrackIdsWithListOfBlockIds[parentTrackId] + else: + blockOrder = firstBlock.parentTrack.asListOfBlockIds() + + uniqueBlockForThisPosition = firstBlock.copy(newParentTrack = firstBlock.parentTrack) + uniqueBlockForThisPosition.name = uniqueBlockForThisPosition.name[:-5] #remove "-copy" + uniqueBlockForThisPosition.data = protoBlock.data + uniqueBlockForThisPosition.linkedContentBlocks = protoBlock.linkedContentBlocks + uniqueBlockForThisPosition.linkedContentBlocks.add(uniqueBlockForThisPosition) + + assert id(uniqueBlockForThisPosition) in Block.allBlocks + blockOrder[blockOrder.index(id(firstBlock))] = id(uniqueBlockForThisPosition) + assert not id(firstBlock) in blockOrder + + #We don't need to actually delete the blocks here, this will be done indirectly by rearrangeBlocks through the api later. + blockOrder.remove(id(secondBlock)) + assert not id(secondBlock) in blockOrder + + dictOfTrackIdsWithListOfBlockIds[parentTrackId] = blockOrder #eventhough it is mutable and therefore changes in the list are reflected in the dict-value we did not make sure that the list is in the dict in the first place above. + + protoBlock.linkedContentBlocks.remove(protoBlock) + del(protoBlock) + + return dictOfTrackIdsWithListOfBlockIds + + + def splitCurrentBlockAndAllContentLinks(self): + """split the current block around the cursor position. + If used in an appending position it just creates a new block. + + The new block gets inserted directly right of + each original content-linked block. + + For the user this looks like all contentLinked blocks got + splitted in half, but they remain content linked. + """ + + track = self.currentTrack() + startBlock = track.currentBlock() #this is the only unique thing we can rely on. + + dictOfTrackIdsWithListOfBlockIds = {} # [trackId] = [listOfBlockIds] + + protoBlockLeft = startBlock.copy(track) + protoBlockLeft.data = startBlock.data[:startBlock.localCursorIndex] #everything left of the cursor. The local cursor index of the current block is guaranteed to be correct. The one from other blocks is not. + + protoBlockRight = startBlock.copy(track) + protoBlockRight.data = startBlock.data[startBlock.localCursorIndex:] #everything right of the cursor. The local cursor index of the current block is guaranteed to be correct. The one from other blocks is not. + + + for block in startBlock.linkedContentBlocksInScore(): #all linked blocks in all tracks, including currentBlock. All blocks are unique. The content is not. + parentTrackId = id(block.parentTrack) + if parentTrackId in dictOfTrackIdsWithListOfBlockIds: + blockOrder = dictOfTrackIdsWithListOfBlockIds[parentTrackId] + else: + blockOrder = block.parentTrack.asListOfBlockIds() + + newLeft = protoBlockLeft.contentLink() + newLeftId = id(newLeft) + newLeft.name = block.name + newLeft.minimumInTicks = block.minimumInTicks / 2 + assert newLeftId in Block.allBlocks + assert newLeft.parentTrack is block.parentTrack + assert newLeft in protoBlockLeft.linkedContentBlocks + + newRight = protoBlockRight.contentLink() + newRightId = id(newRight) + newRight.name = block.name + newRight.minimumInTicks = newLeft.minimumInTicks + assert newRightId in Block.allBlocks + assert newRight.parentTrack is block.parentTrack + assert newRight in protoBlockRight.linkedContentBlocks + + positionToInsert = blockOrder.index(id(block)) + + blockOrder[positionToInsert] = newLeftId #replaces the original block which will be kept intact for undo + blockOrder.insert(positionToInsert + 1, newRightId) + + dictOfTrackIdsWithListOfBlockIds[parentTrackId] = blockOrder #eventhough it is mutable and therefore changes in the list are reflected in the dict-value we did not make sure that the list is in the dict in the first place above. + + protoBlockLeft.linkedContentBlocks.remove(protoBlockLeft) #probably redundant. But makes the intention clear. + protoBlockRight.linkedContentBlocks.remove(protoBlockRight) + del(protoBlockLeft) + del(protoBlockRight) + + return dictOfTrackIdsWithListOfBlockIds + + def removeEmptyBlocks(self): + dictOfTrackIdsWithListOfBlockIds = {} # [trackId] = [listOfBlockIds] + + for trId, track in Track.allTracks.items(): + listOfBlockIds = track.asListOfBlockIds() + for block in track.blocks: + if not block.data and len(track.blocks) > 1: + listOfBlockIds.remove(id(block)) + dictOfTrackIdsWithListOfBlockIds[trId] = listOfBlockIds + return dictOfTrackIdsWithListOfBlockIds + + def lilypond(self): + """Entry point for converting the score into lilypond. + Called by session.saveAsLilypond(), returns a string, which is the file content. + + What is happening here? + Only visible tracks get exported. + Each object controls what it exports. Overrides are possible at every level. + """ + tempoStaff = self.tempoTrack.lilypond() + data = {track:track.lilypond() for track in self.tracks} #processed in the lilypond module + return fromTemplate(session = self.parentSession, templateFile = "default.ly", data = data, meta = self.metaData, tempoStaff = tempoStaff) + + + + + #Save / Load / Export + @classmethod + def instanceFromSerializedData(cls, serializedObject, parentObject): + """This does not call init. We need to construct it + from a blank slate.""" + assert cls.__name__ == serializedObject["class"] + self = cls.__new__(cls) + + self._secondInit() + return self + + + def serialize(self)->dict: + dictionary = super().serialize() + dictionary["class"] = self.__class__.__name__ + dictionary["tracks"] = [track.serialize() for track in self.tracks] + #we can't save hiddenTracks as dict because the serialized track is a dict itself, which is not hashable and therefore not a dict-key. + dictionary["hiddenTracks"] = [[track.serialize(), originalIndex] for track, originalIndex in self.hiddenTracks.items()] + dictionary["tempoTrack"] = self.tempoTrack.serialize() + dictionary["metaData"] = self.metaData + return dictionary + + @classmethod + def instanceFromSerializedData(cls, parentSession, serializedData): + assert cls.__name__ == serializedData["class"] + self = cls.__new__(cls) + super().copyFromSerializedData(parentSession, serializedData, self) #Tracks, parentSession and tempoMap + self.parentSession = parentSession + self.hiddenTracks = {Track.instanceFromSerializedData(track, parentData = self):originalIndex for track, originalIndex in serializedData["hiddenTracks"]} + self.tempoTrack = TempoTrack.instanceFromSerializedData(serializedData["tempoTrack"], parentData = self) + self.metaData = serializedData["metaData"] + self._processAfterInit() + return self + + def export(self)->dict: + dictionary = super().export() + + return { + "numberOfTracks" : len(self.tracks), + "howManyUnits" : self.howManyUnits, + "whatTypeOfUnit" : self.whatTypeOfUnit, + "numberOfMeasures" : self.numberOfMeasures, + "measuresPerGroup" : self.measuresPerGroup, + "subdivisions" : self.subdivisions, + "isTransportMaster" : self.tempoMap.export()["isTransportMaster"], + } + diff --git a/engine/oldmidi.py b/engine/oldmidi.py new file mode 100644 index 0000000..26aaba6 --- /dev/null +++ b/engine/oldmidi.py @@ -0,0 +1,52 @@ + + +class MidiState(object): + """Various data to keep track what midi in looks like currently""" + def __init__(self): + self.midiInIsActive = False + self.ccState = {} + for cc in range(0,127): + self.ccState[cc] = None #start with undefined. + self.firstActiveNote = None #for chord entry. + self.cboxMidiPortUid = None #the INPUT midi in port. set in startMidiModule + self.currentOutputMidiPortUid = None #set in self.setMidiThrough. This changes with the active track + self.scene = cbox.Document.get_engine().new_scene() + self.scene.clear() + + def toggleMidiIn(self): + self.midiInIsActive = not self.midiInIsActive + if self.midiInIsActive: + #CachedTrackDuration is a dict and never cleared completely. So our midiIn will never get touched + #We hope that nobody uses the PortUid as a track name by chance :) + api.session.data.cachedTrackDurations[self.cboxMidiPortUid] = api.DINF + else: + api.session.data.cachedTrackDurations[self.cboxMidiPortUid] = 0 + + finalizeRecordingBuffer() + api.callbacksDatabase._prevailingBaseDurationChanged(api.session.data.cursor.prevailingBaseDuration) + + def updateCCState(self, ccNumber, ccValue): + assert 0 <= ccValue <= 127 + self.ccState[ccNumber] = ccValue + + def setMidiThrough(self, cursorExport): + """ + Instruct the RT part to echo midi in directly to the connect output ports so we hear the current track with the tracks instrument. + Added to the cursorChanged api callback""" + if not self.currentOutputMidiPortUid == cursorExport["cboxMidiOutUuid"]: #most of the time this stays the same e.g. cursor left/right. we only care about up and down + self.currentOutputMidiPortUid = cursorExport["cboxMidiOutUuid"] + cbox.JackIO.route_midi_input(midiState.cboxMidiPortUid, cursorExport["cboxMidiOutUuid"]) + +def startMidiModule(pApi): + global api + api = pApi + + #global midiState + #midiState = MidiState() + + midiState.cboxMidiPortUid = cbox.JackIO.create_midi_input("in") + cbox.JackIO.set_appsink_for_midi_input(midiState.cboxMidiPortUid, True) #This sounds like a program wide sink, but it is needed for every port. + cbox.JackIO.route_midi_input(midiState.cboxMidiPortUid, midiState.scene.uuid) + #midiState.currentOutputMidiPortUid = api.session.data.cursorExport()["cboxMidiOutUuid"] #TODO. Im cursor habn ich das deaktiviert. + #api.callbacks.setCursor.append(midiState.setMidiThrough) #TODO. Das brauchen wir damit wir das verknüpfte instrument vom track hören. + return processMidiIn diff --git a/engine/resources/LICENSE b/engine/resources/LICENSE new file mode 100644 index 0000000..7f73629 --- /dev/null +++ b/engine/resources/LICENSE @@ -0,0 +1 @@ +Licenses for 3rd party resources can be found in text files with the same name as the resource. diff --git a/engine/resources/lilypondTemplate/default.ly b/engine/resources/lilypondTemplate/default.ly new file mode 100644 index 0000000..49f9b89 --- /dev/null +++ b/engine/resources/lilypondTemplate/default.ly @@ -0,0 +1,105 @@ +%% LilyPond-File generated by Laborejo - http://www.laborejo.org +%% Generation Date: %$$DATE$$ +%% Filename: %$$FILENAME$$ + +\version "2.18" +#(set-default-paper-size "a4") +#(set-global-staff-size 18 ) +#(ly:set-option 'point-and-click #f) + +\paper { + print-all-headers = ##f + %scoreTitleMarkup = ##f + + %Print small title on every page. + oddHeaderMarkup = \markup + \fill-line { + \on-the-fly #not-first-page \fromproperty #'header:title + \on-the-fly #not-first-page \fromproperty #'header:instrument + %"" % This will make sure that the header is never completely empty, to + % avoid some layout problems. Also, moving it in between the title and + % the page number, makes these be typeset left and right aligned, respectively. + \on-the-fly #not-first-page \on-the-fly #print-page-number-check-first \fromproperty #'page:page-number-string + } + + evenHeaderMarkup = \markup + \fill-line { + \on-the-fly #print-page-number-check-first \fromproperty #'page:page-number-string + \fromproperty #'header:instrument + \fromproperty #'header:title + } + +} + +\header{ + %$$HEADER$$ +} + +correctFraction = #(lambda (grob) + (let ((ev (event-cause grob))) + (if (and (= (ly:event-property ev 'numerator) 2) (= (ly:event-property ev 'denominator) 3)) + + (format #f "~a" 3) + + (format #f "~a/~a" + (ly:event-property ev 'numerator) + (ly:event-property ev 'denominator)) + ))) + + +\layout{ + %ragged-right = ##t + \context { \Score + \override TupletNumber #'text = \correctFraction %traditional but wrong: #tuplet-number::calc-fraction-text + \override Fingering #'add-stem-support = ##t + \override StringNumber #'add-stem-support = ##t + \override StrokeFinger #'add-stem-support = ##t + %Dynamics + \override Hairpin #'to-barline = ##f + \override DynamicLineSpanner #'staff-padding = #2.0 + \override DynamicLineSpanner #'Y-extent = #'(-1.5 . 1.5) + \override TextScript #'Y-extent = #'(-1.5 . 1.5) + \override PaperColumn #'keep-inside-line = ##t + %Remove engraver here and add them in context staff to make multiple timesigs possible. This deactivates barnumbers! + %\remove "Timing_translator" + %\remove "Default_bar_line_engraver" + %\override Tie #'details #'ratio = #2 + } + \context { \Voice + %Exchange note_heads_engraver with the completition variant which auto-ties notes on bar-breaks + \remove "Note_heads_engraver" + \consists "Completion_heads_engraver" + tieWaitForNote = ##t + } + \context { \Staff + \RemoveEmptyStaves + %\override VerticalAxisGroup #'remove-first = ##t + \override TimeSignature #'style = #'numbered + + %Commenting the following two lines in again, together with the revmoval in \score enables mutli-timesig mode. But disables barnumbers. + %\consists "Timing_translator" + %\consists "Default_bar_line_engraver" + + \override NoteHead #'style = #'baroque %breve and longa are squared. + } +} + + +%Music definitions. Containers, Staff, Parts. +tempoStaff = { %$$TEMPOSTAFF$$ } + +%$$VOICES$$ + +\score{ +<< +%How the definitions are arranged. Only staffgroups (staff prefix) and staffs, merged as voices. +\accidentalStyle Score.neo-modern-voice +%$$STRUCTURE$$ +>>} + +\markup{ + %\column { + %$$SUBTEXT$$ + %} +} + diff --git a/engine/resources/lilypondTemplate/minimal.ly b/engine/resources/lilypondTemplate/minimal.ly new file mode 100644 index 0000000..81965b8 --- /dev/null +++ b/engine/resources/lilypondTemplate/minimal.ly @@ -0,0 +1,17 @@ +%% LilyPond-File generated by Laborejo - http://www.laborejo.org +%% Generation Date: %$$DATE$$ +%% Filename: %$$FILENAME$$ + +\version "2.18" +#(ly:set-option 'point-and-click #f) + +%Music definitions. Containers, Staff, Parts. +%$$VOICES$$ + +\score {<< +%How the definitions are arranged. Only staffgroups (staff prefix) and staffs, merged as voices. +%$$STRUCTURE$$ +>>} + +%no subtext + diff --git a/engine/resources/normal.wav b/engine/resources/normal.wav new file mode 100644 index 0000000000000000000000000000000000000000..ae57da1d0951b136aef363062b3eff0a68c1193d GIT binary patch literal 133692 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

3Ue1$+j@KG%Bkv!)TewH_F@KFRQWxa@ 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 literal 0 HcmV?d00001 diff --git a/engine/resources/stressed.wav b/engine/resources/stressed.wav new file mode 100644 index 0000000000000000000000000000000000000000..6463e758aceb6cac32d9dff70010b47cf8ebbe75 GIT binary patch literal 106120 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 F`oF%Dha><1 literal 0 HcmV?d00001 diff --git a/engine/track.py b/engine/track.py new file mode 100644 index 0000000..7bc62e6 --- /dev/null +++ b/engine/track.py @@ -0,0 +1,1161 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2019, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), +more specifically its template base application. + +The Template Base Application 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 . +""" + +import logging; logging.info("import {}".format(__file__)) + +#Standard Library Modules +from weakref import WeakKeyDictionary, WeakValueDictionary +from collections import OrderedDict + +#Third Party Modules + +#Template Modules +import template.engine.sequencer + +#Our modules +from .block import Block +from .graphtracks import GraphTrackCC +from .items import * #parseRight and trackState need all items. + +class DynamicSettingsSignature(object): + """Holds the meaning of dynamic keywords for one track. + Only used once per Track. Cannot be inserted. + + Each track needs a different one because "Forte" for a brass instrument + has a different meaning than for a string instruments. Tracks + are instruments. + + Do not confuse with trackState.dynamicSignatures, which is + a stack of actual dyn-signatures like "forte". + """ + def __init__(self): + #self.dynamics = filled in by self.reset + self.reset() + self._secondInit(parentTrack = None) + + def reset(self): + """Reset to the programs default values. + This is a function and not in init because the api wants to reset as well.""" + self.dynamics = { #This is a dict instead of direct values so that dynamicSignature can use a string keyword to get their value and don't have to use getattr(). + "ppppp":15, + "pppp":31, + "ppp":43, + "pp":53, + "p":69, + + "mp":77, + "mf":90, + + "f":98, + "ff":108, + "fff":116, + "ffff":127, + + "custom":64, + + "tacet":0, + + "fp":98, + "sf":98, + "sff":108, + "sp":69, + "spp":53, + "sfz":116, + #TODO: accent > ? + } + + def __setattr__(self, name, value): + super().__setattr__(name, value) + self.sanityCheck() + + def _secondInit(self, parentTrack): + """see Item._secondInit""" + #ignore parentTrack + pass + + @classmethod + def instanceFromSerializedData(cls, serializedData, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedData["class"] + self = cls.__new__(cls) + self.dynamics = {key:int(value) for key, value in serializedData["dynamics"].items()} + self._secondInit(parentTrack = parentObject) + return self + + def serialize(self): + result = {} + result["class"] = self.__class__.__name__ + result["dynamics"] = self.dynamics + return result + + def copy(self): + """ + Since there is only one DynSig, directly in the track, + this copy is only called when doing a track-copy which copies + the track itself. + """ + new = DynamicSettingsSignature() + new.dynamics = self.dynamics.copy() + return new + + def sanityCheck(self): + for key, value in self.dynamics.items(): + if not 0 <= value <= 127: + warn("Dynamic {} of value {} not allowed. Choose a dynamic between 0 and 127. Now set to 0, please edit manually.".format(key, value)) + self.dynamics[key] = 0 + +class DurationSettingsSignature(object): + """Only used once per Track. Cannot be inserted, is already in the track. + Can and should be modified though.""" + + class DurationMod(object): + """A descriptor that converts a string to a function + and checks if a duration mod string is valid. + + We need this as descriptor because we want the user to change a dur-sig by writing a new + calculation in string form as e.g. defaultOff. Each time a new string is set we create + a new DurationMod which holds the evaluated calculation as a function, which was tested if + valid.""" + + class EvaluatedFunction(object): + """This is a callable class as substitute for a function. We need this as a class + to get the __str__ parameter since we use strings as a method of user input. + These strings get saved and loaded. + """ + def __init__(self, string): + try: + testFunction = lambda x: eval(string) + testFunction(D4) + self.evaluated = lambda x: eval(string) + self.string = string + self.evaluated.__str__ = self.__str__ + except Exception as err: + warn("Syntax Warning: duration processing not possible. Only 'x' and numbers are allowed for calculations. Please check your input: {} ".format(string)) + self.string = string + self.evaluated = lambda x: 0 + + def __call__(self, parameter): + return self.evaluated(parameter) + + def __str__(self): + return self.string + + def __init__(self): + self.data = WeakKeyDictionary() + + def __get__(self, instance, owner): + # we get here when someone calls instance.attribute, and attribute is a DurationMod instance + #return self.data.get(instance) + return self.data[instance] + + def __set__(self, instance, string): + # we get here when someone calls instance.attribute = val, and attribute is a DurationMod instance + self.data[instance] = self.EvaluatedFunction(string) + + #Descriptors belong in the class scope + defaultOn = DurationMod() + defaultOff = DurationMod() + staccatoOn = DurationMod() + staccatoOff = DurationMod() + tenutoOn = DurationMod() + tenutoOff = DurationMod() + legatoOn = DurationMod() + legatoOff = DurationMod() + + def __init__(self): + """-On- means the modification on the left side of a note duration, + -off- means the right side. + Note on and off. + + All values will be added to the start/end of the notes duration. Since the start as always + "0" in this reference frame you essentially set the note on here. + + Duration keywords like D4 are supported. + The special variable "x" will be provided in the scope to be used in the string. + + Examples: + "0" means no change. + + defaultOn= "D8" will result in a duration starting an eighth later than expected + + defaultOff = "-0.10 * x" will evaluate to negative 10% of the original duration (x) which + will then be added to the original duration, resulting in the note off to be 10% less than + normally. However, that scales quite unnaturally to large duration and we better use + a fixed offset. + + If you want to set your duration, e.g. note off, to an absolute value start by adding the + negative original duration and build up from there. "-1*x + D8" always results in an eigth + note duration. + """ + + self.reset() #fills in all our values + self._secondInit(parentTrack = None) + + + def reset(self): + """This is not in init because the api wants to reset as well""" + self.defaultOn = "0" + self.defaultOff = "-1 * D64 if x <= D16 else -1 * D32" + self.staccatoOn = "0" + self.staccatoOff = "-1 * x + D128" + self.tenutoOn = "0" + self.tenutoOff = "0" + self.legatoOn = "0" #for slurs + self.legatoOff = "D128" #overlap + + def _secondInit(self, parentTrack): + """see Item._secondInit""" + #ignore parentTrack + pass + + @classmethod + def instanceFromSerializedData(cls, serializedData, parentObject): + """see Score.instanceFromSerializedData""" + assert cls.__name__ == serializedData["class"] + self = cls.__new__(cls) + self.defaultOn = str(serializedData["defaultOn"]) + self.defaultOff = str(serializedData["defaultOff"]) + self.staccatoOn = str(serializedData["staccatoOn"]) + self.staccatoOff = str(serializedData["staccatoOff"]) + self.tenutoOn = str(serializedData["tenutoOn"]) + self.tenutoOff = str(serializedData["tenutoOff"]) + self.legatoOn = str(serializedData["legatoOn"]) + self.legatoOff = str(serializedData["legatoOff"]) + self._secondInit(parentTrack = parentObject) + return self + + def serialize(self): + result = {} + result["class"] = self.__class__.__name__ + result["defaultOn"] = str(self.defaultOn) + result["defaultOff"] = str(self.defaultOff) + result["staccatoOn"] = str(self.staccatoOn) + result["staccatoOff"] = str(self.staccatoOff) + result["tenutoOn"] = str(self.tenutoOn) + result["tenutoOff"] = str(self.tenutoOff) + result["legatoOn"] = str(self.legatoOn) + result["legatoOff"] = str(self.legatoOff) + return result + + def copy(self): + #Strings are not mutable so they are just copied by new assignment + #Also the strings will trigger the creation of new functions immediately + new = DurationSettingsSignature() + new.defaultOn = str(self.defaultOn) + new.defaultOff = str(self.defaultOff) + new.staccatoOn = str(self.staccatoOn) + new.staccatoOff = str(self.staccatoOff) + new.tenutoOn = str(self.tenutoOn) + new.tenutoOff = str(self.tenutoOff) + new.legatoOn = str(self.legatoOn) + new.legatoOff = str(self.legatoOff) + return new + +class TrackState(object): + """TrackState stays not the same for one track but gets recreated, at least in track.head(). + This means init is always position 0.""" + + #in init these will get recreated all the time. This confuses cashing and hashing + defaultClef = Clef("treble") + defaultDynamicSignature = DynamicSignature("custom") + defaultMetricalInstruction = MetricalInstruction(tuple(), isMetrical = False) + defaultKeySignature = KeySignature(20, [0,0,0,0,0,0,0]) + + def __init__(self, track): + self.track = track + self.tickindex = 0 #The tickindex has no metrical connection. It doesn't care about upbeats, barlines or timesigs. + self.ticksSinceLastMeasureStartLive = -1*track.upbeatInTicks + self.blockindex = 0 + self.ticksSinceLastMeasureStart = 0 #Only for export. + self.barlines = [] #a list of ints/tickpositions. These are the non-editable, non-movable single barlines. + #stacks. There is always one item left in the stack, the default: + self.keySignatures = [self.defaultKeySignature] #C Major + self.clefs = [self.defaultClef] + self.metricalInstructions = [self.defaultMetricalInstruction] #no barlines, no metrical information. + self.dynamicSignatures = [self.defaultDynamicSignature] + self.dynamicRamp = None #Not for cursor movement so it is not a stack. + self.EXPORTtiedNoteExportObjectsWaitingForClosing = {} #pitch:noteExportObject . Empty during cursor movement, filled during export. + self.duringLegatoSlur = False #there are no nested legato slurs + self.duringBeamGroup = False #no nested beam groups. + self.midiChannels = [track.initialMidiChannel] #these are just integers, not items. items.ChannelChange parsing changes this and items automatically get the new value. A stack of midi channels allows the cursor to know the current channel for immediate playback/feedback. + self.instrumentChanges = [InstrumentChange(track.initialMidiProgram, track.initialMidiBankMsb, track.initialMidiBankLsb, track.initialInstrumentName, track.initialShortInstrumentName, )] + self.midiTranspose = track.midiTranspose + + # TODO: When a change item for the following functions is introduced they need to get parsed in track.parseLeft and track.parseRight + + def position(self): + """The position in the track""" + #[0, 1, 2, 3][:3] means slice item 0, 1, 2 but not include 3. + result = 0 + for block in self.track.blocks[:self.blockindex]: #all blocks without the current one. + #TODO: the following assert fails. somewhere in the code the local cursor index gets not updated properly. most likely in insert, delete or track.tail, track.head + #This is the reason why inserting in contend linket blocks results in the wrong cursor position if we rely on keeping track of the track position manually or using the local block positions. We can only rely on the current one. + #assert len(block.data) == block.localCursorIndex #does not hold for the current block because it was not completely traversed yet. + result += len(block.data) + 1 #+1 for the appending position + result += self.track.currentBlock().localCursorIndex #finally add the position in the current block which is somewhere in the middle or so. at least not the same as len(currentBlock) + return result + + def index(self): + if self.track in self.track.parentData.tracks: + return self.track.parentData.tracks.index(self.track) + else: + return None #hidden + + def clef(self): + return self.clefs[-1] + + def keySignature(self): + return self.keySignatures[-1] + + def metricalInstruction(self): + return self.metricalInstructions[-1] + + def dynamicSignature(self): + return self.dynamicSignatures[-1] + + def midiChannel(self): + return self.midiChannels[-1] + + def instrumentChange(self): + return self.instrumentChanges[-1] + + def isAppending(self): + """Return if the cursor is on the end of a block (which is + also the end of the track)""" + return self.track.currentBlock().isAppending() + + + #You cannot cache the trackState, especially not keysignatures. Leave this in as a reminder. + #An item can be in two blocks which places it in two different contexts/states. If you want to know the context of an item you really have to put the cursor on it. + def createCached(self): + """Create a static version of the current state which can be + put into items. Apply to selection does not have to do a local + cursor walk then to get keysigs. + This does not change anything for the items. They still get a + keysig as parameter, if they need it. The alternative would be + to let the item get the cached version themselves. That is not + versatile enough for complex musical operations. + The cache is created during track.staticRepresentation so we + can be sure that it is always up-to-date. + + The format and the names are different as well. You cannot + use a cached trackState as a drop-in replacement for the real state. + """ + #TODO: for now we only cache values that we know we need. This should keep this function under control and prevent misuse from lazyness, like explained in the docstring. + #return { + # "keySignature" : self.keySignatures[-1], + #} + pass + +class Track(object): + allTracks = WeakValueDictionary() #key is the trackId, value is the weak reference to the Track. Deleted tracks (from the current session) and hidden tracks are in here as well. + + def __repr__(self) -> str: + return f"Laborejo Track: {self.sequencerInterface.name}" + + def __init__(self, parentData, name=None): + self.parentData = parentData + self.sequencerInterface = template.engine.sequencer.SequencerInterface(parentTrack=self, name=name) + + self.ccGraphTracks = {} #cc number, graphTrackCC.d + self.ccChannels = tuple() #numbers from 0-15 which represent the midi channels all CCs are sent to. Only replaced by a new tuple by the user directly. From json this becomes a list, so don't test for type. If empty then CC uses the initial midi channel. + + self.blocks = [Block(track = self)] + self.durationSettingsSignature = DurationSettingsSignature() #only one per track + self.dynamicSettingsSignature = DynamicSettingsSignature() #only one per track + self.upbeatInTicks = 0 #playback does not care about upbeats. But exporting does. for example barlines. + self.double = False #if true add 5 stafflines extra below. Clef will always stay in the upper staff. This is a representation-hint. E.g. a gui can offer a bigger staff system for the user. + + #A set of starting values. They are user editable and represent the tracks playback state on head(). Therefore they get saved. + self.initialMidiChannel = 0 # 0-15 + self.initialMidiProgram = -1 # 0-127. -1 is "don't send" + self.initialMidiBankMsb = 0 # 0-127. Depends on program >= 0 + self.initialMidiBankLsb = 0 # 0-127. Depends on program >= 0 + self.midiTranspose = 0 # -127 to +127 but the result is never outside of 0-127.1 Cannot change during the track. + + #The instrument names are also handled by the trackState so that the cursor knows about instrument changes + self.initialInstrumentName = "" #different than the track name. e.g. "Violin" + self.initialShortInstrumentName = "" # e.g. "vl" + + self._processAfterInit() + + def _processAfterInit(self): + """Call this after either init or instanceFromSerializedData""" + self.state = TrackState(self) + Track.allTracks[id(self)] = self #remember track as weakref + #weakref_finalize(self, print, "deleted track "+str(id(self))) + + + @property + def hidden(self): + """Is this editable or read-only (and not shown in a possible GUI). + hidden still emits playback and exports to other formats""" + return not self in self.score.tracks + + @property + def name(self): + return self.sequencerInterface.name + + @name.setter + def name(self, newValue): + self.sequencerInterface.name = newValue + + def duration(self): + """Return the duration of the whole track, in ticks""" + result = 0 + for block in self.blocks: + result += block.duration() + return result + + def listOfCCsInThisTrack(self): + return list(self.ccGraphTracks.keys()) + + def appendBlock(self): + new = Block(self) + self.blocks.append(new) + return new + + def appendExistingBlock(self, block): + block.parentTrack = self + self.blocks.append(block) + + def deleteBlock(self, block): + """Undo of deleteBlock is rearrange blocks.""" + if len(self.blocks) > 1: + originalPosition = self.state.position() + #block.parentTrack = None We keep the parent track for undo. Through the linear nature of undo it is guaranteed that the track instance will still exists when this delete attempts undo. + self.blocks.remove(block) #eventhough this must be undone we cannot keep the deleted block in self.blocks. Self.blocks is designed for only active blocks. + block.parentTrack = None + self.toPosition(originalPosition, strict = False) #has head() in it. strict=False just leaves the cursor at head if we can't return to the position because it got deleted. + return self, block #self is parent Track + + def currentBlock(self): + block = self.blocks[self.state.blockindex] + return block + + def duplicateBlock(self, block): + originalPosition = self.state.position() + index = self.blocks.index(block) + copy = block.copy(newParentTrack = self) + self.blocks.insert(index +1, copy) + self.toPosition(originalPosition) #has head() in it + + def duplicateContentLinkBlock(self, block): + originalPosition = self.state.position() + index = self.blocks.index(block) + linked = block.contentLink() + self.blocks.insert(index +1, linked) + self.toPosition(originalPosition) #has head() in it + + def hasContentLinks(self): + return any(len(block.linkedContentBlocks) > 1 for block in self.blocks) + + def asListOfBlockIds(self): + """Return an ordered list of block ids""" + result = [] + for block in self.blocks: + result.append(id(block)) + return result + + def rearrangeBlocks(self, listOfBlockIds): + """Reorder the blocks in this track. + Achtung! Not including a block will delete this block. + + Undo is done by the api.""" + + originalPosition = self.state.position() + #blocksDict = self.blocksAsDict() + newBlockArrangement = [] + + #first remove all parent tracks from the current blocks. They will be added later again for the tracks that really stay in the track. + + for block in self.blocks: + block.parentTrack = None + + for idLong in listOfBlockIds: + actualBlock = Block.allBlocks[idLong] + actualBlock.parentTrack = self + newBlockArrangement.append(actualBlock) + #This also checks if there are IDs which match no blocks. allBlocks includes deleted ones for undo as well. + + #a block is a unique unit in Laborejo2. Let's make sure there are no duplicates. + #http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order + seen = set() + seen_add = seen.add + self.blocks = [ x for x in newBlockArrangement if x not in seen and not seen_add(x)] + + assert self.blocks + #The old position may not exist anymore (block moved to other track) but we can at least try (strict = False) to return to it. + self.toPosition(originalPosition, strict = False) #has head() in it. + + def blocksAsDict(self): + """Key is the block id, value the block instance""" + result = {} + for block in self.blocks: + result[id(block)] = block + return result + + def head(self): + """no left-parsing needed. The beginning of a track + has always the same parameters, an empty TrackState.""" + for block in self.blocks: + block.head() + self.state = TrackState(self) + + def tail(self): + """no shortcuts. Parse right till the end, parsing every + item on its way.""" + while self.right(): + True + assert self.currentItem() is None #appending position + + def left(self): + if self.currentBlock().left(): #side effect: actual moving + self.parseLeft() + assert self.state.position() >= 0 + return 1 + elif self.state.blockindex > 0: + blockBeforeCrossing = self.currentBlock() + self.state.blockindex -= 1 + assert not blockBeforeCrossing is self.currentBlock() + assert self.currentBlock() is self.blocks[self.state.blockindex] + self.currentBlock().tail() #in case we have a block multiple times in the track this resets it from the last time we traversed it + #block end. This is already the next state. right now we are in the next block left already. + #instead of parsing left: + lastBlock = self.blocks[self.state.blockindex] + self.state.tickindex -= lastBlock.staticExportEndMarkerDuration() + return 2 #moving succeeded, but no Item was returned. This is a gap between two blocks. + else: + return 0 + #track beginning + + def right(self): + if self.currentBlock().right(): #side effect: actual moving + self.parseRight() + return 1 + elif self.state.blockindex+1 < len(self.blocks): #block counts from 0, len from 1. If block+1 is smaller than the amount of blocks this means this is not the final block. + #block end. This is already the previous state. right now we are in the next block already. + self.state.blockindex += 1 + self.currentBlock().head() #in case we have a block multiple times in the track this resets it from the last time we traversed it + #instead of parsing right: + lastBlock = self.blocks[self.state.blockindex-1] + self.state.tickindex += lastBlock.staticExportEndMarkerDuration() #why -1? see comment above + return 2 #moving succeeded, but no Item was returned. This is a gap between two blocks. + else: + return 0 + #track end + + def measureLeft(self): + """We don't use goToTickIndex for this because that + is a slow function that starts from head()""" + goalInTicks = self.state.tickindex - self.state.metricalInstruction().oneMeasureInTicks + + while self.left(): + if self.state.tickindex <= goalInTicks: + break + + def measureRight(self): + """We don't use goToTickIndex for this because that + is a slow function that starts from head()""" + if type(self.currentItem()) is MetricalInstruction: #this mostly happens in the beginning of a track when the metrical instruction is the first item + goalInTicks = self.state.tickindex + self.currentItem().oneMeasureInTicks + else: + goalInTicks = self.state.tickindex + self.state.metricalInstruction().oneMeasureInTicks + + while self.right(): + if self.state.tickindex >= goalInTicks: + break + + def measureStart(self): + if self.state.ticksSinceLastMeasureStartLive < 0: #upbeats are lower than 0 + while not self.state.ticksSinceLastMeasureStartLive == 0: + self.right() + else: + while not self.state.ticksSinceLastMeasureStartLive <= 0: + self.left() + while self.left(): #stops automatically at the beginning of the track + if self.currentItem().logicalDuration() > 0 or not self.state.ticksSinceLastMeasureStartLive == 0: #we found the boundary between this measure and the one before it + self.right() + break + else: + self.head() + + def startOfBlock(self): + currentBlock = self.currentBlock() #we stay in this block so this doesn't need to change. + while not currentBlock.localCursorIndex == 0: + self.left() + + def endOfBlock(self): + """Go to the end of this block""" + currentBlock = self.currentBlock() #we stay in this block so this doesn't need to change. + while not currentBlock.isAppending(): + self.right() + + def goToTickindex(self, targetTickIndex, skipOverZeroDurations = True): + """Used for moving the active Track up/down. + If you want to go to a specific position, use the normal + item index.""" + #if not targetTickIndex == self.state.tickindex: #we are already there? #TODO: this is purely for performance. Leave it out until profiling. + + self.head() #resets everything, including the state. + while self.state.tickindex < targetTickIndex: + if not self.right(): #track ends? very well. + break + + if skipOverZeroDurations: + while self.currentItem() and self.currentItem().logicalDuration() == 0: #skip over zero-duration items to find the next likely edit point + self.right() + + return True + + def toPosition(self, position, strict = True): + """wants track.state.position() as parameter""" + self.head() + while not self.state.position() == position: + if not self.right(): + if strict: + raise ValueError("Position does not exist in track", position, self) + else: + self.head() + break + + def toBlockAndLocalCursorIndex(self, blockindex, localCursorIndex): + """A very good way to find a position, while looking the other + way if the item at this position is indeed the item we are + looking for or maybe just a copy. + + Remember: Blocks are unique! Items are are only + unique within a block""" + self.head() + while True: + if self.state.blockindex == blockindex and self.currentBlock().localCursorIndex == localCursorIndex: #self.currentBlock() is only executed if the blockindex is already correct + return True + else: + if not self.right(): #end of track + raise RuntimeError("Position or block not found. Either the block has been deleted or is too short now.", (self.state.blockindex, self.currentBlock().localCursorIndex)) + + def toItemInBlock(self, targetItem, targetBlock): + """A block is the only unique element in a Laborejo score. + Items are unique per-block. So if we find the block we can find + the correct item + + We start from head to make sure we parse the actual content of + the block and not some confused leftovers after a content linked + insert/delete. This was indeed the reason why this function + was introduced.""" + self.head() + while True: + if self.currentBlock() is targetBlock and self.currentItem() is targetItem: + return True + else: + if not self.right(): #end of track + raise RuntimeError("Item {} in block {} not found.".format(targetItem, targetBlock)) + + def currentItem(self): + return self.currentBlock().currentItem() + + def previousItem(self): + return self.currentBlock().previousItem() + + def nextItem(self): + return self.currentBlock().nextItem() + + """ + def lookaheadItems(self, number): + #return a list of items, including the current one. + #number=2 is the current and the next item. + startItem = self.currentItem() + startBlock = self.currentBlock() #this is the only unique thing we can rely on. + result = [startItem] + for i in range(number-1): + self.right() + result.append(self.currentItem()) + self.toItemInBlock(startItem, startBlock) #find the correct cursor position and trackState + assert len(result) == number + return result + """ #Never used, never tested. + + + def insert(self, item): + """We want the cursor to stay on the the same item + (or appending) as before the insert. + + If there is a simple item insert the old item will be one + position to the right. But with linked content blocks the + step to the right gets multiplied and so the trackState + counting goes wrong. Sometimes horribly. We need to reset. + """ + startItem = self.currentItem() + startBlock = self.currentBlock() #this is the only unique thing we can rely on. + startBlock.insert(item) + self.toItemInBlock(startItem, startBlock) #find the correct cursor position and trackState + return True + + def delete(self): + """Delete stops at a block boundary. It returns None + and nothing happens. Item stay the same, cursor stays the same""" + startBlock = self.currentBlock() + nextItem = self.nextItem() #we want to return to that item because all items "gravitate to the left" after deletion. Like like in a text editor. + result = startBlock.delete() + self.toItemInBlock(nextItem, startBlock) #find the correct cursor position and trackState + return result + + def parseLeft(self): + item = self.currentItem() + dur = item.logicalDuration() + self.state.tickindex -= dur + + #Metrical position + self.state.ticksSinceLastMeasureStartLive -= dur #can become < 0, we crossed a measure-border left. + if self.state.ticksSinceLastMeasureStartLive < 0 : + self.state.ticksSinceLastMeasureStartLive = self.state.metricalInstruction().oneMeasureInTicks + self.state.ticksSinceLastMeasureStartLive + + if isinstance(item, Chord): + pass + elif isinstance(item, Rest): + pass + elif isinstance(item, LegatoSlur): + self.state.duringLegatoSlur = not self.state.duringLegatoSlur #there is only level of slurs and it is not allowed to insert a legatoSlurOpen when self.state.duringLegatoSlur is True or ..close if the state is false. This makes just toggling the value possible, + elif isinstance(item, MultiMeasureRest): + pass + elif isinstance(item, Clef): + self.state.clefs.pop() + elif isinstance(item, KeySignature): + self.state.keySignatures.pop() + elif isinstance(item, MetricalInstruction): + self.state.metricalInstructions.pop() + elif isinstance(item, DynamicSignature): + self.state.dynamicSignatures.pop() + elif isinstance(item, InstrumentChange): + self.state.instrumentChanges.pop() + #else: + #items.Item + + def parseRight(self): + item = self.previousItem() + dur = item.logicalDuration() + self.state.tickindex += dur #Anything that is right of the cursor (including the current item, which is technically right of the cursor as well) does not matter for the tickindex and is not saved in here. + + #Metrical position + self.state.ticksSinceLastMeasureStartLive += dur + tickRest = self.state.ticksSinceLastMeasureStartLive - self.state.metricalInstruction().oneMeasureInTicks + if tickRest >= 0: #Measure Number calculation does not protect against human error. A user can add a MetricalInstruction at the beginning of a measure which will create problems here and there but is allowed nevertheless as temporary state while editing + self.state.ticksSinceLastMeasureStartLive = tickRest #If one measure was overfull the rest ist chosen as next startpoint. + + if isinstance(item, Chord): + pass + elif isinstance(item, Rest): + pass + elif isinstance(item, LegatoSlur): + self.state.duringLegatoSlur = not self.state.duringLegatoSlur #there is only level of slurs and it is not allowed to insert a legatoSlurOpen when self.state.duringLegatoSlur is True or ..close if the state is false. This makes just toggling the value possible, + elif isinstance(item, MultiMeasureRest): + pass + elif isinstance(item, Clef): + self.state.clefs.append(item) + elif isinstance(item, KeySignature): + self.state.keySignatures.append(item) + elif isinstance(item, MetricalInstruction): + self.state.metricalInstructions.append(item) + elif isinstance(item, DynamicSignature): + self.state.dynamicSignatures.append(item) + self.state.dynamicRamp = None #reset + elif isinstance(item, DynamicRamp): #This is only for a complete parse, not for cursor movement. That is why this is not stack and there is nothing in parseLeft() to unset this. head() is enough to unset. + self.state.dynamicRamp = item + elif isinstance(item, ChannelChange): + self.state.midiChannels.append(item.value) + elif isinstance(item, InstrumentChange): + self.state.instrumentChanges.append(item) + + def newGraphTrackCC(self, cc): + self.ccGraphTracks[cc] = GraphTrackCC(cc, parentTrack = self) + + def addExistingGraphTrackCC(self, cc, graphTrackObject): + graphTrackObject.parentTrack = self #in case of undo this is redundant. In other cases it might be neccessary + graphTrackObject.cc = cc #this makes this function the basis for "change cc" or even moving to other tracks + self.ccGraphTracks[cc] = graphTrackObject + + def deleteGraphTrackCC(self, cc): + result = self.ccGraphTracks[cc] + self.ccGraphTracks[cc].prepareForDeletion() #this only deletes the current midi track. not the midi out. If we add this track again through undo we don't need to do anything. it will be regenerated automatically. + del self.ccGraphTracks[cc] + return result + #we don't need to unregister anything from cbox. + + + #Save / Load / Export + def lilypond(self): + """Called by score.lilypond(), returns a string.""" + for item in self.blocks[0].data[:4]: + if type(item) is MetricalInstruction: + timeSig = "" + break + else: + timeSig = "\\once \\override Staff.TimeSignature #'stencil = ##f \\cadenzaOn " + + upbeatLy = "\\partial {} ".format(Duration.createByGuessing(self.upbeatInTicks).lilypond()) if self.upbeatInTicks else "" + + data = " ".join(block.lilypond() for block in self.blocks) + if data: + return timeSig + upbeatLy + data + else: + return "" + + + def serialize(self)->dict: + return { + "sequencerInterface" : self.sequencerInterface.serialize(), + "blocks" : [block.serialize() for block in self.blocks], + "ccGraphTracks" : {ccNumber:graphTrackCC.serialize() for ccNumber, graphTrackCC in self.ccGraphTracks.items()}, + "durationSettingsSignature" : self.durationSettingsSignature.serialize(), + "dynamicSettingsSignature" : self.dynamicSettingsSignature.serialize(), + + "double" : self.double, + "initialMidiChannel" : self.initialMidiChannel, + "initialMidiProgram" : self.initialMidiProgram, + "initialMidiBankMsb" : self.initialMidiBankMsb, + "initialMidiBankLsb" : self.initialMidiBankLsb, + "ccChannels" : self.ccChannels, + "midiTranspose" : self.midiTranspose, + "initialInstrumentName" : self.initialInstrumentName, + "initialShortInstrumentName" : self.initialShortInstrumentName, + "upbeatInTicks" : self.upbeatInTicks, + } + + + + @classmethod + def instanceFromSerializedData(cls, parentData, serializedData): + self = cls.__new__(cls) + self.parentData = parentData + self.sequencerInterface = template.engine.sequencer.SequencerInterface.instanceFromSerializedData(self, serializedData["sequencerInterface"]) + + self.upbeatInTicks = int(serializedData["upbeatInTicks"]) + self.blocks = [Block.instanceFromSerializedData(block, parentObject = self) for block in serializedData["blocks"]] + self.durationSettingsSignature = DurationSettingsSignature.instanceFromSerializedData(serializedData["durationSettingsSignature"], parentObject = self) + self.dynamicSettingsSignature = DynamicSettingsSignature.instanceFromSerializedData(serializedData["dynamicSettingsSignature"], parentObject = self) + self.double = serializedData["double"] + self.initialMidiChannel = serializedData["initialMidiChannel"] + self.initialMidiProgram = serializedData["initialMidiProgram"] + self.initialMidiBankMsb = serializedData["initialMidiBankMsb"] + self.initialMidiBankLsb = serializedData["initialMidiBankLsb"] + self.ccGraphTracks = {int(ccNumber):GraphTrackCC.instanceFromSerializedData(graphTrackCC, parentObject = self) for ccNumber, graphTrackCC in serializedData["ccGraphTracks"].items()} + self.ccChannels = serializedData["ccChannels"] + self.midiTranspose = serializedData["midiTranspose"] + self.initialInstrumentName = serializedData["initialInstrumentName"] + self.initialShortInstrumentName = serializedData["initialShortInstrumentName"] + + self._processAfterInit() + return self + + def staticBlocksRepresentation(self): + """Only the blocks""" + result = [] + tickindex = 0 + for block in self.blocks: + duration = block.duration() + d = { + "id" : id(block), + "name" : block.name, + "tickindex" : tickindex, + #"data" : block, + "completeDuration" : duration, + "minimumInTicks" : block.minimumInTicks, + } + result.append(d) + tickindex += duration + return result + + def staticTrackRepresentation(self)->dict: + """Only the minimal track data itself, no items. + Can be used to re-order tracks or keep the number of tracks + in sync.""" + result = { + "id" : id(self), + "name" : self.name, + "index" : self.state.index(), + "upbeatInTicks": int(self.upbeatInTicks), + "double" : self.double, + "initialMidiChannel" : self.initialMidiChannel, + "initialMidiProgram" : self.initialMidiProgram, + "initialMidiBankMsb" : self.initialMidiBankMsb, + "initialMidiBankLsb" : self.initialMidiBankLsb, + "ccChannels" : self.ccChannels, + "midiTranspose" : self.midiTranspose, + "initialInstrumentName" : self.initialInstrumentName, + "initialShortInstrumentName" : self.initialShortInstrumentName, + #DurationSettings, all strings + "duration.defaultOn" : str(self.durationSettingsSignature.defaultOn), + "duration.defaultOff" : str(self.durationSettingsSignature.defaultOff), + "duration.staccatoOn" : str(self.durationSettingsSignature.staccatoOn), + "duration.staccatoOff" : str(self.durationSettingsSignature.staccatoOff), + "duration.tenutoOn" : str(self.durationSettingsSignature.tenutoOn), + "duration.tenutoOff" : str(self.durationSettingsSignature.tenutoOff), + "duration.legatoOn" : str(self.durationSettingsSignature.legatoOn), + "duration.legatoOff" : str(self.durationSettingsSignature.legatoOff), + } + + for key, value in self.dynamicSettingsSignature.dynamics.items(): + #keys are all strings. we prefix with dynamics for clarity + result["dynamics." + key] = value + + return result + + def export(self)->dict: + return { + "sequencerInterface" : self.sequencerInterface.export(), + } + + + def getPreliminaryData(self): + """Parse the track and gather information: + All Dynamic Signatures + All Dynamic Ramps. + + This data will be used in self.staticRepresentation. + """ + self.head() + localRight = self.right #performance + localPreviousItem = self.previousItem #performance + localType = type #performance + lastDynamicRamp = None + countBlockIndex = 0 + + #Parse from left to right. Remember that the item we are interested in is always the previous item! + while localRight(): + if self.state.blockindex > countBlockIndex: + assert self.state.blockindex == countBlockIndex+1 + #we crossed a block boundary. previousItem() will fail because it assumes we do not call it on a block beginning. + countBlockIndex += 1 + continue + + item = localPreviousItem() + itemtype = localType(item) + if itemtype is DynamicRamp: + lastDynamicRamp = item + item._cachedTickIndex = self.state.tickindex + item._cachedVelocity = self.dynamicSettingsSignature.dynamics[self.state.dynamicSignature().keyword] + elif itemtype is DynamicSignature and lastDynamicRamp: # A dynamic signature directly after a DynamicRamp. This is what we are looking for. + lastDynamicRamp._cachedTargetVelocity = self.dynamicSettingsSignature.dynamics[item.keyword] + lastDynamicRamp._cachedTargetTick = self.state.tickindex + lastDynamicRamp = None + + def staticRepresentation(self): + """The basis for all representations. Be it a GUI or playback. + Representation does NOT mean export. Lilypond Export works + in a different way. + + Not for saving, which is called serialize. + + One special case is that it takes block minimumTicks into + account. + + It also generates the metronome for this track, which is not included in the export dict + + For the changes to take effect a GUI must react to them and calfbox must be updated. + This is done on the API level by special functions and callbacks. + """ + #TODO: this is a hack. This makes Laborejo dependent on the api beeing used. This is only the case with GUI or Midi but not as a script. However, we need to expand the tempo track constantly. + #TODO: However, it is even less elegant to put this call in all rhythm editing methods and functions. inserts, block duplicate, content links, augment, tuplets undo etc. + #Taken out an placed in tempo Export. #self.score.tempoTrack.expandLastBlockToScoreDuration() #we guarantee that the tempo track is always at least as long as the music tracks. + + pblob = bytes() # Create a binary blob that contains the MIDI events + + originalPosition = self.state.position() + self.getPreliminaryData() + barlines = OrderedDict() #tick:metricalInstruction . We do not use selft.state.barlines, which is simply barlines for the live cursor. This is to send Barlines to a UI and also to generate the Metronome by associating a metricalInstruction with each barline. + result = [] + metaData = {} #this will be the last item in the representation and can be popped by a GUI. It holds information like the position of barlines. + + #if self.hasContentLinks(): + self.head() #reset the state + #At this point there is NOTHING in the track state except the init data. You can't look up anything in the state until the cursor moved at least once right. That means a metrical instruction is impossible to detect through the trackstate right now. + + #Initial Midi values + initialProgamChange = self.state.instrumentChange() + assert self.state.midiChannel() == self.initialMidiChannel + assert self.initialMidiProgram == initialProgamChange.program + assert self.initialMidiBankMsb == initialProgamChange.msb + assert self.initialMidiBankLsb == initialProgamChange.lsb + if initialProgamChange.program >= 0: #-1 is off. + pblob += cbox.Pattern.serialize_event(0, 0xC0 + self.initialMidiChannel, initialProgamChange.program, 0) + pblob += cbox.Pattern.serialize_event(0, 0xB0 + self.initialMidiChannel, 0, self.initialMidiBankMsb) #position, status byte+channel, controller number, controller value + pblob += cbox.Pattern.serialize_event(0, 0xB0 + self.initialMidiChannel, 32, self.initialMidiBankLsb) #position, status byte+channel, controller number, controller value + + localRight = self.right #performance + resultAppend = result.append #performance + _allExportedChords = [] #a shortcuts for easier beam creation + _allExportedChordsAppend = _allExportedChords.append + + #Process the items, most likely notes. Remember that the item we are interested in is the previous item because it is left of our cursor. + previousBarlineTickIndex = self.upbeatInTicks + previousItem = None + while True: + r = localRight() + if r == 1: #Exporting the items and adding them to the result is completely done in this block. expObj is not used anywhere else in this function. + previousItem = self.previousItem() + expObj = previousItem.exportObject(self.state) #yes, it is correct that the state in the parameter is ahead by one position. Why is it that way? Because everything that matters, like new dynamics will only be parsed afterwards. The trackState is always correct except for the tickindex when exporting after parsing. Thats why exportObject sometimes substracts its own duration for finding its starting tick. + resultAppend(expObj) + dur = expObj["completeDuration"] + for blob in expObj["midiBytes"]: #a list of + pblob += blob + if expObj["type"] == "Chord" or expObj["type"] == "Rest": #save for later when we create Beams. No other use. + _allExportedChordsAppend(expObj) + + elif r == 2: #block end. Again, this is already the previous state. right now we are in the next block already. + lastBlock = self.blocks[self.state.blockindex-1] #why -1? see comment above + dur = lastBlock.staticExportEndMarkerDuration() + resultAppend(BlockEndMarker().exportObject(self.state)) #this instance of BlockEndMarker does only exist during this export. + else: + break + + #Check if any new Barlines need to get created. It is possible that since the last item more than one barline needs to get created (Multi Measure Rests) + #Achtung! Barlines are calculated by completed measure. That means it counts until a measure is full, according to the current metrical instruction. + #But metrical instructions themselves need to be calculated at the beginning of the measure. To put them in sync we need to keep track. Therefore we use an ordered dict which provides pairing as well as order. + #Additional benefit is that multiple metrical instructions on the same tick can be handled, eventhough we consider them a user error (according to the users manual) + + if type(previousItem) is MetricalInstruction and not(self.state.tickindex == 0 and self.upbeatInTicks) : #always start a new metrical section with a barline. Otherwise we don't see a barlines after a long section without barlines. + previousBarlineTickIndex = self.state.tickindex + barlines[self.state.tickindex] = self.state.metricalInstruction() + else: + #There is a distinction between metrical and non-metrical instructions. However, that doesn't matter for barlines. Both produce barlines. + #Empty Metrical Instructions (the default for a new track) disable barlines until a metrical instruction appears which then (re)starts the metrical cycles. + if dur and self.state.metricalInstruction().oneMeasureInTicks > 0: + self.state.ticksSinceLastMeasureStart += dur + tickRest = self.state.ticksSinceLastMeasureStart - self.state.metricalInstruction().oneMeasureInTicks + while tickRest >= self.upbeatInTicks: #we crossed into the next measure. Or even more measures, for MMRests. By definition the metricalInstruction cannot have changed in the meantime since every tick was occupied by a sinle tick. + barlines[previousBarlineTickIndex] = self.state.metricalInstruction() + previousBarlineTickIndex = self.state.tickindex - tickRest + self.upbeatInTicks + self.state.ticksSinceLastMeasureStart = tickRest #If one measure was overfull the rest ist chosen as next startpoint. + tickRest = self.state.ticksSinceLastMeasureStart - self.state.metricalInstruction().oneMeasureInTicks + + #Loop Over + #In the end add one final barline if the last measure was complete. This will create the effect, for the GUI and the user, that a measure "closes" once it is complete. There is no chance for a double barline because we use a dict. + if barlines: + barlines[previousBarlineTickIndex] = self.state.metricalInstruction() + + #We are now at the end the the track. + + + ######### + #Converting laborejo objects to export dicts is done. From here on everything uses the exported data + ######### + + #Metronome start + #The metronome cannot be calculated by simply looking at metricalInstructions. We need to look at the barlines. Two instructions in a row at the same tick are wrong, but technically possible. These are not two full measures of metronome + #TODO: metronome activate + #if self is self.parentData.currentMetronomeTrack: + # self.parentData.metronome.generate(((pos, m.isMetrical, m.treeOfInstructions) for pos, m in barlines.items())) + #Metronome end. Nothing below is connected with the metronome subtrack. + + #Calculate the beam positions for the static groups. + #We send this data to the GUI. + beamGroups = [] #a list of list of exportChords. + currentlyDuringBeaming = False + if _allExportedChords: + lastExpChord = _allExportedChords[-1] #for performance + for expChord in _allExportedChords: + if "beamGroup" in expChord and expChord["beamGroup"]: + if currentlyDuringBeaming: #switch it off then + expChord["beamGroup"] = "close" #for the GUI + currentlyDuringBeaming = False + beamGroups[-1].append(expChord) + else: + expChord["beamGroup"] = "open" #for the GUI + if expChord is lastExpChord: + continue + currentlyDuringBeaming = True + beamGroups.append(list()) + beamGroups[-1].append(expChord) + + elif currentlyDuringBeaming: + if expChord is lastExpChord or expChord["baseDuration"] > D8: #invalid beaming. An open beaming group encountering either the end of the track or >D8 is invalid and not counted. + currentlyDuringBeaming = False + beamGroups.pop() #the group so far was invalid because it was not closed properly. + else: + beamGroups[-1].append(expChord) + + resultBeamGroups = [] #will be added to the exported meta-data + for beamGroup in beamGroups: + if beamGroup: #with content + #stem means in staffline coordinates (dots on lines): (starting point, length, 1|-)] 1 stem is on the right or -1 left side of the note. + #We don't deal with the length, stem[1], here. By the time writing this function it was just constant "5" anyway + #min and max below are "reversed" (min for the highest position in upward stems) because we set coordinates in lines and rows with the middle line as origin/0. Important: Stems do not begin at the same line/space as their note. Upstems begin notehead-1, downstems notehead+1 + stems = [o["stem"] for o in beamGroup] #this cannot be a generator because we are using it multiple times. + assert stems + minimum = min(s[0] for s in stems) + maximum = max(s[0] for s in stems) + if sum(s[2] for s in stems) >= 0: #beam upwards direction + direction = 1 + length = -5 + beamPosition = minimum + length + startDotOnLineKeyword = "highestPitchAsDotOnLine" + #assert beamPosition <= 0 + else: #beam down direction + length = 5 + beamPosition = maximum + length + direction = -1 + startDotOnLineKeyword = "lowestPitchAsDotOnLine" + #assert beamPosition > 0 + + #beams have the same syntax and structure as a stem. + #Until now we figured out the position of the beams as well as their length. However: Mixed duration (e.g. 8th + 16th) groups are allowed and also common. We need to split these groups into sub-groups + #These groups are different than the real groups because they share the same baseline for the beams and also have at least one uninterrupted beam connecting all sub-groups. + + subBeamGroups = [[]] + currentSubGroupFlag = beamGroup[0]["flag"] + for obj in beamGroup: + if obj["flag"] == currentSubGroupFlag: + subBeamGroups[-1].append(obj) + else: + subBeamGroups.append(list()) + currentSubGroupFlag = obj["flag"] + subBeamGroups[-1].append(obj) + + + for subBeamGroup in subBeamGroups: + for obj in subBeamGroup: + startStaffLine = obj[startDotOnLineKeyword] + length = beamPosition - startStaffLine + obj["beam"] = (startStaffLine, length, direction) #(starting point, length, 1|-)] 1 stem is on the right or -1 left side of the note. + firstItem, lastItem = subBeamGroup[0], subBeamGroup[-1] + connectorLength = lastItem["completeDuration"] if not lastItem == beamGroup[-1] else 0 + resultBeamGroups.append((firstItem["tickindex"], lastItem["tickindex"] + connectorLength, abs(firstItem["flag"]), beamPosition, direction)) #tick-start, tick-end, duration-type, position as staffline. Extra simple for the GUI. + #Beams finished + + resultAppend(metaData) + metaData["barlines"] = barlines.keys() + metaData["duration"] = self.state.tickindex #tickindex is now at the end, so this is the end duration. This includes Blocks minimumDuration as well since it is included in left/right + metaData["beams"] = resultBeamGroups + + t = (pblob, 0, self.state.tickindex) + self.sequencerInterface.setTrack([t]) #(bytes-blob, position, length) #tickindex is still on the last position, which means the second parameter is the length + + self.toPosition(originalPosition, strict = False) #has head() in it + return result + + + + + + +#Dependency Injections. +template.engine.sequencer.Score.TrackClass = Track #Score will look for Track in its module. diff --git a/laborejo2 b/laborejo2 new file mode 100755 index 0000000..834f613 --- /dev/null +++ b/laborejo2 @@ -0,0 +1,9 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +from template import start #Executes various start up checks and sets up our environment likes search paths + +from qtgui import mainwindow #which in turn imports the engine and starts the engine +with start.profiler(): + mainwindow.MainWindow().qtApp.exec_() + #Program is over. Code here does not get executed. Quit is done via NSM in mainWindow._nsmQuit diff --git a/midiinput/stepmidiinput.py b/midiinput/stepmidiinput.py new file mode 100644 index 0000000..4f28e3d --- /dev/null +++ b/midiinput/stepmidiinput.py @@ -0,0 +1,103 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2019, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), +more specifically its template base application. + +The Template Base Application 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 . +""" + +import logging; logging.info("import {}".format(__file__)) + +#Python Standard Library + +#Third Party Modules + +#Template Modules +from template.engine.input_midi import MidiInput + +#Our Modules +import engine.api as api + + +class StepMidiInput(MidiInput): + """We initialize with everything switched off. This makes it easier for a complex system + of engine, GUI and midiinput to start up and get the order of operations right + + For chord entry we use the first note only as indicator. The indicator was a set() at one time, + which means that as long as one of the chord notes would still be down the chord was still "on". + That is not as robust and convenient as using the starting note, which is counter intuitive, + therefore documented here. + """ + + def __init__(self): + self.firstActiveNote = None #for chord entry. + self._currentlyActiveNotes = set() + + def start(self): + """Call this manually after the engine and an event loop have started. + For example from the GUI. It is currently started by mainwindow.py start() + But it could be started from a simple command line interface as well.""" + assert api.laborejoEngineStarted + super().__init__(session=api.session, portName="in") + self.midiProcessor.active = False #specific to Laborejo + + #Connect the template midi input with Laborejo api calls. + #self.midiProcessor.notePrinter(True) + self.midiProcessor.register_NoteOn(self._insertMusicItemFromMidi) + self.midiProcessor.register_NoteOff(self._pop) + + api.callbacks.setCursor.append(self._setMidiThru) #When the track changes re-route cbox RT midi thru + + @property + def midiInIsActive(self): + try: + return self.midiProcessor.active + except AttributeError: #during startupt + return False + + def _insertMusicItemFromMidi(self, channel, midipitch, velocity): + if self._currentlyActiveNotes: #Chord + api.left() + keysig = api.session.data.currentTrack().state.keySignature() + pitchToInsert = api.pitchmath.fromMidi(midipitch, keysig) + api.addNoteToChord(pitchToInsert) + api.right() + else: #Single note + baseDuration = api.session.data.cursor.prevailingBaseDuration + keysig = api.session.data.currentTrack().state.keySignature() + pitchToInsert = api.pitchmath.fromMidi(midipitch, keysig) + api.insertChord(baseDuration, pitchToInsert) + + self._currentlyActiveNotes.add(midipitch) + + def _pop(self, channel, midipitch, velocity): + self._currentlyActiveNotes.remove(midipitch) + + def setMidiInputActive(self, state:bool): + self.midiProcessor.active = state + api.callbacks._prevailingBaseDurationChanged(api.session.data.cursor.prevailingBaseDuration) + + def toggleMidiIn(self): + self.setMidiInputActive(not self.midiInIsActive) + + def _setMidiThru(self, cursorExport): + """We don't need to react to deleted tracks because that does reset the cursor. + The template midi in does _not_ check if the routed output ports still exist. + however, that is a low risk state that needs changes in the program""" + self.setMidiThru(cursorExport["cboxMidiOutUuid"]) + +stepMidiInput = StepMidiInput() #global to use in other parts of Laborejo diff --git a/qtgui/__init__.py b/qtgui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/qtgui/conductor.py b/qtgui/conductor.py new file mode 100644 index 0000000..43f1776 --- /dev/null +++ b/qtgui/conductor.py @@ -0,0 +1,635 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +import logging; logging.info("import {}".format(__file__)) + +from PyQt5 import QtCore, QtGui, QtSvg, QtWidgets +from .constantsAndConfigs import constantsAndConfigs +from template.qtgui.helper import stringToColor, removeInstancesFromScene, callContextMenu, stretchLine, stretchRect +from template.helper import pairwise +from .submenus import SecondaryTempoChangeMenu, TempoBlockPropertiesEdit +import engine.api as api + +oneRectToReturnThemAll = QtCore.QRectF(0,0,0,0) #prevent the annoying "NotImplementError" from Qt for boundingRect. For items that don't need any collision detection. + +_zValuesRelativeToConductor = { #Only use for objects added directly to the Conductor, not their children. + "line":0, + "block":3, + "item":4, + "handle":5, +} + +class Conductor(QtWidgets.QGraphicsItem): + """The track for tempo items. Some methods have the same name and functionality + as note-track to be compatible. For example drag and drop of blocks.""" + + def __init__(self, parentView): + super().__init__() + + self.parentView = parentView + self.totalHeight = 71 + + self.staticPoints = None #Cached backend staticRepresentationList: TempoPoints and interpolated points list + self.staticBlocks = None #Cached Block Data list + self.staticMeta = None #Cached track meta data dict. + + self.staffLine = QtWidgets.QGraphicsLineItem(0,0,10,0) #x1, y1, x2, y2 + self.staffLine.setParentItem(self) + self.staffLine.setPos(0,0) + + self.timeLine = TimeLine(self) #registers its own callbacks + self.timeLine.setParentItem(self) + + api.callbacks.updateTempoTrackBlocks.append(self.updateBlocks) + api.callbacks.updateTempoTrack.append(self.createGraphicItemsFromData) + api.callbacks.updateTempoTrackMeta.append(self.updateMetaData) + + def paint(self, *args): + pass + def boundingRect(self, *args): + return oneRectToReturnThemAll + + def blockAt(self, xScenePosition): + for block in ConductorTransparentBlock.instances: + start = block.staticExportItem["position"] / constantsAndConfigs.ticksToPixelRatio + end = start + block.staticExportItem["duration"] / constantsAndConfigs.ticksToPixelRatio + if start <= xScenePosition < end: + return block + return None #After the last block. + + @property + def transparentBlockHandles(self): + return ConductorTransparentBlock.instances + + def updateMetaData(self, trackMetaDictionary): + """Keep the meta data up to date. + Meta Data is (absolute) min and max tempo values: + {'minimumAbsoluteTempoValue': 120, 'maximumAbsoluteTempoValue': 120} + """ + self.staticMeta = trackMetaDictionary + + def updateBlocks(self, staticRepresentationList): + """This is called when the blocks itself change, of course. + But also """ + self.staticBlocks = staticRepresentationList + + removeInstancesFromScene(ConductorTransparentBlock) + for dictExportItem in staticRepresentationList: + guiBlock = ConductorTransparentBlock(parent = self, staticExportItem = dictExportItem, x = 0, y = -10, w = dictExportItem["duration"] / constantsAndConfigs.ticksToPixelRatio, h = 20) + guiBlock.setParentItem(self) + guiBlock.setPos(dictExportItem["position"] / constantsAndConfigs.ticksToPixelRatio,0) + guiBlock.setZValue(_zValuesRelativeToConductor["block"]) #including the handle + + rightBorder = (dictExportItem["duration"] + dictExportItem["position"]) / constantsAndConfigs.ticksToPixelRatio + self.updateStaffLine(rightBorder) + + def blockById(self, backendId): + for guiblock in ConductorTransparentBlock.instances: + if guiblock.staticExportItem["id"] == backendId: + return guiblock + #else: + # raise ValueError(f"{backendId} not found") + + + def updateStaffLine(self, x): + assert not self.staffLine.line().isNull() + line = self.staffLine.line() + line.setLength(x) + self.staffLine.setLine(line) + self.staffLine.setZValue(_zValuesRelativeToConductor["line"]) + + def createGraphicItemsFromData(self, staticRepresentationList): + self.staticPoints = staticRepresentationList + + removeInstancesFromScene(TempoPoint) + y = -35 #The Y Value adjusts for the offset the text-item creates + + for point in staticRepresentationList: + if not point["type"] == "interpolated": #a real user point or lastInBlock or lastInTrack + x = point["position"] / constantsAndConfigs.ticksToPixelRatio + p = TempoPoint(self, point, self.blockById(point["blockId"])) + p.setParentItem(self) + p.setPos(x, y) + + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + + positionalItems = (TempoPoint.instances + ConductorTransparentBlock.instances) + + for tempoPoint in positionalItems: + tempoPoint.setX(tempoPoint.pos().x() * factor) + + for block in ConductorTransparentBlock.instances: + block.stretchXCoordinates(factor) + + stretchLine(self.staffLine, factor) + self.timeLine.stretchXCoordinates(factor) + + + def mousePressEvent(self, event): + """It is possible that this has coordinates outside of the Conductor instance. When the + mousePressEvent is inside and the mouse moves outside for the release event it still counts + as event of this instance""" + + if event.button() == 1 and 0 <= event.scenePos().x() < self.staffLine.line().x2(): #within the conductor line: # QtCore.Qt.MouseButton.LeftButton + event.accept() + self.add(event.scenePos()) #create a new tempo point by telling the api a position and then reacting to "delete all, recreate" from the callback. + else: + super().mousePressEvent(event) #call default implementation from QGraphicsRectItem + + def add(self, scenePos): + """Use a scenePos (from self.mousePressEvent) to instruct the backend + to create a new tempo point.""" + unitsPerMinute = 120 + referenceTicks = api.D4 + + sp = scenePos.x() * constantsAndConfigs.ticksToPixelRatio + if constantsAndConfigs.snapToGrid: + sp = round(sp / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + + api.insertTempoItemAtAbsolutePosition(sp, unitsPerMinute, referenceTicks, graphType = "standalone") + +class ConductorTransparentBlock(QtWidgets.QGraphicsRectItem): + """A simplified version of a Block. Since we don't use blocks in the GUI, only in the backend + we still need them sometimes as macro strutures, where we don't care about the content. + + The block handle is at the END of a block. """ + + + class ConductorBlockName(QtWidgets.QGraphicsSimpleTextItem): + + instances = [] + + def __init__(self, parent, positionInSeconds): + self.__class__.instances.append(self) + m, s = divmod(positionInSeconds, 60) + text = "{}:{} min".format(str(int(m)).zfill(2), str(int(s)).zfill(2)) + super().__init__(text) + + marker = QtWidgets.QGraphicsLineItem(0, 0, 0, -10) #vertical marker to connect to the conductor line + marker.setParentItem(self) + + + instances = [] + + def __init__(self, parent, staticExportItem, x, y, w, h): + self.__class__.instances.append(self) + super().__init__(x, y, w, h) + self.setFlags(QtWidgets.QGraphicsItem.ItemDoesntPropagateOpacityToChildren|QtWidgets.QGraphicsItem.ItemIsMovable) #no mouseReleaseEvent without selection or movable. + self.parent = parent #Conductor instance + self.color = stringToColor(staticExportItem["name"]) + self.trans = QtGui.QColor("transparent") + self.setPen(self.trans) + self.setBrush(self.color) + self.setOpacity(0.2) #mimic background behaviour + self.staticExportItem = staticExportItem + + self.posBeforeMove = None + self.cursorPosOnMoveStart = None + + #Display Block ID + #self.idText = QtWidgets.QGraphicsSimpleTextItem(str(self.staticExportItem["id"])) + #self.idText.setParentItem(self) + #self.idText.setPos(0, -30) + + if self.staticExportItem["duration"] >= 8*api.D1: #cosmetics + self.startLabel = QtWidgets.QGraphicsSimpleTextItem(self.staticExportItem["name"] + " start") + self.startLabel.setParentItem(self) + self.startLabel.setPos(15, -2*constantsAndConfigs.stafflineGap) + self.startLabel.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + + self.endLabel = QtWidgets.QGraphicsSimpleTextItem(self.staticExportItem["name"] + " end ") + self.endLabel.setParentItem(self) + self.endLabel.setPos(self.rect().width() - self.endLabel.boundingRect().width(), -2*constantsAndConfigs.stafflineGap) + self.endLabel.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + else: + self.startLabel = QtWidgets.QGraphicsSimpleTextItem("") + self.endLabel = QtWidgets.QGraphicsSimpleTextItem("") + + #Add End Line + self.marker = ConductorBlockHandle(parent = self) + self.marker.setParentItem(self) + self.marker.setPos(staticExportItem["duration"] / constantsAndConfigs.ticksToPixelRatio, -1/2* self.rect().height()+2) + + #def paint(self, *args): + # """Prevent the selection rectangle when clicking the item""" + #!! This also prevents the rectangle to show up. Very bad decision. + # pass + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + stretchRect(self, factor) + self.marker.setX(self.marker.pos().x() * factor) + + def mouseMoveEvent(self, event): + """Don't use the qt system. we move ourselves""" + event.accept() + + def mousePressEvent(self, event): + self.parent.mousePressEvent(event) + + def mouseMoveEventCustom(self, event): + """ + Move the whole block, change the tempoTrack form. + Custom gets called by the scene mouse press event directly only when the right keys + are hold down""" + # All the positions below don't work. They work fine when dragging Tracks around but not this Item. I can't be bothered to figure out why. + #scenePos() results ins an item position that is translated down and right. The higher the x/y value the more the offset + #Instead we calculate our delta ourselves. + + #self.setPos(self.mapToItem(self, event.scenePos())) + #self.setPos(self.mapFromScene(event.scenePos())) + #posGlobal = QtGui.QCursor.pos() + #posView = self.parent.parentScore.parentView.mapFromGlobal(posGlobal) #a widget + #posScene = self.parent.parentScore.parentView.mapToScene(posView) + #print (posGlobal, posView, posScene, event.scenePos()) + + if self.cursorPosOnMoveStart: + self.setPos(event.scenePos().x(), self.posBeforeMove.y()) + + """ + #does not work with zooming + if self.cursorPosOnMoveStart: + delta = QtGui.QCursor.pos() - self.cursorPosOnMoveStart + new = self.posBeforeMove + delta + if new.x() < 0: + self.setPos(0, self.posBeforeMove.y()) + else: + self.setPos(new.x(), self.posBeforeMove.y()) + #event.ignore() #this blocks the qt movable object since we already move the object on our own. + """ + super().mouseMoveEvent(event) + + def mousePressEventCustom(self, event): + """Custom gets called by the scene mouse press event directly only when the right keys + are hold down""" + self.posBeforeMove = self.pos() + self.cursorPosOnMoveStart = QtGui.QCursor.pos() + #self.setBrush(self.color) + super().mousePressEvent(event) + + def mouseReleaseEventCustom(self, event): + """Custom gets called by the scene mouse press event directly only when the right keys + are hold down""" + #self.setBrush(self.trans) + self.setPos(self.posBeforeMove) #In case the block was moved to a position where no track is (below the tracks) we just reset the graphics. If the moving was correct then the new position will be set by redrawing the whole Conductor. + self.posBeforeMove = None + self.cursorPosOnMoveStart = None + super().mouseReleaseEvent(event) + + def splitHere(self, event): + posRelativeToBlockStart = event.scenePos().x() * constantsAndConfigs.ticksToPixelRatio - self.x() * constantsAndConfigs.ticksToPixelRatio + if constantsAndConfigs.snapToGrid: + posRelativeToBlockStart = round(posRelativeToBlockStart / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + + if posRelativeToBlockStart > 0: + api.splitTempoBlock(self.staticExportItem["id"], int(posRelativeToBlockStart)) + + def contextMenuEvent(self, event): + listOfLabelsAndFunctions = [ + ("edit properties", lambda: TempoBlockPropertiesEdit(self.scene().parentView.mainWindow, staticExportItem = self.staticExportItem)), + ("separator", None), + ("split here", lambda: self.splitHere(event)), + ("duplicate", lambda: api.duplicateTempoBlock(self.staticExportItem["id"])), + ("create content link", lambda: api.duplicateContentLinkTempoBlock(self.staticExportItem["id"])), + ("unlink", lambda: api.unlinkTempoBlock(self.staticExportItem["id"])), + ("separator", None), + ("join with next block", lambda: api.mergeWithNextTempoBlock(self.staticExportItem["id"])), + ("delete block", lambda: api.deleteTempoBlock(self.staticExportItem["id"])), + ("separator", None), + ("append block at the end", api.appendTempoBlock), + ] + callContextMenu(listOfLabelsAndFunctions) + +class ConductorBlockHandle(QtWidgets.QGraphicsLineItem): + """Provides user interaction so the temp block can be resized by moving this handle with the + mouse left and right. + When user interaction happens this handle acts upon its parent transparent block to resize it + and finally sends a message to the backend, to ask for a data change.""" + + def __init__(self, parent): + self.parentTransparentBlock = parent + super().__init__(0,-1, 0, parent.rect().height()-4) #x1, y1, x2, y2 + self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable|QtWidgets.QGraphicsItem.ItemSendsGeometryChanges|QtWidgets.QGraphicsItem.ItemIsFocusable|QtWidgets.QGraphicsItem.ItemClipsToShape) + self.setAcceptHoverEvents(True) + self.setCursor(QtCore.Qt.SizeHorCursor) + + pen = QtGui.QPen() # creates a default pen + if not self.parentTransparentBlock.staticExportItem["exportsAllItems"]: + pen.setStyle(QtCore.Qt.DotLine) + pen.setWidth(2) + self.setPen(pen) + + self.inactivePen = pen + self.inactivePen.setColor(QtGui.QColor("black")) + + self.activePen = QtGui.QPen(pen) + self.activePen.setColor(QtGui.QColor("cyan")) + + self.minimalSize = api.D1 / constantsAndConfigs.ticksToPixelRatio + + self.setZValue(_zValuesRelativeToConductor["handle"]) + + def shape(self): + """Return a more accurate shape for this item so that + mouse hovering is more accurate""" + path = QtGui.QPainterPath() + path.addRect(QtCore.QRectF(-2, -2, 5, self.parentTransparentBlock.rect().height()+2 )) #this is directly related to inits parameter x, y, w, h + return path + + def hoverEnterEvent(self, event): + self.setPen(self.activePen) + #self.parentTransparentBlock.setBrush(self.parentTransparentBlock.color) + + + def hoverLeaveEvent(self, event): + self.setPen(self.inactivePen) + #self.parentTransparentBlock.setBrush(self.parentTransparentBlock.trans) + + def mousePressEvent(self, event): + self.posBeforeMove = self.pos() + self.cursorPosOnMoveStart = QtGui.QCursor.pos() + super().mousePressEvent(event) + + def mouseMoveEvent(self, event): + if not self.cursorPosOnMoveStart: + super().mouseMoveEvent(event) + return None + + delta = QtGui.QCursor.pos() - self.cursorPosOnMoveStart + new = self.posBeforeMove + delta + + if not new.x() < self.minimalSize: + self.setPos(new.x(), self.posBeforeMove.y()) + pRect = self.parentTransparentBlock.rect() + pRect.setRight(new.x()) + self.parentTransparentBlock.setRect(pRect) + + event.accept() #this blocks the qt movable object since we already move the object on our own. + #Don't call the super mouseMoveEvent! + + def mouseReleaseEvent(self, event): + if self.cursorPosOnMoveStart: + + endingRelativeToBlockStart = self.x() * constantsAndConfigs.ticksToPixelRatio - self.parentTransparentBlock.x() + if constantsAndConfigs.snapToGrid: + endingRelativeToBlockStart = round(endingRelativeToBlockStart / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + assert endingRelativeToBlockStart > 0 + + self.setPos(self.posBeforeMove) #In case the handle was moved to a position where it wasn't allowed no backend action will happen. Just in case we reset the graphics for a smoother user experience. + self.posBeforeMove = None + self.cursorPosOnMoveStart = None + + api.changeTempoBlockDuration(self.parentTransparentBlock.staticExportItem["id"], endingRelativeToBlockStart) + + super().mouseReleaseEvent(event) + +class TempoPoint(QtWidgets.QGraphicsItem): + """A point where the values can be edited by the user. + + The first TempoPoint cannot be hovered. It is instead attached to a block handle. + """ + + instances = [] + + def __init__(self, parentTempoTrack, staticExportItem, parentBlock): + self.__class__.instances.append(self) + super().__init__() + self.staticExportItem = staticExportItem + self.parentTempoTrack = parentTempoTrack + self.parentBlock = parentBlock + self.setZValue(_zValuesRelativeToConductor["item"]) + + + self.setAcceptHoverEvents(True) + + + if not self.staticExportItem["positionInBlock"] == 0: + self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable|QtWidgets.QGraphicsItem.ItemIsFocusable) + #Too irritating. And confuses with handle movement. self.setCursor(QtCore.Qt.SizeHorCursor) #this sets the cursor while the mouse is over the item. It is independent of AcceptHoverEvents + else: + self.ungrabMouse = api.nothing #to surpress a warning from the context menu + + self.note = QtWidgets.QGraphicsTextItem("") + self.note.setParentItem(self) + self.note.setFont(constantsAndConfigs.musicFont) + self.note.setHtml("{}".format(constantsAndConfigs.realNoteDisplay[staticExportItem["referenceTicks"]])) + self.note.setPos(-6,0) #adjust items font x offsset. + + self.number = QtWidgets.QGraphicsTextItem("") + self.number.setParentItem(self) + #self.number.setHtml("{}".format(str(int(staticExportItem["unitsPerMinute"])))) + self.number.setHtml("{}".format(str(int(staticExportItem["unitsPerMinute"])))) + self.number.setPos(-6,0) #adjust items font x offsset. + + if not self.staticExportItem["graphType"] == "standalone": + self.arrow = QtWidgets.QGraphicsTextItem("⟶") #unicode long arrow right #http://xahlee.info/comp/unicode_arrows.html + self.arrow.setParentItem(self) + self.arrow.setPos(7,30) + else: + self.arrow = None + + for n in (self.note, self.number, self.arrow): + if n: n.setDefaultTextColor(QtGui.QColor("black")) + + self.wheelEventChangedValue = 0 #resetted in hoverEnterEvent. But we still need it for new items that appear directly under the mouse cursor + + def paint(self, painter, options, widget=None): + #painter.drawRect(self.boundingRect()) #uncomment to show the bounding rect + pass + + def boundingRect(self): + return QtCore.QRectF(0,0,25,50) #x, y, w, h + + + def mouseMoveEvent(self, event): + if self.staticExportItem["positionInBlock"] == 0: + #First in block can't be moved + event.accept() + return + + #toTheRight = True if event.scenePos().x() - event.lastScenePos().x()) > 0 else False + + delta = event.scenePos().x() - event.lastScenePos().x() + newPos = self.x() + delta + + if 0 <= newPos < self.parentTempoTrack.staffLine.line().x2(): #within the conductor line + self.setX(newPos) + event.accept() + + def mousePressEvent(self, event): + """Override the mousePressEvent to deactivate it. + Otherwise the event will be sent to the parent block and create a new TempoItem + at this point even if there is already one. Effectively replacing a custom item with + default value""" + #if self.staticExportItem["positionInBlock"] == 0: + # print ("no") + # #super().mousePressEvent(event) + event.accept() # + + def mouseReleaseEvent(self, event): + if self.staticExportItem["positionInBlock"] == 0: + #First in block can't be moved + event.accept() + return + + tickPositionAbsolute = self.scenePos().x() * constantsAndConfigs.ticksToPixelRatio + + if constantsAndConfigs.snapToGrid: + tickPositionAbsolute = round(tickPositionAbsolute / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + + api.moveTempoItem(self.staticExportItem["id"], tickPositionAbsolute) + event.accept() + + def hoverEnterEvent(self, event): + self.parentTempoTrack.parentView.mainWindow.ui.actionDelete.setEnabled(False) #Delete key collides with our hover-delete. + self.grabKeyboard() + self.wheelEventChangedValue = 0 + for n in (self.note, self.number, self.arrow): + if n: n.setDefaultTextColor(QtGui.QColor("cyan")) + + def hoverLeaveEvent(self, event): + self.parentTempoTrack.parentView.mainWindow.ui.actionDelete.setEnabled(True) #Delete key collides with our hover-delete. + self.ungrabKeyboard() + for n in (self.note, self.number, self.arrow): + if n: n.setDefaultTextColor(QtGui.QColor("black")) + if self.wheelEventChangedValue: + api.insertTempoItemAtAbsolutePosition(self.staticExportItem["position"], self.staticExportItem["unitsPerMinute"] + self.wheelEventChangedValue, self.staticExportItem["referenceTicks"], self.staticExportItem["graphType"]) + + def wheelEvent(self, event): + """This buffers until hoverLeaveEvent and then the new value is sent in self.hoverLeaveEvent""" + if event.delta() > 0: + self.wheelEventChangedValue += 1 + else: + self.wheelEventChangedValue -= 1 + self.number.setHtml("{}".format(str(int(self.staticExportItem["unitsPerMinute"] + self.wheelEventChangedValue)))) + event.accept() + + def keyPressEvent(self, event): + """Handle the delete item key. + Needs grabKeyboard, but NOT setFocus + + The event will not be sent if it is blocked by a global shortcut. + """ + key = event.key() + if key == 16777223: + #after delete the item and tempo tracks gets recreated so we need to reactivate the shortcut now. It will work without these two lines, but that is only implicit behaviour. + self.parentTempoTrack.parentView.mainWindow.ui.actionDelete.setEnabled(True) #Delete key collides with our hover-delete. + self.ungrabKeyboard() + api.removeTempoItem(self.staticExportItem["id"]) + else: + return super().keyPressEvent(event) + + def contextMenuEvent(self, event): + listOfLabelsAndFunctions = [ + ("edit properties", lambda: SecondaryTempoChangeMenu(self.scene().parentView.mainWindow, staticExportTempoItem = self.staticExportItem)), + ] + if not self.staticExportItem["positionInBlock"] == 0: + listOfLabelsAndFunctions.append(("delete", lambda: api.removeTempoItem(self.staticExportItem["id"]))) + callContextMenu(listOfLabelsAndFunctions) + +class TimeLine(QtWidgets.QGraphicsItem): + """Displays the real time.""" + + class TimePoint(QtWidgets.QGraphicsSimpleTextItem): + + instances = [] + + def __init__(self, parent, positionInSeconds): + self.__class__.instances.append(self) + m, s = divmod(positionInSeconds, 60) + text = "{}:{} min".format(str(int(m)).zfill(2), str(int(s)).zfill(2)) + super().__init__(text) + + marker = QtWidgets.QGraphicsLineItem(0, 0, 0, -10) #vertical marker to connect to the conductor line + marker.setParentItem(self) + + + def __init__(self, parent): + super().__init__() + self.parent = parent + self.gridInSeconds = 10 + api.callbacks.updateTempoTrackBlocks.append(self.redraw) + #no redraw on init. self.parent.staticPoints is not set yet. + + def paint(self, *args): + pass + def boundingRect(self, *args): + return oneRectToReturnThemAll + + def redraw(self, staticRepresentationList): + if not self.parent.staticPoints: + return None + removeInstancesFromScene(self.TimePoint) + sliceStartInSeconds = 0 #counted, not calculated + gridCounter = 0 # int("how often was a gridMarker generated") + result = [] + for nowPoint, nextPoint in pairwise(self.parent.staticPoints): + """Values we can't calculate: + sliceEndInTicks / ticksPerSecond . sliceEndInTicks is an absolute position. + but ticksPerSecond changes with every slice. Therefore you would discard all + ticksPerSecond value except the last and calculate a wrong value. + Instead we need to calculate the seconds always in the slice and then count + the overall length. + """ + + tempoForThisSlice = abs(nowPoint["value"]) + + sliceDurationInTicks = nextPoint["position"] - nowPoint["position"] + ticksPerSecondForThisSlice = tempoForThisSlice * api.D4 / 60 # ["value"] is normalized beatsPerMinute(!) for quarter notes. calculated from "units" and "referenceTicks" + sliceDurationInSeconds = sliceDurationInTicks / ticksPerSecondForThisSlice + sliceEndInSeconds = sliceStartInSeconds + sliceDurationInSeconds + + while sliceStartInSeconds < (gridCounter+1) * self.gridInSeconds <= sliceEndInSeconds: #is the next grid marker(+1) in the current slice? + gridCounter += 1 + secondsSinceLastTempoChange = gridCounter * self.gridInSeconds - sliceStartInSeconds + + posInTicks = nowPoint["position"] + secondsSinceLastTempoChange * ticksPerSecondForThisSlice + assert nowPoint["position"] <= posInTicks <= nextPoint["position"] + result.append((posInTicks, gridCounter * self.gridInSeconds)) + + sliceStartInSeconds = sliceEndInSeconds + + #After the loop both sliceStartInSeconds and sliceEndInSeconds are equal to the overall length of the track in seconds + #Add an end marker to the results and create the qGraphicItems to display the time markers. + if nextPoint["position"] > 0: + result.append((nextPoint["position"], sliceEndInSeconds)) + + for tickPos, secPos in result: + timePoint = self.TimePoint(self, secPos) + timePoint.setParentItem(self) + timePoint.setPos(tickPos / constantsAndConfigs.ticksToPixelRatio, 10) + + + def stretchXCoordinates(self, factor): + """Does NOT just reposition the existing items but displays a different + time grid""" + for timePoint in self.TimePoint.instances: + timePoint.setX(timePoint.pos().x() * factor) + + + + diff --git a/qtgui/constantsAndConfigs.py b/qtgui/constantsAndConfigs.py new file mode 100644 index 0000000..5db06bc --- /dev/null +++ b/qtgui/constantsAndConfigs.py @@ -0,0 +1,177 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +import logging; logging.info("import {}".format(__file__)) + +import engine.api as api +from PyQt5 import QtGui + +class ConstantsAndConfigs(object): + def __init__(self): + self.ticksToPixelRatio = 128*3*5 #bigger value means less space between notes #api.D128 and 128*3*5 is also good. This gets changed during runtime as "Stretch Factor". Also: the QSettings save and reload this on a per-file basis. + #a quarter note has 53760 ticks. that is 53760 / 1920 = 28 pixels. + self.stafflineGap = 7 #it is 7 because it is an odd number, which has a middle. 123 4 567 which translates 1:1 to pixels. + self.beamHeight = 2 + self.magicPixel = 4 + self.negativeMagicPixel = -2 + self.trackHeight = self.stafflineGap * 10 + self.trackHeight = self.stafflineGap * 12 + self.gridRhythm = api.D4 #Default value is quarter. The QSettings save and reload this on a per-file basis. + self.gridOpacity = 0.1 #this is only the default value. Once changed a QSetting will be used instead. + self.noteHeadMode = True #False means rectangle noteheads + self.followPlayhead = True #camera follows the playhead during playback. + self.duringPlayback = False #set by a callback. + self.velocityToPixelRatio = 2 #2.0 is the default. 128 pixels maximum. + + self.availableEditModes = ("notation", "cc", "block") + + self.ccViewValue = 0 #0-127. Only has effect if ccView is True + self.ccViewCallbacks = [] #list of functions. For example the main Window CC spin box and the block Editor CC spin box. + + self._snapToGrid = True # For CC point and Tempo point placements + self.snapToGridCallbacks = [] # see ccViewCallbacks + + self.zoomFactor = 1 # #Initial Zoom Level. Also hardcoded into scoreView.zoomNull + self.maximumZoomOut = 0.25 + + + #fonts which are used in the QGraphicsScenes. They are special because they don't scale with the DPI. + self.fontDB = QtGui.QFontDatabase() + #fid = self.fontDB.addApplicationFont("gui/resources/freesans.ttf") + #if fid == -1: + # raise ValueError("Freesans.ttf not loaded ") + + fid = self.fontDB.addApplicationFont(":euterpe.ttf") + if fid == -1: + raise ValueError("euterpe.ttf not loaded. Make sure resources were generated") + + #For easier programWide access move these to constantsAndConfigs + #constantsAndConfigs.theFont = self.fontDB.font("FreeSans", "", 13) + #constantsAndConfigs.theFont.setPixelSize(13) #It is very important to set the pixel size before setting the font to the text + self.musicFont = self.fontDB.font("Euterpe", "", 13) + self.musicFont.setPixelSize(13) #It is very important to set the pixel size before setting the font to the text + + self.dynamics = ["f", "ff", "p", "pp", "mf", "mp", "tacet"] + + self.prettyRhythms = [ #list because we need item order + (api.DL, "0.25 Longa"), + (api.DB, "0.5 Brevis"), + (api.D1, "1 Whole"), + (api.D2, "2 Half"), + (api.D4, "4 Quarter"), + (api.D8, "8 Eigth"), + (api.D16, "16 Sixteenth"), + (api.D32, "32 Thirthy-Second"), + (api.D64, "64 Sixty-Fourth"), + (api.D128, "128 Hundred Twenty-Eighth "), + (api.D256, "256 Two-hundred Fifty-Sixth"), + ] + self.prettyRhythmsStrings = [v for k,v in self.prettyRhythms] + self.prettyRhythmsValues = [k for k,v in self.prettyRhythms] + + self.prettyExtendedRhythms = [ #list because we need item order + (api.DL, "0.25 Longa"), + (api.DB, "0.5 Brevis"), + (api.D1, "1 Whole"), + (api.D2, "2 Half "), + (api.D4, "4 Quarter"), + (api.D8, "8 Eigth"), + (api.D16, "16 Sixteenth"), + (api.D32, "32 Thirthy-Second"), + (api.D64, "64 Sixty-Fourth"), + (api.D128, "128 Hundred Twenty-Eighth"), + + (1.5*api.DL, "Dotted 0.25 Longa"), + (1.5*api.DB, "Dotted 0.5 Brevis"), + (1.5*api.D1, "Dotted 1 Whole"), + (1.5*api.D2, "Dotted 2 Half"), + (1.5*api.D4, "Dotted 4 Quarter"), + (1.5*api.D8, "Dotted 8 Eigth "), + (1.5*api.D16, "Dotted 16 Sixteenth"), + (1.5*api.D32, "Dotted 32 Thirthy-Second"), + (1.5*api.D64, "Dotted 64 Sixty-Fourth "), + (1.5*api.D128, "Dotted 128 Hundred Twenty-Eighth "), + + ] + self.prettyExtendedRhythmsStrings = [v for k,v in self.prettyExtendedRhythms] + self.prettyExtendedRhythmsValues = [k for k,v in self.prettyExtendedRhythms] + + #use with constantsAndConfigs.musicFont + self.realNoteDisplay = { + api.DB : "𝅜", + api.D1 : "𝅝", + api.D2 : "𝅗𝅥", + api.D4 : "𝅘𝅥", + api.D8 : "𝅘𝅥𝅮", + api.D16 : "𝅘𝅥𝅯", + api.D32 : "𝅘𝅥𝅰", + api.D64 : "𝅘𝅥𝅱", + api.D128 : "𝅘𝅥𝅲", + + 1.5 * api.DB : "𝅜𝅭", #dotted DB + 1.5 * api.D1 : "𝅝𝅭", #dotted D1 + 1.5 * api.D2 : "𝅗𝅥𝅭", #dotted D2 + 1.5 * api.D4 : "𝅘𝅥𝅭", #dotted D4 + 1.5 * api.D8 : "𝅘𝅥𝅮𝅭", #dotted D8 + 1.5 * api.D16 : "𝅘𝅥𝅯𝅭", #dotted D16 + 1.5 * api.D32 : "𝅘𝅥𝅰𝅭", #dotted D32 + 1.5 * api.D64 : "𝅘𝅥𝅱𝅭", #dotted D64 + 1.5 * api.D128 : "𝅘𝅥𝅲𝅭", #dotted D128 + + 2.25 * api.DB : "𝅜𝅭", #double dotted DB + 2.25 * api.D1 : "𝅝𝅭", #double dotted D1 + 2.25 * api.D2 : "𝅗𝅥𝅭", #double dotted D2 + 2.25 * api.D4 : "𝅘𝅥𝅭", #double dotted D4 + 2.25 * api.D8 : "𝅘𝅥𝅮𝅭", #double dotted D8 + 2.25 * api.D16 : "𝅘𝅥𝅯𝅭", #double dotted D16 + 2.25 * api.D32 : "𝅘𝅥𝅰𝅭", #double dotted D32 + 2.25 * api.D64 : "𝅘𝅥𝅱𝅭", #double dotted D64 + 2.25 * api.D128 : "𝅘𝅥𝅲𝅭", #double dotted D128 + } + + + self.commonNotes = [ #list because we need item order + (api.D1, "𝅝"), #D1 + (api.D2 , "𝅗𝅥"), #D2 + (api.D4 , "𝅘𝅥"), #D4 + (api.D8 , "𝅘𝅥𝅮"), #D8 + + (1.5 * api.D1 , "𝅝𝅭"), #dotted D1 + (1.5 * api.D2 , "𝅗𝅥𝅭"), #dotted D2 + (1.5 * api.D4 , "𝅘𝅥𝅭"), #dotted D4 + (1.5 * api.D8 , "𝅘𝅥𝅮𝅭"), #dotted D8 + ] + + self.realNotesStrings = [v for k,v in self.commonNotes] + self.realNotesValues = [k for k,v in self.commonNotes] + + @property + def snapToGrid(self): + return self._snapToGrid + + @snapToGrid.setter + def snapToGrid(self, value): + self._snapToGrid = value + for func in self.snapToGridCallbacks: + func() + + +constantsAndConfigs = ConstantsAndConfigs() #singleton diff --git a/qtgui/cursor.py b/qtgui/cursor.py new file mode 100644 index 0000000..a116d1e --- /dev/null +++ b/qtgui/cursor.py @@ -0,0 +1,242 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from PyQt5 import QtCore, QtGui, QtWidgets, QtWidgets +from .constantsAndConfigs import constantsAndConfigs +import engine.api as api + +pen = QtGui.QPen() +pen.setCapStyle(QtCore.Qt.RoundCap) +pen.setJoinStyle(QtCore.Qt.RoundJoin) +pen.setWidth(2) +#pen.setColor(QtGui.QColor("red")) + +class PitchCursor(QtWidgets.QGraphicsRectItem): + def __init__(self): + """Does not need the actual dotOnLine. + this is done by the parent cursor. + This is just a fancy rect.""" + #super().__init__(constantsAndConfigs.magicPixel, 2, constantsAndConfigs.magicPixel*3, constantsAndConfigs.stafflineGap/3) + super().__init__(0, 1, constantsAndConfigs.magicPixel*3, 5) + self.setBrush(QtGui.QColor("cyan")) + self.setPen(pen) + self.setEnabled(False) + +class PositionCursor(QtWidgets.QGraphicsRectItem): + def __init__(self): + """Does not need the actual position. + this is done by the parent cursor + This is just a fancy rect.""" + super().__init__(-1.5*constantsAndConfigs.magicPixel, -3.5*constantsAndConfigs.stafflineGap, constantsAndConfigs.magicPixel*1.5, 7*constantsAndConfigs.stafflineGap) + self.setBrush(QtGui.QColor("cyan")) + self.setPen(pen) + self.setScale(0.8) + self.setEnabled(False) + +class Cursor(QtWidgets.QGraphicsItemGroup): + """A cursor that shows the vertical + as well as the horizontal position + """ + def __init__(self): + super().__init__() + self.cursorExportObject = None #the last cached cursor object aka the current cursor position + self.pitch = PitchCursor() + self.addToGroup(self.pitch) + self.position = PositionCursor() + self.addToGroup(self.position) + api.callbacks.setCursor.append(self.setCursor) + self.setEnabled(False) + + def clearItemHighlight(self): + """Gets called before a track changes. Most of the time when a new item is inserted/deleted. + This means the gui track will be recreated and a current highlight on an item might get + deleted while still on the item. This results in a qt crash + """ + Cursor.hightlightEffect = QtWidgets.QGraphicsColorizeEffect() #default strength of the effect is 1.0 + Cursor.hightlightEffect.setColor(QtGui.QColor("cyan")) + Cursor.hightlightEffect.setStrength(0.7) #opacity of the effect + + #Cursor.stafflineEffect = QtWidgets.QGraphicsColorizeEffect() #default strength of the effect is 1.0 + #Cursor.stafflineEffect.setColor(QtGui.QColor("cyan")) + #Cursor.stafflineEffect.setStrength(1) #opacity of the effect + + Cursor.stafflineEffect = QtWidgets.QGraphicsDropShadowEffect() + Cursor.stafflineEffect.setColor(QtGui.QColor("black")) + Cursor.stafflineEffect.setOffset(0,0) + Cursor.stafflineEffect.setBlurRadius(5) + + def setCursor(self, cursorExportObject): + self.cursorExportObject = cursorExportObject + self.scene().parentView.setFocus() + + self.pitch.setY(constantsAndConfigs.stafflineGap * cursorExportObject["dotOnLine"] / 2 - 3) #the same as a notehead + + x = cursorExportObject["tickindex"] / constantsAndConfigs.ticksToPixelRatio + #Finally shift the Position to the correct track. Trackindex from 0, naturally. + #self.setPos(x, constantsAndConfigs.timeLineOffsetNoteEditor + cursorExportObject["trackIndex"] * constantsAndConfigs.trackHeight) + currentGuiTrack = self.scene().tracks[cursorExportObject["trackId"]] + self.setPos(x, currentGuiTrack.y() ) + + try: + guiItemAtCursor = currentGuiTrack.itemById(cursorExportObject["itemId"]) + if not guiItemAtCursor.staticItem["completeDuration"] > 0: + #guiItemAtCursor has no duration. is type guiItemAtCursor.staticItem["type"] + Cursor.hightlightEffect.setEnabled(True) + guiItemAtCursor.setGraphicsEffect(Cursor.hightlightEffect) + else: + Cursor.hightlightEffect.setEnabled(False) + + except StopIteration: + Cursor.hightlightEffect.setEnabled(False) #happens only on startup or appending (which is the same) + + #Highlight the current staffline + if currentGuiTrack.staticExportItem["double"] and cursorExportObject["dotOnLine"] in (8, 10, 12, 14, 16): + lineNumber = int(cursorExportObject["dotOnLine"] / 2) + 1 #gui-stafflines are counted from 0 to n, top to bottom (listindex) while backend stafflines begin on -4 + currentGuiTrack.staffLines[lineNumber].setGraphicsEffect(Cursor.stafflineEffect) + Cursor.stafflineEffect.setEnabled(True) + elif cursorExportObject["dotOnLine"] in (-4, -2, 0, 2, 4): + lineNumber = int(cursorExportObject["dotOnLine"] / 2) + 2 #gui-stafflines are counted from 0 to n, top to bottom (listindex) while backend stafflines begin on -4 + currentGuiTrack.staffLines[lineNumber].setGraphicsEffect(Cursor.stafflineEffect) + Cursor.stafflineEffect.setEnabled(True) + else: + Cursor.stafflineEffect.setEnabled(False) + +class Playhead(QtWidgets.QGraphicsLineItem): + def __init__(self, parentScoreScene): + super().__init__(0, 0, 0, 0) # (x1, y1, x2, y2) + self.parentScoreScene = parentScoreScene + p = QtGui.QPen() + p.setColor(QtGui.QColor("red")) + p.setCosmetic(True) + self.setPen(p) + self.setAcceptHoverEvents(True) + api.callbacks.setPlaybackTicks.append(self.setCursorPosition) + api.callbacks.tracksChanged.append(self.setLineToWindowHeigth) #for new tracks + api.callbacks.updateTempoTrack.append(self.setLineToWindowHeigth) + self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable) + self.setAcceptedMouseButtons(QtCore.Qt.LeftButton) + self.setZValue(90) + #self.parentScoreScene.parentView.verticalScrollBar().valueChanged.connect(self.setLineToWindowHeigth) + #self.hide() + #self.maxHeight = QtWidgets.QDesktopWidget().geometry().height() #we really hope the screen resolution does not change during the session. + + def setCursorPosition(self, tickindex:int, playbackStatus:bool): + """Set the playhead to the right position, but keep the viewport stable. + Shift the entire "page" if the cursor becomes invisible because its steps outside the viewport""" + self.setLineToWindowHeigth() + x = tickindex / constantsAndConfigs.ticksToPixelRatio + self.setX(x) + if constantsAndConfigs.followPlayhead and playbackStatus: + scenePos = self.parentScoreScene.parentView.mapFromScene(self.pos()) + cursorViewPosX = scenePos.x() #the cursor position in View coordinates + width = self.parentScoreScene.parentView.geometry().width() + if cursorViewPosX <= 0 or cursorViewPosX >= width: #"pageflip" + self.parentScoreScene.parentView.horizontalScrollBar().setValue(x * constantsAndConfigs.zoomFactor) + + + def _Deprecated__ScrollingVariant___setCursorPosition(self, tickindex): + """the tickindex to pixel index on the x axis is a fixed 1:n + relation. What you see is where you are. No jumps, the playhead + stays on course.""" + self.setLineToWindowHeigth() + x = tickindex / constantsAndConfigs.ticksToPixelRatio + self.setX(x) + if constantsAndConfigs.followPlayhead and api.playbackStatus(): + #self.parentScoreScene.parentView.centerOn(self) Do not use center on. It centers for Y as well which creates a recursion and the score gets taller and taller. + #self.scene().parentView.horizontalScrollBar().setValue(x - 150) + #xV = self.parentScoreScene.parentView.mapFromScene(x,0).x() + self.parentScoreScene.parentView.horizontalScrollBar().setValue(x - 150) #x does not with zoom levels. the bar drifts away. + + def setLineToWindowHeigth(self, *args): + h = self.parentScoreScene.cachedSceneHeight + self.setLine(0, 0, 0, h) #(x1, y1, x2, y2) + + def mouseMoveEvent(self, event): + """Only allow movement in Y direction. + Only triggered when dragging.""" + #super().mouseMoveEvent(event) allows free movement through Qt. Don't call that. + p = event.scenePos().x() + if p < 0: + p = 0 + #self.setPos(p, self.scene().parentView.mapToScene(0, 0).y()) + self.setX(p) + api.seek(p * constantsAndConfigs.ticksToPixelRatio) + event.accept() + + def mouseReleaseEvent(self, event): + if constantsAndConfigs.snapToGrid: + x = event.scenePos().x() * constantsAndConfigs.ticksToPixelRatio + p = round(x / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + if p < 0: + p = 0 + api.seek(p) + + def hoverEnterEvent(self, event): + self.setCursor(QtCore.Qt.SizeHorCursor) + self.update() #the default implementation calls this. event.accept/ignore has no effect. + + def hoverLeaveEvent(self, event): + self.unsetCursor() + self.update() #the default implementation calls this. event.accept/ignore has no effect. + +class Selection(QtWidgets.QGraphicsRectItem): + """A semi-transparent rectangle that shows the current selection""" + def __init__(self): + super().__init__(0, 0, 0, 0) + + self.validBrush = QtGui.QBrush(QtGui.QColor("grey")) + self.invalidBrush = QtGui.QBrush(QtGui.QColor("grey")) + self.invalidBrush.setStyle(QtCore.Qt.DiagCrossPattern) + + self.setPen(pen) + self.setOpacity(0.2) + self.setEnabled(False) + api.callbacks.setSelection.append(self.setSelection) + + def setSelection(self, tupleOfCursorExportObjects): + if tupleOfCursorExportObjects: + validSelection, topleftCursorObject, bottomRightCursorObject = tupleOfCursorExportObjects + if validSelection: + self.setBrush(self.validBrush) + else: + self.setBrush(self.invalidBrush) + + topGuiTrack = self.scene().tracks[topleftCursorObject["trackId"]] + bottomGuiTrack = self.scene().tracks[bottomRightCursorObject["trackId"]] + + #y = constantsAndConfigs.timeLineOffsetNoteEditor + topleftCursorObject["trackIndex"] * constantsAndConfigs.trackHeight - constantsAndConfigs.trackHeight/2 + #h = (bottomRightCursorObject["trackIndex"] - topleftCursorObject["trackIndex"]) * constantsAndConfigs.trackHeight + constantsAndConfigs.trackHeight + + x = topleftCursorObject["tickindex"] / constantsAndConfigs.ticksToPixelRatio + w = (bottomRightCursorObject["tickindex"] - topleftCursorObject["tickindex"]) / constantsAndConfigs.ticksToPixelRatio + y = topGuiTrack.y() - constantsAndConfigs.trackHeight/2 + + if bottomGuiTrack.staticExportItem["double"]: + h = bottomGuiTrack.y() - y + constantsAndConfigs.trackHeight + else: + h = bottomGuiTrack.y() - y + constantsAndConfigs.trackHeight/2 + + + self.setRect(0, 0, w-3, h) #substract a few pixels to make it look less ambigious if the last item on the right edge is included or not (it is not) + self.setPos(x,y) + self.setVisible(True) + else: #no selection + self.setVisible(False) diff --git a/qtgui/designer/clefs.ui b/qtgui/designer/clefs.ui new file mode 100644 index 0000000..37211eb --- /dev/null +++ b/qtgui/designer/clefs.ui @@ -0,0 +1,49 @@ + + + Form + + + + 0 + 0 + 585 + 130 + + + + Form + + + + + + [2] Bass + + + + + + + [3] Treble +Oct + + + + + + + [4] Bass -Oct + + + + + + + [1] Treble + + + + + + + + diff --git a/qtgui/designer/mainwindow.py b/qtgui/designer/mainwindow.py new file mode 100644 index 0000000..32056e0 --- /dev/null +++ b/qtgui/designer/mainwindow.py @@ -0,0 +1,956 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'mainwindow.ui' +# +# Created by: PyQt5 UI code generator 5.11.3 +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore, QtGui, QtWidgets + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(1036, 625) + self.centralwidget = QtWidgets.QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.mainStackWidget = QtWidgets.QStackedWidget(self.centralwidget) + self.mainStackWidget.setObjectName("mainStackWidget") + self.verticalLayout_2.addWidget(self.mainStackWidget) + MainWindow.setCentralWidget(self.centralwidget) + self.statusbar = QtWidgets.QStatusBar(MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + self.toolBar = QtWidgets.QToolBar(MainWindow) + self.toolBar.setMovable(False) + self.toolBar.setFloatable(False) + self.toolBar.setObjectName("toolBar") + MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) + self.menubar = QtWidgets.QMenuBar(MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1036, 20)) + self.menubar.setObjectName("menubar") + self.menuHelp = QtWidgets.QMenu(self.menubar) + self.menuHelp.setObjectName("menuHelp") + self.menuObjects = QtWidgets.QMenu(self.menubar) + self.menuObjects.setObjectName("menuObjects") + self.menuGeneric = QtWidgets.QMenu(self.menubar) + self.menuGeneric.setEnabled(True) + self.menuGeneric.setObjectName("menuGeneric") + self.menuType_Here = QtWidgets.QMenu(self.menuGeneric) + self.menuType_Here.setObjectName("menuType_Here") + self.menuTracks = QtWidgets.QMenu(self.menubar) + self.menuTracks.setObjectName("menuTracks") + self.menuEdit = QtWidgets.QMenu(self.menubar) + self.menuEdit.setObjectName("menuEdit") + self.menuView = QtWidgets.QMenu(self.menubar) + self.menuView.setObjectName("menuView") + self.menuMode = QtWidgets.QMenu(self.menuView) + self.menuMode.setObjectName("menuMode") + self.menu = QtWidgets.QMenu(self.menubar) + self.menu.setEnabled(False) + self.menu.setObjectName("menu") + self.menu_2 = QtWidgets.QMenu(self.menubar) + self.menu_2.setEnabled(False) + self.menu_2.setObjectName("menu_2") + self.menuEdit_MusicItem = QtWidgets.QMenu(self.menubar) + self.menuEdit_MusicItem.setObjectName("menuEdit_MusicItem") + self.menuEdit_2 = QtWidgets.QMenu(self.menubar) + self.menuEdit_2.setObjectName("menuEdit_2") + self.menuToolbox = QtWidgets.QMenu(self.menubar) + self.menuToolbox.setObjectName("menuToolbox") + self.menuOrder = QtWidgets.QMenu(self.menuToolbox) + self.menuOrder.setObjectName("menuOrder") + self.menuInsert = QtWidgets.QMenu(self.menuToolbox) + self.menuInsert.setObjectName("menuInsert") + self.menuMIDI = QtWidgets.QMenu(self.menuToolbox) + self.menuMIDI.setObjectName("menuMIDI") + self.menuLilypond = QtWidgets.QMenu(self.menubar) + self.menuLilypond.setObjectName("menuLilypond") + MainWindow.setMenuBar(self.menubar) + self.leftToolBar = QtWidgets.QToolBar(MainWindow) + self.leftToolBar.setEnabled(True) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.leftToolBar.sizePolicy().hasHeightForWidth()) + self.leftToolBar.setSizePolicy(sizePolicy) + self.leftToolBar.setMinimumSize(QtCore.QSize(26, 0)) + self.leftToolBar.setMaximumSize(QtCore.QSize(26, 16777215)) + self.leftToolBar.setMovable(False) + self.leftToolBar.setAllowedAreas(QtCore.Qt.LeftToolBarArea) + self.leftToolBar.setFloatable(False) + self.leftToolBar.setObjectName("leftToolBar") + MainWindow.addToolBar(QtCore.Qt.LeftToolBarArea, self.leftToolBar) + self.actionUp = QtWidgets.QAction(MainWindow) + self.actionUp.setObjectName("actionUp") + self.actionDown = QtWidgets.QAction(MainWindow) + self.actionDown.setObjectName("actionDown") + self.actionLeft = QtWidgets.QAction(MainWindow) + self.actionLeft.setObjectName("actionLeft") + self.actionRight = QtWidgets.QAction(MainWindow) + self.actionRight.setObjectName("actionRight") + self.actionModal1 = QtWidgets.QAction(MainWindow) + self.actionModal1.setObjectName("actionModal1") + self.actionModal2 = QtWidgets.QAction(MainWindow) + self.actionModal2.setObjectName("actionModal2") + self.actionModal3 = QtWidgets.QAction(MainWindow) + self.actionModal3.setObjectName("actionModal3") + self.actionModal4 = QtWidgets.QAction(MainWindow) + self.actionModal4.setObjectName("actionModal4") + self.actionModal5 = QtWidgets.QAction(MainWindow) + self.actionModal5.setObjectName("actionModal5") + self.actionModal6 = QtWidgets.QAction(MainWindow) + self.actionModal6.setObjectName("actionModal6") + self.actionModal7 = QtWidgets.QAction(MainWindow) + self.actionModal7.setObjectName("actionModal7") + self.actionModal8 = QtWidgets.QAction(MainWindow) + self.actionModal8.setObjectName("actionModal8") + self.actionModal9 = QtWidgets.QAction(MainWindow) + self.actionModal9.setObjectName("actionModal9") + self.actionModal0 = QtWidgets.QAction(MainWindow) + self.actionModal0.setObjectName("actionModal0") + self.actionDelete = QtWidgets.QAction(MainWindow) + self.actionDelete.setObjectName("actionDelete") + self.actionBackspace = QtWidgets.QAction(MainWindow) + self.actionBackspace.setObjectName("actionBackspace") + self.actionShift_modal1 = QtWidgets.QAction(MainWindow) + self.actionShift_modal1.setObjectName("actionShift_modal1") + self.actionShift_modal2 = QtWidgets.QAction(MainWindow) + self.actionShift_modal2.setObjectName("actionShift_modal2") + self.actionShift_modal3 = QtWidgets.QAction(MainWindow) + self.actionShift_modal3.setObjectName("actionShift_modal3") + self.actionShift_modal4 = QtWidgets.QAction(MainWindow) + self.actionShift_modal4.setObjectName("actionShift_modal4") + self.actionShift_modal5 = QtWidgets.QAction(MainWindow) + self.actionShift_modal5.setObjectName("actionShift_modal5") + self.actionShift_modal6 = QtWidgets.QAction(MainWindow) + self.actionShift_modal6.setObjectName("actionShift_modal6") + self.actionShift_modal7 = QtWidgets.QAction(MainWindow) + self.actionShift_modal7.setObjectName("actionShift_modal7") + self.actionShift_modal8 = QtWidgets.QAction(MainWindow) + self.actionShift_modal8.setObjectName("actionShift_modal8") + self.actionShift_modal9 = QtWidgets.QAction(MainWindow) + self.actionShift_modal9.setObjectName("actionShift_modal9") + self.actionShift_modal0 = QtWidgets.QAction(MainWindow) + self.actionShift_modal0.setObjectName("actionShift_modal0") + self.actionAddCursorNoteToChord = QtWidgets.QAction(MainWindow) + self.actionAddCursorNoteToChord.setShortcutContext(QtCore.Qt.WindowShortcut) + self.actionAddCursorNoteToChord.setObjectName("actionAddCursorNoteToChord") + self.actionDeleteCursorNoteFromChord = QtWidgets.QAction(MainWindow) + self.actionDeleteCursorNoteFromChord.setObjectName("actionDeleteCursorNoteFromChord") + self.actionAdd_Track = QtWidgets.QAction(MainWindow) + self.actionAdd_Track.setObjectName("actionAdd_Track") + self.actionTrackUp = QtWidgets.QAction(MainWindow) + self.actionTrackUp.setObjectName("actionTrackUp") + self.actionTrackDown = QtWidgets.QAction(MainWindow) + self.actionTrackDown.setObjectName("actionTrackDown") + self.actionHead = QtWidgets.QAction(MainWindow) + self.actionHead.setObjectName("actionHead") + self.actionTail = QtWidgets.QAction(MainWindow) + self.actionTail.setObjectName("actionTail") + self.actionTrackFirst = QtWidgets.QAction(MainWindow) + self.actionTrackFirst.setObjectName("actionTrackFirst") + self.actionTrackLast = QtWidgets.QAction(MainWindow) + self.actionTrackLast.setObjectName("actionTrackLast") + self.actionSharpen_Note = QtWidgets.QAction(MainWindow) + self.actionSharpen_Note.setObjectName("actionSharpen_Note") + self.actionFlatten_Note = QtWidgets.QAction(MainWindow) + self.actionFlatten_Note.setObjectName("actionFlatten_Note") + self.actionMeasureLeft = QtWidgets.QAction(MainWindow) + self.actionMeasureLeft.setObjectName("actionMeasureLeft") + self.actionMeasureRight = QtWidgets.QAction(MainWindow) + self.actionMeasureRight.setObjectName("actionMeasureRight") + self.actionStep_Up = QtWidgets.QAction(MainWindow) + self.actionStep_Up.setObjectName("actionStep_Up") + self.actionStep_Down = QtWidgets.QAction(MainWindow) + self.actionStep_Down.setObjectName("actionStep_Down") + self.actionOctave_Up = QtWidgets.QAction(MainWindow) + self.actionOctave_Up.setObjectName("actionOctave_Up") + self.actionOctave_Down = QtWidgets.QAction(MainWindow) + self.actionOctave_Down.setObjectName("actionOctave_Down") + self.actionAugment = QtWidgets.QAction(MainWindow) + self.actionAugment.setObjectName("actionAugment") + self.actionDiminish = QtWidgets.QAction(MainWindow) + self.actionDiminish.setObjectName("actionDiminish") + self.actionAppend_Block = QtWidgets.QAction(MainWindow) + self.actionAppend_Block.setObjectName("actionAppend_Block") + self.actionSplit_Current_Block = QtWidgets.QAction(MainWindow) + self.actionSplit_Current_Block.setObjectName("actionSplit_Current_Block") + self.actionDuplicate = QtWidgets.QAction(MainWindow) + self.actionDuplicate.setObjectName("actionDuplicate") + self.actionCreate_Linked_Copy = QtWidgets.QAction(MainWindow) + self.actionCreate_Linked_Copy.setObjectName("actionCreate_Linked_Copy") + self.actionDelete_Current_Block = QtWidgets.QAction(MainWindow) + self.actionDelete_Current_Block.setObjectName("actionDelete_Current_Block") + self.actionToggle_Notehead_Rectangles = QtWidgets.QAction(MainWindow) + self.actionToggle_Notehead_Rectangles.setCheckable(True) + self.actionToggle_Notehead_Rectangles.setObjectName("actionToggle_Notehead_Rectangles") + self.actionPlayPause = QtWidgets.QAction(MainWindow) + self.actionPlayPause.setObjectName("actionPlayPause") + self.actionPlayFromBeginning = QtWidgets.QAction(MainWindow) + self.actionPlayFromBeginning.setObjectName("actionPlayFromBeginning") + self.actionFollow_Playhead = QtWidgets.QAction(MainWindow) + self.actionFollow_Playhead.setCheckable(True) + self.actionFollow_Playhead.setChecked(True) + self.actionFollow_Playhead.setObjectName("actionFollow_Playhead") + self.actionPlayFromEditCursor = QtWidgets.QAction(MainWindow) + self.actionPlayFromEditCursor.setObjectName("actionPlayFromEditCursor") + self.actionStaccato = QtWidgets.QAction(MainWindow) + self.actionStaccato.setObjectName("actionStaccato") + self.actionCopy = QtWidgets.QAction(MainWindow) + self.actionCopy.setObjectName("actionCopy") + self.actionCut = QtWidgets.QAction(MainWindow) + self.actionCut.setObjectName("actionCut") + self.actionPaste = QtWidgets.QAction(MainWindow) + self.actionPaste.setObjectName("actionPaste") + self.actionUpOctave = QtWidgets.QAction(MainWindow) + self.actionUpOctave.setObjectName("actionUpOctave") + self.actionDownOctave = QtWidgets.QAction(MainWindow) + self.actionDownOctave.setObjectName("actionDownOctave") + self.actionDots = QtWidgets.QAction(MainWindow) + self.actionDots.setObjectName("actionDots") + self.actionCC_Mode = QtWidgets.QAction(MainWindow) + self.actionCC_Mode.setCheckable(True) + self.actionCC_Mode.setObjectName("actionCC_Mode") + self.CCactionSplit_Current_Block = QtWidgets.QAction(MainWindow) + self.CCactionSplit_Current_Block.setObjectName("CCactionSplit_Current_Block") + self.actionChange_Grid_Rhythm = QtWidgets.QAction(MainWindow) + self.actionChange_Grid_Rhythm.setCheckable(False) + self.actionChange_Grid_Rhythm.setChecked(False) + self.actionChange_Grid_Rhythm.setObjectName("actionChange_Grid_Rhythm") + self.actionSnap_To_Grid = QtWidgets.QAction(MainWindow) + self.actionSnap_To_Grid.setCheckable(True) + self.actionSnap_To_Grid.setChecked(True) + self.actionSnap_To_Grid.setObjectName("actionSnap_To_Grid") + self.actionAlt_modal1 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal1.setObjectName("actionAlt_modal1") + self.actionAlt_modal2 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal2.setObjectName("actionAlt_modal2") + self.actionAlt_modal3 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal3.setObjectName("actionAlt_modal3") + self.actionAlt_modal4 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal4.setObjectName("actionAlt_modal4") + self.actionAlt_modal5 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal5.setObjectName("actionAlt_modal5") + self.actionAlt_modal6 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal6.setObjectName("actionAlt_modal6") + self.actionAlt_modal7 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal7.setObjectName("actionAlt_modal7") + self.actionAlt_modal8 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal8.setObjectName("actionAlt_modal8") + self.actionAlt_modal9 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal9.setObjectName("actionAlt_modal9") + self.actionAlt_modal0 = QtWidgets.QAction(MainWindow) + self.actionAlt_modal0.setObjectName("actionAlt_modal0") + self.actionMidi_In_is_Active = QtWidgets.QAction(MainWindow) + self.actionMidi_In_is_Active.setCheckable(True) + self.actionMidi_In_is_Active.setObjectName("actionMidi_In_is_Active") + self.actionTie = QtWidgets.QAction(MainWindow) + self.actionTie.setObjectName("actionTie") + self.actionLegatoSlur = QtWidgets.QAction(MainWindow) + self.actionLegatoSlur.setObjectName("actionLegatoSlur") + self.actionTenuto = QtWidgets.QAction(MainWindow) + self.actionTenuto.setObjectName("actionTenuto") + self.actionTriplet = QtWidgets.QAction(MainWindow) + self.actionTriplet.setObjectName("actionTriplet") + self.actionCustom_Tuplets = QtWidgets.QAction(MainWindow) + self.actionCustom_Tuplets.setEnabled(False) + self.actionCustom_Tuplets.setObjectName("actionCustom_Tuplets") + self.actionPrevailingRest = QtWidgets.QAction(MainWindow) + self.actionPrevailingRest.setEnabled(False) + self.actionPrevailingRest.setObjectName("actionPrevailingRest") + self.actionSplit_in_2 = QtWidgets.QAction(MainWindow) + self.actionSplit_in_2.setObjectName("actionSplit_in_2") + self.actionSplit_in_3 = QtWidgets.QAction(MainWindow) + self.actionSplit_in_3.setObjectName("actionSplit_in_3") + self.actionCustom_Split = QtWidgets.QAction(MainWindow) + self.actionCustom_Split.setEnabled(True) + self.actionCustom_Split.setObjectName("actionCustom_Split") + self.actionUndo = QtWidgets.QAction(MainWindow) + self.actionUndo.setObjectName("actionUndo") + self.actionRedo = QtWidgets.QAction(MainWindow) + self.actionRedo.setObjectName("actionRedo") + self.actionJoin_with_next_Block = QtWidgets.QAction(MainWindow) + self.actionJoin_with_next_Block.setObjectName("actionJoin_with_next_Block") + self.actionSet_UpBeat = QtWidgets.QAction(MainWindow) + self.actionSet_UpBeat.setObjectName("actionSet_UpBeat") + self.actionSelectLeft = QtWidgets.QAction(MainWindow) + self.actionSelectLeft.setObjectName("actionSelectLeft") + self.actionSelectRight = QtWidgets.QAction(MainWindow) + self.actionSelectRight.setObjectName("actionSelectRight") + self.actionSelectMeasureLeft = QtWidgets.QAction(MainWindow) + self.actionSelectMeasureLeft.setObjectName("actionSelectMeasureLeft") + self.actionSelectMeasureRight = QtWidgets.QAction(MainWindow) + self.actionSelectMeasureRight.setObjectName("actionSelectMeasureRight") + self.actionSelectHead = QtWidgets.QAction(MainWindow) + self.actionSelectHead.setObjectName("actionSelectHead") + self.actionSelectTail = QtWidgets.QAction(MainWindow) + self.actionSelectTail.setObjectName("actionSelectTail") + self.actionSelectTrackUp = QtWidgets.QAction(MainWindow) + self.actionSelectTrackUp.setObjectName("actionSelectTrackUp") + self.actionSelectTrackDown = QtWidgets.QAction(MainWindow) + self.actionSelectTrackDown.setObjectName("actionSelectTrackDown") + self.actionSelectTrackFirst = QtWidgets.QAction(MainWindow) + self.actionSelectTrackFirst.setObjectName("actionSelectTrackFirst") + self.actionSelectTrackLast = QtWidgets.QAction(MainWindow) + self.actionSelectTrackLast.setObjectName("actionSelectTrackLast") + self.actionSelectUp = QtWidgets.QAction(MainWindow) + self.actionSelectUp.setObjectName("actionSelectUp") + self.actionSelectDown = QtWidgets.QAction(MainWindow) + self.actionSelectDown.setObjectName("actionSelectDown") + self.actionSelectUpOctave = QtWidgets.QAction(MainWindow) + self.actionSelectUpOctave.setObjectName("actionSelectUpOctave") + self.actionSelectDownOctave = QtWidgets.QAction(MainWindow) + self.actionSelectDownOctave.setObjectName("actionSelectDownOctave") + self.actionSelectTrack = QtWidgets.QAction(MainWindow) + self.actionSelectTrack.setObjectName("actionSelectTrack") + self.actionSelectMeasureColumn = QtWidgets.QAction(MainWindow) + self.actionSelectMeasureColumn.setObjectName("actionSelectMeasureColumn") + self.actionSelectAllTracks = QtWidgets.QAction(MainWindow) + self.actionSelectAllTracks.setObjectName("actionSelectAllTracks") + self.actionVelocityMore = QtWidgets.QAction(MainWindow) + self.actionVelocityMore.setObjectName("actionVelocityMore") + self.actionVelocityLess = QtWidgets.QAction(MainWindow) + self.actionVelocityLess.setObjectName("actionVelocityLess") + self.actionDurationModMore = QtWidgets.QAction(MainWindow) + self.actionDurationModMore.setObjectName("actionDurationModMore") + self.actionDurationModLess = QtWidgets.QAction(MainWindow) + self.actionDurationModLess.setObjectName("actionDurationModLess") + self.actionReset_Velocity_Duration_Mod = QtWidgets.QAction(MainWindow) + self.actionReset_Velocity_Duration_Mod.setObjectName("actionReset_Velocity_Duration_Mod") + self.actionWiden_Score_View = QtWidgets.QAction(MainWindow) + self.actionWiden_Score_View.setObjectName("actionWiden_Score_View") + self.actionShrink_Score_View = QtWidgets.QAction(MainWindow) + self.actionShrink_Score_View.setObjectName("actionShrink_Score_View") + self.actionData_Editor = QtWidgets.QAction(MainWindow) + self.actionData_Editor.setCheckable(True) + self.actionData_Editor.setObjectName("actionData_Editor") + self.actionClef = QtWidgets.QAction(MainWindow) + self.actionClef.setObjectName("actionClef") + self.actionMetrical_Instruction = QtWidgets.QAction(MainWindow) + self.actionMetrical_Instruction.setObjectName("actionMetrical_Instruction") + self.actionKey_Signature = QtWidgets.QAction(MainWindow) + self.actionKey_Signature.setObjectName("actionKey_Signature") + self.actionDynamics = QtWidgets.QAction(MainWindow) + self.actionDynamics.setObjectName("actionDynamics") + self.actionMulti_Measure_Rest = QtWidgets.QAction(MainWindow) + self.actionMulti_Measure_Rest.setObjectName("actionMulti_Measure_Rest") + self.actionTemporary_Tempo_Change = QtWidgets.QAction(MainWindow) + self.actionTemporary_Tempo_Change.setObjectName("actionTemporary_Tempo_Change") + self.actionBeam = QtWidgets.QAction(MainWindow) + self.actionBeam.setObjectName("actionBeam") + self.actionRemoveBeams = QtWidgets.QAction(MainWindow) + self.actionRemoveBeams.setObjectName("actionRemoveBeams") + self.actionTempo_Change = QtWidgets.QAction(MainWindow) + self.actionTempo_Change.setObjectName("actionTempo_Change") + self.actionDelete_Tempo_Change = QtWidgets.QAction(MainWindow) + self.actionDelete_Tempo_Change.setObjectName("actionDelete_Tempo_Change") + self.actionBlock_Mode = QtWidgets.QAction(MainWindow) + self.actionBlock_Mode.setCheckable(True) + self.actionBlock_Mode.setObjectName("actionBlock_Mode") + self.actionNotation_Mode = QtWidgets.QAction(MainWindow) + self.actionNotation_Mode.setCheckable(True) + self.actionNotation_Mode.setChecked(True) + self.actionNotation_Mode.setObjectName("actionNotation_Mode") + self.actionTransposeChord = QtWidgets.QAction(MainWindow) + self.actionTransposeChord.setObjectName("actionTransposeChord") + self.actionTranspose_Score = QtWidgets.QAction(MainWindow) + self.actionTranspose_Score.setObjectName("actionTranspose_Score") + self.actionSave = QtWidgets.QAction(MainWindow) + self.actionSave.setObjectName("actionSave") + self.actionExport_File = QtWidgets.QAction(MainWindow) + self.actionExport_File.setObjectName("actionExport_File") + self.actionImport_File_replaces_current = QtWidgets.QAction(MainWindow) + self.actionImport_File_replaces_current.setObjectName("actionImport_File_replaces_current") + self.actionUnlink_Current_Block = QtWidgets.QAction(MainWindow) + self.actionUnlink_Current_Block.setObjectName("actionUnlink_Current_Block") + self.actionDelete_All_Empty_Blocks = QtWidgets.QAction(MainWindow) + self.actionDelete_All_Empty_Blocks.setObjectName("actionDelete_All_Empty_Blocks") + self.actionBlockRight = QtWidgets.QAction(MainWindow) + self.actionBlockRight.setObjectName("actionBlockRight") + self.actionBlockLeft = QtWidgets.QAction(MainWindow) + self.actionBlockLeft.setObjectName("actionBlockLeft") + self.actionSelectBlockRight = QtWidgets.QAction(MainWindow) + self.actionSelectBlockRight.setObjectName("actionSelectBlockRight") + self.actionSelectBlockLeft = QtWidgets.QAction(MainWindow) + self.actionSelectBlockLeft.setObjectName("actionSelectBlockLeft") + self.actionPedalNotes = QtWidgets.QAction(MainWindow) + self.actionPedalNotes.setObjectName("actionPedalNotes") + self.actionReverse = QtWidgets.QAction(MainWindow) + self.actionReverse.setObjectName("actionReverse") + self.actionDuplicateItem = QtWidgets.QAction(MainWindow) + self.actionDuplicateItem.setObjectName("actionDuplicateItem") + self.actionRandom = QtWidgets.QAction(MainWindow) + self.actionRandom.setObjectName("actionRandom") + self.actionAscending = QtWidgets.QAction(MainWindow) + self.actionAscending.setObjectName("actionAscending") + self.actionDescending = QtWidgets.QAction(MainWindow) + self.actionDescending.setObjectName("actionDescending") + self.actionMirror_around_Cursor = QtWidgets.QAction(MainWindow) + self.actionMirror_around_Cursor.setObjectName("actionMirror_around_Cursor") + self.actionInsert_Random = QtWidgets.QAction(MainWindow) + self.actionInsert_Random.setObjectName("actionInsert_Random") + self.actionRandom_chromatic_in_clef_range = QtWidgets.QAction(MainWindow) + self.actionRandom_chromatic_in_clef_range.setObjectName("actionRandom_chromatic_in_clef_range") + self.actionRandom_in_scale_in_clef_range = QtWidgets.QAction(MainWindow) + self.actionRandom_in_scale_in_clef_range.setObjectName("actionRandom_in_scale_in_clef_range") + self.actionRandom_pitch_from_clipboard = QtWidgets.QAction(MainWindow) + self.actionRandom_pitch_from_clipboard.setObjectName("actionRandom_pitch_from_clipboard") + self.actionProperties = QtWidgets.QAction(MainWindow) + self.actionProperties.setObjectName("actionProperties") + self.actionExport_to_Ly = QtWidgets.QAction(MainWindow) + self.actionExport_to_Ly.setObjectName("actionExport_to_Ly") + self.actionShow_PDF = QtWidgets.QAction(MainWindow) + self.actionShow_PDF.setObjectName("actionShow_PDF") + self.actionExport_to_pdf_file = QtWidgets.QAction(MainWindow) + self.actionExport_to_pdf_file.setObjectName("actionExport_to_pdf_file") + self.actionInstrument_Change = QtWidgets.QAction(MainWindow) + self.actionInstrument_Change.setObjectName("actionInstrument_Change") + self.actionProgram_Change_Relative = QtWidgets.QAction(MainWindow) + self.actionProgram_Change_Relative.setObjectName("actionProgram_Change_Relative") + self.actionBank_Change_Absolute = QtWidgets.QAction(MainWindow) + self.actionBank_Change_Absolute.setObjectName("actionBank_Change_Absolute") + self.actionBank_Change_Relative = QtWidgets.QAction(MainWindow) + self.actionBank_Change_Relative.setObjectName("actionBank_Change_Relative") + self.actionChannel_Change = QtWidgets.QAction(MainWindow) + self.actionChannel_Change.setObjectName("actionChannel_Change") + self.actionChannel_Change_Relative = QtWidgets.QAction(MainWindow) + self.actionChannel_Change_Relative.setObjectName("actionChannel_Change_Relative") + self.actionMIDI_Channel_Plus = QtWidgets.QAction(MainWindow) + self.actionMIDI_Channel_Plus.setObjectName("actionMIDI_Channel_Plus") + self.actionMIDI_Channel_Minus = QtWidgets.QAction(MainWindow) + self.actionMIDI_Channel_Minus.setObjectName("actionMIDI_Channel_Minus") + self.actionMIDI_Channel_Reset = QtWidgets.QAction(MainWindow) + self.actionMIDI_Channel_Reset.setObjectName("actionMIDI_Channel_Reset") + self.actionDelete_Current_Track = QtWidgets.QAction(MainWindow) + self.actionDelete_Current_Track.setObjectName("actionDelete_Current_Track") + self.actionUse_Current_Track_as_Metronome = QtWidgets.QAction(MainWindow) + self.actionUse_Current_Track_as_Metronome.setObjectName("actionUse_Current_Track_as_Metronome") + self.actionMetronome_Enabled = QtWidgets.QAction(MainWindow) + self.actionMetronome_Enabled.setCheckable(True) + self.actionMetronome_Enabled.setObjectName("actionMetronome_Enabled") + self.actionRandom_in_scale_in_cursor_plus_octave = QtWidgets.QAction(MainWindow) + self.actionRandom_in_scale_in_cursor_plus_octave.setObjectName("actionRandom_in_scale_in_cursor_plus_octave") + self.actionRandom_in_scale_in_octave_around_cursor = QtWidgets.QAction(MainWindow) + self.actionRandom_in_scale_in_octave_around_cursor.setObjectName("actionRandom_in_scale_in_octave_around_cursor") + self.actionCreate_pool_from_selection = QtWidgets.QAction(MainWindow) + self.actionCreate_pool_from_selection.setObjectName("actionCreate_pool_from_selection") + self.menuObjects.addAction(self.actionMetrical_Instruction) + self.menuObjects.addAction(self.actionClef) + self.menuObjects.addAction(self.actionKey_Signature) + self.menuObjects.addSeparator() + self.menuObjects.addAction(self.actionDynamics) + self.menuObjects.addAction(self.actionMulti_Measure_Rest) + self.menuObjects.addAction(self.actionLegatoSlur) + self.menuObjects.addSeparator() + self.menuObjects.addAction(self.actionTempo_Change) + self.menuObjects.addAction(self.actionDelete_Tempo_Change) + self.menuObjects.addAction(self.actionTemporary_Tempo_Change) + self.menuObjects.addSeparator() + self.menuObjects.addAction(self.actionInstrument_Change) + self.menuGeneric.addAction(self.actionBlockLeft) + self.menuGeneric.addAction(self.actionBlockRight) + self.menuGeneric.addAction(self.actionSelectBlockRight) + self.menuGeneric.addAction(self.actionSelectBlockLeft) + self.menuGeneric.addAction(self.actionDownOctave) + self.menuGeneric.addAction(self.actionAlt_modal1) + self.menuGeneric.addAction(self.actionAlt_modal2) + self.menuGeneric.addAction(self.actionUpOctave) + self.menuGeneric.addAction(self.actionUp) + self.menuGeneric.addAction(self.actionDown) + self.menuGeneric.addAction(self.actionLeft) + self.menuGeneric.addAction(self.actionRight) + self.menuGeneric.addAction(self.actionAlt_modal3) + self.menuGeneric.addAction(self.actionAlt_modal4) + self.menuGeneric.addAction(self.actionAlt_modal5) + self.menuGeneric.addAction(self.actionAlt_modal6) + self.menuGeneric.addAction(self.actionAlt_modal7) + self.menuGeneric.addAction(self.actionAlt_modal8) + self.menuGeneric.addAction(self.actionAlt_modal9) + self.menuGeneric.addAction(self.actionAlt_modal0) + self.menuGeneric.addAction(self.actionModal1) + self.menuGeneric.addAction(self.actionModal2) + self.menuGeneric.addAction(self.actionModal3) + self.menuGeneric.addAction(self.actionModal4) + self.menuGeneric.addAction(self.actionModal5) + self.menuGeneric.addAction(self.actionModal6) + self.menuGeneric.addAction(self.actionModal7) + self.menuGeneric.addAction(self.actionModal8) + self.menuGeneric.addAction(self.actionModal9) + self.menuGeneric.addAction(self.actionModal0) + self.menuGeneric.addAction(self.actionShift_modal1) + self.menuGeneric.addAction(self.actionShift_modal2) + self.menuGeneric.addAction(self.actionShift_modal3) + self.menuGeneric.addAction(self.actionShift_modal4) + self.menuGeneric.addAction(self.actionShift_modal5) + self.menuGeneric.addAction(self.actionShift_modal6) + self.menuGeneric.addAction(self.actionShift_modal7) + self.menuGeneric.addAction(self.actionShift_modal8) + self.menuGeneric.addAction(self.actionShift_modal9) + self.menuGeneric.addAction(self.actionShift_modal0) + self.menuGeneric.addAction(self.actionTrackUp) + self.menuGeneric.addAction(self.actionTrackDown) + self.menuGeneric.addAction(self.actionHead) + self.menuGeneric.addAction(self.actionTail) + self.menuGeneric.addAction(self.actionTrackFirst) + self.menuGeneric.addAction(self.actionMeasureRight) + self.menuGeneric.addAction(self.actionTrackLast) + self.menuGeneric.addAction(self.actionMeasureLeft) + self.menuGeneric.addAction(self.actionSelectLeft) + self.menuGeneric.addAction(self.actionSelectRight) + self.menuGeneric.addAction(self.actionSelectMeasureLeft) + self.menuGeneric.addAction(self.actionSelectMeasureRight) + self.menuGeneric.addAction(self.actionSelectHead) + self.menuGeneric.addAction(self.actionSelectTail) + self.menuGeneric.addAction(self.actionSelectTrackUp) + self.menuGeneric.addAction(self.actionSelectTrackDown) + self.menuGeneric.addAction(self.actionSelectTrackFirst) + self.menuGeneric.addAction(self.actionSelectTrackLast) + self.menuGeneric.addAction(self.actionSelectUp) + self.menuGeneric.addAction(self.actionSelectDown) + self.menuGeneric.addAction(self.actionSelectUpOctave) + self.menuGeneric.addAction(self.actionSelectDownOctave) + self.menuGeneric.addAction(self.actionSelectTrack) + self.menuGeneric.addAction(self.actionSelectAllTracks) + self.menuGeneric.addAction(self.actionSelectMeasureColumn) + self.menuGeneric.addAction(self.menuType_Here.menuAction()) + self.menuTracks.addAction(self.actionAdd_Track) + self.menuTracks.addAction(self.actionDelete_Current_Track) + self.menuTracks.addAction(self.actionUse_Current_Track_as_Metronome) + self.menuTracks.addSeparator() + self.menuTracks.addAction(self.actionSplit_Current_Block) + self.menuTracks.addAction(self.actionAppend_Block) + self.menuTracks.addAction(self.actionDuplicate) + self.menuTracks.addAction(self.actionUnlink_Current_Block) + self.menuTracks.addAction(self.actionCreate_Linked_Copy) + self.menuTracks.addAction(self.actionDelete_Current_Block) + self.menuTracks.addAction(self.actionJoin_with_next_Block) + self.menuTracks.addSeparator() + self.menuTracks.addAction(self.actionTranspose_Score) + self.menuTracks.addAction(self.actionDelete_All_Empty_Blocks) + self.menuEdit.addAction(self.actionSharpen_Note) + self.menuEdit.addAction(self.actionFlatten_Note) + self.menuEdit.addAction(self.actionStep_Up) + self.menuEdit.addAction(self.actionStep_Down) + self.menuEdit.addAction(self.actionOctave_Up) + self.menuEdit.addAction(self.actionOctave_Down) + self.menuEdit.addAction(self.actionTransposeChord) + self.menuEdit.addSeparator() + self.menuEdit.addAction(self.actionAugment) + self.menuEdit.addAction(self.actionDiminish) + self.menuEdit.addAction(self.actionDots) + self.menuEdit.addAction(self.actionTriplet) + self.menuEdit.addAction(self.actionCustom_Tuplets) + self.menuEdit.addSeparator() + self.menuEdit.addAction(self.actionStaccato) + self.menuEdit.addAction(self.actionTenuto) + self.menuEdit.addAction(self.actionTie) + self.menuEdit.addSeparator() + self.menuEdit.addAction(self.actionVelocityMore) + self.menuEdit.addAction(self.actionVelocityLess) + self.menuEdit.addAction(self.actionDurationModMore) + self.menuEdit.addAction(self.actionDurationModLess) + self.menuEdit.addAction(self.actionReset_Velocity_Duration_Mod) + self.menuMode.addAction(self.actionNotation_Mode) + self.menuMode.addAction(self.actionBlock_Mode) + self.menuMode.addAction(self.actionCC_Mode) + self.menuView.addAction(self.actionSave) + self.menuView.addSeparator() + self.menuView.addAction(self.actionToggle_Notehead_Rectangles) + self.menuView.addAction(self.actionChange_Grid_Rhythm) + self.menuView.addAction(self.actionFollow_Playhead) + self.menuView.addAction(self.actionMidi_In_is_Active) + self.menuView.addAction(self.menuMode.menuAction()) + self.menuView.addSeparator() + self.menuView.addAction(self.actionData_Editor) + self.menuView.addAction(self.actionProperties) + self.menuView.addAction(self.actionWiden_Score_View) + self.menuView.addAction(self.actionShrink_Score_View) + self.menuView.addSeparator() + self.menuView.addAction(self.actionPlayPause) + self.menuView.addAction(self.actionPlayFromEditCursor) + self.menuView.addAction(self.actionPlayFromBeginning) + self.menuView.addAction(self.actionMetronome_Enabled) + self.menuView.addSeparator() + self.menuEdit_MusicItem.addAction(self.actionAddCursorNoteToChord) + self.menuEdit_MusicItem.addAction(self.actionDeleteCursorNoteFromChord) + self.menuEdit_MusicItem.addAction(self.actionSplit_in_2) + self.menuEdit_MusicItem.addAction(self.actionSplit_in_3) + self.menuEdit_MusicItem.addAction(self.actionCustom_Split) + self.menuEdit_MusicItem.addSeparator() + self.menuEdit_MusicItem.addAction(self.actionBeam) + self.menuEdit_MusicItem.addAction(self.actionRemoveBeams) + self.menuEdit_MusicItem.addSeparator() + self.menuEdit_MusicItem.addAction(self.actionMIDI_Channel_Plus) + self.menuEdit_MusicItem.addAction(self.actionMIDI_Channel_Minus) + self.menuEdit_MusicItem.addAction(self.actionMIDI_Channel_Reset) + self.menuEdit_2.addAction(self.actionDelete) + self.menuEdit_2.addAction(self.actionBackspace) + self.menuEdit_2.addAction(self.actionUndo) + self.menuEdit_2.addAction(self.actionRedo) + self.menuEdit_2.addAction(self.actionCopy) + self.menuEdit_2.addAction(self.actionPaste) + self.menuEdit_2.addAction(self.actionCut) + self.menuEdit_2.addAction(self.actionDuplicateItem) + self.menuOrder.addAction(self.actionRandom) + self.menuOrder.addAction(self.actionReverse) + self.menuOrder.addAction(self.actionAscending) + self.menuOrder.addAction(self.actionDescending) + self.menuInsert.addAction(self.actionRandom_chromatic_in_clef_range) + self.menuInsert.addAction(self.actionRandom_in_scale_in_clef_range) + self.menuInsert.addAction(self.actionRandom_in_scale_in_cursor_plus_octave) + self.menuInsert.addAction(self.actionRandom_in_scale_in_octave_around_cursor) + self.menuInsert.addAction(self.actionRandom_pitch_from_clipboard) + self.menuInsert.addSeparator() + self.menuInsert.addAction(self.actionPedalNotes) + self.menuInsert.addAction(self.actionMirror_around_Cursor) + self.menuMIDI.addAction(self.actionChannel_Change) + self.menuToolbox.addAction(self.menuInsert.menuAction()) + self.menuToolbox.addAction(self.menuOrder.menuAction()) + self.menuToolbox.addAction(self.menuMIDI.menuAction()) + self.menuLilypond.addAction(self.actionShow_PDF) + self.menuLilypond.addAction(self.actionExport_to_Ly) + self.menubar.addAction(self.menuView.menuAction()) + self.menubar.addAction(self.menuEdit_2.menuAction()) + self.menubar.addAction(self.menu.menuAction()) + self.menubar.addAction(self.menuTracks.menuAction()) + self.menubar.addAction(self.menuObjects.menuAction()) + self.menubar.addAction(self.menuEdit_MusicItem.menuAction()) + self.menubar.addAction(self.menuEdit.menuAction()) + self.menubar.addAction(self.menuToolbox.menuAction()) + self.menubar.addAction(self.menu_2.menuAction()) + self.menubar.addAction(self.menuLilypond.menuAction()) + self.menubar.addAction(self.menuHelp.menuAction()) + self.menubar.addAction(self.menuGeneric.menuAction()) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "Laborejo")) + self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar")) + self.menuHelp.setTitle(_translate("MainWindow", "Help")) + self.menuObjects.setTitle(_translate("MainWindow", "&Insert Objects")) + self.menuGeneric.setTitle(_translate("MainWindow", "&Generic")) + self.menuType_Here.setTitle(_translate("MainWindow", "T&ype Here")) + self.menuTracks.setTitle(_translate("MainWindow", "&Structures")) + self.menuEdit.setTitle(_translate("MainWindow", "E&dit Note")) + self.menuView.setTitle(_translate("MainWindow", "&Control")) + self.menuMode.setTitle(_translate("MainWindow", "&View and Edit Mode")) + self.menu.setTitle(_translate("MainWindow", "|")) + self.menu_2.setTitle(_translate("MainWindow", "|")) + self.menuEdit_MusicItem.setTitle(_translate("MainWindow", "Edit &MusicItem")) + self.menuEdit_2.setTitle(_translate("MainWindow", "E&dit")) + self.menuToolbox.setTitle(_translate("MainWindow", "&Toolbox")) + self.menuOrder.setTitle(_translate("MainWindow", "Note &Sorting")) + self.menuInsert.setTitle(_translate("MainWindow", "&Note Generation")) + self.menuMIDI.setTitle(_translate("MainWindow", "&MIDI")) + self.menuLilypond.setTitle(_translate("MainWindow", "&Lilypond")) + self.leftToolBar.setWindowTitle(_translate("MainWindow", "leftToolBar")) + self.actionUp.setText(_translate("MainWindow", "u&p")) + self.actionUp.setShortcut(_translate("MainWindow", "Up")) + self.actionDown.setText(_translate("MainWindow", "d&own")) + self.actionDown.setShortcut(_translate("MainWindow", "Down")) + self.actionLeft.setText(_translate("MainWindow", "&left")) + self.actionLeft.setShortcut(_translate("MainWindow", "Left")) + self.actionRight.setText(_translate("MainWindow", "&right")) + self.actionRight.setShortcut(_translate("MainWindow", "Right")) + self.actionModal1.setText(_translate("MainWindow", "&modal1")) + self.actionModal1.setShortcut(_translate("MainWindow", "1")) + self.actionModal2.setText(_translate("MainWindow", "modal&2")) + self.actionModal2.setShortcut(_translate("MainWindow", "2")) + self.actionModal3.setText(_translate("MainWindow", "modal&3")) + self.actionModal3.setShortcut(_translate("MainWindow", "3")) + self.actionModal4.setText(_translate("MainWindow", "modal&4")) + self.actionModal4.setShortcut(_translate("MainWindow", "4")) + self.actionModal5.setText(_translate("MainWindow", "modal&5")) + self.actionModal5.setShortcut(_translate("MainWindow", "5")) + self.actionModal6.setText(_translate("MainWindow", "modal&6")) + self.actionModal6.setShortcut(_translate("MainWindow", "6")) + self.actionModal7.setText(_translate("MainWindow", "modal&7")) + self.actionModal7.setShortcut(_translate("MainWindow", "7")) + self.actionModal8.setText(_translate("MainWindow", "modal&8")) + self.actionModal8.setShortcut(_translate("MainWindow", "8")) + self.actionModal9.setText(_translate("MainWindow", "modal&9")) + self.actionModal9.setShortcut(_translate("MainWindow", "9")) + self.actionModal0.setText(_translate("MainWindow", "modal&0")) + self.actionModal0.setShortcut(_translate("MainWindow", "0")) + self.actionDelete.setText(_translate("MainWindow", "&Delete Item")) + self.actionDelete.setShortcut(_translate("MainWindow", "Del")) + self.actionBackspace.setText(_translate("MainWindow", "Delete previous &Item")) + self.actionBackspace.setShortcut(_translate("MainWindow", "Backspace")) + self.actionShift_modal1.setText(_translate("MainWindow", "sh&ift+modal1")) + self.actionShift_modal1.setShortcut(_translate("MainWindow", "Shift+1")) + self.actionShift_modal2.setText(_translate("MainWindow", "shi&ft+modal2")) + self.actionShift_modal2.setShortcut(_translate("MainWindow", "Shift+2")) + self.actionShift_modal3.setText(_translate("MainWindow", "shift+modal3")) + self.actionShift_modal3.setShortcut(_translate("MainWindow", "Shift+3")) + self.actionShift_modal4.setText(_translate("MainWindow", "shift+modal4")) + self.actionShift_modal4.setShortcut(_translate("MainWindow", "Shift+4")) + self.actionShift_modal5.setText(_translate("MainWindow", "shift+modal5")) + self.actionShift_modal5.setShortcut(_translate("MainWindow", "Shift+5")) + self.actionShift_modal6.setText(_translate("MainWindow", "shift+modal6")) + self.actionShift_modal6.setShortcut(_translate("MainWindow", "Shift+6")) + self.actionShift_modal7.setText(_translate("MainWindow", "shift+modal7")) + self.actionShift_modal7.setShortcut(_translate("MainWindow", "Shift+7")) + self.actionShift_modal8.setText(_translate("MainWindow", "shift+modal8")) + self.actionShift_modal8.setShortcut(_translate("MainWindow", "Shift+8")) + self.actionShift_modal9.setText(_translate("MainWindow", "shift+modal9")) + self.actionShift_modal9.setShortcut(_translate("MainWindow", "Shift+9")) + self.actionShift_modal0.setText(_translate("MainWindow", "shift+modal0")) + self.actionShift_modal0.setShortcut(_translate("MainWindow", "Shift+0")) + self.actionAddCursorNoteToChord.setText(_translate("MainWindow", "&Add Note to Chord")) + self.actionAddCursorNoteToChord.setShortcut(_translate("MainWindow", "Return")) + self.actionDeleteCursorNoteFromChord.setText(_translate("MainWindow", "&Delete Note from Chord")) + self.actionDeleteCursorNoteFromChord.setShortcut(_translate("MainWindow", "Shift+Del")) + self.actionAdd_Track.setText(_translate("MainWindow", "&Add Track")) + self.actionTrackUp.setText(_translate("MainWindow", "&trackUp")) + self.actionTrackUp.setShortcut(_translate("MainWindow", "PgUp")) + self.actionTrackDown.setText(_translate("MainWindow", "trac&kDown")) + self.actionTrackDown.setShortcut(_translate("MainWindow", "PgDown")) + self.actionHead.setText(_translate("MainWindow", "&head")) + self.actionHead.setShortcut(_translate("MainWindow", "Home")) + self.actionTail.setText(_translate("MainWindow", "tail")) + self.actionTail.setShortcut(_translate("MainWindow", "End")) + self.actionTrackFirst.setText(_translate("MainWindow", "trackFirst")) + self.actionTrackFirst.setShortcut(_translate("MainWindow", "Ctrl+PgUp")) + self.actionTrackLast.setText(_translate("MainWindow", "trackLast")) + self.actionTrackLast.setShortcut(_translate("MainWindow", "Ctrl+PgDown")) + self.actionSharpen_Note.setText(_translate("MainWindow", "&Sharpen Note")) + self.actionSharpen_Note.setShortcut(_translate("MainWindow", "+")) + self.actionFlatten_Note.setText(_translate("MainWindow", "&Flatten Note")) + self.actionFlatten_Note.setShortcut(_translate("MainWindow", "-")) + self.actionMeasureLeft.setText(_translate("MainWindow", "measureLeft")) + self.actionMeasureLeft.setShortcut(_translate("MainWindow", "Ctrl+Left")) + self.actionMeasureRight.setText(_translate("MainWindow", "measureRight")) + self.actionMeasureRight.setShortcut(_translate("MainWindow", "Ctrl+Right")) + self.actionStep_Up.setText(_translate("MainWindow", "Step &Up")) + self.actionStep_Up.setShortcut(_translate("MainWindow", "Alt+Up")) + self.actionStep_Down.setText(_translate("MainWindow", "Ste&p Down")) + self.actionStep_Down.setShortcut(_translate("MainWindow", "Alt+Down")) + self.actionOctave_Up.setText(_translate("MainWindow", "&Octave Up")) + self.actionOctave_Up.setShortcut(_translate("MainWindow", "Ctrl+Alt+Up")) + self.actionOctave_Down.setText(_translate("MainWindow", "Octa&ve Down")) + self.actionOctave_Down.setShortcut(_translate("MainWindow", "Ctrl+Alt+Down")) + self.actionAugment.setText(_translate("MainWindow", "&Augment")) + self.actionAugment.setShortcut(_translate("MainWindow", "Alt+Right")) + self.actionDiminish.setText(_translate("MainWindow", "&Diminish")) + self.actionDiminish.setShortcut(_translate("MainWindow", "Alt+Left")) + self.actionAppend_Block.setText(_translate("MainWindow", "Append &Block")) + self.actionSplit_Current_Block.setText(_translate("MainWindow", "&Split Current Block")) + self.actionSplit_Current_Block.setShortcut(_translate("MainWindow", "Ins")) + self.actionDuplicate.setText(_translate("MainWindow", "&Duplicate Current Block")) + self.actionDuplicate.setShortcut(_translate("MainWindow", "Alt+Ins")) + self.actionCreate_Linked_Copy.setText(_translate("MainWindow", "&Create Linked Copy")) + self.actionCreate_Linked_Copy.setShortcut(_translate("MainWindow", "Alt+Shift+Ins")) + self.actionDelete_Current_Block.setText(_translate("MainWindow", "De&lete Current Block")) + self.actionToggle_Notehead_Rectangles.setText(_translate("MainWindow", "&Rectangle Noteheads")) + self.actionToggle_Notehead_Rectangles.setShortcut(_translate("MainWindow", "F1")) + self.actionPlayPause.setText(_translate("MainWindow", "P&lay / Pause")) + self.actionPlayPause.setShortcut(_translate("MainWindow", "Space")) + self.actionPlayFromBeginning.setText(_translate("MainWindow", "Play fr&om Start")) + self.actionPlayFromBeginning.setShortcut(_translate("MainWindow", "Shift+Space")) + self.actionFollow_Playhead.setText(_translate("MainWindow", "&Follow Playhead")) + self.actionFollow_Playhead.setShortcut(_translate("MainWindow", "F3")) + self.actionPlayFromEditCursor.setText(_translate("MainWindow", "Pla&y from Cursor")) + self.actionPlayFromEditCursor.setShortcut(_translate("MainWindow", "Ctrl+Space")) + self.actionStaccato.setText(_translate("MainWindow", "Staccato")) + self.actionStaccato.setShortcut(_translate("MainWindow", ",")) + self.actionCopy.setText(_translate("MainWindow", "&Copy")) + self.actionCopy.setShortcut(_translate("MainWindow", "Ctrl+C")) + self.actionCut.setText(_translate("MainWindow", "Cut")) + self.actionCut.setShortcut(_translate("MainWindow", "Ctrl+X")) + self.actionPaste.setText(_translate("MainWindow", "&Paste")) + self.actionPaste.setShortcut(_translate("MainWindow", "Ctrl+V")) + self.actionUpOctave.setText(_translate("MainWindow", "&upOctave")) + self.actionUpOctave.setShortcut(_translate("MainWindow", "Ctrl+Up")) + self.actionDownOctave.setText(_translate("MainWindow", "&downOctave")) + self.actionDownOctave.setShortcut(_translate("MainWindow", "Ctrl+Down")) + self.actionDots.setText(_translate("MainWindow", "Dots")) + self.actionDots.setShortcut(_translate("MainWindow", "Q")) + self.actionCC_Mode.setText(_translate("MainWindow", "&Control Changes")) + self.actionCC_Mode.setShortcut(_translate("MainWindow", "F7")) + self.CCactionSplit_Current_Block.setText(_translate("MainWindow", "CCactionSplit_Current_Block")) + self.CCactionSplit_Current_Block.setShortcut(_translate("MainWindow", "Ins")) + self.actionChange_Grid_Rhythm.setText(_translate("MainWindow", "&Change Grid Rhythm")) + self.actionChange_Grid_Rhythm.setShortcut(_translate("MainWindow", "F2")) + self.actionSnap_To_Grid.setText(_translate("MainWindow", "Snap To Grid")) + self.actionAlt_modal1.setText(_translate("MainWindow", "&Alt_modal1")) + self.actionAlt_modal1.setShortcut(_translate("MainWindow", "Alt+1")) + self.actionAlt_modal2.setText(_translate("MainWindow", "Alt_modal2")) + self.actionAlt_modal2.setShortcut(_translate("MainWindow", "Alt+2")) + self.actionAlt_modal3.setText(_translate("MainWindow", "Alt_modal3")) + self.actionAlt_modal3.setShortcut(_translate("MainWindow", "Alt+3")) + self.actionAlt_modal4.setText(_translate("MainWindow", "Alt_modal4")) + self.actionAlt_modal4.setShortcut(_translate("MainWindow", "Alt+4")) + self.actionAlt_modal5.setText(_translate("MainWindow", "Alt_modal5")) + self.actionAlt_modal5.setShortcut(_translate("MainWindow", "Alt+5")) + self.actionAlt_modal6.setText(_translate("MainWindow", "Alt_modal6")) + self.actionAlt_modal6.setShortcut(_translate("MainWindow", "Alt+6")) + self.actionAlt_modal7.setText(_translate("MainWindow", "Alt_modal7")) + self.actionAlt_modal7.setShortcut(_translate("MainWindow", "Alt+7")) + self.actionAlt_modal8.setText(_translate("MainWindow", "Alt_modal8")) + self.actionAlt_modal8.setShortcut(_translate("MainWindow", "Alt+8")) + self.actionAlt_modal9.setText(_translate("MainWindow", "Alt_modal9")) + self.actionAlt_modal9.setShortcut(_translate("MainWindow", "Alt+9")) + self.actionAlt_modal0.setText(_translate("MainWindow", "Alt_modal0")) + self.actionAlt_modal0.setShortcut(_translate("MainWindow", "Alt+0")) + self.actionMidi_In_is_Active.setText(_translate("MainWindow", "&Midi In is Active")) + self.actionMidi_In_is_Active.setToolTip(_translate("MainWindow", "Toggle midi in on and off")) + self.actionMidi_In_is_Active.setShortcut(_translate("MainWindow", "F4")) + self.actionTie.setText(_translate("MainWindow", "T&ie")) + self.actionTie.setShortcut(_translate("MainWindow", "I")) + self.actionLegatoSlur.setText(_translate("MainWindow", "&Legato Slur")) + self.actionLegatoSlur.setToolTip(_translate("MainWindow", "Toggle Legato Slur")) + self.actionLegatoSlur.setShortcut(_translate("MainWindow", "S")) + self.actionTenuto.setText(_translate("MainWindow", "T&enuto")) + self.actionTenuto.setShortcut(_translate("MainWindow", "E")) + self.actionTriplet.setText(_translate("MainWindow", "Triplet")) + self.actionTriplet.setShortcut(_translate("MainWindow", "T")) + self.actionCustom_Tuplets.setText(_translate("MainWindow", "&Custom Tuplets")) + self.actionCustom_Tuplets.setShortcut(_translate("MainWindow", "Alt+T")) + self.actionPrevailingRest.setText(_translate("MainWindow", "Prevailing Rest")) + self.actionSplit_in_2.setText(_translate("MainWindow", "&Split in 2")) + self.actionSplit_in_2.setShortcut(_translate("MainWindow", "X")) + self.actionSplit_in_3.setText(_translate("MainWindow", "Split &in 3")) + self.actionSplit_in_3.setShortcut(_translate("MainWindow", "Shift+X")) + self.actionCustom_Split.setText(_translate("MainWindow", "Split in &X")) + self.actionCustom_Split.setShortcut(_translate("MainWindow", "Alt+X")) + self.actionUndo.setText(_translate("MainWindow", "&Undo")) + self.actionUndo.setShortcut(_translate("MainWindow", "Ctrl+Z")) + self.actionRedo.setText(_translate("MainWindow", "&Redo")) + self.actionRedo.setShortcut(_translate("MainWindow", "Ctrl+Shift+Z")) + self.actionJoin_with_next_Block.setText(_translate("MainWindow", "&Join with next Block")) + self.actionJoin_with_next_Block.setShortcut(_translate("MainWindow", "Shift+Ins")) + self.actionSet_UpBeat.setText(_translate("MainWindow", "Set Upbeat")) + self.actionSelectLeft.setText(_translate("MainWindow", "selectLeft")) + self.actionSelectLeft.setShortcut(_translate("MainWindow", "Shift+Left")) + self.actionSelectRight.setText(_translate("MainWindow", "selectRi&ght")) + self.actionSelectRight.setShortcut(_translate("MainWindow", "Shift+Right")) + self.actionSelectMeasureLeft.setText(_translate("MainWindow", "selectMeasureLeft")) + self.actionSelectMeasureLeft.setShortcut(_translate("MainWindow", "Ctrl+Shift+Left")) + self.actionSelectMeasureRight.setText(_translate("MainWindow", "selectMeasureRight")) + self.actionSelectMeasureRight.setShortcut(_translate("MainWindow", "Ctrl+Shift+Right")) + self.actionSelectHead.setText(_translate("MainWindow", "selectHead")) + self.actionSelectHead.setShortcut(_translate("MainWindow", "Shift+Home")) + self.actionSelectTail.setText(_translate("MainWindow", "selectTail")) + self.actionSelectTail.setShortcut(_translate("MainWindow", "Shift+End")) + self.actionSelectTrackUp.setText(_translate("MainWindow", "selectTrackUp")) + self.actionSelectTrackUp.setShortcut(_translate("MainWindow", "Shift+PgUp")) + self.actionSelectTrackDown.setText(_translate("MainWindow", "selectTrackDown")) + self.actionSelectTrackDown.setShortcut(_translate("MainWindow", "Shift+PgDown")) + self.actionSelectTrackFirst.setText(_translate("MainWindow", "selectTrackFirst")) + self.actionSelectTrackFirst.setShortcut(_translate("MainWindow", "Ctrl+Shift+PgUp")) + self.actionSelectTrackLast.setText(_translate("MainWindow", "selectTrackLast")) + self.actionSelectTrackLast.setShortcut(_translate("MainWindow", "Ctrl+Shift+PgDown")) + self.actionSelectUp.setText(_translate("MainWindow", "selectUp")) + self.actionSelectUp.setShortcut(_translate("MainWindow", "Shift+Up")) + self.actionSelectDown.setText(_translate("MainWindow", "selectDo&wn")) + self.actionSelectDown.setShortcut(_translate("MainWindow", "Shift+Down")) + self.actionSelectUpOctave.setText(_translate("MainWindow", "selectUpOcta&ve")) + self.actionSelectUpOctave.setShortcut(_translate("MainWindow", "Ctrl+Shift+Up")) + self.actionSelectDownOctave.setText(_translate("MainWindow", "selectDow&nOctave")) + self.actionSelectDownOctave.setShortcut(_translate("MainWindow", "Ctrl+Shift+Down")) + self.actionSelectTrack.setText(_translate("MainWindow", "selectTrack")) + self.actionSelectTrack.setShortcut(_translate("MainWindow", "Shift+A")) + self.actionSelectMeasureColumn.setText(_translate("MainWindow", "selectMeasureColumn")) + self.actionSelectMeasureColumn.setShortcut(_translate("MainWindow", "Ctrl+A")) + self.actionSelectAllTracks.setText(_translate("MainWindow", "selectAllTracks")) + self.actionSelectAllTracks.setShortcut(_translate("MainWindow", "Ctrl+Shift+A")) + self.actionVelocityMore.setText(_translate("MainWindow", "&More Velocity")) + self.actionVelocityMore.setToolTip(_translate("MainWindow", "More Velocity")) + self.actionVelocityMore.setShortcut(_translate("MainWindow", ">")) + self.actionVelocityLess.setText(_translate("MainWindow", "&Less Velocity")) + self.actionVelocityLess.setToolTip(_translate("MainWindow", "Less Velocity")) + self.actionVelocityLess.setShortcut(_translate("MainWindow", "<")) + self.actionDurationModMore.setText(_translate("MainWindow", "Lo&nger Duration Mod.")) + self.actionDurationModMore.setToolTip(_translate("MainWindow", "Longer Duration Mod.")) + self.actionDurationModMore.setShortcut(_translate("MainWindow", "Alt+Shift+Right")) + self.actionDurationModLess.setText(_translate("MainWindow", "Shorter Duration Mod.")) + self.actionDurationModLess.setToolTip(_translate("MainWindow", "Shorter Duration Mod.")) + self.actionDurationModLess.setShortcut(_translate("MainWindow", "Alt+Shift+Left")) + self.actionReset_Velocity_Duration_Mod.setText(_translate("MainWindow", "&Reset Velocity / Duration Mod.")) + self.actionWiden_Score_View.setText(_translate("MainWindow", "&Widen Score View")) + self.actionWiden_Score_View.setShortcut(_translate("MainWindow", "Ctrl++")) + self.actionShrink_Score_View.setText(_translate("MainWindow", "Shr&ink Score View")) + self.actionShrink_Score_View.setShortcut(_translate("MainWindow", "Ctrl+-")) + self.actionData_Editor.setText(_translate("MainWindow", "&Track Editor")) + self.actionData_Editor.setShortcut(_translate("MainWindow", "Ctrl+T")) + self.actionClef.setText(_translate("MainWindow", "&Clef")) + self.actionClef.setShortcut(_translate("MainWindow", "C")) + self.actionMetrical_Instruction.setText(_translate("MainWindow", "&Metrical Instruction")) + self.actionMetrical_Instruction.setShortcut(_translate("MainWindow", "M")) + self.actionKey_Signature.setText(_translate("MainWindow", "&Key Signature")) + self.actionKey_Signature.setShortcut(_translate("MainWindow", "K")) + self.actionDynamics.setText(_translate("MainWindow", "&Dynamics")) + self.actionDynamics.setShortcut(_translate("MainWindow", "D")) + self.actionMulti_Measure_Rest.setText(_translate("MainWindow", "Multi Measure &Rest")) + self.actionMulti_Measure_Rest.setShortcut(_translate("MainWindow", "R")) + self.actionTemporary_Tempo_Change.setText(_translate("MainWindow", "Tem&porary Tempo Change")) + self.actionTemporary_Tempo_Change.setShortcut(_translate("MainWindow", "F")) + self.actionBeam.setText(_translate("MainWindow", "&Beam")) + self.actionBeam.setShortcut(_translate("MainWindow", "B")) + self.actionRemoveBeams.setText(_translate("MainWindow", "&Remove Beams")) + self.actionRemoveBeams.setShortcut(_translate("MainWindow", "Alt+B")) + self.actionTempo_Change.setText(_translate("MainWindow", "&Tempo Change")) + self.actionTempo_Change.setShortcut(_translate("MainWindow", "G")) + self.actionDelete_Tempo_Change.setText(_translate("MainWindow", "D&elete Tempo Change")) + self.actionDelete_Tempo_Change.setShortcut(_translate("MainWindow", "Alt+G")) + self.actionBlock_Mode.setText(_translate("MainWindow", "&Blocks Only")) + self.actionBlock_Mode.setShortcut(_translate("MainWindow", "F6")) + self.actionNotation_Mode.setText(_translate("MainWindow", "&Notation")) + self.actionNotation_Mode.setShortcut(_translate("MainWindow", "F5")) + self.actionTransposeChord.setText(_translate("MainWindow", "&Transpose Chord")) + self.actionTranspose_Score.setText(_translate("MainWindow", "&Transpose Score")) + self.actionSave.setText(_translate("MainWindow", "&Save")) + self.actionSave.setShortcut(_translate("MainWindow", "Ctrl+S")) + self.actionExport_File.setText(_translate("MainWindow", "Export File")) + self.actionImport_File_replaces_current.setText(_translate("MainWindow", "Import File (replaces current)")) + self.actionUnlink_Current_Block.setText(_translate("MainWindow", "&Unlink Current Block")) + self.actionDelete_All_Empty_Blocks.setText(_translate("MainWindow", "Delete All &Empty Blocks")) + self.actionBlockRight.setText(_translate("MainWindow", "blo&ckRight")) + self.actionBlockRight.setShortcut(_translate("MainWindow", "Ctrl+Alt+Right")) + self.actionBlockLeft.setText(_translate("MainWindow", "&blockLeft")) + self.actionBlockLeft.setShortcut(_translate("MainWindow", "Ctrl+Alt+Left")) + self.actionSelectBlockRight.setText(_translate("MainWindow", "&selectBlockRight")) + self.actionSelectBlockRight.setShortcut(_translate("MainWindow", "Ctrl+Alt+Shift+Right")) + self.actionSelectBlockLeft.setText(_translate("MainWindow", "s&electBlockLeft")) + self.actionSelectBlockLeft.setShortcut(_translate("MainWindow", "Ctrl+Alt+Shift+Left")) + self.actionPedalNotes.setText(_translate("MainWindow", "&Pedal Notes")) + self.actionReverse.setText(_translate("MainWindow", "&Reverse")) + self.actionDuplicateItem.setText(_translate("MainWindow", "Dup&licate")) + self.actionDuplicateItem.setShortcut(_translate("MainWindow", "Ctrl+D")) + self.actionRandom.setText(_translate("MainWindow", "&Shuffle")) + self.actionAscending.setText(_translate("MainWindow", "&Ascending")) + self.actionDescending.setText(_translate("MainWindow", "&Descending")) + self.actionMirror_around_Cursor.setText(_translate("MainWindow", "&Mirror around Cursor")) + self.actionInsert_Random.setText(_translate("MainWindow", "Insert Random")) + self.actionRandom_chromatic_in_clef_range.setText(_translate("MainWindow", "&Random chromatic in clef range")) + self.actionRandom_in_scale_in_clef_range.setText(_translate("MainWindow", "Random &in-scale in clef range")) + self.actionRandom_pitch_from_clipboard.setText(_translate("MainWindow", "Random pitch &from clipboard")) + self.actionProperties.setText(_translate("MainWindow", "Meta&data")) + self.actionExport_to_Ly.setText(_translate("MainWindow", "&Export to .ly file")) + self.actionShow_PDF.setText(_translate("MainWindow", "&Show PDF")) + self.actionShow_PDF.setShortcut(_translate("MainWindow", "Ctrl+P")) + self.actionExport_to_pdf_file.setText(_translate("MainWindow", "Export to .pdf file")) + self.actionInstrument_Change.setText(_translate("MainWindow", "&Instrument Change")) + self.actionProgram_Change_Relative.setText(_translate("MainWindow", "Program Change Relative")) + self.actionBank_Change_Absolute.setText(_translate("MainWindow", "Insert Bank Change")) + self.actionBank_Change_Relative.setText(_translate("MainWindow", "Bank Change Relative")) + self.actionChannel_Change.setText(_translate("MainWindow", "&Insert Channel Change ")) + self.actionChannel_Change_Relative.setText(_translate("MainWindow", "Channel Change Relative")) + self.actionMIDI_Channel_Plus.setText(_translate("MainWindow", "&MIDI Channel +")) + self.actionMIDI_Channel_Minus.setText(_translate("MainWindow", "MIDI &Channel -")) + self.actionMIDI_Channel_Reset.setText(_translate("MainWindow", "MIDI C&hannel Reset")) + self.actionDelete_Current_Track.setText(_translate("MainWindow", "Delete Current Track")) + self.actionUse_Current_Track_as_Metronome.setText(_translate("MainWindow", "Use Current Track as &Metronome")) + self.actionUse_Current_Track_as_Metronome.setShortcut(_translate("MainWindow", "U")) + self.actionMetronome_Enabled.setText(_translate("MainWindow", "Metronome &Enabled")) + self.actionMetronome_Enabled.setShortcut(_translate("MainWindow", "Alt+U")) + self.actionRandom_in_scale_in_cursor_plus_octave.setText(_translate("MainWindow", "Random in-scale in cursor plus octave (authentic mode)")) + self.actionRandom_in_scale_in_octave_around_cursor.setText(_translate("MainWindow", "Random in-scale in octave around cursor (hypo mode)")) + self.actionCreate_pool_from_selection.setText(_translate("MainWindow", "Create pool from selection")) + diff --git a/qtgui/designer/mainwindow.ui b/qtgui/designer/mainwindow.ui new file mode 100644 index 0000000..46471bd --- /dev/null +++ b/qtgui/designer/mainwindow.ui @@ -0,0 +1,1675 @@ + + + MainWindow + + + + 0 + 0 + 1036 + 625 + + + + Laborejo + + + + + + + + + + + + toolBar + + + false + + + false + + + TopToolBarArea + + + false + + + + + + 0 + 0 + 1036 + 20 + + + + + Help + + + + + &Insert Objects + + + + + + + + + + + + + + + + + + true + + + &Generic + + + + T&ype Here + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + &Structures + + + + + + + + + + + + + + + + + + + E&dit Note + + + + + + + + + + + + + + + + + + + + + + + + + + + + &Control + + + + &View and Edit Mode + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + | + + + + + false + + + | + + + + + Edit &MusicItem + + + + + + + + + + + + + + + + + E&dit + + + + + + + + + + + + + &Toolbox + + + + Note &Sorting + + + + + + + + + &Note Generation + + + + + + + + + + + + + &MIDI + + + + + + + + + + &Lilypond + + + + + + + + + + + + + + + + + + + + true + + + + 0 + 0 + + + + + 26 + 0 + + + + + 26 + 16777215 + + + + leftToolBar + + + false + + + Qt::LeftToolBarArea + + + false + + + LeftToolBarArea + + + false + + + + + u&p + + + Up + + + + + d&own + + + Down + + + + + &left + + + Left + + + + + &right + + + Right + + + + + &modal1 + + + 1 + + + + + modal&2 + + + 2 + + + + + modal&3 + + + 3 + + + + + modal&4 + + + 4 + + + + + modal&5 + + + 5 + + + + + modal&6 + + + 6 + + + + + modal&7 + + + 7 + + + + + modal&8 + + + 8 + + + + + modal&9 + + + 9 + + + + + modal&0 + + + 0 + + + + + &Delete Item + + + Del + + + + + Delete previous &Item + + + Backspace + + + + + sh&ift+modal1 + + + Shift+1 + + + + + shi&ft+modal2 + + + Shift+2 + + + + + shift+modal3 + + + Shift+3 + + + + + shift+modal4 + + + Shift+4 + + + + + shift+modal5 + + + Shift+5 + + + + + shift+modal6 + + + Shift+6 + + + + + shift+modal7 + + + Shift+7 + + + + + shift+modal8 + + + Shift+8 + + + + + shift+modal9 + + + Shift+9 + + + + + shift+modal0 + + + Shift+0 + + + + + &Add Note to Chord + + + Return + + + Qt::WindowShortcut + + + + + &Delete Note from Chord + + + Shift+Del + + + + + &Add Track + + + + + &trackUp + + + PgUp + + + + + trac&kDown + + + PgDown + + + + + &head + + + Home + + + + + tail + + + End + + + + + trackFirst + + + Ctrl+PgUp + + + + + trackLast + + + Ctrl+PgDown + + + + + &Sharpen Note + + + + + + + + + &Flatten Note + + + - + + + + + measureLeft + + + Ctrl+Left + + + + + measureRight + + + Ctrl+Right + + + + + Step &Up + + + Alt+Up + + + + + Ste&p Down + + + Alt+Down + + + + + &Octave Up + + + Ctrl+Alt+Up + + + + + Octa&ve Down + + + Ctrl+Alt+Down + + + + + &Augment + + + Alt+Right + + + + + &Diminish + + + Alt+Left + + + + + Append &Block + + + + + &Split Current Block + + + Ins + + + + + &Duplicate Current Block + + + Alt+Ins + + + + + &Create Linked Copy + + + Alt+Shift+Ins + + + + + De&lete Current Block + + + + + true + + + &Rectangle Noteheads + + + F1 + + + + + P&lay / Pause + + + Space + + + + + Play fr&om Start + + + Shift+Space + + + + + true + + + true + + + &Follow Playhead + + + F3 + + + + + Pla&y from Cursor + + + Ctrl+Space + + + + + Staccato + + + , + + + + + &Copy + + + Ctrl+C + + + + + Cut + + + Ctrl+X + + + + + &Paste + + + Ctrl+V + + + + + &upOctave + + + Ctrl+Up + + + + + &downOctave + + + Ctrl+Down + + + + + Dots + + + Q + + + + + true + + + &Control Changes + + + F7 + + + + + CCactionSplit_Current_Block + + + Ins + + + + + false + + + false + + + &Change Grid Rhythm + + + F2 + + + + + true + + + true + + + Snap To Grid + + + + + &Alt_modal1 + + + Alt+1 + + + + + Alt_modal2 + + + Alt+2 + + + + + Alt_modal3 + + + Alt+3 + + + + + Alt_modal4 + + + Alt+4 + + + + + Alt_modal5 + + + Alt+5 + + + + + Alt_modal6 + + + Alt+6 + + + + + Alt_modal7 + + + Alt+7 + + + + + Alt_modal8 + + + Alt+8 + + + + + Alt_modal9 + + + Alt+9 + + + + + Alt_modal0 + + + Alt+0 + + + + + true + + + &Midi In is Active + + + Toggle midi in on and off + + + F4 + + + + + T&ie + + + I + + + + + &Legato Slur + + + Toggle Legato Slur + + + S + + + + + T&enuto + + + E + + + + + Triplet + + + T + + + + + false + + + &Custom Tuplets + + + Alt+T + + + + + false + + + Prevailing Rest + + + + + &Split in 2 + + + X + + + + + Split &in 3 + + + Shift+X + + + + + true + + + Split in &X + + + Alt+X + + + + + &Undo + + + Ctrl+Z + + + + + &Redo + + + Ctrl+Shift+Z + + + + + &Join with next Block + + + Shift+Ins + + + + + Set Upbeat + + + + + selectLeft + + + Shift+Left + + + + + selectRi&ght + + + Shift+Right + + + + + selectMeasureLeft + + + Ctrl+Shift+Left + + + + + selectMeasureRight + + + Ctrl+Shift+Right + + + + + selectHead + + + Shift+Home + + + + + selectTail + + + Shift+End + + + + + selectTrackUp + + + Shift+PgUp + + + + + selectTrackDown + + + Shift+PgDown + + + + + selectTrackFirst + + + Ctrl+Shift+PgUp + + + + + selectTrackLast + + + Ctrl+Shift+PgDown + + + + + selectUp + + + Shift+Up + + + + + selectDo&wn + + + Shift+Down + + + + + selectUpOcta&ve + + + Ctrl+Shift+Up + + + + + selectDow&nOctave + + + Ctrl+Shift+Down + + + + + selectTrack + + + Shift+A + + + + + selectMeasureColumn + + + Ctrl+A + + + + + selectAllTracks + + + Ctrl+Shift+A + + + + + &More Velocity + + + More Velocity + + + > + + + + + &Less Velocity + + + Less Velocity + + + < + + + + + Lo&nger Duration Mod. + + + Longer Duration Mod. + + + Alt+Shift+Right + + + + + Shorter Duration Mod. + + + Shorter Duration Mod. + + + Alt+Shift+Left + + + + + &Reset Velocity / Duration Mod. + + + + + &Widen Score View + + + Ctrl++ + + + + + Shr&ink Score View + + + Ctrl+- + + + + + true + + + &Track Editor + + + Ctrl+T + + + + + &Clef + + + C + + + + + &Metrical Instruction + + + M + + + + + &Key Signature + + + K + + + + + &Dynamics + + + D + + + + + Multi Measure &Rest + + + R + + + + + Tem&porary Tempo Change + + + F + + + + + &Beam + + + B + + + + + &Remove Beams + + + Alt+B + + + + + &Tempo Change + + + G + + + + + D&elete Tempo Change + + + Alt+G + + + + + true + + + &Blocks Only + + + F6 + + + + + true + + + true + + + &Notation + + + F5 + + + + + &Transpose Chord + + + + + &Transpose Score + + + + + &Save + + + Ctrl+S + + + + + Export File + + + + + Import File (replaces current) + + + + + &Unlink Current Block + + + + + Delete All &Empty Blocks + + + + + blo&ckRight + + + Ctrl+Alt+Right + + + + + &blockLeft + + + Ctrl+Alt+Left + + + + + &selectBlockRight + + + Ctrl+Alt+Shift+Right + + + + + s&electBlockLeft + + + Ctrl+Alt+Shift+Left + + + + + &Pedal Notes + + + + + &Reverse + + + + + Dup&licate + + + Ctrl+D + + + + + &Shuffle + + + + + &Ascending + + + + + &Descending + + + + + &Mirror around Cursor + + + + + Insert Random + + + + + &Random chromatic in clef range + + + + + Random &in-scale in clef range + + + + + Random pitch &from clipboard + + + + + Meta&data + + + + + &Export to .ly file + + + + + &Show PDF + + + Ctrl+P + + + + + Export to .pdf file + + + + + &Instrument Change + + + + + Program Change Relative + + + + + Insert Bank Change + + + + + Bank Change Relative + + + + + &Insert Channel Change + + + + + Channel Change Relative + + + + + &MIDI Channel + + + + + + MIDI &Channel - + + + + + MIDI C&hannel Reset + + + + + Delete Current Track + + + + + Use Current Track as &Metronome + + + U + + + + + true + + + Metronome &Enabled + + + Alt+U + + + + + Random in-scale in cursor plus octave (authentic mode) + + + + + Random in-scale in octave around cursor (hypo mode) + + + + + Create pool from selection + + + + + + diff --git a/qtgui/designer/tickWidget.py b/qtgui/designer/tickWidget.py new file mode 100644 index 0000000..71bf41d --- /dev/null +++ b/qtgui/designer/tickWidget.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'tickWidget.ui' +# +# Created by: PyQt5 UI code generator 5.7 +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore, QtGui, QtWidgets + +class Ui_tickWidget(object): + def setupUi(self, tickWidget): + tickWidget.setObjectName("tickWidget") + tickWidget.resize(453, 229) + self.D1 = QtWidgets.QPushButton(tickWidget) + self.D1.setGeometry(QtCore.QRect(10, 40, 80, 22)) + self.D1.setObjectName("D1") + self.D2 = QtWidgets.QPushButton(tickWidget) + self.D2.setGeometry(QtCore.QRect(100, 40, 80, 22)) + self.D2.setObjectName("D2") + self.D4 = QtWidgets.QPushButton(tickWidget) + self.D4.setGeometry(QtCore.QRect(190, 40, 80, 22)) + self.D4.setObjectName("D4") + self.D8 = QtWidgets.QPushButton(tickWidget) + self.D8.setGeometry(QtCore.QRect(280, 40, 80, 22)) + self.D8.setObjectName("D8") + self.D16 = QtWidgets.QPushButton(tickWidget) + self.D16.setGeometry(QtCore.QRect(370, 40, 80, 22)) + self.D16.setObjectName("D16") + self.DB = QtWidgets.QPushButton(tickWidget) + self.DB.setGeometry(QtCore.QRect(10, 80, 80, 22)) + self.DB.setObjectName("DB") + self.DL = QtWidgets.QPushButton(tickWidget) + self.DL.setGeometry(QtCore.QRect(100, 80, 80, 22)) + self.DL.setObjectName("DL") + self.D32 = QtWidgets.QPushButton(tickWidget) + self.D32.setGeometry(QtCore.QRect(190, 80, 80, 22)) + self.D32.setObjectName("D32") + self.D64 = QtWidgets.QPushButton(tickWidget) + self.D64.setGeometry(QtCore.QRect(280, 80, 80, 22)) + self.D64.setObjectName("D64") + self.D128 = QtWidgets.QPushButton(tickWidget) + self.D128.setGeometry(QtCore.QRect(370, 80, 80, 22)) + self.D128.setObjectName("D128") + self.ticks = QtWidgets.QSpinBox(tickWidget) + self.ticks.setGeometry(QtCore.QRect(160, 190, 161, 23)) + self.ticks.setReadOnly(True) + self.ticks.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons) + self.ticks.setPrefix("") + self.ticks.setMinimum(0) + self.ticks.setMaximum(999999999) + self.ticks.setObjectName("ticks") + self.ok = QtWidgets.QPushButton(tickWidget) + self.ok.setGeometry(QtCore.QRect(60, 190, 80, 22)) + self.ok.setObjectName("ok") + self.cancel = QtWidgets.QPushButton(tickWidget) + self.cancel.setGeometry(QtCore.QRect(340, 190, 80, 22)) + self.cancel.setObjectName("cancel") + self.durationLabel = QtWidgets.QLabel(tickWidget) + self.durationLabel.setGeometry(QtCore.QRect(30, 150, 401, 31)) + self.durationLabel.setAlignment(QtCore.Qt.AlignCenter) + self.durationLabel.setObjectName("durationLabel") + self.reset = QtWidgets.QPushButton(tickWidget) + self.reset.setGeometry(QtCore.QRect(190, 120, 80, 22)) + self.reset.setObjectName("reset") + self.label = QtWidgets.QLabel(tickWidget) + self.label.setGeometry(QtCore.QRect(120, 10, 241, 20)) + self.label.setObjectName("label") + + self.retranslateUi(tickWidget) + QtCore.QMetaObject.connectSlotsByName(tickWidget) + + def retranslateUi(self, tickWidget): + _translate = QtCore.QCoreApplication.translate + tickWidget.setWindowTitle(_translate("tickWidget", "Tick Calculator")) + self.D1.setText(_translate("tickWidget", "[1] D1")) + self.D1.setShortcut(_translate("tickWidget", "1")) + self.D2.setText(_translate("tickWidget", "[2] D2")) + self.D2.setShortcut(_translate("tickWidget", "2")) + self.D4.setText(_translate("tickWidget", "[3] D4")) + self.D4.setShortcut(_translate("tickWidget", "3")) + self.D8.setText(_translate("tickWidget", "[4] D8")) + self.D8.setShortcut(_translate("tickWidget", "4")) + self.D16.setText(_translate("tickWidget", "[5] D16")) + self.D16.setShortcut(_translate("tickWidget", "5")) + self.DB.setText(_translate("tickWidget", "DBrevis")) + self.DL.setText(_translate("tickWidget", "DLonga")) + self.D32.setText(_translate("tickWidget", "D32")) + self.D64.setText(_translate("tickWidget", "D64")) + self.D128.setText(_translate("tickWidget", "D128")) + self.ticks.setSuffix(_translate("tickWidget", " Ticks")) + self.ok.setText(_translate("tickWidget", "OK")) + self.ok.setShortcut(_translate("tickWidget", "Return")) + self.cancel.setText(_translate("tickWidget", "Cancel")) + self.cancel.setShortcut(_translate("tickWidget", "Esc")) + self.durationLabel.setText(_translate("tickWidget", "Simplest Duration")) + self.reset.setText(_translate("tickWidget", "Reset")) + self.label.setText(_translate("tickWidget", "Use buttons to add to total tick duration")) + diff --git a/qtgui/designer/tickWidget.ui b/qtgui/designer/tickWidget.ui new file mode 100644 index 0000000..23702f0 --- /dev/null +++ b/qtgui/designer/tickWidget.ui @@ -0,0 +1,266 @@ + + + tickWidget + + + + 0 + 0 + 453 + 229 + + + + Tick Calculator + + + + + 10 + 40 + 80 + 22 + + + + [1] D1 + + + 1 + + + + + + 100 + 40 + 80 + 22 + + + + [2] D2 + + + 2 + + + + + + 190 + 40 + 80 + 22 + + + + [3] D4 + + + 3 + + + + + + 280 + 40 + 80 + 22 + + + + [4] D8 + + + 4 + + + + + + 370 + 40 + 80 + 22 + + + + [5] D16 + + + 5 + + + + + + 10 + 80 + 80 + 22 + + + + DBrevis + + + + + + 100 + 80 + 80 + 22 + + + + DLonga + + + + + + 190 + 80 + 80 + 22 + + + + D32 + + + + + + 280 + 80 + 80 + 22 + + + + D64 + + + + + + 370 + 80 + 80 + 22 + + + + D128 + + + + + + 160 + 190 + 161 + 23 + + + + true + + + QAbstractSpinBox::NoButtons + + + Ticks + + + + + + 0 + + + 999999999 + + + + + + 60 + 190 + 80 + 22 + + + + OK + + + Return + + + + + + 340 + 190 + 80 + 22 + + + + Cancel + + + Esc + + + + + + 30 + 150 + 401 + 31 + + + + Simplest Duration + + + Qt::AlignCenter + + + + + + 190 + 120 + 80 + 22 + + + + Reset + + + + + + 120 + 10 + 241 + 20 + + + + Use buttons to add to total tick duration + + + + + + diff --git a/qtgui/designer/trackWidget.py b/qtgui/designer/trackWidget.py new file mode 100644 index 0000000..81efd30 --- /dev/null +++ b/qtgui/designer/trackWidget.py @@ -0,0 +1,491 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'trackWidget.ui' +# +# Created by: PyQt5 UI code generator 5.9.2 +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore, QtGui, QtWidgets + +class Ui_trackGroupWidget(object): + def setupUi(self, trackGroupWidget): + trackGroupWidget.setObjectName("trackGroupWidget") + trackGroupWidget.resize(1374, 530) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(trackGroupWidget.sizePolicy().hasHeightForWidth()) + trackGroupWidget.setSizePolicy(sizePolicy) + trackGroupWidget.setMaximumSize(QtCore.QSize(16777215, 900)) + self.verticalLayout = QtWidgets.QVBoxLayout(trackGroupWidget) + self.verticalLayout.setContentsMargins(3, 3, 3, 3) + self.verticalLayout.setSpacing(3) + self.verticalLayout.setObjectName("verticalLayout") + self.track = QtWidgets.QWidget(trackGroupWidget) + self.track.setMaximumSize(QtCore.QSize(16777215, 45)) + self.track.setObjectName("track") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.track) + self.horizontalLayout.setContentsMargins(3, 3, 3, 3) + self.horizontalLayout.setSpacing(3) + self.horizontalLayout.setObjectName("horizontalLayout") + self.nameLineEdit = QtWidgets.QLineEdit(self.track) + self.nameLineEdit.setEnabled(True) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.nameLineEdit.sizePolicy().hasHeightForWidth()) + self.nameLineEdit.setSizePolicy(sizePolicy) + self.nameLineEdit.setMinimumSize(QtCore.QSize(200, 0)) + self.nameLineEdit.setObjectName("nameLineEdit") + self.horizontalLayout.addWidget(self.nameLineEdit) + self.frame = QtWidgets.QFrame(self.track) + self.frame.setFrameShape(QtWidgets.QFrame.Box) + self.frame.setFrameShadow(QtWidgets.QFrame.Sunken) + self.frame.setObjectName("frame") + self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.frame) + self.horizontalLayout_3.setContentsMargins(3, 0, 3, 0) + self.horizontalLayout_3.setSpacing(0) + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.upbeatSpinBox = QtWidgets.QSpinBox(self.frame) + self.upbeatSpinBox.setPrefix("") + self.upbeatSpinBox.setMaximum(999999999) + self.upbeatSpinBox.setObjectName("upbeatSpinBox") + self.horizontalLayout_3.addWidget(self.upbeatSpinBox) + self.callTickWidget = QtWidgets.QPushButton(self.frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.callTickWidget.sizePolicy().hasHeightForWidth()) + self.callTickWidget.setSizePolicy(sizePolicy) + self.callTickWidget.setMaximumSize(QtCore.QSize(25, 16777215)) + self.callTickWidget.setFlat(False) + self.callTickWidget.setObjectName("callTickWidget") + self.horizontalLayout_3.addWidget(self.callTickWidget) + self.horizontalLayout.addWidget(self.frame) + self.doubleTrackCheckbox = QtWidgets.QCheckBox(self.track) + self.doubleTrackCheckbox.setObjectName("doubleTrackCheckbox") + self.horizontalLayout.addWidget(self.doubleTrackCheckbox) + self.visibleCheckbox = QtWidgets.QCheckBox(self.track) + self.visibleCheckbox.setChecked(True) + self.visibleCheckbox.setObjectName("visibleCheckbox") + self.horizontalLayout.addWidget(self.visibleCheckbox) + self.frame_2 = QtWidgets.QFrame(self.track) + self.frame_2.setFrameShape(QtWidgets.QFrame.Box) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Sunken) + self.frame_2.setObjectName("frame_2") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.frame_2) + self.horizontalLayout_4.setContentsMargins(3, 0, 3, 0) + self.horizontalLayout_4.setSpacing(3) + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.midiChannelSpinBox = QtWidgets.QSpinBox(self.frame_2) + self.midiChannelSpinBox.setMaximum(15) + self.midiChannelSpinBox.setObjectName("midiChannelSpinBox") + self.horizontalLayout_4.addWidget(self.midiChannelSpinBox) + self.ccChannelsPushButton = QtWidgets.QPushButton(self.frame_2) + self.ccChannelsPushButton.setObjectName("ccChannelsPushButton") + self.horizontalLayout_4.addWidget(self.ccChannelsPushButton) + self.midiProgramSpinBox = QtWidgets.QSpinBox(self.frame_2) + self.midiProgramSpinBox.setMinimum(-1) + self.midiProgramSpinBox.setMaximum(127) + self.midiProgramSpinBox.setProperty("value", -1) + self.midiProgramSpinBox.setObjectName("midiProgramSpinBox") + self.horizontalLayout_4.addWidget(self.midiProgramSpinBox) + self.midiBankMsbSpinBox = QtWidgets.QSpinBox(self.frame_2) + self.midiBankMsbSpinBox.setEnabled(False) + self.midiBankMsbSpinBox.setMinimum(0) + self.midiBankMsbSpinBox.setMaximum(127) + self.midiBankMsbSpinBox.setProperty("value", 0) + self.midiBankMsbSpinBox.setObjectName("midiBankMsbSpinBox") + self.horizontalLayout_4.addWidget(self.midiBankMsbSpinBox) + self.midiTransposeSpinBox = QtWidgets.QSpinBox(self.frame_2) + self.midiTransposeSpinBox.setMinimum(-127) + self.midiTransposeSpinBox.setMaximum(128) + self.midiTransposeSpinBox.setObjectName("midiTransposeSpinBox") + self.horizontalLayout_4.addWidget(self.midiTransposeSpinBox) + self.midiBankLsbSpinBox = QtWidgets.QSpinBox(self.frame_2) + self.midiBankLsbSpinBox.setEnabled(False) + self.midiBankLsbSpinBox.setMinimum(0) + self.midiBankLsbSpinBox.setMaximum(127) + self.midiBankLsbSpinBox.setProperty("value", 0) + self.midiBankLsbSpinBox.setObjectName("midiBankLsbSpinBox") + self.horizontalLayout_4.addWidget(self.midiBankLsbSpinBox) + self.horizontalLayout.addWidget(self.frame_2) + self.deleteButton = QtWidgets.QPushButton(self.track) + self.deleteButton.setObjectName("deleteButton") + self.horizontalLayout.addWidget(self.deleteButton) + spacerItem = QtWidgets.QSpacerItem(640, 477, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem) + self.verticalLayout.addWidget(self.track) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.label = QtWidgets.QLabel(trackGroupWidget) + self.label.setObjectName("label") + self.horizontalLayout_2.addWidget(self.label) + self.instrumentName = QtWidgets.QLineEdit(trackGroupWidget) + self.instrumentName.setMaxLength(32767) + self.instrumentName.setObjectName("instrumentName") + self.horizontalLayout_2.addWidget(self.instrumentName) + self.label_2 = QtWidgets.QLabel(trackGroupWidget) + self.label_2.setObjectName("label_2") + self.horizontalLayout_2.addWidget(self.label_2) + self.shortInstrumentName = QtWidgets.QLineEdit(trackGroupWidget) + self.shortInstrumentName.setMaxLength(5) + self.shortInstrumentName.setObjectName("shortInstrumentName") + self.horizontalLayout_2.addWidget(self.shortInstrumentName) + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_2.addItem(spacerItem1) + self.verticalLayout.addLayout(self.horizontalLayout_2) + self.advanced = QtWidgets.QGroupBox(trackGroupWidget) + self.advanced.setCheckable(True) + self.advanced.setObjectName("advanced") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.advanced) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.advancedContent = QtWidgets.QTabWidget(self.advanced) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.advancedContent.sizePolicy().hasHeightForWidth()) + self.advancedContent.setSizePolicy(sizePolicy) + self.advancedContent.setObjectName("advancedContent") + self.tab = QtWidgets.QWidget() + self.tab.setObjectName("tab") + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.tab) + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.widget_3 = QtWidgets.QWidget(self.tab) + self.widget_3.setObjectName("widget_3") + self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.widget_3) + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + self.widget_2 = QtWidgets.QWidget(self.widget_3) + self.widget_2.setObjectName("widget_2") + self.formLayout_4 = QtWidgets.QFormLayout(self.widget_2) + self.formLayout_4.setObjectName("formLayout_4") + self.label_3 = QtWidgets.QLabel(self.widget_2) + self.label_3.setObjectName("label_3") + self.formLayout_4.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_3) + self.defaultOn = QtWidgets.QLineEdit(self.widget_2) + self.defaultOn.setObjectName("defaultOn") + self.formLayout_4.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.defaultOn) + self.label_4 = QtWidgets.QLabel(self.widget_2) + self.label_4.setObjectName("label_4") + self.formLayout_4.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_4) + self.defaultOff = QtWidgets.QLineEdit(self.widget_2) + self.defaultOff.setObjectName("defaultOff") + self.formLayout_4.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.defaultOff) + self.label_6 = QtWidgets.QLabel(self.widget_2) + self.label_6.setObjectName("label_6") + self.formLayout_4.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_6) + self.staccatoOn = QtWidgets.QLineEdit(self.widget_2) + self.staccatoOn.setObjectName("staccatoOn") + self.formLayout_4.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.staccatoOn) + self.label_5 = QtWidgets.QLabel(self.widget_2) + self.label_5.setObjectName("label_5") + self.formLayout_4.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.label_5) + self.staccatoOff = QtWidgets.QLineEdit(self.widget_2) + self.staccatoOff.setObjectName("staccatoOff") + self.formLayout_4.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.staccatoOff) + self.label_8 = QtWidgets.QLabel(self.widget_2) + self.label_8.setObjectName("label_8") + self.formLayout_4.setWidget(11, QtWidgets.QFormLayout.LabelRole, self.label_8) + self.tenutoOn = QtWidgets.QLineEdit(self.widget_2) + self.tenutoOn.setObjectName("tenutoOn") + self.formLayout_4.setWidget(11, QtWidgets.QFormLayout.FieldRole, self.tenutoOn) + self.label_9 = QtWidgets.QLabel(self.widget_2) + self.label_9.setObjectName("label_9") + self.formLayout_4.setWidget(12, QtWidgets.QFormLayout.LabelRole, self.label_9) + self.tenutoOff = QtWidgets.QLineEdit(self.widget_2) + self.tenutoOff.setObjectName("tenutoOff") + self.formLayout_4.setWidget(12, QtWidgets.QFormLayout.FieldRole, self.tenutoOff) + self.label_10 = QtWidgets.QLabel(self.widget_2) + self.label_10.setObjectName("label_10") + self.formLayout_4.setWidget(13, QtWidgets.QFormLayout.LabelRole, self.label_10) + self.legatoOn = QtWidgets.QLineEdit(self.widget_2) + self.legatoOn.setObjectName("legatoOn") + self.formLayout_4.setWidget(13, QtWidgets.QFormLayout.FieldRole, self.legatoOn) + self.label_7 = QtWidgets.QLabel(self.widget_2) + self.label_7.setObjectName("label_7") + self.formLayout_4.setWidget(14, QtWidgets.QFormLayout.LabelRole, self.label_7) + self.legatoOff = QtWidgets.QLineEdit(self.widget_2) + self.legatoOff.setObjectName("legatoOff") + self.formLayout_4.setWidget(14, QtWidgets.QFormLayout.FieldRole, self.legatoOff) + self.horizontalLayout_5.addWidget(self.widget_2) + spacerItem2 = QtWidgets.QSpacerItem(643, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_5.addItem(spacerItem2) + self.verticalLayout_4.addWidget(self.widget_3) + self.buttonResetDurations = QtWidgets.QPushButton(self.tab) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.buttonResetDurations.sizePolicy().hasHeightForWidth()) + self.buttonResetDurations.setSizePolicy(sizePolicy) + self.buttonResetDurations.setObjectName("buttonResetDurations") + self.verticalLayout_4.addWidget(self.buttonResetDurations) + self.advancedContent.addTab(self.tab, "") + self.tab_2 = QtWidgets.QWidget() + self.tab_2.setObjectName("tab_2") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.tab_2) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.widget = QtWidgets.QWidget(self.tab_2) + self.widget.setObjectName("widget") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.widget) + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.widget_4 = QtWidgets.QWidget(self.widget) + self.widget_4.setObjectName("widget_4") + self.formLayout = QtWidgets.QFormLayout(self.widget_4) + self.formLayout.setObjectName("formLayout") + self.label_11 = QtWidgets.QLabel(self.widget_4) + self.label_11.setObjectName("label_11") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_11) + self.dynamics_ppppp = QtWidgets.QSpinBox(self.widget_4) + self.dynamics_ppppp.setMaximum(127) + self.dynamics_ppppp.setObjectName("dynamics_ppppp") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.dynamics_ppppp) + self.label_13 = QtWidgets.QLabel(self.widget_4) + self.label_13.setObjectName("label_13") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_13) + self.dynamics_pppp = QtWidgets.QSpinBox(self.widget_4) + self.dynamics_pppp.setMaximum(127) + self.dynamics_pppp.setObjectName("dynamics_pppp") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.dynamics_pppp) + self.label_29 = QtWidgets.QLabel(self.widget_4) + self.label_29.setObjectName("label_29") + self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_29) + self.dynamics_ppp = QtWidgets.QSpinBox(self.widget_4) + self.dynamics_ppp.setObjectName("dynamics_ppp") + self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.dynamics_ppp) + self.label_14 = QtWidgets.QLabel(self.widget_4) + self.label_14.setObjectName("label_14") + self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_14) + self.dynamics_pp = QtWidgets.QSpinBox(self.widget_4) + self.dynamics_pp.setMaximum(127) + self.dynamics_pp.setObjectName("dynamics_pp") + self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.dynamics_pp) + self.label_15 = QtWidgets.QLabel(self.widget_4) + self.label_15.setObjectName("label_15") + self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_15) + self.dynamics_p = QtWidgets.QSpinBox(self.widget_4) + self.dynamics_p.setMaximum(127) + self.dynamics_p.setObjectName("dynamics_p") + self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.dynamics_p) + self.label_16 = QtWidgets.QLabel(self.widget_4) + self.label_16.setObjectName("label_16") + self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_16) + self.dynamics_mp = QtWidgets.QSpinBox(self.widget_4) + self.dynamics_mp.setMaximum(127) + self.dynamics_mp.setObjectName("dynamics_mp") + self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.dynamics_mp) + self.horizontalLayout_6.addWidget(self.widget_4) + self.widgetLeft = QtWidgets.QWidget(self.widget) + self.widgetLeft.setObjectName("widgetLeft") + self.formLayout_2 = QtWidgets.QFormLayout(self.widgetLeft) + self.formLayout_2.setObjectName("formLayout_2") + self.label_17 = QtWidgets.QLabel(self.widgetLeft) + self.label_17.setObjectName("label_17") + self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_17) + self.dynamics_mf = QtWidgets.QSpinBox(self.widgetLeft) + self.dynamics_mf.setMaximum(127) + self.dynamics_mf.setObjectName("dynamics_mf") + self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.dynamics_mf) + self.label_18 = QtWidgets.QLabel(self.widgetLeft) + self.label_18.setObjectName("label_18") + self.formLayout_2.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_18) + self.dynamics_f = QtWidgets.QSpinBox(self.widgetLeft) + self.dynamics_f.setMaximum(127) + self.dynamics_f.setObjectName("dynamics_f") + self.formLayout_2.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.dynamics_f) + self.label_19 = QtWidgets.QLabel(self.widgetLeft) + self.label_19.setObjectName("label_19") + self.formLayout_2.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_19) + self.dynamics_ff = QtWidgets.QSpinBox(self.widgetLeft) + self.dynamics_ff.setMaximum(127) + self.dynamics_ff.setObjectName("dynamics_ff") + self.formLayout_2.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.dynamics_ff) + self.label_20 = QtWidgets.QLabel(self.widgetLeft) + self.label_20.setObjectName("label_20") + self.formLayout_2.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_20) + self.dynamics_fff = QtWidgets.QSpinBox(self.widgetLeft) + self.dynamics_fff.setMaximum(127) + self.dynamics_fff.setObjectName("dynamics_fff") + self.formLayout_2.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.dynamics_fff) + self.label_21 = QtWidgets.QLabel(self.widgetLeft) + self.label_21.setObjectName("label_21") + self.formLayout_2.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.label_21) + self.dynamics_ffff = QtWidgets.QSpinBox(self.widgetLeft) + self.dynamics_ffff.setMaximum(127) + self.dynamics_ffff.setObjectName("dynamics_ffff") + self.formLayout_2.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.dynamics_ffff) + self.horizontalLayout_6.addWidget(self.widgetLeft) + self.widgetRight = QtWidgets.QWidget(self.widget) + self.widgetRight.setObjectName("widgetRight") + self.formLayout_3 = QtWidgets.QFormLayout(self.widgetRight) + self.formLayout_3.setObjectName("formLayout_3") + self.label_12 = QtWidgets.QLabel(self.widgetRight) + self.label_12.setObjectName("label_12") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_12) + self.dynamics_tacet = QtWidgets.QSpinBox(self.widgetRight) + self.dynamics_tacet.setMaximum(127) + self.dynamics_tacet.setObjectName("dynamics_tacet") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.dynamics_tacet) + self.label_22 = QtWidgets.QLabel(self.widgetRight) + self.label_22.setObjectName("label_22") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_22) + self.dynamics_custom = QtWidgets.QSpinBox(self.widgetRight) + self.dynamics_custom.setMaximum(127) + self.dynamics_custom.setObjectName("dynamics_custom") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.dynamics_custom) + self.label_23 = QtWidgets.QLabel(self.widgetRight) + self.label_23.setObjectName("label_23") + self.formLayout_3.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_23) + self.dynamics_sfz = QtWidgets.QSpinBox(self.widgetRight) + self.dynamics_sfz.setMaximum(127) + self.dynamics_sfz.setObjectName("dynamics_sfz") + self.formLayout_3.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.dynamics_sfz) + self.label_24 = QtWidgets.QLabel(self.widgetRight) + self.label_24.setObjectName("label_24") + self.formLayout_3.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_24) + self.dynamics_sf = QtWidgets.QSpinBox(self.widgetRight) + self.dynamics_sf.setMaximum(127) + self.dynamics_sf.setObjectName("dynamics_sf") + self.formLayout_3.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.dynamics_sf) + self.label_25 = QtWidgets.QLabel(self.widgetRight) + self.label_25.setObjectName("label_25") + self.formLayout_3.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_25) + self.dynamics_sff = QtWidgets.QSpinBox(self.widgetRight) + self.dynamics_sff.setMaximum(127) + self.dynamics_sff.setObjectName("dynamics_sff") + self.formLayout_3.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.dynamics_sff) + self.label_26 = QtWidgets.QLabel(self.widgetRight) + self.label_26.setObjectName("label_26") + self.formLayout_3.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_26) + self.dynamics_fp = QtWidgets.QSpinBox(self.widgetRight) + self.dynamics_fp.setMaximum(127) + self.dynamics_fp.setObjectName("dynamics_fp") + self.formLayout_3.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.dynamics_fp) + self.label_27 = QtWidgets.QLabel(self.widgetRight) + self.label_27.setObjectName("label_27") + self.formLayout_3.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_27) + self.dynamics_sp = QtWidgets.QSpinBox(self.widgetRight) + self.dynamics_sp.setMaximum(127) + self.dynamics_sp.setObjectName("dynamics_sp") + self.formLayout_3.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.dynamics_sp) + self.label_28 = QtWidgets.QLabel(self.widgetRight) + self.label_28.setObjectName("label_28") + self.formLayout_3.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_28) + self.dynamics_spp = QtWidgets.QSpinBox(self.widgetRight) + self.dynamics_spp.setMaximum(127) + self.dynamics_spp.setObjectName("dynamics_spp") + self.formLayout_3.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.dynamics_spp) + self.horizontalLayout_6.addWidget(self.widgetRight) + spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_6.addItem(spacerItem3) + self.verticalLayout_3.addWidget(self.widget) + self.buttonResetDynamics = QtWidgets.QPushButton(self.tab_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.buttonResetDynamics.sizePolicy().hasHeightForWidth()) + self.buttonResetDynamics.setSizePolicy(sizePolicy) + self.buttonResetDynamics.setObjectName("buttonResetDynamics") + self.verticalLayout_3.addWidget(self.buttonResetDynamics) + self.advancedContent.addTab(self.tab_2, "") + self.verticalLayout_2.addWidget(self.advancedContent) + self.verticalLayout.addWidget(self.advanced) + + self.retranslateUi(trackGroupWidget) + self.advancedContent.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(trackGroupWidget) + trackGroupWidget.setTabOrder(self.nameLineEdit, self.upbeatSpinBox) + trackGroupWidget.setTabOrder(self.upbeatSpinBox, self.callTickWidget) + trackGroupWidget.setTabOrder(self.callTickWidget, self.doubleTrackCheckbox) + trackGroupWidget.setTabOrder(self.doubleTrackCheckbox, self.visibleCheckbox) + trackGroupWidget.setTabOrder(self.visibleCheckbox, self.midiChannelSpinBox) + trackGroupWidget.setTabOrder(self.midiChannelSpinBox, self.ccChannelsPushButton) + trackGroupWidget.setTabOrder(self.ccChannelsPushButton, self.midiProgramSpinBox) + trackGroupWidget.setTabOrder(self.midiProgramSpinBox, self.midiBankMsbSpinBox) + trackGroupWidget.setTabOrder(self.midiBankMsbSpinBox, self.midiTransposeSpinBox) + trackGroupWidget.setTabOrder(self.midiTransposeSpinBox, self.midiBankLsbSpinBox) + trackGroupWidget.setTabOrder(self.midiBankLsbSpinBox, self.deleteButton) + trackGroupWidget.setTabOrder(self.deleteButton, self.instrumentName) + trackGroupWidget.setTabOrder(self.instrumentName, self.shortInstrumentName) + trackGroupWidget.setTabOrder(self.shortInstrumentName, self.advanced) + trackGroupWidget.setTabOrder(self.advanced, self.advancedContent) + trackGroupWidget.setTabOrder(self.advancedContent, self.defaultOn) + trackGroupWidget.setTabOrder(self.defaultOn, self.defaultOff) + trackGroupWidget.setTabOrder(self.defaultOff, self.staccatoOn) + trackGroupWidget.setTabOrder(self.staccatoOn, self.staccatoOff) + trackGroupWidget.setTabOrder(self.staccatoOff, self.tenutoOn) + trackGroupWidget.setTabOrder(self.tenutoOn, self.tenutoOff) + trackGroupWidget.setTabOrder(self.tenutoOff, self.legatoOn) + trackGroupWidget.setTabOrder(self.legatoOn, self.legatoOff) + trackGroupWidget.setTabOrder(self.legatoOff, self.buttonResetDurations) + trackGroupWidget.setTabOrder(self.buttonResetDurations, self.dynamics_ppppp) + trackGroupWidget.setTabOrder(self.dynamics_ppppp, self.dynamics_pppp) + trackGroupWidget.setTabOrder(self.dynamics_pppp, self.dynamics_ppp) + trackGroupWidget.setTabOrder(self.dynamics_ppp, self.dynamics_pp) + trackGroupWidget.setTabOrder(self.dynamics_pp, self.dynamics_p) + trackGroupWidget.setTabOrder(self.dynamics_p, self.dynamics_mp) + trackGroupWidget.setTabOrder(self.dynamics_mp, self.dynamics_mf) + trackGroupWidget.setTabOrder(self.dynamics_mf, self.dynamics_f) + trackGroupWidget.setTabOrder(self.dynamics_f, self.dynamics_ff) + trackGroupWidget.setTabOrder(self.dynamics_ff, self.dynamics_fff) + trackGroupWidget.setTabOrder(self.dynamics_fff, self.dynamics_ffff) + trackGroupWidget.setTabOrder(self.dynamics_ffff, self.dynamics_tacet) + trackGroupWidget.setTabOrder(self.dynamics_tacet, self.dynamics_custom) + trackGroupWidget.setTabOrder(self.dynamics_custom, self.dynamics_sfz) + trackGroupWidget.setTabOrder(self.dynamics_sfz, self.dynamics_sf) + trackGroupWidget.setTabOrder(self.dynamics_sf, self.dynamics_sff) + trackGroupWidget.setTabOrder(self.dynamics_sff, self.dynamics_fp) + trackGroupWidget.setTabOrder(self.dynamics_fp, self.dynamics_sp) + trackGroupWidget.setTabOrder(self.dynamics_sp, self.dynamics_spp) + trackGroupWidget.setTabOrder(self.dynamics_spp, self.buttonResetDynamics) + + def retranslateUi(self, trackGroupWidget): + _translate = QtCore.QCoreApplication.translate + trackGroupWidget.setWindowTitle(_translate("trackGroupWidget", "GroupBox")) + trackGroupWidget.setTitle(_translate("trackGroupWidget", "GroupBox")) + self.upbeatSpinBox.setSuffix(_translate("trackGroupWidget", " Upbeat Ticks")) + self.callTickWidget.setText(_translate("trackGroupWidget", "𝅘𝅥𝅮 ")) + self.doubleTrackCheckbox.setText(_translate("trackGroupWidget", "Double Track")) + self.visibleCheckbox.setText(_translate("trackGroupWidget", "Visible")) + self.midiChannelSpinBox.setPrefix(_translate("trackGroupWidget", "Channel ")) + self.ccChannelsPushButton.setText(_translate("trackGroupWidget", "CC Channels")) + self.midiProgramSpinBox.setPrefix(_translate("trackGroupWidget", "Program ")) + self.midiBankMsbSpinBox.setPrefix(_translate("trackGroupWidget", "Bank MSB")) + self.midiTransposeSpinBox.setPrefix(_translate("trackGroupWidget", "Transpose ")) + self.midiBankLsbSpinBox.setPrefix(_translate("trackGroupWidget", "Bank LSB")) + self.deleteButton.setText(_translate("trackGroupWidget", "Delete")) + self.label.setText(_translate("trackGroupWidget", "Instrument Name")) + self.label_2.setText(_translate("trackGroupWidget", "Short Instrument Name")) + self.advanced.setTitle(_translate("trackGroupWidget", "Advanced")) + self.label_3.setText(_translate("trackGroupWidget", "Derfault On")) + self.label_4.setText(_translate("trackGroupWidget", "Default Off")) + self.label_6.setText(_translate("trackGroupWidget", "Staccato On")) + self.label_5.setText(_translate("trackGroupWidget", "Staccato Off")) + self.label_8.setText(_translate("trackGroupWidget", "Tenuto On")) + self.label_9.setText(_translate("trackGroupWidget", "Tenuto Off")) + self.label_10.setText(_translate("trackGroupWidget", "Legato On")) + self.label_7.setText(_translate("trackGroupWidget", "Legato Off")) + self.buttonResetDurations.setText(_translate("trackGroupWidget", "Reset to Default Duration Values")) + self.advancedContent.setTabText(self.advancedContent.indexOf(self.tab), _translate("trackGroupWidget", "Duration Offsets")) + self.label_11.setText(_translate("trackGroupWidget", "ppppp")) + self.label_13.setText(_translate("trackGroupWidget", "pppp")) + self.label_29.setText(_translate("trackGroupWidget", "ppp")) + self.label_14.setText(_translate("trackGroupWidget", "pp")) + self.label_15.setText(_translate("trackGroupWidget", "p")) + self.label_16.setText(_translate("trackGroupWidget", "mp")) + self.label_17.setText(_translate("trackGroupWidget", "mf")) + self.label_18.setText(_translate("trackGroupWidget", "f")) + self.label_19.setText(_translate("trackGroupWidget", "ff")) + self.label_20.setText(_translate("trackGroupWidget", "fff")) + self.label_21.setText(_translate("trackGroupWidget", "ffff")) + self.label_12.setText(_translate("trackGroupWidget", "tacet")) + self.label_22.setText(_translate("trackGroupWidget", "custom")) + self.label_23.setText(_translate("trackGroupWidget", "sfz")) + self.label_24.setText(_translate("trackGroupWidget", "sf")) + self.label_25.setText(_translate("trackGroupWidget", "sff")) + self.label_26.setText(_translate("trackGroupWidget", "fp")) + self.label_27.setText(_translate("trackGroupWidget", "sp")) + self.label_28.setText(_translate("trackGroupWidget", "spp")) + self.buttonResetDynamics.setText(_translate("trackGroupWidget", "Reset to Default Dynamic Values")) + self.advancedContent.setTabText(self.advancedContent.indexOf(self.tab_2), _translate("trackGroupWidget", "Dynamic Signature Definitions")) + diff --git a/qtgui/designer/trackWidget.ui b/qtgui/designer/trackWidget.ui new file mode 100644 index 0000000..64fc241 --- /dev/null +++ b/qtgui/designer/trackWidget.ui @@ -0,0 +1,868 @@ + + + trackGroupWidget + + + + 0 + 0 + 1374 + 530 + + + + + 0 + 0 + + + + + 16777215 + 900 + + + + GroupBox + + + GroupBox + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + 16777215 + 45 + + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + true + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 0 + + + 3 + + + 0 + + + 3 + + + 0 + + + + + Upbeat Ticks + + + + + + 999999999 + + + + + + + + 0 + 0 + + + + + 25 + 16777215 + + + + 𝅘𝅥𝅮 + + + false + + + + + + + + + + Double Track + + + + + + + Visible + + + true + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 0 + + + 3 + + + 0 + + + + + Channel + + + 15 + + + + + + + CC Channels + + + + + + + Program + + + -1 + + + 127 + + + -1 + + + + + + + false + + + Bank MSB + + + 0 + + + 127 + + + 0 + + + + + + + Transpose + + + -127 + + + 128 + + + + + + + false + + + Bank LSB + + + 0 + + + 127 + + + 0 + + + + + + + + + + Delete + + + + + + + Qt::Horizontal + + + + 640 + 477 + + + + + + + + + + + + + Instrument Name + + + + + + + 32767 + + + + + + + Short Instrument Name + + + + + + + 5 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Advanced + + + true + + + + + + + 0 + 0 + + + + 0 + + + + Duration Offsets + + + + + + + + + + + + Derfault On + + + + + + + + + + Default Off + + + + + + + + + + Staccato On + + + + + + + + + + Staccato Off + + + + + + + + + + Tenuto On + + + + + + + + + + Tenuto Off + + + + + + + + + + Legato On + + + + + + + + + + Legato Off + + + + + + + + + + + + + Qt::Horizontal + + + + 643 + 20 + + + + + + + + + + + + 0 + 0 + + + + Reset to Default Duration Values + + + + + + + + Dynamic Signature Definitions + + + + + + + + + + + + ppppp + + + + + + + 127 + + + + + + + pppp + + + + + + + 127 + + + + + + + ppp + + + + + + + + + + pp + + + + + + + 127 + + + + + + + p + + + + + + + 127 + + + + + + + mp + + + + + + + 127 + + + + + + + + + + + + + mf + + + + + + + 127 + + + + + + + f + + + + + + + 127 + + + + + + + ff + + + + + + + 127 + + + + + + + fff + + + + + + + 127 + + + + + + + ffff + + + + + + + 127 + + + + + + + + + + + + + tacet + + + + + + + 127 + + + + + + + custom + + + + + + + 127 + + + + + + + sfz + + + + + + + 127 + + + + + + + sf + + + + + + + 127 + + + + + + + sff + + + + + + + 127 + + + + + + + fp + + + + + + + 127 + + + + + + + sp + + + + + + + 127 + + + + + + + spp + + + + + + + 127 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 0 + + + + Reset to Default Dynamic Values + + + + + + + + + + + + + + nameLineEdit + upbeatSpinBox + callTickWidget + doubleTrackCheckbox + visibleCheckbox + midiChannelSpinBox + ccChannelsPushButton + midiProgramSpinBox + midiBankMsbSpinBox + midiTransposeSpinBox + midiBankLsbSpinBox + deleteButton + instrumentName + shortInstrumentName + advanced + advancedContent + defaultOn + defaultOff + staccatoOn + staccatoOff + tenutoOn + tenutoOff + legatoOn + legatoOff + buttonResetDurations + dynamics_ppppp + dynamics_pppp + dynamics_ppp + dynamics_pp + dynamics_p + dynamics_mp + dynamics_mf + dynamics_f + dynamics_ff + dynamics_fff + dynamics_ffff + dynamics_tacet + dynamics_custom + dynamics_sfz + dynamics_sf + dynamics_sff + dynamics_fp + dynamics_sp + dynamics_spp + buttonResetDynamics + + + + diff --git a/qtgui/graphs.py b/qtgui/graphs.py new file mode 100644 index 0000000..b335fb4 --- /dev/null +++ b/qtgui/graphs.py @@ -0,0 +1,571 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from PyQt5 import QtCore, QtGui, QtSvg, QtWidgets +from .constantsAndConfigs import constantsAndConfigs +from template.qtgui.helper import stringToColor, removeInstancesFromScene, callContextMenu, stretchLine, stretchRect +import engine.api as api + +class CCPath(QtWidgets.QGraphicsRectItem): + """ + A CCPath only exists when the backend track has a cc-part activated. + Since each track has 128 potential CC paths we don't create and + save a bunch of empty ones, neither in the backend nor here. + + Therefore: you cannot display a message "click here to create + a CC track/block" here in the CC Path since the CCPath does not + exist at this point in time. Thus this button is created in the track. One button for all CCs. + + There are two item types. Movable, or handle-points, + and non-movable: interpolation-points. + + The backend only knows handle points and a function which + interpolates until the next point. + + However, that results only in CC values 0-128 anyway. So + we use these directly. + + We don't lie to the user. There is no smooth curve, not even + a linear one, between CC values 65 and 66. It is just a step. + + So we show the steps.""" + + def __init__(self, parentGuiTrack, parentDataTrackId): + super().__init__(0, 0, 0, 0) + self.setAcceptHoverEvents(True) + #self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable|QtWidgets.QGraphicsItem.ItemSendsGeometryChanges|QtWidgets.QGraphicsItem.ItemIsFocusable|QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + self.setFlags(QtWidgets.QGraphicsItem.ItemIsFocusable|QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + #self.setBrush(QtCore.Qt.red) #debug + self.setPen(QtGui.QPen(QtCore.Qt.transparent)) + + self.parentDataTrackId = parentDataTrackId + self.parentGuiTrack = parentGuiTrack + self.userItems = [] + self.interpolatedItems = [] + self.other = [] + self.blockListCache = [] #backend dictExport items. updated through self.updateGraphBlockTrack + self.blockdictCache = {} #blockId:guiBlock updated through self.updateGraphBlockTrack + self.transparentBlockHandles = [] #transparentBlockHandles in correct order. updated through self.updateGraphBlockTrack + + def itemChange(self, changeEnum, value): + if changeEnum == QtWidgets.QGraphicsItem.ItemVisibleHasChanged: #12 + if self.isVisible(): + self.parentGuiTrack.universalCreateFirstCCBlock.hide() + else: + self.parentGuiTrack.universalCreateFirstCCBlock.show() + + return super().itemChange(changeEnum, value) + + def mousePressEvent(self, event): + if event.button() == 1: #QtCore.Qt.MouseButton.LeftButton + self.add(event.pos()) + + @property + def items(self): + return self.userItems + self.interpolatedItems + self.other + + #@property + #def transparentBlockHandles(self): + #return CCGraphTransparentBlock.instances This does not work because we need the blocks per track, not all of them in all tracks. + + def createGraphicItemsFromData(self, staticRepresentationList): + """The tick position is, as always, a long tickvalue from the + backend. + The CC value, 0-127, has its default 0-line on the middle line + as all items, since this is the track root. Since CC 64 is the + middle value for CCs we shift all the points down by 64 so + the middle staff line becomes CC 64. + """ + for item in self.items: + self.scene().removeWhenIdle(item) + self.other = [] + self.userItems = [] + self.interpolatedItems = [] + + for point in staticRepresentationList: + if point["type"] == "interpolated": + p = CCInterpolatedPoint() + self.interpolatedItems.append(p) + self.userItems[-1].interpolatedItemsRight.append(p) + else: #user, lastInBlock or lastInTrack + p = CCUserPoint(self, point) + + if self.userItems: + p.interpolatedItemsLeft = self.userItems[-1].interpolatedItemsRight + + self.userItems.append(p) + + t = QtWidgets.QGraphicsSimpleTextItem(str(abs(point["value"]))) + t.setFont(constantsAndConfigs.theFont) + t.setParentItem(self) + t.setScale(0.75) + self.other.append(t) + t.setPos(point["position"] / constantsAndConfigs.ticksToPixelRatio, 29) + + p.setParentItem(self) + p.setPos(point["position"] / constantsAndConfigs.ticksToPixelRatio , (point["value"]+64)*0.4375) #value goes from -0 to -127 and are compressed to fit between two lines in the staff. + + + def updateGraphBlockTrack(self, staticRepresentationList): + """Handles and visualizes block boundaries""" + #{"type" : "GraphBlock", "id":id(block), "name":block.name, "duration":block.duration, "position":tickCounter} + + self.blockListCache = staticRepresentationList #sorted list + self.blockdictCache = {} #reset + + for tbh in self.transparentBlockHandles: + tbh.setParentItem(None) + tbh.scene().removeWhenIdle(tbh) + self.transparentBlockHandles = [] #reset + + #removeInstancesFromScene(CCGraphTransparentBlock) #this removes ALL blocks in all tracks from the scene. don't. + for dictExportItem in staticRepresentationList: + guiBlock = CCGraphTransparentBlock(parent = self, staticExportItem = dictExportItem, x = 0, y = -28, w = dictExportItem["duration"] / constantsAndConfigs.ticksToPixelRatio, h = 2*28) + guiBlock.setParentItem(self) + guiBlock.setPos(dictExportItem["position"] / constantsAndConfigs.ticksToPixelRatio,0) + self.blockdictCache[dictExportItem["id"]] = guiBlock + self.transparentBlockHandles.append(guiBlock) + + #Use the last item of the loop above to draw length of the boundary lines. + maximumPixels = (dictExportItem["duration"] + dictExportItem["position"]) / constantsAndConfigs.ticksToPixelRatio + upperLine = QtWidgets.QGraphicsLineItem(0,-28,maximumPixels,-28) #x1, y1, x2, y2 + #upperLine.setPen(QtGui.QColor("red")) + upperLine.setParentItem(self) + self.other.append(upperLine) + lowerLine = QtWidgets.QGraphicsLineItem(0,28,maximumPixels,28) #x1, y1, x2, y2 + #lowerLine.setPen(QtGui.QColor("green")) + lowerLine.setParentItem(self) + self.other.append(lowerLine) + upperLine.setOpacity(0.3) + lowerLine.setOpacity(0.3) + upperLine.setPos(0,0) + lowerLine.setPos(0,0) + #for self.stretchXCoordinates + self.upperLine = upperLine + self.lowerLine = lowerLine + + self.setRect(0,-28,maximumPixels,2*28) + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + stretchRect(self, factor) + stretchLine(self.upperLine, factor) + stretchLine(self.lowerLine, factor) + + for item in self.items: + item.setX(item.pos().x() * factor) + + for transparentBlockHandle in self.transparentBlockHandles: + transparentBlockHandle.setX(transparentBlockHandle.pos().x() * factor) + transparentBlockHandle.stretchXCoordinates(factor) + + def blocKByPosition(self, tickPositionAbsoluteBackendValue): + for block in self.blockListCache: + start = block["position"] + end = start + block["duration"] + if start <= tickPositionAbsoluteBackendValue < end: + return block["id"], block["position"] + return None #After the last block. + + def blockAt(self, qScenePosition): + """For compatibility with track.blockAt + Can return a block or None for "after the last block" """ + backendPosition = qScenePosition * constantsAndConfigs.ticksToPixelRatio + result = self.blocKByPosition(backendPosition) + if result: + blockId, blockBackendPosition = result + assert blockId in self.blockdictCache + return self.blockdictCache[blockId] + else: + return None + + def getCCNumber(self): + """The CC number is a dynamic value""" + for ccNumber, ccGraphTrack in self.parentGuiTrack.ccPaths.items(): + if ccGraphTrack is self: + return ccNumber + else: + raise ValueError("This Block is not in the ccPath dict of the GuiTrack""") + + + def getYAsBackendValue(self, y): + newCCValue = int(y / 0.4375 - 64) #value goes from -0 to -127 and are compressed to fit between two lines in the staff. + newCCValue = abs(newCCValue) + assert 0 <= newCCValue < 128 + return newCCValue + + def add(self, qPos): + """Only activated through the hover area which gives are the + most control over where clicks are allowed. + Also there was a weird bug that the CCPath itself cannot + detect mouse clicks in the right position""" + y = qPos.y() + if -28 < y < 28: + sp = qPos.x() * constantsAndConfigs.ticksToPixelRatio + blockId, blockStartOffset = self.blocKByPosition(sp) #get the block before rounding. Otherwise rounding might result in a position higher than the blocks duration + if constantsAndConfigs.snapToGrid: + sp = round(sp / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + positionInBlockBackendTicks = sp - blockStartOffset + api.addGraphItem(blockId, positionInBlockBackendTicks, self.getYAsBackendValue(y)) + +class CCGraphTransparentBlock(QtWidgets.QGraphicsRectItem): + instances = [] + + def __init__(self, parent, staticExportItem, x, y, w, h): + self.__class__.instances.append(self) + super().__init__(x, y, w, h) + #self.setFlags(QtWidgets.QGraphicsItem.ItemDoesntPropagateOpacityToChildren|QtWidgets.QGraphicsItem.ItemIsMovable) #no mouseReleaseEvent without selection or movable. + self.setFlags(QtWidgets.QGraphicsItem.ItemDoesntPropagateOpacityToChildren) #no mouseReleaseEvent without selection or movable. + self.parent = parent # CCPath instance + self.color = stringToColor(staticExportItem["name"]) + self.setBrush(self.color) + self.trans = QtGui.QColor("transparent") + self.setPen(self.trans) + self.setBrush(self.trans) + self.setOpacity(0.2) #mimic background behaviour + self.staticExportItem = staticExportItem + + self.blockEndMarker = CCGraphBlockEndMarker(self, staticExportItem) + self.blockEndMarker.setParentItem(self) + self.blockEndMarker.setPos(staticExportItem["duration"] / constantsAndConfigs.ticksToPixelRatio, 0) + + self.posBeforeMove = None + self.cursorPosOnMoveStart = None + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + stretchRect(self, factor) + self.blockEndMarker.setX(self.blockEndMarker.pos().x() * factor) + + def mousePressEventCustom(self, event): + """Custom gets called by the scene mouse press event directly only when the right keys + are hold down. + e.g. shift + middle mouse button for moving this block""" + self.posBeforeMove = self.pos() + self.cursorPosOnMoveStart = QtGui.QCursor.pos() + self.setBrush(self.color) + super().mousePressEvent(event) + + def mouseMoveEventCustom(self, event): + """Custom gets called by the scene mouse press event directly only when the right keys + are hold down + e.g. shift + middle mouse button for moving this block""" + # All the positions below don't work. They work fine when dragging Tracks around but not this Item. I can't be bothered to figure out why. + #scenePos() results ins an item position that is translated down and right. The higher the x/y value the more the offset + #Instead we calculate our delta ourselves. + + #self.setPos(self.mapToItem(self, event.scenePos())) + #self.setPos(self.mapFromScene(event.scenePos())) + #posGlobal = QtGui.QCursor.pos() + #posView = self.parent.parentScore.parentView.mapFromGlobal(posGlobal) #a widget + #posScene = self.parent.parentScore.parentView.mapToScene(posView) + #print (posGlobal, posView, posScene, event.scenePos()) + + + if self.cursorPosOnMoveStart: + self.setPos(event.scenePos()) + + """ + #does not work with zooming + if self.cursorPosOnMoveStart: + delta = QtGui.QCursor.pos() - self.cursorPosOnMoveStart + new = self.posBeforeMove + delta + if new.x() < 0: + #self.setPos(0, self.posBeforeMove.y()) + self.setPos(0, new.y()) + else: + #self.setPos(new.x(), self.posBeforeMove.y()) #only move in one track + self.setPos(new.x(), new.y()) + #event.ignore() #this blocks the qt movable object since we already move the object on our own. + """ + super().mouseMoveEvent(event) + + + def mouseReleaseEventCustom(self, event): + """Custom gets called by the scene mouse press event directly only when the right keys + are hold down""" + self.setBrush(self.trans) + self.setPos(self.posBeforeMove) #In case the block was moved to a position where no track is (below the tracks) we just reset the graphics. If the moving was correct then the new position will be set by redrawing the whole Conductor. + self.posBeforeMove = None + self.cursorPosOnMoveStart = None + super().mouseReleaseEvent(event) + + def splitHere(self, event): + posRelativeToBlockStart = event.scenePos().x() * constantsAndConfigs.ticksToPixelRatio - self.x() * constantsAndConfigs.ticksToPixelRatio + if constantsAndConfigs.snapToGrid: + posRelativeToBlockStart = round(posRelativeToBlockStart / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + + if posRelativeToBlockStart > 0: + api.splitCCBlock(self.staticExportItem["id"], int(posRelativeToBlockStart)) + + def contextMenuEvent(self, event): + listOfLabelsAndFunctions = [ + ("split here", lambda: self.splitHere(event)), + ("duplicate", lambda: api.duplicateCCBlock(self.staticExportItem["id"])), + ("create content link", lambda: api.duplicateContentLinkCCBlock(self.staticExportItem["id"])), + ("unlink", lambda: api.unlinkCCBlock(self.staticExportItem["id"])), + ("separator", None), + ("join with next block", lambda: api.mergeWithNextGraphBlock(self.staticExportItem["id"])), + ("delete block", lambda: api.deleteCCBlock(self.staticExportItem["id"])), + ("separator", None), + ("append block at the end", lambda ccNum = self.parent.getCCNumber(): api.appendGraphBlock(self.parent.parentDataTrackId, ccNum)), + ] + callContextMenu(listOfLabelsAndFunctions) + +class CCGraphBlockEndMarker(QtWidgets.QGraphicsLineItem): + def __init__(self, parentTransparentBlock, staticExportItem): + super(CCGraphBlockEndMarker, self).__init__(0,-28,0,28) #x, y, w, h + self.parentTransparentBlock = parentTransparentBlock + self.parentCCPath = self.parentTransparentBlock.parent + self.staticExportItem = staticExportItem + self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable|QtWidgets.QGraphicsItem.ItemSendsGeometryChanges|QtWidgets.QGraphicsItem.ItemIsFocusable) + self.setAcceptHoverEvents(True) + self.setCursor(QtCore.Qt.SizeHorCursor) + self.lastPos = self.pos() + #self.setBrush(QtGui.QColor("red")) + pen = QtGui.QPen() # creates a default pen + if not self.staticExportItem["exportsAllItems"]: + pen.setStyle(QtCore.Qt.DashDotLine) + pen.setWidth(2) + self.setPen(pen) + self.setZValue(10) + + self.inactivePen = pen + self.inactivePen.setColor(QtGui.QColor("black")) + + self.activePen = QtGui.QPen(pen) + self.activePen.setColor(QtGui.QColor("cyan")) + + def allItemsRightOfMe(self): + for item in self.parentCCPath.items: + if item.x() > self.x(): + yield item + + def shape(self): + """Qt Function + Return a more accurate shape for this item so that + mouse hovering is more accurate""" + path = QtGui.QPainterPath() + path.addRect(QtCore.QRectF(-3, -1/2 * constantsAndConfigs.trackHeight, 9, constantsAndConfigs.trackHeight)) #this is directly related to inits parameter x, y, w, h + return path + + def mouseReleaseEvent(self, event): + """After moving a point around + send an update to the backend""" + super(CCGraphBlockEndMarker, self).mouseReleaseEvent(event) + if event.button() == 1: #QtCore.Qt.MouseButton.LeftButton + x = event.scenePos().x() + #x = self.x() + x = x * constantsAndConfigs.ticksToPixelRatio + endingRelativeToBlockStart = x - self.staticExportItem["position"] + if constantsAndConfigs.snapToGrid: + endingRelativeToBlockStart = round(endingRelativeToBlockStart / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + assert endingRelativeToBlockStart > 0 + api.changeGraphBlockDuration(self.staticExportItem["id"], endingRelativeToBlockStart) + + + def mousePressEvent(self, event): + super(CCGraphBlockEndMarker, self).mousePressEvent(event) + + if event.button() == 1: #QtCore.Qt.MouseButton.LeftButton + for i in self.allItemsRightOfMe(): + i.hide() + + def mouseMoveEvent(self, event): + """Only active when the item is also selected and left + mouse button is down. Not any mouse event, no hover.""" + super(CCGraphBlockEndMarker, self).mouseMoveEvent(event) + self.setY(self.lastPos.y()) + + def hoverEnterEvent(self, event): + #self.setZValue(20) + #self.parentTransparentBlock.setZValue(19) + self.setPen(self.activePen) + self.parentTransparentBlock.setBrush(self.parentTransparentBlock.color) + + def hoverLeaveEvent(self, event): + #self.setZValue(10) + #self.parentTransparentBlock.setZValue(9) + self.setPen(self.inactivePen) + self.parentTransparentBlock.setBrush(self.parentTransparentBlock.trans) + + +class CCInterpolatedPoint(QtWidgets.QGraphicsEllipseItem): + """This is practically read-only""" + def __init__(self): + super(CCInterpolatedPoint, self).__init__(0, 0,1,1) #x,y,w,h + self.setOpacity(0.6) + self.setBrush(QtCore.Qt.black) #fill + self.setEnabled(False) + self.setZValue(1) + +class CCUserPoint(QtWidgets.QGraphicsEllipseItem): + """the position is set by the parent""" + def __init__(self, parentCCPath, staticExportItem): + super(CCUserPoint, self).__init__(-3,-3,6,6) #x,y,w,h + #color = QtGui.QColor() + #color.setHsl(127-abs(value), 255, 127) #l(h, s, l) # 8bit values. Sets a HSL color value; h is the hue, s is the saturation, l is the lightness. l goes from black(0), over color(255/2) to white (255). #0 hue is green, 128 is red + #self.setBrush(color) #fill + self.setBrush(QtGui.QColor("cyan")) + self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable|QtWidgets.QGraphicsItem.ItemSendsGeometryChanges|QtWidgets.QGraphicsItem.ItemIsFocusable) + self.setAcceptHoverEvents(True) + self.setCursor(QtCore.Qt.SizeAllCursor) + self.parentCCPath = parentCCPath + self.staticExportItem = staticExportItem + self.interpolatedItemsRight = [] + self.interpolatedItemsLeft = [] + self.setZValue(9) + + def shape(self): + """Return a more accurate shape for this item so that + mouse hovering is more accurate""" + path = QtGui.QPainterPath() + path.addEllipse(QtCore.QRectF(-5, -5, 14, 14)) #this is directly related to inits parameter. -3, -3, 6, 6. + return path + + def mousePressEvent(self, event): + super().mousePressEvent(event) + self.lastPos = self.pos() + + if event.button() == 1: #QtCore.Qt.MouseButton.LeftButton + self.setCursor(QtCore.Qt.BlankCursor) + for i in self.interpolatedItemsLeft + self.interpolatedItemsRight: + i.hide() + + def mouseDoubleClickEvent(self, event): + self.changeCCValue() + + def hoverEnterEvent(self, event): + self.grabKeyboard() + #self.setFocus() #do NOT set the focus. GrabKeyboard is enough. The focus will stay even after hoverLeaveEvent so that Delete will delete the last hovered item. not good! + + def hoverLeaveEvent(self, event): + """reverse hoverEnterEvent""" + self.ungrabKeyboard() + + def keyPressEvent(self, event): + """Handle the delete item key. + Needs grabKeyboard, but NOT setFocus""" + key = event.key() + if key == 16777223: + self.delete() + else: + return super().keyPressEvent(event) + + def mouseReleaseEvent(self, event): + """After moving a point around + send an update to the backend""" + super(CCUserPoint, self).mouseReleaseEvent(event) + self.setCursor(QtCore.Qt.SizeAllCursor) + if event.button() == 1: #QtCore.Qt.MouseButton.LeftButton + api.changeGraphItem(self.staticExportItem["id"], self.getXDifferenceAsBackendValue(), self.getYAsBackendValue()) #send update to the backend, don't wait for callback. + + def mouseMoveEvent(self, event): + """Only active when the item is also selected and left + mouse button is down. Not any mouse event, no hover.""" + modifiers = QtWidgets.QApplication.keyboardModifiers() + super(CCUserPoint, self).mouseMoveEvent(event) + if modifiers == QtCore.Qt.ShiftModifier: + self.setY(self.lastPos.y()) + elif modifiers == QtCore.Qt.AltModifier: + self.setX(self.lastPos.x()) + + absoluteXPosition = self.x() * constantsAndConfigs.ticksToPixelRatio + withinBlock = self.staticExportItem["minPossibleAbsolutePosition"] <= absoluteXPosition <= self.staticExportItem["maxPossibleAbsolutePosition"] + if not withinBlock: + if absoluteXPosition < self.staticExportItem["minPossibleAbsolutePosition"]: + self.setX(self.staticExportItem["minPossibleAbsolutePosition"] / constantsAndConfigs.ticksToPixelRatio) + else: + self.setX(self.staticExportItem["maxPossibleAbsolutePosition"] / constantsAndConfigs.ticksToPixelRatio) + #Make mouse cursor movement not weird. + a = self.scene().parentView.mapFromScene(self.pos()) + b = self.scene().parentView.viewport().mapToGlobal(a) + QtGui.QCursor.setPos(b.x(), QtGui.QCursor.pos().y()) + + withinYRange = -28 <= self.y() <= 28 + if not withinYRange: + if self.y() < -28: + self.setY(-27.9) + else: + self.setY(28) + #Make mouse cursor movement not weird. + a = self.scene().parentView.mapFromScene(self.pos()) + b = self.scene().parentView.viewport().mapToGlobal(a) + QtGui.QCursor.setPos(QtGui.QCursor.pos().x(), b.y()) + + def delete(self): + """Instruct the backend to delete this item. Will trigger a + callback to redraw the graphTrack""" + api.removeGraphItem(self.staticExportItem["id"]) + + def contextMenuEvent(self, event): + menu = QtWidgets.QMenu() + + listOfLabelsAndFunctions = [ + ("interpolation Type", self.changeInterpolationType), + ("CC Value", self.changeCCValue), + ("delete", self.delete), #deletes the last hover item which is of course the current one. + ] + + for text, function in listOfLabelsAndFunctions: + if text == "separator": + self.addSeparator() + else: + a = QtWidgets.QAction(text, menu) + menu.addAction(a) + a.triggered.connect(function) + + pos = QtGui.QCursor.pos() + pos.setY(pos.y() + 5) + self.ungrabMouse() #if we don't ungrab and the user clicks the context menu "away" by clicking in an empty area this will still get registered as mouseclick belonging to the current item and change the value to some insane amount, breaking the point. + menu.exec_(pos) + + def changeInterpolationType(self): + graphTypeString = QtWidgets.QInputDialog.getItem(self.scene().parentView, "Interpolation Type", "choose Interpolation Type", api.getListOfGraphInterpolationTypesAsStrings(), 0, False) + if graphTypeString[1]: #[1] bool if canceled + api.changeGraphItemInterpolation(self.staticExportItem["id"], graphTypeString[0]) + + def changeCCValue(self): + ccValue = QtWidgets.QInputDialog.getInt(self.scene().parentView, "CC Value", "specify midi Continuous Control value", value=64, minValue=0, maxValue=127) + if ccValue[1]: #[1] bool if canceled + api.changeGraphItem(self.staticExportItem["id"], self.getXDifferenceAsBackendValue(), ccValue[0]) #send update to the backend, don't wait for callback. + + def getYAsBackendValue(self): + newCCValue = int(self.y() / 0.4375 - 64) #value goes from -0 to -127 and are compressed to fit between two lines in the staff. + newCCValue = abs(newCCValue) + assert 0 <= newCCValue < 128 + return newCCValue + + def getXDifferenceAsBackendValue(self): + """The problem is that we need the position relativ to its + parent block, which we don't use in that way in the GUI. + So we calculate the difference to the old position""" + + oldPositionAbsolute = int(self.staticExportItem["position"]) + newPositionAbsolute = self.pos().x() * constantsAndConfigs.ticksToPixelRatio + if constantsAndConfigs.snapToGrid: + newPositionAbsolute = round(newPositionAbsolute / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + diff = int(-1 * (oldPositionAbsolute - newPositionAbsolute)) + return diff diff --git a/qtgui/items.py b/qtgui/items.py new file mode 100644 index 0000000..870f8ad --- /dev/null +++ b/qtgui/items.py @@ -0,0 +1,920 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from PyQt5 import QtCore, QtGui, QtSvg, QtWidgets +from itertools import groupby +from engine.items import Chord, KeySignature +from .constantsAndConfigs import constantsAndConfigs +from template.qtgui.helper import stretchRect +import engine.api as api + +"""All svg items (execept pitch-related) graphics are expected to be +already on the correct position and will be inserter ON the middle line +That means g-clef needs to be 14 pxiels below the y=0 coordinate since +these are two stafflines. Or in other words: Open the graphic and +scale and reposition it until it fits correctly when inserted with +setPos(0,0)""" + +#Atomic items: + +oneRectToReturnThemAll = QtCore.QRectF(0,0,0,0) #prevent the annoying "NotImplementError" from Qt for boundingRect. For items that don't need any collision detection. + +class GuiTieCurveGraphicsItem(QtWidgets.QGraphicsPathItem): + pen = QtGui.QPen() + pen.setCapStyle(QtCore.Qt.RoundCap) + pen.setWidth(2) + + def __init__(self, noteExportObject): + """The origin of this item is the scene position. + We create a curve by drawing a straight line from zero + to end (the local item and the receiving tie item) and then + bend it down in the middle, leaving one of the control points + empty (0,0).""" + super().__init__() + self.setPen(GuiTieCurveGraphicsItem.pen) + if noteExportObject["dotOnLine"] < 0: #higher than the middle line + #self.translate(6, -5) + pass + else: + if noteExportObject["notehead"] <= 1: #whole notes have a bug in the gui because the backend stem info is misleading. Works fine except for ties. + pass #TODO + #self.translate(6, 0) + else: + pass #TODO + #self.translate(6, 6) + + self.noteExportObject = noteExportObject + self.draw() + + def draw(self): + lengthInPixel = self.noteExportObject["tieDistanceInTicks"] / constantsAndConfigs.ticksToPixelRatio + path = QtGui.QPainterPath() + path.cubicTo(0, 0, lengthInPixel/2, constantsAndConfigs.stafflineGap, lengthInPixel, 0) # ctrlPt1x, ctrlPt1y, ctrlPt2x, ctrlPt2y, endPtx, endPty + self.setPath(path) #set path edits the old one in place + + def stretchXCoordinates(self, factor): + """Called directly by the track by iterating through instances""" + self.draw() + + +class GuiPositionMarker(QtWidgets.QGraphicsRectItem): + def __init__(self, height, position = 1): + """A simple position marker that connects an annotation above a staff with the staff. + Height and position are calculated in stafflines/gaps""" + super().__init__(-2, position*constantsAndConfigs.stafflineGap, 1, height * constantsAndConfigs.stafflineGap) #x,y, w, h + self.setBrush(QtCore.Qt.black) + +class GuiTupletNumber(QtWidgets.QGraphicsItem): + """The baseline is the scene Position. + We position in the up direction""" + + pen = QtGui.QPen() + pen.setColor(QtGui.QColor("darkGrey")) + pen.setWidth(1) + + def paint(self, *args): + pass + def boundingRect(self, *args): + return oneRectToReturnThemAll + + def __init__(self, upper, lower): + super().__init__() + #self.upper = QtWidgets.QGraphicsSimpleTextItem(str(upper)) + #self.divider = QtWidgets.QGraphicsLineItem(0,0,10,0) + #self.divider.rotate(-70) + #self.divider.setPen(GuiTupletNumber.pen) + self.lower = QtWidgets.QGraphicsSimpleTextItem(str(lower)) + + #self.upper.setParentItem(self) + #self.divider.setParentItem(self) + self.lower.setParentItem(self) + + #self.upper.setPos(-1,-8) + #self.divider.setPos(5,5) + #self.lower.setPos(7,-5) + + self.lower.setPos(-1,-4) + self.setScale(0.75) + +class GuiItem(QtWidgets.QGraphicsItem): + """A blank item. Subclass to implement your own""" + def __init__(self, staticItem): + super().__init__() + self.staticItem = staticItem + dur = self.staticItem["completeDuration"] + exceptions = ["BlockEndMarker"] + #Deactivated after stretchX was reimplemented properly as recursive function and not a catch all on all items. I don't think that was used anywhere else. #self.rectangles = [] #Prevents typechecking. only implemented in GuiChord + + self.pixelPosition = self.staticItem["tickindex"] / constantsAndConfigs.ticksToPixelRatio + self.pixelWidth = self.staticItem["completeDuration"] / constantsAndConfigs.ticksToPixelRatio + + #if dur or self.staticItem["type"] in exceptions: + # self.pixelPosition = self.staticItem["tickindex"] / constantsAndConfigs.ticksToPixelRatio + # self.pixelWidth = self.staticItem["completeDuration"] / constantsAndConfigs.ticksToPixelRatio + #else: + # self.pixelPosition = self.staticItem["tickindex"] / constantsAndConfigs.ticksToPixelRatio + constantsAndConfigs.negativeMagicPixel*6 #an offset to the left. this will still get in the way for short notes, but for now it is better than colliding 100% when placed on the note. #TODO: place above the track + # self.pixelWidth = 25 #Does not need to be the actual size because this is ONLY important when the item gets inserted at the appending position and the cursor needs to jump "over" the current item, because there is no next one. This is the direct response to the cursor method that sets the appending position as items tickposition+pixelwidth. + + def updateVisibility(self): + """Prevent against typechecking. This method is only implemented + in GuiChord""" + pass + + def paint(self, *args): + pass + def boundingRect(self, *args): + return oneRectToReturnThemAll + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + pass + +class GuiRectangleNotehead(QtWidgets.QGraphicsRectItem): + """Displays the pitch and actual duration of one note when in rectangle view mode""" + + def __init__(self, parent, noteExportObject): + #Dimensions and Position + x = noteExportObject["leftModInTicks"] / constantsAndConfigs.ticksToPixelRatio + y = -1 * constantsAndConfigs.stafflineGap / 2 + 1 + w = (noteExportObject["rightModInTicks"] + noteExportObject["completeDuration"] - noteExportObject["leftModInTicks"]) / constantsAndConfigs.ticksToPixelRatio + h = constantsAndConfigs.stafflineGap #- 2 #2 pixel to make room for the pen-width. + super().__init__(x, y, w, h) + self.setPos(0, constantsAndConfigs.stafflineGap * noteExportObject["dotOnLine"] / 2) + self.setParentItem(parent) + + #Prepare self.shape() + #NOTE: this was from a time when mouse modification was possible. Leave for later use. + #self.path = QtGui.QPainterPath() + #self.pathRect = QtCore.QRectF(x, y-1, w, h+4) #this is directly related to inits parameter x, y, w, h + #self.path.addRect(self.pathRect) + #self.setCursor(QtCore.Qt.SizeHorCursor) + + #Different color when the duration was modified by the user + inactive = "green" if noteExportObject["manualOverride"] else "black" + self.inactiveColor = QtGui.QColor(inactive) + self.setBrush(self.inactiveColor) + + #Pen for the borders + pen = QtGui.QPen() + pen.setWidth(0) + pen.setColor(QtGui.QColor("darkGrey")) + self.setPen(pen) + + #Since accidentals are part of the notehead we need one here. It doesn't matter if the traditional notehead already has one + if noteExportObject["accidental"]: #0 means no difference to keysig + self.accidental = GuiNote.createAccidentalGraphicsItem(self, noteExportObject["accidental"]) + self.accidental.setPos(0, 0) #not analogue to the notehead acciental position because here we choose the rectangle as parent + self.accidental.setParentItem(self) + + #NOTE: this was from a time when mouse modification was possible. Leave for later use. + #def shape(self): + # """Qt Function + # Return a more accurate shape for this item so that + # mouse hovering is more accurate. + # + # Must be within the bounding rect.""" + # return self.path + + #def boundingRect(self, *args): + # """Keep in syn with self.shape()""" + # return self.pathRect + + #def paint(self, *args): + #Do NOT implement this. This actually works already. The parent item needs this. + + +class GuiRectangleVelocity(QtWidgets.QGraphicsRectItem): + """Displays the velocity of one note when in rectangle view mode. + + The Y-position is fixed on the staff and not bound to the rectangle notehead. + This makes it possible for the user to compare velocities visually. + + """ + def __init__(self, parent, noteExportObject): + #Dimensions and Position + x = noteExportObject["leftModInTicks"] / constantsAndConfigs.ticksToPixelRatio #same as GuiRectangleNotehead + y = -1 * (noteExportObject["velocity"] / constantsAndConfigs.velocityToPixelRatio) + w = (noteExportObject["rightModInTicks"] + noteExportObject["completeDuration"] - noteExportObject["leftModInTicks"]) / constantsAndConfigs.ticksToPixelRatio #same as GuiRectangleNotehead + h = noteExportObject["velocity"] / constantsAndConfigs.velocityToPixelRatio #velocityToPixelRation has its own compress factor since values can go from 0 to 127 + super().__init__(x, y, w, h) + self.setPos(0, 2*constantsAndConfigs.stafflineGap) #The position is fixed to the staff, not to the GuiRectangleNotehead. + self.setParentItem(parent) + + #Prepare self.shape() + #NOTE: this was from a time when mouse modification was possible. Leave for later use. + #self.path = QtGui.QPainterPath() + #self.pathRect = QtCore.QRectF(x, y-1, w, h+4) #this is directly related to inits parameter x, y, w, h + #self.path.addRect(self.pathRect) + #self.setCursor(QtCore.Qt.SizeHorCursor) + + #Colors and Apperance + inactive = "green" if noteExportObject["velocityManualOverride"] else "lightGray" + self.inactiveVelocityColor = QtGui.QColor(inactive) + self.activeVelocityColor = QtGui.QColor("darkCyan") + self.setBrush(self.inactiveVelocityColor) + self.setOpacity(0.3) + + #Pen for the borders + #The pen interferes with the precise appearance we want for live notes + pen = QtGui.QPen() + pen.setCapStyle(QtCore.Qt.RoundCap) + pen.setJoinStyle(QtCore.Qt.RoundJoin) + pen.setWidth(2) + pen.setColor(QtGui.QColor("black")) + self.setPen(pen) + + #Attach a label that displays the velocity as midi value 0-127 + #label = QtWidgets.QGraphicsSimpleTextItem(str(noteExportObject["velocity"])) + #label.setPos(3, -3) + #label.setParentItem(parent) + + #Misc Qt Flags + self.setAcceptHoverEvents(False) #Make this explicit so it will be remembered that the gui rectangle velocity is a display only. + + #NOTE: this was from a time when mouse modification was possible. Leave for later use. + #def shape(self): + # """Qt Function + # Return a more accurate shape for this item so that + # mouse hovering is more accurate. + # + # Must be within the bounding rect.""" + # return self.path + + #def boundingRect(self, *args): + # """Keep in syn with self.shape()""" + # return self.pathRect + + #def paint(self, *args): + #Do NOT implement this. This actually works already. The parent item needs this. + +class GuiRectangle(QtWidgets.QGraphicsItem): + """An alternative notehead, used to change velocity and duration + finetuning. + + This is a GraphicsItem with two main components: + The notehead which displays the duration and pitch of the note + The Velocity which displays only the velocity. + Both components share their Y position in the staff so they are one item. + + The notehead rectangles have full opacity and can't layer. + The velocity rectangles layer and only a grahpical highlight shows the active one. + """ + + def __init__(self, noteExportObject): + super().__init__() + self.notehead = GuiRectangleNotehead(parent = self, noteExportObject = noteExportObject) + self.velocity = GuiRectangleVelocity(parent = self, noteExportObject = noteExportObject) + self.notehead.setZValue(10) #within GuiRectangle + + def boundingRect(self, *args): + return oneRectToReturnThemAll + def paint(self, *args): + pass + +class GuiNote(QtWidgets.QGraphicsItem): + def __init__(self, noteExportObject, directionRightAndUpwards): + super(GuiNote, self).__init__() + self.createNote(noteExportObject, directionRightAndUpwards) + + def paint(self, *args): + pass + def boundingRect(self, *args): + return oneRectToReturnThemAll + + def createNote(self, noteExportObject, directionRightAndUpwards): + #note head + self.noteExportObject = noteExportObject + #self.noteHead = GuiNote.noteheads[noteExportObject["notehead"]]() + self.noteHead = self.createNoteheadGraphicsItem(noteExportObject["notehead"]) + self.noteHead.setPos(0, constantsAndConfigs.stafflineGap * noteExportObject["dotOnLine"] / 2) + self.noteHead.setParentItem(self) + #Ledger lines need to be done in the chord to not be redundant and work for multiple notes. + if noteExportObject["accidental"]: #0 means no difference to keysig + self.accidental = self.createAccidentalGraphicsItem(noteExportObject["accidental"]) + self.accidental.setPos(0, constantsAndConfigs.stafflineGap * noteExportObject["dotOnLine"] / 2) + self.accidental.setParentItem(self) + + for dot in range(noteExportObject["dots"]): + d = QtSvg.QGraphicsSvgItem(":svg/dot.svg") + d.setPos((dot+1)*4+6, constantsAndConfigs.stafflineGap * noteExportObject["dotOnLine"] / 2) + d.setParentItem(self) + + for i, (upper, lower) in enumerate(noteExportObject["tuplets"]): + tuplet = GuiTupletNumber(upper, lower) + + if directionRightAndUpwards: + tuplet.setPos(3, -6*(i+1)) + else: + tuplet.setPos(3, 6*(i+1)) + + tuplet.setParentItem(self.noteHead) + + if noteExportObject["durationKeyword"]: + self.durationKeywordGlyph = GuiNote.durationKeywords[noteExportObject["durationKeyword"]](noteExportObject) + if directionRightAndUpwards: + self.durationKeywordGlyph.setPos(3, 6) + else: + self.durationKeywordGlyph.setPos(3, -6) + + self.durationKeywordGlyph.setParentItem(self.noteHead) + + + def createNoteheadGraphicsItem(self, number): + item = QtSvg.QGraphicsSvgItem() + item.setSharedRenderer(GuiNote.noteheads[number]) + return item + + def createAccidentalGraphicsItem(self, number): + item = QtSvg.QGraphicsSvgItem() + item.setSharedRenderer(GuiNote.accidentals[number]) + return item + + durationKeywords = { #0 is default and has no markers. + api.D_STACCATO : lambda noteExportObject: QtSvg.QGraphicsSvgItem(":svg/scriptsStaccato.svg"), + api.D_TENUTO : lambda noteExportObject: QtWidgets.QGraphicsSimpleTextItem("-"), #TODO: tenuto glyph + api.D_TIE : lambda noteExportObject: GuiTieCurveGraphicsItem(noteExportObject), + } + + noteheads = { + 4 : QtSvg.QSvgRenderer(":svg/noteheadsBlack.svg"), #and 8, 16, 32, ... + 2 : QtSvg.QSvgRenderer(":svg/noteheadsHalf.svg"), + 1 : QtSvg.QSvgRenderer(":svg/noteheadsWhole.svg"), + 0 : QtSvg.QSvgRenderer(":svg/noteheadsBrevis.svg"), + -1 : QtSvg.QSvgRenderer(":svg/noteheadsLonga.svg"), + -2 : QtSvg.QSvgRenderer(":svg/noteheadsMaxima.svg"), + } + + #Accidental .svg are shifted to the left a bit already so we can place them on the same x-coordinates as the notes. + accidentals = { + 1 : QtSvg.QSvgRenderer(":svg/accidentalsNatural.svg"), + 10 : QtSvg.QSvgRenderer(":svg/accidentalsSharp.svg"), + 20 : QtSvg.QSvgRenderer(":svg/accidentalsDoublesharp.svg"), + -10 : QtSvg.QSvgRenderer(":svg/accidentalsFlat.svg"), + -20 : QtSvg.QSvgRenderer(":svg/accidentalsFlatFlat.svg"), + } + + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + try: + self.durationKeywordGlyph.stretchXCoordinates(factor) + except AttributeError: #does not have any attachements or the attachment does not have the stretch function (e.g. staccato) + pass + +#Top level items, all based on GuiItem. + +class GuiChord(GuiItem): + """staticItem is a chord Dict which has another list of dicts: + staticItem["notelist"]. + Each note with its notehead, accidental etc is in there. + This means that a chord can consist of multiple durations as well + as pitches, of course. + + For spacing calculations the chord itself gives us a duration as + well.""" + + def __init__(self, staticItem,): + super().__init__(staticItem) + self.staticItem = staticItem + self.rectangles = [] + self.notes = [] + self.stem = None #stored for rectangle/head switching + self.flag = None #stored for rectangle/head switching + self.beamGroupGlyph = None #stored for rectangle/head switching + #The actual beams are in the track + + self.createRectanglesFromData() + self.createNotesFromData() + self.createGenericFromData() + self.updateVisibility() + + + ledgerPen = QtGui.QPen(QtCore.Qt.SolidLine) + ledgerPen.setCapStyle(QtCore.Qt.RoundCap) + ledgerPen.setWidth(1) + + stemPen = QtGui.QPen(QtCore.Qt.SolidLine) + stemPen.setCapStyle(QtCore.Qt.RoundCap) + stemPen.setWidth(1.5) + + flags = { #QGraphicsItems can only be used once so we have to save a class constructor here instead of an instance. + 1024 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag1024.svg"), #TODO + 512 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag512.svg"), #TODO + 256 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag256.svg"), + 128 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag128.svg"), + 64 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag64.svg"), + 32 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag32.svg"), + 16 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag16.svg"), + 8 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag8.svg"), + -1024 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag1024i.svg"), #TODO + -512 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag512i.svg"), #TODO + -256 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag256i.svg"), + -128 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag128i.svg"), + -64 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag64i.svg"), + -32 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag32i.svg"), + -16 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag16i.svg"), + -8 : lambda: QtSvg.QGraphicsSvgItem(":svg/flag8i.svg"), + } + + + def createGenericFromData(self): + """Graphics for both rectangles and noteheads""" + + #Ledger Lines + below, above = self.staticItem["ledgerLines"] + + for i in range(below): + line = QtWidgets.QGraphicsLineItem(QtCore.QLineF(0, 0, 12, 0)) + line.setPen(GuiChord.ledgerPen) + line.setParentItem(self) + line.setPos(constantsAndConfigs.negativeMagicPixel, i * constantsAndConfigs.stafflineGap + constantsAndConfigs.stafflineGap*3) + + for i in range(above): + line = QtWidgets.QGraphicsLineItem(QtCore.QLineF(0, 0, 12, 0)) + line.setPen(GuiChord.ledgerPen) + line.setParentItem(self) + line.setPos(constantsAndConfigs.negativeMagicPixel, -1 * i * constantsAndConfigs.stafflineGap - constantsAndConfigs.stafflineGap*3) + + #Display relative channel changes + if not self.staticItem["midiChannelOffset"] == 0: + channelGlyph = QtWidgets.QGraphicsSimpleTextItem("ch{0:+}".format(self.staticItem["midiChannelOffset"])) + channelGlyph.setScale(0.75) + channelGlyph.setParentItem(self) + channelGlyph.setPos(0, -5*constantsAndConfigs.stafflineGap) + + def createRectanglesFromData(self): + """Graphics only for rectangles""" + for noteExportObject in self.staticItem["notelist"]: + if not noteExportObject["tie"] == "notFirst": + #Tied notes, except the first, do not produce rectangles because the first note gets an extra large rectangle. + rectangle = GuiRectangle(noteExportObject) + self.rectangles.append(rectangle) + rectangle.setParentItem(self) + + def createNotesFromData(self): + """Graphics only for noteheads""" + if self.staticItem["beam"]: + stemOrBeam = self.staticItem["beam"] + else: + stemOrBeam = self.staticItem["stem"] + + if stemOrBeam and stemOrBeam[2] > 0: + self.directionRightAndUpwards = False + else: + self.directionRightAndUpwards = True + + #Stem - Both for groups and standalone. + if stemOrBeam: #may be an empty tuple for whole notes and brevis + line = QtWidgets.QGraphicsLineItem(QtCore.QLineF(0, constantsAndConfigs.stafflineGap * stemOrBeam[1]/2, 0, 0)) #x1, y1, x2, y2 + line.setPen(GuiChord.stemPen) + self.stem = line #store as persistent item. Otherwise qt will delete it. + line.setParentItem(self) + line.setPos(constantsAndConfigs.magicPixel + stemOrBeam[2]*3, constantsAndConfigs.stafflineGap * stemOrBeam[0] / 2) #stem[2] is left/-1 or right/1 shifting. #4 is the middle + + #Flags + if not self.staticItem["beam"] and self.staticItem["flag"]: + assert self.stem + flag = GuiChord.flags[self.staticItem["flag"]]() #the graphic. + flag.setParentItem(self) + self.flag = flag #store as persistent item. Otherwise qt will delete it. + flag.setPos(self.stem.pos().x(), self.stem.line().p1().y() + self.stem.pos().y()) #we already know where the stem-line is. + + #Check if this item is the start or end of a beam group and mark it with lilypond syntax + if self.staticItem["beamGroup"]: + if self.staticItem["beamGroup"] == "open": + beamGroupGlyph = QtWidgets.QGraphicsSimpleTextItem("[") + beamGroupGlyph.setParentItem(self) + beamGroupGlyph.setPos(0, -5*constantsAndConfigs.stafflineGap) + elif self.staticItem["beamGroup"] == "close": + beamGroupGlyph = QtWidgets.QGraphicsSimpleTextItem("]") + beamGroupGlyph.setParentItem(self) + beamGroupGlyph.setPos(constantsAndConfigs.magicPixel, -5*constantsAndConfigs.stafflineGap) + self.beamGroupGlyph = beamGroupGlyph + + #Actual Noteheads + lastDotOnLine = float("inf") + for noteExportObject in self.staticItem["notelist"]: + #notes in a chord come in the order highest to lowest + #determine if we have two neighbouring noteheads. If yes we shift one of the heads to the right + assert lastDotOnLine > noteExportObject["dotOnLine"] + if lastDotOnLine - noteExportObject["dotOnLine"] == 1: + moveThisNoteheadToTheRight = True + lastDotOnLine = noteExportObject["dotOnLine"] + lastDotOnLine += 1 #we shift the current notehead. The next pair would be no problem, even if neighbours. + else: + moveThisNoteheadToTheRight = False + lastDotOnLine = noteExportObject["dotOnLine"] + + note = GuiNote(noteExportObject, self.directionRightAndUpwards) + self.notes.append(note) #we need them later for switching between rectangles and noteheads + note.setParentItem(self) + if moveThisNoteheadToTheRight: + note.setX(note.pos().x() + 6) #6 pixels. + + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + for rectNote in self.rectangles: + stretchRect(rectNote.notehead, factor) + stretchRect(rectNote.velocity, factor) + for note in self.notes: #this is for ties only at the moment, the rest does not stretch + note.stretchXCoordinates(factor) + + def updateVisibility(self): + """decide during creation what part is visible at the moment. aka. are we in notehead + or rectangle mode. + Beams visibility is done in the track function createBeams""" + + if constantsAndConfigs.noteHeadMode: + for r in self.rectangles: + r.hide() + for n in self.notes: + n.show() + if self.flag: + self.flag.show() + if self.stem: + self.stem.show() + if self.beamGroupGlyph: + #This is about the start and end marker [ ] .The beam itself is in the track + self.beamGroupGlyph.show() + else: #rectangle mode. + for r in self.rectangles: + r.show() + for n in self.notes: + n.hide() + if self.flag: + self.flag.hide() + if self.stem: + self.stem.hide() + if self.beamGroupGlyph: + #This is about the start and end marker [ ] .The beam itself is in the track + self.beamGroupGlyph.hide() + +class GuiLiveNote(QtWidgets.QGraphicsRectItem): + """A pure rectangle note, meant for live recording.""" + #TODO: Velocity indicator? + + instances = [] + + def __init__(self, parent, liveNoteData): + self.__class__.instances.append(self) + self.liveNoteData = liveNoteData + #Dimensions and Position + x = 0 #A live note is always literally where it sounds + y = -1 * constantsAndConfigs.stafflineGap / 2 + w = liveNoteData["duration"] / constantsAndConfigs.ticksToPixelRatio + h = constantsAndConfigs.stafflineGap + super().__init__(x, y, w, h) + self.setY(constantsAndConfigs.stafflineGap * liveNoteData["dotOnLine"] / 2) + self.setParentItem(parent) + + self.setBrush(QtGui.QColor("red")) + + #Pen for the borders + pen = QtGui.QPen() + pen.setWidth(0) + self.setPen(pen) + + if liveNoteData["accidental"]: #0 means no difference to keysig + self.accidental = GuiNote.createAccidentalGraphicsItem(self, liveNoteData["accidental"]) + self.accidental.setPos(0, 0) #not analogue to the notehead acciental position because here we choose the rectangle as parent + self.accidental.setParentItem(self) + + def update(self, duration): + r = self.rect() + r.setRight(duration / constantsAndConfigs.ticksToPixelRatio) + self.setRect(r) + +class GuiRest(GuiItem): + def __init__(self, staticItem): + super(GuiRest, self).__init__(staticItem) + self.createGraphicItemsFromData() + + rests = { #QGraphicsItems can only be used once so we have to save a class constructor here instead of an instance. + -1 : lambda: QtSvg.QGraphicsSvgItem(":svg/restLonga.svg"), + -2 : lambda: QtSvg.QGraphicsSvgItem(":svg/restMaxima.svg"), + 0 : lambda: QtSvg.QGraphicsSvgItem(":svg/restBrevis.svg"), + 1 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest1.svg"), + 2 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest2.svg"), + 4 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest4.svg"), + 8 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest8.svg"), + 16 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest16.svg"), + 32 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest32.svg"), + 64 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest64.svg"), + 128 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest128.svg"), + 256 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest256.svg"), #TODO + 512 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest512.svg"), #TODO + 1024 : lambda: QtSvg.QGraphicsSvgItem(":svg/rest1024.svg"), #TODO + } + + def createGraphicItemsFromData(self): + self.glyph = GuiRest.rests[self.staticItem["rest"]]() + self.glyph.setParentItem(self) + + for dot in range(self.staticItem["dots"]): + d = QtSvg.QGraphicsSvgItem(":svg/dot.svg") + d.setPos((dot+1)*4+6, -2) + d.setParentItem(self) + + for i, (upper, lower) in enumerate(self.staticItem["tuplets"]): + tuplet = GuiTupletNumber(upper, lower) + tuplet.setParentItem(self) + tuplet.setPos(2, (i+1)*-4-constantsAndConfigs.stafflineGap*2) + +class GuiKeySignature(GuiItem): + def __init__(self, staticItem): + super(GuiKeySignature, self).__init__(staticItem) + self.createGraphicItemsFromData() + + def createGraphicItemsFromData(self): + """staticItems accidentalsOnLines is ordered. We receive the + correct accidental order from left to right and only need + to place the gaps""" + for i, (accidentalOnLine, pitchMod) in enumerate(self.staticItem["accidentalsOnLines"]): + glyph = GuiKeySignature.accidentals[pitchMod]() + glyph.setParentItem(self) + glyph.setPos(constantsAndConfigs.magicPixel + i*1.5*constantsAndConfigs.magicPixel, constantsAndConfigs.stafflineGap * accidentalOnLine / 2) #These accidental graphics are shifted to the left in the .svg so they can be placed just as noteheads and match automatically. So we set them +x here. + + if not self.staticItem["accidentalsOnLines"]: + #No accidentals in the keysig (C-Major, D-Dorian etc.) gets a big natural sign. + self.bigNatural = GuiKeySignature.accidentals[0]() #"big natural"... hö hö hö hö + self.bigNatural.setParentItem(self) + self.bigNatural.setPos(constantsAndConfigs.magicPixel, constantsAndConfigs.stafflineGap * -1) + + self.rootGlyph = QtWidgets.QGraphicsSimpleTextItem(constantsAndConfigs.baseNotes[self.staticItem["root"]]) + self.rootGlyph.setParentItem(self) + self.rootGlyph.setPos(constantsAndConfigs.negativeMagicPixel, 2*constantsAndConfigs.stafflineGap) + + + accidentals = { #QGraphicsItems can only be used once so we have to save a class constructor here instead of an instance. + 0 : lambda: QtSvg.QGraphicsSvgItem(":svg/accidentalsNatural.svg"), #normaly we don't receive those, but it is possible to ask for explicit naturals in the backend and in lilypond. + 10 : lambda: QtSvg.QGraphicsSvgItem(":svg/accidentalsSharp.svg"), + 20 : lambda: QtSvg.QGraphicsSvgItem(":svg/accidentalsDoublesharp.svg"), + -10 : lambda: QtSvg.QGraphicsSvgItem(":svg/accidentalsFlat.svg"), + -20 : lambda: QtSvg.QGraphicsSvgItem(":svg/accidentalsFlatFlat.svg"), + } + +class GuiClef(GuiItem): + def __init__(self, staticItem): + super(GuiClef, self).__init__(staticItem) + self.createGraphicItemsFromData() + + def createGraphicItemsFromData(self): + self.glyph = GuiClef.clefs[self.staticItem["clef"]]() + self.glyph.setParentItem(self) + self.glyph.setPos(-5, -5 * constantsAndConfigs.stafflineGap) + + #self.text = QtWidgets.QGraphicsSimpleTextItem(self.staticItem["clef"].title()) + #self.text.setParentItem(self) + #self.text.setPos(0, -5 * constantsAndConfigs.stafflineGap) + + self.marker = GuiPositionMarker(-5) + self.marker.setParentItem(self) + self.marker.setPos(0,0) + + clefs = { #QGraphicsItems can only be used once so we have to save a class constructor here instead of an instance. + "treble" : lambda: QtSvg.QGraphicsSvgItem(":svg/clefTreble.svg"), + "treble_8" : lambda: QtSvg.QGraphicsSvgItem(":svg/clefTreble_8.svg"), + "treble^8" : lambda: QtSvg.QGraphicsSvgItem(":svg/clefTreble^8.svg"), + "bass" : lambda: QtSvg.QGraphicsSvgItem(":svg/clefBass.svg"), + "bass_8" : lambda: QtSvg.QGraphicsSvgItem(":svg/clefBass_8.svg"), + "alto" : lambda: QtSvg.QGraphicsSvgItem(":svg/clefAlto.svg"), + "midiDrum" : lambda: QtSvg.QGraphicsSvgItem(":svg/clefPercussion.svg"), + "percussion" : lambda: QtSvg.QGraphicsSvgItem(":svg/clefPercussion.svg"), + } + +class GuiTimeSignature(GuiItem): + def __init__(self, staticItem): + raise Exception("Don't use this item. It will be deleted in future versions. Use a Metrical Instruction") + super().__init__(staticItem) + self.setPos(0, constantsAndConfigs.stafflineGap) + self.createGraphicItemsFromData() + + def createGraphicItemsFromData(self): + #higher number, how many notes + for i, charInt in enumerate(str(self.staticItem["nominator"])): + n = GuiTimeSignature.digits[int(charInt)] + charInt = QtSvg.QGraphicsSvgItem() + charInt.setSharedRenderer(GuiTimeSignature.renderer) + charInt.setElementId(n) + charInt.setPos(i*2*constantsAndConfigs.magicPixel, -1*constantsAndConfigs.stafflineGap) + charInt.setParentItem(self) + + #lower number, which note type + for i, charInt in enumerate(str(self.staticItem["denominator"])): #2^n + n = GuiTimeSignature.digits[int(charInt)] + charInt = QtSvg.QGraphicsSvgItem() + charInt.setSharedRenderer(GuiTimeSignature.renderer) + charInt.setElementId(n) + charInt.setPos(i*2*constantsAndConfigs.magicPixel, constantsAndConfigs.stafflineGap) + charInt.setParentItem(self) + + renderer = QtSvg.QSvgRenderer(":svg/numbers.svg") + digits = "zero one two three four five six seven eight nine".split() #a list + + +class GuiMetricalInstruction(GuiItem): + def __init__(self, staticItem): + super().__init__(staticItem) + + if staticItem["oneMeasureInTicks"] == 0: + #Basically just a manual barline + displayString = "Metrical Off" + markerPosition = -2 + markerHeight = 4 + + else: + #Format the Tree of Instructions + realTree = eval(staticItem["treeOfInstructions"]) + if not type(realTree[0]) is tuple: #first order measure. like 3/4 or 2/4 or anything with just one stressed position + realTree = (realTree, ) #created nested iterator + r = self.treeToPrettyString(realTree) + r = r.__repr__()[1:-1].replace("'", "") + onlyTopLevelElements = not any(isinstance(el, list) for el in r) + if onlyTopLevelElements: + r = r.replace(",", "") + + displayString = "Metrical " + r + markerHeight = -7 + markerPosition = 1 + + self.text = QtWidgets.QGraphicsSimpleTextItem(displayString) + self.text.setParentItem(self) + self.text.setPos(0, -7 * constantsAndConfigs.stafflineGap) + + self.marker = GuiPositionMarker(markerHeight, markerPosition) + self.marker.setParentItem(self) + self.marker.setPos(0,0) + + def treeToPrettyString(self, tree): + """Convert a metrical instruction into a pretty string with note symbols + For example + ((53760, 53760), (53760, 53760)) + which is ((D4, D4), (D4, D4)) + + into + 2𝅘𝅥 2𝅘𝅥 + + """ + result = [] + + for element in tree: + if type(element) is tuple: + l = self.treeToPrettyString(element) + l = ["{}{}".format(sum(1 for e in grouper), note) for note, grouper in groupby(l)] + if len(l) == 1: + l = l[0] #makes formatting clearerm + result.append(l) + else: + assert type(element) is int + noteString = constantsAndConfigs.realNoteDisplay[element] + result.append(noteString) + return result + + +class GuiBlockEndMarker(GuiItem): + def __init__(self, staticItem): + super(GuiBlockEndMarker, self).__init__(staticItem) + self.glyph = QtSvg.QGraphicsSvgItem(":svg/blockEnd.svg") + self.createGraphicItemsFromData() + + def createGraphicItemsFromData(self): + self.glyph.setParentItem(self) + +class GuiDynamicSignature(GuiItem): + def __init__(self, staticItem): + super(GuiDynamicSignature, self).__init__(staticItem) + self.glyph = QtWidgets.QGraphicsSimpleTextItem(staticItem["keyword"]) + self.createGraphicItemsFromData() + + def createGraphicItemsFromData(self): + self.glyph.setPos(0, 5*constantsAndConfigs.stafflineGap) + self.glyph.setParentItem(self) + +class GuiMultiMeasureRest(GuiItem): + def __init__(self, staticItem): + super(GuiMultiMeasureRest, self).__init__(staticItem) + self.createGraphicItemsFromData() + + def createGraphicItemsFromData(self): + w = self.staticItem["completeDuration"] / constantsAndConfigs.ticksToPixelRatio - constantsAndConfigs.magicPixel*2 + + if int(self.staticItem["numberOfMeasures"]) == self.staticItem["numberOfMeasures"]: #just an int? + numberOfMeasuresString = str(int(self.staticItem["numberOfMeasures"])) + else: + numberOfMeasuresString = str(self.staticItem["numberOfMeasures"]) #include the decimal dot + + rect = QtWidgets.QGraphicsRectItem(constantsAndConfigs.magicPixel,0, w, constantsAndConfigs.stafflineGap) #x,y, w, h + rect.setBrush(QtCore.Qt.black) + rect.setParentItem(self) + self.rect = rect #for stretching + + leftBlock = QtWidgets.QGraphicsRectItem(2, -1* constantsAndConfigs.stafflineGap, constantsAndConfigs.magicPixel, 3*constantsAndConfigs.stafflineGap) + leftBlock.setBrush(QtCore.Qt.black) + leftBlock.setParentItem(self) + + rightBlock = QtWidgets.QGraphicsRectItem(0, -1* constantsAndConfigs.stafflineGap, constantsAndConfigs.magicPixel, 3*constantsAndConfigs.stafflineGap) #x, y, w, h + rightBlock.setBrush(QtCore.Qt.black) + #rightBlock.setPos(w,0) + rightBlock.setPos(rect.rect().right(),0) + rightBlock.setParentItem(self) + self.rightBlock = rightBlock #for stretching + + for i, char in enumerate(numberOfMeasuresString): + if char == ".": + continue #TODO: Maybe warn about that? MMR below 1 are not valid but they are needed for editing purposes. Sometimes you need to go through such a value. + else: + n = GuiTimeSignature.digits[int(char)] + char = QtSvg.QGraphicsSvgItem() + char.setSharedRenderer(GuiTimeSignature.renderer) + char.setElementId(n) + #char.setPos(i*4*constantsAndConfigs.magicPixel + 4* constantsAndConfigs.magicPixel, -3*constantsAndConfigs.stafflineGap) + char.setPos(leftBlock.rect().width(), -3*constantsAndConfigs.stafflineGap) + char.setScale(1.5) + char.setParentItem(self) + + self.setPos(0, -3 * constantsAndConfigs.stafflineGap) + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + stretchRect(self.rect, factor) + self.rightBlock.setX(self.rightBlock.pos().x() * factor) + #self.char.setX(self.char.pos().x() * factor) + +class GuiLegatoSlur(GuiItem): + def __init__(self, staticItem): + super().__init__(staticItem) + if staticItem["slur"] == "open": + self.glyph = QtWidgets.QGraphicsSimpleTextItem("(") + self.glyph.setPos(2,-5*constantsAndConfigs.stafflineGap) + else: + assert staticItem["slur"] == "close" + self.glyph = QtWidgets.QGraphicsSimpleTextItem(")") + self.glyph.setPos(-4,-5*constantsAndConfigs.stafflineGap) + + self.createGraphicItemsFromData() + + def createGraphicItemsFromData(self): + #self.glyph.setPos(0, -5*constantsAndConfigs.stafflineGap) + self.glyph.setParentItem(self) + +class GuiGenericText(GuiItem): + def __init__(self, staticItem): + super().__init__(staticItem) + self.glyph = QtWidgets.QGraphicsSimpleTextItem(staticItem["UIstring"]) + self.glyph.setPos(0, -5*constantsAndConfigs.stafflineGap) + self.glyph.setParentItem(self) + +def staticItem2Item(staticItem): + typ = staticItem["type"] + if typ is "Chord": + return GuiChord(staticItem) + elif typ is "Rest": + return GuiRest(staticItem) + elif typ is "LegatoSlur": + return GuiLegatoSlur(staticItem) + elif typ is "MultiMeasureRest": + return GuiMultiMeasureRest(staticItem) + elif typ is "DynamicSignature": + return GuiDynamicSignature(staticItem) + elif typ is "Clef": + return GuiClef(staticItem) + elif typ is "KeySignature": + return GuiKeySignature(staticItem) + #elif typ is "TimeSignature": + # return GuiTimeSignature(staticItem) + + elif typ is "MetricalInstruction": + return GuiMetricalInstruction(staticItem) + elif typ is "BlockEndMarker": + return GuiBlockEndMarker(staticItem) + elif typ in ("InstrumentChange", "ChannelChange",): + return GuiGenericText(staticItem) + else: + raise ValueError("Unknown Item Type:", staticItem) diff --git a/qtgui/mainwindow.py b/qtgui/mainwindow.py new file mode 100644 index 0000000..7102bb2 --- /dev/null +++ b/qtgui/mainwindow.py @@ -0,0 +1,200 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2018, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), +more specifically its template base application. + +The Template Base Application 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 . +""" +import logging; logging.info("import {}".format(__file__)) + +#Standard Library Modules +import os.path + +#Third Party Modules +from PyQt5 import QtWidgets, QtCore, QtGui + +#Template Modules +from template.qtgui.mainwindow import MainWindow as TemplateMainWindow +from template.qtgui.menu import Menu +from template.qtgui.about import About + +#Our modules +import engine.api as api +from midiinput.stepmidiinput import stepMidiInput #singleton instance +from .constantsAndConfigs import constantsAndConfigs +from .menu import MenuActionDatabase +from .scoreview import ScoreView +from .structures import GuiScore +from .trackEditor import TrackEditor +from .resources import * + +class MainWindow(TemplateMainWindow): + + def __init__(self): + """The order of calls is very important. + The split ploint is calling the super.__init. Some functions need to be called before, + some after. + For example: + + The about dialog is created in the template main window init. So we need to set additional + help texts before that init. + """ + + #Inject more help texts in the templates About "Did You Know" field. + #About.didYouKnow is a class variable. + #Make the first three words matter! + #Do not start them all with "You can..." or "...that you can", in response to the Did you know? title. + #We use injection into the class and not a parameter because this dialog gets shown by creating an object. We can't give the parameters when this is shown via the mainWindow menu. + About.didYouKnow = [ + QtCore.QCoreApplication.translate("About", "This is an example application. Extend it to your liking. Start by editing config.py") + ] + About.didYouKnow + + super().__init__() + + #New menu entries and template-menu overrides + self.menu.addMenuEntry("menuDebug", "actionRedrawAllTracks", "Redraw all Tracks") + self.menu.connectMenuEntry("actionSave", api.save) + self.menu.hideSubmenu("menuFile") + self.menu.hideSubmenu("menuGeneric") + + + api.callbacks.setCursor.append(self.updateStatusBar) #returns a dict. This get's called after loading the file so the status bar is filled on self.show + + self.initiGuiSharedDataToSave() + + #Create the Main Widgets in the Stacked Widget + self.scoreView = ScoreView(self) + self.ui.mainStackWidget.addWidget(self.scoreView) + self.ui.mainStackWidget.setCurrentIndex(self.ui.mainStackWidget.indexOf(self.scoreView)) + + self.trackEditor = QtWidgets.QScrollArea() + self.trackEditor.setWidgetResizable(True) + self.actualTrackEditor = TrackEditor(self) + self.trackEditor.setWidget(self.actualTrackEditor) + self.ui.actionData_Editor.setChecked(False) + self.ui.mainStackWidget.addWidget(self.trackEditor) + + #Bind shortcuts to actions (as init effect) + #TODO: Integrate better into template menu system. + self.menuActionDatabase = MenuActionDatabase(self) #The menu needs to be started before api.startEngine + + #Make toolbars unclosable + ##self.ui.toolBar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu) #only for right mouse clicks. Keyboard context menu key still works. + ##self.ui.leftToolBar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu) + self.setContextMenuPolicy(QtCore.Qt.NoContextMenu) #instead prevent the main window from having context menus. + + #The statusbar is used for tooltips. To make it permanent we add our own widget + self.statusLabel = QtWidgets.QLabel() + self.statusBar().insertPermanentWidget(0, self.statusLabel) + + self.scoreView.setFocus() #So the user can start typing from moment 0. + self.start() #Inherited from template main window #This shows the GUI, or not, depends on the NSM gui save setting. We need to call that after the menu, otherwise the about dialog will block and then we get new menu entries, which looks strange. + stepMidiInput.start() #imported directly. Handles everything else internally, we just need to start it after the engine somehow. Which is here. + + #Populate the left toolbar. The upper toolbar is created in menu.py + self.ui.leftToolBar.addWidget(LeftToolBarPrevailingDuration(self)) #needs stepmidiinput started + + #Now all tracks and items from a loaded backend-file are created. We can setup the initial editMode and viewPort. + self.scoreView.updateMode() #hide CCs at program start and other stuff + self.scoreView.scoreScene.grid.redrawTickGrid() #Init the grid only after everything got loaded and drawn to prevent a gap in the display. #TODO: which might be a bug. but this here works fine. + + + def initiGuiSharedDataToSave(self): + """Called by init""" + + if not "last_export_dir" in api.session.guiSharedDataToSave: + api.session.guiSharedDataToSave["last_export_dir"] = os.path.expanduser("~") + + if "grid_opacity" in api.session.guiSharedDataToSave: + constantsAndConfigs.gridOpacity = float(api.session.guiSharedDataToSave["grid_opacity"]) + + if "grid_rhythm" in api.session.guiSharedDataToSave: + #setting this is enough. When the grid gets created it fetches the constantsAndConfigs value. + #Set only in submenus.GridRhytmEdit + constantsAndConfigs.gridRhythm = int(api.session.guiSharedDataToSave["grid_rhythm"]) + + #Stretch + if "ticks_to_pixel_ratio" in api.session.guiSharedDataToSave: + #setting this is enough. Drawing on startup uses the constantsAndConfigs value. + #Set only in ScoreView._stretchXCoordinates + constantsAndConfigs.ticksToPixelRatio = float(api.session.guiSharedDataToSave["ticks_to_pixel_ratio"]) + + if "zoom_factor" in api.session.guiSharedDataToSave: + #setting this is enough. Drawing on startup uses the constantsAndConfigs value. + #Set only in ScoreView._zoom + constantsAndConfigs.zoomFactor = float(api.session.guiSharedDataToSave["zoom_factor"]) + + def updateStatusBar(self, exportCursorDict): + """Every cursor movement updates the statusBar message""" + c = exportCursorDict + i = c["item"] + if i: + ly = i.lilypond() + if (not ly) or len(ly) > 10: + ly = "" + else: + ly = "Lilypond: {}".format(ly.replace("<", "<").replace(">", ">")) + itemMessage = "Item: {} {}".format(i.__class__.__name__, ly) + + else: + itemMessage = "" #Appending + + positionMessage = "Pos: {} Ticks: {} Pitch: {}".format(c["position"], c["tickindex"], c["lilypondPitch"]) + + message = "{} | {}".format(itemMessage, positionMessage) + #self.statusBar().showMessage(message) #overriden by tool tips, even empty ones + self.statusLabel.setText(message) + + + def toggleMainView(self): + if self.ui.actionData_Editor.isChecked(): + self.ui.mainStackWidget.setCurrentIndex(self.ui.mainStackWidget.indexOf(self.trackEditor)) + self.scoreView.setEnabled(False) #disables shortcut like cursor movement, but not all of them. + self.menuActionDatabase.writeProtection(True) + self.trackEditor.setEnabled(True) + else: + self.ui.mainStackWidget.setCurrentIndex(self.ui.mainStackWidget.indexOf(self.scoreView)) + self.scoreView.setEnabled(True) + self.menuActionDatabase.writeProtection(False) + self.scoreView.updateMode() + self.trackEditor.setEnabled(False) + +class LeftToolBarPrevailingDuration(QtWidgets.QLabel): + def __init__(self, mainWindow): + super().__init__(self.makeText(api.D4)) + self.mainWindow = mainWindow + + #self.setFont(constantsAndConfigs.musicFont) #TODO replace with svg + api.callbacks.prevailingBaseDurationChanged.append(self.changed) + + def makeText(self, baseDuration): + if not stepMidiInput.midiInIsActive: + return "" + + labelText = "" + for i in (api.D1, api.D2, api.D4, api.D8, api.D16): #,api.DB, api.DL): + if i == baseDuration: + labelText += "" + labelText += constantsAndConfigs.realNoteDisplay[i] + if i == baseDuration: + labelText += "" + labelText += "
" + labelText += "
" + return labelText + + def changed(self, newBaseDuration): + self.setText(self.makeText(newBaseDuration)) diff --git a/qtgui/menu.py b/qtgui/menu.py new file mode 100644 index 0000000..c380408 --- /dev/null +++ b/qtgui/menu.py @@ -0,0 +1,570 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from PyQt5 import QtCore, QtGui, QtWidgets +import os.path +import engine.api as api +from midiinput.stepmidiinput import stepMidiInput #singleton instance +from .constantsAndConfigs import constantsAndConfigs +from .submenus import SecondaryClefMenu, SecondaryKeySignatureMenu, SecondaryDynamicsMenu, SecondaryMetricalInstructionMenu, SecondaryTempoChangeMenu, SecondaryTemporaryTempoChangeMenu, SecondarySplitMenu, TransposeMenu, pedalNoteChooser, SecondaryProperties, SecondaryProgramChangeMenu, SecondaryChannelChangeMenu + +class ModalKeys(object): + def __init__(self): + pass + + def keyRest(self): + if stepMidiInput.midiInIsActive: + baseDuration = api.session.data.cursor.prevailingBaseDuration + api.insertRest(baseDuration) + #else: deactivated. + + def key1(self): + if stepMidiInput.midiInIsActive: api.prevailing1() + else: api.insert1() + + def key2(self): + if stepMidiInput.midiInIsActive: api.prevailing2() + else: api.insert2() + + def key3(self): + if stepMidiInput.midiInIsActive: api.prevailing4() + else: api.insert4() + + def key4(self): + if stepMidiInput.midiInIsActive: api.prevailing8() + else: api.insert8() + + def key5(self): + if stepMidiInput.midiInIsActive: api.prevailing16() + else: api.insert16() + + def key6(self): + if stepMidiInput.midiInIsActive: api.prevailing32() + else: api.insert32() + + def key7(self): + if stepMidiInput.midiInIsActive: api.prevailingBrevis() + else: api.insertBrevis() + + def key8(self): + if stepMidiInput.midiInIsActive: api.prevailingLonga() + else: api.insertLonga() + + def key9(self): + pass + + def key0(self): + pass + +class MenuActionDatabase(object): + """There are different edit and view modes in Laborejo-Qt: + + Main Program + ScoreView + NoteEdit + Noteheads + Rectangles + BlockEdit + Transparent Block Handles + CCEdit + CC 0 + CC 1 + ... + CC 127 + DataEditor + + + Each level has shorcuts associated with them which depend on the context. + To implement those we use the qt shortcut contexts. See QAction docs. + + Additionaly there is midi-in and the modal number keys, which are + connected to each other. Without midi in the modal keys insert notes, + in midi mode they choose the duration for the next midi key. + """ + + def __init__(self, mainWindow): + self.mainWindow = mainWindow + self.modalKeys = ModalKeys() + + modes = QtWidgets.QActionGroup(self.mainWindow) + modes.addAction(self.mainWindow.ui.actionNotation_Mode) + modes.addAction(self.mainWindow.ui.actionBlock_Mode) + modes.addAction(self.mainWindow.ui.actionCC_Mode) + self.mainWindow.ui.actionNotation_Mode.setChecked(True) + + self.rememberMidi = stepMidiInput.midiInIsActive + + api.callbacks.historyChanged.append(self.renameUndoRedoByHistory) + api.callbacks.metronomeChanged.append(lambda v: self.mainWindow.ui.actionMetronome_Enabled.setChecked(v["enabled"])) #accompanied by a normal menu action down below + + self.actionsWithoutMenu = { #these are only available in Note Edit Mode, not in CC Edit Mode etc. but have no menu entry. + #Of course these actions have shortcuts, they are in a menu, visible and editable in qt-Designer, which gets hidden on program start. + self.mainWindow.ui.actionLeft : api.left, + self.mainWindow.ui.actionRight : api.right, + self.mainWindow.ui.actionSelectLeft : api.selectLeft, + self.mainWindow.ui.actionSelectRight : api.selectRight, + + self.mainWindow.ui.actionMeasureLeft : api.measureLeft, + self.mainWindow.ui.actionMeasureRight : api.measureRight, + self.mainWindow.ui.actionSelectMeasureLeft : api.selectMeasureLeft, + self.mainWindow.ui.actionSelectMeasureRight : api.selectMeasureRight, + + + self.mainWindow.ui.actionBlockLeft : api.blockLeft, + self.mainWindow.ui.actionBlockRight : api.blockRight, + self.mainWindow.ui.actionSelectBlockLeft : api.selectBlockLeft, + self.mainWindow.ui.actionSelectBlockRight : api.selectBlockRight, + + self.mainWindow.ui.actionHead : api.head, + self.mainWindow.ui.actionTail : api.tail, + self.mainWindow.ui.actionSelectHead : api.selectHead, + self.mainWindow.ui.actionSelectTail : api.selectTail, + + self.mainWindow.ui.actionTrackUp : api.trackUp, + self.mainWindow.ui.actionTrackDown : api.trackDown, + self.mainWindow.ui.actionTrackFirst : api.trackFirst, + self.mainWindow.ui.actionTrackLast : api.trackLast, + self.mainWindow.ui.actionSelectTrackUp : api.selectTrackUp, + self.mainWindow.ui.actionSelectTrackDown : api.selectTrackDown, + self.mainWindow.ui.actionSelectTrackFirst : api.selectTrackFirst, + self.mainWindow.ui.actionSelectTrackLast : api.selectTrackLast, + + self.mainWindow.ui.actionUp : api.up, + self.mainWindow.ui.actionDown : api.down, + self.mainWindow.ui.actionUpOctave : api.upOctave, + self.mainWindow.ui.actionDownOctave : api.downOctave, + self.mainWindow.ui.actionSelectUp : api.up, #these are the same as up and down. But for a good user experience they should work if shift is pressed down as well. + self.mainWindow.ui.actionSelectDown : api.down, + self.mainWindow.ui.actionSelectUpOctave : api.upOctave, + self.mainWindow.ui.actionSelectDownOctave : api.downOctave, + + + self.mainWindow.ui.actionSelectAllTracks : api.selectAllTracks, + self.mainWindow.ui.actionSelectTrack : api.selectTrack, + self.mainWindow.ui.actionSelectMeasureColumn : api.selectMeasureColumn, + + #CC Edit Actions. Share the same shortcuts as some of the actions above. But only one of these is enabled at any time. + #Don't forget to add them to the list below: self.ccEditActions + #... + } + + self.actions = { #always available in the main window. It doesn't matter if you change to CC mode or Note Edit etc. + self.mainWindow.ui.actionToggle_Notehead_Rectangles : self.mainWindow.scoreView.toggleNoteheadsRectangles, + self.mainWindow.ui.actionData_Editor : self.mainWindow.toggleMainView, + self.mainWindow.ui.actionProperties : lambda: SecondaryProperties(self.mainWindow), + self.mainWindow.ui.actionFollow_Playhead : self.mainWindow.scoreView.toggleFollowPlayhead, + #Modes Submenu + self.mainWindow.ui.actionNotation_Mode : self.mainWindow.scoreView.updateMode, + self.mainWindow.ui.actionBlock_Mode : self.mainWindow.scoreView.updateMode, + self.mainWindow.ui.actionCC_Mode : self.mainWindow.scoreView.updateMode, + + self.mainWindow.ui.actionChange_Grid_Rhythm : self.mainWindow.scoreView.changeGridRhythm, + self.mainWindow.ui.actionAdd_Track : api.newEmptyTrack, + self.mainWindow.ui.actionDelete_Current_Track : api.deleteCurrentTrack, + self.mainWindow.ui.actionUse_Current_Track_as_Metronome : api.useCurrentTrackAsMetronome, + self.mainWindow.ui.actionMidi_In_is_Active : self.toggleMidiInIsActive, + #self.mainWindow.ui.actionZoom_In_Score : self.mainWindow.scoreView.zoomIn, + #self.mainWindow.ui.actionZoom_Out_Score : self.mainWindow.scoreView.zoomOut, + self.mainWindow.ui.actionWiden_Score_View : self.mainWindow.scoreView.widen, + self.mainWindow.ui.actionShrink_Score_View : self.mainWindow.scoreView.shrinken, + self.mainWindow.ui.actionSave : api.save, + + self.mainWindow.ui.actionShow_PDF : api.showPDF, + self.mainWindow.ui.actionExport_to_Ly : self.exportLy, + + self.mainWindow.ui.actionPlayFromBeginning : api.playFromStart, + self.mainWindow.ui.actionPlayPause : api.playPause, + self.mainWindow.ui.actionPlayFromEditCursor : api.playFromCursor, + self.mainWindow.ui.actionMetronome_Enabled : api.toggleMetronome, #toggle is enough. The callback makes sure all the checkboxes have the correct value. + } + + self.noteEditActions = { #these are only available in Note Edit Mode, not in CC Edit Mode etc. #all xxxEditActions are mutually exclusive. + self.mainWindow.ui.actionBeam : api.toggleBeam, + self.mainWindow.ui.actionRemoveBeams : api.removeBeam, + + self.mainWindow.ui.actionLegatoSlur : api.insertLegatoSlur, + self.mainWindow.ui.actionClef : SecondaryClefMenu(self.mainWindow), #no lambda for submenus. They get created here once and have a __call__ option that executes them. There is no internal state in these menus. + self.mainWindow.ui.actionKey_Signature : SecondaryKeySignatureMenu(self.mainWindow), + self.mainWindow.ui.actionDynamics : SecondaryDynamicsMenu(self.mainWindow), + self.mainWindow.ui.actionMulti_Measure_Rest : lambda: api.insertMultiMeasureRest(1), + self.mainWindow.ui.actionMetrical_Instruction : SecondaryMetricalInstructionMenu(self.mainWindow), + + + self.mainWindow.ui.actionTempo_Change : lambda: SecondaryTempoChangeMenu(self.mainWindow), + self.mainWindow.ui.actionDelete_Tempo_Change : api.removeCurrentTempoItem, + self.mainWindow.ui.actionTemporary_Tempo_Change : SecondaryTemporaryTempoChangeMenu(self.mainWindow), + + self.mainWindow.ui.actionSharpen_Note : api.sharpenNote, + self.mainWindow.ui.actionFlatten_Note : api.flattenNote, + self.mainWindow.ui.actionStep_Up : api.stepUp, + self.mainWindow.ui.actionStep_Down : api.stepDown, + self.mainWindow.ui.actionOctave_Up : api.stepUpOctave, + self.mainWindow.ui.actionOctave_Down : api.stepDownOctave, + self.mainWindow.ui.actionTransposeChord : lambda: TransposeMenu(self.mainWindow, "item"), + + + self.mainWindow.ui.actionVelocityMore : lambda: self.mainWindow.scoreView._switchToRectanglesForFunction(api.moreVelocity), + self.mainWindow.ui.actionVelocityLess : lambda: self.mainWindow.scoreView._switchToRectanglesForFunction(api.lessVelocity), + self.mainWindow.ui.actionDurationModMore : lambda: self.mainWindow.scoreView._switchToRectanglesForFunction(api.moreDuration), + self.mainWindow.ui.actionDurationModLess : lambda: self.mainWindow.scoreView._switchToRectanglesForFunction(api.lessDuration), + self.mainWindow.ui.actionReset_Velocity_Duration_Mod : lambda: self.mainWindow.scoreView._switchToRectanglesForFunction(api.resetDurationVelocity), + + self.mainWindow.ui.actionAugment : api.augment, + self.mainWindow.ui.actionDiminish : api.diminish, + self.mainWindow.ui.actionDots : api.dot, + self.mainWindow.ui.actionTriplet : api.triplet, + #self.mainWindow.ui.actionCustomTuplet : something with a GUI that allows any type and number of nested tuplets, #TODO + self.mainWindow.ui.actionStaccato : api.staccato, + self.mainWindow.ui.actionTenuto : api.tenuto, + self.mainWindow.ui.actionTie : api.tie, + self.mainWindow.ui.actionSplit_in_2 : lambda: api.split(2), + self.mainWindow.ui.actionSplit_in_3 : lambda: api.split(3), + self.mainWindow.ui.actionCustom_Split : SecondarySplitMenu(self.mainWindow), #no lambda for submenus. They get created here once and have a __call__ option that executes them. There is no internal state in these menus. + + self.mainWindow.ui.actionMIDI_Channel_Plus : api.midiRelativeChannelPlus, + self.mainWindow.ui.actionMIDI_Channel_Minus : api.midiRelativeChannelMinus, + self.mainWindow.ui.actionMIDI_Channel_Reset : api.midiRelativeChannelReset, + + self.mainWindow.ui.actionAppend_Block : api.appendBlock, + self.mainWindow.ui.actionSplit_Current_Block : api.splitBlock, + self.mainWindow.ui.actionJoin_with_next_Block : api.joinBlock, + self.mainWindow.ui.actionDuplicate : api.duplicateCurrentBlock, + self.mainWindow.ui.actionCreate_Linked_Copy : api.duplicateContentLinkCurrentBlock, + self.mainWindow.ui.actionUnlink_Current_Block : api.unlinkCurrentBlock, + self.mainWindow.ui.actionDelete_Current_Block : api.deleteCurrentBlock, + + self.mainWindow.ui.actionTranspose_Score : lambda: TransposeMenu(self.mainWindow, "score"), + self.mainWindow.ui.actionDelete_All_Empty_Blocks : api.deleteEmptyBlocks, + + self.mainWindow.ui.actionDelete : api.delete, + self.mainWindow.ui.actionBackspace : api.backspace, + self.mainWindow.ui.actionAddCursorNoteToChord : api.addCursorNoteToChord, + self.mainWindow.ui.actionDeleteCursorNoteFromChord : api.deleteCursorNoteFromChord, + self.mainWindow.ui.actionCut : api.cutObjects, + self.mainWindow.ui.actionCopy : api.copyObjects, + self.mainWindow.ui.actionPaste : api.pasteObjects, + self.mainWindow.ui.actionDuplicateItem : api.duplicate, + self.mainWindow.ui.actionUndo : api.undo, + self.mainWindow.ui.actionRedo : api.redo, + + self.mainWindow.ui.actionRedrawAllTracks : api.updateCallbackAllTracks, + + #Toolbox + #Note Generation + self.mainWindow.ui.actionPedalNotes : lambda: pedalNoteChooser(self.mainWindow), + self.mainWindow.ui.actionRandom_chromatic_in_clef_range: api.insertRandomChromaticInClefRange, + self.mainWindow.ui.actionRandom_in_scale_in_clef_range: api.insertRandomFromScaleInClefRange, + self.mainWindow.ui.actionRandom_pitch_from_clipboard: api.insertRandomFromClipboard, + self.mainWindow.ui.actionRandom_in_scale_in_octave_around_cursor: api.insertRandomFromScaleAuthenticModeCursor, + self.mainWindow.ui.actionRandom_in_scale_in_cursor_plus_octave: api.insertRandomFromScaleHypoModeCursor, + self.mainWindow.ui.actionMirror_around_Cursor: api.mirrorAroundCursor, + + #Note Sorting + self.mainWindow.ui.actionRandom: api.nothing, + self.mainWindow.ui.actionReverse: api.nothing, + self.mainWindow.ui.actionAscending: api.nothing, + self.mainWindow.ui.actionDescending: api.nothing, + #Midi + self.mainWindow.ui.actionInstrument_Change: SecondaryProgramChangeMenu(self.mainWindow), #no lambda for submenus. They get created here once and have a __call__ option that executes them. There is no internal state in these menus. + self.mainWindow.ui.actionChannel_Change: SecondaryChannelChangeMenu(self.mainWindow), #no lambda for submenus. They get created here once and have a __call__ option that executes them. There is no internal state in these menus. + } + + self.modalActions = { #these are only available in Note Edit Mode, not in CC Edit Mode etc. + self.mainWindow.ui.actionModal1 : self.modalKeys.key1, + self.mainWindow.ui.actionModal2 : self.modalKeys.key2, + self.mainWindow.ui.actionModal3 : self.modalKeys.key3, + self.mainWindow.ui.actionModal4 : self.modalKeys.key4, + self.mainWindow.ui.actionModal5 : self.modalKeys.key5, + self.mainWindow.ui.actionModal6 : self.modalKeys.key6, + self.mainWindow.ui.actionModal7 : self.modalKeys.key7, #brevis + self.mainWindow.ui.actionModal8 : self.modalKeys.key8, #longa + + self.mainWindow.ui.actionPrevailingRest : self.modalKeys.keyRest, + + self.mainWindow.ui.actionShift_modal1 : api.insertRest1, + self.mainWindow.ui.actionShift_modal2 : api.insertRest2, + self.mainWindow.ui.actionShift_modal3 : api.insertRest4, + self.mainWindow.ui.actionShift_modal4 : api.insertRest8, + self.mainWindow.ui.actionShift_modal5 : api.insertRest16, + self.mainWindow.ui.actionShift_modal6 : api.insertRest32, + #self.mainWindow.ui.actionShift_modal7 : api.insertRestBrevis, + #self.mainWindow.ui.actionShift_modal8 : api.insertRestLonga, + #self.mainWindow.ui.actionShift_modal7 : api.insertRest64, + #self.mainWindow.ui.actionShift_modal8 : api.insertRest128, + } + + self.nonEditingMusicActions = [ #These are available in CC Edit Mode, Note Edit mode etc. + self.mainWindow.ui.actionPlayFromBeginning, + self.mainWindow.ui.actionPlayPause, + self.mainWindow.ui.actionPlayFromEditCursor, + self.mainWindow.ui.actionToggle_Notehead_Rectangles, + self.mainWindow.ui.actionData_Editor, + self.mainWindow.ui.actionFollow_Playhead, + self.mainWindow.ui.actionNotation_Mode, + self.mainWindow.ui.actionBlock_Mode, + self.mainWindow.ui.actionCC_Mode, + self.mainWindow.ui.actionChange_Grid_Rhythm, + self.mainWindow.ui.actionAdd_Track, + self.mainWindow.ui.actionUndo, + self.mainWindow.ui.actionRedo, + #self.mainWindow.ui.actionZoom_In_Score, + #self.mainWindow.ui.actionZoom_Out_Score, + self.mainWindow.ui.actionWiden_Score_View, + self.mainWindow.ui.actionShrink_Score_View, + self.mainWindow.ui.actionSave, + + ] + + self.ccEditActions = [ #only in CC edit, when editing user points. #all xxxEditActions are mutually exclusive. These are defined in non-menu actions above. + # self.mainWindow.ui.CCactionDelete, + ] + + #Prepare non-designer widgets. Designer can't put normal widgets in a toolbar, but Qt can. + #Eventhough this is a dict, which has no order, the CREATION has an order. So the first item in the dict will be the first item in the toolBar + self.extraToolBarWidgets = { + "snapToGrid" : self.mainWindow.ui.toolBar.addWidget(ToolBarSnapToGrid(mainWindow=self.mainWindow)), + "metronome" : self.mainWindow.ui.toolBar.addWidget(ToolBarMetronome(mainWindow=self.mainWindow)), + "playbackSpeed" : self.mainWindow.ui.toolBar.addWidget(ToolBarPlaybackSpeed(mainWindow=self.mainWindow)), + "ccType" : self.mainWindow.ui.toolBar.addWidget(ToolBarCCType(mainWindow=self.mainWindow)), #keep this at the end of the toolbar because it toggles visibility + } + + self.toolbarContexts = { + "notation" : [self.extraToolBarWidgets["snapToGrid"], self.extraToolBarWidgets["metronome"], self.extraToolBarWidgets["playbackSpeed"], ], + "cc" : [self.extraToolBarWidgets["snapToGrid"], self.extraToolBarWidgets["metronome"], self.extraToolBarWidgets["ccType"], self.extraToolBarWidgets["playbackSpeed"]], + "block": [self.extraToolBarWidgets["snapToGrid"], self.extraToolBarWidgets["metronome"], self.extraToolBarWidgets["playbackSpeed"], ], + } + + #Now connect all actions to functions + + for action, function in self.actions.items(): + action.triggered.connect(function) + + #all xxxEditActions are mutually exclusive. + for action, function in self.noteEditActions.items(): + action.triggered.connect(function) + + for action in self.ccEditActions: # a list. + action.setEnabled(False) #These are the same keys as noteEditActions, so we need to disable them for now. + + for action, function in self.modalActions.items(): + self.mainWindow.ui.centralwidget.addAction(action) #no actions without a widget + action.triggered.connect(function) + + #Do not connect modalActionsPrevailing yet + + for action, function in self.actionsWithoutMenu.items(): + self.mainWindow.ui.centralwidget.addAction(action) #no actions without a widget + action.triggered.connect(function) + + self.mainWindow.ui.menubar.removeAction(self.mainWindow.ui.menuGeneric.menuAction()) #thats why we added the actions to the centralwidget above. + self.loadToolbarContext("notation") + + def toggleMidiInIsActive(self): + """That is: "toggle midiInIsActive", not "toggleMidiIn is active?" """ + stepMidiInput.toggleMidiIn() + self.mainWindow.ui.actionPrevailingRest.setEnabled(stepMidiInput.midiInIsActive) + self.mainWindow.ui.actionMidi_In_is_Active.setChecked(stepMidiInput.midiInIsActive) + + def setMusicEditingEnabled(self, boolean): + """This is the "reset to standard" functions for shortcuts. + If you want to enable other keys, such as CC editing keys, + you have to call another function after this one""" + allActions = list(self.actions.keys()) + list(self.modalActions.keys()) + list(self.actionsWithoutMenu.keys()) + list(self.noteEditActions.keys()) + + for x in self.nonEditingMusicActions: + allActions.remove(x) + + for editAction in allActions: + editAction.setEnabled(boolean) + + for action in self.ccEditActions: # Call this after enabling stuff in the for-loop above. + action.setEnabled(False) #These are the same keys as noteEditActions, so we need to disable them for now. Maybe they are enabled later again, after this function. + + self.mainWindow.ui.actionPrevailingRest.setEnabled(boolean and stepMidiInput.midiInIsActive) + + def noteEditMode(self): + self.setMusicEditingEnabled(True) + + def ccEditMode(self): + self.setMusicEditingEnabled(False) + for action in self.ccEditActions: # a list. + action.setEnabled(True) #These are the same keys as noteEditActions, which are disabled above. + + def writeProtection(self, boolean): + """Artificial read only mode that was designed for the mouse-only track editor etc. + When zoomed out the user should be able to use the mouse but the cursor is hidden and + """ + + if boolean: + #Switch off midi input + if stepMidiInput.midiInIsActive: + self.rememberMidi = stepMidiInput.midiInIsActive + stepMidiInput.toggleMidiIn() + assert not stepMidiInput.midiInIsActive + self.mainWindow.ui.actionPrevailingRest.setEnabled(stepMidiInput.midiInIsActive) + self.mainWindow.ui.actionMidi_In_is_Active.setChecked(stepMidiInput.midiInIsActive) + #Deactivate Note Editing Actions + self.setMusicEditingEnabled(False) + self.mainWindow.scoreView.scoreScene.cursor.hide() #the cursor which can be used to edit notes. Since the cursor shortcuts get disabled it cannot be changed invisbly. + else: + self.setMusicEditingEnabled(True) + self.mainWindow.scoreView.scoreScene.cursor.show() + if self.rememberMidi and not stepMidiInput.midiInIsActive: + self.toggleMidiInIsActive() + self.rememberMidi = None + + def loadToolbarContext(self, nameAsString): + """Hide all toolbar actions and only load those + which are in the current context, defined as list""" + + assert nameAsString in constantsAndConfigs.availableEditModes + + for action in self.mainWindow.ui.toolBar.actions(): + action.setVisible(False) + + for action in self.toolbarContexts[nameAsString]: + action.setVisible(True) + + def renameUndoRedoByHistory(self, undoList, redoList): + if undoList: + self.mainWindow.ui.actionUndo.setText("Undo: {}".format(undoList[-1])) + self.mainWindow.ui.actionUndo.setEnabled(True) + else: + self.mainWindow.ui.actionUndo.setText("Undo") + self.mainWindow.ui.actionUndo.setEnabled(False) + + + if redoList: + self.mainWindow.ui.actionRedo.setText("Redo: {}".format(redoList[-1])) + self.mainWindow.ui.actionRedo.setEnabled(True) + else: + self.mainWindow.ui.actionRedo.setText("Redo") + self.mainWindow.ui.actionRedo.setEnabled(False) + + + def exportLy(self): + filename = QtWidgets.QFileDialog.getSaveFileName(self.mainWindow, "Export Lilypond Source File", self.mainWindow.settings.value("last_export_dir"), "Lilypond Source (*.ly)") + filename = filename[0] #(path, filter) + if filename: + if not os.path.splitext(filename)[1]: #no file extension given? + filename = filename + ".ly" + self.mainWindow.settings.setValue("last_export_dir", os.path.dirname(filename)) + api.exportLilypond(filename) + + +class ToolBarCCType(QtWidgets.QSpinBox): + def __init__(self, mainWindow): + super().__init__() + self.mainWindow = mainWindow + self.setRange(0,127) + self.setPrefix("CC ") + + self.valueChanged.connect(self.changed) + + #self.addItems([str(i).zfill(3) for i in range(128) ]) + + def changed(self): + constantsAndConfigs.ccViewValue = self.value() + self.mainWindow.scoreView.updateMode() #gets the new value itself from constantsAndConfigs + +class ToolBarSnapToGrid(QtWidgets.QCheckBox): + def __init__(self, mainWindow): + super().__init__("Snap to Grid") + self.setStatus() + self.stateChanged.connect(self.changed) + + constantsAndConfigs.snapToGridCallbacks.append(self.updateFromCallback) + + def setStatus(self): + if constantsAndConfigs.snapToGrid: + self.setCheckState(QtCore.Qt.Checked) + else: + self.setCheckState(QtCore.Qt.Unchecked) + + def isChecked(self): + if self.checkState() == QtCore.Qt.Checked: + return True + else: + return False + + def updateFromCallback(self): + self.blockSignals(True) + self.setStatus() + self.blockSignals(False) + + def changed(self): + constantsAndConfigs.snapToGrid = self.isChecked() #this sends a call back to all Snap to Grid in the whole program + + +class ToolBarMetronome(QtWidgets.QCheckBox): + """Contrary to SnapToGrid this reflects a backend state, not a pure GUI one. + There is also the menu actionMetronome_Enabled , itself a normal checkbox. It's callback and + state are handled in the menuDatabase classes init.""" + def __init__(self, mainWindow): + super().__init__("Metronome") + self.setStatus() + self.stateChanged.connect(self.changed) + api.callbacks.metronomeChanged.append(self.updateFromCallback) + + def setStatus(self): + if api.isMetronomeEnabled(): + self.setCheckState(QtCore.Qt.Checked) + else: + self.setCheckState(QtCore.Qt.Unchecked) + + def isChecked(self): + if self.checkState() == QtCore.Qt.Checked: + assert api.isMetronomeEnabled(), api.isMetronomeEnabled() + return True + else: + assert not api.isMetronomeEnabled(), api.isMetronomeEnabled() + return False + + def updateFromCallback(self, exportDict): + self.blockSignals(True) + self.setStatus() + assert self.isChecked() == exportDict["enabled"], (self.isChecked(), exportDict["enabled"]) + self.setText("Metronome: " + exportDict["trackName"]) + self.blockSignals(False) + + def changed(self, value): + api.enableMetronome(value) #triggers callback + + +class ToolBarPlaybackSpeed(QtWidgets.QDoubleSpinBox): + def __init__(self, mainWindow): + super().__init__() + self.setRange(0.1,3.0) + self.setDecimals(1) + self.setValue(1.0) + self.setSingleStep(0.1) + self.setPrefix("Tempo ×") #yes, this is the unicode multiplication sign × and not an x + api.callbacks.playbackSpeedChanged.append(self.updateFromCallback) + self.valueChanged.connect(self.changed) + + def updateFromCallback(self, newValue): + self.blockSignals(True) + self.setValue(newValue) + self.blockSignals(False) + + def changed(self): + api.playbackChangeSpeed(self.value()) + constantsAndConfigs.ccViewValue = self.value() #this sends a call back to all CC spinboxes in the whole program diff --git a/qtgui/resources.py b/qtgui/resources.py new file mode 100644 index 0000000..e7a83cd --- /dev/null +++ b/qtgui/resources.py @@ -0,0 +1,10728 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt5 (Qt v5.12.1) +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore + +qt_resource_data = b"\ +\x00\x00\x2d\x28\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x01\x2c\x00\x00\x00\x97\x08\x06\x00\x00\x00\xaf\x07\x66\x77\ +\x00\x00\x00\x06\x62\x4b\x47\x44\x00\x80\x00\x78\x00\x73\xdb\x4b\ +\x12\x83\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x2e\x23\x00\x00\ +\x2e\x23\x01\x78\xa5\x3f\x76\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ +\xe2\x08\x18\x12\x27\x11\x9d\x52\xc1\x11\x00\x00\x00\x19\x74\x45\ +\x58\x74\x43\x6f\x6d\x6d\x65\x6e\x74\x00\x43\x72\x65\x61\x74\x65\ +\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\x57\x81\x0e\x17\x00\ +\x00\x20\x00\x49\x44\x41\x54\x78\xda\xed\x9d\xe9\x73\x9c\xd7\x75\ +\xe6\x7f\x8d\xc6\x0e\x90\xe0\xbe\x89\xa4\xa8\x8d\xd4\x42\xed\x96\ +\x6c\xcb\x92\x05\xdb\x34\x93\x78\xbc\x4d\x32\x53\x53\x9e\x9a\xa9\ +\x9a\xaa\xa4\x6a\xe6\x7b\xf0\x21\xf8\xd4\xc1\xa7\xfe\xd2\xff\x43\ +\xaa\x52\x93\x99\xcc\x4c\x32\x71\x9c\xd8\x13\xd3\xa6\x6d\xda\x96\ +\x17\x2d\x96\x65\x85\x5a\x28\x51\x24\x25\x2e\xe0\x06\x92\x00\xb1\ +\xf6\x36\x1f\xee\x73\xfc\x5e\xbc\x7c\xdf\x46\x03\x04\xd0\xdd\xc0\ +\x3d\x55\x6f\x75\x63\x6b\xbc\xcb\xbd\xcf\x7d\xce\x39\xcf\x3d\x27\ +\xf3\x97\x7f\xf1\xe7\x04\x0b\x16\x2c\x58\x2b\x58\x5b\xb8\x05\xc1\ +\x82\x05\x0b\x80\x15\x2c\x58\xb0\x60\x01\xb0\x82\x05\x0b\x16\x00\ +\x2b\x58\xb0\x60\xc1\x02\x60\x05\x0b\x16\x2c\x58\x00\xac\x60\xc1\ +\x82\x05\xc0\x0a\x16\x2c\x58\xb0\x00\x58\xc1\x82\x05\x0b\x16\x00\ +\x2b\x58\xb0\x60\x01\xb0\x82\x05\x0b\x16\x2c\x00\x56\xb0\x60\xc1\ +\x82\x05\xc0\x0a\x16\x2c\x58\x00\xac\xb8\xe5\xf2\x85\x4c\x2e\x5f\ +\xc8\x84\xdb\x17\x2c\x58\xb0\xd5\xb4\x4c\xbd\xd5\x1a\x04\x50\xed\ +\x40\x0f\xd0\x07\x64\x80\x22\x30\x01\x14\x47\x86\x87\xca\xe1\x76\ +\x06\x0b\x16\xac\xe1\x0c\x4b\x60\xd5\x03\xec\x03\x9e\x06\xbe\x04\ +\x7c\x19\x18\x04\x1e\x05\xb6\xe6\xf2\x85\xf6\x70\x3b\x83\x05\x0b\ +\xb6\x92\x96\x1d\x7c\xf1\x85\x7a\xc1\x6a\x3f\xf0\x59\xe0\x0b\xc0\ +\x67\x80\xc7\x81\x07\x80\x1d\x40\x05\x18\x1f\x3c\x72\x74\xe6\xc4\ +\xf1\x63\x95\x70\x5b\x83\x05\x0b\xd6\x28\x86\xd5\x06\x0c\x00\x87\ +\xc5\xaa\xfe\x10\xf8\x3c\xf0\x92\x18\xd6\x1f\x01\x47\x80\x87\x80\ +\xde\x10\xdb\x0a\x16\x2c\xd8\x4a\x59\x3d\x6e\x5c\x27\xb0\x5b\xae\ +\xdf\x23\x62\x5a\xdd\xb8\x18\x56\xbf\xde\xdf\x06\xce\x01\xe7\x81\ +\x49\x20\xc4\xb3\x82\xb5\xbc\xe5\xf2\x85\x36\x20\xab\xb1\x0e\x50\ +\x95\x37\x51\x19\x19\x1e\xaa\x86\x3b\xd4\x9c\x80\xd5\x26\x60\xba\ +\x47\xee\x5f\x97\xc7\xcc\xb2\xfa\xd9\x5e\xe0\x00\xb0\x45\xa0\x15\ +\x00\x2b\x58\xab\x82\x54\x56\x63\xbc\x47\x63\xbb\x4f\xf3\x24\x03\ +\xcc\x6a\x41\x1e\xcf\xe5\x0b\x53\x40\x29\x00\x57\xf3\x01\x56\x46\ +\x2c\xab\xdb\x7b\x70\x71\x40\xdb\x00\xec\x94\xeb\x98\x0d\xb7\x35\ +\x58\x8b\x02\xd5\x46\x60\xbb\x16\xdf\x5d\x3a\x7a\x34\xf6\x4b\x02\ +\xab\x2b\xf2\x26\x3e\x02\xae\xe4\xf2\x85\xa9\x00\x5a\xcd\x05\x58\ +\x73\x38\xe9\xc2\xac\x98\x53\x35\x01\xd0\x3a\xf4\x60\x3b\x09\x62\ +\xd4\x60\xad\xe7\xf6\xf5\x03\xf7\xe2\x32\xe0\x87\x71\xf1\xd8\x6d\ +\x02\xb0\x0e\x2d\xc2\x25\x60\x06\xb8\x0a\x9c\x01\xde\x04\x5e\x05\ +\x4e\xe7\xf2\x85\xdb\x01\xb4\x9a\x07\xb0\xca\xc0\x38\x70\x0d\x98\ +\x96\x0f\x1f\x67\x51\x59\x7d\x56\xb7\x1e\x70\xb0\x60\xad\x02\x56\ +\xdb\x81\xa7\x70\x09\xa5\x4f\x89\x5d\x6d\xd4\x58\xce\x7a\x0b\x70\ +\x55\x73\x61\x16\xb8\x1f\x27\xf1\xe9\xd7\xcf\x4e\x01\x53\xe1\x8e\ +\x36\x07\x60\x55\x70\x41\xf5\xcb\xc0\x4d\x3d\xb4\xb8\x6b\x98\xf1\ +\xfc\xfe\xa0\xc7\x5a\x5b\x93\x3a\xa3\x49\x6b\xcf\xbb\x32\x32\x3c\ +\x54\x59\x03\xd7\xd5\x06\x6c\x16\x48\x7d\x1d\x78\x19\xd8\x03\xf4\ +\xc6\xae\x37\x3e\x5f\x2c\x3c\x62\x1e\x45\x19\x98\xcb\xe5\x0b\x1f\ +\x8d\x0c\x0f\xcd\x84\x11\xd3\x60\xc0\x1a\x19\x1e\xaa\xe6\xf2\x85\ +\x19\xe0\xba\x00\x6b\x4e\xe0\x14\x67\x58\xdd\xb8\x58\x56\x67\xb8\ +\xad\x89\x13\xde\xcf\x38\x65\x34\xd0\x2b\x5a\xb9\x9b\x0e\x04\xbc\ +\x9d\x0d\xdd\xb8\xc0\xb3\x25\x5b\xe6\x72\xf9\xc2\xb4\xd8\xf6\x1c\ +\xad\x9b\x31\x6b\xc7\x65\xbc\x5f\x12\x58\xdd\xab\x6b\xac\x25\xcb\ +\xb1\x67\xd7\x89\x4b\x40\x55\xe5\x2a\xce\x02\xe5\x5c\xbe\x70\x2e\ +\x80\x56\xe3\x19\x16\x1a\x98\xb7\x74\xcc\x8a\x0a\x67\x62\x80\xd5\ +\x87\xcb\x12\xf6\xe4\xf2\x85\xb6\xb5\xb0\x0a\x2f\xc3\x0a\xde\xab\ +\x7b\xb5\x5d\x2b\x72\x2f\x51\x06\xb5\x28\xc0\x9a\x01\x26\x73\xf9\ +\xc2\x2d\xa2\x6d\x4e\x95\x26\x00\xab\x4e\x5c\x12\x65\x0f\xf3\x33\ +\xc4\x55\x8d\x83\x31\xe0\x12\x70\x2d\x97\x2f\xdc\x00\xe6\x5a\xec\ +\x99\x6f\xc4\xc5\xaa\x1e\xd1\xf3\x59\x08\xac\xe2\xc0\xd5\xa1\xbf\ +\x7b\x54\xa0\x05\xf0\xe3\x5c\xbe\xf0\xf1\xc8\xf0\xd0\x74\x80\x96\ +\xc6\x02\x56\x51\xec\xca\x00\x2b\xbe\xa2\x5a\xe0\x72\xb3\x58\x56\ +\xbb\x40\x6e\xbd\x82\x55\x37\xb0\x15\x78\x0c\x78\x50\x13\xa3\x5f\ +\x80\x55\xd4\xfd\x2b\x0a\xbc\xa6\x71\x81\xdc\xb3\xc0\xfb\xc0\xd9\ +\x5c\xbe\x70\xab\xc1\x7b\x33\xdb\x05\x56\x0f\x01\x4f\x6a\x52\xee\ +\xd5\xb3\xcd\xea\xd9\xde\xc4\x65\xcb\x3e\x00\xde\xc2\x05\x9f\x6f\ +\x8e\x0c\x0f\x95\x5a\x64\x31\xe9\xd2\x35\x6e\xd0\x62\x52\x0b\xac\ +\xaa\x31\xb0\xf2\xc3\x20\x3b\x75\x8f\x2c\xf1\xf4\xc3\x5c\xbe\x70\ +\x7a\x64\x78\x28\xc4\xb4\x1a\x08\x58\x25\x5c\x1c\x6b\x0c\x17\x5c\ +\xf4\x03\xef\xe6\xf2\xf4\x08\xb0\x2c\xb3\x32\xb7\x8e\xc1\xea\x7e\ +\xe0\xd3\xc0\x17\x81\x87\x71\x19\x27\x8b\x8d\xfc\x5e\x7c\x68\xf1\ +\x0f\x31\xab\x8b\xc0\x3b\xc0\x4f\x81\x37\x72\xf9\xc2\x95\x91\xe1\ +\xa1\xe2\x2a\xba\x7e\x1d\xde\x6b\xaf\x00\xea\x29\xdc\x6e\x86\x27\ +\x74\x0d\x9d\x9e\x3b\x3b\x8b\x4b\xc6\x9c\xd7\xcf\x4f\x00\xaf\xe5\ +\xf2\x85\x4b\x23\xc3\x43\xb3\x2d\xf0\xa8\xb2\x5e\xac\xca\x5c\xf3\ +\x4c\x02\x50\x55\x34\xfe\xab\xba\x3f\xd9\x04\xd0\xda\x25\xd7\x79\ +\xb3\xbc\x8c\x7f\xca\xe5\x0b\xef\x8c\x0c\x0f\xdd\x0e\x10\xd3\x18\ +\xc0\x2a\x0b\xb0\x6e\x0a\xb0\xe2\x81\xf7\x36\x2f\x86\x65\x80\xb5\ +\x1e\xc1\xaa\x53\x2e\xd4\xf3\xc0\xbf\xd5\xca\xbb\x9d\x3b\xe5\x1e\ +\xd5\xd8\xfb\x32\x70\x9f\x80\xee\x1e\xb1\xb1\x9f\xe5\xf2\x85\xd1\ +\x95\x04\x2d\x9d\xef\x06\xdc\x4e\x86\xad\x7a\x76\x5d\x44\x42\xe1\ +\xc7\x70\x7b\x46\xf7\x25\xb8\x4c\xc6\xa8\x77\xea\x77\x77\xe9\xb3\ +\x7e\x91\xcb\x17\x3e\x06\xa6\x9b\x31\xb6\x25\xbd\x55\x2f\xb0\xc9\ +\x73\xd1\x8b\xb1\x45\xb8\xea\x3d\x97\x39\xb1\x60\xf4\x1c\x7b\x62\ +\x63\xdf\xdc\xc3\xad\x9a\x03\x03\x0a\x8f\x7c\x3b\x97\x2f\xbc\x31\ +\x32\x3c\x34\x19\x60\x66\xf5\x01\xcb\x62\x2d\x13\x7a\x2d\x27\xf8\ +\xf4\xed\x1a\x00\xbd\xac\xdf\x4c\x61\x37\x2e\x78\xfb\x39\x81\xd5\ +\x6e\x92\xc5\xb6\x99\x84\xd5\xbe\x43\xa0\xd0\xa7\xa3\x13\x38\x2e\ +\xc6\x52\x5a\xe6\x49\xdb\xa6\xff\x71\xd0\x03\xa5\xed\x9a\xc4\x6d\ +\x3a\x97\x3e\xc5\xad\x76\x31\x7f\x77\x03\x31\x66\xdd\x27\x40\xb3\ +\xc9\xba\x15\x78\x05\x78\x2f\x97\x2f\x8c\x37\x83\x8b\x28\x90\x32\ +\xe5\xfa\x1e\xb1\xc7\x43\x62\x90\xdb\x3d\x70\x4a\x7a\x4e\x59\x3d\ +\x8b\x19\x1d\x55\x5d\x73\x9c\x69\x65\x05\xd8\x07\x80\xaf\xe9\xfb\ +\x93\x62\x5a\x21\xa6\xb5\x5c\xb4\x78\xa1\x6a\x0d\x00\x27\x8e\x1f\ +\x63\xf0\xc8\xd1\x5e\x3d\x8c\xc7\x34\x11\x3b\x63\x0f\x78\x0e\x18\ +\x95\x5b\xf3\xd1\x89\xe3\xc7\xd6\xd5\xca\x22\x10\xd8\x06\x3c\x03\ +\x3c\x8b\x0b\xe6\x2e\x14\x1b\x49\x9a\x1c\x3d\x02\x8e\x01\xb1\xd9\ +\xab\x83\x47\x8e\x4e\x2f\x57\x15\x0c\x9d\xe7\x56\x5c\x3a\xff\x1b\ +\xc0\xbf\x11\x23\x3c\x8c\xab\xbe\x71\x40\x00\xb4\x4b\xe7\xd1\x45\ +\x7a\x9a\xdf\x3f\x6f\x63\x2d\xbb\x35\xa1\xe7\x80\xdb\xcb\x79\xee\ +\x4b\xb8\xd6\xf6\xc1\x23\x47\x37\xe2\xb2\x81\xcf\xe1\x36\xed\xff\ +\xa1\xdc\xdc\x17\x04\x5a\xbb\x75\xee\xbe\x8b\x98\xf1\x00\x39\xeb\ +\xb9\x82\x33\xba\xae\x36\x7d\xaf\x2d\xe5\x5e\x58\x02\x6a\x06\x38\ +\x3f\x78\xe4\xe8\xc4\x89\xe3\xc7\xc2\x76\xb5\x65\xb0\xc5\xa8\xd2\ +\x2d\x6e\x91\x14\x74\xc7\x7b\x88\xed\x8b\x98\xa4\x6b\xd5\xfa\x97\ +\x78\x1f\xfc\xec\xd3\xd3\xc0\x57\x04\x26\x5b\xc4\x12\x96\x83\x69\ +\x6c\xc5\x95\x07\xfa\x96\x98\xc0\xb3\x02\xa9\xed\x02\xc9\x8d\x3a\ +\x2c\x49\xd0\xa1\xf3\xaa\x2e\x70\xde\xed\x72\x11\x0f\xe2\xea\xa5\ +\x7d\x4d\x0c\x66\x59\xce\x7d\x91\xd7\xd9\x91\xcb\x17\x36\x6b\x71\ +\xfd\x0a\xf0\x67\xc0\x7f\x03\xfe\x54\xe7\xf5\x92\x62\x8b\xe6\x7e\ +\x77\x30\x5f\x72\x92\x04\x5a\x5d\x7a\xbd\x8e\x4b\x92\xcc\xa4\xdc\ +\x13\x8b\x6b\xed\xf5\xc0\x71\x4f\xa8\x17\xb7\xba\x2e\xa1\xb9\x85\ +\x73\x9e\xbf\x9f\x06\x58\xd9\xf5\x04\x58\x0a\x5a\x9b\xdb\x60\xfb\ +\x2d\x6f\x28\xee\xd1\x9d\xb0\x28\x54\xbd\x81\x9e\x49\x71\x43\xda\ +\xc5\xd6\x9e\xc6\x05\xb6\x67\x70\x01\xed\x1b\x4b\xcd\x1e\xea\x3c\ +\xfb\x05\x50\x7f\x82\x4b\x08\xec\x48\x60\xca\x69\x6e\x6b\xd5\x3b\ +\x6a\x9d\xf7\x80\x62\x71\x25\x31\xee\xf3\xb8\xec\x72\x79\x15\x9e\ +\x85\xed\x6b\xbd\x4f\x60\xf9\x3c\x2e\xc3\x79\x9f\xd8\x5f\x4f\x82\ +\x2b\x57\xaf\x59\xe2\xe9\x1c\x91\xae\x6e\x0f\xc9\xba\x43\xbb\xd7\ +\x0f\xe3\xca\x2f\xdd\x94\x7b\x78\x7d\xbd\xcb\x7d\x56\x1b\xb0\x4a\ +\x44\xe9\xf8\x78\x56\xc5\xd8\x41\x37\xd0\x9e\xcb\x17\x32\x6b\x75\ +\x7f\x95\x26\xbf\xc5\x9c\x36\x6a\x92\x0e\x08\x64\x06\x34\x98\x6f\ +\xe9\x5e\x74\x79\x0c\xc5\x58\xea\x0c\x51\xb9\xe9\xb4\xf8\x90\x65\ +\x9f\x9e\x91\x6b\x58\x04\xde\xca\xe5\x0b\x63\x8b\x05\x2d\x9d\x6f\ +\xb7\xdc\xd4\x3f\x10\xc3\xaa\x05\x56\x69\x2c\xca\x9e\x3f\x35\xd8\ +\xb4\xe9\xcf\x76\x28\x9e\xf7\x10\x70\x59\x59\xcf\xea\x0a\x3e\x8f\ +\x4e\xdd\xaf\x67\xe5\xfa\x3d\xa7\xff\xbf\xb9\x0e\xb7\x36\x0e\xcc\ +\xfe\xfb\x0a\x91\xac\xe7\x1c\xf0\xb6\x58\xd6\x9c\xe7\xfa\x25\x31\ +\xc8\xac\xc6\xc2\x33\x62\x64\x97\x81\xd7\x08\x5b\x78\x56\xd5\x25\ +\x34\x75\x73\x39\xe5\xb3\x6c\x7b\x4e\xc7\x5a\x65\x59\xa2\xf6\x1b\ +\x35\x19\x9e\x93\xcb\xf1\xef\x81\xff\x04\xfc\x07\x73\x01\x34\xd8\ +\x6f\x6b\x80\x4e\xe9\xfd\x35\xdc\x2e\xff\xd7\x81\x5f\xe9\xfd\x38\ +\x91\xf0\x30\x7e\x3f\xfb\xc4\x56\x3e\x23\x57\xe6\xd3\xc0\xf6\x25\ +\xb8\x17\x19\x31\x8c\x27\xc5\x3a\xf6\x2e\x00\x56\xd5\xd8\x61\x93\ +\xf6\x96\x18\xd3\x47\x62\x4f\x13\x44\x29\xff\x24\xd0\xda\x49\x24\ +\x3c\xed\x5f\x09\xb7\xc8\xab\xb2\xf0\x98\xee\xd1\x7f\x01\xbe\x29\ +\x86\xb5\x2b\x81\x55\xa5\x5d\xaf\x2d\xc8\x73\x7a\x5e\x13\x62\xca\ +\xa3\xc0\x87\xc0\x1b\xc0\xcf\x81\x5f\x03\x3f\x01\xbe\x83\xdb\x00\ +\x3d\x91\xe2\x71\x18\xa8\xef\x10\x53\x7e\x02\xd8\x14\x0a\x5c\xae\ +\x1e\xc3\x2a\x8b\x19\x4c\x27\x0c\xd2\x8c\x07\x58\xfd\x44\x69\xfc\ +\xca\x1a\x02\x2a\x2b\x15\xbd\x0b\x17\xac\x3d\xac\xd7\xfd\x1a\x94\ +\x03\x44\x9b\xbf\xb3\xde\x91\xf1\x18\x2a\xb8\x12\x25\x9f\x68\x12\ +\x6c\xc5\x65\x14\x1f\x16\xa0\xc4\x19\x8b\x65\x9e\x0e\x0a\x00\x06\ +\x74\x7f\x5f\x59\x64\xf6\xb0\x4b\xe7\x79\x58\x60\xd5\x5d\x63\x02\ +\x9b\x3e\xac\x14\x03\xab\x09\x31\x8c\xf7\xc4\x16\x76\x69\x12\xee\ +\x13\x8b\xb1\x67\x6e\x7f\x53\x15\x60\x3d\xef\xb9\xcb\xa7\xe5\x16\ +\x95\x96\xe9\x79\x74\xea\x7f\x3c\xa2\xb8\xd4\xe7\xf5\x7e\xd3\x22\ +\x42\x13\x76\x7d\x93\xba\xc6\x71\xbd\xda\x42\x73\x03\x57\x52\xe6\ +\x23\xdc\x26\xe7\x33\x38\x3d\xe2\x55\xdd\xd7\x2e\x2d\x04\x1b\x12\ +\x98\x96\xcf\xfc\x0e\x6b\x91\xba\xea\xb1\xd4\x60\x2b\x08\x58\x25\ +\x8f\x29\xcc\x91\x5c\x66\xa6\x4b\x0f\xae\x97\x35\x54\x66\x46\x93\ +\x63\x03\x2e\x8b\xf6\x1c\x2e\xc3\x74\x50\x93\xdf\xdf\xd9\x9f\x49\ +\x70\x93\x6d\x05\xef\x24\xda\x83\x79\x0b\xa7\x10\xff\x95\x26\xff\ +\x97\xc5\x10\xb6\x79\x71\xaf\x4c\x2c\x2e\x64\x92\x07\xbb\xb7\x3f\ +\x5b\x04\x68\x75\xe8\xb3\xf7\x7b\x2e\x6b\x12\xcb\xb0\x9a\x4f\x57\ +\x89\xf6\x8d\x96\x34\x81\xaf\xe2\x94\xf8\xef\x02\x1f\xeb\xba\x9f\ +\xc5\xd5\xf8\x8f\x6f\x6f\x29\xeb\x7a\xf7\x11\xe9\xbc\x76\x00\x3f\ +\x02\x5e\x97\x22\xbe\x7c\x17\xcf\xc3\x76\x56\x1c\x90\xcb\xf5\x79\ +\xbd\xde\x4b\x94\xf0\xa8\xc7\xf5\x33\x7d\xe1\x28\x6e\xa7\x81\x31\ +\xc7\x1b\xba\xe6\x49\x22\xc1\xf4\x98\xee\x89\x8d\xff\x49\xe0\x7b\ +\xde\x73\x32\xd0\x6a\x4b\x89\x67\x6d\xf3\x16\xa5\x00\x58\xab\x14\ +\xc3\x9a\xd1\x03\x9b\x49\x71\x03\x8c\x61\xd9\xa0\x99\x5b\x23\x60\ +\xd5\x27\xb0\xfa\x92\x37\x41\xb7\xd5\x00\xaa\x24\x97\xcc\xee\xd1\ +\x16\xb9\x48\x5b\xb4\x00\xbc\xa2\x09\x72\x84\x48\xa4\xb9\xc1\x63\ +\x5b\xbe\x6c\x60\xaf\x37\xe0\xc7\x81\x29\x05\xe2\x17\x62\xb2\xdd\ +\x44\xe2\xd0\x8e\x1a\x0b\xd2\x75\xdc\x36\x9b\xd7\x04\x50\xa6\xc8\ +\x9f\x13\xcb\xb0\x20\xfa\x4d\x9d\xd3\x15\xb9\xb9\x2f\x28\x56\xb5\ +\x47\xd7\x65\x19\xc6\x7e\x7d\xbd\x4b\xaf\x25\xfd\xfe\x49\x96\x18\ +\x84\xcf\xe5\x0b\x1d\x9a\xf8\x8f\xe3\x9a\xa2\xd8\xe2\xe1\xbb\x7f\ +\x0b\x01\x55\x45\x9e\xc2\x75\x81\xf0\x5b\x72\xef\xce\xea\x7b\x16\ +\x33\x2c\xc5\x5e\xcb\x40\x55\xb1\xb8\x4a\x2e\x5f\xb8\x08\xfc\x50\ +\xd7\xb6\x55\x63\xa4\x3b\x65\x9e\x59\x9c\xb3\x83\x48\x88\x1a\x6c\ +\x85\x5d\xc2\x49\xb1\x03\x13\x8f\xc6\x15\xbf\xbe\xf0\x71\xad\xa4\ +\x71\xb3\x1a\x90\xcf\xe0\x32\x6b\x4f\x79\x13\x3f\xb3\xc4\xcf\x33\ +\x17\xa9\x2c\x00\x18\xd5\x44\x1e\x05\x5e\x54\xdc\x6a\x73\xc2\xfd\ +\xed\xf4\x62\x22\x97\x04\x18\xbf\xd3\xf3\xa8\x05\xb8\xdd\x62\x44\ +\x7d\x29\xae\x52\x45\xcf\xf5\x75\xe0\x7f\xea\x75\xd2\x73\xf5\xab\ +\x9a\x64\x96\x30\x28\xa9\x8a\xc7\x69\xfd\xdd\x05\x01\xc7\xcb\xba\ +\x57\x5d\xde\xff\x31\xb7\xf6\x7e\x9d\xf7\x49\xb9\x96\x33\x4b\x00\ +\x2b\xeb\x2f\xf0\x2c\x70\x54\xaf\xfb\x04\x04\x0b\x15\x8f\xac\x78\ +\x5e\xc2\x0d\x81\xd3\x49\x5c\x11\xbe\xb7\xc5\x1a\x0d\xa8\xaa\x1e\ +\xb8\x91\x96\x2c\x18\x19\x1e\x2a\x49\xd5\x7f\x42\xee\xf1\xee\x84\ +\xf3\xc8\x78\xe1\x81\x4e\x42\xbd\xb8\xd5\x01\xac\x91\xe1\xa1\x4a\ +\x2e\x5f\x98\xf5\x18\x56\x25\xe5\xf3\x4c\xed\xbe\x56\x1e\x8c\xa9\ +\xd7\x4d\x58\x59\x0b\xac\xe2\x19\xa6\xb8\x7e\xc9\x5c\x90\x6b\x02\ +\x9b\x29\xdd\xcb\x29\x05\x73\x6f\x7b\xee\xc2\xc3\x02\x99\xa4\xba\ +\x63\xbb\xc5\x30\xde\x05\xce\x6b\x0b\x4f\xa5\x06\x40\xf6\x79\x31\ +\xb6\x24\x99\xc5\x9c\x26\xec\x4f\xc4\xf8\x3e\x49\xbb\x36\x7f\xf2\ +\x8e\x0c\x0f\x15\x73\xf9\xc2\x15\x8d\x85\xed\xb8\xe4\x40\x77\x02\ +\x28\x5a\x02\xe1\x5e\x73\xdb\x94\xed\xac\x2c\x02\xac\xec\x39\xbc\ +\x84\x93\x0a\x1c\x16\xab\xea\x5d\x20\x5e\x55\xf1\x5c\xdd\xf3\xc0\ +\x69\x31\xaa\x0f\x05\x54\x97\x04\x60\x4b\xad\xcf\x3e\x27\xb7\xfe\ +\x7d\x9c\x18\x77\x63\x8a\x5b\xd8\x4d\xa4\xf9\x0a\xb6\x0a\x0c\xcb\ +\xdc\x06\x53\xfb\x56\x12\x1e\x4a\x9b\x17\xab\x59\x2b\x31\xac\x4e\ +\xb1\x86\xbd\x02\xab\xa4\x54\xbe\xb9\x19\x16\xac\xae\xc4\x5c\x9e\ +\xaa\xb7\xba\x5f\xd4\xca\x7e\x56\xa0\x65\x99\xd7\x31\xb1\xa5\x76\ +\xb9\x3c\x9b\x98\x2f\x8b\xf0\x27\x7f\x2f\x4e\x5b\xf4\x88\x26\xdf\ +\x75\xb1\x9f\x5a\x80\xb5\x21\x05\x68\xab\x9a\xcc\x67\x34\xe9\x16\ +\x05\x24\x23\xc3\x43\xe5\x5c\xbe\x60\x99\xe3\x5e\xd2\xcb\xb4\x58\ +\x36\x6f\x33\x8b\x2b\xe5\x62\x60\xb5\x5f\x6e\xf3\x57\xc5\x66\xb6\ +\xd4\x60\x55\x16\x9f\x2a\x12\x15\x9f\x3c\xa9\x45\xe1\x77\x02\x2b\ +\x8b\x51\xcd\xdd\x8d\xdc\x42\x4c\xd3\xe2\x5c\x93\x29\x0b\xb9\xbf\ +\x75\x2d\xd4\x8b\x5b\x45\xc0\xb2\xd5\xb8\x58\xe3\xc1\xf8\x5b\x1c\ +\xd6\x82\x75\x10\x95\x21\x49\x03\xab\x39\x4d\x0c\x2b\x72\x68\x20\ +\xe4\xbb\x16\xd3\x5a\xc9\xcf\xe0\x32\x6d\xef\x6a\x90\xdb\xca\x5e\ +\x55\x4d\xac\xdf\x6a\x62\x6f\xd5\x8a\xbc\x23\x01\x68\x4c\x55\xfe\ +\x80\x5c\xad\x8f\x6a\x00\x96\x09\x7a\x3b\x53\xce\xdf\x2a\xca\x5e\ +\x92\x6b\xb7\x94\x02\x74\x16\xbf\xec\x5e\x60\xa1\xea\xf4\x62\x3c\ +\x95\x3a\xc1\xaa\x4b\x6e\xdf\x17\x71\xb2\x05\xab\x1c\x91\xf6\x2c\ +\x4a\xba\xd7\xb7\xe4\x62\x7f\xa0\xf8\xd4\x6b\x02\xe4\x9b\x76\xaf\ +\x96\x51\x17\x96\x59\xe0\xba\x7d\xc5\x7c\x66\x2d\x6b\x14\x9b\x0d\ +\xb0\x2a\xcc\x2f\xb7\x41\x0d\xb7\x68\xad\x3c\x10\xbb\xe6\xb6\x94\ +\x41\x69\x35\xef\xdf\xd5\xc4\x38\xa7\x49\x51\xf2\xe2\x7c\xc6\x4e\ +\x2d\xdb\x36\x2a\xb0\x9a\xf2\xb3\x7c\x72\xbb\x6f\xe1\x34\x3f\xb6\ +\x4d\xe6\x69\x8f\xd9\xf9\x13\xa0\x17\x17\xbc\xbf\x1f\xd8\xba\xc0\ +\x46\x63\x13\x79\xb6\xa5\x30\x43\x8b\x4d\x4e\xb3\x34\x29\x4a\x49\ +\x47\x3d\xc9\x07\x63\xa1\xf5\x80\x95\xe9\x98\x9e\x57\xcc\xea\xb1\ +\x05\x58\xee\xac\x16\x0d\x8b\x4f\xbd\xa9\xe7\xf2\xa1\xee\xf7\xcc\ +\x72\x03\x85\x62\x84\x5d\x44\xd5\x1f\xd2\x18\x9f\x25\x2f\x4a\x01\ +\x76\x56\x97\x61\x95\x63\xa0\xe4\xa7\xee\xab\xde\x24\x5f\x4b\x80\ +\x55\xf4\x5c\xbd\xa4\x81\x78\x1d\x17\xa8\xfe\x8e\xd8\xce\x9c\xf7\ +\x33\x03\x3a\xbf\x5c\x89\x05\xae\x2b\x09\x2e\x46\x29\x97\x2f\x5c\ +\x02\x7e\x41\xd4\xb9\xc5\x4a\xf7\xb4\x79\x13\xdf\xf6\x1c\xde\xab\ +\x49\x7d\x21\x65\x32\x54\x3d\x16\xb4\x90\x9c\x61\x76\x89\xcf\xcd\ +\xc0\x79\xa1\x3d\x87\xe6\x2a\x57\x17\x02\x0e\x01\xc1\x46\xc5\xea\ +\xbe\xe4\x31\xab\x8e\x1a\x60\x35\xaa\xb8\xd4\x4f\xc4\xa8\x3e\x14\ +\xab\x9d\x5d\x41\x46\x63\x49\x99\x7d\x29\xf1\x2b\xbb\x6e\xab\x76\ +\x32\x1b\xd8\xd5\xea\x01\x56\x3d\xd4\x78\xad\x99\x0d\x36\x5f\x30\ +\x9b\x49\x98\x2c\xd7\x70\x41\xdd\x4b\x24\x97\x2a\xf9\xfd\xef\x2f\ +\x34\x60\x15\xcc\x3e\x87\x53\x56\xdf\x87\x13\x47\xc6\x57\x6f\x8b\ +\x09\xdd\xa3\x9f\x77\x93\xbc\xed\x23\x53\x03\xac\x88\x2d\x30\x99\ +\xbb\xb8\x47\x99\x3a\x42\x01\x25\xef\x3e\x2e\x64\x5d\xb8\x6a\xad\ +\x2f\xe2\x32\xb4\x3b\x49\x56\xe7\x9b\x4b\x3e\x2a\x66\xfa\xcf\xc0\ +\x2f\xf5\x2c\x56\xa3\x67\x60\x1f\x2e\x41\x72\xbf\x9e\x51\xd2\xf9\ +\x15\xf5\x6c\xc6\x96\xe8\x72\x07\x5b\x22\x60\xc5\x07\x65\x92\x48\ +\xb2\x9e\x81\xdb\x4a\x66\xc1\x72\x4b\x79\x27\xdd\x0f\x13\x06\xf6\ +\x7b\xb1\x91\xbb\x9d\x28\x73\xb8\x6c\xdd\xfb\x72\x89\xf6\x70\xa7\ +\xcc\xa1\x47\x2e\xd2\x1e\xa0\x57\x9a\xac\x24\x41\x6f\xad\xf3\x99\ +\x17\x5f\x59\xe2\xb9\xda\x79\xd4\x2a\xa7\x63\x4c\x6e\x66\xa1\x7b\ +\xa3\xed\x36\x3b\x70\x59\xb7\x4f\x8b\xbd\xf4\xa4\xb8\xb4\xb3\xb8\ +\xa0\xfa\xeb\xc0\x3f\xe2\x2a\xb6\x8e\x8e\x0c\x0f\xad\xb8\x06\xd0\ +\x2b\x29\x74\x88\xe4\x22\x87\xfe\xb3\x1c\x15\x13\x0f\xa2\xd1\x55\ +\x06\xac\x7a\xe2\x14\x99\x35\x06\x58\x13\x44\x92\x83\x6a\x82\x4b\ +\x60\x75\xb0\x4e\x03\xa5\x5c\xbe\x70\xdd\x73\x9d\x2d\x83\x56\xf1\ +\x5c\xb3\xb4\xca\x07\x49\xdf\x9b\x22\x59\x80\xeb\x97\x74\xf1\x33\ +\x6f\xd5\x1a\x71\xb8\x4a\x0a\x23\xb6\xa0\xfc\xa2\x41\x4b\xda\xa8\ +\x7b\x88\xb6\xc4\xb4\xd5\x00\xac\xd9\x3a\xe3\x38\x3d\xb8\x84\xc2\ +\xb3\x38\x41\x6a\xd2\xb6\x17\x13\x7f\x8e\xe2\xb4\x54\xff\x0c\xfc\ +\x0c\xb8\xb4\x8a\x45\x03\x7b\x70\xa2\xd5\x27\x88\xb6\x03\x25\xdd\ +\x7b\x93\xb2\x8c\x85\x18\xd6\xea\xbb\x84\xb5\x4a\x73\x2c\xa5\x6c\ +\x47\x2b\x00\xd6\x24\x2e\x90\x9e\xa6\xf0\xef\x53\xac\xa5\xa2\xc9\ +\xfb\x89\x40\xce\x5c\x81\x59\xa2\xcc\x6a\x26\x16\xeb\xb3\xaf\xdb\ +\x62\x9f\x6d\x82\x4b\xdb\xf6\x92\x04\x26\x56\x1d\x74\x20\xc5\x1d\ +\x81\x28\xbd\x5f\xab\x73\xb7\x55\x9d\xe8\x65\x71\x72\x83\x2c\x4e\ +\x13\xf6\x39\x01\xf6\xa6\x05\x18\x96\x6d\x2c\x5e\x28\xb0\x6f\x1d\ +\x6d\x1e\x52\x7c\xa8\x3d\x05\xfc\x2e\xe0\xb6\x37\xfd\xa3\x62\x56\ +\xab\x06\x56\x62\x57\x5b\x74\x8e\xfb\x6a\xb0\x4b\xdb\x41\xf0\x01\ +\x70\xad\xc1\xcd\x45\xd6\x25\x60\xd5\xca\x02\xae\xb5\x0c\xa1\x4d\ +\xf8\xdb\x68\x2b\x0c\xf3\x33\x7f\xfe\x7d\x1c\x90\x0b\xb3\x8f\x48\ +\x14\x3a\xeb\x81\xd5\xac\x37\x51\xab\x09\xb1\xa3\x38\xd8\x5b\x6d\ +\xa7\x07\x14\xbf\x69\x4f\x59\x20\x3a\x88\xb6\x8e\x54\x6b\xc4\xe0\ +\x6a\x6d\xa9\xea\xf1\x98\x5a\x67\x3d\x2c\x40\x5b\x64\xf6\xe0\xb2\ +\x77\xdf\x90\x5b\x54\x8f\x4b\x58\x33\x56\x26\x10\xdc\x8c\x4b\x26\ +\x6c\x4b\x89\x5b\x95\x71\xc1\xf4\xdf\xe2\x12\x1d\xbf\x00\xae\xae\ +\x32\x18\xf4\x28\x6e\xf5\x6c\x8d\xe7\x53\xd1\xc2\x75\x16\x97\x8c\ +\x09\x4d\x29\x56\x19\xb0\x2a\xd4\xce\x12\xda\x6b\x99\x35\x52\xa9\ +\x41\x52\x83\x71\x9c\x12\xfc\xba\x26\x5d\xd2\x24\x6a\x57\x0c\xab\ +\x47\x2c\xab\xe4\xdd\x87\x12\x77\x66\x4e\xe3\xe0\x9e\x89\xc5\x9c\ +\x0c\x8c\xfc\x26\xa6\x69\x6e\x56\x2d\x99\x89\x01\xee\x0d\xbd\x26\ +\x6d\xa9\xea\x25\x2a\x03\xd3\x47\x8d\x9a\x4d\x5e\xd5\x8a\xfb\x70\ +\x9b\xb6\xbf\x2e\x76\x99\xe6\x12\x11\x73\x77\x3b\x80\xce\x1a\x5a\ +\x24\xbf\xdc\x72\x7f\xc2\x67\x5a\x10\x7b\x14\x27\x04\x7d\x7d\xb5\ +\xc1\x4a\x72\x8b\xfd\x38\x65\xff\x23\x5a\xac\xd2\xce\xf3\x92\xce\ +\xf1\x5d\x42\xc0\xbd\x21\x31\x2c\x3f\x06\x93\x36\x28\xd7\x52\xd0\ +\x1d\x0d\xb4\x8b\x72\x41\x26\x6a\x30\x09\xcb\xc6\xb5\x27\x30\xcd\ +\xa5\xb0\xce\x85\xe2\x81\x26\x93\xb8\x0c\xdc\x4c\x91\x49\x54\x72\ +\xf9\xc2\xa4\x58\xdf\x0d\x01\x5c\x67\x0c\xb0\xba\xc5\x0c\x9f\x01\ +\x3e\xc8\xe5\x0b\xb7\xad\x71\x82\xd7\xb9\xda\xca\x04\x0f\xe0\xb2\ +\x77\x5f\xc0\x15\x03\x3c\x28\x17\x2e\x5b\xc7\xb5\x74\x08\x84\x0c\ +\x80\xd3\xea\xaa\xf9\xd5\x5b\xd3\xae\x7b\x46\xac\xb7\x02\x74\x6b\ +\xdb\x58\x79\xa5\xb3\x82\x72\x05\xb7\x8b\x4d\xbf\x8c\xab\x18\xd1\ +\x93\xc2\x02\xc7\xc4\x02\x7f\x83\xdb\x41\x10\xe4\x0c\x0d\x70\x09\ +\x2b\x35\x26\x91\x7d\x7f\xad\x95\x81\x9d\xc1\x05\xd4\xdf\x14\x9b\ +\xb0\x7d\x79\x99\x25\xc4\xf9\x96\xcb\x2c\x26\x74\x5e\x40\x5a\xab\ +\x02\xc0\x94\x56\xfa\xcb\x62\x59\xfd\x09\x40\xb2\x13\x57\xfd\xe0\ +\x06\x90\xcd\xe5\x0b\x9f\x88\xb9\x59\x65\xd5\x0d\xfa\x9d\x7b\x35\ +\x59\x9f\x13\xcb\xea\xa3\xbe\x6d\x58\xb6\x79\xdb\x04\x96\x59\xd2\ +\x2b\x36\x94\xbd\x85\x2f\xc9\xac\x5c\xce\xb3\x02\xe0\x4f\x04\xc8\ +\x93\x02\xe7\x39\xa2\xe0\xfe\x72\x83\x58\x8f\xc6\xc0\x1f\xe0\x4a\ +\xca\x24\x25\x1a\x4c\x8c\xfb\x81\x58\xe0\x3b\x84\x0a\x0d\x0d\x65\ +\x58\x24\x4c\xc8\xf8\x7e\xb7\x35\xc3\xb0\xb4\x5f\xee\x9a\xa8\xfd\ +\x43\x44\xdd\x61\x3a\x1b\x78\x9d\x65\x9c\x6a\xfe\x34\x6e\xbb\x4f\ +\xad\xd2\xbb\x96\x56\x3f\x27\xb7\x76\x6b\xec\x19\x59\xbc\xec\x20\ +\x51\x1d\xab\xf7\xf5\x99\x06\x56\x5b\x71\x52\x83\x7d\x3a\xb6\x91\ +\x2c\x35\xa8\x35\x76\x7a\x88\x9a\x5c\x2c\x54\x7e\xc8\x2f\xc7\x9c\ +\xc4\xd4\xf6\x88\xe5\x1d\x10\xfb\x1d\xd5\xfd\xb8\x4a\x54\xbf\xea\ +\x16\x30\x9e\xcb\x17\xa6\x3d\xd7\xb9\xb4\x94\xba\xea\x62\x9a\xbd\ +\x02\xa9\xaf\x0a\xb0\x93\x54\xf7\xbe\xcb\xfa\x9a\x8e\x6b\xa1\x96\ +\x7b\x63\x00\xab\x4a\xfd\xb2\x86\x35\x45\x7f\x47\x86\x87\xa6\x72\ +\xf9\xc2\xdb\x9a\xbc\xdd\xb8\x52\xc8\x3b\x3c\xa6\x95\x49\x89\x49\ +\x2d\x87\xc5\x27\x44\x19\x97\xb5\x3c\x89\x2b\x6d\x72\x8e\xda\xf5\ +\xa5\x8a\x62\x20\xef\xe3\xca\xe3\xec\x4d\x70\x0b\x2d\x71\x70\xd0\ +\x73\x79\x66\x89\x82\xf2\xd6\xd7\xaf\xcf\x73\xd7\x32\x75\x8c\x15\ +\xff\x1a\x2c\x1b\xd9\xb7\x80\xbb\x37\x25\xb0\x49\x4b\x24\xd8\x06\ +\xf0\x03\x62\x7d\x26\x3b\xb9\x29\x37\xf1\x06\x4e\x46\x60\xb5\xd4\ +\xad\x20\xe1\x0d\xe0\x66\x2e\x5f\xb0\x86\xc0\x45\xea\x53\xdd\xb7\ +\x69\x91\x7a\x44\x31\xbb\x2f\x92\x5e\x66\xba\xaa\xf3\x79\x4f\x0b\ +\xdc\x59\xd2\xf7\x79\x06\x5b\x05\x97\xb0\xd6\x84\xcc\xdc\x45\xbc\ +\xa6\x15\x6c\x5c\x2b\x66\x55\x13\xe0\x39\x4d\x18\xd3\x09\x65\xbd\ +\xfb\x60\x5f\xb7\x2d\xe0\x22\xa6\xdd\xcf\x6a\xc2\x7d\xb5\xfd\x68\ +\x56\x78\xee\x7b\xb8\x6a\x0d\x13\xb5\x26\x9d\xe2\x58\x13\xb8\xad\ +\x2a\x1f\x88\x25\xf6\x25\x4c\xb8\xac\x07\x48\xdb\x99\xaf\x60\xf7\ +\x8f\x5a\x80\x5c\xf5\xfe\x2e\xfe\x7b\x96\x44\xb0\xca\x11\x69\x21\ +\x87\x09\x31\x94\x2b\x62\xb2\xd9\x1a\xb1\x2e\x8b\x8b\x95\x89\x24\ +\x1c\x33\x1e\xe8\x4d\xe8\xf5\x96\x40\xec\x32\x2e\x81\x72\x4e\xef\ +\xc7\x15\xff\x2a\x31\x3f\xa1\x64\x20\x6e\x1d\x8c\x9e\xc4\x6d\x11\ +\x7a\x99\xda\x65\xa6\x8b\x02\xc8\xdf\xe9\x08\xb1\xab\x06\x03\x56\ +\x2d\x50\x5a\x09\x76\xb1\x68\x13\x7d\xf7\xbb\xba\x18\x2b\x29\xdd\ +\x0d\x35\xd7\xc4\xbf\x86\x4b\xa3\x5f\xc6\xed\x5b\x33\x46\x62\xb1\ +\x9c\x76\x4d\xa2\x1e\x6f\x42\x65\xbd\xc9\x1e\x67\xa0\x69\x31\x41\ +\x5f\xec\x69\xf5\xf1\xcb\x02\xab\x73\xb8\xed\x27\xaf\x03\xe7\xea\ +\x6c\x67\x3f\xad\xbf\x7b\x13\xd7\xfa\x2a\x6d\x5f\x9e\xdd\xbb\x6c\ +\x0d\x96\x57\xcb\x4d\xb5\x6a\x1e\x5d\xcc\x2f\xa5\x62\x9f\x6b\x05\ +\x1e\x6b\x01\xd6\x98\x00\xf9\x63\xb9\x9f\x3b\x48\x97\x75\xf8\x49\ +\x01\x3c\x26\x58\x15\xd8\xd9\xc6\x6c\x93\x98\xdc\xd4\xf1\x91\xd8\ +\xcf\x79\xdd\x53\xdb\x4b\x59\xf1\xc0\xdb\x36\x35\x3f\x28\xc6\xf9\ +\xb4\x16\xa8\xb4\xac\x6d\x85\x68\x23\xfc\xab\xfa\xec\xa0\xbb\x6a\ +\x70\x0c\x6b\xa1\x6d\x27\x55\xee\x6e\x5f\x5a\xbd\xa0\xd4\x16\x8b\ +\x97\xf9\x65\x54\x36\x78\xae\x07\x44\xd5\x08\x6e\xe6\xf2\x85\xe9\ +\xbb\x11\x17\xaa\xfe\xd1\x38\x2e\x90\x7a\x1e\x27\x5c\x1c\xd0\x44\ +\xb1\xff\x6f\x52\x84\x3e\x0f\xc0\xe2\x0c\xcc\x26\xb8\x65\xcb\xb2\ +\xdc\xa9\x78\x9f\xf3\x62\x50\xa6\xa7\xba\xae\x98\xcd\xc7\xc0\xad\ +\x7a\xb7\xa0\x08\x6c\xaf\xcb\x8d\x7c\x03\x27\x61\xe8\xa9\xc1\x14\ +\xea\x7d\x7e\xf1\xae\x3a\x63\xfa\xfe\x3d\x09\x80\x98\xd5\xff\xeb\ +\x23\xa5\x15\x9c\xee\xef\xa4\xee\xef\x8f\x89\x4a\xc9\x6c\xf2\x40\ +\x6e\xa1\xf3\xcd\xc6\x40\xc7\xbf\xa7\xbb\x04\x4c\x87\x74\x2f\xad\ +\x24\xd0\xa4\x40\xbd\xec\xcd\x0d\x6b\xfc\xb1\x53\xe0\xb7\xa9\x46\ +\xdc\xd2\x4a\x08\x7d\x2c\xb0\x7a\x07\x98\x0c\xec\xaa\xf1\x31\xac\ +\x4a\x4a\x9c\xa2\x1a\x5b\x69\xaa\x4b\x04\xa2\xb8\x2b\x11\x5f\x41\ +\x0d\x00\xac\x31\x83\x65\xbc\xba\x35\x01\xb7\x69\x50\x5a\x50\x78\ +\x56\x14\xfd\x2c\x2e\x40\x7d\x7e\x81\x52\x2c\x75\x81\x16\x30\x23\ +\x57\x62\xcc\x63\x72\xc6\xa4\x3a\x98\x5f\xd2\xa5\x2d\x36\x91\x32\ +\xcc\xaf\xe6\x50\x21\xbd\xf4\x0b\x5e\x2c\x67\xce\x73\x79\x96\xc2\ +\x16\xe7\x74\x0f\x5e\xc1\xe9\x88\x2c\xf3\xd7\xb9\x48\x80\xb2\xc3\ +\xda\x62\x59\x91\xbc\x53\x72\xe5\x1e\xc0\xdb\x5b\x19\x73\xe3\x2c\ +\xf0\xde\x99\x16\xeb\x54\xc5\x8a\x51\xdc\xe6\xef\x76\x01\xc1\xfd\ +\x5e\xcc\xb0\xa3\x4e\xf7\x34\x29\x29\x94\xf5\x5c\xd3\xcd\xba\x0f\ +\x76\x5f\xe3\x5b\xa8\x6c\x01\xea\x62\x7e\x77\xe8\xa4\x7b\x62\xca\ +\xfb\x5f\x10\xed\x67\x0c\xec\xaa\x09\x5c\xc2\x7a\x75\x58\x69\x60\ +\x94\x49\x70\x8f\xfc\x36\x61\x1d\xde\xe0\x68\xf7\xdc\x2a\xd3\xe6\ +\x6c\x20\x6a\xe4\x60\x85\xee\x6c\xe5\xee\xd2\x20\x1c\xf0\xd8\x4d\ +\xd1\x8b\xf9\xfc\xca\x26\x7e\x2e\x5f\x98\xba\xdb\xcc\x8d\x80\xcb\ +\x5c\x8e\xf8\x35\x26\x6d\xb7\x81\xbb\x4b\x48\x54\x97\xa1\x3a\xe6\ +\x84\xe2\x5e\x26\x76\x34\xa5\x76\x37\x0b\x97\x1a\xae\x78\xee\x95\ +\x55\x1f\xb8\x46\x54\xad\xf4\xa4\xc7\x70\xd3\x54\xf5\xf1\xfa\xf2\ +\x95\x94\x73\x9d\xc9\xe5\x0b\x1f\xe8\x7f\x5d\x21\x92\x51\xec\x15\ +\xd3\xd9\xe8\xc5\xe1\x92\x8a\x46\xd6\x93\x18\xb2\xb1\xd6\x9b\x12\ +\xe6\xc8\xc4\x7e\x9f\x1a\xcc\xea\x92\x80\xea\x7b\xba\x17\x41\xc6\ +\xd0\x44\x0c\xab\x96\x0e\xcb\xd8\x50\x77\x2e\x5f\xd8\x18\x8b\xdf\ +\x74\x6b\x80\xf5\xc4\x56\x2d\xeb\x82\xdc\xe7\x1d\x56\x6e\xd7\x7e\ +\xb7\x9b\x48\x01\xbd\x5d\x93\x62\xc0\x1b\x74\x19\x8f\x7d\xf9\xab\ +\x61\x45\x83\x7c\x80\xa8\x44\xf1\xb5\x58\xbc\x62\xd9\x2c\x56\xa9\ +\xa1\xe9\x56\x58\x49\x34\x2e\x8b\x65\x19\xfb\x7c\x54\x2e\xcf\x06\ +\xa2\xca\xa4\x6d\x1e\x50\x19\x48\x4d\x2a\x46\x33\x26\x26\x75\x51\ +\xb1\xa0\x73\x02\xad\x5b\xb8\xcc\xdd\x98\x77\x7f\xb3\xb1\xb1\xd1\ +\xeb\x2d\x28\x59\x6a\x54\x2f\x10\x68\x9d\xd1\xf3\x7a\x5f\x6c\xc8\ +\x40\xcb\x62\x5b\x36\x16\x7a\x63\x31\xc3\x6c\x6c\x51\xac\xc5\xc0\ +\xee\xa6\xac\xce\x34\x4e\x07\xf6\x53\xe0\x1f\x14\x57\xbc\x19\x5c\ +\xc1\xe6\x00\xac\x78\x19\x92\x4c\x02\x58\x6d\x50\x90\x72\x52\x00\ +\xe1\x03\x94\x35\x02\xdd\xc4\xfc\x92\xba\x5d\x1e\x38\xf5\x7a\xc0\ +\xd6\xe9\x01\x90\x1d\xdd\x5e\x40\x37\x9b\x12\x34\x26\xe6\xaa\xb6\ +\xcb\x4d\xdc\x47\x72\x6d\xa9\x75\x65\xaa\xb7\x75\x41\xcf\xe7\x3c\ +\x2e\x5d\x7f\xaf\xee\x51\x3f\xf3\x55\xe6\x7e\xf1\x39\x6b\x2a\x7a\ +\x45\x8c\xe2\xaa\xd8\xab\x75\xb8\x86\x48\x5e\x30\xc5\x9d\x75\xb6\ +\x32\xde\x38\xd8\xa8\xe7\x39\x53\xc7\xb9\xda\xb6\xa2\x33\x38\xe5\ +\xf8\x36\x01\xec\x1e\x1d\xd6\x46\x6c\xb3\xce\x7f\x83\x0e\x6b\x37\ +\xd6\xc1\xdd\x95\xcf\x49\xf2\x22\xac\x8a\xc7\x27\xb8\x82\x81\xdf\ +\xc5\x29\xda\x6f\x06\xcd\x55\x73\xb9\x84\xb5\x56\xa5\x4e\xad\x7e\ +\x5f\xc4\xa5\x81\x8b\x1e\xeb\x31\x20\xea\x67\x7e\xa3\x8a\xac\xf7\ +\x6a\x71\x9f\x6c\x82\xcb\x98\x74\xd4\x7b\xbe\x19\x92\x4b\x04\xb3\ +\x8e\x41\xab\xa4\x8c\xe7\x6d\x31\x24\x6b\x7c\x61\x93\xdc\x9e\xc3\ +\x9c\xd8\xd2\x84\x77\xd8\x46\xea\xa2\x8e\x8a\xdc\xcd\x8c\x18\x87\ +\x75\x4e\x2e\x27\x3c\x0b\x4b\x4a\x18\x9b\xab\x97\xb5\xce\xe5\xf2\ +\x05\x6b\x2a\x61\x9d\x98\xfb\x05\x7c\x5b\x04\x82\x9b\x15\x22\xd8\ +\x2a\xe6\xb5\x9b\x28\x60\xee\x27\x46\x96\x52\xfe\xc8\x4f\x2e\x4c\ +\xeb\x1c\xce\x88\x59\xfd\x0c\xf8\x57\x60\x3c\x30\xab\xe6\x03\xac\ +\x6a\x0d\x77\xb0\x5d\x03\x65\x80\x48\xd3\xe2\x37\x03\x6d\xaf\x23\ +\xde\x70\x37\x19\xab\xb4\xf3\x9d\x23\x12\x0e\x4e\x90\xde\xa6\x6c\ +\xbd\x81\x56\x15\x98\x56\xf2\xe0\xba\xb7\x60\xf8\x93\xda\x0f\xae\ +\x9b\xb4\xa2\x92\x34\x31\x05\x5a\x73\xba\xc7\xd3\x29\x80\xe5\xb7\ +\x82\x6b\x5f\xc2\xf9\x96\x81\xb2\xce\x79\x42\xc0\x91\xf5\x18\x79\ +\x8f\xc7\xe2\x77\xc8\x45\xbd\x1f\x27\x3f\xd9\x26\x30\xeb\xf2\x58\ +\x64\x1b\xb5\x77\x66\x54\x3d\x97\x78\x42\xee\xee\x05\x5c\x82\xe1\ +\x37\x3a\x2e\x8e\x0c\x0f\x4d\x04\x38\x69\xce\x18\x56\xb5\xc6\x64\ +\xcf\x7a\x2e\x5e\x1a\xc8\xad\x86\x46\xcb\x3f\x4f\x9b\x8c\x1f\xe0\ +\x52\xcd\xe7\x14\x87\x69\xe9\x0c\x8e\xa7\x35\xb3\x85\xc0\x6f\x6d\ +\x55\x59\xcc\x4a\x2f\x17\xc6\xd8\x83\x9f\x38\x80\xc5\x07\xfa\x8b\ +\xdc\x29\x11\x88\x8f\x11\x73\xff\x97\xcc\x78\x7d\xf0\xd2\x39\xcf\ +\x78\x61\x8b\xb8\xc4\x65\x87\xe2\x5f\x0f\xca\x7d\xdc\x29\x96\xd7\ +\xef\x85\x23\xb2\x09\xa1\x84\xaa\xc7\xa8\xac\x0b\xcf\x27\x38\x01\ +\xee\x69\x8d\xa5\x89\x3a\x75\x70\xc1\x1a\x00\x58\xb5\x1a\x32\xac\ +\x14\x43\x8a\x03\x11\x09\x03\xcb\x1f\x60\x65\x6f\x45\x34\xf7\xe1\ +\x03\x5c\x30\xf4\x55\xad\x8e\x33\xad\x1a\x67\x50\xbd\x28\xdb\xe2\ +\x62\xb1\xa0\x4e\x31\x20\x63\x00\x13\xb9\x7c\x61\x76\xa9\xd7\x78\ +\x97\x25\x9e\xad\x6e\xfb\x4c\x8c\x65\xfb\xcf\xcd\xb2\xbe\xed\xcb\ +\xd5\xf2\xca\xfb\x8c\xdf\x2b\xde\x05\x62\x13\x38\xc9\xc5\x07\x62\ +\x43\x1b\x89\x24\x17\x1b\x05\x68\x3d\xde\x62\xeb\x8b\x9f\xcb\x1e\ +\x00\x8f\x69\xe1\xb3\xfd\x8a\xb7\xb9\xcb\x9e\x86\xc1\x56\x87\x61\ +\xcd\xe9\x01\x16\x59\x3e\x81\x68\x35\xe5\xeb\x38\x18\x55\x13\xbe\ +\x67\xec\xc0\xb6\x63\x8c\x6b\x35\xb4\xfd\x64\xe7\x70\xca\xe3\xf7\ +\xb5\x3a\xb6\xdc\x8a\x28\x91\xac\xb1\x92\x9d\x3a\x0e\x10\x05\x9b\ +\xdb\x88\x3a\x1b\x9f\xd1\xea\x7f\x45\x22\xd9\xd5\x06\x66\xab\xdb\ +\x6e\xdb\x5d\xe2\xe6\xc7\x2b\xdb\x58\xc1\x7d\xa7\x1e\xf0\x56\x04\ +\x60\x96\x25\xf6\x93\x39\x96\xad\x4e\xda\x0b\x6a\x7f\x6f\x2a\xf9\ +\xdf\x57\x81\x08\x40\xd5\x1a\x80\x55\xd4\x4a\x73\x59\x2b\xd7\xa6\ +\x3a\x68\x7d\xb5\x06\x28\x55\x13\x80\xc7\x18\x52\xd1\x7b\x5f\x62\ +\x7e\xc9\x90\xa2\x06\x94\xb1\xbd\x09\xc5\xa8\xae\x13\xb5\x81\xb7\ +\xf7\x97\xf5\x6a\x2b\x62\xb9\xc5\xc0\xca\xb6\x87\xec\xc7\x09\x32\ +\x0f\x09\xac\xf6\x0a\xac\xac\x16\xd3\xa4\xd8\xe3\x5b\x44\x55\x43\ +\xaf\xe4\xf2\x85\xd5\x66\x01\x55\xef\x59\x95\x53\xc0\xa8\x21\x49\ +\x10\xef\xd9\x97\x62\x6e\x2f\x29\xc0\xe9\x7f\xaf\x1a\x40\xaa\x35\ +\x01\xcb\x1a\x55\x5a\x66\x69\x80\x3b\x83\x96\x3e\x08\x95\x3d\xf0\ +\xf1\x2b\x70\x96\xbd\x55\xcb\x5f\xbd\x8c\x29\x4d\x7b\xc7\x9c\xf7\ +\x7e\xca\x5b\xbd\x2d\x53\x75\x93\x28\x9d\x3e\xa9\xf7\x7e\x49\x91\ +\x62\xab\x0d\x36\xaf\x42\xc0\x01\xe0\x30\x2e\xeb\x7a\x50\x40\x65\ +\x2e\x8d\xdf\x69\xb9\x24\xc6\xd5\x29\x80\xbe\x44\xed\x8a\x07\x2b\ +\x69\xe5\x1a\x60\x05\xb5\xc5\xc7\xab\x05\x5e\x0d\xfd\xff\xc1\x56\ +\x07\xb0\xac\xba\xe5\xdb\x38\xfd\x4b\xb7\x26\xd4\x06\xe6\x57\xd9\ +\xf4\x63\x48\x37\x88\xea\xa1\xcf\x79\x87\x81\xca\x6d\xef\x67\x53\ +\x02\x1c\x3b\x0c\xac\x8a\x1e\x98\x15\x3d\xd6\x55\xf4\xe2\x6a\x15\ +\x0f\x18\xab\xad\xba\x22\x7a\x9d\x84\xf7\xe2\x04\x9d\xcf\xe3\x36\ +\xdd\x3e\x80\xcb\xc0\xf6\x7a\x2e\x8c\xcf\x12\xec\x7b\xf7\xe8\xa8\ +\xb5\xef\x6d\x35\x58\xd6\x42\xdb\xb3\x32\x61\xfa\x05\x5b\x8d\x18\ +\xd6\x84\xe2\x41\x1d\x02\xa3\x87\x70\x3a\x17\xab\xbf\x6d\x35\xc4\ +\xc7\x88\x0a\xab\x8d\x11\xed\x86\x9f\xf6\xe2\x60\x16\x9c\x2d\x31\ +\xbf\x3c\x88\xdf\xb4\xc1\x77\x1b\xcb\x35\x5c\x4c\x5a\x9d\xb2\x2b\ +\xa0\x3e\x20\xa0\xfa\x0c\xae\x02\xe8\x21\x22\x41\x67\x07\xb5\x35\ +\x44\xfe\x9e\xcb\x46\x59\xbd\x71\xcd\x2c\x41\x17\x17\x6c\x25\x01\ +\xcb\xd3\xd9\x5c\xc1\xed\xf8\x1f\xc5\xd5\xfc\xb1\x58\x0a\x44\x1d\ +\x5a\xe2\x2a\xe8\x72\xcc\x45\x34\xd7\x30\x71\x4f\xe2\x7a\x8b\x17\ +\xa8\xb1\xc1\x6e\x5c\xe3\xd0\xa3\xb8\x3d\x7e\x7b\x89\x04\x96\x0b\ +\x69\x85\xca\xde\x7d\x37\x65\x78\x23\xdc\xc1\xaa\x07\x9e\xb5\xb6\ +\x6f\x11\x5c\xb2\x60\x2b\xcd\xb0\x0c\xb4\x4c\xdb\x34\x81\x2b\xa7\ +\xd1\xe9\x0d\xc0\xa2\xe7\xc2\x19\x30\xad\x5b\x20\x5a\x04\xb3\xda\ +\x8d\x2b\x0e\xf7\xc7\x02\xab\xed\x44\xcd\x51\x17\x2a\x96\x57\x94\ +\xdb\xfd\x31\x4e\x71\xfd\x9e\x5c\xf7\x99\x06\x80\x42\x7c\x73\x7b\ +\xda\xef\xac\xa5\x66\xbb\xc1\x9a\x15\xb0\x3c\xd7\xab\x84\xcb\xb6\ +\x4c\x73\x67\xc0\x9d\x00\x4c\x75\x83\x55\x86\xa8\xa7\xe1\x37\xe4\ +\x0a\x5a\x0d\xa8\x85\x18\x95\x69\xaf\xae\xe1\xb6\xaa\x58\xad\xab\ +\xf7\xc4\xb2\x1a\x91\x6c\xf0\x77\x36\xa4\x81\x56\x18\x1b\xc1\x56\ +\x0f\xb0\x12\xc0\x2b\x0c\xc0\xa5\x5b\x07\x2e\x71\xf1\x22\xae\xde\ +\xfa\x56\xd2\xab\x71\x1a\x50\x4d\xe3\x32\xa2\xd6\x58\xe2\x34\x4e\ +\x18\x79\x8a\xa8\xd1\xc4\x74\x83\xc4\xb1\xa6\x19\xeb\x4d\xb8\x0e\ +\x5f\xeb\xb4\x60\x53\xd5\x60\xc1\x96\x1d\xb0\x82\x2d\x0b\xbb\x7a\ +\x54\xc7\xf6\x05\xc0\x6a\x56\xcc\xe9\x63\x9c\x18\xf6\x6d\xdc\x36\ +\x11\x03\xa9\x5b\x44\xc5\xfd\x1a\xb5\x88\x74\x10\x95\x7d\x49\xab\ +\x66\xea\x37\xe4\x0d\x8b\x5d\xb0\x00\x58\x2d\xc4\xae\xb6\x03\x0f\ +\xe3\x84\xa1\x3d\x35\x5c\x28\x6b\xe6\xfa\x26\x51\x75\x80\x8f\x04\ +\x60\x56\xca\xa5\xd2\x48\x57\x5c\xda\xb1\x1d\x38\xdd\xd8\x3e\xa2\ +\x18\x5c\x12\x60\x15\xa9\xdd\xb1\x3a\x58\xb0\x00\x58\x4d\xc6\xae\ +\xac\x55\x95\x95\x14\xce\xd6\x60\x56\x17\x71\x2d\xbd\xbe\x87\xdb\ +\x13\x77\x0d\x98\x6a\x32\xe5\x7e\x17\x4e\x86\xf1\xd4\x02\xd7\x63\ +\x6e\x6d\xd8\x8b\x17\x6c\xd1\xf1\x86\x60\x8d\xbb\xf7\xfd\x38\x8d\ +\xd5\x6e\xd2\x3b\x28\x5b\x17\xe1\xb3\x38\x09\xc9\x69\x9c\xae\xad\ +\xa9\xc0\x4a\x00\xbc\x13\x27\x72\x3d\x50\x83\x2d\x5a\xab\xb2\x69\ +\x92\xf7\x1a\x06\x0b\x16\x18\x56\x93\x02\x96\x35\x81\xe8\x21\xb9\ +\xe5\x96\x5f\x23\x7f\x00\x78\x42\x93\x7c\x13\x70\x26\x97\x2f\x5c\ +\x05\x66\x9b\x04\xb8\x3a\xe5\xd6\x1e\x24\xaa\xb3\x9f\xc4\xae\x8a\ +\x44\x1b\xd3\x43\x83\xd1\x60\x01\xb0\x5a\xc8\x4c\x47\x95\xa6\x4e\ +\x37\x79\x40\x3f\xae\x96\xd3\x16\xbd\xbe\x8f\xab\xed\xf5\x36\xf0\ +\x49\x2e\x5f\xb8\x88\x2b\x99\xd3\x48\xc6\xb2\x51\x60\x75\xbf\x5c\ +\xdd\x34\x76\x35\x8e\xab\x9a\x71\x29\x00\x56\xb0\x00\x58\xad\x63\ +\x7e\xad\xf4\xeb\x9a\xbc\xb5\x1a\x9b\x6e\x14\x10\x6c\x93\xcb\xf5\ +\x84\xdc\xaf\x53\xb8\x40\xfc\x47\x56\xa7\x7d\xb5\x19\x57\x2e\x5f\ +\xe8\xc1\xc5\xe1\x9e\xc5\xed\x31\xed\x48\x01\xe7\x19\x81\xd5\x6f\ +\x70\x95\x25\x42\x1b\xac\x60\x8b\xb2\xcc\x5f\xfe\xc5\x9f\x87\xbb\ +\xd0\x20\x53\x57\xa1\x4f\x01\xdf\x02\x06\x71\x9b\x96\xd3\xa4\x00\ +\xfe\xc4\x2f\x79\x60\x77\x11\x27\x6b\x78\x03\x17\xe3\x3a\x85\xdb\ +\x3a\x35\x09\x94\x57\x3a\xa8\x9d\xcb\x17\x4c\x47\xf6\x75\x5d\xc7\ +\x21\x5c\x3c\x2e\x7e\x0d\x45\x5c\xbd\xae\x7f\x00\xfe\x1a\x78\xa7\ +\x59\xeb\x92\x29\x1e\xe7\xf7\x3d\xac\xb4\x72\x8f\x41\xaf\xd7\x67\ +\xcb\x0b\xba\x03\x60\x35\x76\x20\xb5\x0b\xa4\x5e\x00\xbe\x86\xcb\ +\xae\xed\xa1\xbe\x66\x09\xe6\x4e\x9a\xda\xfd\xbc\xdc\xc4\xdf\xe2\ +\x14\xef\x1f\x1a\x70\xad\xd4\x64\xcb\xe5\x0b\xd6\x74\xe4\x2b\xc0\ +\x9f\xe0\xe4\x0c\x9b\x13\x5c\xdc\x0a\x4e\xe8\xfa\x0a\xf0\x57\xc0\ +\x8f\x46\x86\x87\x6e\x35\xe1\xf3\x68\xc3\xc5\xe2\xac\x19\xc7\x06\ +\xa2\x2a\x22\xd7\xc5\x5e\x4b\x2d\x34\xbe\xac\xa9\xaf\x75\x0d\xb2\ +\x92\xe1\xa5\x56\xad\xb8\x9b\x1d\x7c\xf1\x85\x80\x1c\x0d\xb2\x13\ +\xc7\x8f\x55\x06\x8f\x1c\x9d\x22\x2a\xc3\x63\x4c\xc4\x40\x2a\xde\ +\x39\x28\xee\x2a\x5a\xed\xf2\x1e\x5c\x50\x7e\xb7\x00\x64\x17\x51\ +\x6b\xf7\xd2\xe0\x91\xa3\x73\x83\x47\x8e\x96\x4f\x1c\x3f\xb6\x12\ +\x60\xf5\x25\xe0\x9b\x72\x51\x37\x27\x84\x19\xac\xa0\xdf\x69\xe0\ +\xfb\xb8\xf6\xf3\x57\x4e\x1c\x3f\x56\x6d\xc2\xc9\x6d\xf5\xc7\x5e\ +\x02\x3e\x87\xdb\xdb\xf9\x98\xdc\xdd\x6e\x60\x6e\xf0\xc8\xd1\xe9\ +\x13\xc7\x8f\x95\x9b\x1c\xa8\x32\x83\x47\x8e\x76\xe1\x92\x1f\xf7\ +\xe2\x7a\x39\xee\x27\x6a\xc0\x51\x1e\x3c\x72\xb4\xd2\xec\xd7\x11\ +\x18\x56\xf3\x0e\xb0\x0e\x4d\x96\x83\x38\x11\xe9\xe3\x7a\x7f\x00\ +\x27\xc4\xec\x23\x6a\xcf\xbe\x50\x77\x97\x69\x81\xdf\x27\x62\x5c\ +\xbf\xc1\x55\x21\x3d\x23\x96\x73\xd7\xda\x27\x55\x41\xdd\x03\x7c\ +\x19\xb7\xff\xf1\x19\x22\xdd\x55\xfc\xfc\xca\xb8\x8d\xd8\x3f\x01\ +\xfe\x06\xf8\xf9\xc8\xf0\xd0\x78\x13\xba\x4c\x9b\x74\xdf\xbf\x20\ +\xc6\x7b\x00\x17\x33\xac\xea\x7e\x9e\x05\x7e\xa0\xeb\xf8\x70\x64\ +\x78\x68\xa6\x89\x19\xd5\x80\x00\xea\x61\x5c\xf9\xa7\x6d\x02\xdc\ +\xeb\xb8\xd8\xe1\x6f\x71\x5b\xb9\xae\x8d\x0c\x0f\xcd\x05\xc0\x0a\ +\xb6\xd4\x49\x63\x4c\x69\x9f\x00\xeb\x71\xad\xf0\xf7\xe3\x14\xf1\ +\xfd\x75\x00\x57\xc5\x03\xae\x6b\x9a\x68\x6f\x6b\x90\xbe\x87\xcb\ +\xce\xdd\x24\xaa\xc6\x5a\xb7\x3a\x3e\x26\x76\x7d\x59\x6e\xec\x93\ +\x44\xfb\x1f\x33\x09\xe7\x72\x5b\x2e\xea\xdf\x00\xff\x0c\x9c\x6f\ +\x86\x78\x90\x17\xa7\x82\x48\xf0\xfa\x4d\x5c\x2c\xee\x01\xa2\x66\ +\xbb\x26\x74\x1d\xd7\x02\xf0\xbf\x70\xe2\xdd\x4f\x9a\xc5\x3d\xd4\ +\xb5\x74\x6a\xec\xdc\x23\xd7\xfc\x69\x8d\x9f\x3d\xfa\xbe\xf5\x8c\ +\xfc\x18\x78\x4d\xe0\xfb\x5b\xe0\x46\x2b\xc5\xe7\x02\x60\x35\xe7\ +\x2a\x69\x5d\x71\xf6\x7a\x8c\xeb\x51\x51\xfb\x5d\x75\x00\x97\xdf\ +\xa2\xca\x6a\x64\x9d\xc3\xc9\x21\x3e\xd0\xfb\x4b\x44\x25\x82\x26\ +\x89\x8a\x28\x9a\xbb\xe9\x37\x63\xb0\x4e\x37\xc6\x02\x5f\x92\x2b\ +\x78\xa8\x06\x58\x55\x35\x41\xce\x02\xff\x04\xfc\x5f\xe0\x5f\x47\ +\x86\x87\xa6\x9a\x60\x72\x5b\x0b\x30\x2b\x31\xbd\x55\xd7\xf3\x1f\ +\x71\x71\xc4\x9e\x14\xf0\xbd\x77\xa7\x7a\xad\x00\x00\x0c\x84\x49\ +\x44\x41\x54\x01\xfc\x4a\x71\xb8\xe3\xc0\xad\x46\x07\xb1\x75\x3d\ +\x7d\x38\x3d\xdf\x13\xc0\x73\x62\xbc\x0f\xe9\xba\x7a\x89\x62\x8a\ +\x15\x3d\xef\x93\xc0\xff\xd3\x02\x72\xaa\x19\xd9\x62\x9a\x05\x59\ +\x43\x93\x99\x82\xa1\xd6\xdc\xf4\x16\x51\x30\xfd\xa0\x07\x5c\x36\ +\x18\xad\xc5\x57\x36\x16\xe7\xb2\xf7\x16\x40\xee\x13\x43\x7b\x00\ +\x57\xe1\x61\x54\xae\x81\x1d\x56\x15\x36\xae\x3e\xb7\x4c\xd9\x66\ +\x9c\x06\xec\x90\xce\xe1\x19\xb1\x40\x2b\x8d\x9d\x04\x56\x45\x5c\ +\xd0\xff\x55\xc5\xad\xde\x6d\x12\xb0\xf2\x7b\x15\x6e\xd3\xfd\xb9\ +\x57\xee\xed\x21\xd2\x15\xfa\x26\xde\x7d\x08\x57\xb6\xfa\x94\x16\ +\x83\x46\xb3\xac\x1e\x3d\x8b\xcf\x08\x74\x9f\x12\xcb\xea\x4b\x78\ +\x36\x6d\x1a\x33\xd6\xcc\xe4\x77\xc0\x05\xb5\x84\xab\x06\xc0\x0a\ +\x76\xb7\xc0\x35\x23\xe0\xba\x29\x56\xf4\x36\xf0\x88\x40\xeb\x09\ +\xc5\x29\x76\x6b\x10\x26\x65\x16\xfd\xba\x54\x36\x51\x77\x11\xb5\ +\x43\xbb\x21\xf6\x75\x93\x48\x0a\x61\xfd\x04\xad\xb6\x7c\x8f\xfe\ +\xc7\x16\x4d\x6c\x6b\x0b\xef\x37\xc0\x48\x02\xab\x6b\x38\x7d\xd8\ +\x77\x71\x92\x8b\xdb\x4d\x32\xde\x37\xc8\xc5\x7e\x42\x8c\x75\x9f\ +\xd8\xc9\x61\xcf\x75\x4a\xb3\xac\x7e\xf7\x21\xb9\xc5\x9f\xe8\xde\ +\x35\x0a\x80\xad\xd3\xfa\xb3\xc0\x1f\x89\x5d\xed\xa6\x76\x2d\x7f\ +\xdb\x61\xb1\x47\x7f\xdb\xc9\x0a\xb6\x5a\x0b\x80\xb5\xfe\x80\xab\ +\x0a\xcc\x7a\x2d\xe0\x47\xbd\x98\xd4\x41\x2f\xc6\xb5\x4f\x60\xd2\ +\xc7\x9d\xf5\xd2\x7d\xb7\xae\x43\x20\xb4\x59\x2b\xb1\xa5\xed\x93\ +\x9a\x9f\xda\xef\xf6\x10\xd5\xb7\x6a\x5f\xc0\x15\x9d\xc5\x05\xd9\ +\xdf\x04\xbe\x0d\xfc\x1a\xb8\xd9\x24\xae\x53\xa7\x00\xe7\x49\x5c\ +\x70\xfd\x30\x91\x84\xc1\x77\x9d\x52\x43\x28\xba\x17\xfb\x05\x76\ +\x6f\xe6\xf2\x85\xf1\x06\x4a\x04\x7a\xc5\x96\x3e\x2b\x66\xb5\x10\ +\x58\xd9\x35\xb4\xeb\x6f\xfb\x88\xaa\x05\x07\x97\x30\xd8\xb2\x03\ +\x57\x31\x97\x2f\xdc\x90\xab\x78\x49\xc0\xf5\xa6\x58\xd7\x93\x62\ +\x5e\x06\x5c\xdd\xdc\x99\xb5\xcb\x78\x4c\xc1\x9a\x99\x76\x69\xc2\ +\x9a\xae\x2b\x3e\xb8\x6b\x49\x2b\xe2\x60\x35\x23\x40\x7d\x43\x60\ +\xf5\x0b\x60\xb4\x49\x82\xd3\x6d\x02\x9b\xed\x02\xf8\xc7\x05\x3a\ +\xdd\x2c\xae\x64\x73\xbb\xdc\xc9\x07\xf4\x7a\x95\x06\x6c\x31\x52\ +\x59\xed\xcd\x72\xed\x1e\x16\x10\xd7\xdb\x25\xe9\x8e\x0a\xc1\x01\ +\xb0\x82\xad\x24\x70\x95\x71\xed\xe8\x2d\x13\x78\x46\x71\xae\xa7\ +\x71\xca\xf9\x87\xc5\x9e\x16\x6a\x60\x91\x49\x19\xbc\x8b\xad\x02\ +\x6a\xdb\x8c\x2e\xe2\x82\xd2\xdf\x05\x7e\x0e\x5c\x69\x32\x35\xbb\ +\x75\x25\xda\x23\x37\xba\x9b\xc5\x77\x19\xca\xe8\x6f\x0f\xc8\xbd\ +\x3e\x45\x63\xf6\x44\xb6\xe3\xe2\x98\x07\x70\xc9\x99\x9e\x45\x3c\ +\x37\x1b\x43\xd6\x36\xaf\x65\x40\x2b\x00\x56\x6b\x83\x57\x09\xb8\ +\x9d\xcb\x17\x66\x04\x5c\x17\x70\x45\xfd\x9e\x15\x83\xf0\xe5\x10\ +\x5d\xdc\x19\x9c\xaf\xb5\xf2\x2e\x66\xe0\xdf\xd6\xff\xfe\xa5\xc0\ +\xea\xf5\x26\x62\x56\x71\x60\xb5\x06\x29\x4b\x2d\xad\x94\x11\xd0\ +\xed\x14\x50\xf4\xd1\x98\xf8\x5c\xa7\x18\xd6\x4e\x81\x70\x76\x91\ +\xf7\x61\x06\x17\xb3\x6c\xa9\x9a\x64\xa1\x1e\xd6\x1a\x01\xae\x91\ +\xe1\xa1\x09\x31\xad\x9f\xe1\x24\x04\xff\x07\xf8\x8e\xbe\x3e\x89\ +\xcb\x36\xde\xf4\x56\x55\xbf\x44\x71\x75\x89\x93\x7f\x06\x17\xaf\ +\x7a\x4b\xff\xeb\xef\x05\x5a\xcd\x0a\x56\xd3\x72\xa7\xc7\xf5\xba\ +\x54\xfd\x91\x05\xef\xb7\x02\xbd\x92\xa2\x34\x82\x2d\x76\x09\x30\ +\xbb\x16\xb9\xd8\x58\x13\xe2\x49\x81\x77\xcb\x58\x00\xac\xb5\x05\ +\x5c\x45\x9c\x3c\xe1\x5d\xe0\x87\x02\x90\xff\xa1\xd7\xef\xe3\xf6\ +\xf2\xbd\x8d\xd3\x46\x5d\xd5\xc4\x9d\x26\x2a\x57\x5c\xf6\x8e\x0a\ +\xf3\x1b\xd9\xc2\x7c\x7d\xd7\x2d\xdc\x76\x9b\x1f\x02\x7f\x0b\xfc\ +\x1d\x2e\xc0\x7e\xb5\x19\xf7\xdb\x59\xf2\x82\xa8\x15\xda\x28\x2e\ +\xd9\xb0\x14\xb0\xb6\x00\x7e\x0f\x8d\xed\xae\x9d\x5d\x82\x4b\x6b\ +\xcf\xcf\xfa\x86\x16\x5b\x69\x8c\x07\x97\x70\xed\x81\x56\x15\x27\ +\x87\x28\x32\x5f\x0e\xb1\x1b\x17\xd7\xda\xa7\xf7\xbb\xe5\x52\x6c\ +\xc2\x65\x8c\x7a\x35\x1e\x2c\x0b\x68\x5d\xa4\x3b\xbc\xf7\x25\xad\ +\xc8\x57\xf4\xb9\xbf\x14\x48\xbd\xa7\x09\xd0\xd4\x7a\x9e\x91\xe1\ +\xa1\x62\x2e\x5f\xb8\xae\xfb\xf1\x06\x2e\xdb\x67\xdb\x9e\x16\x3b\ +\xe9\xe3\x40\xbe\xda\x36\xa7\x45\x63\x4c\x4c\x77\x63\x9d\xc0\x69\ +\x5b\x8d\x2e\xe8\x6f\x03\x60\x05\x6b\x8a\xc9\x59\x06\xca\x31\x39\ +\xc4\xbb\x8a\x77\x98\x10\x74\x97\xf7\xbe\x8f\x3b\xa5\x0b\x5d\x44\ +\x5a\xac\x8c\x98\xd7\x15\xb1\x94\x37\x05\x54\xe7\x71\x55\x0c\x2a\ +\x2d\x72\x5f\xa6\x72\xf9\xc2\x29\xb1\xcd\x43\xb8\x18\xdf\x00\x8b\ +\x63\x49\x96\x11\xb5\x2e\x45\x8d\x30\xd3\xba\x9d\x97\x5b\xbe\x09\ +\x17\x5b\xab\x07\xe8\x6c\x3f\xe1\xe5\x56\x2b\x9b\x13\x00\x6b\x7d\ +\x30\xae\x22\x4e\x12\x31\x25\xd6\x75\x81\x48\x8b\x63\x87\xb9\x38\ +\x59\x6f\x5c\x18\xbb\xda\xa0\xcf\x68\x23\xda\x8b\x38\x2a\xa0\x2a\ +\xb6\xe0\x6d\xb9\x8d\xdb\x14\x7e\x1f\xae\x82\xab\x5d\xff\x62\x62\ +\x40\x63\x44\x85\x17\x1b\xc1\xb0\xca\x44\x59\xd9\xfb\xb4\xf0\xec\ +\x22\x79\x9b\x94\x7f\xde\x17\x71\x19\xdc\x93\x34\x87\x98\x77\x71\ +\xbe\x78\xd8\x4b\xb8\x7e\xcd\xdb\x00\xec\x77\x6b\xb6\xef\xf9\x12\ +\x87\x76\xef\xeb\x19\x5c\x61\xc0\x72\x8b\x5f\x7b\x27\x4e\x74\xfb\ +\xa7\xc0\xbf\x13\xd3\xaa\x27\xa6\x5b\x15\xb3\xf9\x17\x5c\x21\xc2\ +\x5f\x2b\xe1\xd1\x88\x6b\xe8\xc0\x49\x34\x3e\x4b\xa4\x74\xdf\x4b\ +\xb4\x71\x3b\x13\x03\xb8\x51\xe0\x47\xc0\x7f\x07\x5e\x19\x19\x1e\ +\x9a\x0c\x80\x15\x6c\xad\x02\x9b\xcf\xd8\xd6\xca\x75\xf5\xe3\x36\ +\x72\xff\x57\xe0\x8b\x38\xf9\xc7\x42\xae\xe1\xac\xd8\xc9\xdf\xe1\ +\xc4\xb1\xa7\x1b\x59\xa2\x45\xa0\xb5\x03\x27\x1e\x7e\x01\xf8\xb4\ +\xde\x5b\xed\xab\x0c\x51\x90\xfd\x55\xa2\x12\x3f\x63\xad\xf8\xcc\ +\x82\x4b\x18\xac\x5e\xb7\x72\x2d\x5e\xd7\xed\x5c\xbe\xf0\x1a\x4e\ +\xcb\xb4\x0d\xb7\x5b\xa0\x8f\xf4\x6d\x47\x45\xb9\xd3\xbf\xc6\x69\ +\xcd\x2e\xd3\xe0\xa0\xb5\x12\x09\x97\x71\xf1\xb4\xb3\xb8\xd8\xe2\ +\x93\xb8\xbd\x92\x9b\xe4\xe6\x5f\xc5\x49\x5e\x7e\x8a\x4b\x36\x8c\ +\xb7\xea\x33\x0b\x80\x15\x6c\xbd\xdb\x98\xdc\xa4\x1e\x9c\x8c\xe3\ +\x30\x2e\x66\x97\xf5\x80\xaa\x8c\x93\x40\x9c\x13\x58\x1d\xc3\x95\ +\xea\x99\x68\x06\x30\xf7\x04\xc4\x1f\x09\x50\x4f\xe2\x9a\xee\xde\ +\xa7\x5f\x99\xc3\x95\x15\xba\x80\x2b\xda\xd7\xb2\xfd\x20\x83\x4b\ +\x18\x2c\xb8\xbc\xce\xad\xba\x8f\x28\x16\xf4\xa0\xdc\x2c\x93\x72\ +\x8c\xe1\x6a\xe4\xff\x46\x80\x75\x0a\xb7\xed\x68\xae\x49\xaf\xc7\ +\xea\x7d\x99\xd4\xa1\x2a\x06\x56\x6c\x65\xb0\x0a\x80\x15\x2c\xd8\ +\x7c\xd0\xda\x21\xb0\x7a\x14\x17\x84\xdf\x80\xcb\x88\x5e\x16\x43\ +\xb9\x28\xf7\x6a\xb2\x15\xb2\xa3\xbe\x02\xbf\x55\x9b\x4e\x04\xc0\ +\x0a\x16\x2c\x7d\x82\x67\x71\x5a\xa6\x8d\xb8\x80\x75\x27\x6e\xfb\ +\xca\x34\x51\x71\xc3\xd2\x5a\x8d\xe9\x05\xc0\x0a\x16\xac\x35\x81\ +\xcb\x98\x49\x86\x45\xd4\xbc\x0f\x16\x00\x2b\x58\xb0\x60\xc1\x7e\ +\x6f\x61\xf3\x73\xb0\x60\xc1\x02\x60\x05\x0b\x16\x2c\x58\x00\xac\ +\x60\xc1\x82\x05\xc0\x0a\x16\x2c\x58\xb0\x00\x58\xc1\x82\x05\x0b\ +\x16\x00\x2b\x58\xb0\x60\xeb\xcd\xc2\x5e\xc2\x60\xeb\xde\x54\x8d\ +\xc2\x6f\xce\x51\x05\xaa\x6b\x4d\x7f\xe5\x5d\xa7\x5f\x61\xb5\xd8\ +\x4a\xd7\x1a\x18\x56\xb0\xf5\x0e\x56\xd6\x15\x7b\x23\x6e\x6b\xce\ +\x1e\xbd\x0e\x68\xbb\xce\x5a\x02\xab\x4e\x5c\x75\xd5\x5d\x3a\x76\ +\xa0\x56\x70\x7e\x09\xa1\x66\xb6\x20\x1c\x0d\xb6\xde\xc1\xaa\x07\ +\x57\x3b\xea\x1e\x5c\x9d\xfb\x2d\x62\x1d\xb6\xe1\xf9\x22\x30\xde\ +\xca\x6c\x4b\x60\xd4\x2f\x90\xba\x4f\xa0\xd5\xae\x6b\xbc\xaa\x6b\ +\xbc\x41\x0b\xb4\xfc\x0a\x2e\x61\xb0\xf5\xec\x06\x76\x89\x65\x1c\ +\xc6\xf5\x72\x3c\xa8\xaf\xab\xb8\x9a\x51\xef\xe3\xea\x5e\xbd\x99\ +\xcb\x17\xae\xe0\x8a\xf7\x95\x5b\x10\xbc\xfa\x71\xf5\xeb\x9f\xc7\ +\xd5\xca\xda\x2c\xb7\xf0\x63\xdc\xa6\xee\xd7\x04\xd2\x37\x59\x7a\ +\xeb\xb3\x00\x58\xc1\x82\xad\xa0\xb5\xe1\x8a\xf5\xdd\x8b\xab\xd4\ +\x39\x88\x6b\x3c\x6b\x0d\x37\x66\x70\x45\xf0\x9e\xc4\x75\x07\x7a\ +\x13\x57\xcf\xfe\x6a\x2e\x5f\x98\xc4\x35\xf6\x28\x37\x7b\x15\x84\ +\x5c\xbe\xd0\x8b\xab\x40\xfa\x65\x5d\xe3\x7e\x01\x56\x55\xdf\xdf\ +\x8e\x2b\x3d\x73\x03\x57\xf3\x6b\xba\xd9\x1f\x5a\xb0\x60\xeb\xd1\ +\xac\x19\xea\x1e\x31\xab\x07\xe4\x1a\xf6\x0b\xc8\xb6\x08\xcc\x3e\ +\x0b\x7c\x0b\xf8\x33\xe0\x3f\x03\x7f\x0c\xbc\x2c\xc6\xb2\x45\xb5\ +\xe1\x9b\x15\xac\xb2\x72\x73\x3f\x0f\x7c\x15\x78\x46\x2e\xe1\x56\ +\x01\xd5\x3e\x5c\x29\x9d\xfd\xb8\x18\x5e\x7b\xb3\xc7\xb2\x02\xc3\ +\x0a\xb6\xde\x41\xcb\xda\xbd\xf7\x30\xbf\x71\x83\x35\xe3\x18\xc0\ +\x35\x75\xd8\x0d\x3c\x4e\xd4\x5a\xeb\x0c\xae\x21\xeb\x7b\xb9\x7c\ +\xe1\x22\xae\x83\xce\x5c\x93\x15\xc8\xdb\x0c\x7c\x0e\x57\x94\xf0\ +\x90\x40\xc9\x6f\xbc\xda\x29\xd0\xde\xa5\xd7\xb6\x56\x78\x60\xc1\ +\x82\xad\x47\xb3\xd2\xc7\x73\x72\xff\xaa\x35\xbc\x90\x4e\x5c\xcc\ +\xc7\x18\xd9\x83\xc0\x53\xc0\xa7\x70\xbd\x19\x4f\x02\xef\x00\x67\ +\x72\xf9\xc2\x55\x60\xba\xd1\x5d\x85\xe4\x0a\x1e\x06\x8e\xe8\x35\ +\x0e\x56\x06\xca\xed\xba\x0f\xb3\xb4\x40\xad\xaf\x00\x58\xc1\xd6\ +\xab\x95\x70\x71\x28\x6b\xd9\x3e\x2e\x26\x95\xd4\xfa\x3d\xe3\x31\ +\xae\x2c\x2e\x58\xbf\x41\x6e\xd5\xfd\x02\xaf\x53\xc0\xef\x70\x5d\ +\xa5\xcf\x0a\xb8\x26\x71\x65\x89\x57\x15\x04\x24\xc7\xd8\x0f\x7c\ +\x09\x17\x9f\xdb\x94\x72\x5d\x15\x81\xf5\xac\xee\xc5\x5c\xb3\x3f\ +\xb4\x00\x58\xc1\xd6\x33\xc3\x9a\xc0\x75\xc3\x7e\x15\xd7\xcf\xaf\ +\x5f\x47\xb6\xc6\xdf\x19\x78\x19\xeb\xea\xc3\x75\xdc\xd9\x2f\xb7\ +\xeb\x71\x7d\xe6\x29\x5c\x17\x9b\x0b\xb9\x7c\x61\x1c\x98\x5d\x0d\ +\xe0\x52\x3d\xf7\xad\xb8\xf6\x65\x83\x72\x77\xd3\xf4\x64\x65\x5c\ +\xc0\xfd\x43\x5c\x42\xa1\xe9\xeb\xbd\x67\x07\x5f\x7c\x21\x0c\xdd\ +\x60\xeb\xce\x4e\x1c\x3f\xc6\xe0\x91\xa3\xe6\x12\x4e\x89\x3d\x59\ +\xbb\x77\xbf\x7b\x72\x66\x01\xf0\x6a\x23\xea\xa2\xbd\x45\x2e\xe3\ +\x7e\x1d\x7b\x71\x71\xa4\x5e\xa0\x32\x78\xe4\x28\x83\x47\x8e\x56\ +\x06\x8f\x1c\xad\x9e\x38\x7e\x6c\xa5\x98\xd5\x6e\xe0\x0b\xc0\xd7\ +\x71\x19\xce\x01\x92\x63\x53\x15\x81\xd5\xeb\xc0\x0f\x81\x8f\x5a\ +\xa1\x41\x45\x10\x8e\x06\x5b\xd7\xa6\xac\x58\x1f\x2e\x53\xf8\x12\ +\xae\xa1\xea\x43\x72\xf7\x7a\x04\x5e\xe6\x0a\x2e\x94\x41\xf3\xe3\ +\x62\x93\x38\xa9\xc0\x05\xa2\x00\xfd\x69\x9c\xf6\x69\x4c\x20\x39\ +\x8b\xd3\x3f\x95\x58\xa2\xbe\xcb\x53\xea\x0f\x88\xe1\xbd\x20\xc0\ +\xb2\x46\x1a\x9d\x29\xe7\x3d\x8b\xd3\x99\xfd\x35\xf0\xb7\x23\xc3\ +\x43\x17\x5a\xe1\x79\x05\xc0\x0a\x16\xcc\x4d\xfc\x6e\x5c\xb6\xec\ +\x29\x31\x93\x43\xfa\x7a\xab\x58\xd2\xc6\x18\xfb\xca\x2c\x00\x5c\ +\x55\x01\xd1\xac\x98\xcc\x15\xb9\x88\xe7\x70\x59\xc6\xeb\x3a\x26\ +\x70\x82\xcd\x09\x5c\x3c\xa9\x24\xf6\x53\x14\xf8\x95\x13\x98\x9e\ +\x05\xcb\x2d\x96\xb6\x47\xe7\xfd\x39\x9d\xfb\x6e\xb1\xba\xf6\x94\ +\xf3\x2c\xe1\x62\x77\xdf\x05\xfe\x0a\x78\x63\x64\x78\x68\xb6\x15\ +\x9e\x53\x88\x61\x05\x0b\x06\x8c\x0c\x0f\xcd\xe4\xf2\x85\x8f\x71\ +\xc1\xf7\x77\x70\x1a\xac\x5d\x38\xad\xd2\x3e\x9c\x7e\x69\xbf\x58\ +\x4b\xbf\xc7\xbc\x32\x29\xae\xa2\x1f\xe7\xb2\xed\x3f\xf7\x0a\x9c\ +\x6e\x00\xb7\xf5\xbf\x2c\xf0\x7f\x55\xc0\x36\x21\xc0\x9a\xf2\xdc\ +\x55\x03\xae\xac\xfe\x67\x47\xcc\x05\x3d\x84\xcb\x04\xee\x13\x80\ +\x75\x90\xde\xbd\xba\x2c\x86\xf7\x2a\xf0\x7d\x5c\xbc\x6d\xae\x55\ +\x9e\x53\x60\x58\xc1\x82\xdd\xe9\x22\x76\x88\x4d\x75\x09\x9c\xb6\ +\x03\x07\x70\xca\x77\x13\x99\x6e\xf7\x58\x57\x7b\x0d\xf0\x8a\xb3\ +\x2e\x03\x9f\x92\x5e\x67\x70\xea\xf2\xdb\x72\x23\x67\xf5\xb3\x39\ +\xb1\xac\xdb\x7a\x5f\xd6\xe7\x5b\x96\xb2\x47\xe7\xb6\x0d\x17\x58\ +\x1f\x10\x40\xb6\xd5\xf8\xff\x45\xb1\xba\x37\x80\xff\x8d\xeb\x78\ +\x7d\xa9\x95\x7a\x16\x06\xc0\x0a\x16\x2c\x1d\xb8\x60\x7e\x50\xdd\ +\x36\x0f\x1f\xd2\x71\xbf\x18\x8e\x29\xe4\xbb\x6a\xb8\x61\x71\xf0\ +\x48\x03\xb2\xaa\x18\x56\xd5\x03\x35\x73\x13\xf1\x40\xab\x5d\xc0\ +\xda\x59\x07\x60\x56\x05\x7a\x97\x71\x41\xf6\x6f\x03\x3f\x06\x46\ +\x5b\xad\x13\x74\x00\xac\x60\xc1\x16\xc7\xbc\x7a\xe5\x76\xed\x15\ +\x60\x3d\x88\x0b\xd2\xdf\xa7\xef\x6d\x11\xeb\xaa\x27\x48\x5f\x0b\ +\xc8\xe2\xdf\xab\xc6\x5c\xce\xa4\xd7\x34\x2b\xe1\x62\x68\xaf\x89\ +\x59\x9d\x00\x2e\xb7\x62\xdb\xfa\x20\x6b\x08\x16\xac\x0e\x3b\x71\ +\xfc\x18\x27\x8e\x1f\x2b\x0f\x1e\x39\x3a\x2b\x37\xed\x0a\x2e\x80\ +\x7e\x06\x17\x44\xbf\x2c\x97\x0e\x8f\xfd\x18\xeb\xa9\x17\xb8\x32\ +\x35\x8e\x36\xef\x88\xff\xac\x96\x95\x71\xb1\xb2\xb7\x80\xbf\x17\ +\xb3\x6a\x49\xb0\x0a\x0c\x2b\x58\xb0\xbb\x67\x5e\xbe\x06\xeb\x01\ +\x5c\x96\xee\x39\xe0\x61\x5c\x6c\xc9\x02\xf4\xd9\x04\xb0\x59\x49\ +\xb3\x98\xd5\x4d\x9c\x02\xff\xdb\xc0\x0f\x80\xb3\x23\xc3\x43\x73\ +\xad\x7a\xbf\x03\x60\x05\x0b\xb6\x3c\xc0\x95\xc5\x05\xc2\x77\xe0\ +\x34\x50\x8f\xe3\xe2\x5c\x7b\x71\x82\xd4\x0d\x02\xaf\x5e\xfd\x9e\ +\xc5\x9d\x92\x58\x56\xbd\xee\x62\xdc\x65\xb4\xf8\x57\x09\x17\xc8\ +\xbf\x2c\xb0\xfa\x01\xf0\x73\xe0\x5c\xab\xc8\x17\x02\x60\x05\x0b\ +\xb6\x7a\xc0\xb5\x91\x48\xc6\xb0\x13\x57\xcd\x74\x13\x4e\x1f\xb5\ +\x47\xaf\x03\x38\xc1\x6a\x9b\xc7\xbe\x2c\x98\xee\xc7\xbf\x2a\x1e\ +\x18\x55\x3d\x80\xaa\x10\x05\xe4\x6d\x03\xf7\x2c\x4e\x06\x71\x53\ +\x6e\xea\xdb\xb8\x20\xfb\x49\x60\x6c\x64\x78\xa8\xd8\xea\xf7\x37\ +\x00\x56\xb0\x60\xcb\x0f\x5a\x26\xec\xec\xc1\x65\xf1\xfa\xc4\xb0\ +\x36\xe3\xb4\x52\xf1\x6d\x3b\xed\xfa\xbd\x7e\x01\x5b\xaf\xbe\xf6\ +\xd9\x92\x29\xe2\x2b\x44\xc2\xd2\x19\x0f\xa0\x6e\xe1\xf4\x55\xd7\ +\xc4\xac\xce\xe1\x54\xf6\x63\xc0\x4c\x2b\x49\x17\x02\x60\x05\x0b\ +\xd6\x38\xe0\x82\x28\x58\x6e\xf1\xae\x01\xb9\x8e\xbd\x02\x29\x70\ +\x92\x88\xad\x38\x5d\xd5\x56\x5c\xa6\x11\xa2\x2a\xa0\xb7\x99\x2f\ +\x77\x28\xea\x67\xe3\x02\x2b\x03\xad\x71\xfd\xfe\x2c\xab\xb4\xe1\ +\x3a\x00\x56\xb0\x60\x6b\x17\xc4\x0c\xbc\x3a\x3d\x37\xd0\x40\xad\ +\x47\x6c\x6c\xb3\xbe\xd7\x8e\x53\xbe\x17\x05\x40\x19\xa2\x38\x55\ +\xd9\x03\xae\x39\x22\x71\x69\x79\xad\x81\x54\x00\xac\x60\xc1\x9a\ +\x87\x7d\x31\x32\x3c\x54\xd5\xd7\x96\x45\xec\x24\x8a\x55\x95\x3c\ +\x66\x95\x64\x55\xfb\x8c\xf5\x70\xdf\x02\x60\x05\x0b\xd6\xe4\x60\ +\x16\xee\x48\x00\xac\x60\xc1\x82\xb5\xa0\x85\xae\x39\xc1\x82\x05\ +\x0b\x80\x15\x2c\x58\xb0\x60\x01\xb0\x82\x05\x0b\x16\x00\x2b\x58\ +\xb0\x60\xc1\x02\x60\x05\x0b\x16\x2c\x58\x00\xac\x60\xc1\x82\x05\ +\xc0\x0a\x16\x2c\x58\xb0\x00\x58\xc1\x82\x05\x0b\x16\x00\x2b\x58\ +\xb0\x60\x01\xb0\x82\x05\x0b\x16\x2c\x00\x56\xb0\x60\xc1\x82\x2d\ +\xc9\xfe\x3f\x7e\x40\xe8\xe4\x51\x58\x6a\xf0\x00\x00\x00\x00\x49\ +\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\xc6\xb0\ +\x00\ +\x01\x00\x00\x00\x0f\x00\x80\x00\x03\x00\x70\x46\x46\x54\x4d\x49\ +\xeb\x7b\x7e\x00\x00\xc6\x94\x00\x00\x00\x1c\x47\x44\x45\x46\x01\ +\xf0\x02\x9a\x00\x00\xc3\x50\x00\x00\x00\x48\x47\x50\x4f\x53\x8b\ +\x53\x9a\x33\x00\x00\xc5\xa4\x00\x00\x00\xee\x47\x53\x55\x42\x48\ +\x47\x1f\xb8\x00\x00\xc3\x98\x00\x00\x02\x0c\x4f\x53\x2f\x32\xa7\ +\x2d\x81\xee\x00\x00\x01\x78\x00\x00\x00\x56\x63\x6d\x61\x70\x70\ +\x7e\x24\xa4\x00\x00\x06\x20\x00\x00\x02\xb2\x67\x61\x73\x70\xff\ +\xff\x00\x03\x00\x00\xc3\x48\x00\x00\x00\x08\x67\x6c\x79\x66\x3d\ +\xa4\xde\x6e\x00\x00\x0b\x00\x00\x00\x76\xd0\x68\x65\x61\x64\xf6\ +\x63\x42\xf5\x00\x00\x00\xfc\x00\x00\x00\x36\x68\x68\x65\x61\x19\ +\x1b\x0d\xa7\x00\x00\x01\x34\x00\x00\x00\x24\x68\x6d\x74\x78\x56\ +\xf6\x59\x13\x00\x00\x01\xd0\x00\x00\x04\x50\x6c\x6f\x63\x61\xdd\ +\x6f\xc0\x6e\x00\x00\x08\xd4\x00\x00\x02\x2a\x6d\x61\x78\x70\x01\ +\x76\x01\x72\x00\x00\x01\x58\x00\x00\x00\x20\x6e\x61\x6d\x65\x4c\ +\x2c\x61\x0f\x00\x00\x81\xd0\x00\x00\x36\xc9\x70\x6f\x73\x74\x8f\ +\x05\xee\x61\x00\x00\xb8\x9c\x00\x00\x0a\xa9\x00\x01\x00\x00\x00\ +\x01\x19\x99\xf7\x59\x13\xfd\x5f\x0f\x3c\xf5\x00\x0b\x08\x00\x00\ +\x00\x00\x00\xc4\xa0\xef\x5f\x00\x00\x00\x00\xc4\xa0\xef\x5f\xfc\ +\x78\xfb\x43\x11\x8a\x0a\x5e\x00\x00\x00\x08\x00\x02\x00\x00\x00\ +\x00\x00\x00\x00\x01\x00\x00\x0a\x5e\xfb\x43\x00\xb8\x12\x52\xfc\ +\x78\xfe\xfd\x11\x8a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x01\x14\x00\x01\x00\x00\x01\x14\x00\xc8\x00\ +\x15\x00\xa6\x00\x07\x00\x02\x00\x00\x00\x01\x00\x01\x00\x00\x00\ +\x40\x00\x00\x00\x04\x00\x01\x00\x01\x04\xb1\x01\x90\x00\x05\x00\ +\x00\x05\x33\x05\x99\x00\x00\x01\x1e\x05\x33\x05\x99\x00\x00\x03\ +\xd7\x00\x66\x02\x12\x00\x00\x02\x00\x06\x03\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x01\x12\x00\x40\x00\x01\x00\x00\x00\x00\x00\x00\ +\x00\x50\x66\x45\x64\x00\x40\x00\x20\xff\xff\x06\x66\xfe\x66\x00\ +\xb8\x0a\x5e\x04\xbd\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x04\ +\xe2\x00\xc8\x00\x00\x00\x00\x02\xaa\x00\x00\x03\x4d\x00\x00\x03\ +\x0c\x00\xc8\x03\x0c\x00\xc8\x03\x0c\x00\xc8\x06\x7c\x00\x78\x08\ +\xde\x00\x78\x06\x32\x00\x8b\x08\x08\x00\x8b\x07\xee\x00\x92\x07\ +\x92\x00\x92\x05\xe0\x00\xb8\x06\x48\x00\x8b\x07\xce\x00\xb8\x0b\ +\xb8\x00\xc8\x06\xef\x00\xc8\x05\xe5\x00\x90\x05\xe5\x00\x90\x05\ +\xe5\x00\x90\x03\x48\x00\xc8\x05\x9a\x00\xc8\x0a\xe3\x00\xbe\x0b\ +\x18\x00\xc9\x12\x52\x00\xc8\x08\x02\x00\xc8\x0d\x9e\x00\xc8\x01\ +\x7a\x00\x1c\x04\xd8\x00\xc8\x04\xd8\x00\xc8\x04\xd8\x00\xc8\x03\ +\x0c\x00\xc8\x03\xb6\x00\xc8\x03\x0c\x00\xc8\x04\xce\x00\xc8\x04\ +\x38\x00\x50\x04\x38\x00\xd7\x04\x38\x00\x54\x04\x38\x00\x50\x03\ +\xa4\x00\x64\x04\x85\x00\x4b\x03\x55\x00\x46\x01\x62\x00\x5a\x03\ +\x4e\x00\x5b\x02\xe6\x00\x5b\x02\xac\xff\x65\x04\xe9\x00\x54\x03\ +\xf0\x00\x54\x03\x6d\x00\x15\x02\x9a\x00\x54\x02\xb2\x00\x5b\x03\ +\x0d\x00\x4b\x03\x24\x00\x54\x01\xe0\x00\xc8\x02\xa8\x00\xc8\x03\ +\x4c\x00\xc8\x03\x4c\x00\xc8\x01\xe0\x00\xc8\x01\xe0\x00\xc8\x04\ +\xb0\x00\xc8\x04\xb0\x00\xc8\x02\x58\x00\xc8\x08\xe8\x00\x96\x08\ +\xe8\x00\x96\x04\xf3\x00\x9d\x05\x62\x00\x96\x04\xe2\x00\xbe\x04\ +\xe2\x00\xbe\x06\x97\x00\xbe\x05\x7a\x00\xa5\x05\x7a\x00\xa5\x02\ +\x95\x00\xb1\x06\x97\x00\xbe\x02\x60\x00\x8c\x03\x40\x00\xc8\x06\ +\x40\x00\x00\x06\x40\x00\x00\x06\x40\x00\x00\x06\x40\x00\x00\x06\ +\x40\x00\x00\x06\x40\x00\x00\x06\xd6\x00\xc8\x04\xce\x00\xc8\x05\ +\x60\x00\xb8\x05\x60\x00\xb8\x05\x60\x00\xb8\x06\x1e\x00\xc8\x06\ +\x2f\x00\x90\x06\x2f\x00\x90\x06\x2f\x00\x90\x04\x32\x00\xc8\x03\ +\x9c\x00\xc8\x0b\xb8\x00\xc8\x03\x4c\x00\xc8\x04\x4c\x00\xc8\x03\ +\x0c\x00\x82\x03\x0c\x00\x82\x03\x0c\x00\x82\x03\x0c\x00\xc8\x03\ +\x0c\x00\xc8\x03\x0c\x00\xc8\x02\x9a\x00\x6c\x02\x9a\x00\x3b\x03\ +\xda\x00\xa4\x03\xda\x00\xa4\x05\xfe\x00\xc8\x05\xc4\x00\xc8\x07\ +\xc0\x00\xc8\x07\x83\x00\xc8\x05\x5f\x00\xbe\x05\x5f\x00\xbe\x05\ +\x5f\x00\xbe\x03\x2c\x00\xc0\x03\x5e\x00\xc3\x03\xe2\x00\xc3\x04\ +\x66\x00\xc3\x04\xea\x00\xc3\x05\x6e\x00\xc3\x03\x4d\x00\xc9\x03\ +\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\ +\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\ +\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\ +\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x9d\x00\xc9\x03\x9d\x00\xc9\x03\ +\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\xd9\x00\xc9\x03\ +\xd9\x00\xc9\x03\x4d\x00\x00\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x05\ +\x54\x00\xc8\x04\x33\x00\xc9\x03\xd9\x00\xc9\x03\xd9\x00\xc9\x05\ +\xa4\x00\xc9\x05\xa4\x00\xc9\x05\xa4\x00\xc9\x05\xa4\x00\xc9\x05\ +\xa4\x00\xc9\x00\x00\xfe\xf2\x00\x00\xfe\x37\x00\x00\xfd\xdf\x00\ +\x00\xfd\xdf\x00\x00\xfd\xdf\x05\x78\x00\xaf\x05\x78\x00\xaf\x05\ +\x78\x00\xaf\x00\x00\xff\xd8\x00\x00\xff\x38\x00\x00\xff\x38\x00\ +\x00\xfe\xf2\x00\x00\xfe\xf2\x00\x00\xfe\xf2\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xbf\x00\ +\x00\xfd\xc4\x00\x00\xfc\xf0\x00\x00\xfd\x9c\x00\x00\xfd\x2c\x00\ +\x00\xfd\x2c\x00\x00\xfc\xbf\x00\x00\xfc\xf0\x02\x76\x00\xc8\x02\ +\x76\x00\xb4\x00\x00\xfc\xab\x00\x00\xfc\xab\x00\x00\xfd\x12\x00\ +\x00\xfd\x6c\x00\x00\xfd\x07\x00\x00\xfc\x78\x00\x00\xfc\x78\x03\ +\x5e\x00\xb4\x03\x58\x00\xb8\x03\xc0\x00\x8c\x04\x1a\x00\x78\x05\ +\x75\x00\x92\x04\x90\x00\x8b\x09\xba\x00\xc8\x09\xba\x00\xc8\x04\ +\x6a\x00\xc8\x04\x6a\x00\xc8\x05\x4c\x00\xb9\x05\xae\x00\xc1\x05\ +\xae\x00\xc1\x05\xae\x00\xc1\x03\x6e\x00\xc0\x02\xc0\x00\xc8\x04\ +\x6d\x00\xc7\x04\xfe\x00\xc7\x02\x90\x00\xc7\x03\x35\x00\xc7\x01\ +\xe5\x00\xc8\x05\x11\x00\xc8\x04\x31\x00\xc8\x04\x88\x00\xc7\x04\ +\x8a\x00\xc8\x03\xf6\x00\xc8\x06\x40\x00\xc8\x06\x40\x00\xc8\x04\ +\x1a\x00\xc8\x03\x1a\x00\xb4\x00\x00\xfd\x29\x00\x00\xfd\x6b\x00\ +\x00\xfd\xa1\x00\x00\xfd\x65\x0a\x24\x00\xa3\x05\xea\x00\xb4\x0d\ +\x9e\x00\xc8\x06\x34\x00\xc8\x06\x34\x00\xbe\x04\xb8\x00\xb4\x03\ +\xec\x00\xb4\x04\xc0\x00\xb4\x06\x22\x00\xc9\x04\x2e\x00\xc9\x04\ +\x2e\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\x4d\x00\xc9\x03\ +\x4d\x00\xc9\x04\x5d\x00\xc9\x04\x5d\x00\xc9\x04\x5d\x00\xc9\x04\ +\x5d\x00\xc9\x01\xd6\x00\xc8\x01\xd6\x00\xc8\x01\xd6\x00\xc8\x01\ +\xd6\x00\xc8\x01\xd6\x00\xc8\x02\xd7\x00\xc8\x04\x10\x00\xb4\x04\ +\x10\x00\xb4\x04\x10\x00\xb4\x03\xac\x00\xb4\x03\xac\x00\xb4\x03\ +\xac\x00\xb4\x03\xac\x00\xb4\x03\xac\x00\xb4\x03\xf7\x00\xb5\x02\ +\xb7\x00\xc9\x04\x47\x00\xc9\x02\xb7\x00\xc9\x02\xb7\x00\xc9\x02\ +\xb7\x00\xca\x03\xbf\x00\xc9\x03\xbf\x00\xc9\x05\x67\x00\xc9\x04\ +\xa9\x00\xc9\x06\x0e\x00\xc9\x07\xec\x00\xc9\x05\x45\x00\xc9\x06\ +\xef\x00\xca\x05\x67\x00\xc9\x04\xfe\x00\xc7\x04\x6d\x00\xc7\x00\ +\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00\x2c\x00\x00\x00\x04\x00\ +\x00\x00\xc4\x00\x01\x00\x00\x00\x00\x01\xac\x00\x03\x00\x01\x00\ +\x00\x00\x2c\x00\x03\x00\x0a\x00\x00\x00\xc4\x00\x04\x00\x98\x00\ +\x00\x00\x22\x00\x20\x00\x04\x00\x02\x00\x20\x26\x6f\xe0\x14\xe0\ +\x21\xe0\x25\xe0\x28\xe0\x33\xe0\x42\xe0\x4a\xe0\x51\xe0\x55\xe0\ +\x5d\xe0\x5f\xe0\x62\xe0\x65\xe0\x69\xff\xff\x00\x00\x00\x20\x26\ +\x6d\xe0\x00\xe0\x18\xe0\x25\xe0\x28\xe0\x32\xe0\x42\xe0\x4a\xe0\ +\x50\xe0\x55\xe0\x5c\xe0\x5f\xe0\x61\xe0\x65\xe0\x69\xff\xff\xff\ +\xe3\xd9\x97\x20\x07\x20\x04\x20\x01\x1f\xff\x1f\xf6\x1f\xe8\x1f\ +\xe1\x1f\xdc\x1f\xd9\x1f\xd3\x1f\xd2\x1f\xd1\x1f\xcf\x1f\xcc\x00\ +\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x00\ +\x00\x00\x12\x00\x00\x00\x20\x00\x00\x00\x20\x00\x00\x00\x03\x00\ +\x00\x26\x6d\x00\x00\x26\x6f\x00\x00\x00\x04\x00\x00\xe0\x00\x00\ +\x00\xe0\x14\x00\x00\x00\x07\x00\x00\xe0\x18\x00\x00\xe0\x21\x00\ +\x00\x00\x1c\x00\x00\xe0\x25\x00\x00\xe0\x25\x00\x00\x00\x26\x00\ +\x00\xe0\x28\x00\x00\xe0\x28\x00\x00\x00\x27\x00\x00\xe0\x32\x00\ +\x00\xe0\x33\x00\x00\x00\x28\x00\x00\xe0\x42\x00\x00\xe0\x42\x00\ +\x00\x00\x2a\x00\x00\xe0\x4a\x00\x00\xe0\x4a\x00\x00\x00\x2b\x00\ +\x00\xe0\x50\x00\x00\xe0\x51\x00\x00\x00\x2c\x00\x00\xe0\x55\x00\ +\x00\xe0\x55\x00\x00\x00\x2e\x00\x00\xe0\x5c\x00\x00\xe0\x5d\x00\ +\x00\x00\x2f\x00\x00\xe0\x5f\x00\x00\xe0\x5f\x00\x00\x00\x31\x00\ +\x00\xe0\x61\x00\x00\xe0\x62\x00\x00\x00\x32\x00\x00\xe0\x65\x00\ +\x00\xe0\x65\x00\x00\x00\x34\x00\x00\xe0\x69\x00\x00\xe0\x69\x00\ +\x00\x00\x35\x00\x01\xd1\x00\x00\x01\xd1\x26\x00\x00\x00\x36\x00\ +\x01\xd1\x29\x00\x01\xd1\xdd\x00\x00\x00\x5d\x00\x00\x01\x06\x00\ +\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x00\x02\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\ +\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x94\x00\x94\x00\x94\x00\x94\x00\xbe\x00\ +\xd8\x01\x0c\x01\x9c\x02\x6c\x03\x08\x03\xea\x04\x90\x05\x3c\x05\ +\xd4\x06\x5e\x07\x2e\x07\x46\x07\x5a\x07\xc8\x07\xd4\x07\xe0\x08\ +\x2c\x08\x74\x08\xb6\x08\xda\x09\x00\x09\x1a\x09\x3c\x09\x7c\x09\ +\xaa\x09\xe8\x0a\x30\x0a\x52\x0a\x98\x0a\xc2\x0b\x10\x0b\x52\x0b\ +\x96\x0b\xe4\x0c\x3c\x0c\x86\x0c\xda\x0d\x44\x0d\x56\x0d\xa0\x0d\ +\xf0\x0e\x44\x0e\xa2\x0e\xe8\x0f\x38\x0f\x6e\x0f\xb8\x10\x00\x10\ +\x40\x10\x4e\x10\x62\x10\x76\x10\x8a\x10\xae\x10\xbc\x10\xc8\x10\ +\xd4\x10\xf2\x11\xc6\x12\x76\x12\xe4\x13\x46\x13\x56\x13\x7e\x13\ +\xb0\x13\xe6\x14\x20\x14\x42\x14\x5a\x14\xac\x14\xd8\x14\xe6\x14\ +\xfa\x15\x14\x15\x34\x15\x5c\x15\x8a\x16\x0a\x16\x5e\x17\x08\x17\ +\x14\x17\x20\x17\xaa\x18\x02\x18\x0e\x18\x1a\x18\x2e\x18\x44\x18\ +\x4c\x18\x68\x18\xb4\x18\xe6\x19\x18\x19\x3a\x19\x5c\x19\xa0\x19\ +\xe4\x1a\x22\x1a\x56\x1a\x9c\x1a\xec\x1b\x9c\x1c\x56\x1d\x4c\x1e\ +\x46\x1e\x5c\x1e\x6e\x1e\x80\x1e\xc6\x1e\xec\x1f\x2c\x1f\x84\x1f\ +\xf8\x20\x84\x20\x9e\x20\xb2\x20\xe4\x20\xfa\x21\x08\x21\x1a\x21\ +\x28\x21\x3a\x21\x46\x21\x5a\x21\x68\x21\x7c\x21\x88\x21\x9a\x21\ +\xa8\x21\xc6\x21\xd8\x21\xf4\x22\x08\x22\x3a\x22\x62\x22\x76\x22\ +\x76\x22\x8c\x22\x9a\x22\xe2\x23\x10\x23\x3c\x23\x54\x23\x8e\x23\ +\xde\x24\x4c\x24\xd6\x25\x7c\x25\x8a\x25\xac\x25\xbc\x25\xd2\x25\ +\xf0\x25\xfe\x26\x14\x26\x32\x26\x44\x26\x70\x26\xb0\x27\x10\x27\ +\x8c\x28\x22\x28\x22\x28\x22\x28\x22\x28\x22\x28\x22\x28\x22\x28\ +\x22\x28\x22\x28\x34\x28\x46\x28\x54\x28\x62\x28\x74\x28\x92\x28\ +\xb0\x28\xca\x29\x4e\x29\xcc\x29\xf0\x2a\x10\x2a\x24\x2a\x58\x2a\ +\x76\x2a\xa6\x2a\xe2\x2b\x18\x2b\x62\x2b\xa2\x2b\xf0\x2c\x4e\x2c\ +\xa2\x2c\xb8\x2c\xce\x2d\x1a\x2d\x52\x2d\xc4\x2e\x14\x2e\x66\x2e\ +\xc0\x2f\x10\x2f\x36\x2f\x5a\x2f\x88\x2f\xb0\x2f\xea\x2f\xf8\x30\ +\x32\x30\x72\x30\xa6\x30\xd8\x31\x0e\x31\x2a\x31\x44\x31\x54\x31\ +\x8e\x31\xa2\x31\xb4\x31\xd2\x32\x00\x33\x02\x33\xfc\x34\x18\x34\ +\x90\x35\x08\x35\x3a\x35\x80\x35\xe0\x35\xfe\x36\x1c\x36\x38\x36\ +\x4e\x36\x5c\x36\x76\x36\x88\x36\xc4\x36\xf8\x37\x4a\x37\x94\x37\ +\xa2\x37\xb0\x37\xbe\x37\xcc\x37\xda\x37\xea\x38\x16\x38\x36\x38\ +\x68\x38\x96\x38\xb8\x38\xda\x39\x0a\x39\x3c\x39\x76\x39\x8a\x39\ +\xa6\x39\xbe\x39\xce\x39\xe0\x39\xf8\x3a\x10\x3a\x30\x3a\x4e\x3a\ +\x74\x3a\xa0\x3a\xc2\x3a\xec\x3b\x0e\x3b\x40\x3b\x68\x00\x00\x00\ +\x05\x00\xc8\x00\x00\x04\x1a\x05\xcd\x00\x03\x00\x1d\x00\x28\x00\ +\x61\x00\x6b\x00\x00\x13\x21\x11\x21\x01\x2e\x01\x35\x34\x36\x37\ +\x1e\x02\x17\x06\x23\x22\x2e\x02\x35\x34\x37\x16\x17\x0e\x01\x15\ +\x14\x37\x32\x33\x32\x16\x15\x14\x07\x2e\x02\x27\x37\x3e\x01\x35\ +\x34\x26\x23\x22\x0e\x02\x15\x14\x17\x0e\x03\x15\x14\x16\x33\x32\ +\x37\x16\x15\x14\x06\x23\x22\x26\x27\x36\x35\x34\x26\x23\x22\x06\ +\x15\x14\x16\x33\x32\x36\x35\x34\x27\x3e\x01\x35\x34\x26\x23\x22\ +\x07\x27\x26\x35\x34\x36\x33\x32\x16\x15\x14\xc8\x03\x52\xfc\xae\ +\x01\xb2\x2d\x15\x27\x20\x07\x1f\x14\x08\x22\x27\x1c\x40\x39\x26\ +\x91\x18\x03\x2a\x2f\x8e\x04\x04\x34\x44\x3f\x08\x14\x1d\x3c\x02\ +\x49\x43\x31\x1a\x24\x37\x1d\x0d\x0f\x28\x35\x30\x18\x80\x67\x29\ +\x25\x16\x2c\x2e\x20\x1c\x08\x43\x2b\x22\x27\x27\x4f\x4c\x3c\x41\ +\x19\x2e\x37\x68\x3e\x0f\x0e\x32\x07\x43\x17\x18\x15\x05\xcd\xfa\ +\x33\x02\x05\x1d\x23\x2c\x0e\x32\x0b\x1b\x6d\x48\x21\x0f\x1d\x30\ +\x4b\x29\x6e\x82\x54\x0e\x12\x55\x30\x65\xb4\x34\x2f\x57\x2e\x21\ +\x48\x64\xde\x02\x3d\x89\x5d\x42\x81\x33\x4f\x4e\x24\x65\x4e\x24\ +\x3a\x49\x52\x2f\x71\x90\x0e\x6a\x6a\x26\x42\x14\x15\x04\x3c\x23\ +\x29\x2b\x27\x3f\x48\x56\x33\x72\x73\x1a\x57\x33\x54\x66\x03\xcd\ +\x33\x5e\x28\x7d\x41\x29\x5a\x00\x02\x00\xc8\xff\xd8\x02\x44\x03\ +\xe1\x00\x0d\x00\x19\x00\x00\x17\x11\x33\x11\x3e\x02\x33\x32\x16\ +\x15\x14\x06\x07\x19\x01\x3e\x03\x35\x34\x23\x22\x0e\x01\xc8\x46\ +\x25\x25\x40\x2a\x42\x40\xa1\x95\x2a\x39\x36\x1b\x32\x1a\x22\x26\ +\x28\x04\x09\xfd\x8b\x1c\x18\x13\x5c\x43\x49\x9a\x59\x01\x49\xff\ +\x00\x1e\x32\x40\x47\x27\x44\x0c\x1e\x00\x00\x00\x02\x00\xc8\xfe\ +\x8d\x02\x44\x03\x2f\x00\x07\x00\x0b\x00\x00\x17\x11\x33\x11\x25\ +\x11\x23\x11\x03\x15\x37\x35\xc8\x46\x01\x36\x46\xf0\xf0\x28\x03\ +\x57\xfe\x8c\x29\xfc\xa9\x01\x74\x01\x2d\xbb\x1b\xbb\x00\x00\x00\ +\x02\x00\xc8\xfe\x84\x02\x44\x03\x38\x00\x1b\x00\x1f\x00\x00\x05\ +\x11\x23\x11\x07\x35\x37\x35\x07\x35\x37\x11\x33\x11\x37\x11\x33\ +\x11\x37\x15\x07\x15\x37\x15\x07\x11\x23\x11\x27\x37\x35\x07\x01\ +\x54\x46\x46\x46\x46\x46\x46\x64\x46\x46\x46\x46\x46\x46\x64\x64\ +\x64\x16\xfe\x9a\x01\x5d\x09\x8c\x09\xc2\x09\x8c\x09\x01\x3f\xfe\ +\xca\x0e\x01\x66\xfe\xa3\x09\x8c\x09\xc2\x09\x8c\x09\xfe\xc1\x01\ +\x36\x7e\x0e\xc2\x0e\x00\x00\x00\x03\x00\x78\x00\x00\x05\xed\x03\ +\x89\x00\x10\x00\x23\x00\x67\x00\x00\x01\x07\x06\x15\x14\x33\x32\ +\x36\x37\x36\x35\x34\x23\x22\x0e\x02\x05\x07\x06\x15\x14\x33\x32\ +\x3e\x02\x37\x36\x35\x34\x23\x22\x0e\x02\x05\x14\x0e\x04\x23\x22\ +\x27\x03\x33\x15\x21\x35\x33\x13\x36\x23\x22\x06\x07\x0e\x04\x23\ +\x22\x27\x03\x33\x15\x21\x35\x33\x13\x36\x23\x22\x06\x07\x27\x3e\ +\x03\x33\x32\x17\x3e\x01\x33\x32\x16\x17\x3e\x01\x33\x32\x17\x3e\ +\x01\x33\x32\x1e\x02\x02\x18\x32\x08\x36\x2e\x66\x19\x14\x47\x10\ +\x1f\x24\x1c\x02\x6f\x32\x07\x35\x14\x2c\x33\x2d\x0e\x14\x48\x10\ +\x1e\x24\x1d\x01\x57\x0c\x1a\x30\x41\x62\x3b\x4a\x32\x34\x7d\xfe\ +\x6a\x82\x8d\x07\x15\x11\x4a\x25\x07\x1a\x30\x41\x62\x3b\x49\x33\ +\x33\x7c\xfe\x6a\x82\x8e\x07\x15\x13\x50\x27\x38\x1b\x35\x35\x56\ +\x3c\x46\x07\x33\x48\x3e\x43\x4d\x0c\x26\x5e\x51\x46\x06\x33\x49\ +\x3e\x2a\x40\x25\x11\x02\xda\xfa\x26\x1e\x4f\x6b\x80\x69\x39\x6e\ +\x08\x15\x2f\x22\xfa\x26\x1e\x4f\x15\x2f\x63\x44\x69\x39\x6e\x08\ +\x15\x2f\x53\x26\x53\x61\x55\x47\x2a\x36\xff\x00\x3f\x3f\x02\xc1\ +\x25\x6a\x63\x2f\x58\x5b\x43\x2a\x36\xff\x00\x3f\x3f\x02\xc1\x25\ +\x77\x70\x18\x44\x71\x51\x2d\x41\x26\x1b\x54\x47\x4f\x4c\x41\x26\ +\x1b\x24\x3f\x4e\x00\x00\x00\x00\x04\x00\x78\x00\x00\x08\x4f\x03\ +\x89\x00\x12\x00\x75\x00\x88\x00\x99\x00\x00\x01\x07\x06\x15\x14\ +\x33\x32\x3e\x02\x37\x36\x35\x34\x23\x22\x0e\x02\x05\x14\x0e\x04\ +\x23\x22\x27\x03\x33\x15\x21\x35\x33\x13\x36\x23\x22\x06\x07\x0e\ +\x05\x23\x22\x27\x03\x33\x15\x21\x35\x33\x13\x36\x23\x22\x06\x07\ +\x0e\x04\x23\x22\x27\x03\x33\x15\x21\x35\x33\x13\x36\x23\x22\x06\ +\x07\x27\x3e\x03\x33\x32\x17\x3e\x01\x33\x32\x16\x17\x3e\x01\x33\ +\x32\x17\x3e\x01\x33\x32\x17\x3e\x01\x33\x32\x17\x3e\x01\x33\x32\ +\x1e\x02\x25\x07\x06\x15\x14\x33\x32\x3e\x02\x37\x36\x35\x34\x23\ +\x22\x0e\x02\x05\x07\x06\x15\x14\x33\x32\x36\x37\x36\x35\x34\x23\ +\x22\x0e\x02\x06\xf0\x32\x07\x35\x14\x2c\x33\x2d\x0e\x14\x48\x10\ +\x1e\x24\x1d\x01\x57\x0c\x1a\x30\x41\x62\x3b\x4a\x32\x34\x7d\xfe\ +\x6a\x82\x8d\x07\x15\x0e\x39\x1f\x01\x0e\x1c\x31\x40\x60\x38\x4a\ +\x32\x34\x7d\xfe\x6a\x82\x8d\x07\x15\x11\x4a\x25\x07\x1a\x30\x41\ +\x62\x3b\x49\x33\x33\x7c\xfe\x6a\x82\x8e\x07\x15\x13\x50\x27\x38\ +\x1b\x35\x35\x56\x3c\x46\x07\x33\x48\x3e\x43\x4d\x0c\x26\x5e\x51\ +\x46\x06\x33\x49\x3e\x74\x21\x23\x5a\x4a\x46\x06\x33\x49\x3e\x2a\ +\x40\x25\x11\xfc\x40\x32\x07\x35\x14\x2c\x33\x2d\x0e\x14\x48\x10\ +\x1e\x24\x1d\xfd\x83\x32\x08\x36\x2e\x66\x19\x14\x47\x10\x1f\x24\ +\x1c\x02\xda\xfa\x26\x1e\x4f\x15\x2f\x63\x44\x69\x39\x6e\x08\x15\ +\x2f\x53\x26\x53\x61\x55\x47\x2a\x36\xff\x00\x3f\x3f\x02\xc1\x25\ +\x49\x44\x28\x51\x5d\x50\x43\x26\x36\xff\x00\x3f\x3f\x02\xc1\x25\ +\x6a\x63\x2f\x58\x5b\x43\x2a\x36\xff\x00\x3f\x3f\x02\xc1\x25\x77\ +\x70\x18\x44\x71\x51\x2d\x41\x26\x1b\x54\x47\x4f\x4c\x41\x26\x1b\ +\x7f\x40\x3f\x41\x26\x1b\x24\x3f\x4e\x02\xfa\x26\x1e\x4f\x15\x2f\ +\x63\x44\x69\x39\x6e\x08\x15\x2f\x22\xfa\x26\x1e\x4f\x6b\x80\x69\ +\x39\x6e\x08\x15\x2f\x00\x00\x00\x01\x00\x8b\xff\xf1\x05\xdc\x05\ +\x1e\x00\x76\x00\x00\x01\x06\x07\x0a\x01\x23\x22\x26\x35\x34\x36\ +\x33\x32\x16\x15\x14\x06\x23\x22\x06\x15\x14\x33\x32\x3e\x02\x37\ +\x36\x37\x23\x35\x33\x3e\x02\x33\x32\x16\x15\x14\x06\x23\x22\x26\ +\x35\x34\x36\x33\x32\x35\x34\x26\x23\x22\x0e\x02\x07\x21\x3e\x02\ +\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x36\x35\ +\x34\x26\x23\x22\x0e\x02\x07\x33\x15\x23\x06\x07\x0a\x01\x23\x22\ +\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\x06\x15\x14\x33\ +\x32\x3e\x02\x37\x36\x37\x02\xbf\x1c\x01\x35\xd5\x75\x55\x43\x3c\ +\x27\x22\x32\x19\x13\x15\x11\x33\x2e\x43\x26\x24\x0e\x0c\x18\x86\ +\x98\x25\x63\x81\x42\x3f\x59\x3c\x27\x22\x32\x19\x13\x26\x21\x12\ +\x21\x34\x27\x1a\x0e\x01\x2f\x26\x63\x80\x43\x3e\x5a\x3d\x27\x22\ +\x31\x19\x12\x16\x10\x20\x12\x22\x34\x26\x1b\x0d\x95\x9f\x1c\x02\ +\x35\xd4\x75\x56\x42\x3c\x26\x23\x31\x19\x12\x16\x11\x34\x2d\x44\ +\x26\x23\x0e\x0d\x17\x03\x41\xb1\x09\xfe\xc6\xfe\xa4\x33\x3e\x3b\ +\x4d\x23\x1f\x1d\x25\x10\x0f\x10\x6a\xab\xd9\x6e\x57\x57\x3f\x75\ +\xb6\x73\x39\x39\x3a\x4d\x23\x1f\x1c\x26\x1f\x07\x09\x34\x65\x6f\ +\x50\x75\xb6\x73\x39\x39\x3a\x4d\x23\x1f\x1c\x26\x10\x0f\x07\x09\ +\x34\x65\x6f\x50\x3f\xb2\x08\xfe\xc6\xfe\xa4\x33\x3e\x3b\x4d\x23\ +\x1f\x1d\x25\x10\x0f\x10\x6a\xab\xd9\x6e\x57\x57\x00\x00\x00\x00\ +\x01\x00\x8b\xff\xf1\x07\xb2\x05\x1e\x00\xaf\x00\x00\x01\x06\x07\ +\x0a\x01\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\ +\x06\x15\x14\x33\x32\x3e\x02\x37\x36\x37\x21\x06\x07\x0a\x01\x23\ +\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\x06\x15\x14\ +\x33\x32\x3e\x02\x37\x36\x37\x21\x06\x07\x0a\x01\x23\x22\x26\x35\ +\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\x06\x15\x14\x33\x32\x3e\ +\x02\x37\x36\x37\x23\x35\x33\x3e\x02\x33\x32\x16\x15\x14\x06\x23\ +\x22\x26\x35\x34\x36\x33\x32\x35\x34\x26\x23\x22\x0e\x02\x07\x21\ +\x3e\x02\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\ +\x36\x35\x34\x26\x23\x22\x0e\x02\x07\x21\x3e\x02\x33\x32\x16\x15\ +\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x35\x34\x26\x23\x22\x0e\ +\x02\x07\x33\x15\x06\x6c\x1c\x01\x35\xd5\x75\x55\x43\x3c\x27\x22\ +\x31\x18\x12\x16\x11\x33\x2e\x43\x26\x24\x0e\x0c\x18\xfe\xd9\x1c\ +\x02\x35\xd4\x75\x56\x42\x3c\x26\x23\x31\x19\x12\x16\x11\x34\x2d\ +\x44\x26\x23\x0e\x0d\x17\xfe\xd9\x1c\x01\x35\xd5\x75\x55\x43\x3c\ +\x27\x22\x32\x19\x13\x15\x11\x33\x2e\x43\x26\x24\x0e\x0c\x18\x86\ +\x98\x25\x63\x81\x42\x3f\x59\x3c\x27\x22\x32\x19\x13\x26\x21\x12\ +\x21\x34\x27\x1a\x0e\x01\x2f\x26\x63\x80\x43\x3e\x5a\x3d\x27\x22\ +\x31\x19\x12\x16\x10\x20\x12\x22\x34\x26\x1b\x0d\x01\x2f\x25\x63\ +\x81\x42\x3f\x59\x3c\x27\x22\x31\x18\x12\x27\x21\x12\x21\x34\x27\ +\x1a\x0e\x96\x03\x41\xb2\x08\xfe\xc6\xfe\xa4\x33\x3e\x3b\x4d\x23\ +\x1f\x1d\x25\x10\x0f\x10\x6a\xab\xd9\x6e\x57\x57\xb2\x08\xfe\xc6\ +\xfe\xa4\x33\x3e\x3b\x4d\x23\x1f\x1d\x25\x10\x0f\x10\x6a\xab\xd9\ +\x6e\x57\x57\xb1\x09\xfe\xc6\xfe\xa4\x33\x3e\x3b\x4d\x23\x1f\x1d\ +\x25\x10\x0f\x10\x6a\xab\xd9\x6e\x57\x57\x3f\x75\xb6\x73\x39\x39\ +\x3a\x4d\x23\x1f\x1c\x26\x1f\x07\x09\x34\x65\x6f\x50\x75\xb6\x73\ +\x39\x39\x3a\x4d\x23\x1f\x1c\x26\x10\x0f\x07\x09\x34\x65\x6f\x50\ +\x75\xb6\x73\x39\x39\x3a\x4d\x23\x1f\x1c\x26\x1f\x07\x09\x34\x65\ +\x6f\x50\x3f\x00\x03\x00\x92\x00\x00\x07\x5f\x03\x89\x00\x3e\x00\ +\x63\x00\x74\x00\x00\x01\x22\x26\x37\x13\x36\x26\x23\x22\x0e\x02\ +\x07\x03\x23\x13\x36\x26\x23\x22\x0e\x02\x07\x03\x23\x13\x36\x23\ +\x22\x06\x07\x27\x3e\x03\x33\x32\x17\x36\x33\x32\x17\x3e\x03\x33\ +\x32\x16\x07\x03\x06\x33\x3e\x01\x37\x17\x0e\x03\x01\x14\x0e\x04\ +\x23\x22\x27\x03\x33\x15\x21\x35\x33\x13\x36\x23\x22\x07\x27\x3e\ +\x04\x33\x32\x17\x3e\x01\x33\x32\x1e\x02\x25\x07\x06\x15\x14\x33\ +\x32\x36\x37\x36\x35\x34\x23\x22\x0e\x02\x03\xc0\x36\x26\x09\x54\ +\x04\x10\x1b\x10\x21\x26\x1e\x07\x5c\x97\x6a\x04\x10\x1b\x10\x21\ +\x26\x1e\x07\x5c\x97\x63\x07\x15\x13\x50\x27\x38\x1b\x35\x35\x56\ +\x3c\x46\x07\x56\x82\x41\x13\x18\x20\x28\x40\x38\x2b\x39\x0d\x4a\ +\x07\x15\x15\x4f\x26\x38\x1b\x35\x35\x56\x03\x63\x0c\x1a\x30\x41\ +\x63\x3b\x49\x33\x34\x7e\xfe\x6a\x81\x8e\x07\x15\x1f\x41\x38\x07\ +\x20\x1d\x30\x4a\x2f\x46\x07\x33\x48\x3e\x2b\x3f\x25\x12\xfe\xa2\ +\x32\x08\x35\x2f\x66\x19\x14\x47\x10\x1f\x24\x1c\x01\x09\x46\x2f\ +\x01\xa2\x17\x11\x08\x15\x2f\x22\xfe\x39\x02\x0d\x17\x11\x08\x15\ +\x2f\x22\xfe\x39\x01\xed\x25\x77\x70\x18\x44\x71\x51\x2d\x41\x41\ +\x41\x12\x19\x0f\x07\x4d\x3f\xfe\x95\x25\x01\x77\x6f\x18\x44\x71\ +\x51\x2d\x01\xa0\x26\x53\x61\x55\x47\x2a\x36\xff\x00\x3f\x3f\x02\ +\xc1\x25\x80\x18\x0b\x46\x2b\x35\x1b\x41\x26\x1b\x24\x3f\x4e\x02\ +\xfa\x26\x1e\x4f\x6b\x80\x69\x39\x6e\x08\x15\x2f\x00\x00\x00\x00\ +\x02\x00\x92\xff\xf1\x07\x3c\x05\x1e\x00\x3d\x00\x7c\x00\x00\x01\ +\x22\x0e\x02\x07\x33\x15\x23\x06\x07\x0a\x01\x23\x22\x26\x35\x34\ +\x36\x33\x32\x16\x15\x14\x06\x23\x22\x06\x15\x14\x33\x32\x3e\x02\ +\x37\x36\x37\x23\x35\x33\x3e\x02\x33\x32\x16\x15\x14\x06\x23\x22\ +\x26\x35\x34\x36\x33\x32\x36\x35\x34\x26\x01\x22\x26\x37\x13\x36\ +\x26\x23\x22\x0e\x02\x07\x03\x23\x13\x36\x26\x23\x22\x0e\x02\x07\ +\x03\x23\x13\x36\x23\x22\x06\x07\x27\x3e\x03\x33\x32\x17\x36\x33\ +\x32\x17\x3e\x03\x33\x32\x16\x07\x03\x06\x33\x3e\x01\x37\x17\x0e\ +\x03\x06\xa4\x22\x34\x26\x1b\x0d\x95\x9f\x1c\x02\x35\xd4\x75\x56\ +\x42\x3c\x26\x23\x31\x19\x12\x16\x11\x34\x2d\x44\x26\x23\x0e\x0d\ +\x17\x85\x97\x26\x63\x80\x43\x3e\x5a\x3d\x27\x22\x31\x19\x12\x16\ +\x10\x20\xfd\x0a\x36\x26\x09\x54\x04\x10\x1b\x10\x21\x26\x1e\x07\ +\x5c\x97\x6a\x04\x10\x1b\x10\x21\x26\x1e\x07\x5c\x97\x63\x07\x15\ +\x13\x50\x27\x38\x1b\x35\x35\x56\x3c\x46\x07\x56\x82\x41\x13\x18\ +\x20\x28\x40\x38\x2b\x39\x0d\x4a\x07\x15\x15\x4f\x26\x38\x1b\x35\ +\x35\x56\x04\xd8\x34\x65\x6f\x50\x3f\xb2\x08\xfe\xc6\xfe\xa4\x33\ +\x3e\x3b\x4d\x23\x1f\x1d\x25\x10\x0f\x10\x6a\xab\xd9\x6e\x57\x57\ +\x3f\x75\xb6\x73\x39\x39\x3a\x4d\x23\x1f\x1c\x26\x10\x0f\x07\x09\ +\xfc\x31\x46\x2f\x01\xa2\x17\x11\x08\x15\x2f\x22\xfe\x39\x02\x0d\ +\x17\x11\x08\x15\x2f\x22\xfe\x39\x01\xed\x25\x77\x70\x18\x44\x71\ +\x51\x2d\x41\x41\x41\x12\x19\x0f\x07\x4d\x3f\xfe\x95\x25\x01\x77\ +\x6f\x18\x44\x71\x51\x2d\x00\x00\x02\x00\xb8\xff\xf1\x05\x8b\x05\ +\x1e\x00\x3d\x00\x75\x00\x00\x01\x22\x0e\x02\x07\x33\x15\x23\x06\ +\x07\x0a\x01\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x23\ +\x22\x06\x15\x14\x33\x32\x3e\x02\x37\x36\x37\x23\x35\x33\x3e\x02\ +\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x36\x35\ +\x34\x26\x01\x34\x26\x23\x22\x06\x15\x14\x1e\x04\x15\x14\x06\x23\ +\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x15\x14\x16\x33\x32\ +\x36\x35\x34\x2e\x04\x35\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\ +\x26\x35\x34\x36\x04\xf2\x21\x34\x26\x1b\x0d\x95\x9f\x1c\x02\x35\ +\xd4\x76\x55\x43\x3d\x27\x22\x31\x19\x12\x16\x10\x32\x2e\x44\x26\ +\x23\x0e\x0d\x17\x85\x98\x25\x63\x80\x42\x3f\x59\x3c\x26\x23\x31\ +\x19\x12\x16\x11\x21\xfd\x34\x23\x1f\x38\x2c\x26\x3a\x43\x3a\x26\ +\x9e\x74\x5a\x72\x30\x20\x1b\x25\x12\x3a\x29\x2c\x3a\x25\x38\x40\ +\x38\x25\x83\x71\x55\x66\x28\x1a\x20\x20\x07\x04\xd8\x34\x65\x6f\ +\x50\x3f\xb2\x08\xfe\xc6\xfe\xa4\x33\x3e\x3b\x4d\x23\x1f\x1d\x25\ +\x10\x0f\x10\x6a\xab\xd9\x6e\x57\x57\x3f\x75\xb6\x73\x39\x39\x3a\ +\x4d\x23\x1f\x1c\x26\x10\x0f\x07\x09\xfe\x3c\x11\x24\x23\x31\x1b\ +\x30\x21\x2f\x30\x51\x32\x53\x51\x48\x43\x31\x32\x23\x16\x10\x18\ +\x0b\x1f\x23\x33\x27\x25\x37\x20\x27\x28\x48\x30\x50\x59\x55\x3c\ +\x18\x20\x1f\x15\x07\x13\x00\x00\x02\x00\x8b\xff\xf1\x05\x95\x05\ +\x1e\x00\x29\x00\x66\x00\x00\x01\x32\x36\x35\x34\x23\x22\x26\x35\ +\x34\x36\x33\x32\x16\x15\x14\x23\x22\x26\x23\x22\x06\x07\x23\x35\ +\x01\x23\x22\x07\x06\x07\x23\x37\x21\x15\x01\x36\x33\x32\x1e\x02\ +\x01\x22\x0e\x02\x07\x33\x15\x23\x06\x07\x0a\x01\x23\x22\x26\x35\ +\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\x06\x15\x14\x33\x32\x3e\ +\x02\x37\x36\x37\x23\x35\x33\x3e\x02\x33\x32\x16\x15\x14\x06\x23\ +\x22\x26\x35\x34\x36\x33\x32\x35\x34\x26\x04\xd8\x19\x29\x22\x24\ +\x2c\x28\x2e\x31\x2f\xba\x1f\x73\x2a\x2d\x39\x20\x4e\x01\xaa\x80\ +\x2f\x23\x10\x0c\x32\x28\x01\xce\xfe\x6c\x16\x1a\x1e\x30\x19\x28\ +\xfe\xae\x21\x34\x27\x1a\x0e\x95\x9f\x1c\x01\x35\xd5\x75\x55\x43\ +\x3c\x27\x22\x32\x19\x13\x15\x11\x33\x2e\x43\x26\x24\x0e\x0c\x18\ +\x86\x98\x25\x63\x81\x42\x3f\x59\x3c\x27\x22\x32\x19\x13\x26\x21\ +\x01\x52\x1b\x0c\x11\x29\x1f\x25\x25\x50\x3c\xa4\x51\x11\x19\x1d\ +\x01\xc7\x15\x08\x22\xc8\x5b\xfe\x82\x03\x1c\x20\x1c\x03\x86\x34\ +\x65\x6f\x50\x3f\xb1\x09\xfe\xc6\xfe\xa4\x33\x3e\x3b\x4d\x23\x1f\ +\x1d\x25\x10\x0f\x10\x6a\xab\xd9\x6e\x57\x57\x3f\x75\xb6\x73\x39\ +\x39\x3a\x4d\x23\x1f\x1c\x26\x1f\x07\x09\x00\x00\x03\x00\xb8\xff\ +\xf1\x07\x1a\x05\x1e\x00\x2a\x00\x68\x00\xa0\x00\x00\x01\x32\x36\ +\x35\x34\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x23\x22\x2e\ +\x01\x23\x22\x06\x07\x23\x35\x01\x23\x22\x07\x06\x07\x23\x37\x21\ +\x15\x01\x36\x33\x32\x1e\x02\x01\x22\x0e\x02\x07\x33\x15\x23\x06\ +\x07\x0a\x01\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x23\ +\x22\x06\x15\x14\x33\x32\x3e\x02\x37\x36\x37\x23\x35\x33\x3e\x02\ +\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x36\x35\ +\x34\x26\x01\x34\x26\x23\x22\x06\x15\x14\x1e\x04\x15\x14\x06\x23\ +\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x15\x14\x16\x33\x32\ +\x36\x35\x34\x2e\x04\x35\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\ +\x26\x35\x34\x36\x06\x5d\x19\x2a\x23\x24\x2c\x28\x2f\x30\x2f\xb9\ +\x1b\x3d\x42\x22\x2d\x3a\x1f\x4e\x01\xaa\x80\x2f\x24\x10\x0c\x31\ +\x28\x01\xce\xfe\x6b\x17\x19\x1f\x2f\x19\x29\xfe\xad\x21\x34\x26\ +\x1b\x0d\x95\x9f\x1c\x02\x35\xd4\x76\x55\x43\x3d\x27\x22\x31\x19\ +\x12\x16\x10\x32\x2e\x44\x26\x23\x0e\x0d\x17\x85\x98\x25\x63\x80\ +\x42\x3f\x59\x3c\x26\x23\x31\x19\x12\x16\x11\x21\xfd\x34\x23\x1f\ +\x38\x2c\x26\x3a\x43\x3a\x26\x9e\x74\x5a\x72\x30\x20\x1b\x25\x12\ +\x3a\x29\x2c\x3a\x25\x38\x40\x38\x25\x83\x71\x55\x66\x28\x1a\x20\ +\x20\x07\x01\x52\x1b\x0c\x11\x29\x1f\x25\x25\x50\x3c\xa4\x28\x29\ +\x11\x19\x1d\x01\xc7\x15\x08\x22\xc8\x5b\xfe\x82\x03\x1c\x20\x1c\ +\x03\x86\x34\x65\x6f\x50\x3f\xb2\x08\xfe\xc6\xfe\xa4\x33\x3e\x3b\ +\x4d\x23\x1f\x1d\x25\x10\x0f\x10\x6a\xab\xd9\x6e\x57\x57\x3f\x75\ +\xb6\x73\x39\x39\x3a\x4d\x23\x1f\x1c\x26\x10\x0f\x07\x09\xfe\x3c\ +\x11\x24\x23\x31\x1b\x30\x21\x2f\x30\x51\x32\x53\x51\x48\x43\x31\ +\x32\x23\x16\x10\x18\x0b\x1f\x23\x33\x27\x25\x37\x20\x27\x28\x48\ +\x30\x50\x59\x55\x3c\x18\x20\x1f\x15\x07\x13\x00\x01\x00\xc8\x01\ +\x8e\x0a\xf0\x04\xd8\x00\x0b\x00\x00\x13\x11\x33\x11\x21\x11\x33\ +\x11\x23\x11\x21\x11\xc8\x46\x09\x9c\x46\x46\xf6\x64\x01\x8e\x03\ +\x4a\xff\x00\x01\x00\xfc\xb6\x01\x00\xff\x00\xff\xff\x00\xc8\x00\ +\x00\x06\x28\x06\x66\x10\x27\x00\x3e\x04\x98\x00\x00\x10\x27\x00\ +\x36\x03\xac\x00\x00\x10\x26\x00\x3e\x00\x00\x10\x07\x00\x38\x01\ +\x64\x00\x00\x00\x03\x00\x90\x01\x8e\x05\x51\x06\x66\x00\x3b\x00\ +\x43\x00\x4b\x00\x00\x01\x36\x16\x07\x02\x21\x22\x2e\x01\x02\x35\ +\x34\x3e\x01\x33\x32\x16\x15\x14\x0e\x01\x07\x06\x26\x35\x34\x36\ +\x33\x32\x16\x15\x14\x06\x23\x22\x26\x27\x26\x06\x15\x14\x16\x33\ +\x32\x36\x35\x34\x26\x23\x22\x02\x15\x14\x12\x04\x33\x32\x3e\x02\ +\x26\x34\x36\x32\x16\x14\x06\x22\x02\x34\x36\x32\x16\x14\x06\x22\ +\x04\xed\x0e\x46\x0c\xcb\xfe\x81\x78\xd8\xa8\x63\x70\xe1\x9e\xcb\ +\xf6\x56\xa0\x67\x98\xd1\x89\x5a\x75\x67\x6f\x3b\x20\x38\x14\x11\ +\x1e\x7a\x70\x7c\x8c\xb7\xa4\xae\xd9\x93\x01\x04\x9a\x4d\x86\x6b\ +\x51\x3c\x3b\x53\x3a\x3a\x53\x3b\x3b\x53\x3a\x3a\x53\x03\x23\x14\ +\x2b\x15\xfe\x97\x5c\xa9\x01\x07\x9f\xa5\xf9\x8f\xd9\xc3\x6d\xb7\ +\x73\x06\x09\xd3\xa8\x54\xa4\x62\x62\x46\x57\x23\x01\x01\x11\x0c\ +\x5f\x69\xbe\x8c\x9f\xc0\xfe\xfe\xbf\x94\xfe\xf9\xa2\x28\x4c\x55\ +\xe7\x52\x3b\x3b\x52\x3b\x01\xc9\x52\x3b\x3b\x52\x3b\x00\x00\xff\ +\xff\x00\x90\x01\x8e\x05\x51\x08\x40\x10\x27\x00\x1c\x02\x26\x06\ +\x51\x10\x06\x00\x12\x00\x00\xff\xff\x00\x90\xff\xb0\x05\x51\x06\ +\x66\x10\x27\x00\x1c\x02\x26\xff\xb5\x10\x06\x00\x12\x00\x00\x00\ +\x07\x00\xc8\xff\xe2\x02\x80\x06\x84\x00\x03\x00\x07\x00\x16\x00\ +\x1f\x00\x25\x00\x2d\x00\x30\x00\x00\x13\x21\x15\x21\x37\x33\x11\ +\x23\x03\x33\x32\x16\x15\x14\x07\x16\x15\x14\x06\x2b\x02\x11\x17\ +\x15\x33\x32\x36\x35\x34\x26\x23\x07\x15\x33\x32\x34\x23\x13\x23\ +\x27\x23\x07\x23\x13\x33\x03\x33\x27\xc8\x01\xb8\xfe\x48\xb4\x50\ +\x50\x3c\x96\x35\x52\x2d\x46\x42\x47\xad\x50\x50\x91\x1e\x19\x1f\ +\x18\x91\xa6\x3b\x3b\x9a\x5a\x28\xb3\x28\x5b\xb4\x50\x65\x7b\x3e\ +\x06\x84\x50\x11\xfe\x4b\xfd\x46\x56\x38\x49\x17\x24\x4e\x42\x52\ +\x01\xf4\x50\x7c\x1e\x20\x1a\x24\xcc\x88\x88\x01\x7f\x73\x73\x01\ +\xf4\xfe\xcf\xb1\x00\x00\x00\x00\x02\x00\xc8\x00\x00\x04\xe9\x06\ +\x66\x00\x03\x00\x2f\x00\x00\x01\x11\x23\x11\x01\x23\x11\x33\x11\ +\x21\x11\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\x26\x22\x06\x16\ +\x07\x11\x21\x15\x21\x11\x16\x06\x16\x32\x36\x33\x32\x16\x15\x14\ +\x06\x23\x22\x26\x35\x11\x21\x01\xa6\xde\x01\xba\x50\x50\x01\x0a\ +\x72\x6e\x33\x4a\x41\x2d\x19\x31\x3c\x1a\x02\x01\xfe\xa6\x01\x5a\ +\x01\x02\x1a\x3c\x31\x19\x2d\x41\x4a\x33\x6e\x72\xfe\xf6\x06\x66\ +\xf9\x9a\x06\x66\xf9\x9a\x06\x66\xfd\xb4\x01\x3a\x72\xa0\x52\x34\ +\x2a\x36\x3e\x34\x46\x22\xfe\x62\xa2\xfe\x62\x22\x46\x34\x3e\x36\ +\x2a\x34\x52\xa0\x72\x01\x3a\x00\x06\x00\xbe\x01\x90\x0a\x40\x04\ +\xd6\x00\x07\x00\x0b\x00\x0f\x00\x13\x00\x1b\x00\x1f\x00\x00\x00\ +\x34\x36\x32\x16\x14\x06\x22\x13\x01\x23\x01\x23\x01\x23\x01\x21\ +\x01\x23\x01\x00\x34\x36\x32\x16\x14\x06\x22\x09\x01\x23\x01\x09\ +\x6e\x3a\x53\x3b\x3b\x53\x98\xfd\x8e\xf4\x02\x70\xda\xfd\x8f\xf5\ +\x02\x71\xfe\x79\xfd\x8e\xf4\x02\x70\xfb\xca\x3b\x52\x3b\x3b\x52\ +\x03\x21\xfd\x8f\xf5\x02\x71\x02\x43\x52\x3b\x3b\x52\x3b\x02\xce\ +\xfc\xba\x03\x46\xfc\xba\x03\x46\xfc\xba\x03\x46\xfe\xfb\x52\x3b\ +\x3b\x52\x3b\x01\x40\xfc\xba\x03\x46\x00\x00\x00\x03\x00\xc9\x01\ +\x0e\x0a\x50\x03\x9c\x00\x03\x00\x07\x00\x0e\x00\x00\x01\x33\x35\ +\x23\x07\x11\x21\x11\x37\x01\x17\x09\x01\x07\x01\x01\x0f\x9a\x9a\ +\x46\x01\x26\x37\x08\x20\x0a\xf8\xd8\x07\x28\x0a\xf7\xe0\x02\x09\ +\x9a\xe0\x01\x26\xfe\xda\xb5\x01\x24\x45\xfe\xfe\xfe\xfe\x45\x01\ +\x24\x00\x00\x00\x02\x00\xc8\x01\x0e\x11\x8a\x03\x9c\x00\x06\x00\ +\x0d\x00\x00\x13\x01\x17\x09\x01\x07\x01\x25\x15\x01\x27\x09\x01\ +\x37\xc8\x08\x20\x0a\xf8\xd8\x07\x28\x0a\xf7\xe0\x10\xc2\xf7\xe0\ +\x0a\x07\x28\xf8\xd8\x0a\x02\x78\x01\x24\x45\xfe\xfe\xfe\xfe\x45\ +\x01\x24\x46\x46\xfe\xdc\x45\x01\x02\x01\x02\x45\x00\x00\x00\x00\ +\x01\x00\xc8\x01\x8e\x07\x3a\x04\xd8\x00\x0b\x00\x00\x01\x23\x11\ +\x21\x11\x23\x11\x21\x11\x23\x11\x21\x07\x3a\x64\xfd\x4e\x46\xfd\ +\x4e\x64\x06\x72\x01\x8e\x02\xe6\xfe\xa8\x01\x58\xfd\x1a\x03\x4a\ +\x00\x00\x00\x00\x01\x00\xc8\x01\x5e\x0c\xd6\x04\x77\x00\x0e\x00\ +\x00\x09\x01\x21\x11\x33\x11\x21\x09\x01\x21\x11\x33\x11\x21\x01\ +\x06\xe6\x01\xa1\x04\x09\x46\xfb\x89\xfe\x70\xfe\x70\xfb\x89\x46\ +\x04\x09\x01\xa2\x04\x77\xfd\x2d\x02\xd2\xfc\xe8\x02\xb5\xfd\x4b\ +\x03\x18\xfd\x2e\x02\xd3\x00\x00\x03\x00\x1c\xff\xfb\x01\x5e\x01\ +\xef\x00\x09\x00\x16\x00\x2a\x00\x00\x37\x0e\x01\x15\x14\x16\x32\ +\x36\x35\x34\x27\x3e\x01\x35\x34\x26\x22\x06\x15\x14\x1e\x02\x17\ +\x1e\x01\x15\x14\x20\x35\x34\x36\x37\x2e\x01\x35\x34\x36\x32\x16\ +\x15\x14\x06\xa9\x28\x31\x3c\x62\x3c\x5d\x2a\x24\x37\x4e\x37\x11\ +\x24\x1e\x43\x2e\x3b\xfe\xbe\x3a\x2d\x29\x2a\x56\x6e\x56\x2d\xf4\ +\x13\x3d\x21\x39\x34\x34\x39\x3d\x5f\x11\x29\x25\x28\x2e\x2e\x28\ +\x16\x20\x15\x0c\x17\x17\x4e\x28\x88\x88\x25\x46\x15\x12\x36\x33\ +\x31\x40\x40\x31\x2d\x32\x00\x00\x04\x00\xc8\xfe\x8d\x04\x10\x03\ +\x2f\x00\x07\x00\x0b\x00\x13\x00\x17\x00\x00\x05\x11\x33\x11\x25\ +\x11\x23\x11\x03\x15\x37\x35\x01\x11\x33\x11\x25\x11\x23\x11\x03\ +\x15\x37\x35\x02\x94\x46\x01\x36\x46\xf0\xf0\xfc\xfe\x46\x01\x36\ +\x46\xf0\xf0\x28\x03\x57\xfe\x8c\x29\xfc\xa9\x01\x74\x01\x2d\xbb\ +\x1b\xbb\xfe\x8f\x03\x57\xfe\x8c\x29\xfc\xa9\x01\x74\x01\x2d\xbb\ +\x1b\xbb\x00\x00\x04\x00\xc8\xfe\x8d\x04\x10\x03\xe1\x00\x0d\x00\ +\x19\x00\x21\x00\x25\x00\x00\x05\x11\x33\x11\x3e\x02\x33\x32\x16\ +\x15\x14\x06\x07\x19\x01\x3e\x03\x35\x34\x23\x22\x0e\x01\x01\x11\ +\x33\x11\x25\x11\x23\x11\x03\x15\x37\x35\x02\x94\x46\x25\x25\x40\ +\x2a\x42\x40\xa1\x95\x2a\x39\x36\x1b\x32\x1a\x22\x26\xfd\xce\x46\ +\x01\x36\x46\xf0\xf0\x28\x04\x09\xfd\x8b\x1c\x18\x13\x5c\x43\x49\ +\x9a\x59\x01\x49\xff\x00\x1e\x32\x40\x47\x27\x44\x0c\x1e\xfe\x9f\ +\x03\x57\xfe\x8c\x29\xfc\xa9\x01\x74\x01\x2d\xbb\x1b\xbb\x00\x00\ +\x04\x00\xc8\xfe\x84\x04\x10\x03\x38\x00\x1b\x00\x1f\x00\x27\x00\ +\x2b\x00\x00\x05\x11\x23\x11\x07\x35\x37\x35\x07\x35\x37\x11\x33\ +\x11\x37\x11\x33\x11\x37\x15\x07\x15\x37\x15\x07\x11\x23\x11\x27\ +\x37\x35\x07\x01\x11\x33\x11\x25\x11\x23\x11\x03\x15\x37\x35\x03\ +\x20\x46\x46\x46\x46\x46\x46\x64\x46\x46\x46\x46\x46\x46\x64\x64\ +\x64\xfd\xa8\x46\x01\x36\x46\xf0\xf0\x16\xfe\x9a\x01\x5d\x09\x8c\ +\x09\xc2\x09\x8c\x09\x01\x3f\xfe\xca\x0e\x01\x66\xfe\xa3\x09\x8c\ +\x09\xc2\x09\x8c\x09\xfe\xc1\x01\x36\x7e\x0e\xc2\x0e\xfe\xa0\x03\ +\x57\xfe\x8c\x29\xfc\xa9\x01\x74\x01\x2d\xbb\x1b\xbb\x00\x00\x00\ +\x01\x00\xc8\xfe\x84\x01\xa4\x02\xfa\x00\x13\x00\x00\x05\x11\x23\ +\x11\x07\x35\x37\x35\x07\x35\x37\x11\x33\x11\x37\x15\x07\x15\x37\ +\x15\x01\x54\x46\x46\x46\x46\x46\x46\x50\x50\x50\x16\xfe\x9a\x01\ +\x5d\x09\x8c\x09\xc2\x09\x8c\x09\x01\x3f\xfe\xca\x0b\x8c\x0b\xc2\ +\x0b\x8c\x00\x00\x03\x00\xc8\xfe\x84\x02\xee\x03\x4e\x00\x23\x00\ +\x27\x00\x2b\x00\x00\x05\x11\x23\x11\x07\x35\x37\x35\x07\x35\x37\ +\x11\x33\x11\x37\x11\x33\x11\x37\x11\x33\x11\x37\x15\x07\x15\x37\ +\x15\x07\x11\x23\x11\x07\x11\x23\x11\x13\x07\x15\x37\x27\x07\x15\ +\x37\x01\x54\x46\x46\x46\x46\x46\x46\x64\x46\x64\x46\x46\x46\x46\ +\x46\x46\x64\x46\xaa\x64\x64\xaa\x64\x64\x16\xfe\x9a\x01\x5d\x09\ +\x8c\x09\xc2\x09\x8c\x09\x01\x3f\xfe\xca\x0e\x01\x52\xfe\xb7\x0d\ +\x01\x66\xfe\xa3\x09\x8c\x09\xc2\x09\x8c\x09\xfe\xc1\x01\x36\x0d\ +\xfe\xad\x01\x4a\x01\x64\x0d\xc2\x0d\xac\x0e\xc2\x0e\x00\x00\x00\ +\x02\x00\xc8\xff\xd8\x02\x44\x03\xe1\x00\x0d\x00\x19\x00\x00\x05\ +\x23\x2e\x01\x35\x34\x36\x33\x32\x1e\x01\x17\x11\x33\x03\x2e\x02\ +\x23\x22\x15\x14\x1e\x02\x17\x02\x44\x46\x95\xa1\x40\x42\x2a\x40\ +\x25\x25\x46\x46\x20\x26\x22\x1a\x32\x1b\x36\x39\x2a\x28\x59\x9a\ +\x49\x43\x5c\x13\x18\x1c\x02\x75\xfd\x40\x18\x1e\x0c\x44\x27\x47\ +\x40\x32\x1e\x00\x04\x00\xc8\xff\xd8\x04\x06\x03\xe1\x00\x0d\x00\ +\x19\x00\x27\x00\x33\x00\x00\x05\x11\x33\x11\x3e\x02\x33\x32\x16\ +\x15\x14\x06\x07\x19\x01\x3e\x03\x35\x34\x23\x22\x0e\x01\x03\x23\ +\x2e\x01\x35\x34\x36\x33\x32\x1e\x01\x17\x11\x33\x03\x2e\x02\x23\ +\x22\x15\x14\x1e\x02\x17\x02\x8a\x46\x25\x25\x40\x2a\x42\x40\xa1\ +\x95\x2a\x39\x36\x1b\x32\x1a\x22\x26\xac\x46\x95\xa1\x40\x42\x2a\ +\x40\x25\x25\x46\x46\x20\x26\x22\x1a\x32\x1b\x36\x39\x2a\x28\x04\ +\x09\xfd\x8b\x1c\x18\x13\x5c\x43\x49\x9a\x59\x01\x49\xff\x00\x1e\ +\x32\x40\x47\x27\x44\x0c\x1e\xfe\x9f\x59\x9a\x49\x43\x5c\x13\x18\ +\x1c\x02\x75\xfd\x40\x18\x1e\x0c\x44\x27\x47\x40\x32\x1e\x00\x00\ +\x02\x00\x50\xff\xf3\x03\xe8\x05\x85\x00\x1b\x00\x2f\x00\x00\x24\ +\x32\x3e\x05\x34\x2e\x05\x22\x0e\x05\x14\x1e\x04\x12\x32\x1e\x03\ +\x14\x0e\x03\x22\x2e\x03\x34\x3e\x02\x01\xe3\x72\x5a\x3c\x2b\x18\ +\x0d\x03\x03\x0d\x18\x2b\x3c\x5a\x72\x5a\x3c\x2b\x18\x0d\x03\x03\ +\x0d\x18\x2b\x3c\x33\xc0\x9d\x68\x48\x1f\x1f\x48\x68\x9d\xc0\x9d\ +\x68\x48\x1f\x1f\x48\x68\x3e\x2c\x44\x6c\x67\x8c\x69\x8c\x69\x8c\ +\x67\x6c\x44\x2c\x2c\x44\x6c\x67\x8c\x69\x8c\x69\x8c\x67\x6c\x44\ +\x05\x1b\x55\x8d\xbb\xc5\xce\xc5\xbb\x8d\x55\x55\x8d\xbb\xc5\xce\ +\xc5\xbb\x8d\x00\x01\x00\xd7\x00\x00\x03\x61\x05\x85\x00\x2f\x00\ +\x00\x29\x01\x22\x26\x35\x34\x33\x32\x3e\x04\x35\x11\x34\x36\x26\ +\x27\x26\x0f\x01\x0e\x02\x27\x26\x27\x26\x3f\x01\x36\x33\x32\x16\ +\x15\x11\x14\x1e\x04\x33\x32\x15\x14\x06\x03\x38\xfd\xc8\x14\x15\ +\x41\x1d\x22\x32\x1d\x1e\x0d\x01\x07\x09\x10\x27\x5a\x05\x0f\x0c\ +\x08\x1c\x02\x02\x1b\xdc\x16\x2a\x1b\x2c\x0d\x1e\x1d\x32\x22\x1d\ +\x41\x15\x14\x0d\x2a\x01\x04\x0b\x11\x1c\x13\x03\xee\x0d\x15\x14\ +\x06\x0c\x16\x32\x03\x0c\x06\x01\x03\x19\x21\x15\xad\x11\x20\x19\ +\xfb\x4f\x13\x1c\x11\x0b\x04\x01\x2a\x0d\x14\x00\x01\x00\x54\xff\ +\xf3\x03\xcc\x05\xd0\x00\x35\x00\x00\x01\x0e\x03\x23\x21\x03\x32\ +\x04\x16\x15\x14\x0e\x02\x23\x22\x26\x27\x2e\x01\x35\x34\x36\x33\ +\x32\x1e\x01\x17\x1e\x02\x33\x32\x36\x35\x34\x2e\x02\x23\x13\x21\ +\x32\x36\x37\x36\x37\x36\x33\x32\x15\x14\x03\x70\x0f\x17\x28\x34\ +\x20\xfe\xac\x4e\xba\x01\x36\xb0\x50\x87\x9e\x57\x60\x8a\x46\x3f\ +\x3d\x20\x18\x11\x1d\x1e\x07\x2f\x43\x65\x4a\x85\xb1\x4e\x91\xf1\ +\x91\x77\x01\x8a\x35\x39\x18\x01\x01\x05\x07\x0f\x05\x89\x22\x2c\ +\x35\x1b\xfe\xc4\x8a\xeb\x8a\x73\xb1\x66\x33\x2d\x27\x23\x3a\x2a\ +\x18\x1a\x17\x2b\x06\x30\x2e\x1c\xc6\xac\x43\x8b\x7a\x4e\x02\x32\ +\x26\x26\x01\x02\x09\x12\x1e\x00\x03\x00\x50\xff\xf3\x03\xe8\x05\ +\x85\x00\x11\x00\x21\x00\x3c\x00\x00\x01\x0e\x01\x15\x14\x1e\x02\ +\x32\x3e\x02\x35\x34\x2e\x03\x37\x3e\x01\x35\x34\x26\x22\x06\x15\ +\x14\x1e\x05\x17\x1e\x01\x15\x10\x20\x11\x34\x36\x37\x2e\x04\x35\ +\x34\x3e\x01\x32\x1e\x01\x15\x14\x0e\x02\x01\xe1\x71\x8a\x30\x56\ +\x6d\x86\x6d\x56\x30\x2c\x46\x63\x63\x30\x78\x66\x9c\xe0\x9c\x13\ +\x1c\x33\x2e\x4a\x35\x9e\x81\xaa\xfc\x68\xa6\x80\x2c\x43\x3f\x27\ +\x18\x76\xb7\xcc\xb7\x76\x25\x46\x50\x02\xba\x38\xad\x5f\x54\x7b\ +\x47\x22\x22\x47\x7b\x54\x29\x50\x42\x40\x31\x92\x30\x76\x69\x73\ +\x84\x84\x73\x24\x3e\x2e\x29\x1b\x1d\x11\x39\x41\xdd\x74\xfe\x7d\ +\x01\x83\x6a\xc7\x3e\x14\x28\x3b\x47\x63\x3d\x5e\x96\x4e\x4e\x96\ +\x5e\x43\x6a\x49\x30\x00\x00\x00\x01\x00\x64\x01\x06\x03\x92\x04\ +\xef\x00\x34\x00\x00\x01\x22\x26\x27\x26\x23\x22\x0e\x03\x15\x14\ +\x1e\x01\x33\x32\x3e\x02\x33\x32\x16\x15\x14\x0e\x02\x23\x22\x2e\ +\x01\x35\x34\x3e\x03\x33\x32\x17\x1e\x02\x33\x32\x3e\x01\x33\x32\ +\x0f\x01\x06\x03\x5b\x07\x0e\x0b\x46\x8a\x49\x7d\x54\x3c\x1b\x38\ +\x72\x48\x41\x6a\x32\x24\x04\x07\x17\x2c\x4b\x7d\x45\x72\xad\x53\ +\x2a\x5b\x7c\xb6\x67\x2a\x51\x0b\x0f\x0b\x12\x16\x23\x16\x05\x0e\ +\x09\x1c\x06\x04\x19\x3f\x0b\x46\x44\x6e\x8b\x8a\x41\x4b\x99\x71\ +\x2a\x31\x2a\x12\x06\x0c\x37\x40\x30\x7d\xbc\x6a\x3c\x95\x9e\x83\ +\x54\x1e\x05\x04\x01\x14\x14\x2e\x89\x1f\x00\x00\x02\x00\x4b\x01\ +\x13\x04\x21\x04\xe2\x00\x13\x00\x39\x00\x00\x01\x0e\x01\x1e\x03\ +\x33\x32\x3e\x03\x35\x34\x26\x23\x22\x06\x07\x27\x21\x32\x1e\x04\ +\x15\x14\x06\x04\x23\x21\x22\x2e\x02\x35\x34\x3e\x03\x37\x3e\x01\ +\x37\x13\x36\x27\x2e\x03\x35\x34\x36\x01\x6c\x03\x01\x07\x0e\x22\ +\x29\x23\x50\x87\x5a\x3f\x1c\x8c\x80\x40\x26\x08\xd4\x01\x47\x30\ +\x5a\x67\x53\x46\x27\x9e\xfe\xfb\x98\xfe\xa0\x0e\x0e\x15\x0a\x0a\ +\x15\x10\x1b\x03\x20\x17\x04\x95\x09\x30\x07\x25\x13\x12\x25\x01\ +\x95\x0f\x11\x0f\x07\x05\x01\x41\x68\x85\x87\x41\xa3\xaa\x18\x26\ +\x84\x0d\x21\x40\x5c\x90\x5b\x98\xf9\x89\x01\x05\x0b\x0a\x0a\x10\ +\x08\x05\x04\x01\x06\x0f\x14\x02\xe3\x2f\x0b\x01\x06\x04\x0d\x0a\ +\x0d\x13\x00\x00\x01\x00\x46\x01\x06\x03\x09\x04\xef\x00\x4b\x00\ +\x00\x01\x2e\x03\x35\x34\x3e\x01\x33\x32\x1e\x01\x17\x1e\x02\x33\ +\x32\x3e\x01\x33\x32\x0f\x01\x06\x23\x22\x26\x27\x26\x23\x22\x06\ +\x15\x14\x16\x17\x1e\x03\x15\x14\x06\x23\x22\x27\x2e\x02\x23\x22\ +\x0e\x01\x23\x22\x3f\x01\x3e\x02\x33\x32\x1e\x01\x17\x1e\x01\x33\ +\x32\x36\x35\x34\x2e\x01\x01\x94\x3e\x3d\x36\x11\x5e\x79\x38\x26\ +\x3b\x1f\x13\x0b\x0f\x0b\x12\x16\x23\x16\x05\x0e\x09\x1c\x06\x10\ +\x07\x0e\x0b\x46\x8a\x3d\x3d\x49\x51\x3a\x3d\x41\x1b\x99\x8a\x86\ +\x51\x0b\x0f\x0b\x12\x16\x23\x16\x05\x0f\x0a\x25\x02\x03\x0a\x07\ +\x0a\x03\x0a\x10\x25\x61\x67\x40\x65\x27\x4c\x02\xeb\x2f\x34\x47\ +\x4a\x37\x44\x67\x2e\x0a\x0d\x07\x05\x04\x01\x14\x14\x2e\x89\x1f\ +\x3f\x0b\x46\x4b\x36\x39\x69\x38\x28\x32\x4a\x57\x39\x7d\x97\x1e\ +\x05\x04\x01\x14\x14\x2e\xae\x0a\x0a\x0b\x26\x39\x10\x25\x21\x64\ +\x43\x44\x52\x38\x00\x00\x00\x00\x01\x00\x5a\x01\x0e\x01\x08\x01\ +\xbe\x00\x07\x00\x00\x12\x34\x36\x32\x16\x14\x06\x22\x5a\x33\x48\ +\x33\x33\x48\x01\x42\x48\x34\x34\x48\x34\x00\x00\x02\x00\x5b\x01\ +\x03\x02\xfe\x03\x89\x00\x12\x00\x2f\x00\x00\x01\x22\x0e\x03\x15\ +\x14\x33\x32\x3e\x02\x37\x36\x37\x13\x36\x26\x03\x0e\x02\x22\x2e\ +\x02\x35\x34\x3e\x01\x33\x32\x16\x07\x03\x06\x33\x3e\x01\x37\x17\ +\x0e\x03\x23\x22\x01\xc4\x2f\x4d\x2d\x1f\x0b\x3e\x13\x1f\x0d\x1d\ +\x06\x01\x02\x54\x05\x0e\x3d\x15\x1b\x33\x4c\x3b\x3c\x21\x6a\xb2\ +\x5c\x48\x6a\x0d\x4a\x07\x15\x15\x4f\x26\x38\x1b\x35\x35\x56\x3c\ +\x2e\x03\x48\x37\x52\x66\x54\x23\x9e\x07\x07\x14\x03\x0b\x0a\x01\ +\xa2\x18\x10\xfd\xde\x0a\x0f\x0a\x11\x2d\x61\x48\x59\xc1\x85\x4d\ +\x3f\xfe\x95\x25\x01\x77\x6f\x18\x44\x71\x51\x2d\x00\x00\x00\x00\ +\x02\x00\x5b\x01\x09\x02\x8b\x05\x30\x00\x24\x00\x37\x00\x00\x13\ +\x34\x3e\x01\x37\x3e\x01\x33\x32\x16\x07\x03\x3e\x02\x33\x32\x16\ +\x15\x14\x0e\x03\x23\x22\x26\x27\x13\x36\x35\x34\x23\x22\x06\x23\ +\x22\x13\x07\x06\x15\x1c\x01\x15\x14\x16\x33\x32\x36\x37\x36\x35\ +\x34\x26\x23\x22\x90\x1f\x3e\x0e\x13\x61\x0f\x0f\x14\x02\x59\x1d\ +\x20\x3b\x29\x54\x50\x14\x31\x48\x74\x46\x70\x73\x06\x8f\x03\x16\ +\x0b\x24\x0c\x0c\x9d\x32\x08\x0e\x16\x2f\x77\x19\x14\x22\x28\x5d\ +\x04\xc6\x08\x0e\x14\x06\x07\x33\x10\x0c\xfe\x43\x13\x11\x0e\x6f\ +\x60\x2e\x6a\x79\x60\x40\x5f\x4e\x02\xd3\x0d\x06\x1e\x04\xfe\x24\ +\xfa\x28\x1c\x05\x12\x04\x1a\x1a\x7d\x7f\x6b\x37\x32\x2b\x00\x00\ +\x01\xff\x65\xff\xf1\x02\xdf\x05\x1e\x00\x3c\x00\x00\x01\x22\x0e\ +\x02\x07\x33\x15\x23\x06\x07\x0a\x01\x23\x22\x26\x35\x34\x36\x33\ +\x32\x16\x15\x14\x06\x23\x22\x06\x15\x14\x33\x32\x3e\x02\x37\x36\ +\x37\x23\x35\x33\x3e\x02\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\ +\x34\x36\x33\x32\x35\x34\x26\x02\x47\x21\x34\x27\x1a\x0e\x95\x9f\ +\x1c\x01\x35\xd5\x75\x55\x43\x3c\x27\x22\x32\x19\x13\x15\x11\x33\ +\x2e\x43\x26\x24\x0e\x0c\x18\x86\x98\x25\x63\x81\x42\x3f\x59\x3c\ +\x27\x22\x32\x19\x13\x26\x21\x04\xd8\x34\x65\x6f\x50\x3f\xb1\x09\ +\xfe\xc6\xfe\xa4\x33\x3e\x3b\x4d\x23\x1f\x1d\x25\x10\x0f\x10\x6a\ +\xab\xd9\x6e\x57\x57\x3f\x75\xb6\x73\x39\x39\x3a\x4d\x23\x1f\x1c\ +\x26\x1f\x07\x09\x00\x00\x00\x00\x01\x00\x54\x01\x09\x04\x99\x03\ +\x89\x00\x3e\x00\x00\x01\x22\x26\x37\x13\x36\x26\x23\x22\x0e\x02\ +\x07\x03\x23\x13\x36\x26\x23\x22\x0e\x02\x07\x03\x23\x13\x36\x23\ +\x22\x06\x07\x27\x3e\x03\x33\x32\x17\x36\x33\x32\x17\x3e\x03\x33\ +\x32\x16\x07\x03\x06\x33\x3e\x01\x37\x17\x0e\x03\x03\x82\x36\x26\ +\x09\x54\x04\x10\x1b\x10\x21\x26\x1e\x07\x5c\x97\x6a\x04\x10\x1b\ +\x10\x21\x26\x1e\x07\x5c\x97\x63\x07\x15\x13\x50\x27\x38\x1b\x35\ +\x35\x56\x3c\x46\x07\x56\x82\x41\x13\x18\x20\x28\x40\x38\x2b\x39\ +\x0d\x4a\x07\x15\x15\x4f\x26\x38\x1b\x35\x35\x56\x01\x09\x46\x2f\ +\x01\xa2\x17\x11\x08\x15\x2f\x22\xfe\x39\x02\x0d\x17\x11\x08\x15\ +\x2f\x22\xfe\x39\x01\xed\x25\x77\x70\x18\x44\x71\x51\x2d\x41\x41\ +\x41\x12\x19\x0f\x07\x4d\x3f\xfe\x95\x25\x01\x77\x6f\x18\x44\x71\ +\x51\x2d\x00\x00\x01\x00\x54\x01\x09\x03\xa0\x03\x89\x00\x2b\x00\ +\x00\x01\x32\x16\x07\x03\x06\x33\x3e\x01\x37\x17\x0e\x03\x23\x22\ +\x26\x37\x13\x36\x26\x23\x22\x06\x07\x03\x23\x13\x36\x23\x22\x06\ +\x07\x27\x3e\x03\x33\x32\x17\x3e\x01\x02\x8d\x31\x68\x0c\x4a\x07\ +\x15\x15\x4f\x26\x38\x1b\x35\x35\x56\x3c\x36\x26\x09\x54\x05\x17\ +\x23\x45\x4f\x0d\x5c\x97\x63\x07\x15\x13\x50\x27\x38\x1b\x35\x35\ +\x56\x3c\x46\x07\x30\x62\x03\x89\x50\x3c\xfe\x95\x25\x01\x77\x6f\ +\x18\x44\x71\x51\x2d\x46\x2f\x01\xa2\x17\x11\x2c\x42\xfe\x39\x01\ +\xed\x25\x77\x70\x18\x44\x71\x51\x2d\x41\x24\x1d\x00\x00\x00\x00\ +\x02\x00\x15\x00\x00\x03\x13\x03\x89\x00\x24\x00\x37\x00\x00\x01\ +\x14\x0e\x04\x23\x22\x27\x03\x33\x15\x21\x35\x33\x13\x36\x23\x22\ +\x06\x07\x27\x3e\x03\x33\x32\x17\x3e\x01\x33\x32\x1e\x02\x25\x07\ +\x06\x15\x14\x33\x32\x3e\x02\x37\x36\x35\x34\x23\x22\x0e\x02\x03\ +\x12\x0c\x1a\x30\x41\x62\x3b\x4a\x32\x34\x7d\xfe\x6a\x82\x8d\x07\ +\x15\x13\x50\x27\x38\x1c\x34\x36\x55\x3d\x46\x06\x33\x49\x3e\x2a\ +\x40\x25\x11\xfe\xa2\x32\x07\x35\x14\x2c\x33\x2d\x0e\x14\x48\x10\ +\x1e\x24\x1d\x02\xa9\x26\x53\x61\x55\x47\x2a\x36\xff\x00\x3f\x3f\ +\x02\xc1\x25\x77\x70\x18\x44\x71\x51\x2d\x41\x26\x1b\x24\x3f\x4e\ +\x02\xfa\x26\x1e\x4f\x15\x2f\x63\x44\x69\x39\x6e\x08\x15\x2f\x00\ +\x01\x00\x54\x01\x13\x02\x4a\x03\x89\x00\x23\x00\x00\x01\x32\x17\ +\x3e\x02\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\ +\x35\x34\x26\x23\x22\x07\x03\x23\x13\x36\x26\x23\x22\x07\x27\x36\ +\x01\x15\x2b\x12\x17\x12\x2f\x1f\x32\x4f\x2e\x31\x2f\x28\x2c\x24\ +\x23\x2a\x19\x50\x0f\x63\x97\x65\x02\x0b\x07\x17\x25\x30\x51\x03\ +\x89\x36\x16\x0e\x12\x49\x35\x3c\x50\x25\x25\x1f\x29\x11\x0c\x1b\ +\x4c\xfe\x16\x01\xf4\x0b\x13\x3d\x23\x7e\x00\x00\x01\x00\x5b\x01\ +\x03\x02\x57\x03\x89\x00\x36\x00\x00\x01\x34\x26\x23\x22\x06\x15\ +\x14\x1e\x04\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\ +\x14\x06\x15\x14\x16\x33\x32\x36\x35\x34\x2e\x03\x35\x34\x36\x33\ +\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x01\xdc\x23\x1f\x38\ +\x2c\x26\x3a\x43\x3a\x26\x9e\x74\x5a\x72\x30\x21\x1a\x25\x12\x3a\ +\x29\x2c\x3a\x34\x49\x49\x34\x83\x71\x55\x66\x28\x1a\x20\x20\x07\ +\x03\x14\x11\x24\x23\x31\x1b\x30\x21\x2f\x30\x51\x32\x53\x51\x48\ +\x43\x31\x32\x23\x16\x10\x18\x0b\x1f\x23\x33\x27\x2b\x3d\x27\x2c\ +\x4f\x39\x50\x59\x55\x3c\x18\x20\x1f\x15\x07\x13\x00\x00\x00\x00\ +\x01\x00\x4b\x01\x09\x02\xb2\x03\x89\x00\x31\x00\x00\x01\x32\x1e\ +\x01\x15\x14\x0e\x03\x23\x22\x26\x35\x34\x37\x13\x36\x26\x23\x22\ +\x07\x27\x36\x33\x32\x16\x07\x03\x06\x15\x1c\x01\x15\x14\x16\x33\ +\x32\x36\x37\x36\x35\x34\x26\x23\x22\x26\x35\x34\x36\x02\x51\x25\ +\x2c\x10\x14\x31\x48\x74\x46\x6e\x74\x04\x3a\x02\x0b\x07\x17\x25\ +\x30\x51\x70\x2f\x2c\x0b\x3a\x08\x29\x19\x56\x73\x28\x1a\x1e\x0f\ +\x12\x1f\x27\x03\x89\x38\x57\x40\x2e\x6a\x79\x60\x40\x5e\x42\x2d\ +\x14\x01\x1d\x0b\x13\x3d\x23\x7e\x54\x38\xfe\xe3\x27\x1d\x05\x12\ +\x04\x16\x1e\x5d\x76\x4c\x4b\x1e\x2f\x26\x1e\x1f\x22\x00\x00\x00\ +\x01\x00\x54\x00\xec\x02\xd4\x03\x80\x00\x2a\x00\x00\x01\x32\x36\ +\x35\x34\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x23\x22\x2e\ +\x01\x23\x22\x06\x07\x23\x35\x01\x23\x22\x07\x06\x07\x23\x37\x21\ +\x15\x01\x36\x33\x32\x1e\x02\x02\x17\x19\x2a\x23\x24\x2c\x28\x2f\ +\x30\x2f\xb9\x1b\x3d\x42\x22\x2d\x3a\x1f\x4e\x01\xaa\x80\x2f\x24\ +\x10\x0c\x31\x28\x01\xce\xfe\x6b\x17\x19\x1f\x2f\x19\x29\x01\x52\ +\x1b\x0c\x11\x29\x1f\x25\x25\x50\x3c\xa4\x28\x29\x11\x19\x1d\x01\ +\xc7\x15\x08\x22\xc8\x5b\xfe\x82\x03\x1c\x20\x1c\x00\x00\x00\x00\ +\x01\x00\xc8\x00\x00\x01\x18\x06\x66\x00\x03\x00\x00\x13\x33\x11\ +\x23\xc8\x50\x50\x06\x66\xf9\x9a\x00\x00\x00\x00\x02\x00\xc8\x00\ +\x00\x01\xf5\x06\x66\x00\x03\x00\x07\x00\x00\x01\x33\x11\x23\x03\ +\x33\x11\x23\x01\xa5\x50\x50\xdd\x50\x50\x06\x66\xf9\x9a\x06\x66\ +\xf9\x9a\x00\x00\x02\x00\xc8\x00\x00\x02\x84\x06\x66\x00\x03\x00\ +\x07\x00\x00\x01\x33\x11\x23\x03\x33\x11\x23\x01\xa4\xe0\xe0\xdc\ +\x50\x50\x06\x66\xf9\x9a\x06\x66\xf9\x9a\x00\x00\x02\x00\xc8\x00\ +\x00\x02\x84\x06\x66\x00\x03\x00\x07\x00\x00\x01\x11\x23\x11\x21\ +\x11\x23\x11\x01\xa8\xe0\x01\xbc\x50\x06\x66\xf9\x9a\x06\x66\xf9\ +\x9a\x06\x66\x00\x05\x00\xc8\x00\x00\x01\x18\x06\x66\x00\x03\x00\ +\x07\x00\x0b\x00\x0f\x00\x13\x00\x00\x37\x33\x15\x23\x11\x33\x11\ +\x23\x11\x33\x15\x23\x11\x33\x11\x23\x11\x33\x11\x23\xc8\x50\x50\ +\x50\x50\x50\x50\x50\x50\x50\x50\x99\x99\x05\x43\xfe\xfc\x02\x27\ +\x99\xfc\x5a\xfe\xfc\x02\x92\xfe\xfc\x00\x00\x00\x01\x00\xc8\x00\ +\xbf\x01\x18\x05\xa7\x00\x03\x00\x00\x13\x33\x11\x23\xc8\x50\x50\ +\x05\xa7\xfb\x18\x00\x00\x00\xff\xff\x00\xc8\x00\x00\x03\xe9\x06\ +\x66\x10\x27\x00\x3e\x02\x58\x00\x00\x10\x06\x00\x39\x00\x00\xff\ +\xff\x00\xc8\x00\x00\x03\xe8\x06\x66\x10\x26\x00\x3e\x00\x00\x10\ +\x07\x00\x38\x01\x64\x00\x00\x00\x02\x00\xc8\x02\x08\x01\x90\x04\ +\x5e\x00\x07\x00\x0f\x00\x00\x12\x34\x36\x32\x16\x14\x06\x22\x02\ +\x34\x36\x32\x16\x14\x06\x22\xc8\x3b\x52\x3b\x3b\x52\x3b\x3b\x52\ +\x3b\x3b\x52\x02\x43\x52\x3b\x3b\x52\x3b\x01\xc9\x52\x3b\x3b\x52\ +\x3b\x00\x00\x00\x05\x00\x96\x01\x06\x08\x52\x04\xef\x00\x50\x00\ +\x64\x00\x8a\x00\x92\x00\x9a\x00\x00\x01\x2e\x04\x35\x34\x3e\x02\ +\x33\x32\x1e\x01\x17\x1e\x02\x33\x32\x36\x33\x32\x0f\x01\x0e\x02\ +\x23\x22\x26\x27\x26\x23\x22\x06\x15\x14\x16\x17\x1e\x04\x15\x14\ +\x06\x23\x22\x26\x27\x2e\x02\x23\x22\x06\x23\x22\x3f\x01\x3e\x02\ +\x33\x32\x1e\x01\x17\x1e\x01\x33\x32\x36\x35\x34\x2e\x02\x01\x0e\ +\x01\x1e\x03\x33\x32\x3e\x03\x35\x34\x26\x23\x22\x06\x07\x27\x21\ +\x32\x1e\x04\x15\x14\x06\x04\x23\x21\x22\x2e\x02\x35\x34\x3e\x03\ +\x37\x3e\x01\x37\x13\x36\x27\x2e\x03\x35\x34\x36\x00\x34\x36\x32\ +\x16\x14\x06\x22\x24\x34\x36\x32\x16\x14\x06\x22\x06\x3c\x31\x35\ +\x36\x17\x0f\x37\x54\x5c\x29\x26\x3b\x1e\x13\x0b\x10\x0a\x13\x1d\ +\x33\x04\x0e\x0a\x1c\x02\x02\x0a\x08\x07\x0d\x0c\x46\x8a\x3c\x3e\ +\x49\x51\x2e\x34\x3d\x1f\x16\x99\x8b\x40\x79\x1d\x0b\x10\x0a\x13\ +\x1d\x33\x04\x0e\x0a\x24\x03\x02\x0a\x07\x0a\x04\x09\x11\x24\x61\ +\x67\x41\x65\x16\x2b\x40\xfb\x50\x03\x01\x07\x0e\x22\x29\x23\x50\ +\x87\x5a\x3f\x1c\x8c\x80\x40\x26\x08\xd4\x01\x47\x30\x5a\x67\x53\ +\x46\x27\x9e\xfe\xfb\x99\xfe\xa0\x0d\x0e\x15\x0a\x0a\x15\x10\x1b\ +\x03\x20\x17\x04\x95\x09\x30\x07\x25\x13\x11\x24\x02\x98\x33\x47\ +\x34\x34\x47\x03\x79\x33\x48\x33\x33\x48\x02\xeb\x25\x2c\x38\x33\ +\x43\x2c\x34\x56\x33\x1c\x0a\x0d\x07\x05\x04\x01\x28\x2e\x89\x0a\ +\x0a\x0b\x3f\x0b\x46\x4b\x36\x39\x69\x38\x20\x27\x3c\x37\x4c\x2e\ +\x7d\x97\x13\x0b\x05\x04\x01\x28\x2e\xae\x0a\x0a\x0b\x26\x39\x10\ +\x25\x21\x64\x43\x34\x46\x30\x30\xfe\xc8\x0f\x11\x0f\x07\x05\x01\ +\x41\x68\x85\x87\x41\xa3\xaa\x18\x26\x84\x0d\x21\x40\x5c\x90\x5b\ +\x98\xf9\x89\x01\x05\x0b\x0a\x0a\x10\x08\x05\x04\x01\x06\x0f\x14\ +\x02\xe3\x2f\x0b\x01\x06\x04\x0d\x0a\x0d\x13\xfc\x60\x48\x34\x34\ +\x48\x34\x34\x48\x34\x34\x48\x34\x00\x00\x00\x00\x05\x00\x96\x01\ +\x06\x08\x52\x04\xef\x00\x13\x00\x39\x00\x41\x00\x76\x00\x7e\x00\ +\x00\x01\x0e\x01\x1e\x03\x33\x32\x3e\x03\x35\x34\x26\x23\x22\x06\ +\x07\x27\x21\x32\x1e\x04\x15\x14\x06\x04\x23\x21\x22\x2e\x02\x35\ +\x34\x3e\x03\x37\x3e\x01\x37\x13\x36\x27\x2e\x03\x35\x34\x36\x00\ +\x34\x36\x32\x16\x14\x06\x22\x01\x22\x26\x27\x26\x23\x22\x0e\x03\ +\x15\x14\x1e\x01\x33\x32\x3e\x02\x33\x32\x16\x15\x14\x0e\x02\x23\ +\x22\x2e\x01\x35\x34\x3e\x03\x33\x32\x17\x1e\x02\x33\x32\x3e\x01\ +\x33\x32\x0f\x01\x06\x02\x34\x36\x32\x16\x14\x06\x22\x01\xb7\x03\ +\x01\x07\x0e\x22\x29\x23\x50\x87\x5a\x3f\x1c\x8c\x80\x40\x26\x08\ +\xd4\x01\x47\x30\x5a\x67\x53\x46\x27\x9e\xfe\xfb\x99\xfe\xa0\x0d\ +\x0e\x15\x0a\x0a\x15\x10\x1b\x03\x20\x17\x04\x95\x09\x30\x07\x25\ +\x13\x11\x24\x02\x98\x33\x47\x34\x34\x47\x03\x98\x07\x0e\x0b\x46\ +\x8a\x49\x7d\x54\x3c\x1b\x38\x72\x48\x41\x6a\x32\x24\x04\x07\x17\ +\x2c\x4b\x7d\x45\x72\xad\x53\x2a\x5b\x7c\xb6\x67\x2a\x51\x0b\x0f\ +\x0b\x12\x16\x23\x16\x05\x0e\x09\x1c\x06\x2f\x33\x48\x33\x33\x48\ +\x01\x95\x0f\x11\x0f\x07\x05\x01\x41\x68\x85\x87\x41\xa3\xaa\x18\ +\x26\x84\x0d\x21\x40\x5c\x90\x5b\x98\xf9\x89\x01\x05\x0b\x0a\x0a\ +\x10\x08\x05\x04\x01\x06\x0f\x14\x02\xe3\x2f\x0b\x01\x06\x04\x0d\ +\x0a\x0d\x13\xfc\x60\x48\x34\x34\x48\x34\x03\x0b\x3f\x0b\x46\x44\ +\x6e\x8b\x8a\x41\x4b\x99\x71\x2a\x31\x2a\x12\x06\x0c\x37\x40\x30\ +\x7d\xbc\x6a\x3c\x95\x9e\x83\x54\x1e\x05\x04\x01\x14\x14\x2e\x89\ +\x1f\xfd\x29\x48\x34\x34\x48\x34\x00\x00\x00\x00\x03\x00\x9d\x00\ +\xe4\x04\x63\x05\x5a\x00\x07\x00\x0f\x00\x4f\x00\x00\x12\x34\x36\ +\x32\x16\x14\x06\x22\x00\x34\x36\x32\x16\x14\x06\x22\x27\x1e\x04\ +\x15\x14\x06\x23\x22\x35\x34\x36\x33\x32\x1e\x02\x33\x32\x36\x35\ +\x34\x2e\x04\x27\x01\x23\x01\x2e\x04\x35\x34\x36\x33\x32\x15\x14\ +\x06\x23\x22\x2e\x02\x23\x22\x06\x15\x14\x1e\x04\x17\x01\x33\x9d\ +\x3b\x52\x3b\x3b\x52\x02\xc3\x3b\x52\x3b\x3b\x52\xe4\x37\x55\x55\ +\x38\x23\xa5\x78\xc6\x4b\x2a\x2d\x3c\x15\x14\x0a\x26\x3e\x19\x2d\ +\x3e\x49\x52\x2b\xfe\xe3\x7f\x01\x34\x37\x55\x55\x38\x23\xa5\x78\ +\xc6\x4b\x2a\x2d\x3c\x15\x14\x0a\x27\x3d\x19\x2d\x3e\x49\x52\x2b\ +\x01\x1d\x7f\x02\x51\x52\x3b\x3b\x52\x3b\x01\x85\x52\x3b\x3b\x52\ +\x3b\x0c\x14\x2b\x44\x50\x73\x45\x71\x8c\x7d\x38\x4a\x2e\x36\x2e\ +\x42\x33\x22\x39\x29\x23\x1a\x1c\x0c\xfe\x4b\x01\xd8\x14\x2b\x44\ +\x50\x73\x45\x71\x8c\x7d\x38\x4a\x2e\x36\x2e\x42\x33\x22\x39\x29\ +\x23\x1a\x1c\x0c\x01\xb5\x00\x00\x05\x00\x96\x00\xa0\x04\xce\x05\ +\xa0\x00\x1f\x00\x29\x00\x33\x00\x3d\x00\x47\x00\x00\x01\x33\x15\ +\x1e\x03\x17\x33\x15\x23\x0e\x03\x07\x15\x23\x35\x2e\x03\x27\x23\ +\x35\x33\x3e\x03\x37\x15\x0e\x06\x15\x33\x19\x01\x23\x14\x1e\x05\ +\x17\x3e\x06\x35\x23\x19\x01\x33\x34\x2e\x05\x02\x8a\x50\x4a\x7d\ +\x54\x33\x05\xa1\xa1\x05\x33\x54\x7d\x4a\x50\x4a\x7d\x54\x33\x05\ +\xa1\xa1\x05\x33\x54\x7d\x4a\x1a\x29\x1b\x13\x0a\x06\x01\x82\x82\ +\x01\x06\x0a\x13\x1b\x29\x6a\x1a\x29\x1b\x13\x0a\x06\x01\x82\x82\ +\x01\x06\x0a\x13\x1b\x29\x05\xa0\x98\x09\x52\x7c\x97\x52\x50\x52\ +\x97\x7c\x52\x09\x98\x98\x09\x52\x7c\x97\x52\x50\x52\x97\x7c\x52\ +\x09\x49\x06\x22\x29\x3f\x37\x4f\x38\x29\xfe\x39\x01\x77\x29\x38\ +\x4f\x37\x3f\x29\x22\x06\x06\x22\x29\x3f\x37\x4f\x38\x29\x01\xc7\ +\xfe\x89\x29\x38\x4f\x37\x3f\x29\x22\x00\x00\x00\x01\x00\xbe\x01\ +\x90\x04\x24\x04\xd6\x00\x03\x00\x00\x09\x01\x23\x01\x04\x24\xfd\ +\x8f\xf5\x02\x71\x04\xd6\xfc\xba\x03\x46\x00\x00\x03\x00\xbe\x01\ +\x90\x04\x24\x04\xd6\x00\x07\x00\x0f\x00\x13\x00\x00\x00\x34\x36\ +\x32\x16\x14\x06\x22\x00\x34\x36\x32\x16\x14\x06\x22\x09\x01\x23\ +\x01\x03\x52\x3b\x52\x3b\x3b\x52\xfd\x3b\x3b\x52\x3b\x3b\x52\x03\ +\x21\xfd\x8f\xf5\x02\x71\x02\x43\x52\x3b\x3b\x52\x3b\x01\xc9\x52\ +\x3b\x3b\x52\x3b\x01\x40\xfc\xba\x03\x46\x00\x00\x04\x00\xbe\x01\ +\x90\x05\xf4\x04\xd6\x00\x07\x00\x0b\x00\x13\x00\x17\x00\x00\x00\ +\x34\x36\x32\x16\x14\x06\x22\x13\x01\x23\x01\x00\x34\x36\x32\x16\ +\x14\x06\x22\x09\x01\x23\x01\x05\x22\x3a\x53\x3b\x3b\x53\x98\xfd\ +\x8e\xf4\x02\x70\xfb\xca\x3b\x52\x3b\x3b\x52\x03\x21\xfd\x8f\xf5\ +\x02\x71\x02\x43\x52\x3b\x3b\x52\x3b\x02\xce\xfc\xba\x03\x46\xfe\ +\xfb\x52\x3b\x3b\x52\x3b\x01\x40\xfc\xba\x03\x46\x00\x00\x00\x00\ +\x02\x00\xa5\x04\x09\x04\xd3\x06\x66\x00\x0b\x00\x23\x00\x00\x01\ +\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\x26\x12\x22\x0e\x01\x15\ +\x14\x06\x26\x35\x34\x3e\x02\x32\x1e\x02\x15\x14\x06\x26\x35\x34\ +\x26\x02\x58\x3b\x29\x2a\x3a\x3a\x2a\x29\x3b\xdf\xf6\xdc\x7d\x22\ +\x21\x52\x8c\xc9\xe0\xc9\x8c\x52\x21\x22\x7d\x04\x90\x2a\x3a\x3a\ +\x2a\x29\x3b\x3b\x01\x8b\x8d\xd6\x6b\x11\x0d\x0d\x11\x6f\xd3\x9f\ +\x61\x61\x9f\xd3\x6f\x11\x0d\x0d\x11\x6b\xd6\x00\x02\x00\xa5\x00\ +\x00\x04\xd3\x02\x5d\x00\x0b\x00\x25\x00\x00\x01\x34\x36\x33\x32\ +\x16\x15\x14\x06\x23\x22\x26\x12\x32\x3e\x02\x35\x34\x36\x16\x15\ +\x14\x0e\x02\x22\x2e\x02\x35\x34\x36\x16\x15\x14\x1e\x01\x02\x58\ +\x3b\x29\x2a\x3a\x3a\x2a\x29\x3b\x07\xba\xaf\x7d\x4b\x22\x21\x52\ +\x8c\xc9\xe0\xc9\x8c\x52\x21\x22\x4b\x7d\x01\xd6\x29\x3b\x3b\x29\ +\x2a\x3a\x3a\xfe\xc8\x54\x84\xa6\x50\x11\x0d\x0d\x11\x6f\xd3\x9f\ +\x61\x61\x9f\xd3\x6f\x11\x0d\x0d\x11\x50\xa6\x84\x00\x00\x00\x00\ +\x01\x00\xb1\x03\x93\x01\xcc\x05\x62\x00\x13\x00\x00\x01\x32\x16\ +\x15\x14\x07\x23\x22\x26\x35\x34\x37\x3e\x01\x37\x22\x26\x35\x34\ +\x36\x01\x35\x41\x56\xd9\x04\x0a\x0f\x08\x33\x2d\x02\x4b\x44\x49\ +\x05\x62\x4f\x45\xe8\x53\x18\x0d\x0c\x04\x1d\x5c\x4d\x2a\x3d\x31\ +\x3c\x00\x00\x00\x02\x00\xbe\x01\x90\x05\xf4\x04\xd6\x00\x03\x00\ +\x07\x00\x00\x09\x01\x23\x01\x23\x01\x23\x01\x05\xf4\xfd\x8e\xf4\ +\x02\x70\xda\xfd\x8f\xf5\x02\x71\x04\xd6\xfc\xba\x03\x46\xfc\xba\ +\x03\x46\x00\x00\x01\x00\x8c\xff\xca\x01\xce\x06\x9c\x00\x39\x00\ +\x00\x13\x1e\x05\x15\x14\x06\x15\x14\x16\x17\x16\x06\x27\x2e\x03\ +\x35\x34\x3e\x02\x35\x34\x26\x27\x3e\x01\x35\x34\x2e\x02\x35\x34\ +\x3e\x02\x37\x36\x16\x07\x0e\x01\x15\x14\x16\x15\x14\x0e\x04\xdc\ +\x0e\x3a\x23\x31\x1b\x14\x4a\x2f\x40\x08\x27\x09\x28\x4c\x3b\x24\ +\x1f\x25\x1f\x5c\x4c\x4c\x5c\x1f\x25\x1f\x24\x3b\x4c\x28\x09\x27\ +\x08\x40\x2f\x4a\x14\x1b\x31\x23\x3a\x03\x33\x09\x24\x17\x2e\x2f\ +\x4b\x2d\x46\xc8\x46\x43\x4e\x3c\x08\x2c\x07\x1f\x44\x40\x57\x32\ +\x4a\x7a\x41\x53\x29\x19\x67\x3a\x3a\x67\x19\x29\x53\x41\x7a\x4a\ +\x32\x57\x40\x44\x1f\x07\x2c\x08\x3c\x4e\x43\x46\xc8\x46\x2d\x4b\ +\x2f\x2e\x17\x24\x00\x00\x00\x00\x01\x00\xc8\xfe\x62\x02\xd0\x08\ +\x04\x00\x1d\x00\x00\x21\x1e\x01\x15\x14\x06\x23\x22\x2e\x05\x27\ +\x11\x3e\x06\x33\x32\x16\x15\x14\x06\x07\x01\x7c\x97\xbd\x20\x0a\ +\x0b\x17\x1e\x28\x45\x57\x88\x52\x52\x88\x57\x45\x28\x1e\x17\x0b\ +\x0a\x20\xbd\x97\x5a\xef\x35\x08\x18\x1b\x30\x3e\x4c\x4e\x56\x25\ +\x06\x66\x25\x56\x4e\x4c\x3e\x30\x1b\x18\x08\x35\xef\x5a\x00\x00\ +\x01\x00\x00\x03\x1c\x06\x40\x03\x4a\x00\x03\x00\x00\x11\x21\x15\ +\x21\x06\x40\xf9\xc0\x03\x4a\x2e\x00\x00\x00\x00\x02\x00\x00\x02\ +\x55\x06\x40\x04\x11\x00\x03\x00\x07\x00\x00\x11\x21\x15\x21\x11\ +\x21\x15\x21\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x04\x11\x2e\xfe\xa0\ +\x2e\x00\x00\x00\x03\x00\x00\x01\x8e\x06\x40\x04\xd8\x00\x03\x00\ +\x07\x00\x0b\x00\x00\x11\x21\x15\x21\x11\x21\x15\x21\x11\x21\x15\ +\x21\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x04\xd8\x2e\ +\xfe\xa0\x2e\xfe\xa0\x2e\x00\x00\x04\x00\x00\x00\xc7\x06\x40\x05\ +\x9f\x00\x03\x00\x07\x00\x0b\x00\x0f\x00\x00\x11\x21\x15\x21\x11\ +\x21\x15\x21\x11\x21\x15\x21\x11\x21\x15\x21\x06\x40\xf9\xc0\x06\ +\x40\xf9\xc0\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x05\x9f\x2e\xfe\xa0\ +\x2e\xfe\xa0\x2e\xfe\xa0\x2e\x00\x05\x00\x00\x00\x00\x06\x40\x06\ +\x66\x00\x03\x00\x07\x00\x0b\x00\x0f\x00\x13\x00\x00\x11\x21\x15\ +\x21\x11\x21\x15\x21\x11\x21\x15\x21\x11\x21\x15\x21\x11\x21\x15\ +\x21\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x06\x40\xf9\ +\xc0\x06\x40\xf9\xc0\x04\xd8\x2e\xfe\xa0\x2e\xfe\xa0\x2e\xfe\xa0\ +\x2e\x06\x66\x2e\x00\x00\x00\x00\x06\x00\x00\xff\x39\x06\x40\x07\ +\x2d\x00\x03\x00\x07\x00\x0b\x00\x0f\x00\x13\x00\x17\x00\x00\x15\ +\x21\x15\x21\x11\x21\x15\x21\x11\x21\x15\x21\x11\x21\x15\x21\x11\ +\x21\x15\x21\x11\x21\x15\x21\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x06\ +\x40\xf9\xc0\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x06\x40\xf9\xc0\x99\ +\x2e\x06\x66\x2e\xfe\xa0\x2e\xfe\xa0\x2e\xfe\xa0\x2e\x06\x66\x2e\ +\x00\x00\x00\x00\x15\x00\xc8\x00\xc8\x06\x0e\x04\xfe\x00\x03\x00\ +\x07\x00\x0b\x00\x0f\x00\x13\x00\x17\x00\x1b\x00\x1f\x00\x23\x00\ +\x27\x00\x2b\x00\x2f\x00\x33\x00\x37\x00\x3b\x00\x3f\x00\x43\x00\ +\x47\x00\x4b\x00\x4f\x00\x53\x00\x00\x01\x33\x35\x23\x11\x33\x35\ +\x23\x35\x33\x35\x23\x35\x33\x35\x23\x25\x33\x35\x23\x07\x35\x23\ +\x15\x21\x33\x35\x23\x05\x33\x35\x23\x01\x21\x11\x21\x01\x33\x35\ +\x23\x35\x33\x35\x23\x35\x33\x35\x23\x03\x35\x23\x15\x13\x35\x23\ +\x15\x13\x35\x23\x15\x01\x33\x35\x23\x35\x33\x35\x23\x35\x33\x35\ +\x23\x01\x33\x35\x23\x35\x33\x35\x23\x35\x33\x35\x23\x05\x0a\xd2\ +\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xfd\xf8\xd2\xd2\x32\xd2\x02\x08\xd2\ +\xd2\xfc\xf4\xd2\xd2\x05\x14\xfa\xba\x05\x46\xfc\xf4\xd2\xd2\xd2\ +\xd2\xd2\xd2\x32\xd2\xd2\xd2\xd2\xd2\x02\x08\xd2\xd2\xd2\xd2\xd2\ +\xd2\xfc\xf4\xd2\xd2\xd2\xd2\xd2\xd2\x03\xfc\xd4\xfc\x26\xd4\x2e\ +\xd4\x2e\xd4\x2e\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xfb\xf8\x04\x36\xfb\ +\xf8\xd4\x2e\xd4\x2e\xd4\xfd\x28\xd4\xd4\x01\x02\xd4\xd4\x01\x02\ +\xd4\xd4\xfd\xfc\xd4\x2e\xd4\x2e\xd4\xfd\x28\xd4\x2e\xd4\x2e\xd4\ +\x00\x00\x00\x00\x0d\x00\xc8\x00\xc8\x04\x06\x04\xfe\x00\x03\x00\ +\x07\x00\x0b\x00\x0f\x00\x13\x00\x17\x00\x1b\x00\x1f\x00\x23\x00\ +\x27\x00\x2b\x00\x2f\x00\x33\x00\x00\x01\x33\x35\x23\x07\x35\x23\ +\x15\x21\x33\x35\x23\x01\x21\x11\x21\x01\x33\x35\x23\x35\x33\x35\ +\x23\x35\x33\x35\x23\x03\x35\x23\x15\x13\x35\x23\x15\x13\x35\x23\ +\x15\x01\x33\x35\x23\x35\x33\x35\x23\x35\x33\x35\x23\x03\x02\xd2\ +\xd2\x32\xd2\xfe\xfc\xd2\xd2\x03\x0c\xfc\xc2\x03\x3e\xfe\xfc\xd2\ +\xd2\xd2\xd2\xd2\xd2\x32\xd2\xd2\xd2\xd2\xd2\xfe\xfc\xd2\xd2\xd2\ +\xd2\xd2\xd2\x03\xfc\xd4\xd4\xd4\xd4\xd4\xfb\xf8\x04\x36\xfb\xf8\ +\xd4\x2e\xd4\x2e\xd4\xfd\x28\xd4\xd4\x01\x02\xd4\xd4\x01\x02\xd4\ +\xd4\xfd\xfc\xd4\x2e\xd4\x2e\xd4\x00\x00\x00\x00\x04\x00\xb8\xfd\ +\x13\x04\x8c\x08\x79\x00\x1e\x00\x2a\x00\x6d\x00\x7a\x00\x00\x25\ +\x2e\x04\x35\x34\x36\x37\x26\x27\x00\x15\x14\x1e\x02\x33\x32\x37\ +\x2e\x02\x27\x0e\x02\x15\x14\x16\x13\x1e\x02\x17\x3e\x01\x35\x34\ +\x26\x23\x22\x03\x17\x36\x33\x32\x1e\x02\x15\x14\x06\x07\x16\x15\ +\x14\x0e\x02\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x07\ +\x1e\x01\x33\x32\x3e\x02\x35\x34\x27\x06\x23\x22\x00\x35\x34\x3e\ +\x03\x37\x26\x35\x34\x3e\x03\x33\x32\x1e\x01\x15\x14\x02\x07\x27\ +\x24\x35\x34\x2e\x02\x23\x22\x0e\x01\x15\x14\x02\xbc\x23\x3b\x42\ +\x2e\x1e\x68\x5e\x08\x35\xfe\xbf\x55\x7e\x8f\x3c\x58\x4a\x11\x2b\ +\x46\x10\x31\x4c\x21\x30\xb4\x10\x41\x2c\x12\x43\x4a\x97\x74\x09\ +\x7d\x43\x1f\x21\x3f\x81\x6d\x45\x79\x67\x36\x21\x40\x6e\x46\xa8\ +\xb1\x58\x55\x4c\x5f\x4e\x46\x11\x3e\x48\x36\x51\x2c\x15\x30\x54\ +\x5b\xe3\xfe\xe3\x25\x3d\x62\x65\x46\x23\x12\x2c\x41\x69\x40\x25\ +\x50\x33\x95\xa3\x30\x01\x1c\x09\x15\x2a\x1d\x21\x60\x46\xe7\x03\ +\x0e\x22\x33\x56\x39\x6b\xbc\x2a\x1e\xbc\xfe\xde\xf5\x5b\xa6\x6c\ +\x3f\x20\x4a\xa1\xf2\x3c\x11\x46\x3e\x13\x61\x4e\x01\x65\x3b\xde\ +\xa0\x48\x30\x97\x5f\x69\x73\x01\xb1\xfb\x06\x37\x64\xa1\x60\x71\ +\xc2\x3a\xfe\xfe\x34\x67\x5c\x39\xa0\x8c\x56\x5f\x5c\x4d\x42\x47\ +\x05\x2e\x2c\x2d\x48\x4c\x25\xec\xea\x1f\x01\x42\xfa\x54\x9a\x7e\ +\x80\x67\x3f\xad\xe1\x3e\x89\x95\x75\x4c\x86\xcc\x5f\xcd\xfe\xce\ +\x88\xc9\xfd\xc9\x28\x4b\x4b\x2e\x86\xb1\x39\xd1\x00\x00\x00\xff\ +\xff\x00\xb8\xfd\x13\x04\x8c\x0a\x4d\x10\x27\x00\x1c\x02\x26\x08\ +\x5e\x10\x06\x00\x54\x00\x00\xff\xff\x00\xb8\xfb\x43\x04\x8c\x08\ +\x79\x10\x27\x00\x1c\x02\x26\xfb\x48\x10\x06\x00\x54\x00\x00\x00\ +\x02\x00\xc8\xff\xff\x05\x6d\x06\x66\x00\x60\x00\x64\x00\x00\x01\ +\x17\x36\x33\x32\x16\x15\x14\x0e\x03\x23\x22\x26\x35\x34\x36\x33\ +\x32\x16\x15\x14\x07\x1e\x01\x33\x32\x11\x34\x26\x23\x22\x0e\x02\ +\x07\x0e\x02\x23\x22\x26\x27\x2e\x01\x27\x11\x23\x11\x33\x11\x3e\ +\x01\x37\x3e\x01\x33\x32\x1e\x01\x17\x1e\x03\x33\x32\x36\x35\x10\ +\x23\x22\x06\x07\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\ +\x1e\x03\x15\x14\x06\x23\x22\x27\x01\x11\x23\x11\x03\x46\x4e\x34\ +\x5a\xb0\x9a\x16\x32\x4b\x70\x46\x9f\xb2\x4d\x32\x3b\x4b\x4c\x14\ +\x42\x42\x9c\x43\x59\x24\x3a\x2e\x20\x14\x04\x06\x0f\x0b\x0b\x2a\ +\x05\x27\x30\x2c\x50\x50\x2c\x30\x27\x05\x2a\x0b\x0b\x0f\x06\x04\ +\x14\x20\x2e\x3a\x24\x59\x43\x9c\x42\x42\x14\x4c\x4b\x3b\x32\x4d\ +\xb2\x9f\x46\x70\x4b\x32\x16\x9a\xb0\x5a\x34\xfe\x12\xde\x03\x33\ +\xa5\x2c\xa5\xa5\x3d\x6b\x5e\x43\x27\x83\x53\x3b\x4e\x45\x38\x54\ +\x24\x15\x11\x01\x2c\x95\x75\x16\x2f\x2f\x25\x08\x08\x07\x5b\x10\ +\x54\x5b\x43\xfc\xd9\x06\x66\xfc\xd9\x43\x5b\x54\x10\x5b\x07\x08\ +\x08\x25\x2f\x2f\x16\x75\x95\x01\x2c\x11\x15\x24\x54\x38\x45\x4e\ +\x3b\x53\x83\x27\x43\x5e\x6b\x3d\xa5\xa5\x2c\x02\x8e\xf9\x9a\x06\ +\x66\x00\x00\x00\x03\x00\x90\x01\x39\x05\x9a\x06\x59\x00\x07\x00\ +\x0f\x00\x3d\x00\x00\x00\x34\x36\x32\x16\x14\x06\x22\x02\x34\x36\ +\x32\x16\x14\x06\x22\x05\x22\x26\x35\x34\x3e\x02\x33\x32\x1e\x02\ +\x15\x14\x0e\x05\x07\x06\x23\x22\x26\x35\x34\x37\x24\x00\x35\x34\ +\x26\x23\x22\x0e\x03\x07\x36\x33\x32\x15\x14\x04\xd2\x3a\x53\x3b\ +\x3b\x53\x3a\x3a\x53\x3b\x3b\x53\xfc\xb9\x54\x68\x28\x56\x9d\x6a\ +\x67\xaa\x71\x3e\x2b\x4b\x7c\x8c\xc2\xc3\x80\x04\x04\x11\x22\x04\ +\x01\x4e\x01\x6c\x63\x61\x3d\x60\x3b\x2b\x14\x06\x21\x35\xb1\x03\ +\xd1\x52\x3b\x3b\x52\x3b\x01\xc9\x52\x3b\x3b\x52\x3b\xd8\x61\x62\ +\x3f\x6f\x62\x3a\x3d\x6d\x94\x57\x60\xaa\x8e\x83\x6c\x6f\x5d\x36\ +\x02\x2c\x0f\x06\x02\x9c\x01\xa1\xfc\xa2\xb7\x16\x23\x32\x2e\x1b\ +\x05\x8f\x84\xff\xff\x00\x90\x01\x39\x05\x9a\x08\x40\x10\x27\x00\ +\x1c\x02\x26\x06\x51\x10\x06\x00\x58\x00\x00\xff\xff\x00\x90\xff\ +\xe2\x05\x9a\x06\x59\x10\x27\x00\x1c\x02\x26\xff\xe7\x10\x06\x00\ +\x58\x00\x00\x00\x02\x00\xc8\x01\x90\x03\x6a\x04\xd6\x00\x03\x00\ +\x07\x00\x00\x01\x11\x23\x11\x23\x11\x23\x11\x03\x6a\xe0\xe2\xe0\ +\x04\xd6\xfc\xba\x03\x46\xfc\xba\x03\x46\x00\x00\x02\x00\xc8\x00\ +\x82\x02\xd4\x05\xe4\x00\x03\x00\x07\x00\x00\x37\x11\x21\x11\x01\ +\x11\x21\x11\xc8\x02\x0c\xfe\x5c\x01\x3c\x82\x05\x62\xfa\x9e\x04\ +\xae\xfc\x06\x03\xfa\x00\x00\xff\xff\x00\xc8\x01\x8e\x0a\xf0\x04\ +\xd8\x10\x06\x00\x10\x00\x00\x00\x01\x00\xc8\x00\x00\x02\x84\x01\ +\xbc\x00\x13\x00\x00\x13\x35\x33\x15\x33\x35\x33\x15\x23\x15\x33\ +\x15\x23\x35\x23\x15\x23\x35\x33\x35\xc8\x9e\x80\x9e\x8a\x8a\x9e\ +\x80\x9e\x8a\x01\x1e\x9e\x8a\x8a\x9e\x80\x9e\x8a\x8a\x9e\x80\x00\ +\x03\x00\xc8\xff\xd8\x03\x84\x03\xe1\x00\x0b\x00\x26\x00\x32\x00\ +\x00\x01\x11\x3e\x03\x35\x34\x23\x22\x0e\x01\x03\x11\x33\x11\x3e\ +\x02\x33\x32\x17\x11\x33\x11\x3e\x02\x33\x32\x16\x15\x14\x06\x07\ +\x23\x35\x06\x07\x01\x11\x3e\x03\x35\x34\x23\x22\x0e\x01\x01\x0e\ +\x2a\x39\x36\x1b\x32\x1a\x22\x26\x66\x46\x25\x25\x40\x2a\x29\x1d\ +\x46\x25\x25\x40\x2a\x42\x40\xa1\x95\x46\x49\xb1\x01\x40\x2a\x39\ +\x36\x1b\x32\x1a\x22\x26\x01\x21\xff\x00\x1e\x32\x40\x47\x27\x44\ +\x0c\x1e\xfe\x9f\x04\x09\xfd\x8b\x1c\x18\x13\x13\x02\x41\xfd\x8b\ +\x1c\x18\x13\x5c\x43\x49\x9a\x59\xbb\x52\x69\x01\x49\xff\x00\x1e\ +\x32\x40\x47\x27\x44\x0c\x1e\x00\x02\x00\x82\xff\xd8\x02\x44\x04\ +\xc7\x00\x12\x00\x1e\x00\x00\x13\x16\x17\x23\x11\x3e\x02\x33\x32\ +\x16\x15\x14\x06\x07\x23\x11\x23\x36\x13\x11\x3e\x03\x35\x34\x23\ +\x22\x0e\x01\xeb\x47\x22\x46\x25\x25\x40\x2a\x42\x40\xa1\x95\x46\ +\x46\x22\x6a\x2a\x39\x36\x1b\x32\x1a\x22\x26\x04\xc7\x97\x2a\xfd\ +\x66\x1c\x18\x13\x5c\x43\x49\x9a\x59\x04\x2e\x2a\xfc\xf1\xff\x00\ +\x1e\x32\x40\x47\x27\x44\x0c\x1e\x00\x00\x00\x00\x02\x00\x82\xfe\ +\xa2\x02\x44\x03\xe1\x00\x13\x00\x1f\x00\x00\x05\x33\x06\x07\x26\ +\x27\x33\x11\x33\x11\x3e\x02\x33\x32\x16\x15\x14\x06\x07\x19\x01\ +\x3e\x03\x35\x34\x23\x22\x0e\x01\x01\x0e\x46\x22\x47\x47\x22\x46\ +\x46\x25\x25\x40\x2a\x42\x40\xa1\x95\x2a\x39\x36\x1b\x32\x1a\x22\ +\x26\x9d\x2a\x97\x97\x2a\x04\x7e\xfd\x8b\x1c\x18\x13\x5c\x43\x49\ +\x9a\x59\x01\x49\xff\x00\x1e\x32\x40\x47\x27\x44\x0c\x1e\x00\x00\ +\x02\x00\x82\xfe\x8d\x02\x44\x04\x31\x00\x03\x00\x10\x00\x00\x01\ +\x15\x37\x35\x03\x11\x25\x11\x23\x11\x05\x11\x23\x36\x37\x16\x17\ +\x01\x0e\xf0\xf0\x01\x36\x46\xfe\xca\x46\x22\x47\x47\x22\x01\x2e\ +\xbb\x1b\xbb\x02\x27\xfe\x4b\x29\xfc\xa9\x01\x74\x29\x03\x98\x2a\ +\x97\x97\x2a\x00\x02\x00\xc8\xfd\x8b\x02\x8a\x03\x2f\x00\x03\x00\ +\x10\x00\x00\x01\x15\x37\x35\x13\x33\x06\x07\x26\x27\x33\x11\x05\ +\x11\x33\x11\x25\x01\x0e\xf0\x46\x46\x22\x47\x47\x22\x46\xfe\xca\ +\x46\x01\x36\x01\x2e\xbb\x1b\xbb\xfd\x03\x2a\x97\x97\x2a\x01\xb5\ +\x29\x03\x57\xfe\x8c\x29\x00\x00\x02\x00\xc8\xfe\x84\x02\x44\x04\ +\xc7\x00\x27\x00\x2b\x00\x00\x01\x23\x3e\x02\x37\x1e\x05\x17\x23\ +\x11\x37\x15\x07\x15\x37\x15\x07\x11\x23\x11\x07\x11\x23\x11\x07\ +\x35\x37\x35\x07\x35\x37\x11\x33\x11\x37\x03\x37\x35\x07\x01\xb8\ +\x46\x12\x29\x14\x1a\x08\x12\x11\x11\x11\x13\x09\x46\x46\x46\x46\ +\x46\x46\x64\x46\x46\x46\x46\x46\x46\x64\x64\x64\x64\x04\x06\x16\ +\x49\x2a\x38\x12\x26\x22\x22\x1e\x1c\x0b\xfd\xd5\x09\x8c\x09\xc2\ +\x09\x8c\x09\xfe\xc1\x01\x36\x0e\xfe\x9a\x01\x5d\x09\x8c\x09\xc2\ +\x09\x8c\x09\x01\x3f\xfe\xca\x0e\xfe\xa4\x0e\xc2\x0e\x00\x00\x00\ +\x02\x00\xc8\xfc\xf5\x02\x44\x03\x38\x00\x27\x00\x2b\x00\x00\x01\ +\x33\x0e\x02\x07\x2e\x05\x27\x33\x11\x07\x11\x23\x11\x07\x35\x37\ +\x35\x07\x35\x37\x11\x33\x11\x37\x11\x33\x11\x37\x15\x07\x15\x37\ +\x15\x07\x27\x37\x35\x07\x01\xfe\x46\x12\x29\x14\x1a\x08\x12\x11\ +\x11\x11\x13\x09\x46\x64\x46\x46\x46\x46\x46\x46\x64\x46\x46\x46\ +\x46\x46\xaa\x64\x64\xfd\xb6\x16\x49\x2a\x38\x12\x26\x22\x22\x1e\ +\x1c\x0b\x02\x42\x0e\xfe\x9a\x01\x5d\x09\x8c\x09\xc2\x09\x8c\x09\ +\x01\x3f\xfe\xca\x0e\x01\x66\xfe\xa3\x09\x8c\x09\xc2\x09\x8c\x09\ +\x75\x0e\xc2\x0e\x00\x00\x00\x00\x03\x00\x6c\xff\x39\x01\xd2\x03\ +\xe4\x00\x02\x00\x06\x00\x29\x00\x00\x13\x35\x07\x13\x37\x35\x07\ +\x03\x37\x33\x15\x33\x15\x23\x11\x37\x35\x33\x15\x37\x15\x07\x15\ +\x37\x15\x07\x15\x23\x35\x07\x15\x23\x35\x07\x35\x37\x35\x07\x35\ +\x37\x11\x23\xf9\x4d\x7e\x46\x46\xbe\x8d\x31\x23\x23\x46\x31\x31\ +\x31\x31\x31\x31\x46\x31\x31\x31\x31\x31\x8d\x02\xee\x8c\x8c\xfd\ +\xa7\x0a\x88\x0a\x01\xc9\xfe\xf6\x32\xfe\xc3\x0a\xfa\xf4\x06\x62\ +\x06\x88\x07\x62\x07\xdf\xd9\x0a\xfa\xf4\x06\x62\x06\x88\x07\x62\ +\x07\x01\x43\x00\x03\x00\x3b\x00\x73\x01\xd2\x03\xe4\x00\x09\x00\ +\x1e\x00\x21\x00\x00\x13\x15\x3e\x01\x35\x34\x23\x22\x0e\x01\x03\ +\x11\x3e\x02\x33\x32\x16\x15\x14\x06\x07\x23\x11\x23\x35\x37\x33\ +\x15\x33\x15\x27\x35\x07\xf9\x3d\x41\x23\x12\x18\x1b\x16\x1a\x1a\ +\x2d\x1d\x2e\x2d\x70\x69\x31\x8d\x8d\x31\x23\x54\x4d\x01\x59\xb3\ +\x2c\x52\x34\x2f\x08\x15\x01\x52\xfe\xd2\x13\x11\x0d\x40\x2f\x33\ +\x6b\x3f\x02\x49\x2a\xfe\xf6\x32\x32\x8c\x8c\x00\x01\x00\xa4\x01\ +\x9f\x03\x2c\x04\xc4\x00\x31\x00\x00\x13\x34\x3e\x02\x33\x32\x16\ +\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x17\x2e\x01\x23\x22\ +\x0e\x02\x15\x14\x1e\x02\x33\x32\x3e\x01\x3f\x01\x32\x16\x15\x14\ +\x0e\x02\x23\x22\x2e\x02\xa4\x31\x58\x8b\x53\x85\x8f\x53\x4d\x40\ +\x40\x4c\x37\x1e\x1c\x19\x5d\x40\x33\x4b\x26\x11\x10\x27\x4c\x38\ +\x36\x5c\x2e\x10\x0f\x15\x2c\x24\x41\x75\x46\x5b\x8d\x55\x2b\x03\ +\x33\x47\x8c\x75\x49\x86\x58\x6a\x52\x52\x3f\x36\x44\x0b\x29\x35\ +\x40\x6b\x6e\x3c\x4a\x70\x64\x35\x41\x4d\x20\x21\x09\x03\x16\x51\ +\x5b\x42\x41\x72\x8f\x00\x00\x00\x02\x00\xa4\x00\xe1\x03\x2c\x05\ +\x82\x00\x32\x00\x38\x00\x00\x01\x33\x15\x36\x33\x32\x16\x15\x14\ +\x06\x23\x22\x26\x35\x34\x36\x33\x32\x17\x2e\x01\x23\x22\x07\x11\ +\x16\x33\x32\x3e\x01\x3f\x01\x32\x16\x15\x14\x0e\x02\x23\x22\x27\ +\x15\x23\x35\x2e\x01\x35\x34\x36\x37\x19\x01\x0e\x01\x15\x14\x01\ +\xae\x3c\x16\x0b\x85\x8f\x53\x4d\x40\x40\x4c\x37\x1e\x1c\x19\x5d\ +\x40\x0e\x0e\x10\x12\x36\x5c\x2e\x10\x0f\x15\x2c\x24\x41\x75\x46\ +\x17\x0b\x3c\x84\x86\x90\x7a\x31\x2c\x05\x82\xc0\x02\x86\x58\x6a\ +\x52\x52\x3f\x36\x44\x0b\x29\x35\x03\xfd\x5e\x03\x41\x4d\x20\x21\ +\x09\x03\x16\x51\x5b\x42\x01\xbf\xc8\x1e\xd9\x93\x7e\xe3\x23\xfd\ +\x45\x02\x6c\x2b\xaa\x60\xf4\x00\x06\x00\xc8\x01\xa9\x05\x36\x04\ +\x63\x00\x09\x00\x16\x00\x2c\x00\x3b\x00\x55\x00\x7f\x00\x00\x01\ +\x0e\x01\x15\x14\x16\x32\x36\x35\x34\x27\x3e\x01\x35\x34\x26\x22\ +\x06\x15\x14\x1e\x02\x17\x1e\x01\x15\x14\x23\x22\x35\x34\x36\x37\ +\x2e\x01\x35\x34\x36\x33\x32\x16\x15\x14\x06\x25\x22\x0e\x01\x15\ +\x14\x33\x32\x36\x37\x34\x3f\x01\x36\x26\x03\x0e\x02\x23\x22\x35\ +\x34\x36\x33\x32\x16\x0f\x01\x06\x33\x32\x36\x37\x17\x0e\x03\x23\ +\x22\x01\x32\x15\x14\x0e\x01\x23\x22\x26\x35\x34\x3f\x01\x36\x26\ +\x23\x22\x07\x27\x36\x33\x32\x16\x0f\x01\x06\x1d\x01\x14\x16\x33\ +\x32\x36\x37\x36\x35\x34\x26\x22\x26\x35\x34\x01\x8d\x38\x43\x53\ +\x88\x54\x81\x3b\x32\x4d\x6e\x4c\x17\x33\x2a\x5e\x3f\x54\xe2\xe1\ +\x51\x3f\x39\x3b\x78\x4d\x4e\x78\x3f\x02\x6d\x26\x32\x10\x1e\x11\ +\x16\x0a\x01\x29\x02\x06\x1e\x0a\x0e\x18\x13\x5d\x74\x44\x23\x34\ +\x06\x25\x02\x0a\x09\x27\x13\x1b\x0d\x1a\x1a\x2a\x1d\x19\xfe\xff\ +\x2f\x1b\x4d\x38\x36\x39\x02\x1d\x01\x06\x03\x0a\x13\x18\x29\x35\ +\x18\x16\x06\x1d\x03\x14\x0c\x2a\x39\x13\x0d\x0f\x10\x10\x03\x05\ +\x1b\x55\x2f\x4f\x4a\x4a\x4f\x56\x85\x18\x3a\x33\x38\x41\x41\x38\ +\x1f\x2d\x1e\x10\x21\x20\x6c\x39\xbd\xbd\x34\x61\x1f\x19\x4c\x47\ +\x44\x59\x59\x44\x3f\x46\xfc\x46\x4a\x20\x4d\x0a\x08\x07\x03\xcd\ +\x0c\x08\xfe\xf4\x05\x07\x05\x71\x45\x87\x26\x1f\xb2\x12\x3b\x36\ +\x0c\x21\x38\x27\x16\x01\x3a\x65\x29\x5b\x51\x2f\x20\x16\x09\x8c\ +\x06\x09\x1e\x11\x3e\x29\x1c\x8c\x1b\x06\x0d\x0a\x10\x2e\x3a\x28\ +\x21\x0f\x17\x13\x0f\x20\x00\x00\x06\x00\xc8\x01\xd4\x04\xfc\x05\ +\x56\x00\x21\x00\x30\x00\x5c\x00\x66\x00\x74\x00\x89\x00\x00\x01\ +\x34\x3e\x01\x37\x3e\x01\x33\x32\x16\x0f\x01\x3e\x02\x33\x32\x15\ +\x14\x0e\x02\x23\x22\x26\x27\x13\x36\x35\x34\x23\x22\x06\x22\x17\ +\x07\x06\x1d\x01\x14\x33\x32\x36\x37\x36\x35\x34\x23\x22\x27\x32\ +\x15\x14\x0e\x02\x23\x22\x26\x35\x34\x3f\x01\x36\x26\x23\x22\x07\ +\x27\x36\x33\x32\x16\x0f\x01\x06\x1d\x01\x14\x16\x33\x32\x36\x37\ +\x36\x35\x34\x26\x23\x22\x26\x35\x34\x01\x0e\x01\x15\x14\x16\x32\ +\x36\x35\x34\x27\x3e\x01\x35\x34\x26\x22\x06\x15\x14\x1e\x03\x17\ +\x1e\x01\x15\x14\x23\x22\x35\x34\x36\x37\x2e\x01\x35\x34\x36\x32\ +\x16\x15\x14\x06\x04\x04\x10\x1d\x07\x09\x30\x07\x08\x0a\x01\x2c\ +\x0f\x0e\x1e\x14\x50\x11\x22\x42\x2b\x37\x39\x02\x46\x01\x0a\x05\ +\x12\x0c\x4d\x19\x04\x12\x17\x3a\x0c\x0a\x24\x2e\xc7\x2f\x11\x23\ +\x42\x2a\x36\x39\x02\x1d\x01\x06\x03\x0b\x13\x17\x29\x35\x17\x15\ +\x05\x1c\x04\x14\x0c\x2b\x38\x14\x0c\x0f\x07\x09\x0f\xfe\x1c\x37\ +\x44\x54\x88\x54\x82\x3c\x32\x4d\x6e\x4d\x12\x19\x2f\x22\x57\x3f\ +\x54\xe2\xe1\x51\x3f\x3a\x3a\x77\x9c\x78\x3f\x05\x23\x04\x07\x09\ +\x03\x04\x18\x07\x06\xda\x0a\x08\x07\x66\x1d\x43\x46\x2e\x2f\x26\ +\x01\x62\x04\x05\x0f\x02\xe9\x7b\x12\x0f\x0d\x1a\x3e\x3e\x30\x1f\ +\x2e\x20\x66\x1c\x44\x46\x2e\x2f\x20\x15\x0a\x8c\x05\x0a\x1e\x11\ +\x3e\x2a\x1b\x8c\x12\x0f\x0d\x0b\x0f\x2e\x3a\x25\x24\x0f\x17\x13\ +\x0f\x20\xfe\xa8\x1c\x55\x2e\x4f\x4a\x4a\x4f\x54\x87\x17\x3a\x34\ +\x38\x41\x41\x38\x19\x28\x19\x17\x0b\x1f\x20\x6c\x39\xbd\xbd\x34\ +\x62\x1e\x19\x4b\x48\x45\x58\x58\x45\x40\x46\x00\x04\x00\xc8\x01\ +\xa8\x06\xf8\x04\x87\x00\x51\x00\x61\x00\x8d\x00\xb5\x00\x00\x01\ +\x22\x26\x3f\x01\x36\x26\x23\x22\x0f\x01\x23\x13\x36\x26\x23\x22\ +\x0f\x01\x23\x37\x36\x23\x22\x06\x07\x27\x3e\x03\x33\x32\x17\x36\ +\x33\x32\x17\x3e\x03\x33\x32\x16\x0f\x01\x06\x33\x32\x36\x37\x3e\ +\x01\x33\x32\x16\x0f\x01\x06\x33\x32\x36\x37\x17\x0e\x03\x23\x22\ +\x27\x0e\x04\x23\x22\x27\x0e\x01\x13\x22\x0e\x02\x15\x14\x33\x32\ +\x36\x37\x34\x3f\x01\x36\x26\x25\x0e\x03\x2b\x01\x07\x32\x16\x15\ +\x14\x0e\x01\x23\x22\x27\x2e\x01\x35\x34\x33\x32\x1e\x01\x17\x1e\ +\x01\x33\x32\x36\x35\x34\x26\x23\x13\x33\x32\x37\x36\x33\x32\x15\ +\x14\x01\x21\x22\x35\x34\x33\x32\x3e\x02\x35\x11\x36\x26\x27\x26\ +\x0f\x01\x0e\x01\x27\x26\x27\x34\x3f\x01\x36\x33\x32\x16\x15\x11\ +\x14\x1e\x02\x33\x32\x15\x14\x05\x4d\x1b\x12\x04\x29\x02\x08\x0d\ +\x32\x0a\x2e\x4a\x34\x02\x08\x0d\x32\x0a\x2e\x4a\x31\x02\x09\x0a\ +\x26\x14\x1b\x0d\x1a\x1b\x29\x1e\x22\x03\x29\x41\x20\x09\x0c\x0f\ +\x14\x1f\x1c\x15\x1c\x06\x24\x04\x0b\x08\x20\x10\x0b\x6e\x3d\x24\ +\x34\x06\x25\x02\x09\x0a\x27\x12\x1c\x0d\x1a\x1b\x29\x1e\x18\x09\ +\x03\x0e\x08\x0e\x11\x0c\x4b\x0e\x12\x2d\xec\x1c\x2b\x16\x0a\x1e\ +\x11\x16\x09\x02\x29\x02\x07\xfd\x40\x07\x0c\x13\x19\x10\xa7\x26\ +\x8b\xbe\x45\x62\x3a\x4d\x48\x1e\x1f\x1c\x08\x0e\x0f\x03\x22\x38\ +\x34\x41\x56\xa0\x8a\x3a\xc2\x29\x18\x05\x02\x07\xfe\x44\xfe\xea\ +\x15\x21\x16\x17\x1f\x0e\x01\x02\x06\x07\x14\x2c\x01\x0e\x05\x0d\ +\x02\x0d\x6c\x09\x16\x0e\x14\x0e\x20\x17\x16\x20\x03\x29\x22\x17\ +\xcd\x0b\x09\x37\xde\x01\x01\x0b\x09\x37\xde\xf1\x12\x3a\x37\x0c\ +\x21\x38\x27\x16\x1f\x1f\x1f\x09\x0c\x07\x03\x26\x1e\xb2\x12\x2b\ +\x29\x42\x72\x26\x1e\xb3\x11\x3a\x36\x0c\x21\x37\x27\x16\x0e\x01\ +\x08\x03\x04\x02\x48\x22\x22\x01\x19\x28\x3b\x37\x16\x4d\x0b\x08\ +\x05\x04\xcd\x0c\x08\x22\x11\x15\x1a\x0d\x9b\x93\x68\x4a\x66\x29\ +\x29\x10\x1e\x14\x18\x0b\x15\x03\x22\x1a\x61\x54\x49\x7f\x01\x13\ +\x25\x06\x09\x0f\xfd\x3f\x10\x15\x01\x07\x11\x0e\x01\xed\x08\x11\ +\x04\x05\x09\x19\x01\x0a\x01\x02\x0c\x10\x0a\x55\x08\x0f\x0d\xfd\ +\xb4\x0e\x11\x07\x01\x15\x10\x00\x04\x00\xc8\x01\xcc\x06\xbb\x05\ +\x55\x00\x29\x00\x52\x00\xa9\x00\xb9\x00\x00\x01\x21\x22\x26\x35\ +\x34\x33\x32\x3e\x02\x35\x11\x34\x27\x26\x0f\x01\x0e\x02\x27\x22\ +\x27\x34\x3f\x01\x36\x33\x32\x16\x15\x11\x14\x1e\x02\x33\x32\x15\ +\x14\x06\x01\x06\x2b\x01\x07\x32\x16\x15\x14\x06\x23\x22\x27\x2e\ +\x01\x35\x34\x33\x32\x1e\x01\x17\x1e\x01\x33\x32\x36\x35\x34\x26\ +\x23\x13\x33\x32\x36\x37\x36\x33\x32\x15\x14\x01\x22\x26\x3f\x01\ +\x36\x26\x23\x22\x0f\x01\x23\x13\x36\x26\x23\x22\x0f\x01\x23\x37\ +\x36\x23\x22\x06\x07\x27\x3e\x03\x33\x32\x17\x36\x33\x32\x17\x3e\ +\x03\x33\x32\x16\x0f\x01\x06\x33\x3e\x01\x37\x13\x36\x35\x34\x23\ +\x22\x06\x23\x22\x35\x34\x3e\x01\x37\x3e\x01\x33\x32\x16\x0f\x01\ +\x3e\x02\x33\x32\x15\x14\x0e\x02\x23\x22\x27\x06\x37\x07\x06\x1d\ +\x01\x14\x33\x32\x36\x37\x36\x35\x34\x26\x23\x22\x01\xf2\xfe\xea\ +\x09\x0b\x20\x17\x17\x1f\x0e\x08\x07\x14\x2c\x02\x08\x05\x04\x0e\ +\x02\x0d\x6c\x0b\x14\x0e\x15\x0e\x1f\x17\x17\x20\x0b\x01\xae\x1f\ +\x30\xa6\x27\x8b\xbe\x85\x5c\x49\x4c\x1e\x1e\x1b\x09\x0e\x0e\x03\ +\x23\x37\x34\x41\x57\xa1\x8a\x3b\xc1\x1a\x1b\x0d\x03\x04\x07\x01\ +\x9d\x1b\x12\x04\x2a\x02\x09\x0d\x32\x0a\x2e\x4a\x35\x02\x09\x0d\ +\x32\x0a\x2e\x4a\x31\x05\x0c\x09\x27\x14\x1b\x0d\x1a\x1b\x29\x1e\ +\x22\x03\x2b\x40\x20\x08\x0c\x10\x13\x20\x1c\x15\x1b\x06\x24\x02\ +\x09\x0a\x25\x12\x38\x01\x0a\x06\x12\x05\x06\x0f\x1e\x07\x09\x30\ +\x07\x08\x0a\x01\x2c\x0f\x0f\x1d\x14\x50\x11\x22\x42\x2b\x5c\x12\ +\x21\x84\x19\x04\x12\x17\x3a\x0d\x09\x11\x13\x2e\x01\xd2\x0a\x06\ +\x15\x01\x07\x12\x0e\x01\xec\x18\x06\x05\x0a\x19\x01\x06\x03\x01\ +\x0d\x10\x0a\x55\x09\x10\x0c\xfd\xb4\x0e\x12\x07\x01\x15\x06\x0a\ +\x02\xb7\x4e\x9b\x92\x68\x6d\x6d\x29\x10\x1e\x14\x19\x0c\x14\x03\ +\x23\x1a\x62\x54\x48\x7f\x01\x13\x12\x13\x07\x09\x10\xfe\xba\x22\ +\x17\xcd\x0b\x09\x37\xde\x01\x01\x0b\x09\x37\xde\xf1\x13\x3b\x37\ +\x0c\x22\x37\x28\x16\x20\x20\x20\x09\x0c\x08\x03\x27\x1e\xb2\x12\ +\x01\x37\x34\x01\x1a\x04\x05\x0f\x02\x07\x04\x07\x0a\x03\x04\x18\ +\x07\x06\xdb\x0a\x09\x07\x66\x1d\x44\x45\x2e\x3e\x3e\xe3\x7a\x14\ +\x0e\x0c\x1a\x3d\x3f\x32\x1d\x18\x15\x00\x00\x00\x01\x00\xbe\x03\ +\x1c\x04\x96\x04\xd8\x00\x0b\x00\x00\x13\x21\x15\x23\x11\x33\x15\ +\x21\x35\x33\x11\x23\xbe\x03\xd8\xfa\xfa\xfc\x28\xfa\xfa\x04\xd8\ +\x2e\xfe\xa0\x2e\x2e\x01\x60\x00\x01\x00\xbe\x03\xe0\x04\x96\x04\ +\xd8\x00\x07\x00\x00\x01\x35\x23\x35\x21\x15\x23\x15\x01\xb8\xfa\ +\x03\xd8\xfa\x03\xe0\xca\x2e\x2e\xca\x00\x00\x00\x01\x00\xbe\x03\ +\x1c\x04\x96\x04\x14\x00\x07\x00\x00\x01\x15\x33\x15\x21\x35\x33\ +\x35\x03\x9c\xfa\xfc\x28\xfa\x04\x14\xca\x2e\x2e\xca\x00\x00\x00\ +\x01\x00\xc0\x00\xf5\x02\x5f\x05\xca\x00\x31\x00\x00\x01\x22\x26\ +\x23\x22\x06\x15\x14\x1e\x02\x14\x06\x23\x22\x2e\x02\x35\x34\x36\ +\x33\x32\x17\x2e\x01\x35\x34\x3e\x01\x35\x34\x2e\x01\x35\x34\x36\ +\x33\x32\x1e\x01\x15\x14\x02\x15\x14\x16\x15\x14\x06\x02\x0b\x01\ +\x52\x26\x1d\x25\x2a\x34\x2a\x1f\x0e\x0c\x49\x55\x41\x45\x35\x44\ +\x30\x46\x62\x54\x54\x47\x47\x33\x0b\x0d\x7f\x75\xb4\x99\x28\x02\ +\x01\x14\x24\x26\x22\x42\x2a\x24\x0e\x16\x29\x40\x60\x2e\x51\x5d\ +\x1e\x50\xad\x24\x0d\x74\x85\x22\x19\x60\x51\x06\x0b\x2a\x99\xaf\ +\x1a\x1d\xfe\xe1\x17\x16\xd1\x06\x0f\x18\x00\x00\x01\x00\xc3\x01\ +\x90\x02\xb7\x04\x9d\x00\x15\x00\x00\x01\x17\x03\x27\x13\x06\x23\ +\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x07\x3e\x03\x02\x6f\x48\ +\xed\x47\xbd\x6e\x8c\x3e\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\x1b\ +\x04\x76\x21\xfd\x3b\x21\x02\x3a\x5f\x49\x3f\x37\x52\x52\x37\x0f\ +\x13\x04\x22\x31\x1f\x00\x00\x00\x01\x00\xc3\x01\x90\x03\x3c\x06\ +\x2b\x00\x2a\x00\x00\x01\x27\x13\x06\x23\x22\x26\x35\x34\x36\x33\ +\x32\x16\x15\x14\x07\x3e\x03\x37\x13\x06\x23\x22\x26\x35\x34\x36\ +\x33\x32\x1e\x02\x15\x14\x07\x3e\x03\x37\x17\x01\xca\x47\xbd\x6e\ +\x8c\x3e\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\x1b\x0a\x56\x6e\x8d\ +\x3d\x45\x48\x3a\x21\x31\x1b\x0d\x02\x1d\x3e\x31\x1c\x0a\x48\x01\ +\x90\x21\x02\x3a\x5f\x49\x3f\x37\x52\x52\x37\x0f\x13\x04\x22\x31\ +\x1f\x0e\x01\x03\x5f\x49\x3f\x37\x52\x19\x29\x2e\x19\x0f\x13\x04\ +\x22\x31\x1f\x0e\x21\x00\x00\x00\x01\x00\xc3\x00\x02\x03\xc0\x06\ +\x2b\x00\x3d\x00\x00\x09\x01\x27\x13\x06\x23\x22\x26\x35\x34\x36\ +\x33\x32\x16\x15\x14\x07\x3e\x03\x37\x13\x06\x23\x22\x26\x35\x34\ +\x36\x33\x32\x1e\x02\x15\x14\x07\x3e\x03\x37\x13\x06\x23\x22\x26\ +\x35\x34\x36\x33\x32\x16\x15\x14\x07\x3e\x03\x37\x03\xc0\xfe\x0a\ +\x47\xbd\x6e\x8c\x3e\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\x1b\x0a\ +\x56\x6e\x8d\x3d\x45\x48\x3a\x21\x31\x1b\x0d\x02\x1d\x3e\x31\x1c\ +\x0a\x55\x6e\x8c\x3e\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\x1b\x0a\ +\x05\xe3\xfa\x1f\x21\x02\x3a\x5f\x49\x3f\x37\x52\x52\x37\x0f\x13\ +\x04\x22\x31\x1f\x0e\x01\x03\x5f\x49\x3f\x37\x52\x19\x29\x2e\x19\ +\x0f\x13\x04\x22\x31\x1f\x0e\x01\x03\x5f\x49\x3f\x37\x52\x52\x37\ +\x0f\x13\x04\x22\x31\x1f\x0e\x00\x01\x00\xc3\x00\x02\x04\x45\x07\ +\xb9\x00\x52\x00\x00\x09\x01\x27\x13\x06\x23\x22\x26\x35\x34\x36\ +\x33\x32\x16\x15\x14\x07\x3e\x03\x37\x13\x06\x23\x22\x26\x35\x34\ +\x36\x33\x32\x1e\x02\x15\x14\x07\x3e\x03\x37\x13\x06\x23\x22\x26\ +\x35\x34\x36\x33\x32\x16\x15\x14\x07\x3e\x03\x37\x13\x06\x23\x22\ +\x26\x35\x34\x36\x33\x32\x1e\x02\x15\x14\x07\x3e\x03\x37\x04\x44\ +\xfd\x86\x47\xbd\x6e\x8c\x3e\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\ +\x1b\x0a\x56\x6e\x8d\x3d\x45\x48\x3a\x21\x31\x1b\x0d\x02\x1d\x3e\ +\x31\x1c\x0a\x55\x6e\x8c\x3e\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\ +\x1b\x0a\x56\x6e\x8c\x3e\x46\x49\x3b\x20\x31\x1b\x0e\x04\x1e\x3e\ +\x31\x1c\x0a\x07\x71\xf8\x91\x21\x02\x3a\x5f\x49\x3f\x37\x52\x52\ +\x37\x0f\x13\x04\x22\x31\x1f\x0e\x01\x03\x5f\x49\x3f\x37\x52\x19\ +\x29\x2e\x19\x0f\x13\x04\x22\x31\x1f\x0e\x01\x03\x5f\x49\x3f\x37\ +\x52\x52\x37\x0f\x13\x04\x22\x31\x1f\x0e\x01\x03\x5f\x49\x3f\x37\ +\x52\x19\x29\x2e\x19\x0f\x13\x04\x22\x31\x1f\x0e\x00\x00\x00\x00\ +\x01\x00\xc3\xfe\x74\x04\xc9\x07\xb9\x00\x65\x00\x00\x09\x01\x27\ +\x13\x06\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\x07\x3e\x03\ +\x37\x13\x06\x23\x22\x26\x35\x34\x36\x33\x32\x1e\x02\x15\x14\x07\ +\x3e\x03\x37\x13\x06\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\ +\x07\x3e\x03\x37\x13\x06\x23\x22\x26\x35\x34\x36\x33\x32\x1e\x02\ +\x15\x14\x07\x3e\x03\x37\x13\x06\x23\x22\x26\x35\x34\x36\x33\x32\ +\x16\x15\x14\x07\x3e\x03\x37\x04\xc9\xfd\x01\x47\xbd\x6e\x8c\x3e\ +\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\x1b\x0a\x56\x6e\x8d\x3d\x45\ +\x48\x3a\x21\x31\x1b\x0d\x02\x1d\x3e\x31\x1c\x0a\x55\x6e\x8c\x3e\ +\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\x1b\x0a\x56\x6e\x8c\x3e\x46\ +\x49\x3b\x20\x31\x1b\x0e\x04\x1e\x3e\x31\x1c\x0a\x55\x6e\x8c\x3e\ +\x45\x49\x3a\x3f\x3b\x03\x1d\x3e\x32\x1b\x0b\x07\x71\xf7\x03\x21\ +\x02\x3a\x5f\x49\x3f\x37\x52\x52\x37\x0f\x13\x04\x22\x31\x1f\x0e\ +\x01\x03\x5f\x49\x3f\x37\x52\x19\x29\x2e\x19\x0f\x13\x04\x22\x31\ +\x1f\x0e\x01\x03\x5f\x49\x3f\x37\x52\x52\x37\x0f\x13\x04\x22\x31\ +\x1f\x0e\x01\x03\x5f\x49\x3f\x37\x52\x19\x29\x2e\x19\x0f\x13\x04\ +\x22\x31\x1f\x0e\x01\x03\x5f\x49\x3f\x37\x52\x52\x37\x0f\x13\x04\ +\x22\x31\x1f\x0e\x00\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x01\ +\xbc\x00\x0b\x00\x00\x13\x37\x17\x37\x17\x07\x17\x07\x27\x07\x27\ +\x37\xc9\x2f\xaf\xaf\x2f\xaf\xaf\x2f\xaf\xaf\x2f\xaf\x01\x8d\x2f\ +\xaf\xaf\x2f\xaf\xaf\x2f\xaf\xaf\x2f\xaf\x00\x00\x01\x00\xc9\x00\ +\x00\x02\x85\x01\xbc\x00\x0b\x00\x00\x25\x23\x35\x33\x35\x33\x15\ +\x33\x15\x23\x15\x23\x01\x84\xbb\xbb\x46\xbb\xbb\x46\xbb\x46\xbb\ +\xbb\x46\xbb\x00\x05\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x07\x00\ +\x0c\x00\x11\x00\x16\x00\x1b\x00\x00\x36\x34\x36\x32\x16\x14\x06\ +\x22\x37\x36\x34\x27\x07\x27\x17\x37\x26\x22\x07\x06\x14\x17\x37\ +\x17\x27\x07\x16\x32\xc9\x82\xb8\x82\x82\xb8\xd9\x1b\x1b\x56\x7d\ +\x56\x56\x27\x5e\x4e\x1b\x1b\x56\x7d\x56\x56\x27\x5e\x82\xb8\x82\ +\x82\xb8\x82\x88\x27\x5e\x27\x56\x7d\x56\x56\x1b\x42\x27\x5e\x27\ +\x56\x7d\x56\x56\x1b\x00\x00\x00\x02\x00\xc9\x00\x00\x02\x85\x01\ +\xbc\x00\x03\x00\x07\x00\x00\x25\x21\x11\x21\x03\x11\x21\x11\x01\ +\x0f\x01\x30\xfe\xd0\x46\x01\xbc\x46\x01\x30\xfe\x8a\x01\xbc\xfe\ +\x44\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x03\x00\ +\x00\x33\x11\x21\x11\xc9\x01\xbc\x01\xbc\xfe\x44\x00\x00\x00\x00\ +\x02\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x02\x00\x05\x00\x00\x25\ +\x33\x27\x35\x13\x21\x01\x3c\xd6\x6b\xde\xfe\x44\x46\xd6\xa0\xfe\ +\x44\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x02\x00\ +\x00\x01\x13\x21\x01\xa7\xde\xfe\x44\x01\xbc\xfe\x44\x00\x00\x00\ +\x02\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x02\x00\x05\x00\x00\x01\ +\x15\x33\x17\x21\x11\x01\x0f\xcc\xaa\xfe\x44\x01\x12\xcc\x46\x01\ +\xbc\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x02\x00\ +\x00\x29\x01\x11\x02\x85\xfe\x44\x01\xbc\x00\x00\x02\x00\xc9\x00\ +\x00\x02\x85\x01\xbc\x00\x02\x00\x05\x00\x00\x01\x07\x33\x05\x01\ +\x11\x02\x3f\xcc\xcc\xfe\x8a\x01\xbc\x01\x12\xcc\x46\x01\xbc\xfe\ +\x44\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x02\x00\ +\x00\x01\x11\x21\x02\x85\xfe\x44\x01\xbc\xfe\x44\x00\x00\x00\x00\ +\x02\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x02\x00\x05\x00\x00\x01\ +\x17\x37\x0b\x01\x21\x01\x3c\x6b\x6b\x6b\xde\x01\xbc\x01\x76\xd6\ +\xd6\xfe\x8a\x01\xbc\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x01\ +\xbc\x00\x02\x00\x00\x21\x03\x21\x01\xa7\xde\x01\xbc\x01\xbc\x00\ +\x02\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x02\x00\x05\x00\x00\x25\ +\x35\x23\x27\x21\x11\x02\x3f\xcc\xaa\x01\xbc\xaa\xcc\x46\xfe\x44\ +\x00\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x02\x00\ +\x00\x21\x01\x21\x02\x85\xfe\x44\x01\xbc\x01\xbc\x00\x00\x00\x00\ +\x02\x00\xc9\x00\x00\x02\xd5\x01\xbc\x00\x07\x00\x0f\x00\x00\x25\ +\x14\x16\x32\x36\x3d\x01\x21\x07\x35\x21\x15\x14\x06\x22\x26\x01\ +\x0f\x6d\xa6\x6d\xfe\x80\x46\x02\x0c\x93\xe6\x93\xf7\x54\x5d\x5d\ +\x54\x7f\x81\xc7\xc7\x75\x80\x80\x00\x00\x00\x00\x01\x00\xc9\x00\ +\x00\x02\xd5\x01\xbc\x00\x07\x00\x00\x37\x35\x21\x15\x14\x06\x22\ +\x26\xc9\x02\x0c\x93\xe6\x93\xf5\xc7\xc7\x75\x80\x80\x00\x00\x00\ +\x02\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x04\x00\x0b\x00\x00\x00\ +\x22\x07\x17\x37\x26\x32\x16\x17\x0b\x01\x36\x02\x05\xbc\x1f\x7d\ +\x7d\xcb\x9c\x76\x1a\xde\xde\x1a\x01\x76\x43\xb6\xb6\x89\x3c\x3c\ +\xfe\xbc\x01\x44\x3c\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x01\ +\xbc\x00\x06\x00\x00\x00\x32\x16\x17\x0b\x01\x36\x01\x59\x9c\x76\ +\x1a\xde\xde\x1a\x01\xbc\x3c\x3c\xfe\xbc\x01\x44\x3c\x00\x00\x00\ +\x02\x00\xc9\xff\xec\x02\x85\x01\xd0\x00\x0d\x00\x1b\x00\x00\x00\ +\x14\x0e\x01\x07\x27\x3e\x01\x34\x26\x27\x37\x1e\x01\x04\x34\x3e\ +\x01\x37\x17\x0e\x01\x14\x16\x17\x07\x2e\x01\x02\x85\x25\x30\x2d\ +\x19\x34\x25\x25\x34\x19\x2d\x30\xfe\x69\x25\x30\x2d\x19\x34\x25\ +\x25\x34\x19\x2d\x30\x01\x11\x66\x58\x3b\x2c\x15\x3b\x5c\x8c\x5c\ +\x3b\x15\x2c\x3b\xbe\x66\x58\x3b\x2c\x15\x3b\x5c\x8c\x5c\x3b\x15\ +\x2c\x3b\x00\x00\x02\x00\xc9\x00\x00\x03\x11\x01\xbc\x00\x09\x00\ +\x17\x00\x00\x01\x32\x15\x14\x06\x23\x22\x35\x34\x36\x03\x32\x3e\ +\x02\x34\x26\x23\x22\x0e\x02\x14\x16\x02\x30\xe1\xdb\x8c\xe1\xda\ +\x49\x3d\x88\x61\x41\x29\x18\x3d\x88\x61\x41\x29\x01\xbc\x95\x7d\ +\xaa\x95\x7d\xaa\xfe\x87\x43\x5a\x57\x2a\x18\x43\x5a\x57\x2a\x18\ +\x00\x00\x00\x00\x01\x00\xc9\x00\x00\x03\x11\x01\xbc\x00\x09\x00\ +\x00\x01\x32\x15\x14\x06\x23\x22\x35\x34\x36\x02\x30\xe1\xdb\x8c\ +\xe1\xda\x01\xbc\x95\x7d\xaa\x95\x7d\xaa\x00\x00\x02\x00\xc9\x00\ +\x00\x02\x85\x03\x4a\x00\x03\x00\x07\x00\x00\x25\x21\x11\x21\x03\ +\x11\x21\x11\x01\x0f\x01\x30\xfe\xd0\x46\x01\xbc\x46\x02\xbe\xfc\ +\xfc\x03\x4a\xfc\xb6\x00\x00\x00\x01\x00\xc9\x00\x00\x02\x85\x03\ +\x4a\x00\x03\x00\x00\x33\x11\x21\x11\xc9\x01\xbc\x03\x4a\xfc\xb6\ +\x00\x00\x00\x00\x04\x00\xc8\xff\xd8\x04\x8c\x01\xe4\x00\x0b\x00\ +\x0f\x00\x13\x00\x2f\x00\x00\x01\x22\x06\x15\x14\x16\x33\x32\x36\ +\x35\x34\x26\x25\x11\x23\x11\x21\x11\x23\x11\x23\x11\x23\x35\x0e\ +\x02\x23\x22\x2e\x02\x27\x15\x23\x11\x33\x15\x3e\x02\x33\x32\x1e\ +\x02\x17\x35\x02\x96\x2f\x44\x50\x4b\x2f\x44\x4d\xfe\x14\x30\x03\ +\xc4\x30\x34\x30\x0b\x59\x73\x39\x57\x83\x6b\x3f\x08\x30\x30\x0b\ +\x59\x73\x39\x57\x83\x6b\x3f\x08\x01\x76\x3f\x33\x53\x6b\x3f\x33\ +\x55\x69\x6e\xfd\xf4\x02\x0c\xfd\xf4\x02\x0c\xfd\xf4\xd1\x33\x4f\ +\x27\x13\x2c\x50\x3a\xf1\x02\x0c\xd1\x33\x4f\x27\x13\x2c\x50\x3a\ +\xf1\x00\x00\x00\x02\x00\xc9\x00\x00\x03\x6b\x01\xbc\x00\x0b\x00\ +\x1d\x00\x00\x01\x22\x06\x15\x14\x16\x33\x32\x36\x35\x34\x26\x27\ +\x32\x1e\x02\x15\x14\x0e\x01\x23\x22\x2e\x02\x35\x34\x3e\x01\x02\ +\x06\x2f\x44\x50\x4b\x2f\x44\x4d\x78\x5f\x8b\x6e\x37\x59\x7c\x3e\ +\x5f\x8b\x6e\x37\x59\x7c\x01\x76\x3f\x33\x53\x6b\x3f\x33\x55\x69\ +\x46\x16\x36\x62\x47\x3b\x5e\x2e\x16\x36\x62\x47\x3b\x5e\x2e\x00\ +\x02\x00\xc9\x00\x00\x03\x11\x06\x66\x00\x0d\x00\x1a\x00\x00\x25\ +\x32\x3e\x02\x34\x26\x23\x22\x0e\x02\x14\x16\x01\x33\x11\x14\x06\ +\x23\x22\x35\x34\x36\x33\x32\x17\x01\x5a\x3d\x88\x61\x41\x29\x18\ +\x3d\x88\x61\x41\x29\x01\x89\x46\xdb\x8c\xe1\xda\x8d\x63\x38\x43\ +\x43\x5a\x57\x2a\x18\x43\x5a\x57\x2a\x18\x06\x23\xfa\xc1\x7d\xaa\ +\x95\x7d\xaa\x1e\x00\x00\x00\x00\x01\x00\xc9\x00\x00\x03\x11\x06\ +\x66\x00\x0c\x00\x00\x01\x33\x11\x14\x06\x23\x22\x35\x34\x36\x33\ +\x32\x17\x02\xcb\x46\xdb\x8c\xe1\xda\x8d\x63\x38\x06\x66\xfa\xc1\ +\x7d\xaa\x95\x7d\xaa\x1e\x00\x00\x01\x00\xc9\x00\x00\x04\xdc\x06\ +\x66\x00\x28\x00\x00\x01\x33\x1e\x06\x15\x14\x06\x07\x06\x26\x37\ +\x3e\x04\x35\x34\x2e\x05\x27\x11\x14\x06\x23\x22\x35\x34\x36\x33\ +\x32\x17\x02\xcb\x46\x0f\x43\x52\x5e\x57\x47\x2b\x51\x67\x0c\x37\ +\x0b\x20\x35\x2b\x1e\x10\x26\x3f\x4c\x51\x46\x37\x0a\xdb\x8c\xe1\ +\xda\x8d\x63\x38\x06\x66\x4a\x8b\x6c\x69\x63\x66\x79\x41\x81\xad\ +\x79\x0e\x1b\x0e\x2a\x45\x45\x44\x53\x30\x37\x5c\x43\x3c\x3a\x3d\ +\x52\x30\xfb\xf4\x7d\xaa\x95\x7d\xaa\x1e\x00\x00\x02\x00\xc9\x00\ +\x00\x04\xdc\x06\x66\x00\x29\x00\x38\x00\x00\x01\x11\x14\x06\x23\ +\x22\x35\x34\x36\x33\x32\x17\x11\x33\x1e\x06\x15\x14\x07\x16\x15\ +\x14\x06\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\x03\x03\x1e\x04\x17\ +\x36\x34\x2e\x04\x27\x03\x11\xdb\x8c\xe1\xda\x8d\x63\x38\x46\x0c\ +\x40\x52\x5e\x5a\x49\x2c\x21\x21\x4d\x6b\x0f\x37\x0e\x31\x38\x31\ +\x14\x49\x6b\x6f\x5a\x0c\x0c\x40\x57\x59\x63\x1f\x0b\x34\x50\x61\ +\x56\x44\x0a\x04\x14\xfd\x13\x7d\xaa\x95\x7d\xaa\x1e\x04\xc8\x36\ +\x61\x4c\x4b\x4e\x55\x72\x41\x74\x46\x3f\x4f\x87\x93\x4e\x0b\x1b\ +\x0b\x27\x35\x4a\x59\x3d\x48\x5f\x32\x2d\x4c\x01\x11\x36\x5c\x47\ +\x3c\x4a\x24\x2c\x7a\x5e\x39\x3a\x30\x4e\x30\x00\x03\x00\xc9\x00\ +\x00\x04\xdd\x07\x4c\x00\x0f\x00\x1f\x00\x4f\x00\x00\x01\x1e\x03\ +\x17\x36\x35\x34\x2e\x05\x27\x01\x36\x35\x34\x2e\x04\x27\x15\x1e\ +\x04\x17\x16\x15\x14\x06\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\x05\ +\x27\x11\x14\x06\x23\x22\x35\x34\x36\x33\x32\x17\x11\x33\x1e\x06\ +\x15\x14\x07\x16\x07\x06\x03\x11\x0f\x61\x6a\x85\x25\x05\x27\x3f\ +\x4e\x51\x46\x35\x09\x01\x82\x07\x34\x50\x61\x56\x44\x0a\x0c\x41\ +\x58\x5b\x63\x4c\x1c\x4d\x6b\x0f\x37\x0e\x33\x35\x33\x13\x27\x3f\ +\x4e\x51\x46\x35\x09\xdb\x8c\xe1\xda\x8d\x63\x38\x46\x0c\x40\x52\ +\x5e\x5a\x49\x2c\x19\x1a\x01\x03\x06\x1c\x43\x7b\x50\x6f\x30\x23\ +\x26\x35\x54\x39\x30\x2d\x30\x44\x2a\xfc\xc6\x22\x33\x3c\x5d\x37\ +\x38\x2f\x4d\x30\x58\x37\x63\x4f\x48\x57\x73\x42\x47\x68\x80\x4e\ +\x0b\x1b\x0b\x28\x2f\x41\x44\x2e\x35\x54\x39\x30\x2d\x30\x44\x2a\ +\xfd\x13\x7d\xaa\x95\x7d\xaa\x1e\x05\xae\x36\x61\x4c\x4b\x4e\x55\ +\x71\x41\x66\x42\x3e\x43\x6e\x00\x04\x00\xc9\x00\x00\x04\xdd\x08\ +\x7d\x00\x33\x00\x43\x00\x53\x00\x64\x00\x00\x01\x16\x15\x14\x06\ +\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\x05\x27\x11\x14\x06\x23\x22\ +\x35\x34\x36\x33\x32\x17\x11\x37\x1e\x06\x15\x14\x07\x16\x15\x14\ +\x07\x16\x07\x06\x27\x36\x35\x34\x2e\x04\x27\x15\x1e\x04\x01\x1e\ +\x03\x17\x36\x35\x34\x2e\x05\x27\x11\x15\x1e\x04\x17\x36\x35\x34\ +\x2e\x05\x04\xc0\x1c\x4d\x6b\x0f\x37\x0e\x33\x35\x33\x13\x27\x3f\ +\x4e\x51\x46\x35\x09\xdb\x8c\xe1\xda\x8d\x63\x38\x46\x0c\x40\x52\ +\x5e\x5a\x49\x2c\x1b\x1b\x19\x1a\x01\x03\x46\x07\x34\x50\x61\x56\ +\x44\x0a\x0c\x41\x58\x5b\x63\xfe\x9d\x0f\x61\x6a\x85\x25\x05\x27\ +\x3f\x4e\x51\x46\x35\x09\x0c\x41\x59\x5b\x63\x1f\x06\x27\x3f\x4e\ +\x51\x46\x35\x02\xf1\x42\x47\x68\x80\x4e\x0b\x1b\x0b\x28\x2f\x41\ +\x44\x2e\x35\x54\x39\x30\x2d\x30\x44\x2a\xfd\x13\x7d\xaa\x95\x7d\ +\xaa\x1e\x06\xde\x01\x36\x62\x4b\x4c\x4e\x55\x71\x41\x67\x44\x3e\ +\x47\x66\x42\x3e\x43\x6e\x09\x22\x33\x3c\x5d\x37\x38\x2f\x4d\x30\ +\x58\x37\x63\x4f\x48\x57\x02\xb8\x43\x7b\x50\x6f\x30\x23\x26\x35\ +\x54\x39\x30\x2d\x30\x44\x2a\x01\x30\x59\x37\x63\x50\x47\x58\x29\ +\x21\x2d\x35\x54\x39\x30\x2d\x30\x44\x00\x00\x00\x05\x00\xc9\x00\ +\x00\x04\xdd\x09\xad\x00\x10\x00\x20\x00\x30\x00\x68\x00\x79\x00\ +\x00\x01\x15\x1e\x04\x17\x36\x35\x34\x2e\x05\x03\x1e\x03\x17\x36\ +\x35\x34\x2e\x05\x27\x01\x36\x35\x34\x2e\x04\x27\x15\x1e\x04\x17\ +\x16\x15\x14\x06\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\x05\x27\x11\ +\x14\x06\x23\x22\x35\x34\x36\x33\x32\x17\x11\x33\x1e\x06\x15\x14\ +\x07\x16\x15\x14\x07\x16\x15\x14\x07\x16\x07\x06\x01\x15\x1e\x04\ +\x17\x36\x35\x34\x2e\x05\x03\x11\x0c\x41\x59\x5b\x63\x1f\x06\x27\ +\x3f\x4e\x51\x46\x35\x09\x0f\x61\x6a\x85\x25\x05\x27\x3f\x4e\x51\ +\x46\x35\x09\x01\x82\x07\x34\x50\x61\x56\x44\x0a\x0c\x41\x58\x5b\ +\x63\x4c\x1c\x4d\x6b\x0f\x37\x0e\x33\x35\x33\x13\x27\x3f\x4e\x51\ +\x46\x35\x09\xdb\x8c\xe1\xda\x8d\x63\x38\x46\x0c\x40\x52\x5e\x5a\ +\x49\x2c\x1b\x1b\x1b\x1b\x19\x1a\x01\x03\xfe\x38\x0c\x41\x59\x5b\ +\x63\x1f\x06\x27\x3f\x4e\x51\x46\x35\x07\xa5\x59\x37\x63\x50\x47\ +\x58\x29\x21\x2d\x35\x54\x39\x30\x2d\x30\x44\xfe\xa1\x43\x7b\x50\ +\x6f\x30\x23\x26\x35\x54\x39\x30\x2d\x30\x44\x2a\xfc\xc6\x22\x33\ +\x3c\x5d\x37\x38\x2f\x4d\x30\x58\x37\x63\x4f\x48\x57\x73\x42\x47\ +\x68\x80\x4e\x0b\x1b\x0b\x28\x2f\x41\x44\x2e\x35\x54\x39\x30\x2d\ +\x30\x44\x2a\xfd\x13\x7d\xaa\x95\x7d\xaa\x1e\x08\x0f\x36\x61\x4c\ +\x4b\x4e\x55\x71\x41\x68\x44\x3e\x47\x67\x44\x3e\x47\x66\x42\x3e\ +\x43\x6e\x05\xa4\x59\x37\x63\x50\x48\x58\x29\x22\x2d\x35\x54\x39\ +\x30\x2d\x30\x44\x00\x00\x00\x00\x01\xfe\xf2\x01\x27\xff\x38\x06\ +\x66\x00\x03\x00\x00\x01\x11\x33\x11\xfe\xf2\x46\x01\x27\x05\x3f\ +\xfa\xc1\x00\x00\x01\xfe\x37\x01\x27\xff\xf3\x06\x66\x00\x11\x00\ +\x00\x01\x37\x17\x11\x33\x11\x37\x17\x07\x17\x07\x27\x11\x23\x11\ +\x07\x27\x37\xfe\x37\x2f\x8c\x46\x8c\x2f\xaf\xaf\x2f\x8c\x46\x8c\ +\x2f\xaf\x04\xa9\x2f\x8c\x02\x1a\xfd\xe6\x8c\x2f\xaf\xaf\x2f\x8c\ +\xfd\x7f\x02\x81\x8c\x2f\xaf\x00\x01\xfd\xdf\x03\x93\x00\x4b\x05\ +\x0b\x00\x03\x00\x00\x01\x25\x15\x05\xfd\xdf\x02\x6c\xfd\x94\x04\ +\x22\xe9\x95\xe3\x00\x00\x00\x00\x02\xfd\xdf\x03\x16\x00\x4b\x05\ +\x88\x00\x03\x00\x07\x00\x00\x01\x25\x15\x05\x11\x25\x15\x05\xfd\ +\xdf\x02\x6c\xfd\x94\x02\x6c\xfd\x94\x03\xa5\xe9\x95\xe3\x01\x89\ +\xe9\x95\xe3\x00\x03\xfd\xdf\x02\x99\x00\x4b\x06\x05\x00\x03\x00\ +\x07\x00\x0b\x00\x00\x01\x25\x15\x05\x11\x25\x15\x05\x11\x25\x15\ +\x05\xfd\xdf\x02\x6c\xfd\x94\x02\x6c\xfd\x94\x02\x6c\xfd\x94\x05\ +\x1c\xe9\x95\xe3\xfe\x9b\xe9\x95\xe3\x01\x89\xe9\x95\xe3\x00\x00\ +\x01\x00\xaf\x03\x93\x04\xc9\x05\x33\x00\x03\x00\x00\x13\x25\x15\ +\x05\xaf\x04\x1a\xfb\xe6\x04\x4a\xe9\xbd\xe3\x00\x02\x00\xaf\x02\ +\xfd\x04\xc9\x05\xc9\x00\x03\x00\x07\x00\x00\x13\x25\x15\x05\x11\ +\x25\x15\x05\xaf\x04\x1a\xfb\xe6\x04\x1a\xfb\xe6\x03\xb4\xe9\xbd\ +\xe3\x01\xe3\xe9\xbd\xe3\x00\x00\x03\x00\xaf\x02\x67\x04\xc9\x06\ +\x5f\x00\x03\x00\x07\x00\x0b\x00\x00\x13\x25\x15\x05\x11\x25\x15\ +\x05\x11\x25\x15\x05\xaf\x04\x1a\xfb\xe6\x04\x1a\xfb\xe6\x04\x1a\ +\xfb\xe6\x05\x76\xe9\xbd\xe3\xfe\x5f\xe9\xbd\xe3\x01\xe3\xe9\xbd\ +\xe3\x00\x00\x00\x01\xff\xd8\x00\x7a\x00\xa0\x01\x42\x00\x07\x00\ +\x00\x26\x34\x36\x32\x16\x14\x06\x22\x28\x3b\x52\x3b\x3b\x52\xb5\ +\x52\x3b\x3b\x52\x3b\x00\x00\x00\x01\xff\x38\x01\x8b\x01\x03\x06\ +\x66\x00\x1c\x00\x00\x03\x1e\x06\x15\x14\x06\x07\x06\x26\x37\x3e\ +\x04\x35\x34\x2e\x05\x27\xc8\x0f\x43\x52\x5e\x57\x47\x2b\x51\x67\ +\x0c\x37\x0b\x20\x35\x2b\x1e\x10\x26\x3f\x4c\x51\x46\x37\x0a\x06\ +\x66\x4a\x8b\x6c\x69\x63\x66\x79\x41\x81\xad\x79\x0e\x1b\x0e\x2a\ +\x45\x45\x44\x53\x30\x37\x5c\x43\x3c\x3a\x3d\x52\x30\x00\x00\x00\ +\x01\xff\x38\x01\x2d\x01\x03\x06\x66\x00\x2c\x00\x00\x03\x1e\x06\ +\x15\x14\x07\x16\x15\x14\x06\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\ +\x03\x27\x35\x1e\x04\x17\x36\x34\x2e\x04\x27\xc8\x0c\x40\x52\x5e\ +\x5a\x49\x2c\x21\x21\x4d\x6b\x0f\x37\x0e\x31\x38\x31\x14\x49\x6b\ +\x6f\x5a\x0c\x0c\x40\x57\x59\x63\x1f\x0b\x34\x50\x61\x56\x44\x0a\ +\x06\x66\x36\x61\x4c\x4b\x4e\x55\x72\x41\x74\x46\x3f\x4f\x87\x93\ +\x4e\x0b\x1b\x0b\x27\x35\x4a\x59\x3d\x48\x5f\x32\x2d\x4c\x39\xd8\ +\x36\x5c\x47\x3c\x4a\x24\x2c\x7a\x5e\x39\x3a\x30\x4e\x30\x00\x00\ +\x01\xfe\xf2\x01\x2d\x01\x04\x07\x4c\x00\x46\x00\x00\x01\x35\x33\ +\x1e\x06\x15\x14\x07\x16\x07\x06\x07\x16\x15\x14\x06\x07\x06\x26\ +\x37\x3e\x03\x35\x34\x2e\x05\x27\x35\x1e\x04\x17\x36\x35\x34\x2e\ +\x04\x27\x35\x1e\x03\x17\x36\x35\x34\x2e\x05\x27\x15\xfe\xf2\x46\ +\x0c\x40\x52\x5e\x5a\x49\x2c\x19\x1a\x01\x03\x19\x1c\x4d\x6b\x0f\ +\x37\x0e\x34\x33\x34\x13\x27\x3f\x4e\x51\x46\x35\x09\x0c\x41\x58\ +\x5b\x63\x1f\x07\x34\x50\x61\x56\x44\x0a\x0f\x61\x6a\x85\x25\x05\ +\x27\x3f\x4e\x51\x46\x35\x09\x06\x52\xfa\x36\x61\x4c\x4b\x4e\x55\ +\x71\x41\x66\x42\x3e\x43\x6e\x41\x42\x47\x68\x80\x4e\x0b\x1b\x0b\ +\x29\x2e\x41\x44\x2e\x35\x54\x39\x30\x2d\x30\x44\x2a\xd8\x37\x63\ +\x4f\x48\x57\x29\x22\x33\x3c\x5d\x37\x38\x2f\x4d\x30\xd8\x43\x7b\ +\x50\x6f\x30\x23\x26\x35\x54\x39\x30\x2d\x30\x44\x2a\x23\x00\x00\ +\x02\xfe\xf2\x01\x2d\x01\x04\x08\x7d\x00\x4a\x00\x5b\x00\x00\x01\ +\x11\x33\x1e\x06\x15\x14\x07\x16\x15\x14\x07\x16\x07\x06\x07\x16\ +\x15\x14\x06\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\x05\x27\x35\x1e\ +\x04\x17\x36\x35\x34\x2e\x04\x27\x35\x1e\x03\x17\x36\x35\x34\x2e\ +\x05\x27\x15\x11\x15\x1e\x04\x17\x36\x35\x34\x2e\x05\xfe\xf2\x46\ +\x0c\x40\x52\x5e\x5a\x49\x2c\x1b\x1b\x19\x1a\x01\x03\x19\x1c\x4d\ +\x6b\x0f\x37\x0e\x34\x33\x34\x13\x27\x3f\x4e\x51\x46\x35\x09\x0c\ +\x41\x58\x5b\x63\x1f\x07\x34\x50\x61\x56\x44\x0a\x0f\x61\x6a\x85\ +\x25\x05\x27\x3f\x4e\x51\x46\x35\x09\x0c\x41\x59\x5b\x63\x1f\x06\ +\x27\x3f\x4e\x51\x46\x35\x06\x52\x02\x2b\x36\x62\x4b\x4c\x4e\x55\ +\x71\x41\x67\x44\x3e\x47\x66\x42\x3e\x43\x6e\x41\x42\x47\x68\x80\ +\x4e\x0b\x1b\x0b\x29\x2e\x41\x44\x2e\x35\x54\x39\x30\x2d\x30\x44\ +\x2a\xd8\x37\x63\x4f\x48\x57\x29\x22\x33\x3c\x5d\x37\x38\x2f\x4d\ +\x30\xd8\x43\x7b\x50\x6f\x30\x23\x26\x35\x54\x39\x30\x2d\x30\x44\ +\x2a\x23\x01\x53\x59\x37\x63\x50\x47\x58\x29\x21\x2d\x35\x54\x39\ +\x30\x2d\x30\x44\x00\x00\x00\x00\x03\xfe\xf2\x01\x2d\x01\x04\x09\ +\xad\x00\x4e\x00\x5f\x00\x70\x00\x00\x01\x11\x33\x1e\x06\x15\x14\ +\x07\x16\x15\x14\x07\x16\x15\x14\x07\x16\x07\x06\x07\x16\x15\x14\ +\x06\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\x05\x27\x35\x1e\x04\x17\ +\x36\x35\x34\x2e\x04\x27\x35\x1e\x03\x17\x36\x35\x34\x2e\x05\x27\ +\x15\x11\x15\x1e\x04\x17\x36\x35\x34\x2e\x05\x03\x15\x1e\x04\x17\ +\x36\x35\x34\x2e\x05\xfe\xf2\x46\x0c\x40\x52\x5e\x5a\x49\x2c\x1b\ +\x1b\x1b\x1b\x19\x1a\x01\x03\x19\x1c\x4d\x6b\x0f\x37\x0e\x34\x33\ +\x34\x13\x27\x3f\x4e\x51\x46\x35\x09\x0c\x41\x58\x5b\x63\x1f\x07\ +\x34\x50\x61\x56\x44\x0a\x0f\x61\x6a\x85\x25\x05\x27\x3f\x4e\x51\ +\x46\x35\x09\x0c\x41\x59\x5b\x63\x1f\x06\x27\x3f\x4e\x51\x46\x35\ +\x09\x0c\x41\x59\x5b\x63\x1f\x06\x27\x3f\x4e\x51\x46\x35\x06\x52\ +\x03\x5b\x36\x61\x4c\x4b\x4e\x55\x71\x41\x68\x44\x3e\x47\x67\x44\ +\x3e\x47\x66\x42\x3e\x43\x6e\x41\x42\x47\x68\x80\x4e\x0b\x1b\x0b\ +\x29\x2e\x41\x44\x2e\x35\x54\x39\x30\x2d\x30\x44\x2a\xd8\x37\x63\ +\x4f\x48\x57\x29\x22\x33\x3c\x5d\x37\x38\x2f\x4d\x30\xd8\x43\x7b\ +\x50\x6f\x30\x23\x26\x35\x54\x39\x30\x2d\x30\x44\x2a\x23\x02\x84\ +\x59\x37\x63\x50\x48\x58\x29\x22\x2d\x35\x54\x39\x30\x2d\x30\x44\ +\xfe\xf9\x59\x37\x63\x50\x47\x58\x29\x21\x2d\x35\x54\x39\x30\x2d\ +\x30\x44\x00\x00\x01\xfc\xbf\xfd\xb5\xff\x8f\xff\x85\x00\x05\x00\ +\x00\x0d\x02\x35\x2d\x01\xfc\xbf\x02\xd0\xfd\x30\x01\xd3\xfe\x2d\ +\x7b\xe8\xe8\x4d\x9b\x95\x00\x00\x01\xfd\xc4\xfe\xb1\xfe\x64\xff\ +\x51\x00\x07\x00\x00\x00\x34\x36\x32\x16\x14\x06\x22\xfd\xc4\x2f\ +\x42\x2f\x2f\x42\xfe\xe0\x42\x2f\x2f\x42\x2f\x00\x01\xfc\xf0\xfe\ +\xca\xff\x38\xff\x10\x00\x03\x00\x00\x05\x21\x15\x21\xfc\xf0\x02\ +\x48\xfd\xb8\xf0\x46\x00\x00\x00\x01\xfd\x9c\xfe\x11\xfe\x8c\xff\ +\xa6\x00\x02\x00\x00\x01\x1b\x01\xfd\x9c\x78\x78\xfe\x11\x01\x95\ +\xfe\x6b\x00\x00\x01\xfd\x2c\xfc\xcf\xfe\xfc\xff\x9f\x00\x05\x00\ +\x00\x05\x0b\x01\x33\x1b\x01\xfe\xfc\xe8\xe8\x4d\x9b\x95\x61\xfd\ +\x30\x02\xd0\xfe\x2d\x01\xd3\x00\x02\xfd\x2c\xfc\xcf\xfe\xfc\xff\ +\x9f\x00\x05\x00\x0d\x00\x00\x05\x0b\x01\x33\x1b\x01\x06\x34\x36\ +\x32\x16\x14\x06\x22\xfe\xfc\xe8\xe8\x4d\x9b\x95\xe5\x2f\x42\x2f\ +\x2f\x42\x61\xfd\x30\x02\xd0\xfe\x2d\x01\xd3\x74\x42\x2f\x2f\x42\ +\x2f\x00\x00\x00\x02\xfc\xbf\xfc\xcf\xff\x8f\xff\x9c\x00\x07\x00\ +\x0d\x00\x00\x04\x34\x36\x32\x16\x14\x06\x22\x0d\x02\x35\x2d\x01\ +\xfd\xc4\x2f\x42\x2f\x2f\x42\xfe\xcc\x02\xd0\xfd\x30\x01\xd3\xfe\ +\x2d\xd5\x42\x2f\x2f\x42\x2f\x5d\xe8\xe8\x4d\x9b\x95\x00\x00\x00\ +\x02\xfc\xf0\xfe\x02\xff\x38\xff\x51\x00\x03\x00\x0b\x00\x00\x01\ +\x21\x15\x21\x36\x34\x36\x32\x16\x14\x06\x22\xfc\xf0\x02\x48\xfd\ +\xb8\xd4\x2f\x42\x2f\x2f\x42\xfe\x48\x46\xde\x42\x2f\x2f\x42\x2f\ +\x00\x00\x00\x00\x01\x00\xc8\xff\xf8\x01\xae\x06\x6e\x00\x65\x00\ +\x00\x25\x2e\x01\x35\x34\x3e\x02\x35\x34\x2e\x02\x35\x34\x3e\x02\ +\x35\x34\x2e\x02\x35\x34\x3e\x02\x35\x34\x2e\x02\x35\x34\x3e\x02\ +\x35\x34\x2e\x02\x27\x26\x35\x34\x36\x33\x32\x17\x1e\x02\x15\x14\ +\x0e\x02\x15\x14\x1e\x03\x15\x14\x0e\x02\x15\x14\x1e\x03\x15\x14\ +\x0e\x02\x15\x14\x1e\x03\x15\x14\x0e\x02\x15\x14\x16\x17\x16\x15\ +\x14\x06\x23\x22\x01\x02\x20\x1a\x24\x2c\x24\x24\x2c\x24\x24\x2c\ +\x24\x24\x2c\x24\x24\x2c\x24\x24\x2c\x24\x24\x2c\x24\x0e\x0a\x20\ +\x03\x05\x15\x0a\x0d\x2a\x07\x3a\x1a\x28\x31\x28\x1b\x26\x26\x1b\ +\x29\x30\x29\x1b\x26\x26\x1b\x29\x30\x29\x1b\x26\x26\x1b\x29\x30\ +\x29\x12\x15\x05\x15\x0a\x19\x17\x21\x34\x2d\x1d\x34\x20\x29\x14\ +\x16\x33\x2a\x46\x27\x1d\x34\x20\x29\x14\x16\x33\x2a\x46\x27\x1d\ +\x34\x20\x29\x14\x16\x33\x2a\x46\x27\x1d\x34\x20\x29\x14\x0d\x1b\ +\x0d\x1e\x03\x05\x0a\x07\x11\x1f\x07\x2e\x26\x18\x21\x3e\x27\x2e\ +\x13\x1e\x30\x1f\x1c\x26\x17\x21\x3f\x27\x2e\x13\x1e\x30\x1f\x1c\ +\x26\x17\x21\x3f\x27\x2e\x13\x1e\x30\x1f\x1c\x26\x17\x21\x3f\x27\ +\x2e\x13\x19\x1e\x15\x05\x0a\x07\x11\x00\x00\x00\x01\x00\xb4\xfe\ +\xcf\x01\xc2\x06\x6e\x00\x60\x00\x00\x01\x03\x33\x2e\x01\x35\x34\ +\x3e\x02\x35\x34\x2e\x02\x35\x34\x3e\x02\x35\x34\x2e\x02\x35\x34\ +\x3e\x02\x35\x34\x2e\x02\x35\x34\x3e\x02\x35\x34\x26\x27\x26\x35\ +\x34\x36\x33\x32\x17\x1e\x02\x15\x14\x0e\x02\x15\x14\x1e\x03\x15\ +\x14\x0e\x02\x15\x14\x1e\x03\x15\x14\x0e\x02\x15\x14\x1e\x03\x15\ +\x14\x0e\x02\x15\x14\x16\x17\x33\x01\x3b\x87\x44\x1a\x16\x24\x2c\ +\x24\x24\x2c\x24\x24\x2c\x24\x24\x2c\x24\x24\x2c\x24\x24\x2c\x24\ +\x24\x2c\x24\x28\x13\x05\x15\x0a\x0f\x28\x07\x3a\x1a\x28\x31\x28\ +\x1b\x26\x26\x1b\x29\x30\x29\x1b\x26\x26\x1b\x29\x30\x29\x1b\x26\ +\x26\x1b\x29\x30\x29\x11\x14\x71\xfe\xcf\x01\x52\x1c\x33\x29\x1d\ +\x34\x20\x29\x14\x16\x33\x2a\x46\x27\x1d\x34\x20\x29\x14\x16\x33\ +\x2a\x46\x27\x1d\x34\x20\x29\x14\x16\x33\x2a\x46\x27\x1d\x34\x20\ +\x29\x14\x18\x2f\x0f\x05\x0a\x07\x11\x1f\x07\x2e\x26\x18\x21\x3e\ +\x27\x2e\x13\x1e\x30\x1f\x1c\x26\x17\x21\x3f\x27\x2e\x13\x1e\x30\ +\x1f\x1c\x26\x17\x21\x3f\x27\x2e\x13\x1e\x30\x1f\x1c\x26\x17\x21\ +\x3f\x27\x2e\x13\x18\x1d\x15\x00\x01\xfc\xab\x06\xda\x00\x0f\x08\ +\x81\x00\x13\x00\x00\x01\x32\x3e\x03\x37\x17\x0e\x03\x07\x06\x23\ +\x22\x26\x27\x37\x16\xfd\xaf\x5e\xac\x74\x65\x33\x12\x38\x12\x3f\ +\x5b\x7c\x42\x51\x68\x5a\xae\x39\x15\x6b\x07\x37\x35\x4b\x62\x47\ +\x20\x25\x28\x5e\x69\x5c\x18\x1e\x2a\x1b\x41\x29\x00\x00\x00\x00\ +\x01\xfc\xab\x06\xda\x00\x0f\x08\x81\x00\x11\x00\x00\x01\x22\x07\ +\x27\x3e\x01\x33\x32\x17\x1e\x01\x17\x07\x2e\x04\xfd\xaf\x84\x6b\ +\x15\x39\xae\x5a\x68\x51\x7c\xc4\x2a\x38\x12\x33\x65\x74\xac\x08\ +\x23\x29\x41\x1b\x2a\x1e\x2e\xd7\x5e\x25\x20\x47\x62\x4b\x35\x00\ +\x01\xfd\x12\x06\xcd\xff\xdc\x08\x7c\x00\x06\x00\x00\x01\x11\x33\ +\x01\x07\x01\x11\xfd\x12\x46\x02\x84\x23\xfd\x9f\x06\xda\x01\xa2\ +\xfe\x8e\x3c\x01\x5d\xfe\xaf\x00\x01\xfd\x6c\x06\xda\xff\x38\x07\ +\xc1\x00\x22\x00\x00\x01\x32\x1e\x03\x33\x32\x3e\x01\x33\x32\x16\ +\x15\x14\x07\x0e\x02\x23\x22\x2e\x03\x23\x22\x0e\x01\x23\x22\x26\ +\x35\x34\x36\xfd\xf8\x1b\x30\x23\x20\x24\x12\x17\x26\x1c\x0b\x07\ +\x11\x1e\x09\x2d\x26\x18\x1c\x32\x25\x23\x29\x16\x10\x1c\x17\x0a\ +\x07\x11\x5e\x07\xc0\x18\x23\x23\x18\x20\x20\x14\x0a\x0d\x2b\x08\ +\x38\x1a\x1b\x26\x27\x1b\x18\x17\x15\x0b\x1a\x58\x00\x00\x00\x00\ +\x01\xfd\x07\x06\xda\xff\x9f\x08\xb4\x00\x10\x00\x00\x03\x11\x14\ +\x07\x06\x23\x22\x27\x26\x35\x11\x33\x11\x14\x20\x35\x11\x61\x94\ +\x3a\x7e\x9d\x41\x6e\x46\x02\x0c\x08\xb4\xfe\xc8\x7a\x1d\x0b\x15\ +\x23\x6a\x01\x38\xfe\xca\x5e\x5e\x01\x36\x00\x00\x03\xfc\x78\xfd\ +\xb8\xff\xb0\xff\x51\x00\x07\x00\x0f\x00\x1b\x00\x00\x00\x34\x36\ +\x32\x16\x14\x06\x22\x24\x34\x36\x32\x16\x14\x06\x22\x04\x22\x26\ +\x27\x37\x1e\x01\x32\x36\x37\x17\x06\xfe\x5a\x2f\x42\x2f\x2f\x42\ +\xfe\xa5\x2f\x42\x2f\x2f\x42\x01\x2e\xee\xdf\x46\x2a\x41\xc5\xd8\ +\xc5\x43\x28\x46\xfe\xe0\x42\x2f\x2f\x42\x2f\x2f\x42\x2f\x2f\x42\ +\x2f\xf9\x76\x48\x2c\x3b\x51\x51\x3b\x2c\x48\x00\x04\xfc\x78\xfd\ +\xb8\xff\xb0\xff\x51\x00\x07\x00\x0f\x00\x17\x00\x23\x00\x00\x00\ +\x34\x36\x32\x16\x14\x06\x22\x36\x34\x36\x32\x16\x14\x06\x22\x24\ +\x34\x36\x32\x16\x14\x06\x22\x04\x22\x26\x27\x37\x1e\x01\x32\x36\ +\x37\x17\x06\xfd\xc4\x2f\x42\x2f\x2f\x42\xcb\x2f\x42\x2f\x2f\x42\ +\xfd\xdd\x2f\x42\x2f\x2f\x42\x01\x92\xee\xdf\x46\x2a\x41\xc5\xd8\ +\xc5\x43\x28\x46\xfe\xe0\x42\x2f\x2f\x42\x2f\x2f\x42\x2f\x2f\x42\ +\x2f\x2f\x42\x2f\x2f\x42\x2f\xf9\x76\x48\x2c\x3b\x51\x51\x3b\x2c\ +\x48\x00\x00\x00\x01\x00\xb4\x01\x13\x02\xaa\x03\x89\x00\x23\x00\ +\x00\x01\x32\x17\x3e\x02\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\ +\x34\x36\x33\x32\x35\x34\x26\x23\x22\x07\x03\x23\x13\x36\x26\x23\ +\x22\x07\x27\x36\x01\x75\x2b\x12\x17\x12\x2f\x1f\x32\x4f\x2e\x31\ +\x2f\x28\x2c\x24\x23\x2a\x19\x50\x0f\x63\x97\x65\x02\x0b\x07\x17\ +\x25\x30\x51\x03\x89\x36\x16\x0e\x12\x49\x35\x3c\x50\x25\x25\x1f\ +\x29\x11\x0c\x1b\x4c\xfe\x16\x01\xf4\x0b\x13\x3d\x23\x7e\x00\x00\ +\x01\x00\xb8\x01\x03\x02\xb4\x03\x89\x00\x37\x00\x00\x01\x34\x26\ +\x23\x22\x06\x15\x14\x1e\x04\x15\x14\x06\x23\x22\x26\x35\x34\x36\ +\x33\x32\x16\x15\x14\x06\x15\x14\x16\x33\x32\x36\x35\x34\x2e\x04\ +\x35\x34\x36\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x02\ +\x39\x23\x1f\x38\x2c\x26\x3a\x43\x3a\x26\x9e\x74\x5a\x72\x30\x20\ +\x1b\x25\x12\x3a\x29\x2c\x3a\x25\x38\x40\x38\x25\x83\x71\x55\x66\ +\x28\x1a\x20\x20\x07\x03\x14\x11\x24\x23\x31\x1b\x30\x21\x2f\x30\ +\x51\x32\x53\x51\x48\x43\x31\x32\x23\x16\x10\x18\x0b\x1f\x23\x33\ +\x27\x25\x37\x20\x27\x28\x48\x30\x50\x59\x55\x3c\x18\x20\x1f\x15\ +\x07\x13\x00\x00\x01\x00\x8c\x00\xec\x03\x0c\x03\x80\x00\x2a\x00\ +\x00\x01\x32\x36\x35\x34\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\ +\x14\x23\x22\x2e\x01\x23\x22\x06\x07\x23\x35\x01\x23\x22\x07\x06\ +\x07\x23\x37\x21\x15\x01\x36\x33\x32\x1e\x02\x02\x4f\x19\x2a\x23\ +\x24\x2c\x28\x2f\x30\x2f\xb9\x1b\x3d\x42\x22\x2d\x3a\x1f\x4e\x01\ +\xaa\x80\x2f\x24\x10\x0c\x31\x28\x01\xce\xfe\x6b\x17\x19\x1f\x2f\ +\x19\x29\x01\x52\x1b\x0c\x11\x29\x1f\x25\x25\x50\x3c\xa4\x28\x29\ +\x11\x19\x1d\x01\xc7\x15\x08\x22\xc8\x5b\xfe\x82\x03\x1c\x20\x1c\ +\x00\x00\x00\x00\x02\x00\x78\x00\x00\x03\x76\x03\x89\x00\x24\x00\ +\x35\x00\x00\x01\x14\x0e\x04\x23\x22\x27\x03\x33\x15\x21\x35\x33\ +\x13\x36\x23\x22\x06\x07\x27\x3e\x03\x33\x32\x17\x3e\x01\x33\x32\ +\x1e\x02\x25\x07\x06\x15\x14\x33\x32\x36\x37\x36\x35\x34\x23\x22\ +\x0e\x02\x03\x76\x0c\x1a\x30\x41\x63\x3b\x49\x33\x33\x7c\xfe\x6a\ +\x82\x8e\x07\x15\x13\x50\x27\x38\x1b\x35\x35\x56\x3c\x46\x07\x33\ +\x48\x3e\x2b\x3f\x25\x12\xfe\xa2\x32\x08\x36\x2e\x66\x19\x14\x47\ +\x10\x1f\x24\x1c\x02\xa9\x26\x53\x61\x55\x47\x2a\x36\xff\x00\x3f\ +\x3f\x02\xc1\x25\x77\x70\x18\x44\x71\x51\x2d\x41\x26\x1b\x24\x3f\ +\x4e\x02\xfa\x26\x1e\x4f\x6b\x80\x69\x39\x6e\x08\x15\x2f\x00\x00\ +\x01\x00\x92\x01\x09\x04\xd7\x03\x89\x00\x3e\x00\x00\x01\x22\x26\ +\x37\x13\x36\x26\x23\x22\x0e\x02\x07\x03\x23\x13\x36\x26\x23\x22\ +\x0e\x02\x07\x03\x23\x13\x36\x23\x22\x06\x07\x27\x3e\x03\x33\x32\ +\x17\x36\x33\x32\x17\x3e\x03\x33\x32\x16\x07\x03\x06\x33\x3e\x01\ +\x37\x17\x0e\x03\x03\xc0\x36\x26\x09\x54\x04\x10\x1b\x10\x21\x26\ +\x1e\x07\x5c\x97\x6a\x04\x10\x1b\x10\x21\x26\x1e\x07\x5c\x97\x63\ +\x07\x15\x13\x50\x27\x38\x1b\x35\x35\x56\x3c\x46\x07\x56\x82\x41\ +\x13\x18\x20\x28\x40\x38\x2b\x39\x0d\x4a\x07\x15\x15\x4f\x26\x38\ +\x1b\x35\x35\x56\x01\x09\x46\x2f\x01\xa2\x17\x11\x08\x15\x2f\x22\ +\xfe\x39\x02\x0d\x17\x11\x08\x15\x2f\x22\xfe\x39\x01\xed\x25\x77\ +\x70\x18\x44\x71\x51\x2d\x41\x41\x41\x12\x19\x0f\x07\x4d\x3f\xfe\ +\x95\x25\x01\x77\x6f\x18\x44\x71\x51\x2d\x00\x00\x01\x00\x8b\xff\ +\xf1\x04\x05\x05\x1e\x00\x3c\x00\x00\x01\x22\x0e\x02\x07\x33\x15\ +\x23\x06\x07\x0a\x01\x23\x22\x26\x35\x34\x36\x33\x32\x16\x15\x14\ +\x06\x23\x22\x06\x15\x14\x33\x32\x3e\x02\x37\x36\x37\x23\x35\x33\ +\x3e\x02\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\ +\x35\x34\x26\x03\x6d\x21\x34\x27\x1a\x0e\x95\x9f\x1c\x01\x35\xd5\ +\x75\x55\x43\x3c\x27\x22\x32\x19\x13\x15\x11\x33\x2e\x43\x26\x24\ +\x0e\x0c\x18\x86\x98\x25\x63\x81\x42\x3f\x59\x3c\x27\x22\x32\x19\ +\x13\x26\x21\x04\xd8\x34\x65\x6f\x50\x3f\xb1\x09\xfe\xc6\xfe\xa4\ +\x33\x3e\x3b\x4d\x23\x1f\x1d\x25\x10\x0f\x10\x6a\xab\xd9\x6e\x57\ +\x57\x3f\x75\xb6\x73\x39\x39\x3a\x4d\x23\x1f\x1c\x26\x1f\x07\x09\ +\x00\x00\x00\x00\x01\x00\xc8\x01\x0e\x08\xf2\x03\x9c\x00\x06\x00\ +\x00\x13\x01\x17\x09\x01\x07\x01\xc8\x08\x20\x0a\xf8\xd8\x07\x28\ +\x0a\xf7\xe0\x02\x78\x01\x24\x45\xfe\xfe\xfe\xfe\x45\x01\x24\x00\ +\x01\x00\xc8\x01\x0e\x08\xf2\x03\x9c\x00\x06\x00\x00\x01\x15\x01\ +\x27\x09\x01\x37\x08\xf2\xf7\xe0\x0a\x07\x28\xf8\xd8\x0a\x02\x78\ +\x46\xfe\xdc\x45\x01\x02\x01\x02\x45\x00\x00\x00\x02\x00\xc8\x01\ +\x09\x03\xa2\x05\x83\x00\x2e\x00\x32\x00\x00\x01\x33\x1e\x01\x17\ +\x37\x17\x07\x1e\x01\x15\x14\x06\x07\x06\x26\x37\x3e\x05\x35\x34\ +\x2e\x04\x27\x07\x11\x14\x06\x23\x22\x35\x34\x36\x33\x32\x17\x11\ +\x07\x27\x3f\x02\x26\x27\x02\x30\x31\x0f\x4c\x3e\x5d\x23\x5f\x43\ +\x44\x39\x48\x08\x27\x08\x13\x20\x1b\x15\x0f\x08\x0c\x16\x1d\x22\ +\x25\x13\x7a\x99\x62\x9e\x98\x63\x44\x29\x75\x23\x98\x31\x53\x45\ +\x0e\x05\x83\x4c\x79\x47\x5d\x23\x5e\x4b\x74\x4a\x5b\x79\x54\x0a\ +\x13\x0a\x17\x2c\x26\x29\x29\x32\x1c\x1a\x2f\x24\x22\x1c\x1c\x0d\ +\x79\xfe\x3e\x57\x77\x68\x57\x78\x15\x01\x3d\x75\x23\x98\x31\x52\ +\x39\x42\x00\x00\x01\x00\xc8\x01\x09\x03\xa2\x05\x83\x00\x25\x00\ +\x00\x01\x33\x1e\x04\x15\x14\x06\x07\x06\x26\x37\x3e\x05\x35\x34\ +\x2e\x03\x27\x11\x14\x06\x23\x22\x35\x34\x36\x33\x32\x17\x02\x30\ +\x31\x0e\x4d\x59\x55\x38\x39\x48\x08\x27\x08\x13\x20\x1b\x15\x0f\ +\x08\x32\x4a\x4d\x40\x0a\x99\x62\x9e\x98\x63\x44\x29\x05\x83\x46\ +\x82\x61\x60\x72\x3e\x5b\x79\x54\x0a\x13\x0a\x17\x2c\x26\x29\x29\ +\x32\x1c\x34\x53\x39\x36\x4b\x2d\xfd\x2b\x57\x77\x68\x57\x78\x15\ +\x00\x00\x00\x00\x03\x00\xb9\x01\x0c\x04\x98\x05\x02\x00\x3d\x00\ +\x47\x00\x4f\x00\x00\x01\x03\x23\x13\x36\x26\x23\x22\x0e\x01\x0f\ +\x01\x1e\x01\x15\x14\x06\x23\x22\x26\x3f\x01\x06\x23\x22\x35\x34\ +\x36\x33\x32\x17\x13\x37\x03\x3e\x01\x33\x32\x16\x17\x3e\x02\x33\ +\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x35\x34\x26\ +\x23\x22\x05\x26\x23\x22\x06\x15\x14\x16\x33\x32\x17\x07\x06\x33\ +\x32\x36\x35\x34\x03\xb3\x63\x97\x6a\x03\x0a\x0d\x13\x41\x33\x33\ +\x16\x22\x28\x4d\x3f\x4d\x3e\x18\x25\x54\x37\x6b\x57\x35\x3d\x44\ +\x54\xa0\x5a\x51\x7b\x37\x1b\x19\x09\x17\x12\x2f\x1f\x32\x4f\x2e\ +\x31\x2f\x28\x2c\x24\x23\x2a\x19\x50\xfd\xf8\x3f\x34\x28\x34\x18\ +\x21\x3b\xcf\x24\x0b\x1b\x18\x25\x02\xfd\xfe\x16\x02\x0d\x0e\x17\ +\x17\x19\x19\x71\x3b\x75\x2a\x46\x5f\x71\x73\xbf\x20\x63\x33\x3a\ +\x3b\x01\xb1\x2d\xfe\x36\x27\x2a\x1b\x1b\x16\x0e\x12\x49\x35\x3c\ +\x50\x25\x25\x1f\x29\x11\x0c\x1b\x5f\x43\x1e\x1d\x16\x18\x8e\xba\ +\x3b\x48\x2d\x29\x00\x00\x00\x00\x01\x00\xc1\x01\x76\x04\xe9\x03\ +\x64\x00\x3b\x00\x00\x01\x22\x2e\x03\x23\x22\x06\x15\x14\x16\x33\ +\x32\x36\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\x3e\x03\x33\ +\x32\x1e\x04\x33\x32\x36\x35\x34\x26\x23\x22\x06\x23\x22\x26\x35\ +\x34\x36\x33\x32\x16\x15\x14\x0e\x02\x03\xc3\x4a\x88\x67\x5f\x67\ +\x31\x33\x4c\x0f\x0d\x06\x1f\x0a\x3e\x38\x48\x2a\x49\x59\x2c\x41\ +\x54\x46\x1f\x41\x7a\x58\x5a\x47\x54\x28\x30\x4f\x0e\x0e\x05\x20\ +\x0a\x3e\x38\x48\x2a\x49\x59\x40\x62\x5b\x01\x76\x4c\x6c\x6c\x4c\ +\x3f\x2e\x18\x10\x02\x44\x23\x32\x44\x77\x83\x38\x58\x35\x22\x0d\ +\x37\x51\x60\x51\x37\x3f\x2d\x19\x0f\x02\x44\x24\x32\x44\x77\x83\ +\x45\x66\x32\x17\x00\x00\x00\x00\x01\x00\xc1\x01\x76\x04\xe9\x03\ +\x64\x00\x3d\x00\x00\x01\x22\x2e\x02\x35\x34\x36\x33\x32\x16\x15\ +\x14\x06\x23\x22\x26\x23\x22\x0e\x01\x15\x14\x16\x33\x32\x3e\x04\ +\x33\x32\x1e\x03\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x16\ +\x33\x32\x3e\x01\x35\x34\x26\x23\x22\x0e\x03\x01\xe7\x29\x5b\x62\ +\x40\x59\x49\x2a\x48\x38\x3e\x0a\x20\x05\x09\x0a\x09\x4f\x30\x28\ +\x54\x47\x5a\x58\x7a\x41\x1f\x46\x54\x41\x2c\x59\x49\x2a\x48\x38\ +\x3e\x0a\x1f\x06\x08\x0b\x09\x4c\x33\x31\x67\x5f\x67\x88\x01\x76\ +\x17\x32\x66\x45\x83\x77\x44\x32\x24\x44\x02\x04\x13\x11\x2d\x3f\ +\x37\x51\x60\x51\x37\x0d\x22\x35\x58\x38\x83\x77\x44\x32\x23\x44\ +\x02\x04\x13\x11\x2e\x3f\x4c\x6c\x6c\x4c\x00\x00\x01\x00\xc1\x01\ +\x26\x04\xe9\x03\xb4\x00\x44\x00\x00\x01\x33\x15\x1e\x04\x33\x32\ +\x36\x35\x34\x26\x23\x22\x06\x23\x22\x26\x35\x34\x36\x33\x32\x16\ +\x15\x14\x0e\x02\x23\x22\x27\x15\x23\x35\x2e\x04\x23\x22\x06\x15\ +\x14\x16\x33\x32\x36\x33\x32\x16\x15\x14\x06\x23\x22\x26\x35\x34\ +\x3e\x03\x33\x32\x17\x02\xb7\x3c\x1a\x46\x32\x3b\x3a\x1d\x30\x4f\ +\x0e\x0e\x05\x20\x0a\x3e\x38\x48\x2a\x49\x59\x40\x62\x5b\x29\x6a\ +\x66\x3c\x17\x48\x2f\x3c\x3c\x1e\x33\x4c\x0f\x0d\x06\x1f\x0a\x3e\ +\x38\x48\x2a\x49\x59\x2c\x41\x54\x46\x1f\x6c\x64\x03\xb4\xd2\x19\ +\x4e\x36\x36\x1b\x3f\x2d\x19\x0f\x02\x44\x24\x32\x44\x77\x83\x45\ +\x66\x32\x17\x52\xa2\xd9\x17\x50\x31\x35\x1a\x3f\x2e\x18\x10\x02\ +\x44\x23\x32\x44\x77\x83\x38\x58\x35\x22\x0d\x4d\x00\x00\x00\x00\ +\x01\x00\xc0\x00\x59\x02\xae\x04\x81\x00\x3b\x00\x00\x01\x14\x0e\ +\x03\x15\x14\x16\x33\x32\x36\x35\x34\x26\x35\x34\x36\x33\x32\x16\ +\x15\x14\x06\x23\x22\x2e\x03\x35\x34\x3e\x04\x35\x34\x26\x23\x22\ +\x06\x15\x14\x16\x15\x14\x06\x23\x22\x26\x35\x34\x36\x33\x32\x1e\ +\x02\x02\xae\x4c\x6c\x6c\x4c\x3f\x2f\x18\x10\x02\x43\x23\x33\x43\ +\x77\x83\x37\x59\x34\x23\x0d\x37\x51\x60\x51\x37\x3f\x2d\x19\x0f\ +\x02\x43\x25\x32\x44\x78\x82\x45\x66\x32\x17\x03\x5b\x4a\x88\x67\ +\x5f\x67\x31\x33\x4c\x0f\x0d\x06\x1f\x0a\x3e\x38\x48\x2a\x49\x59\ +\x2c\x42\x53\x46\x1f\x41\x7a\x58\x5a\x47\x54\x28\x30\x4f\x0e\x0e\ +\x05\x20\x0a\x3e\x38\x48\x2a\x49\x59\x40\x62\x5b\x00\x00\x00\x00\ +\x01\x00\xc8\x02\x40\x01\xf8\x06\x66\x00\x17\x00\x00\x13\x34\x36\ +\x33\x32\x16\x15\x11\x14\x33\x32\x3e\x01\x33\x32\x16\x15\x14\x0e\ +\x01\x23\x22\x26\x35\xc8\x73\x08\x05\x0c\x15\x12\x2a\x1d\x02\x09\ +\x2b\x3e\x67\x2a\x30\x31\x06\x13\x0c\x47\x0d\x0a\xfc\xeb\x83\x1e\ +\x1e\x2c\x09\x04\x3b\x3f\x74\x48\x00\x00\x00\x00\x01\x00\xc7\x02\ +\x34\x03\xa5\x04\x32\x00\x13\x00\x00\x01\x22\x24\x23\x22\x06\x07\ +\x06\x26\x37\x3e\x03\x33\x32\x00\x15\x14\x06\x02\xd7\x0c\xfe\xd7\ +\x10\x13\x27\x5d\x05\x32\x04\x4c\x94\x41\x32\x0c\x1b\x01\x63\xc0\ +\x02\x34\xf0\x25\x61\x05\x39\x05\x4c\x9b\x47\x2d\xfe\xdc\x0e\x0f\ +\xbd\x00\x00\x00\x01\x00\xc7\x02\x34\x04\x37\x04\x32\x00\x1a\x00\ +\x00\x01\x32\x36\x37\x36\x16\x07\x0e\x03\x22\x24\x23\x22\x06\x07\ +\x06\x26\x37\x3e\x03\x33\x32\x04\x03\x6c\x0d\x28\x62\x05\x33\x05\ +\x4b\x92\x42\x34\x18\xfe\xd7\x10\x13\x27\x5d\x05\x32\x04\x4c\x94\ +\x41\x32\x0c\x16\x01\x28\x03\x42\x24\x62\x05\x39\x05\x4b\x9a\x48\ +\x2e\xf0\x25\x61\x05\x39\x05\x4c\x9b\x47\x2d\xf0\x00\x00\x00\x00\ +\x01\x00\xc7\x03\x66\x01\xc8\x06\x23\x00\x17\x00\x00\x13\x3e\x03\ +\x35\x34\x27\x26\x3f\x01\x1e\x04\x15\x14\x0e\x02\x07\x06\x26\xc8\ +\x37\x33\x3d\x17\x43\x04\x0d\x04\x14\x19\x25\x15\x11\x18\x3f\x39\ +\x3c\x04\x34\x03\x9f\x37\x39\x5c\x5f\x3e\xbd\x37\x03\x1d\x06\x11\ +\x18\x33\x38\x5a\x36\x4a\x6e\x64\x40\x3b\x04\x38\x00\x00\x00\x00\ +\x01\x00\xc7\x00\x8a\x02\x6d\x04\x32\x00\x27\x00\x00\x01\x14\x0e\ +\x03\x23\x22\x26\x35\x37\x3e\x03\x35\x34\x2e\x02\x23\x22\x0e\x01\ +\x07\x06\x26\x37\x3e\x03\x33\x32\x1e\x05\x02\x6d\x32\x48\x4c\x34\ +\x06\x03\x0c\x0f\x0f\x2c\x2c\x1e\x27\x36\x2f\x0e\x06\x0c\x26\x25\ +\x05\x33\x05\x1e\x48\x23\x23\x0c\x0a\x1f\x2e\x2d\x2f\x24\x16\x02\ +\x58\x4f\x99\x6a\x53\x29\x43\x05\x12\x13\x42\x57\x7a\x3f\x59\x8f\ +\x4a\x26\x08\x25\x26\x05\x39\x05\x1e\x4d\x25\x1b\x09\x1b\x2a\x4a\ +\x60\x8e\x00\x00\x01\x00\xc8\x01\x46\x01\x1d\x05\x20\x00\x03\x00\ +\x00\x01\x11\x23\x11\x01\x1d\x55\x05\x20\xfc\x26\x03\xda\x00\x00\ +\x01\x00\xc8\x00\xc4\x04\x49\x04\x24\x00\x27\x00\x00\x01\x32\x1e\ +\x02\x15\x14\x06\x23\x22\x2e\x01\x23\x22\x0e\x01\x15\x14\x16\x33\ +\x32\x3e\x01\x33\x32\x16\x15\x14\x0e\x02\x23\x22\x26\x35\x34\x3e\ +\x03\x02\x80\x4c\xae\x7c\x53\xc0\x0e\x09\x8c\xa7\x29\x3c\x57\x27\ +\x88\x54\x33\x58\x31\x04\x0a\x2a\x26\x3e\x5f\x31\x9e\xd2\x23\x49\ +\x65\x93\x04\x24\x56\x6d\x59\x08\x0f\xbd\x74\x74\x48\x65\x37\x66\ +\xa6\x1f\x1f\x23\x05\x07\x27\x2d\x23\xc7\xc1\x3c\x81\x7c\x62\x3d\ +\x00\x00\x00\x00\x01\x00\xc8\x02\x28\x03\x6a\x05\x9c\x00\x2c\x00\ +\x00\x01\x34\x3e\x02\x35\x34\x26\x23\x22\x06\x15\x14\x1e\x02\x33\ +\x32\x37\x36\x16\x07\x0e\x02\x23\x22\x2e\x02\x35\x34\x3e\x02\x33\ +\x32\x1e\x02\x15\x14\x23\x22\x26\x02\x6b\x13\x17\x13\x3f\x39\x55\ +\x83\x26\x3e\x48\x25\xa2\x67\x04\x38\x05\x3b\x50\x7c\x57\x3e\x72\ +\x5c\x37\x3f\x67\x7b\x3f\x3c\x5c\x33\x19\x51\x2d\x23\x04\xb4\x17\ +\x19\x07\x12\x0f\x0d\x17\xb8\xa2\x4b\x78\x48\x26\x67\x04\x34\x04\ +\x43\x43\x2a\x39\x6a\xa8\x67\x6e\xb1\x6b\x38\x1f\x30\x33\x18\x86\ +\x1c\x00\x00\x00\x01\x00\xc7\x03\x4d\x03\xc2\x04\xef\x00\x24\x00\ +\x00\x01\x22\x2e\x04\x23\x22\x0e\x04\x07\x30\x23\x22\x26\x35\x34\ +\x37\x3e\x04\x33\x32\x1e\x02\x17\x16\x15\x14\x06\x03\x9a\x08\x12\ +\x10\x21\x2a\x4e\x31\x1d\x47\x3d\x58\x36\x65\x17\x01\x07\x2c\x01\ +\x12\x68\x52\x6f\x70\x32\x3a\x4f\x41\x30\x21\x01\x1a\x03\xf3\x19\ +\x25\x2c\x25\x19\x1f\x29\x50\x36\x68\x17\x2f\x08\x01\x01\x12\x72\ +\x52\x5e\x34\x16\x3a\x4b\x43\x03\x03\x09\x0f\x00\x01\x00\xc8\x01\ +\x7a\x03\xc2\x03\x1b\x00\x20\x00\x00\x01\x33\x32\x16\x15\x07\x0e\ +\x04\x23\x22\x2e\x02\x27\x26\x35\x34\x36\x33\x32\x17\x1e\x01\x33\ +\x32\x3e\x04\x03\x8e\x01\x07\x2c\x01\x12\x68\x52\x6f\x70\x32\x3a\ +\x4f\x41\x30\x21\x01\x1a\x0d\x0a\x03\x2c\x67\x54\x1d\x47\x3d\x58\ +\x36\x65\x03\x1b\x2f\x08\x02\x12\x72\x52\x5e\x34\x16\x3a\x4b\x43\ +\x02\x04\x09\x0f\x06\x5c\x46\x1f\x29\x50\x36\x68\x00\x00\x00\x00\ +\x01\x00\xc8\x01\xca\x03\x2e\x04\x1a\x00\x23\x00\x00\x01\x22\x26\ +\x35\x34\x3e\x01\x37\x36\x33\x32\x16\x15\x14\x07\x06\x15\x14\x16\ +\x33\x32\x3e\x03\x37\x33\x32\x16\x15\x07\x0e\x04\x01\x83\x4d\x6e\ +\x32\x2d\x04\x02\x06\x0b\x1b\x01\x43\x43\x3b\x29\x4c\x4c\x35\x59\ +\x18\x01\x07\x2c\x01\x13\x55\x3d\x5c\x6c\x01\xca\xad\x7d\x42\x92\ +\x4e\x02\x02\x14\x0a\x03\x02\x96\x68\x64\x7f\x1c\x3d\x34\x60\x18\ +\x2f\x08\x02\x13\x60\x3b\x47\x23\x00\x00\x00\x00\x01\x00\xc8\x01\ +\x5c\x05\x78\x05\x0a\x00\x0d\x00\x00\x13\x11\x33\x11\x21\x11\x21\ +\x15\x21\x11\x23\x11\x21\x11\xc8\x64\x01\xc2\x02\x8a\xfd\xda\x64\ +\xfe\x3e\x01\x5c\x03\xae\xfe\x5b\x01\xa5\x64\xfc\xb6\x01\xa5\xfe\ +\x5b\x00\x00\x00\x01\x00\xc8\x01\x5c\x05\x78\x05\x0a\x00\x0b\x00\ +\x00\x01\x23\x11\x33\x01\x11\x21\x15\x21\x11\x23\x01\x01\x2c\x64\ +\x64\x01\xc2\x02\x8a\xfd\xda\x64\xfe\x3e\x01\x5c\x03\xae\xfd\x16\ +\x02\xea\x64\xfc\xb6\x02\xea\x00\x01\x00\xc8\x01\x5c\x03\x52\x05\ +\x0a\x00\x05\x00\x00\x01\x23\x11\x21\x35\x21\x03\x52\x64\xfd\xda\ +\x02\x8a\x01\x5c\x03\x4a\x64\x00\x03\x00\xb4\x02\xf4\x02\x66\x04\ +\xa6\x00\x13\x00\x1b\x00\x23\x00\x00\x13\x34\x36\x33\x32\x17\x37\ +\x17\x07\x16\x15\x14\x06\x23\x22\x27\x07\x27\x37\x26\x25\x07\x16\ +\x33\x32\x36\x35\x34\x27\x26\x23\x22\x06\x15\x14\x17\xdb\x69\x49\ +\x35\x2e\x45\x31\x45\x1e\x69\x49\x35\x2e\x45\x31\x45\x1e\x01\x15\ +\x95\x17\x1b\x2e\x41\x3d\x17\x1b\x2e\x41\x0c\x03\xcd\x49\x69\x1e\ +\x45\x31\x45\x2e\x35\x49\x69\x1e\x45\x31\x45\x2e\x67\x95\x0c\x41\ +\x2e\x1b\x48\x0c\x41\x2e\x1b\x17\x00\x00\x00\x00\x01\xfd\x29\x06\ +\xd2\xff\xc7\x09\x0c\x00\x07\x00\x00\x03\x11\x21\x11\x23\x11\x21\ +\x11\x7f\xfd\xee\x46\x02\x9e\x06\xd2\x01\x54\xfe\xac\x02\x3a\xfd\ +\xc6\x00\x00\x00\x01\xfd\x6b\x06\xd0\xff\x3b\x09\xa0\x00\x05\x00\ +\x00\x0b\x02\x33\x1b\x01\xc5\xe8\xe8\x4d\x9b\x95\x09\xa0\xfd\x30\ +\x02\xd0\xfe\x2d\x01\xd3\x00\x00\x02\xfd\xa1\x06\xd1\xff\x05\x08\ +\x35\x00\x07\x00\x0f\x00\x00\x00\x14\x16\x32\x36\x34\x26\x22\x06\ +\x34\x36\x32\x16\x14\x06\x22\xfd\xe4\x41\x5c\x41\x41\x5c\x84\x69\ +\x92\x69\x69\x92\x07\xb1\x5c\x41\x41\x5c\x41\xb8\x92\x69\x69\x92\ +\x69\x00\x00\x00\x02\xfd\x65\x06\xda\xff\x41\x0a\x5e\x00\x0d\x00\ +\x1b\x00\x00\x01\x14\x16\x32\x36\x35\x34\x26\x27\x15\x23\x35\x0e\ +\x01\x37\x1e\x01\x15\x14\x06\x22\x26\x35\x34\x36\x37\x11\x33\xfd\ +\xaa\x63\x8c\x63\x4c\x3a\x46\x3a\x4c\xcc\x56\x75\x8c\xc4\x8c\x75\ +\x56\x46\x07\xc8\x46\x63\x63\x46\x3c\x5d\x0c\xa5\xa5\x0c\x5d\xaf\ +\x0c\x86\x59\x62\x8c\x8c\x62\x59\x86\x0c\x01\xab\x00\x00\x00\x00\ +\x04\x00\xa3\x00\xb4\x09\x9a\x05\xaf\x00\x9f\x00\xa7\x00\xb1\x00\ +\xc3\x00\x00\x13\x34\x3e\x03\x33\x32\x1e\x01\x15\x14\x0e\x02\x23\ +\x22\x26\x27\x26\x35\x34\x36\x33\x32\x17\x16\x33\x32\x36\x35\x34\ +\x2e\x02\x27\x06\x15\x14\x1e\x01\x15\x14\x06\x07\x1e\x04\x33\x32\ +\x37\x26\x35\x34\x36\x33\x32\x16\x15\x14\x06\x07\x1e\x01\x33\x32\ +\x37\x26\x35\x34\x36\x37\x26\x24\x27\x26\x35\x34\x36\x33\x32\x33\ +\x1e\x04\x15\x14\x0e\x03\x23\x22\x26\x27\x0e\x01\x23\x22\x2e\x02\ +\x27\x0e\x01\x23\x22\x2e\x02\x27\x0e\x01\x23\x22\x26\x35\x34\x3e\ +\x01\x37\x3e\x01\x35\x34\x2e\x01\x35\x34\x36\x37\x22\x23\x22\x06\ +\x15\x14\x16\x33\x32\x3e\x03\x37\x36\x33\x32\x16\x15\x16\x15\x10\ +\x23\x22\x26\x00\x34\x36\x32\x16\x14\x06\x22\x01\x36\x35\x34\x26\ +\x23\x22\x06\x15\x14\x01\x0e\x06\x15\x14\x16\x33\x32\x3e\x02\x35\ +\x34\xa3\x2a\x5c\x80\xbe\x6e\x7c\xe6\x8c\x1c\x33\x30\x21\x50\x89\ +\x24\x01\x1f\x0a\x03\x02\x3d\x61\x15\x18\x27\x41\x4f\x2c\x6c\x6e\ +\x6e\x55\x44\x3b\x5d\x34\x24\x15\x06\x0e\x4c\x1c\x9a\x7b\x4c\x5b\ +\x8e\x6f\x24\x60\x25\x4f\x69\x10\x85\x5d\x64\xfe\xd3\xbd\x0b\x17\ +\x0c\x02\x01\x82\xf5\xee\xb0\x6c\x25\x3c\x52\x54\x2e\x45\x6b\x21\ +\x47\xad\x36\x15\x35\x3f\x3e\x16\x4c\xa6\x27\x10\x20\x1e\x3d\x25\ +\x54\x97\x2c\x22\x1b\x66\x92\x45\x34\x39\x68\x68\x65\x41\x06\x07\ +\xbb\xda\x24\x2f\x13\x1d\x10\x0c\x05\x02\x01\x0d\x0e\x1a\x01\xb5\ +\x63\x71\x08\x27\x3d\x56\x3d\x3d\x56\xfb\xf7\xa2\x32\x28\x27\x38\ +\x02\x94\x17\x22\x18\x10\x08\x04\x01\x38\x2a\x1d\x2b\x24\x13\x03\ +\xc0\x36\x7f\x87\x6d\x46\x64\xa5\x5a\x3a\x4c\x22\x0b\x81\x5d\x02\ +\x02\x0b\x21\x03\x75\x31\x24\x2b\x4b\x35\x26\x0a\xbe\x51\x1b\x91\ +\x91\x1d\x1e\x8d\x54\x03\x24\x31\x30\x22\x3b\x50\x67\x8b\xc4\x4a\ +\x4c\x34\xab\x5c\x40\x51\x5c\x40\x4e\x7c\xd7\x27\x74\xa3\x21\x02\ +\x0e\x0f\x20\x15\x4e\x83\xa6\xe9\x86\x4d\x7a\x4c\x31\x14\x48\x43\ +\x3f\x4c\x10\x22\x41\x2b\x34\x57\x2c\x3d\x50\x1b\x5d\x77\x15\x1d\ +\x26\x63\x52\x15\x3f\x57\x1a\x0d\x7e\x99\x2f\x27\xea\x6c\xb0\xb5\ +\x4f\x47\x1e\x27\x41\x2d\x21\x08\x0f\x0b\x17\x13\xfe\xdc\x71\xfd\ +\xa7\x56\x3d\x3d\x56\x3d\x01\x3d\x9a\x53\x22\x2b\x6a\x52\x3f\x01\ +\x1b\x0c\x22\x22\x34\x29\x47\x30\x2c\x58\xa2\x15\x34\x62\x47\xb5\ +\x00\x00\x00\x00\x02\x00\xb4\x00\xef\x05\x2e\x05\x67\x00\x07\x00\ +\xc7\x00\x00\x00\x14\x16\x32\x36\x34\x26\x22\x37\x14\x16\x33\x32\ +\x37\x36\x35\x34\x26\x35\x34\x37\x36\x33\x32\x16\x15\x14\x07\x06\ +\x23\x22\x26\x23\x22\x07\x06\x15\x14\x16\x33\x32\x3e\x03\x33\x32\ +\x16\x14\x06\x23\x22\x2e\x03\x23\x22\x06\x15\x14\x17\x16\x33\x32\ +\x36\x33\x32\x17\x16\x15\x14\x06\x23\x22\x27\x26\x35\x34\x36\x35\ +\x34\x27\x26\x23\x22\x06\x15\x14\x1e\x03\x15\x14\x06\x22\x26\x35\ +\x34\x3e\x03\x35\x34\x26\x23\x22\x07\x06\x15\x14\x16\x15\x14\x07\ +\x06\x23\x22\x26\x35\x34\x37\x36\x33\x32\x16\x33\x32\x37\x36\x35\ +\x34\x26\x23\x22\x0e\x03\x23\x22\x26\x34\x36\x33\x32\x1e\x03\x33\ +\x32\x36\x35\x34\x27\x26\x23\x22\x06\x23\x22\x27\x26\x35\x34\x36\ +\x33\x32\x17\x16\x15\x14\x06\x15\x14\x17\x16\x33\x32\x36\x35\x34\ +\x2e\x03\x35\x34\x36\x32\x16\x15\x14\x0e\x03\x02\x83\x41\x5a\x40\ +\x40\x5a\x3f\x55\x22\x12\x08\x1b\x05\x27\x25\x2e\x35\x5e\x25\x26\ +\x36\x0d\x31\x0b\x28\x17\x0e\x2f\x17\x1a\x28\x1b\x1d\x31\x22\x3b\ +\x40\x40\x3b\x22\x32\x1e\x1b\x27\x19\x14\x2c\x08\x1b\x28\x0b\x2f\ +\x0d\x33\x27\x25\x5d\x36\x2e\x24\x28\x06\x1c\x10\x18\x24\x45\x18\ +\x23\x23\x18\x4f\x74\x4f\x19\x23\x23\x18\x45\x23\x19\x0f\x1d\x06\ +\x27\x24\x2e\x37\x5d\x25\x27\x34\x0c\x30\x0b\x28\x1b\x08\x2d\x13\ +\x19\x27\x1b\x1f\x32\x22\x3a\x40\x40\x3a\x22\x32\x1d\x1b\x27\x1b\ +\x17\x2e\x0d\x18\x27\x0b\x31\x0e\x35\x27\x24\x5d\x36\x2e\x25\x27\ +\x06\x1c\x08\x12\x22\x54\x18\x23\x23\x18\x4f\x73\x50\x19\x23\x22\ +\x19\x03\x58\x5a\x40\x40\x5a\x40\x87\x13\x2d\x08\x1b\x28\x0b\x30\ +\x0c\x34\x27\x25\x5d\x37\x2e\x24\x27\x06\x1d\x0f\x19\x23\x45\x18\ +\x23\x23\x19\x4f\x74\x4f\x19\x23\x23\x18\x54\x22\x12\x08\x1c\x06\ +\x27\x25\x2e\x36\x5d\x24\x27\x35\x0e\x31\x0b\x27\x18\x0d\x2e\x17\ +\x19\x27\x1b\x1e\x33\x22\x3a\x40\x40\x3a\x22\x32\x1d\x1b\x27\x1b\ +\x17\x2e\x0d\x18\x27\x0b\x31\x0e\x35\x27\x24\x5d\x36\x2e\x25\x27\ +\x06\x1c\x08\x12\x22\x54\x18\x23\x23\x19\x4f\x74\x4f\x19\x23\x23\ +\x18\x45\x23\x19\x0f\x1d\x06\x27\x24\x2e\x37\x5d\x25\x27\x34\x0c\ +\x30\x0b\x28\x1b\x08\x2d\x13\x1a\x28\x1b\x1d\x32\x22\x3a\x3f\x3f\ +\x3a\x22\x33\x1e\x1b\x27\x00\x00\x01\x00\xc8\x01\x5e\x0c\xd6\x04\ +\x77\x00\x0a\x00\x00\x09\x01\x21\x15\x21\x09\x01\x21\x35\x21\x01\ +\x06\xe6\x01\xa1\x04\x4f\xfb\x89\xfe\x70\xfe\x70\xfb\x89\x04\x4f\ +\x01\xa2\x04\x77\xfd\x2d\x46\x02\xb5\xfd\x4b\x46\x02\xd3\x00\x00\ +\x01\x00\xc8\x00\xe3\x05\x6c\x05\x9b\x00\x60\x00\x00\x01\x32\x3e\ +\x03\x33\x32\x16\x33\x32\x36\x35\x34\x26\x35\x34\x33\x32\x16\x15\ +\x14\x16\x15\x14\x23\x22\x26\x23\x22\x15\x14\x16\x15\x14\x06\x23\ +\x22\x26\x23\x22\x15\x14\x16\x15\x14\x06\x23\x22\x26\x23\x22\x15\ +\x14\x16\x15\x14\x06\x23\x22\x26\x23\x22\x0e\x03\x15\x14\x23\x22\ +\x35\x34\x3e\x02\x33\x32\x16\x33\x32\x3e\x03\x33\x32\x16\x33\x32\ +\x3e\x03\x33\x32\x16\x03\xc8\x28\x21\x06\x0c\x3b\x3b\x0c\x30\x0b\ +\x22\x26\x01\x15\x18\x12\x06\x85\x0b\x2a\x09\x5d\x07\x3a\x4c\x0b\ +\x2b\x09\x5c\x08\x39\x4c\x0c\x2b\x0a\x5b\x07\x3a\x4c\x0b\x2b\x09\ +\x18\x22\x10\x09\x01\x15\x2a\x19\x2b\x29\x17\x0d\x31\x0b\x28\x21\ +\x06\x0c\x3b\x3b\x0c\x30\x0b\x29\x22\x05\x0b\x3c\x3b\x0d\x31\x03\ +\xf9\x3b\x54\x53\x3b\x03\x22\x2c\x07\x1a\x07\x12\x21\x24\x0d\x37\ +\x0d\x65\x02\x64\x0f\x3b\x0e\x26\x39\x01\x64\x0f\x3b\x0e\x26\x39\ +\x02\x64\x0f\x3b\x0e\x26\x39\x01\x0d\x11\x1e\x13\x11\x12\x40\x33\ +\x46\x21\x0d\x04\x3b\x53\x54\x3b\x03\x3b\x53\x54\x3b\x04\x00\x00\ +\x01\x00\xbe\x00\xed\x05\x76\x05\x91\x00\x60\x00\x00\x01\x14\x1e\ +\x03\x15\x14\x06\x15\x14\x16\x33\x32\x36\x33\x32\x15\x14\x06\x23\ +\x22\x06\x23\x22\x35\x34\x36\x35\x34\x23\x22\x06\x23\x22\x26\x35\ +\x34\x36\x35\x34\x23\x22\x06\x23\x22\x26\x35\x34\x36\x35\x34\x23\ +\x22\x06\x23\x22\x26\x35\x34\x36\x35\x34\x2e\x03\x23\x22\x35\x34\ +\x33\x32\x1e\x02\x15\x14\x06\x15\x14\x1e\x03\x15\x14\x06\x15\x14\ +\x1e\x03\x15\x14\x06\x03\xd4\x3b\x53\x54\x3b\x03\x22\x2c\x06\x1c\ +\x06\x12\x21\x24\x0d\x37\x0d\x65\x02\x64\x0f\x3b\x0e\x26\x39\x01\ +\x64\x0f\x3b\x0e\x26\x39\x02\x64\x0f\x3b\x0e\x26\x39\x01\x0d\x11\ +\x1e\x13\x11\x12\x40\x33\x46\x21\x0d\x04\x3b\x54\x53\x3b\x03\x3b\ +\x54\x53\x3b\x04\x02\x91\x28\x21\x06\x0c\x3b\x3b\x0c\x30\x0b\x22\ +\x26\x01\x15\x18\x12\x06\x85\x0b\x2a\x09\x5d\x07\x3a\x4c\x0b\x2b\ +\x09\x5c\x08\x39\x4c\x0c\x2b\x0a\x5b\x07\x3a\x4c\x0b\x2b\x09\x18\ +\x22\x10\x09\x01\x15\x2a\x19\x2b\x29\x17\x0d\x31\x0b\x28\x21\x06\ +\x0c\x3b\x3b\x0c\x30\x0b\x29\x22\x05\x0b\x3c\x3b\x0d\x31\x00\x00\ +\x02\x00\xb4\x02\x34\x04\x04\x04\x2e\x00\x11\x00\x1d\x00\x00\x00\ +\x32\x1e\x03\x17\x07\x2e\x01\x22\x06\x07\x27\x3e\x03\x01\x2e\x03\ +\x22\x0e\x02\x07\x36\x20\x02\x17\x8a\x81\x59\x4f\x2a\x10\x34\x3d\ +\xc6\xe2\xc6\x3d\x34\x10\x2a\x4f\x59\x02\x06\x1c\x35\x4f\x66\x74\ +\x66\x4f\x35\x1c\x9a\x01\x4c\x04\x2e\x49\x67\x88\x66\x30\x2c\x35\ +\x3e\x3e\x35\x2c\x30\x66\x88\x67\xfe\xc2\x3c\x5a\x5f\x34\x34\x5f\ +\x5a\x3c\x5e\x00\x05\x00\xb4\x01\xf1\x03\x38\x04\x75\x00\x17\x00\ +\x1c\x00\x21\x00\x26\x00\x2b\x00\x00\x01\x2e\x01\x27\x23\x35\x33\ +\x3e\x01\x37\x35\x33\x15\x1e\x01\x17\x33\x15\x23\x0e\x01\x07\x15\ +\x23\x11\x0e\x01\x07\x3b\x01\x2e\x01\x27\x1d\x01\x3e\x01\x37\x23\ +\x07\x35\x23\x1e\x01\x01\xd3\x5c\x83\x0c\x34\x34\x0c\x83\x5c\x46\ +\x5c\x83\x0c\x34\x34\x0c\x83\x5c\x46\x3f\x5c\x0b\xa6\xec\x0b\x5c\ +\x3f\x3f\x5c\x0b\xa6\x46\xa6\x0b\x5c\x02\x25\x0c\x83\x5c\x46\x5c\ +\x83\x0c\x34\x34\x0c\x83\x5c\x46\x5c\x83\x0c\x34\x02\x0b\x0b\x5c\ +\x3f\x3f\x5c\x0b\xa6\xec\x0b\x5c\x3f\xa6\xa6\x3f\x5c\x00\x00\x00\ +\x07\x00\xb4\x01\x87\x04\x0c\x04\xdf\x00\x07\x00\x0f\x00\x27\x00\ +\x2c\x00\x31\x00\x36\x00\x3b\x00\x00\x12\x10\x16\x20\x36\x10\x26\ +\x20\x00\x10\x36\x20\x16\x10\x06\x20\x37\x2e\x01\x27\x23\x35\x33\ +\x3e\x01\x37\x35\x33\x15\x1e\x01\x17\x33\x15\x23\x0e\x01\x07\x15\ +\x23\x11\x0e\x01\x07\x3b\x01\x2e\x01\x27\x1d\x01\x3e\x01\x37\x23\ +\x07\x35\x23\x1e\x01\xf8\xd3\x01\x2a\xd3\xd3\xfe\xd6\xfe\xe9\xfb\ +\x01\x62\xfb\xfb\xfe\x9e\x8e\x5b\x84\x0c\x34\x34\x0c\x84\x5b\x46\ +\x5b\x84\x0c\x34\x34\x0c\x84\x5b\x46\x3f\x5c\x0b\xa6\xec\x0b\x5c\ +\x3f\x3f\x5c\x0b\xa6\x46\xa6\x0b\x5c\x03\xc8\xfe\xd6\xd3\xd3\x01\ +\x2a\xd3\xfd\xe7\x01\x62\xfb\xfb\xfe\x9e\xfb\x9e\x0c\x83\x5c\x46\ +\x5c\x83\x0c\x34\x34\x0c\x83\x5c\x46\x5c\x83\x0c\x34\x02\x0b\x0b\ +\x5c\x3f\x3f\x5c\x0b\xa6\xec\x0b\x5c\x3f\xa6\xa6\x3f\x5c\x00\x00\ +\x02\x00\xc9\xff\xc8\x05\x5a\x06\x66\x00\x0b\x00\x0f\x00\x00\x13\ +\x33\x15\x21\x11\x33\x11\x23\x35\x21\x15\x23\x13\x15\x21\x35\xc9\ +\x46\x04\x05\x46\x46\xfb\xfb\x46\x46\x04\x05\x01\xf4\x79\x04\xeb\ +\xf9\x62\x79\x79\x01\x3c\x4c\x4c\x00\x00\x00\x00\x02\x00\xc9\xff\ +\xc8\x03\x66\x06\x66\x00\x0b\x00\x0f\x00\x00\x13\x33\x15\x21\x11\ +\x33\x11\x23\x35\x21\x15\x23\x13\x15\x21\x35\xc9\x46\x02\x11\x46\ +\x46\xfd\xef\x46\x46\x02\x11\x01\xf4\x79\x04\xeb\xf9\x62\x79\x79\ +\x01\x3c\x4c\x4c\x00\x00\x00\x00\x02\x00\xc9\xff\xc8\x03\x66\x01\ +\xf4\x00\x0b\x00\x0f\x00\x00\x13\x33\x15\x21\x35\x33\x11\x23\x35\ +\x21\x15\x23\x13\x15\x21\x35\xc9\x46\x02\x11\x46\x46\xfd\xef\x46\ +\x46\x02\x11\x01\xf4\x79\x79\xfd\xd4\x79\x79\x01\x3c\x4c\x4c\x00\ +\x02\x00\xc9\x00\x00\x02\x85\x01\xbc\x00\x03\x00\x07\x00\x00\x01\ +\x07\x17\x37\x27\x17\x07\x27\x01\xa7\x7e\x7e\x7e\x7e\xde\xde\xde\ +\x01\x5c\x7e\x7e\x7e\xde\xde\xde\xde\x00\x00\x00\x01\x00\xc9\x00\ +\x00\x02\x85\x01\xbc\x00\x03\x00\x00\x01\x17\x07\x27\x01\xa7\xde\ +\xde\xde\x01\xbc\xde\xde\xde\x00\x02\x00\xc9\x00\x00\x02\x85\x06\ +\x66\x00\x03\x00\x0a\x00\x00\x01\x07\x17\x37\x27\x17\x07\x27\x37\ +\x11\x33\x01\xa7\x7e\x7e\x7e\x5b\xbb\xde\xde\xbb\x46\x01\x5c\x7e\ +\x7e\x7e\xbb\xbb\xde\xde\xbb\x04\xcd\x00\x00\x00\x01\x00\xc9\x00\ +\x00\x02\x85\x06\x66\x00\x06\x00\x00\x01\x17\x07\x27\x37\x11\x33\ +\x01\xca\xbb\xde\xde\xbb\x46\x01\x99\xbb\xde\xde\xbb\x04\xcd\x00\ +\x02\x00\xc9\x00\x00\x03\x95\x06\x66\x00\x22\x00\x26\x00\x00\x01\ +\x17\x07\x27\x37\x11\x33\x1e\x06\x15\x14\x06\x07\x06\x26\x37\x3e\ +\x04\x35\x34\x2e\x05\x27\x03\x07\x17\x37\x01\xca\xbb\xde\xde\xbb\ +\x46\x0f\x43\x52\x5e\x57\x47\x2b\x51\x67\x0c\x37\x0b\x20\x35\x2b\ +\x1e\x10\x26\x3f\x4c\x51\x46\x37\x0a\x23\x7e\x7e\x7e\x01\x99\xbb\ +\xde\xde\xbb\x04\xcd\x4a\x8b\x6c\x69\x63\x66\x79\x41\x81\xad\x79\ +\x0e\x1b\x0e\x2a\x45\x45\x44\x53\x30\x37\x5c\x43\x3c\x3a\x3d\x52\ +\x30\xfc\x29\x7e\x7e\x7e\x00\x00\x01\x00\xc9\x00\x00\x03\x95\x06\ +\x66\x00\x22\x00\x00\x01\x17\x07\x27\x37\x11\x33\x1e\x06\x15\x14\ +\x06\x07\x06\x26\x37\x3e\x04\x35\x34\x2e\x05\x27\x01\xca\xbb\xde\ +\xde\xbb\x46\x0f\x43\x52\x5e\x57\x47\x2b\x51\x67\x0c\x37\x0b\x20\ +\x35\x2b\x1e\x10\x26\x3f\x4c\x51\x46\x37\x0a\x01\x99\xbb\xde\xde\ +\xbb\x04\xcd\x4a\x8b\x6c\x69\x63\x66\x79\x41\x81\xad\x79\x0e\x1b\ +\x0e\x2a\x45\x45\x44\x53\x30\x37\x5c\x43\x3c\x3a\x3d\x52\x30\x00\ +\x03\x00\xc9\x00\x00\x03\x95\x06\x66\x00\x23\x00\x27\x00\x36\x00\ +\x00\x01\x17\x07\x27\x37\x11\x33\x1e\x06\x15\x14\x07\x16\x15\x14\ +\x06\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\x03\x27\x03\x07\x17\x37\ +\x03\x15\x1e\x04\x17\x36\x34\x2e\x04\x01\xca\xbb\xde\xde\xbb\x46\ +\x0c\x40\x52\x5e\x5a\x49\x2c\x21\x21\x4d\x6b\x0f\x37\x0e\x31\x38\ +\x31\x14\x49\x6b\x6f\x5a\x0c\x23\x7e\x7e\x7e\x5b\x0c\x40\x57\x59\ +\x63\x1f\x0b\x34\x50\x61\x56\x44\x01\x99\xbb\xde\xde\xbb\x04\xcd\ +\x36\x61\x4c\x4b\x4e\x55\x72\x41\x74\x46\x3f\x4f\x87\x93\x4e\x0b\ +\x1b\x0b\x27\x35\x4a\x59\x3d\x48\x5f\x32\x2d\x4c\x39\xfd\x48\x7e\ +\x7e\x7e\x04\xb0\xa2\x36\x5c\x47\x3c\x4a\x24\x2c\x7a\x5e\x39\x3a\ +\x30\x4e\x00\x00\x02\x00\xc9\x00\x00\x03\x95\x06\x66\x00\x23\x00\ +\x32\x00\x00\x01\x17\x07\x27\x37\x11\x33\x1e\x06\x15\x14\x07\x16\ +\x15\x14\x06\x07\x06\x26\x37\x3e\x03\x35\x34\x2e\x03\x27\x11\x15\ +\x1e\x04\x17\x36\x34\x2e\x04\x01\xca\xbb\xde\xde\xbb\x46\x0c\x40\ +\x52\x5e\x5a\x49\x2c\x21\x21\x4d\x6b\x0f\x37\x0e\x31\x38\x31\x14\ +\x49\x6b\x6f\x5a\x0c\x0c\x40\x57\x59\x63\x1f\x0b\x34\x50\x61\x56\ +\x44\x01\x99\xbb\xde\xde\xbb\x04\xcd\x36\x61\x4c\x4b\x4e\x55\x72\ +\x41\x74\x46\x3f\x4f\x87\x93\x4e\x0b\x1b\x0b\x27\x35\x4a\x59\x3d\ +\x48\x5f\x32\x2d\x4c\x39\x01\x7a\xa2\x36\x5c\x47\x3c\x4a\x24\x2c\ +\x7a\x5e\x39\x3a\x30\x4e\x00\x00\x01\x00\xc8\x01\x5c\x01\x0e\x06\ +\x98\x00\x03\x00\x00\x13\x11\x33\x11\xc8\x46\x01\x5c\x05\x3c\xfa\ +\xc4\x00\x00\x00\x01\x00\xc8\x01\x5c\x01\x0e\x05\x0a\x00\x03\x00\ +\x00\x13\x11\x33\x11\xc8\x46\x01\x5c\x03\xae\xfc\x52\x00\x00\x00\ +\x01\x00\xc8\x01\x5c\x01\x0e\x03\x7c\x00\x03\x00\x00\x13\x11\x33\ +\x11\xc8\x46\x01\x5c\x02\x20\xfd\xe0\x00\x00\x00\x01\x00\xc8\x02\ +\x6c\x01\x0e\x03\x7c\x00\x03\x00\x00\x13\x11\x33\x11\xc8\x46\x02\ +\x6c\x01\x10\xfe\xf0\x00\x00\x00\x01\x00\xc8\x01\x5c\x01\x0e\x02\ +\x6c\x00\x03\x00\x00\x13\x11\x33\x11\xc8\x46\x01\x5c\x01\x10\xfe\ +\xf0\x00\x00\x00\x01\x00\xc8\x01\x5c\x02\x0f\x02\xe6\x00\x05\x00\ +\x00\x01\x11\x23\x11\x21\x15\x01\x0e\x46\x01\x47\x02\xa0\xfe\xbc\ +\x01\x8a\x46\x00\x03\x00\xb4\x01\xdf\x03\x5c\x04\x87\x00\x07\x00\ +\x0f\x00\x17\x00\x00\x00\x34\x36\x32\x16\x14\x06\x22\x26\x14\x16\ +\x32\x36\x34\x26\x22\x02\x10\x36\x20\x16\x10\x06\x20\x01\xb8\x2f\ +\x42\x2f\x2f\x42\xeb\x9d\xde\x9d\x9d\xde\xe5\xc7\x01\x1a\xc7\xc7\ +\xfe\xe6\x03\x12\x42\x2f\x2f\x42\x2f\xbf\xde\x9d\x9d\xde\x9d\xfe\ +\x67\x01\x1a\xc7\xc7\xfe\xe6\xc7\x00\x00\x00\x00\x02\x00\xb4\x01\ +\xdf\x03\x5c\x04\x87\x00\x07\x00\x0f\x00\x00\x12\x14\x16\x32\x36\ +\x34\x26\x22\x02\x10\x36\x20\x16\x10\x06\x20\xfc\x9d\xde\x9d\x9d\ +\xde\xe5\xc7\x01\x1a\xc7\xc7\xfe\xe6\x03\xa2\xde\x9d\x9d\xde\x9d\ +\xfe\x67\x01\x1a\xc7\xc7\xfe\xe6\xc7\x00\x00\x00\x03\x00\xb4\x01\ +\x2b\x03\x5c\x05\x3b\x00\x0f\x00\x15\x00\x1b\x00\x00\x01\x15\x23\ +\x35\x2e\x01\x10\x36\x37\x35\x33\x15\x1e\x01\x10\x06\x03\x11\x3e\ +\x01\x34\x26\x27\x0e\x01\x14\x16\x17\x02\x2b\x46\x81\xb0\xb0\x81\ +\x46\x81\xb0\xb0\x81\x63\x86\x86\xa9\x63\x86\x86\x63\x01\xe1\xb6\ +\xb6\x0d\xc2\x01\x06\xc2\x0d\xb6\xb6\x0d\xc2\xfe\xfa\xc2\x02\x4f\ +\xfd\xec\x0d\x97\xcc\x97\x0d\x0d\x97\xcc\x97\x0d\x00\x00\x00\x00\ +\x02\x00\xb4\x01\xdf\x02\xf9\x04\x87\x00\x07\x00\x1b\x00\x00\x00\ +\x34\x36\x32\x16\x14\x06\x22\x04\x10\x36\x33\x32\x16\x17\x07\x26\ +\x22\x06\x14\x16\x32\x37\x17\x0e\x01\x23\x22\x01\xb8\x2f\x42\x2f\ +\x2f\x42\xfe\xcd\xc7\x8d\x45\x7c\x2f\x32\x4f\xde\x9d\x9d\xde\x4f\ +\x32\x2f\x7c\x45\x8d\x03\x12\x42\x2f\x2f\x42\x2f\x3d\x01\x1a\xc7\ +\x35\x2f\x33\x4f\x9d\xde\x9d\x4f\x33\x2f\x35\x00\x01\x00\xb4\x01\ +\xdf\x02\xf9\x04\x87\x00\x13\x00\x00\x12\x10\x36\x33\x32\x16\x17\ +\x07\x26\x22\x06\x14\x16\x32\x37\x17\x0e\x01\x23\x22\xb4\xc7\x8d\ +\x45\x7c\x2f\x32\x4f\xde\x9d\x9d\xde\x4f\x32\x2f\x7c\x45\x8d\x02\ +\xa6\x01\x1a\xc7\x35\x2f\x33\x4f\x9d\xde\x9d\x4f\x33\x2f\x35\x00\ +\x01\x00\xb4\x01\xdf\x02\xf8\x04\x87\x00\x13\x00\x00\x00\x10\x06\ +\x23\x22\x27\x37\x16\x33\x32\x36\x34\x26\x23\x22\x07\x27\x36\x33\ +\x32\x02\xf8\xc7\x8d\x8c\x64\x33\x4d\x70\x6f\x9d\x9d\x6f\x70\x4d\ +\x33\x64\x8c\x8d\x03\xc0\xfe\xe6\xc7\x64\x33\x4f\x9d\xde\x9d\x4f\ +\x33\x64\x00\x00\x02\x00\xb4\x01\x2b\x02\xf9\x05\x3b\x00\x15\x00\ +\x1b\x00\x00\x01\x33\x15\x16\x17\x07\x26\x27\x11\x36\x37\x17\x06\ +\x07\x15\x23\x35\x2e\x01\x10\x36\x37\x19\x01\x0e\x01\x14\x16\x01\ +\xe5\x46\x78\x55\x32\x41\x5a\x5a\x41\x32\x55\x78\x46\x81\xb0\xb0\ +\x81\x63\x86\x86\x05\x3b\xb6\x0c\x56\x33\x41\x0c\xfd\xec\x0c\x41\ +\x33\x56\x0c\xb6\xb6\x0d\xc2\x01\x06\xc2\x0d\xfd\xa4\x02\x14\x0d\ +\x97\xcc\x97\x00\x02\x00\xb4\x01\x2b\x02\xf8\x05\x3b\x00\x15\x00\ +\x1b\x00\x00\x01\x15\x1e\x01\x10\x06\x07\x15\x23\x35\x26\x27\x37\ +\x16\x17\x11\x06\x07\x27\x36\x37\x35\x13\x3e\x01\x34\x26\x27\x01\ +\xc7\x81\xb0\xb0\x81\x46\x77\x56\x33\x41\x59\x59\x41\x33\x56\x77\ +\x46\x63\x86\x86\x63\x05\x3b\xb6\x0d\xc1\xfe\xf8\xc1\x0d\xb6\xb6\ +\x0c\x56\x33\x41\x0c\x02\x14\x0c\x41\x33\x56\x0c\xb6\xfc\xee\x0d\ +\x97\xcc\x97\x0d\x00\x00\x00\x00\x02\x00\xb5\xff\xec\x03\x42\x01\ +\xd0\x00\x1b\x00\x1f\x00\x00\x13\x37\x17\x37\x27\x37\x17\x37\x17\ +\x07\x17\x37\x17\x07\x17\x07\x27\x07\x17\x07\x27\x07\x27\x37\x27\ +\x07\x27\x3f\x01\x07\x17\x37\xb5\x2f\xc3\x25\x6e\x2f\x6f\x6e\x2f\ +\x6f\x26\xc3\x2f\xc3\xc3\x2f\xc3\x26\x6f\x2f\x6e\x6f\x2f\x6e\x25\ +\xc3\x2f\xc3\x84\x26\x26\x25\x01\xa1\x2f\xc3\x25\x6f\x2f\x6e\x6e\ +\x2f\x6f\x25\xc3\x2f\xc3\xc3\x2f\xc3\x25\x6f\x2f\x6e\x6e\x2f\x6f\ +\x25\xc3\x2f\xc3\x26\x26\x26\x26\x00\x00\x00\x00\x01\x00\xc9\x02\ +\xaf\x01\xef\x05\x45\x00\x07\x00\x00\x01\x21\x11\x21\x11\x23\x15\ +\x33\x01\xef\xfe\xda\x01\x26\xe0\xe0\x02\xaf\x02\x96\xfe\xf8\x86\ +\x00\x00\x00\x00\x02\x00\xc9\x02\x46\x03\x7f\x05\x45\x00\x07\x00\ +\x0d\x00\x00\x01\x21\x11\x21\x11\x23\x15\x33\x05\x23\x11\x21\x11\ +\x23\x03\x7f\xfe\xda\x01\x26\xe0\xe0\xfe\x2a\xe0\x01\x26\x46\x02\ +\xaf\x02\x96\xfe\xf8\x86\x50\x01\x08\xfd\xd7\x00\x02\x00\xc9\x00\ +\xf5\x01\xef\x04\xb4\x00\x03\x00\x09\x00\x00\x01\x27\x15\x17\x03\ +\x17\x11\x25\x11\x33\x01\xa9\x9a\x9a\x9a\xe0\xfe\xda\x46\x01\xe9\ +\x27\x9c\x27\x01\x08\x38\xfe\xd8\x4b\x03\x74\x00\x01\x00\xc9\x00\ +\x8b\x01\xef\x03\xb7\x00\x05\x00\x00\x01\x23\x11\x21\x11\x23\x01\ +\xa9\xe0\x01\x26\x46\x02\xaf\x01\x08\xfc\xd4\x00\x01\x00\xca\x00\ +\xef\x01\xf0\x03\x85\x00\x07\x00\x00\x37\x11\x33\x35\x23\x11\x21\ +\x11\xca\xe0\xe0\x01\x26\xef\x01\x08\x86\x01\x08\xfd\x6a\x00\x00\ +\x02\x00\xc9\x00\x59\x02\xf7\x03\xe9\x00\x03\x00\x09\x00\x00\x01\ +\x21\x11\x21\x03\x11\x23\x11\x21\x11\x01\xef\x01\x08\xfe\xf8\xe0\ +\x46\x01\x26\x02\xe1\xfe\xf8\x01\x08\xfd\x78\x03\x90\xfe\xf8\x00\ +\x01\x00\xc9\x00\x4b\x02\xf7\x03\x85\x00\x0b\x00\x00\x01\x15\x21\ +\x11\x21\x35\x33\x35\x23\x11\x21\x11\x01\xd1\xfe\xf8\x01\x08\xe0\ +\xe0\x01\x26\x01\x21\xd6\x01\x08\xd6\x54\x01\x08\xfd\x9c\x00\x00\ +\x03\x00\xc9\x00\x7b\x04\x9f\x04\x6f\x00\x03\x00\x07\x00\x0d\x00\ +\x00\x01\x17\x07\x27\x03\x17\x07\x2f\x01\x23\x11\x21\x11\x23\x03\ +\xee\xb1\xb1\xb2\x43\xb2\xb2\xb2\x9e\xe0\x01\x26\x46\x02\xfa\xb2\ +\xb2\xb2\x01\x9d\xb2\xb2\xb2\x34\x01\x08\xfc\x0c\x00\x00\x00\x00\ +\x03\x00\xc9\x01\xd9\x03\xe1\x03\xe9\x00\x03\x00\x07\x00\x0b\x00\ +\x00\x01\x21\x11\x29\x02\x11\x21\x01\x21\x11\x21\x01\xd1\x01\x08\ +\xfe\xf8\x01\x08\x01\x08\xfe\xf8\xfd\xf0\x01\x08\xfe\xf8\x03\xe9\ +\xfe\xf8\xfe\xf8\x01\x08\xfe\xf8\x00\x00\x00\x00\x01\x00\xc9\x00\ +\x4b\x05\x46\x04\x70\x00\x14\x00\x00\x01\x11\x23\x11\x37\x16\x00\ +\x1e\x01\x17\x11\x23\x11\x21\x11\x23\x2e\x04\x01\x0f\x46\x46\xa2\ +\x01\x12\xf4\xd3\x76\xe0\x01\x26\x46\x65\xe0\xf1\xd4\xb5\x02\xfb\ +\xfd\x5e\x04\x16\x01\xd9\xfe\xd7\xb3\x58\x10\x01\x5c\x01\x08\xfc\ +\x94\x10\x48\x79\x99\xd2\x00\x00\x01\x00\xc9\xff\x93\x07\x24\x04\ +\x70\x00\x18\x00\x00\x01\x11\x21\x11\x33\x11\x21\x11\x23\x11\x23\ +\x2e\x04\x27\x11\x23\x11\x37\x16\x00\x1e\x01\x05\x00\x01\x44\xe0\ +\xfe\xda\xb8\x46\x65\xe0\xf1\xd4\xb5\x32\x46\x46\xa2\x01\x12\xf4\ +\xd3\x01\x53\x01\x2a\xfe\x1e\xfe\xf8\x01\xe2\xfe\xd6\x10\x48\x79\ +\x99\xd2\x74\xfd\x5e\x04\x16\x01\xd9\xfe\xd7\xb3\x58\x00\x00\x00\ +\x02\x00\xc9\x00\x59\x04\x7d\x04\x6f\x00\x07\x00\x11\x00\x00\x13\ +\x35\x33\x35\x23\x11\x21\x11\x13\x11\x23\x11\x21\x11\x33\x11\x21\ +\x11\xc9\xe0\xe0\x01\x26\xb0\x46\x01\x44\xe0\xfe\xda\x01\xd9\xe4\ +\x46\x01\x08\xfd\xce\x01\x8e\xfc\xf2\x04\x16\xfe\x72\xfe\xf8\x01\ +\x8e\x00\x00\x00\x01\x00\xca\x00\x4b\x06\x27\x04\x70\x00\x16\x00\ +\x00\x01\x37\x16\x00\x1e\x01\x17\x11\x23\x11\x21\x11\x23\x2e\x04\ +\x27\x11\x21\x11\x33\x01\xaa\x46\xa2\x01\x12\xf4\xd3\x76\xe0\x01\ +\x26\x46\x65\xe0\xf1\xd4\xb5\x32\xfe\xda\xe0\x04\x6f\x01\xd9\xfe\ +\xd7\xb3\x58\x10\x01\x5c\x01\x08\xfc\x94\x10\x48\x79\x99\xd2\x74\ +\xfd\x50\x01\x08\x00\x00\x00\x00\x03\x00\xc9\x00\xf2\x04\x9f\x04\ +\x11\x00\x03\x00\x07\x00\x0f\x00\x00\x01\x17\x07\x27\x03\x17\x07\ +\x27\x05\x11\x33\x35\x23\x11\x21\x11\x03\xee\xb1\xb1\xb2\x43\xb2\ +\xb2\xb2\xfe\x82\xe0\xe0\x01\x26\x02\x56\xb2\xb2\xb2\x01\x9b\xb2\ +\xb2\xb2\xd2\x01\x08\x46\x01\x08\xfd\xaa\x00\x00\x01\x00\xc7\x01\ +\x46\x04\x37\x05\x20\x00\x1d\x00\x00\x01\x32\x36\x37\x36\x16\x07\ +\x0e\x03\x22\x24\x27\x11\x23\x11\x07\x06\x26\x3f\x01\x11\x33\x11\ +\x3e\x01\x33\x32\x04\x03\x6c\x0d\x28\x62\x05\x33\x05\x4b\x92\x42\ +\x34\x18\xfe\xf8\x1f\x55\x54\x05\x32\x04\x87\x55\x42\x33\x0e\x16\ +\x01\x28\x03\x42\x24\x62\x05\x39\x05\x4b\x9a\x48\x2e\xd5\x13\xfe\ +\x2a\x01\xae\x56\x05\x39\x05\x8a\x01\xbf\xfe\x9b\x47\x30\xf0\x00\ +\x01\x00\xc7\x01\x46\x03\xa5\x05\x20\x00\x16\x00\x00\x01\x11\x33\ +\x11\x3e\x01\x33\x32\x00\x15\x14\x06\x23\x22\x24\x27\x11\x23\x11\ +\x07\x06\x26\x37\x01\x4f\x55\x42\x33\x0e\x1b\x01\x63\xc0\x0e\x0c\ +\xfe\xf8\x1f\x55\x54\x05\x32\x04\x03\x61\x01\xbf\xfe\x9b\x47\x30\ +\xfe\xdc\x0e\x0f\xbd\xd5\x13\xfe\x2a\x01\xae\x56\x05\x39\x05\x00\ +\x00\x00\x14\x00\xf6\x00\x01\x00\x00\x00\x00\x00\x00\x00\x58\x00\ +\xb2\x00\x01\x00\x00\x00\x00\x00\x01\x00\x07\x01\x1b\x00\x01\x00\ +\x00\x00\x00\x00\x02\x00\x06\x01\x31\x00\x01\x00\x00\x00\x00\x00\ +\x03\x00\x1f\x01\x78\x00\x01\x00\x00\x00\x00\x00\x04\x00\x07\x01\ +\xa8\x00\x01\x00\x00\x00\x00\x00\x05\x00\x0c\x01\xca\x00\x01\x00\ +\x00\x00\x00\x00\x06\x00\x07\x01\xe7\x00\x01\x00\x00\x00\x00\x00\ +\x09\x00\x0a\x02\x05\x00\x01\x00\x00\x00\x00\x00\x0d\x11\x25\x24\ +\x5c\x00\x01\x00\x00\x00\x00\x00\x0e\x00\x1a\x35\xb8\x00\x03\x00\ +\x01\x04\x09\x00\x00\x00\xb0\x00\x00\x00\x03\x00\x01\x04\x09\x00\ +\x01\x00\x0e\x01\x0b\x00\x03\x00\x01\x04\x09\x00\x02\x00\x0c\x01\ +\x23\x00\x03\x00\x01\x04\x09\x00\x03\x00\x3e\x01\x38\x00\x03\x00\ +\x01\x04\x09\x00\x04\x00\x0e\x01\x98\x00\x03\x00\x01\x04\x09\x00\ +\x05\x00\x18\x01\xb0\x00\x03\x00\x01\x04\x09\x00\x06\x00\x0e\x01\ +\xd7\x00\x03\x00\x01\x04\x09\x00\x09\x00\x14\x01\xef\x00\x03\x00\ +\x01\x04\x09\x00\x0d\x22\x4a\x02\x10\x00\x03\x00\x01\x04\x09\x00\ +\x0e\x00\x34\x35\x82\x00\x43\x00\x72\x00\x65\x00\x61\x00\x74\x00\ +\x65\x00\x64\x00\x20\x00\x62\x00\x79\x00\x20\x00\x42\x00\x65\x00\ +\x6e\x00\x20\x00\x4c\x00\x61\x00\x65\x00\x6e\x00\x65\x00\x6e\x00\ +\x20\x00\x28\x00\x62\x00\x65\x00\x6e\x00\x6c\x00\x61\x00\x65\x00\ +\x6e\x00\x65\x00\x6e\x00\x40\x00\x67\x00\x6d\x00\x61\x00\x69\x00\ +\x6c\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x29\x00\x20\x00\x77\x00\ +\x69\x00\x74\x00\x68\x00\x20\x00\x46\x00\x6f\x00\x6e\x00\x74\x00\ +\x46\x00\x6f\x00\x72\x00\x67\x00\x65\x00\x20\x00\x31\x00\x2e\x00\ +\x30\x00\x20\x00\x28\x00\x68\x00\x74\x00\x74\x00\x70\x00\x3a\x00\ +\x2f\x00\x2f\x00\x66\x00\x6f\x00\x6e\x00\x74\x00\x66\x00\x6f\x00\ +\x72\x00\x67\x00\x65\x00\x2e\x00\x73\x00\x66\x00\x2e\x00\x6e\x00\ +\x65\x00\x74\x00\x29\x00\x00\x43\x72\x65\x61\x74\x65\x64\x20\x62\ +\x79\x20\x42\x65\x6e\x20\x4c\x61\x65\x6e\x65\x6e\x20\x28\x62\x65\ +\x6e\x6c\x61\x65\x6e\x65\x6e\x40\x67\x6d\x61\x69\x6c\x2e\x63\x6f\ +\x6d\x29\x20\x77\x69\x74\x68\x20\x46\x6f\x6e\x74\x46\x6f\x72\x67\ +\x65\x20\x31\x2e\x30\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x66\x6f\ +\x6e\x74\x66\x6f\x72\x67\x65\x2e\x73\x66\x2e\x6e\x65\x74\x29\x00\ +\x00\x45\x00\x75\x00\x74\x00\x65\x00\x72\x00\x70\x00\x65\x00\x00\ +\x45\x75\x74\x65\x72\x70\x65\x00\x00\x4d\x00\x65\x00\x64\x00\x69\ +\x00\x75\x00\x6d\x00\x00\x4d\x65\x64\x69\x75\x6d\x00\x00\x46\x00\ +\x6f\x00\x6e\x00\x74\x00\x46\x00\x6f\x00\x72\x00\x67\x00\x65\x00\ +\x20\x00\x3a\x00\x20\x00\x45\x00\x75\x00\x74\x00\x65\x00\x72\x00\ +\x70\x00\x65\x00\x20\x00\x3a\x00\x20\x00\x31\x00\x34\x00\x2d\x00\ +\x37\x00\x2d\x00\x32\x00\x30\x00\x30\x00\x38\x00\x00\x46\x6f\x6e\ +\x74\x46\x6f\x72\x67\x65\x20\x3a\x20\x45\x75\x74\x65\x72\x70\x65\ +\x20\x3a\x20\x31\x34\x2d\x37\x2d\x32\x30\x30\x38\x00\x00\x45\x00\ +\x75\x00\x74\x00\x65\x00\x72\x00\x70\x00\x65\x00\x00\x45\x75\x74\ +\x65\x72\x70\x65\x00\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\ +\x6f\x00\x6e\x00\x20\x00\x31\x00\x2e\x00\x31\x00\x20\x00\x00\x56\ +\x65\x72\x73\x69\x6f\x6e\x20\x31\x2e\x31\x20\x00\x00\x45\x00\x75\ +\x00\x74\x00\x65\x00\x72\x00\x70\x00\x65\x00\x00\x45\x75\x74\x65\ +\x72\x70\x65\x00\x00\x42\x00\x65\x00\x6e\x00\x20\x00\x4c\x00\x61\ +\x00\x65\x00\x6e\x00\x65\x00\x6e\x00\x00\x42\x65\x6e\x20\x4c\x61\ +\x65\x6e\x65\x6e\x00\x00\x43\x00\x6f\x00\x70\x00\x79\x00\x72\x00\ +\x69\x00\x67\x00\x68\x00\x74\x00\x20\x00\x28\x00\x63\x00\x29\x00\ +\x20\x00\x32\x00\x30\x00\x30\x00\x38\x00\x2c\x00\x20\x00\x42\x00\ +\x65\x00\x6e\x00\x20\x00\x4c\x00\x61\x00\x65\x00\x6e\x00\x65\x00\ +\x6e\x00\x20\x00\x28\x00\x62\x00\x65\x00\x6e\x00\x6c\x00\x61\x00\ +\x65\x00\x6e\x00\x65\x00\x6e\x00\x40\x00\x67\x00\x6d\x00\x61\x00\ +\x69\x00\x6c\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x29\x00\x2c\x00\ +\x0a\x00\x77\x00\x69\x00\x74\x00\x68\x00\x20\x00\x52\x00\x65\x00\ +\x73\x00\x65\x00\x72\x00\x76\x00\x65\x00\x64\x00\x20\x00\x46\x00\ +\x6f\x00\x6e\x00\x74\x00\x20\x00\x4e\x00\x61\x00\x6d\x00\x65\x00\ +\x20\x00\x45\x00\x75\x00\x74\x00\x65\x00\x72\x00\x70\x00\x65\x00\ +\x2e\x00\x0a\x00\x0a\x00\x54\x00\x68\x00\x69\x00\x73\x00\x20\x00\ +\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x53\x00\x6f\x00\x66\x00\ +\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\x20\x00\x69\x00\x73\x00\ +\x20\x00\x6c\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x73\x00\x65\x00\ +\x64\x00\x20\x00\x75\x00\x6e\x00\x64\x00\x65\x00\x72\x00\x20\x00\ +\x74\x00\x68\x00\x65\x00\x20\x00\x53\x00\x49\x00\x4c\x00\x20\x00\ +\x4f\x00\x70\x00\x65\x00\x6e\x00\x20\x00\x46\x00\x6f\x00\x6e\x00\ +\x74\x00\x20\x00\x4c\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x73\x00\ +\x65\x00\x2c\x00\x20\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\ +\x6f\x00\x6e\x00\x20\x00\x31\x00\x2e\x00\x31\x00\x2e\x00\x0a\x00\ +\x54\x00\x68\x00\x69\x00\x73\x00\x20\x00\x6c\x00\x69\x00\x63\x00\ +\x65\x00\x6e\x00\x73\x00\x65\x00\x20\x00\x69\x00\x73\x00\x20\x00\ +\x63\x00\x6f\x00\x70\x00\x69\x00\x65\x00\x64\x00\x20\x00\x62\x00\ +\x65\x00\x6c\x00\x6f\x00\x77\x00\x2c\x00\x20\x00\x61\x00\x6e\x00\ +\x64\x00\x20\x00\x69\x00\x73\x00\x20\x00\x61\x00\x6c\x00\x73\x00\ +\x6f\x00\x20\x00\x61\x00\x76\x00\x61\x00\x69\x00\x6c\x00\x61\x00\ +\x62\x00\x6c\x00\x65\x00\x20\x00\x77\x00\x69\x00\x74\x00\x68\x00\ +\x20\x00\x61\x00\x20\x00\x46\x00\x41\x00\x51\x00\x20\x00\x61\x00\ +\x74\x00\x3a\x00\x0a\x00\x68\x00\x74\x00\x74\x00\x70\x00\x3a\x00\ +\x2f\x00\x2f\x00\x73\x00\x63\x00\x72\x00\x69\x00\x70\x00\x74\x00\ +\x73\x00\x2e\x00\x73\x00\x69\x00\x6c\x00\x2e\x00\x6f\x00\x72\x00\ +\x67\x00\x2f\x00\x4f\x00\x46\x00\x4c\x00\x0a\x00\x0a\x00\x0a\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x0a\x00\x53\x00\x49\x00\x4c\x00\x20\x00\ +\x4f\x00\x50\x00\x45\x00\x4e\x00\x20\x00\x46\x00\x4f\x00\x4e\x00\ +\x54\x00\x20\x00\x4c\x00\x49\x00\x43\x00\x45\x00\x4e\x00\x53\x00\ +\x45\x00\x20\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\x6f\x00\ +\x6e\x00\x20\x00\x31\x00\x2e\x00\x31\x00\x20\x00\x2d\x00\x20\x00\ +\x32\x00\x36\x00\x20\x00\x46\x00\x65\x00\x62\x00\x72\x00\x75\x00\ +\x61\x00\x72\x00\x79\x00\x20\x00\x32\x00\x30\x00\x30\x00\x37\x00\ +\x0a\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\ +\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x0a\x00\x0a\x00\x50\x00\x52\x00\ +\x45\x00\x41\x00\x4d\x00\x42\x00\x4c\x00\x45\x00\x0a\x00\x54\x00\ +\x68\x00\x65\x00\x20\x00\x67\x00\x6f\x00\x61\x00\x6c\x00\x73\x00\ +\x20\x00\x6f\x00\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\ +\x4f\x00\x70\x00\x65\x00\x6e\x00\x20\x00\x46\x00\x6f\x00\x6e\x00\ +\x74\x00\x20\x00\x4c\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x73\x00\ +\x65\x00\x20\x00\x28\x00\x4f\x00\x46\x00\x4c\x00\x29\x00\x20\x00\ +\x61\x00\x72\x00\x65\x00\x20\x00\x74\x00\x6f\x00\x20\x00\x73\x00\ +\x74\x00\x69\x00\x6d\x00\x75\x00\x6c\x00\x61\x00\x74\x00\x65\x00\ +\x20\x00\x77\x00\x6f\x00\x72\x00\x6c\x00\x64\x00\x77\x00\x69\x00\ +\x64\x00\x65\x00\x0a\x00\x64\x00\x65\x00\x76\x00\x65\x00\x6c\x00\ +\x6f\x00\x70\x00\x6d\x00\x65\x00\x6e\x00\x74\x00\x20\x00\x6f\x00\ +\x66\x00\x20\x00\x63\x00\x6f\x00\x6c\x00\x6c\x00\x61\x00\x62\x00\ +\x6f\x00\x72\x00\x61\x00\x74\x00\x69\x00\x76\x00\x65\x00\x20\x00\ +\x66\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x70\x00\x72\x00\x6f\x00\ +\x6a\x00\x65\x00\x63\x00\x74\x00\x73\x00\x2c\x00\x20\x00\x74\x00\ +\x6f\x00\x20\x00\x73\x00\x75\x00\x70\x00\x70\x00\x6f\x00\x72\x00\ +\x74\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x66\x00\x6f\x00\ +\x6e\x00\x74\x00\x20\x00\x63\x00\x72\x00\x65\x00\x61\x00\x74\x00\ +\x69\x00\x6f\x00\x6e\x00\x0a\x00\x65\x00\x66\x00\x66\x00\x6f\x00\ +\x72\x00\x74\x00\x73\x00\x20\x00\x6f\x00\x66\x00\x20\x00\x61\x00\ +\x63\x00\x61\x00\x64\x00\x65\x00\x6d\x00\x69\x00\x63\x00\x20\x00\ +\x61\x00\x6e\x00\x64\x00\x20\x00\x6c\x00\x69\x00\x6e\x00\x67\x00\ +\x75\x00\x69\x00\x73\x00\x74\x00\x69\x00\x63\x00\x20\x00\x63\x00\ +\x6f\x00\x6d\x00\x6d\x00\x75\x00\x6e\x00\x69\x00\x74\x00\x69\x00\ +\x65\x00\x73\x00\x2c\x00\x20\x00\x61\x00\x6e\x00\x64\x00\x20\x00\ +\x74\x00\x6f\x00\x20\x00\x70\x00\x72\x00\x6f\x00\x76\x00\x69\x00\ +\x64\x00\x65\x00\x20\x00\x61\x00\x20\x00\x66\x00\x72\x00\x65\x00\ +\x65\x00\x20\x00\x61\x00\x6e\x00\x64\x00\x0a\x00\x6f\x00\x70\x00\ +\x65\x00\x6e\x00\x20\x00\x66\x00\x72\x00\x61\x00\x6d\x00\x65\x00\ +\x77\x00\x6f\x00\x72\x00\x6b\x00\x20\x00\x69\x00\x6e\x00\x20\x00\ +\x77\x00\x68\x00\x69\x00\x63\x00\x68\x00\x20\x00\x66\x00\x6f\x00\ +\x6e\x00\x74\x00\x73\x00\x20\x00\x6d\x00\x61\x00\x79\x00\x20\x00\ +\x62\x00\x65\x00\x20\x00\x73\x00\x68\x00\x61\x00\x72\x00\x65\x00\ +\x64\x00\x20\x00\x61\x00\x6e\x00\x64\x00\x20\x00\x69\x00\x6d\x00\ +\x70\x00\x72\x00\x6f\x00\x76\x00\x65\x00\x64\x00\x20\x00\x69\x00\ +\x6e\x00\x20\x00\x70\x00\x61\x00\x72\x00\x74\x00\x6e\x00\x65\x00\ +\x72\x00\x73\x00\x68\x00\x69\x00\x70\x00\x0a\x00\x77\x00\x69\x00\ +\x74\x00\x68\x00\x20\x00\x6f\x00\x74\x00\x68\x00\x65\x00\x72\x00\ +\x73\x00\x2e\x00\x0a\x00\x0a\x00\x54\x00\x68\x00\x65\x00\x20\x00\ +\x4f\x00\x46\x00\x4c\x00\x20\x00\x61\x00\x6c\x00\x6c\x00\x6f\x00\ +\x77\x00\x73\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x6c\x00\ +\x69\x00\x63\x00\x65\x00\x6e\x00\x73\x00\x65\x00\x64\x00\x20\x00\ +\x66\x00\x6f\x00\x6e\x00\x74\x00\x73\x00\x20\x00\x74\x00\x6f\x00\ +\x20\x00\x62\x00\x65\x00\x20\x00\x75\x00\x73\x00\x65\x00\x64\x00\ +\x2c\x00\x20\x00\x73\x00\x74\x00\x75\x00\x64\x00\x69\x00\x65\x00\ +\x64\x00\x2c\x00\x20\x00\x6d\x00\x6f\x00\x64\x00\x69\x00\x66\x00\ +\x69\x00\x65\x00\x64\x00\x20\x00\x61\x00\x6e\x00\x64\x00\x0a\x00\ +\x72\x00\x65\x00\x64\x00\x69\x00\x73\x00\x74\x00\x72\x00\x69\x00\ +\x62\x00\x75\x00\x74\x00\x65\x00\x64\x00\x20\x00\x66\x00\x72\x00\ +\x65\x00\x65\x00\x6c\x00\x79\x00\x20\x00\x61\x00\x73\x00\x20\x00\ +\x6c\x00\x6f\x00\x6e\x00\x67\x00\x20\x00\x61\x00\x73\x00\x20\x00\ +\x74\x00\x68\x00\x65\x00\x79\x00\x20\x00\x61\x00\x72\x00\x65\x00\ +\x20\x00\x6e\x00\x6f\x00\x74\x00\x20\x00\x73\x00\x6f\x00\x6c\x00\ +\x64\x00\x20\x00\x62\x00\x79\x00\x20\x00\x74\x00\x68\x00\x65\x00\ +\x6d\x00\x73\x00\x65\x00\x6c\x00\x76\x00\x65\x00\x73\x00\x2e\x00\ +\x20\x00\x54\x00\x68\x00\x65\x00\x0a\x00\x66\x00\x6f\x00\x6e\x00\ +\x74\x00\x73\x00\x2c\x00\x20\x00\x69\x00\x6e\x00\x63\x00\x6c\x00\ +\x75\x00\x64\x00\x69\x00\x6e\x00\x67\x00\x20\x00\x61\x00\x6e\x00\ +\x79\x00\x20\x00\x64\x00\x65\x00\x72\x00\x69\x00\x76\x00\x61\x00\ +\x74\x00\x69\x00\x76\x00\x65\x00\x20\x00\x77\x00\x6f\x00\x72\x00\ +\x6b\x00\x73\x00\x2c\x00\x20\x00\x63\x00\x61\x00\x6e\x00\x20\x00\ +\x62\x00\x65\x00\x20\x00\x62\x00\x75\x00\x6e\x00\x64\x00\x6c\x00\ +\x65\x00\x64\x00\x2c\x00\x20\x00\x65\x00\x6d\x00\x62\x00\x65\x00\ +\x64\x00\x64\x00\x65\x00\x64\x00\x2c\x00\x20\x00\x0a\x00\x72\x00\ +\x65\x00\x64\x00\x69\x00\x73\x00\x74\x00\x72\x00\x69\x00\x62\x00\ +\x75\x00\x74\x00\x65\x00\x64\x00\x20\x00\x61\x00\x6e\x00\x64\x00\ +\x2f\x00\x6f\x00\x72\x00\x20\x00\x73\x00\x6f\x00\x6c\x00\x64\x00\ +\x20\x00\x77\x00\x69\x00\x74\x00\x68\x00\x20\x00\x61\x00\x6e\x00\ +\x79\x00\x20\x00\x73\x00\x6f\x00\x66\x00\x74\x00\x77\x00\x61\x00\ +\x72\x00\x65\x00\x20\x00\x70\x00\x72\x00\x6f\x00\x76\x00\x69\x00\ +\x64\x00\x65\x00\x64\x00\x20\x00\x74\x00\x68\x00\x61\x00\x74\x00\ +\x20\x00\x61\x00\x6e\x00\x79\x00\x20\x00\x72\x00\x65\x00\x73\x00\ +\x65\x00\x72\x00\x76\x00\x65\x00\x64\x00\x0a\x00\x6e\x00\x61\x00\ +\x6d\x00\x65\x00\x73\x00\x20\x00\x61\x00\x72\x00\x65\x00\x20\x00\ +\x6e\x00\x6f\x00\x74\x00\x20\x00\x75\x00\x73\x00\x65\x00\x64\x00\ +\x20\x00\x62\x00\x79\x00\x20\x00\x64\x00\x65\x00\x72\x00\x69\x00\ +\x76\x00\x61\x00\x74\x00\x69\x00\x76\x00\x65\x00\x20\x00\x77\x00\ +\x6f\x00\x72\x00\x6b\x00\x73\x00\x2e\x00\x20\x00\x54\x00\x68\x00\ +\x65\x00\x20\x00\x66\x00\x6f\x00\x6e\x00\x74\x00\x73\x00\x20\x00\ +\x61\x00\x6e\x00\x64\x00\x20\x00\x64\x00\x65\x00\x72\x00\x69\x00\ +\x76\x00\x61\x00\x74\x00\x69\x00\x76\x00\x65\x00\x73\x00\x2c\x00\ +\x0a\x00\x68\x00\x6f\x00\x77\x00\x65\x00\x76\x00\x65\x00\x72\x00\ +\x2c\x00\x20\x00\x63\x00\x61\x00\x6e\x00\x6e\x00\x6f\x00\x74\x00\ +\x20\x00\x62\x00\x65\x00\x20\x00\x72\x00\x65\x00\x6c\x00\x65\x00\ +\x61\x00\x73\x00\x65\x00\x64\x00\x20\x00\x75\x00\x6e\x00\x64\x00\ +\x65\x00\x72\x00\x20\x00\x61\x00\x6e\x00\x79\x00\x20\x00\x6f\x00\ +\x74\x00\x68\x00\x65\x00\x72\x00\x20\x00\x74\x00\x79\x00\x70\x00\ +\x65\x00\x20\x00\x6f\x00\x66\x00\x20\x00\x6c\x00\x69\x00\x63\x00\ +\x65\x00\x6e\x00\x73\x00\x65\x00\x2e\x00\x20\x00\x54\x00\x68\x00\ +\x65\x00\x0a\x00\x72\x00\x65\x00\x71\x00\x75\x00\x69\x00\x72\x00\ +\x65\x00\x6d\x00\x65\x00\x6e\x00\x74\x00\x20\x00\x66\x00\x6f\x00\ +\x72\x00\x20\x00\x66\x00\x6f\x00\x6e\x00\x74\x00\x73\x00\x20\x00\ +\x74\x00\x6f\x00\x20\x00\x72\x00\x65\x00\x6d\x00\x61\x00\x69\x00\ +\x6e\x00\x20\x00\x75\x00\x6e\x00\x64\x00\x65\x00\x72\x00\x20\x00\ +\x74\x00\x68\x00\x69\x00\x73\x00\x20\x00\x6c\x00\x69\x00\x63\x00\ +\x65\x00\x6e\x00\x73\x00\x65\x00\x20\x00\x64\x00\x6f\x00\x65\x00\ +\x73\x00\x20\x00\x6e\x00\x6f\x00\x74\x00\x20\x00\x61\x00\x70\x00\ +\x70\x00\x6c\x00\x79\x00\x0a\x00\x74\x00\x6f\x00\x20\x00\x61\x00\ +\x6e\x00\x79\x00\x20\x00\x64\x00\x6f\x00\x63\x00\x75\x00\x6d\x00\ +\x65\x00\x6e\x00\x74\x00\x20\x00\x63\x00\x72\x00\x65\x00\x61\x00\ +\x74\x00\x65\x00\x64\x00\x20\x00\x75\x00\x73\x00\x69\x00\x6e\x00\ +\x67\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x66\x00\x6f\x00\ +\x6e\x00\x74\x00\x73\x00\x20\x00\x6f\x00\x72\x00\x20\x00\x74\x00\ +\x68\x00\x65\x00\x69\x00\x72\x00\x20\x00\x64\x00\x65\x00\x72\x00\ +\x69\x00\x76\x00\x61\x00\x74\x00\x69\x00\x76\x00\x65\x00\x73\x00\ +\x2e\x00\x0a\x00\x0a\x00\x44\x00\x45\x00\x46\x00\x49\x00\x4e\x00\ +\x49\x00\x54\x00\x49\x00\x4f\x00\x4e\x00\x53\x00\x0a\x00\x22\x00\ +\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x53\x00\x6f\x00\x66\x00\ +\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\x22\x00\x20\x00\x72\x00\ +\x65\x00\x66\x00\x65\x00\x72\x00\x73\x00\x20\x00\x74\x00\x6f\x00\ +\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x73\x00\x65\x00\x74\x00\ +\x20\x00\x6f\x00\x66\x00\x20\x00\x66\x00\x69\x00\x6c\x00\x65\x00\ +\x73\x00\x20\x00\x72\x00\x65\x00\x6c\x00\x65\x00\x61\x00\x73\x00\ +\x65\x00\x64\x00\x20\x00\x62\x00\x79\x00\x20\x00\x74\x00\x68\x00\ +\x65\x00\x20\x00\x43\x00\x6f\x00\x70\x00\x79\x00\x72\x00\x69\x00\ +\x67\x00\x68\x00\x74\x00\x0a\x00\x48\x00\x6f\x00\x6c\x00\x64\x00\ +\x65\x00\x72\x00\x28\x00\x73\x00\x29\x00\x20\x00\x75\x00\x6e\x00\ +\x64\x00\x65\x00\x72\x00\x20\x00\x74\x00\x68\x00\x69\x00\x73\x00\ +\x20\x00\x6c\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x73\x00\x65\x00\ +\x20\x00\x61\x00\x6e\x00\x64\x00\x20\x00\x63\x00\x6c\x00\x65\x00\ +\x61\x00\x72\x00\x6c\x00\x79\x00\x20\x00\x6d\x00\x61\x00\x72\x00\ +\x6b\x00\x65\x00\x64\x00\x20\x00\x61\x00\x73\x00\x20\x00\x73\x00\ +\x75\x00\x63\x00\x68\x00\x2e\x00\x20\x00\x54\x00\x68\x00\x69\x00\ +\x73\x00\x20\x00\x6d\x00\x61\x00\x79\x00\x0a\x00\x69\x00\x6e\x00\ +\x63\x00\x6c\x00\x75\x00\x64\x00\x65\x00\x20\x00\x73\x00\x6f\x00\ +\x75\x00\x72\x00\x63\x00\x65\x00\x20\x00\x66\x00\x69\x00\x6c\x00\ +\x65\x00\x73\x00\x2c\x00\x20\x00\x62\x00\x75\x00\x69\x00\x6c\x00\ +\x64\x00\x20\x00\x73\x00\x63\x00\x72\x00\x69\x00\x70\x00\x74\x00\ +\x73\x00\x20\x00\x61\x00\x6e\x00\x64\x00\x20\x00\x64\x00\x6f\x00\ +\x63\x00\x75\x00\x6d\x00\x65\x00\x6e\x00\x74\x00\x61\x00\x74\x00\ +\x69\x00\x6f\x00\x6e\x00\x2e\x00\x0a\x00\x0a\x00\x22\x00\x52\x00\ +\x65\x00\x73\x00\x65\x00\x72\x00\x76\x00\x65\x00\x64\x00\x20\x00\ +\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x4e\x00\x61\x00\x6d\x00\ +\x65\x00\x22\x00\x20\x00\x72\x00\x65\x00\x66\x00\x65\x00\x72\x00\ +\x73\x00\x20\x00\x74\x00\x6f\x00\x20\x00\x61\x00\x6e\x00\x79\x00\ +\x20\x00\x6e\x00\x61\x00\x6d\x00\x65\x00\x73\x00\x20\x00\x73\x00\ +\x70\x00\x65\x00\x63\x00\x69\x00\x66\x00\x69\x00\x65\x00\x64\x00\ +\x20\x00\x61\x00\x73\x00\x20\x00\x73\x00\x75\x00\x63\x00\x68\x00\ +\x20\x00\x61\x00\x66\x00\x74\x00\x65\x00\x72\x00\x20\x00\x74\x00\ +\x68\x00\x65\x00\x0a\x00\x63\x00\x6f\x00\x70\x00\x79\x00\x72\x00\ +\x69\x00\x67\x00\x68\x00\x74\x00\x20\x00\x73\x00\x74\x00\x61\x00\ +\x74\x00\x65\x00\x6d\x00\x65\x00\x6e\x00\x74\x00\x28\x00\x73\x00\ +\x29\x00\x2e\x00\x0a\x00\x0a\x00\x22\x00\x4f\x00\x72\x00\x69\x00\ +\x67\x00\x69\x00\x6e\x00\x61\x00\x6c\x00\x20\x00\x56\x00\x65\x00\ +\x72\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x22\x00\x20\x00\x72\x00\ +\x65\x00\x66\x00\x65\x00\x72\x00\x73\x00\x20\x00\x74\x00\x6f\x00\ +\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x63\x00\x6f\x00\x6c\x00\ +\x6c\x00\x65\x00\x63\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x20\x00\ +\x6f\x00\x66\x00\x20\x00\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\ +\x53\x00\x6f\x00\x66\x00\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\ +\x20\x00\x63\x00\x6f\x00\x6d\x00\x70\x00\x6f\x00\x6e\x00\x65\x00\ +\x6e\x00\x74\x00\x73\x00\x20\x00\x61\x00\x73\x00\x0a\x00\x64\x00\ +\x69\x00\x73\x00\x74\x00\x72\x00\x69\x00\x62\x00\x75\x00\x74\x00\ +\x65\x00\x64\x00\x20\x00\x62\x00\x79\x00\x20\x00\x74\x00\x68\x00\ +\x65\x00\x20\x00\x43\x00\x6f\x00\x70\x00\x79\x00\x72\x00\x69\x00\ +\x67\x00\x68\x00\x74\x00\x20\x00\x48\x00\x6f\x00\x6c\x00\x64\x00\ +\x65\x00\x72\x00\x28\x00\x73\x00\x29\x00\x2e\x00\x0a\x00\x0a\x00\ +\x22\x00\x4d\x00\x6f\x00\x64\x00\x69\x00\x66\x00\x69\x00\x65\x00\ +\x64\x00\x20\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\x6f\x00\ +\x6e\x00\x22\x00\x20\x00\x72\x00\x65\x00\x66\x00\x65\x00\x72\x00\ +\x73\x00\x20\x00\x74\x00\x6f\x00\x20\x00\x61\x00\x6e\x00\x79\x00\ +\x20\x00\x64\x00\x65\x00\x72\x00\x69\x00\x76\x00\x61\x00\x74\x00\ +\x69\x00\x76\x00\x65\x00\x20\x00\x6d\x00\x61\x00\x64\x00\x65\x00\ +\x20\x00\x62\x00\x79\x00\x20\x00\x61\x00\x64\x00\x64\x00\x69\x00\ +\x6e\x00\x67\x00\x20\x00\x74\x00\x6f\x00\x2c\x00\x20\x00\x64\x00\ +\x65\x00\x6c\x00\x65\x00\x74\x00\x69\x00\x6e\x00\x67\x00\x2c\x00\ +\x0a\x00\x6f\x00\x72\x00\x20\x00\x73\x00\x75\x00\x62\x00\x73\x00\ +\x74\x00\x69\x00\x74\x00\x75\x00\x74\x00\x69\x00\x6e\x00\x67\x00\ +\x20\x00\x2d\x00\x2d\x00\x20\x00\x69\x00\x6e\x00\x20\x00\x70\x00\ +\x61\x00\x72\x00\x74\x00\x20\x00\x6f\x00\x72\x00\x20\x00\x69\x00\ +\x6e\x00\x20\x00\x77\x00\x68\x00\x6f\x00\x6c\x00\x65\x00\x20\x00\ +\x2d\x00\x2d\x00\x20\x00\x61\x00\x6e\x00\x79\x00\x20\x00\x6f\x00\ +\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x63\x00\x6f\x00\ +\x6d\x00\x70\x00\x6f\x00\x6e\x00\x65\x00\x6e\x00\x74\x00\x73\x00\ +\x20\x00\x6f\x00\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\x0a\x00\ +\x4f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\x61\x00\x6c\x00\ +\x20\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\ +\x2c\x00\x20\x00\x62\x00\x79\x00\x20\x00\x63\x00\x68\x00\x61\x00\ +\x6e\x00\x67\x00\x69\x00\x6e\x00\x67\x00\x20\x00\x66\x00\x6f\x00\ +\x72\x00\x6d\x00\x61\x00\x74\x00\x73\x00\x20\x00\x6f\x00\x72\x00\ +\x20\x00\x62\x00\x79\x00\x20\x00\x70\x00\x6f\x00\x72\x00\x74\x00\ +\x69\x00\x6e\x00\x67\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\ +\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x53\x00\x6f\x00\x66\x00\ +\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\x20\x00\x74\x00\x6f\x00\ +\x20\x00\x61\x00\x0a\x00\x6e\x00\x65\x00\x77\x00\x20\x00\x65\x00\ +\x6e\x00\x76\x00\x69\x00\x72\x00\x6f\x00\x6e\x00\x6d\x00\x65\x00\ +\x6e\x00\x74\x00\x2e\x00\x0a\x00\x0a\x00\x22\x00\x41\x00\x75\x00\ +\x74\x00\x68\x00\x6f\x00\x72\x00\x22\x00\x20\x00\x72\x00\x65\x00\ +\x66\x00\x65\x00\x72\x00\x73\x00\x20\x00\x74\x00\x6f\x00\x20\x00\ +\x61\x00\x6e\x00\x79\x00\x20\x00\x64\x00\x65\x00\x73\x00\x69\x00\ +\x67\x00\x6e\x00\x65\x00\x72\x00\x2c\x00\x20\x00\x65\x00\x6e\x00\ +\x67\x00\x69\x00\x6e\x00\x65\x00\x65\x00\x72\x00\x2c\x00\x20\x00\ +\x70\x00\x72\x00\x6f\x00\x67\x00\x72\x00\x61\x00\x6d\x00\x6d\x00\ +\x65\x00\x72\x00\x2c\x00\x20\x00\x74\x00\x65\x00\x63\x00\x68\x00\ +\x6e\x00\x69\x00\x63\x00\x61\x00\x6c\x00\x0a\x00\x77\x00\x72\x00\ +\x69\x00\x74\x00\x65\x00\x72\x00\x20\x00\x6f\x00\x72\x00\x20\x00\ +\x6f\x00\x74\x00\x68\x00\x65\x00\x72\x00\x20\x00\x70\x00\x65\x00\ +\x72\x00\x73\x00\x6f\x00\x6e\x00\x20\x00\x77\x00\x68\x00\x6f\x00\ +\x20\x00\x63\x00\x6f\x00\x6e\x00\x74\x00\x72\x00\x69\x00\x62\x00\ +\x75\x00\x74\x00\x65\x00\x64\x00\x20\x00\x74\x00\x6f\x00\x20\x00\ +\x74\x00\x68\x00\x65\x00\x20\x00\x46\x00\x6f\x00\x6e\x00\x74\x00\ +\x20\x00\x53\x00\x6f\x00\x66\x00\x74\x00\x77\x00\x61\x00\x72\x00\ +\x65\x00\x2e\x00\x0a\x00\x0a\x00\x50\x00\x45\x00\x52\x00\x4d\x00\ +\x49\x00\x53\x00\x53\x00\x49\x00\x4f\x00\x4e\x00\x20\x00\x26\x00\ +\x20\x00\x43\x00\x4f\x00\x4e\x00\x44\x00\x49\x00\x54\x00\x49\x00\ +\x4f\x00\x4e\x00\x53\x00\x0a\x00\x50\x00\x65\x00\x72\x00\x6d\x00\ +\x69\x00\x73\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x20\x00\x69\x00\ +\x73\x00\x20\x00\x68\x00\x65\x00\x72\x00\x65\x00\x62\x00\x79\x00\ +\x20\x00\x67\x00\x72\x00\x61\x00\x6e\x00\x74\x00\x65\x00\x64\x00\ +\x2c\x00\x20\x00\x66\x00\x72\x00\x65\x00\x65\x00\x20\x00\x6f\x00\ +\x66\x00\x20\x00\x63\x00\x68\x00\x61\x00\x72\x00\x67\x00\x65\x00\ +\x2c\x00\x20\x00\x74\x00\x6f\x00\x20\x00\x61\x00\x6e\x00\x79\x00\ +\x20\x00\x70\x00\x65\x00\x72\x00\x73\x00\x6f\x00\x6e\x00\x20\x00\ +\x6f\x00\x62\x00\x74\x00\x61\x00\x69\x00\x6e\x00\x69\x00\x6e\x00\ +\x67\x00\x0a\x00\x61\x00\x20\x00\x63\x00\x6f\x00\x70\x00\x79\x00\ +\x20\x00\x6f\x00\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\ +\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x53\x00\x6f\x00\x66\x00\ +\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\x2c\x00\x20\x00\x74\x00\ +\x6f\x00\x20\x00\x75\x00\x73\x00\x65\x00\x2c\x00\x20\x00\x73\x00\ +\x74\x00\x75\x00\x64\x00\x79\x00\x2c\x00\x20\x00\x63\x00\x6f\x00\ +\x70\x00\x79\x00\x2c\x00\x20\x00\x6d\x00\x65\x00\x72\x00\x67\x00\ +\x65\x00\x2c\x00\x20\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x64\x00\ +\x2c\x00\x20\x00\x6d\x00\x6f\x00\x64\x00\x69\x00\x66\x00\x79\x00\ +\x2c\x00\x0a\x00\x72\x00\x65\x00\x64\x00\x69\x00\x73\x00\x74\x00\ +\x72\x00\x69\x00\x62\x00\x75\x00\x74\x00\x65\x00\x2c\x00\x20\x00\ +\x61\x00\x6e\x00\x64\x00\x20\x00\x73\x00\x65\x00\x6c\x00\x6c\x00\ +\x20\x00\x6d\x00\x6f\x00\x64\x00\x69\x00\x66\x00\x69\x00\x65\x00\ +\x64\x00\x20\x00\x61\x00\x6e\x00\x64\x00\x20\x00\x75\x00\x6e\x00\ +\x6d\x00\x6f\x00\x64\x00\x69\x00\x66\x00\x69\x00\x65\x00\x64\x00\ +\x20\x00\x63\x00\x6f\x00\x70\x00\x69\x00\x65\x00\x73\x00\x20\x00\ +\x6f\x00\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x46\x00\ +\x6f\x00\x6e\x00\x74\x00\x0a\x00\x53\x00\x6f\x00\x66\x00\x74\x00\ +\x77\x00\x61\x00\x72\x00\x65\x00\x2c\x00\x20\x00\x73\x00\x75\x00\ +\x62\x00\x6a\x00\x65\x00\x63\x00\x74\x00\x20\x00\x74\x00\x6f\x00\ +\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x66\x00\x6f\x00\x6c\x00\ +\x6c\x00\x6f\x00\x77\x00\x69\x00\x6e\x00\x67\x00\x20\x00\x63\x00\ +\x6f\x00\x6e\x00\x64\x00\x69\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\ +\x73\x00\x3a\x00\x0a\x00\x0a\x00\x31\x00\x29\x00\x20\x00\x4e\x00\ +\x65\x00\x69\x00\x74\x00\x68\x00\x65\x00\x72\x00\x20\x00\x74\x00\ +\x68\x00\x65\x00\x20\x00\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\ +\x53\x00\x6f\x00\x66\x00\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\ +\x20\x00\x6e\x00\x6f\x00\x72\x00\x20\x00\x61\x00\x6e\x00\x79\x00\ +\x20\x00\x6f\x00\x66\x00\x20\x00\x69\x00\x74\x00\x73\x00\x20\x00\ +\x69\x00\x6e\x00\x64\x00\x69\x00\x76\x00\x69\x00\x64\x00\x75\x00\ +\x61\x00\x6c\x00\x20\x00\x63\x00\x6f\x00\x6d\x00\x70\x00\x6f\x00\ +\x6e\x00\x65\x00\x6e\x00\x74\x00\x73\x00\x2c\x00\x0a\x00\x69\x00\ +\x6e\x00\x20\x00\x4f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\ +\x61\x00\x6c\x00\x20\x00\x6f\x00\x72\x00\x20\x00\x4d\x00\x6f\x00\ +\x64\x00\x69\x00\x66\x00\x69\x00\x65\x00\x64\x00\x20\x00\x56\x00\ +\x65\x00\x72\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x2c\x00\ +\x20\x00\x6d\x00\x61\x00\x79\x00\x20\x00\x62\x00\x65\x00\x20\x00\ +\x73\x00\x6f\x00\x6c\x00\x64\x00\x20\x00\x62\x00\x79\x00\x20\x00\ +\x69\x00\x74\x00\x73\x00\x65\x00\x6c\x00\x66\x00\x2e\x00\x0a\x00\ +\x0a\x00\x32\x00\x29\x00\x20\x00\x4f\x00\x72\x00\x69\x00\x67\x00\ +\x69\x00\x6e\x00\x61\x00\x6c\x00\x20\x00\x6f\x00\x72\x00\x20\x00\ +\x4d\x00\x6f\x00\x64\x00\x69\x00\x66\x00\x69\x00\x65\x00\x64\x00\ +\x20\x00\x56\x00\x65\x00\x72\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\ +\x73\x00\x20\x00\x6f\x00\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\ +\x20\x00\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x53\x00\x6f\x00\ +\x66\x00\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\x20\x00\x6d\x00\ +\x61\x00\x79\x00\x20\x00\x62\x00\x65\x00\x20\x00\x62\x00\x75\x00\ +\x6e\x00\x64\x00\x6c\x00\x65\x00\x64\x00\x2c\x00\x0a\x00\x72\x00\ +\x65\x00\x64\x00\x69\x00\x73\x00\x74\x00\x72\x00\x69\x00\x62\x00\ +\x75\x00\x74\x00\x65\x00\x64\x00\x20\x00\x61\x00\x6e\x00\x64\x00\ +\x2f\x00\x6f\x00\x72\x00\x20\x00\x73\x00\x6f\x00\x6c\x00\x64\x00\ +\x20\x00\x77\x00\x69\x00\x74\x00\x68\x00\x20\x00\x61\x00\x6e\x00\ +\x79\x00\x20\x00\x73\x00\x6f\x00\x66\x00\x74\x00\x77\x00\x61\x00\ +\x72\x00\x65\x00\x2c\x00\x20\x00\x70\x00\x72\x00\x6f\x00\x76\x00\ +\x69\x00\x64\x00\x65\x00\x64\x00\x20\x00\x74\x00\x68\x00\x61\x00\ +\x74\x00\x20\x00\x65\x00\x61\x00\x63\x00\x68\x00\x20\x00\x63\x00\ +\x6f\x00\x70\x00\x79\x00\x0a\x00\x63\x00\x6f\x00\x6e\x00\x74\x00\ +\x61\x00\x69\x00\x6e\x00\x73\x00\x20\x00\x74\x00\x68\x00\x65\x00\ +\x20\x00\x61\x00\x62\x00\x6f\x00\x76\x00\x65\x00\x20\x00\x63\x00\ +\x6f\x00\x70\x00\x79\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\ +\x20\x00\x6e\x00\x6f\x00\x74\x00\x69\x00\x63\x00\x65\x00\x20\x00\ +\x61\x00\x6e\x00\x64\x00\x20\x00\x74\x00\x68\x00\x69\x00\x73\x00\ +\x20\x00\x6c\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x73\x00\x65\x00\ +\x2e\x00\x20\x00\x54\x00\x68\x00\x65\x00\x73\x00\x65\x00\x20\x00\ +\x63\x00\x61\x00\x6e\x00\x20\x00\x62\x00\x65\x00\x0a\x00\x69\x00\ +\x6e\x00\x63\x00\x6c\x00\x75\x00\x64\x00\x65\x00\x64\x00\x20\x00\ +\x65\x00\x69\x00\x74\x00\x68\x00\x65\x00\x72\x00\x20\x00\x61\x00\ +\x73\x00\x20\x00\x73\x00\x74\x00\x61\x00\x6e\x00\x64\x00\x2d\x00\ +\x61\x00\x6c\x00\x6f\x00\x6e\x00\x65\x00\x20\x00\x74\x00\x65\x00\ +\x78\x00\x74\x00\x20\x00\x66\x00\x69\x00\x6c\x00\x65\x00\x73\x00\ +\x2c\x00\x20\x00\x68\x00\x75\x00\x6d\x00\x61\x00\x6e\x00\x2d\x00\ +\x72\x00\x65\x00\x61\x00\x64\x00\x61\x00\x62\x00\x6c\x00\x65\x00\ +\x20\x00\x68\x00\x65\x00\x61\x00\x64\x00\x65\x00\x72\x00\x73\x00\ +\x20\x00\x6f\x00\x72\x00\x0a\x00\x69\x00\x6e\x00\x20\x00\x74\x00\ +\x68\x00\x65\x00\x20\x00\x61\x00\x70\x00\x70\x00\x72\x00\x6f\x00\ +\x70\x00\x72\x00\x69\x00\x61\x00\x74\x00\x65\x00\x20\x00\x6d\x00\ +\x61\x00\x63\x00\x68\x00\x69\x00\x6e\x00\x65\x00\x2d\x00\x72\x00\ +\x65\x00\x61\x00\x64\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x20\x00\ +\x6d\x00\x65\x00\x74\x00\x61\x00\x64\x00\x61\x00\x74\x00\x61\x00\ +\x20\x00\x66\x00\x69\x00\x65\x00\x6c\x00\x64\x00\x73\x00\x20\x00\ +\x77\x00\x69\x00\x74\x00\x68\x00\x69\x00\x6e\x00\x20\x00\x74\x00\ +\x65\x00\x78\x00\x74\x00\x20\x00\x6f\x00\x72\x00\x0a\x00\x62\x00\ +\x69\x00\x6e\x00\x61\x00\x72\x00\x79\x00\x20\x00\x66\x00\x69\x00\ +\x6c\x00\x65\x00\x73\x00\x20\x00\x61\x00\x73\x00\x20\x00\x6c\x00\ +\x6f\x00\x6e\x00\x67\x00\x20\x00\x61\x00\x73\x00\x20\x00\x74\x00\ +\x68\x00\x6f\x00\x73\x00\x65\x00\x20\x00\x66\x00\x69\x00\x65\x00\ +\x6c\x00\x64\x00\x73\x00\x20\x00\x63\x00\x61\x00\x6e\x00\x20\x00\ +\x62\x00\x65\x00\x20\x00\x65\x00\x61\x00\x73\x00\x69\x00\x6c\x00\ +\x79\x00\x20\x00\x76\x00\x69\x00\x65\x00\x77\x00\x65\x00\x64\x00\ +\x20\x00\x62\x00\x79\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\ +\x75\x00\x73\x00\x65\x00\x72\x00\x2e\x00\x0a\x00\x0a\x00\x33\x00\ +\x29\x00\x20\x00\x4e\x00\x6f\x00\x20\x00\x4d\x00\x6f\x00\x64\x00\ +\x69\x00\x66\x00\x69\x00\x65\x00\x64\x00\x20\x00\x56\x00\x65\x00\ +\x72\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x20\x00\x6f\x00\x66\x00\ +\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x46\x00\x6f\x00\x6e\x00\ +\x74\x00\x20\x00\x53\x00\x6f\x00\x66\x00\x74\x00\x77\x00\x61\x00\ +\x72\x00\x65\x00\x20\x00\x6d\x00\x61\x00\x79\x00\x20\x00\x75\x00\ +\x73\x00\x65\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x52\x00\ +\x65\x00\x73\x00\x65\x00\x72\x00\x76\x00\x65\x00\x64\x00\x20\x00\ +\x46\x00\x6f\x00\x6e\x00\x74\x00\x0a\x00\x4e\x00\x61\x00\x6d\x00\ +\x65\x00\x28\x00\x73\x00\x29\x00\x20\x00\x75\x00\x6e\x00\x6c\x00\ +\x65\x00\x73\x00\x73\x00\x20\x00\x65\x00\x78\x00\x70\x00\x6c\x00\ +\x69\x00\x63\x00\x69\x00\x74\x00\x20\x00\x77\x00\x72\x00\x69\x00\ +\x74\x00\x74\x00\x65\x00\x6e\x00\x20\x00\x70\x00\x65\x00\x72\x00\ +\x6d\x00\x69\x00\x73\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x20\x00\ +\x69\x00\x73\x00\x20\x00\x67\x00\x72\x00\x61\x00\x6e\x00\x74\x00\ +\x65\x00\x64\x00\x20\x00\x62\x00\x79\x00\x20\x00\x74\x00\x68\x00\ +\x65\x00\x20\x00\x63\x00\x6f\x00\x72\x00\x72\x00\x65\x00\x73\x00\ +\x70\x00\x6f\x00\x6e\x00\x64\x00\x69\x00\x6e\x00\x67\x00\x0a\x00\ +\x43\x00\x6f\x00\x70\x00\x79\x00\x72\x00\x69\x00\x67\x00\x68\x00\ +\x74\x00\x20\x00\x48\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\ +\x2e\x00\x20\x00\x54\x00\x68\x00\x69\x00\x73\x00\x20\x00\x72\x00\ +\x65\x00\x73\x00\x74\x00\x72\x00\x69\x00\x63\x00\x74\x00\x69\x00\ +\x6f\x00\x6e\x00\x20\x00\x6f\x00\x6e\x00\x6c\x00\x79\x00\x20\x00\ +\x61\x00\x70\x00\x70\x00\x6c\x00\x69\x00\x65\x00\x73\x00\x20\x00\ +\x74\x00\x6f\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x70\x00\ +\x72\x00\x69\x00\x6d\x00\x61\x00\x72\x00\x79\x00\x20\x00\x66\x00\ +\x6f\x00\x6e\x00\x74\x00\x20\x00\x6e\x00\x61\x00\x6d\x00\x65\x00\ +\x20\x00\x61\x00\x73\x00\x0a\x00\x70\x00\x72\x00\x65\x00\x73\x00\ +\x65\x00\x6e\x00\x74\x00\x65\x00\x64\x00\x20\x00\x74\x00\x6f\x00\ +\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x75\x00\x73\x00\x65\x00\ +\x72\x00\x73\x00\x2e\x00\x0a\x00\x0a\x00\x34\x00\x29\x00\x20\x00\ +\x54\x00\x68\x00\x65\x00\x20\x00\x6e\x00\x61\x00\x6d\x00\x65\x00\ +\x28\x00\x73\x00\x29\x00\x20\x00\x6f\x00\x66\x00\x20\x00\x74\x00\ +\x68\x00\x65\x00\x20\x00\x43\x00\x6f\x00\x70\x00\x79\x00\x72\x00\ +\x69\x00\x67\x00\x68\x00\x74\x00\x20\x00\x48\x00\x6f\x00\x6c\x00\ +\x64\x00\x65\x00\x72\x00\x28\x00\x73\x00\x29\x00\x20\x00\x6f\x00\ +\x72\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x41\x00\x75\x00\ +\x74\x00\x68\x00\x6f\x00\x72\x00\x28\x00\x73\x00\x29\x00\x20\x00\ +\x6f\x00\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x46\x00\ +\x6f\x00\x6e\x00\x74\x00\x0a\x00\x53\x00\x6f\x00\x66\x00\x74\x00\ +\x77\x00\x61\x00\x72\x00\x65\x00\x20\x00\x73\x00\x68\x00\x61\x00\ +\x6c\x00\x6c\x00\x20\x00\x6e\x00\x6f\x00\x74\x00\x20\x00\x62\x00\ +\x65\x00\x20\x00\x75\x00\x73\x00\x65\x00\x64\x00\x20\x00\x74\x00\ +\x6f\x00\x20\x00\x70\x00\x72\x00\x6f\x00\x6d\x00\x6f\x00\x74\x00\ +\x65\x00\x2c\x00\x20\x00\x65\x00\x6e\x00\x64\x00\x6f\x00\x72\x00\ +\x73\x00\x65\x00\x20\x00\x6f\x00\x72\x00\x20\x00\x61\x00\x64\x00\ +\x76\x00\x65\x00\x72\x00\x74\x00\x69\x00\x73\x00\x65\x00\x20\x00\ +\x61\x00\x6e\x00\x79\x00\x0a\x00\x4d\x00\x6f\x00\x64\x00\x69\x00\ +\x66\x00\x69\x00\x65\x00\x64\x00\x20\x00\x56\x00\x65\x00\x72\x00\ +\x73\x00\x69\x00\x6f\x00\x6e\x00\x2c\x00\x20\x00\x65\x00\x78\x00\ +\x63\x00\x65\x00\x70\x00\x74\x00\x20\x00\x74\x00\x6f\x00\x20\x00\ +\x61\x00\x63\x00\x6b\x00\x6e\x00\x6f\x00\x77\x00\x6c\x00\x65\x00\ +\x64\x00\x67\x00\x65\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\ +\x63\x00\x6f\x00\x6e\x00\x74\x00\x72\x00\x69\x00\x62\x00\x75\x00\ +\x74\x00\x69\x00\x6f\x00\x6e\x00\x28\x00\x73\x00\x29\x00\x20\x00\ +\x6f\x00\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\x0a\x00\x43\x00\ +\x6f\x00\x70\x00\x79\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\ +\x20\x00\x48\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x28\x00\ +\x73\x00\x29\x00\x20\x00\x61\x00\x6e\x00\x64\x00\x20\x00\x74\x00\ +\x68\x00\x65\x00\x20\x00\x41\x00\x75\x00\x74\x00\x68\x00\x6f\x00\ +\x72\x00\x28\x00\x73\x00\x29\x00\x20\x00\x6f\x00\x72\x00\x20\x00\ +\x77\x00\x69\x00\x74\x00\x68\x00\x20\x00\x74\x00\x68\x00\x65\x00\ +\x69\x00\x72\x00\x20\x00\x65\x00\x78\x00\x70\x00\x6c\x00\x69\x00\ +\x63\x00\x69\x00\x74\x00\x20\x00\x77\x00\x72\x00\x69\x00\x74\x00\ +\x74\x00\x65\x00\x6e\x00\x0a\x00\x70\x00\x65\x00\x72\x00\x6d\x00\ +\x69\x00\x73\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x0a\x00\ +\x0a\x00\x35\x00\x29\x00\x20\x00\x54\x00\x68\x00\x65\x00\x20\x00\ +\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x53\x00\x6f\x00\x66\x00\ +\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\x2c\x00\x20\x00\x6d\x00\ +\x6f\x00\x64\x00\x69\x00\x66\x00\x69\x00\x65\x00\x64\x00\x20\x00\ +\x6f\x00\x72\x00\x20\x00\x75\x00\x6e\x00\x6d\x00\x6f\x00\x64\x00\ +\x69\x00\x66\x00\x69\x00\x65\x00\x64\x00\x2c\x00\x20\x00\x69\x00\ +\x6e\x00\x20\x00\x70\x00\x61\x00\x72\x00\x74\x00\x20\x00\x6f\x00\ +\x72\x00\x20\x00\x69\x00\x6e\x00\x20\x00\x77\x00\x68\x00\x6f\x00\ +\x6c\x00\x65\x00\x2c\x00\x0a\x00\x6d\x00\x75\x00\x73\x00\x74\x00\ +\x20\x00\x62\x00\x65\x00\x20\x00\x64\x00\x69\x00\x73\x00\x74\x00\ +\x72\x00\x69\x00\x62\x00\x75\x00\x74\x00\x65\x00\x64\x00\x20\x00\ +\x65\x00\x6e\x00\x74\x00\x69\x00\x72\x00\x65\x00\x6c\x00\x79\x00\ +\x20\x00\x75\x00\x6e\x00\x64\x00\x65\x00\x72\x00\x20\x00\x74\x00\ +\x68\x00\x69\x00\x73\x00\x20\x00\x6c\x00\x69\x00\x63\x00\x65\x00\ +\x6e\x00\x73\x00\x65\x00\x2c\x00\x20\x00\x61\x00\x6e\x00\x64\x00\ +\x20\x00\x6d\x00\x75\x00\x73\x00\x74\x00\x20\x00\x6e\x00\x6f\x00\ +\x74\x00\x20\x00\x62\x00\x65\x00\x0a\x00\x64\x00\x69\x00\x73\x00\ +\x74\x00\x72\x00\x69\x00\x62\x00\x75\x00\x74\x00\x65\x00\x64\x00\ +\x20\x00\x75\x00\x6e\x00\x64\x00\x65\x00\x72\x00\x20\x00\x61\x00\ +\x6e\x00\x79\x00\x20\x00\x6f\x00\x74\x00\x68\x00\x65\x00\x72\x00\ +\x20\x00\x6c\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x73\x00\x65\x00\ +\x2e\x00\x20\x00\x54\x00\x68\x00\x65\x00\x20\x00\x72\x00\x65\x00\ +\x71\x00\x75\x00\x69\x00\x72\x00\x65\x00\x6d\x00\x65\x00\x6e\x00\ +\x74\x00\x20\x00\x66\x00\x6f\x00\x72\x00\x20\x00\x66\x00\x6f\x00\ +\x6e\x00\x74\x00\x73\x00\x20\x00\x74\x00\x6f\x00\x0a\x00\x72\x00\ +\x65\x00\x6d\x00\x61\x00\x69\x00\x6e\x00\x20\x00\x75\x00\x6e\x00\ +\x64\x00\x65\x00\x72\x00\x20\x00\x74\x00\x68\x00\x69\x00\x73\x00\ +\x20\x00\x6c\x00\x69\x00\x63\x00\x65\x00\x6e\x00\x73\x00\x65\x00\ +\x20\x00\x64\x00\x6f\x00\x65\x00\x73\x00\x20\x00\x6e\x00\x6f\x00\ +\x74\x00\x20\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x79\x00\x20\x00\ +\x74\x00\x6f\x00\x20\x00\x61\x00\x6e\x00\x79\x00\x20\x00\x64\x00\ +\x6f\x00\x63\x00\x75\x00\x6d\x00\x65\x00\x6e\x00\x74\x00\x20\x00\ +\x63\x00\x72\x00\x65\x00\x61\x00\x74\x00\x65\x00\x64\x00\x0a\x00\ +\x75\x00\x73\x00\x69\x00\x6e\x00\x67\x00\x20\x00\x74\x00\x68\x00\ +\x65\x00\x20\x00\x46\x00\x6f\x00\x6e\x00\x74\x00\x20\x00\x53\x00\ +\x6f\x00\x66\x00\x74\x00\x77\x00\x61\x00\x72\x00\x65\x00\x2e\x00\ +\x0a\x00\x0a\x00\x54\x00\x45\x00\x52\x00\x4d\x00\x49\x00\x4e\x00\ +\x41\x00\x54\x00\x49\x00\x4f\x00\x4e\x00\x0a\x00\x54\x00\x68\x00\ +\x69\x00\x73\x00\x20\x00\x6c\x00\x69\x00\x63\x00\x65\x00\x6e\x00\ +\x73\x00\x65\x00\x20\x00\x62\x00\x65\x00\x63\x00\x6f\x00\x6d\x00\ +\x65\x00\x73\x00\x20\x00\x6e\x00\x75\x00\x6c\x00\x6c\x00\x20\x00\ +\x61\x00\x6e\x00\x64\x00\x20\x00\x76\x00\x6f\x00\x69\x00\x64\x00\ +\x20\x00\x69\x00\x66\x00\x20\x00\x61\x00\x6e\x00\x79\x00\x20\x00\ +\x6f\x00\x66\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x61\x00\ +\x62\x00\x6f\x00\x76\x00\x65\x00\x20\x00\x63\x00\x6f\x00\x6e\x00\ +\x64\x00\x69\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x20\x00\ +\x61\x00\x72\x00\x65\x00\x0a\x00\x6e\x00\x6f\x00\x74\x00\x20\x00\ +\x6d\x00\x65\x00\x74\x00\x2e\x00\x0a\x00\x0a\x00\x44\x00\x49\x00\ +\x53\x00\x43\x00\x4c\x00\x41\x00\x49\x00\x4d\x00\x45\x00\x52\x00\ +\x0a\x00\x54\x00\x48\x00\x45\x00\x20\x00\x46\x00\x4f\x00\x4e\x00\ +\x54\x00\x20\x00\x53\x00\x4f\x00\x46\x00\x54\x00\x57\x00\x41\x00\ +\x52\x00\x45\x00\x20\x00\x49\x00\x53\x00\x20\x00\x50\x00\x52\x00\ +\x4f\x00\x56\x00\x49\x00\x44\x00\x45\x00\x44\x00\x20\x00\x22\x00\ +\x41\x00\x53\x00\x20\x00\x49\x00\x53\x00\x22\x00\x2c\x00\x20\x00\ +\x57\x00\x49\x00\x54\x00\x48\x00\x4f\x00\x55\x00\x54\x00\x20\x00\ +\x57\x00\x41\x00\x52\x00\x52\x00\x41\x00\x4e\x00\x54\x00\x59\x00\ +\x20\x00\x4f\x00\x46\x00\x20\x00\x41\x00\x4e\x00\x59\x00\x20\x00\ +\x4b\x00\x49\x00\x4e\x00\x44\x00\x2c\x00\x0a\x00\x45\x00\x58\x00\ +\x50\x00\x52\x00\x45\x00\x53\x00\x53\x00\x20\x00\x4f\x00\x52\x00\ +\x20\x00\x49\x00\x4d\x00\x50\x00\x4c\x00\x49\x00\x45\x00\x44\x00\ +\x2c\x00\x20\x00\x49\x00\x4e\x00\x43\x00\x4c\x00\x55\x00\x44\x00\ +\x49\x00\x4e\x00\x47\x00\x20\x00\x42\x00\x55\x00\x54\x00\x20\x00\ +\x4e\x00\x4f\x00\x54\x00\x20\x00\x4c\x00\x49\x00\x4d\x00\x49\x00\ +\x54\x00\x45\x00\x44\x00\x20\x00\x54\x00\x4f\x00\x20\x00\x41\x00\ +\x4e\x00\x59\x00\x20\x00\x57\x00\x41\x00\x52\x00\x52\x00\x41\x00\ +\x4e\x00\x54\x00\x49\x00\x45\x00\x53\x00\x20\x00\x4f\x00\x46\x00\ +\x0a\x00\x4d\x00\x45\x00\x52\x00\x43\x00\x48\x00\x41\x00\x4e\x00\ +\x54\x00\x41\x00\x42\x00\x49\x00\x4c\x00\x49\x00\x54\x00\x59\x00\ +\x2c\x00\x20\x00\x46\x00\x49\x00\x54\x00\x4e\x00\x45\x00\x53\x00\ +\x53\x00\x20\x00\x46\x00\x4f\x00\x52\x00\x20\x00\x41\x00\x20\x00\ +\x50\x00\x41\x00\x52\x00\x54\x00\x49\x00\x43\x00\x55\x00\x4c\x00\ +\x41\x00\x52\x00\x20\x00\x50\x00\x55\x00\x52\x00\x50\x00\x4f\x00\ +\x53\x00\x45\x00\x20\x00\x41\x00\x4e\x00\x44\x00\x20\x00\x4e\x00\ +\x4f\x00\x4e\x00\x49\x00\x4e\x00\x46\x00\x52\x00\x49\x00\x4e\x00\ +\x47\x00\x45\x00\x4d\x00\x45\x00\x4e\x00\x54\x00\x0a\x00\x4f\x00\ +\x46\x00\x20\x00\x43\x00\x4f\x00\x50\x00\x59\x00\x52\x00\x49\x00\ +\x47\x00\x48\x00\x54\x00\x2c\x00\x20\x00\x50\x00\x41\x00\x54\x00\ +\x45\x00\x4e\x00\x54\x00\x2c\x00\x20\x00\x54\x00\x52\x00\x41\x00\ +\x44\x00\x45\x00\x4d\x00\x41\x00\x52\x00\x4b\x00\x2c\x00\x20\x00\ +\x4f\x00\x52\x00\x20\x00\x4f\x00\x54\x00\x48\x00\x45\x00\x52\x00\ +\x20\x00\x52\x00\x49\x00\x47\x00\x48\x00\x54\x00\x2e\x00\x20\x00\ +\x49\x00\x4e\x00\x20\x00\x4e\x00\x4f\x00\x20\x00\x45\x00\x56\x00\ +\x45\x00\x4e\x00\x54\x00\x20\x00\x53\x00\x48\x00\x41\x00\x4c\x00\ +\x4c\x00\x20\x00\x54\x00\x48\x00\x45\x00\x0a\x00\x43\x00\x4f\x00\ +\x50\x00\x59\x00\x52\x00\x49\x00\x47\x00\x48\x00\x54\x00\x20\x00\ +\x48\x00\x4f\x00\x4c\x00\x44\x00\x45\x00\x52\x00\x20\x00\x42\x00\ +\x45\x00\x20\x00\x4c\x00\x49\x00\x41\x00\x42\x00\x4c\x00\x45\x00\ +\x20\x00\x46\x00\x4f\x00\x52\x00\x20\x00\x41\x00\x4e\x00\x59\x00\ +\x20\x00\x43\x00\x4c\x00\x41\x00\x49\x00\x4d\x00\x2c\x00\x20\x00\ +\x44\x00\x41\x00\x4d\x00\x41\x00\x47\x00\x45\x00\x53\x00\x20\x00\ +\x4f\x00\x52\x00\x20\x00\x4f\x00\x54\x00\x48\x00\x45\x00\x52\x00\ +\x20\x00\x4c\x00\x49\x00\x41\x00\x42\x00\x49\x00\x4c\x00\x49\x00\ +\x54\x00\x59\x00\x2c\x00\x0a\x00\x49\x00\x4e\x00\x43\x00\x4c\x00\ +\x55\x00\x44\x00\x49\x00\x4e\x00\x47\x00\x20\x00\x41\x00\x4e\x00\ +\x59\x00\x20\x00\x47\x00\x45\x00\x4e\x00\x45\x00\x52\x00\x41\x00\ +\x4c\x00\x2c\x00\x20\x00\x53\x00\x50\x00\x45\x00\x43\x00\x49\x00\ +\x41\x00\x4c\x00\x2c\x00\x20\x00\x49\x00\x4e\x00\x44\x00\x49\x00\ +\x52\x00\x45\x00\x43\x00\x54\x00\x2c\x00\x20\x00\x49\x00\x4e\x00\ +\x43\x00\x49\x00\x44\x00\x45\x00\x4e\x00\x54\x00\x41\x00\x4c\x00\ +\x2c\x00\x20\x00\x4f\x00\x52\x00\x20\x00\x43\x00\x4f\x00\x4e\x00\ +\x53\x00\x45\x00\x51\x00\x55\x00\x45\x00\x4e\x00\x54\x00\x49\x00\ +\x41\x00\x4c\x00\x0a\x00\x44\x00\x41\x00\x4d\x00\x41\x00\x47\x00\ +\x45\x00\x53\x00\x2c\x00\x20\x00\x57\x00\x48\x00\x45\x00\x54\x00\ +\x48\x00\x45\x00\x52\x00\x20\x00\x49\x00\x4e\x00\x20\x00\x41\x00\ +\x4e\x00\x20\x00\x41\x00\x43\x00\x54\x00\x49\x00\x4f\x00\x4e\x00\ +\x20\x00\x4f\x00\x46\x00\x20\x00\x43\x00\x4f\x00\x4e\x00\x54\x00\ +\x52\x00\x41\x00\x43\x00\x54\x00\x2c\x00\x20\x00\x54\x00\x4f\x00\ +\x52\x00\x54\x00\x20\x00\x4f\x00\x52\x00\x20\x00\x4f\x00\x54\x00\ +\x48\x00\x45\x00\x52\x00\x57\x00\x49\x00\x53\x00\x45\x00\x2c\x00\ +\x20\x00\x41\x00\x52\x00\x49\x00\x53\x00\x49\x00\x4e\x00\x47\x00\ +\x0a\x00\x46\x00\x52\x00\x4f\x00\x4d\x00\x2c\x00\x20\x00\x4f\x00\ +\x55\x00\x54\x00\x20\x00\x4f\x00\x46\x00\x20\x00\x54\x00\x48\x00\ +\x45\x00\x20\x00\x55\x00\x53\x00\x45\x00\x20\x00\x4f\x00\x52\x00\ +\x20\x00\x49\x00\x4e\x00\x41\x00\x42\x00\x49\x00\x4c\x00\x49\x00\ +\x54\x00\x59\x00\x20\x00\x54\x00\x4f\x00\x20\x00\x55\x00\x53\x00\ +\x45\x00\x20\x00\x54\x00\x48\x00\x45\x00\x20\x00\x46\x00\x4f\x00\ +\x4e\x00\x54\x00\x20\x00\x53\x00\x4f\x00\x46\x00\x54\x00\x57\x00\ +\x41\x00\x52\x00\x45\x00\x20\x00\x4f\x00\x52\x00\x20\x00\x46\x00\ +\x52\x00\x4f\x00\x4d\x00\x0a\x00\x4f\x00\x54\x00\x48\x00\x45\x00\ +\x52\x00\x20\x00\x44\x00\x45\x00\x41\x00\x4c\x00\x49\x00\x4e\x00\ +\x47\x00\x53\x00\x20\x00\x49\x00\x4e\x00\x20\x00\x54\x00\x48\x00\ +\x45\x00\x20\x00\x46\x00\x4f\x00\x4e\x00\x54\x00\x20\x00\x53\x00\ +\x4f\x00\x46\x00\x54\x00\x57\x00\x41\x00\x52\x00\x45\x00\x2e\x00\ +\x00\x43\x6f\x70\x79\x72\x69\x67\x68\x74\x20\x28\x63\x29\x20\x32\ +\x30\x30\x38\x2c\x20\x42\x65\x6e\x20\x4c\x61\x65\x6e\x65\x6e\x20\ +\x28\x62\x65\x6e\x6c\x61\x65\x6e\x65\x6e\x40\x67\x6d\x61\x69\x6c\ +\x2e\x63\x6f\x6d\x29\x2c\x0a\x77\x69\x74\x68\x20\x52\x65\x73\x65\ +\x72\x76\x65\x64\x20\x46\x6f\x6e\x74\x20\x4e\x61\x6d\x65\x20\x45\ +\x75\x74\x65\x72\x70\x65\x2e\x0a\x0a\x54\x68\x69\x73\x20\x46\x6f\ +\x6e\x74\x20\x53\x6f\x66\x74\x77\x61\x72\x65\x20\x69\x73\x20\x6c\ +\x69\x63\x65\x6e\x73\x65\x64\x20\x75\x6e\x64\x65\x72\x20\x74\x68\ +\x65\x20\x53\x49\x4c\x20\x4f\x70\x65\x6e\x20\x46\x6f\x6e\x74\x20\ +\x4c\x69\x63\x65\x6e\x73\x65\x2c\x20\x56\x65\x72\x73\x69\x6f\x6e\ +\x20\x31\x2e\x31\x2e\x0a\x54\x68\x69\x73\x20\x6c\x69\x63\x65\x6e\ +\x73\x65\x20\x69\x73\x20\x63\x6f\x70\x69\x65\x64\x20\x62\x65\x6c\ +\x6f\x77\x2c\x20\x61\x6e\x64\x20\x69\x73\x20\x61\x6c\x73\x6f\x20\ +\x61\x76\x61\x69\x6c\x61\x62\x6c\x65\x20\x77\x69\x74\x68\x20\x61\ +\x20\x46\x41\x51\x20\x61\x74\x3a\x0a\x68\x74\x74\x70\x3a\x2f\x2f\ +\x73\x63\x72\x69\x70\x74\x73\x2e\x73\x69\x6c\x2e\x6f\x72\x67\x2f\ +\x4f\x46\x4c\x0a\x0a\x0a\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\ +\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\ +\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\ +\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\ +\x2d\x0a\x53\x49\x4c\x20\x4f\x50\x45\x4e\x20\x46\x4f\x4e\x54\x20\ +\x4c\x49\x43\x45\x4e\x53\x45\x20\x56\x65\x72\x73\x69\x6f\x6e\x20\ +\x31\x2e\x31\x20\x2d\x20\x32\x36\x20\x46\x65\x62\x72\x75\x61\x72\ +\x79\x20\x32\x30\x30\x37\x0a\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\ +\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\ +\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\ +\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\ +\x2d\x2d\x0a\x0a\x50\x52\x45\x41\x4d\x42\x4c\x45\x0a\x54\x68\x65\ +\x20\x67\x6f\x61\x6c\x73\x20\x6f\x66\x20\x74\x68\x65\x20\x4f\x70\ +\x65\x6e\x20\x46\x6f\x6e\x74\x20\x4c\x69\x63\x65\x6e\x73\x65\x20\ +\x28\x4f\x46\x4c\x29\x20\x61\x72\x65\x20\x74\x6f\x20\x73\x74\x69\ +\x6d\x75\x6c\x61\x74\x65\x20\x77\x6f\x72\x6c\x64\x77\x69\x64\x65\ +\x0a\x64\x65\x76\x65\x6c\x6f\x70\x6d\x65\x6e\x74\x20\x6f\x66\x20\ +\x63\x6f\x6c\x6c\x61\x62\x6f\x72\x61\x74\x69\x76\x65\x20\x66\x6f\ +\x6e\x74\x20\x70\x72\x6f\x6a\x65\x63\x74\x73\x2c\x20\x74\x6f\x20\ +\x73\x75\x70\x70\x6f\x72\x74\x20\x74\x68\x65\x20\x66\x6f\x6e\x74\ +\x20\x63\x72\x65\x61\x74\x69\x6f\x6e\x0a\x65\x66\x66\x6f\x72\x74\ +\x73\x20\x6f\x66\x20\x61\x63\x61\x64\x65\x6d\x69\x63\x20\x61\x6e\ +\x64\x20\x6c\x69\x6e\x67\x75\x69\x73\x74\x69\x63\x20\x63\x6f\x6d\ +\x6d\x75\x6e\x69\x74\x69\x65\x73\x2c\x20\x61\x6e\x64\x20\x74\x6f\ +\x20\x70\x72\x6f\x76\x69\x64\x65\x20\x61\x20\x66\x72\x65\x65\x20\ +\x61\x6e\x64\x0a\x6f\x70\x65\x6e\x20\x66\x72\x61\x6d\x65\x77\x6f\ +\x72\x6b\x20\x69\x6e\x20\x77\x68\x69\x63\x68\x20\x66\x6f\x6e\x74\ +\x73\x20\x6d\x61\x79\x20\x62\x65\x20\x73\x68\x61\x72\x65\x64\x20\ +\x61\x6e\x64\x20\x69\x6d\x70\x72\x6f\x76\x65\x64\x20\x69\x6e\x20\ +\x70\x61\x72\x74\x6e\x65\x72\x73\x68\x69\x70\x0a\x77\x69\x74\x68\ +\x20\x6f\x74\x68\x65\x72\x73\x2e\x0a\x0a\x54\x68\x65\x20\x4f\x46\ +\x4c\x20\x61\x6c\x6c\x6f\x77\x73\x20\x74\x68\x65\x20\x6c\x69\x63\ +\x65\x6e\x73\x65\x64\x20\x66\x6f\x6e\x74\x73\x20\x74\x6f\x20\x62\ +\x65\x20\x75\x73\x65\x64\x2c\x20\x73\x74\x75\x64\x69\x65\x64\x2c\ +\x20\x6d\x6f\x64\x69\x66\x69\x65\x64\x20\x61\x6e\x64\x0a\x72\x65\ +\x64\x69\x73\x74\x72\x69\x62\x75\x74\x65\x64\x20\x66\x72\x65\x65\ +\x6c\x79\x20\x61\x73\x20\x6c\x6f\x6e\x67\x20\x61\x73\x20\x74\x68\ +\x65\x79\x20\x61\x72\x65\x20\x6e\x6f\x74\x20\x73\x6f\x6c\x64\x20\ +\x62\x79\x20\x74\x68\x65\x6d\x73\x65\x6c\x76\x65\x73\x2e\x20\x54\ +\x68\x65\x0a\x66\x6f\x6e\x74\x73\x2c\x20\x69\x6e\x63\x6c\x75\x64\ +\x69\x6e\x67\x20\x61\x6e\x79\x20\x64\x65\x72\x69\x76\x61\x74\x69\ +\x76\x65\x20\x77\x6f\x72\x6b\x73\x2c\x20\x63\x61\x6e\x20\x62\x65\ +\x20\x62\x75\x6e\x64\x6c\x65\x64\x2c\x20\x65\x6d\x62\x65\x64\x64\ +\x65\x64\x2c\x20\x0a\x72\x65\x64\x69\x73\x74\x72\x69\x62\x75\x74\ +\x65\x64\x20\x61\x6e\x64\x2f\x6f\x72\x20\x73\x6f\x6c\x64\x20\x77\ +\x69\x74\x68\x20\x61\x6e\x79\x20\x73\x6f\x66\x74\x77\x61\x72\x65\ +\x20\x70\x72\x6f\x76\x69\x64\x65\x64\x20\x74\x68\x61\x74\x20\x61\ +\x6e\x79\x20\x72\x65\x73\x65\x72\x76\x65\x64\x0a\x6e\x61\x6d\x65\ +\x73\x20\x61\x72\x65\x20\x6e\x6f\x74\x20\x75\x73\x65\x64\x20\x62\ +\x79\x20\x64\x65\x72\x69\x76\x61\x74\x69\x76\x65\x20\x77\x6f\x72\ +\x6b\x73\x2e\x20\x54\x68\x65\x20\x66\x6f\x6e\x74\x73\x20\x61\x6e\ +\x64\x20\x64\x65\x72\x69\x76\x61\x74\x69\x76\x65\x73\x2c\x0a\x68\ +\x6f\x77\x65\x76\x65\x72\x2c\x20\x63\x61\x6e\x6e\x6f\x74\x20\x62\ +\x65\x20\x72\x65\x6c\x65\x61\x73\x65\x64\x20\x75\x6e\x64\x65\x72\ +\x20\x61\x6e\x79\x20\x6f\x74\x68\x65\x72\x20\x74\x79\x70\x65\x20\ +\x6f\x66\x20\x6c\x69\x63\x65\x6e\x73\x65\x2e\x20\x54\x68\x65\x0a\ +\x72\x65\x71\x75\x69\x72\x65\x6d\x65\x6e\x74\x20\x66\x6f\x72\x20\ +\x66\x6f\x6e\x74\x73\x20\x74\x6f\x20\x72\x65\x6d\x61\x69\x6e\x20\ +\x75\x6e\x64\x65\x72\x20\x74\x68\x69\x73\x20\x6c\x69\x63\x65\x6e\ +\x73\x65\x20\x64\x6f\x65\x73\x20\x6e\x6f\x74\x20\x61\x70\x70\x6c\ +\x79\x0a\x74\x6f\x20\x61\x6e\x79\x20\x64\x6f\x63\x75\x6d\x65\x6e\ +\x74\x20\x63\x72\x65\x61\x74\x65\x64\x20\x75\x73\x69\x6e\x67\x20\ +\x74\x68\x65\x20\x66\x6f\x6e\x74\x73\x20\x6f\x72\x20\x74\x68\x65\ +\x69\x72\x20\x64\x65\x72\x69\x76\x61\x74\x69\x76\x65\x73\x2e\x0a\ +\x0a\x44\x45\x46\x49\x4e\x49\x54\x49\x4f\x4e\x53\x0a\x22\x46\x6f\ +\x6e\x74\x20\x53\x6f\x66\x74\x77\x61\x72\x65\x22\x20\x72\x65\x66\ +\x65\x72\x73\x20\x74\x6f\x20\x74\x68\x65\x20\x73\x65\x74\x20\x6f\ +\x66\x20\x66\x69\x6c\x65\x73\x20\x72\x65\x6c\x65\x61\x73\x65\x64\ +\x20\x62\x79\x20\x74\x68\x65\x20\x43\x6f\x70\x79\x72\x69\x67\x68\ +\x74\x0a\x48\x6f\x6c\x64\x65\x72\x28\x73\x29\x20\x75\x6e\x64\x65\ +\x72\x20\x74\x68\x69\x73\x20\x6c\x69\x63\x65\x6e\x73\x65\x20\x61\ +\x6e\x64\x20\x63\x6c\x65\x61\x72\x6c\x79\x20\x6d\x61\x72\x6b\x65\ +\x64\x20\x61\x73\x20\x73\x75\x63\x68\x2e\x20\x54\x68\x69\x73\x20\ +\x6d\x61\x79\x0a\x69\x6e\x63\x6c\x75\x64\x65\x20\x73\x6f\x75\x72\ +\x63\x65\x20\x66\x69\x6c\x65\x73\x2c\x20\x62\x75\x69\x6c\x64\x20\ +\x73\x63\x72\x69\x70\x74\x73\x20\x61\x6e\x64\x20\x64\x6f\x63\x75\ +\x6d\x65\x6e\x74\x61\x74\x69\x6f\x6e\x2e\x0a\x0a\x22\x52\x65\x73\ +\x65\x72\x76\x65\x64\x20\x46\x6f\x6e\x74\x20\x4e\x61\x6d\x65\x22\ +\x20\x72\x65\x66\x65\x72\x73\x20\x74\x6f\x20\x61\x6e\x79\x20\x6e\ +\x61\x6d\x65\x73\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x61\ +\x73\x20\x73\x75\x63\x68\x20\x61\x66\x74\x65\x72\x20\x74\x68\x65\ +\x0a\x63\x6f\x70\x79\x72\x69\x67\x68\x74\x20\x73\x74\x61\x74\x65\ +\x6d\x65\x6e\x74\x28\x73\x29\x2e\x0a\x0a\x22\x4f\x72\x69\x67\x69\ +\x6e\x61\x6c\x20\x56\x65\x72\x73\x69\x6f\x6e\x22\x20\x72\x65\x66\ +\x65\x72\x73\x20\x74\x6f\x20\x74\x68\x65\x20\x63\x6f\x6c\x6c\x65\ +\x63\x74\x69\x6f\x6e\x20\x6f\x66\x20\x46\x6f\x6e\x74\x20\x53\x6f\ +\x66\x74\x77\x61\x72\x65\x20\x63\x6f\x6d\x70\x6f\x6e\x65\x6e\x74\ +\x73\x20\x61\x73\x0a\x64\x69\x73\x74\x72\x69\x62\x75\x74\x65\x64\ +\x20\x62\x79\x20\x74\x68\x65\x20\x43\x6f\x70\x79\x72\x69\x67\x68\ +\x74\x20\x48\x6f\x6c\x64\x65\x72\x28\x73\x29\x2e\x0a\x0a\x22\x4d\ +\x6f\x64\x69\x66\x69\x65\x64\x20\x56\x65\x72\x73\x69\x6f\x6e\x22\ +\x20\x72\x65\x66\x65\x72\x73\x20\x74\x6f\x20\x61\x6e\x79\x20\x64\ +\x65\x72\x69\x76\x61\x74\x69\x76\x65\x20\x6d\x61\x64\x65\x20\x62\ +\x79\x20\x61\x64\x64\x69\x6e\x67\x20\x74\x6f\x2c\x20\x64\x65\x6c\ +\x65\x74\x69\x6e\x67\x2c\x0a\x6f\x72\x20\x73\x75\x62\x73\x74\x69\ +\x74\x75\x74\x69\x6e\x67\x20\x2d\x2d\x20\x69\x6e\x20\x70\x61\x72\ +\x74\x20\x6f\x72\x20\x69\x6e\x20\x77\x68\x6f\x6c\x65\x20\x2d\x2d\ +\x20\x61\x6e\x79\x20\x6f\x66\x20\x74\x68\x65\x20\x63\x6f\x6d\x70\ +\x6f\x6e\x65\x6e\x74\x73\x20\x6f\x66\x20\x74\x68\x65\x0a\x4f\x72\ +\x69\x67\x69\x6e\x61\x6c\x20\x56\x65\x72\x73\x69\x6f\x6e\x2c\x20\ +\x62\x79\x20\x63\x68\x61\x6e\x67\x69\x6e\x67\x20\x66\x6f\x72\x6d\ +\x61\x74\x73\x20\x6f\x72\x20\x62\x79\x20\x70\x6f\x72\x74\x69\x6e\ +\x67\x20\x74\x68\x65\x20\x46\x6f\x6e\x74\x20\x53\x6f\x66\x74\x77\ +\x61\x72\x65\x20\x74\x6f\x20\x61\x0a\x6e\x65\x77\x20\x65\x6e\x76\ +\x69\x72\x6f\x6e\x6d\x65\x6e\x74\x2e\x0a\x0a\x22\x41\x75\x74\x68\ +\x6f\x72\x22\x20\x72\x65\x66\x65\x72\x73\x20\x74\x6f\x20\x61\x6e\ +\x79\x20\x64\x65\x73\x69\x67\x6e\x65\x72\x2c\x20\x65\x6e\x67\x69\ +\x6e\x65\x65\x72\x2c\x20\x70\x72\x6f\x67\x72\x61\x6d\x6d\x65\x72\ +\x2c\x20\x74\x65\x63\x68\x6e\x69\x63\x61\x6c\x0a\x77\x72\x69\x74\ +\x65\x72\x20\x6f\x72\x20\x6f\x74\x68\x65\x72\x20\x70\x65\x72\x73\ +\x6f\x6e\x20\x77\x68\x6f\x20\x63\x6f\x6e\x74\x72\x69\x62\x75\x74\ +\x65\x64\x20\x74\x6f\x20\x74\x68\x65\x20\x46\x6f\x6e\x74\x20\x53\ +\x6f\x66\x74\x77\x61\x72\x65\x2e\x0a\x0a\x50\x45\x52\x4d\x49\x53\ +\x53\x49\x4f\x4e\x20\x26\x20\x43\x4f\x4e\x44\x49\x54\x49\x4f\x4e\ +\x53\x0a\x50\x65\x72\x6d\x69\x73\x73\x69\x6f\x6e\x20\x69\x73\x20\ +\x68\x65\x72\x65\x62\x79\x20\x67\x72\x61\x6e\x74\x65\x64\x2c\x20\ +\x66\x72\x65\x65\x20\x6f\x66\x20\x63\x68\x61\x72\x67\x65\x2c\x20\ +\x74\x6f\x20\x61\x6e\x79\x20\x70\x65\x72\x73\x6f\x6e\x20\x6f\x62\ +\x74\x61\x69\x6e\x69\x6e\x67\x0a\x61\x20\x63\x6f\x70\x79\x20\x6f\ +\x66\x20\x74\x68\x65\x20\x46\x6f\x6e\x74\x20\x53\x6f\x66\x74\x77\ +\x61\x72\x65\x2c\x20\x74\x6f\x20\x75\x73\x65\x2c\x20\x73\x74\x75\ +\x64\x79\x2c\x20\x63\x6f\x70\x79\x2c\x20\x6d\x65\x72\x67\x65\x2c\ +\x20\x65\x6d\x62\x65\x64\x2c\x20\x6d\x6f\x64\x69\x66\x79\x2c\x0a\ +\x72\x65\x64\x69\x73\x74\x72\x69\x62\x75\x74\x65\x2c\x20\x61\x6e\ +\x64\x20\x73\x65\x6c\x6c\x20\x6d\x6f\x64\x69\x66\x69\x65\x64\x20\ +\x61\x6e\x64\x20\x75\x6e\x6d\x6f\x64\x69\x66\x69\x65\x64\x20\x63\ +\x6f\x70\x69\x65\x73\x20\x6f\x66\x20\x74\x68\x65\x20\x46\x6f\x6e\ +\x74\x0a\x53\x6f\x66\x74\x77\x61\x72\x65\x2c\x20\x73\x75\x62\x6a\ +\x65\x63\x74\x20\x74\x6f\x20\x74\x68\x65\x20\x66\x6f\x6c\x6c\x6f\ +\x77\x69\x6e\x67\x20\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x73\x3a\ +\x0a\x0a\x31\x29\x20\x4e\x65\x69\x74\x68\x65\x72\x20\x74\x68\x65\ +\x20\x46\x6f\x6e\x74\x20\x53\x6f\x66\x74\x77\x61\x72\x65\x20\x6e\ +\x6f\x72\x20\x61\x6e\x79\x20\x6f\x66\x20\x69\x74\x73\x20\x69\x6e\ +\x64\x69\x76\x69\x64\x75\x61\x6c\x20\x63\x6f\x6d\x70\x6f\x6e\x65\ +\x6e\x74\x73\x2c\x0a\x69\x6e\x20\x4f\x72\x69\x67\x69\x6e\x61\x6c\ +\x20\x6f\x72\x20\x4d\x6f\x64\x69\x66\x69\x65\x64\x20\x56\x65\x72\ +\x73\x69\x6f\x6e\x73\x2c\x20\x6d\x61\x79\x20\x62\x65\x20\x73\x6f\ +\x6c\x64\x20\x62\x79\x20\x69\x74\x73\x65\x6c\x66\x2e\x0a\x0a\x32\ +\x29\x20\x4f\x72\x69\x67\x69\x6e\x61\x6c\x20\x6f\x72\x20\x4d\x6f\ +\x64\x69\x66\x69\x65\x64\x20\x56\x65\x72\x73\x69\x6f\x6e\x73\x20\ +\x6f\x66\x20\x74\x68\x65\x20\x46\x6f\x6e\x74\x20\x53\x6f\x66\x74\ +\x77\x61\x72\x65\x20\x6d\x61\x79\x20\x62\x65\x20\x62\x75\x6e\x64\ +\x6c\x65\x64\x2c\x0a\x72\x65\x64\x69\x73\x74\x72\x69\x62\x75\x74\ +\x65\x64\x20\x61\x6e\x64\x2f\x6f\x72\x20\x73\x6f\x6c\x64\x20\x77\ +\x69\x74\x68\x20\x61\x6e\x79\x20\x73\x6f\x66\x74\x77\x61\x72\x65\ +\x2c\x20\x70\x72\x6f\x76\x69\x64\x65\x64\x20\x74\x68\x61\x74\x20\ +\x65\x61\x63\x68\x20\x63\x6f\x70\x79\x0a\x63\x6f\x6e\x74\x61\x69\ +\x6e\x73\x20\x74\x68\x65\x20\x61\x62\x6f\x76\x65\x20\x63\x6f\x70\ +\x79\x72\x69\x67\x68\x74\x20\x6e\x6f\x74\x69\x63\x65\x20\x61\x6e\ +\x64\x20\x74\x68\x69\x73\x20\x6c\x69\x63\x65\x6e\x73\x65\x2e\x20\ +\x54\x68\x65\x73\x65\x20\x63\x61\x6e\x20\x62\x65\x0a\x69\x6e\x63\ +\x6c\x75\x64\x65\x64\x20\x65\x69\x74\x68\x65\x72\x20\x61\x73\x20\ +\x73\x74\x61\x6e\x64\x2d\x61\x6c\x6f\x6e\x65\x20\x74\x65\x78\x74\ +\x20\x66\x69\x6c\x65\x73\x2c\x20\x68\x75\x6d\x61\x6e\x2d\x72\x65\ +\x61\x64\x61\x62\x6c\x65\x20\x68\x65\x61\x64\x65\x72\x73\x20\x6f\ +\x72\x0a\x69\x6e\x20\x74\x68\x65\x20\x61\x70\x70\x72\x6f\x70\x72\ +\x69\x61\x74\x65\x20\x6d\x61\x63\x68\x69\x6e\x65\x2d\x72\x65\x61\ +\x64\x61\x62\x6c\x65\x20\x6d\x65\x74\x61\x64\x61\x74\x61\x20\x66\ +\x69\x65\x6c\x64\x73\x20\x77\x69\x74\x68\x69\x6e\x20\x74\x65\x78\ +\x74\x20\x6f\x72\x0a\x62\x69\x6e\x61\x72\x79\x20\x66\x69\x6c\x65\ +\x73\x20\x61\x73\x20\x6c\x6f\x6e\x67\x20\x61\x73\x20\x74\x68\x6f\ +\x73\x65\x20\x66\x69\x65\x6c\x64\x73\x20\x63\x61\x6e\x20\x62\x65\ +\x20\x65\x61\x73\x69\x6c\x79\x20\x76\x69\x65\x77\x65\x64\x20\x62\ +\x79\x20\x74\x68\x65\x20\x75\x73\x65\x72\x2e\x0a\x0a\x33\x29\x20\ +\x4e\x6f\x20\x4d\x6f\x64\x69\x66\x69\x65\x64\x20\x56\x65\x72\x73\ +\x69\x6f\x6e\x20\x6f\x66\x20\x74\x68\x65\x20\x46\x6f\x6e\x74\x20\ +\x53\x6f\x66\x74\x77\x61\x72\x65\x20\x6d\x61\x79\x20\x75\x73\x65\ +\x20\x74\x68\x65\x20\x52\x65\x73\x65\x72\x76\x65\x64\x20\x46\x6f\ +\x6e\x74\x0a\x4e\x61\x6d\x65\x28\x73\x29\x20\x75\x6e\x6c\x65\x73\ +\x73\x20\x65\x78\x70\x6c\x69\x63\x69\x74\x20\x77\x72\x69\x74\x74\ +\x65\x6e\x20\x70\x65\x72\x6d\x69\x73\x73\x69\x6f\x6e\x20\x69\x73\ +\x20\x67\x72\x61\x6e\x74\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\ +\x63\x6f\x72\x72\x65\x73\x70\x6f\x6e\x64\x69\x6e\x67\x0a\x43\x6f\ +\x70\x79\x72\x69\x67\x68\x74\x20\x48\x6f\x6c\x64\x65\x72\x2e\x20\ +\x54\x68\x69\x73\x20\x72\x65\x73\x74\x72\x69\x63\x74\x69\x6f\x6e\ +\x20\x6f\x6e\x6c\x79\x20\x61\x70\x70\x6c\x69\x65\x73\x20\x74\x6f\ +\x20\x74\x68\x65\x20\x70\x72\x69\x6d\x61\x72\x79\x20\x66\x6f\x6e\ +\x74\x20\x6e\x61\x6d\x65\x20\x61\x73\x0a\x70\x72\x65\x73\x65\x6e\ +\x74\x65\x64\x20\x74\x6f\x20\x74\x68\x65\x20\x75\x73\x65\x72\x73\ +\x2e\x0a\x0a\x34\x29\x20\x54\x68\x65\x20\x6e\x61\x6d\x65\x28\x73\ +\x29\x20\x6f\x66\x20\x74\x68\x65\x20\x43\x6f\x70\x79\x72\x69\x67\ +\x68\x74\x20\x48\x6f\x6c\x64\x65\x72\x28\x73\x29\x20\x6f\x72\x20\ +\x74\x68\x65\x20\x41\x75\x74\x68\x6f\x72\x28\x73\x29\x20\x6f\x66\ +\x20\x74\x68\x65\x20\x46\x6f\x6e\x74\x0a\x53\x6f\x66\x74\x77\x61\ +\x72\x65\x20\x73\x68\x61\x6c\x6c\x20\x6e\x6f\x74\x20\x62\x65\x20\ +\x75\x73\x65\x64\x20\x74\x6f\x20\x70\x72\x6f\x6d\x6f\x74\x65\x2c\ +\x20\x65\x6e\x64\x6f\x72\x73\x65\x20\x6f\x72\x20\x61\x64\x76\x65\ +\x72\x74\x69\x73\x65\x20\x61\x6e\x79\x0a\x4d\x6f\x64\x69\x66\x69\ +\x65\x64\x20\x56\x65\x72\x73\x69\x6f\x6e\x2c\x20\x65\x78\x63\x65\ +\x70\x74\x20\x74\x6f\x20\x61\x63\x6b\x6e\x6f\x77\x6c\x65\x64\x67\ +\x65\x20\x74\x68\x65\x20\x63\x6f\x6e\x74\x72\x69\x62\x75\x74\x69\ +\x6f\x6e\x28\x73\x29\x20\x6f\x66\x20\x74\x68\x65\x0a\x43\x6f\x70\ +\x79\x72\x69\x67\x68\x74\x20\x48\x6f\x6c\x64\x65\x72\x28\x73\x29\ +\x20\x61\x6e\x64\x20\x74\x68\x65\x20\x41\x75\x74\x68\x6f\x72\x28\ +\x73\x29\x20\x6f\x72\x20\x77\x69\x74\x68\x20\x74\x68\x65\x69\x72\ +\x20\x65\x78\x70\x6c\x69\x63\x69\x74\x20\x77\x72\x69\x74\x74\x65\ +\x6e\x0a\x70\x65\x72\x6d\x69\x73\x73\x69\x6f\x6e\x2e\x0a\x0a\x35\ +\x29\x20\x54\x68\x65\x20\x46\x6f\x6e\x74\x20\x53\x6f\x66\x74\x77\ +\x61\x72\x65\x2c\x20\x6d\x6f\x64\x69\x66\x69\x65\x64\x20\x6f\x72\ +\x20\x75\x6e\x6d\x6f\x64\x69\x66\x69\x65\x64\x2c\x20\x69\x6e\x20\ +\x70\x61\x72\x74\x20\x6f\x72\x20\x69\x6e\x20\x77\x68\x6f\x6c\x65\ +\x2c\x0a\x6d\x75\x73\x74\x20\x62\x65\x20\x64\x69\x73\x74\x72\x69\ +\x62\x75\x74\x65\x64\x20\x65\x6e\x74\x69\x72\x65\x6c\x79\x20\x75\ +\x6e\x64\x65\x72\x20\x74\x68\x69\x73\x20\x6c\x69\x63\x65\x6e\x73\ +\x65\x2c\x20\x61\x6e\x64\x20\x6d\x75\x73\x74\x20\x6e\x6f\x74\x20\ +\x62\x65\x0a\x64\x69\x73\x74\x72\x69\x62\x75\x74\x65\x64\x20\x75\ +\x6e\x64\x65\x72\x20\x61\x6e\x79\x20\x6f\x74\x68\x65\x72\x20\x6c\ +\x69\x63\x65\x6e\x73\x65\x2e\x20\x54\x68\x65\x20\x72\x65\x71\x75\ +\x69\x72\x65\x6d\x65\x6e\x74\x20\x66\x6f\x72\x20\x66\x6f\x6e\x74\ +\x73\x20\x74\x6f\x0a\x72\x65\x6d\x61\x69\x6e\x20\x75\x6e\x64\x65\ +\x72\x20\x74\x68\x69\x73\x20\x6c\x69\x63\x65\x6e\x73\x65\x20\x64\ +\x6f\x65\x73\x20\x6e\x6f\x74\x20\x61\x70\x70\x6c\x79\x20\x74\x6f\ +\x20\x61\x6e\x79\x20\x64\x6f\x63\x75\x6d\x65\x6e\x74\x20\x63\x72\ +\x65\x61\x74\x65\x64\x0a\x75\x73\x69\x6e\x67\x20\x74\x68\x65\x20\ +\x46\x6f\x6e\x74\x20\x53\x6f\x66\x74\x77\x61\x72\x65\x2e\x0a\x0a\ +\x54\x45\x52\x4d\x49\x4e\x41\x54\x49\x4f\x4e\x0a\x54\x68\x69\x73\ +\x20\x6c\x69\x63\x65\x6e\x73\x65\x20\x62\x65\x63\x6f\x6d\x65\x73\ +\x20\x6e\x75\x6c\x6c\x20\x61\x6e\x64\x20\x76\x6f\x69\x64\x20\x69\ +\x66\x20\x61\x6e\x79\x20\x6f\x66\x20\x74\x68\x65\x20\x61\x62\x6f\ +\x76\x65\x20\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x73\x20\x61\x72\ +\x65\x0a\x6e\x6f\x74\x20\x6d\x65\x74\x2e\x0a\x0a\x44\x49\x53\x43\ +\x4c\x41\x49\x4d\x45\x52\x0a\x54\x48\x45\x20\x46\x4f\x4e\x54\x20\ +\x53\x4f\x46\x54\x57\x41\x52\x45\x20\x49\x53\x20\x50\x52\x4f\x56\ +\x49\x44\x45\x44\x20\x22\x41\x53\x20\x49\x53\x22\x2c\x20\x57\x49\ +\x54\x48\x4f\x55\x54\x20\x57\x41\x52\x52\x41\x4e\x54\x59\x20\x4f\ +\x46\x20\x41\x4e\x59\x20\x4b\x49\x4e\x44\x2c\x0a\x45\x58\x50\x52\ +\x45\x53\x53\x20\x4f\x52\x20\x49\x4d\x50\x4c\x49\x45\x44\x2c\x20\ +\x49\x4e\x43\x4c\x55\x44\x49\x4e\x47\x20\x42\x55\x54\x20\x4e\x4f\ +\x54\x20\x4c\x49\x4d\x49\x54\x45\x44\x20\x54\x4f\x20\x41\x4e\x59\ +\x20\x57\x41\x52\x52\x41\x4e\x54\x49\x45\x53\x20\x4f\x46\x0a\x4d\ +\x45\x52\x43\x48\x41\x4e\x54\x41\x42\x49\x4c\x49\x54\x59\x2c\x20\ +\x46\x49\x54\x4e\x45\x53\x53\x20\x46\x4f\x52\x20\x41\x20\x50\x41\ +\x52\x54\x49\x43\x55\x4c\x41\x52\x20\x50\x55\x52\x50\x4f\x53\x45\ +\x20\x41\x4e\x44\x20\x4e\x4f\x4e\x49\x4e\x46\x52\x49\x4e\x47\x45\ +\x4d\x45\x4e\x54\x0a\x4f\x46\x20\x43\x4f\x50\x59\x52\x49\x47\x48\ +\x54\x2c\x20\x50\x41\x54\x45\x4e\x54\x2c\x20\x54\x52\x41\x44\x45\ +\x4d\x41\x52\x4b\x2c\x20\x4f\x52\x20\x4f\x54\x48\x45\x52\x20\x52\ +\x49\x47\x48\x54\x2e\x20\x49\x4e\x20\x4e\x4f\x20\x45\x56\x45\x4e\ +\x54\x20\x53\x48\x41\x4c\x4c\x20\x54\x48\x45\x0a\x43\x4f\x50\x59\ +\x52\x49\x47\x48\x54\x20\x48\x4f\x4c\x44\x45\x52\x20\x42\x45\x20\ +\x4c\x49\x41\x42\x4c\x45\x20\x46\x4f\x52\x20\x41\x4e\x59\x20\x43\ +\x4c\x41\x49\x4d\x2c\x20\x44\x41\x4d\x41\x47\x45\x53\x20\x4f\x52\ +\x20\x4f\x54\x48\x45\x52\x20\x4c\x49\x41\x42\x49\x4c\x49\x54\x59\ +\x2c\x0a\x49\x4e\x43\x4c\x55\x44\x49\x4e\x47\x20\x41\x4e\x59\x20\ +\x47\x45\x4e\x45\x52\x41\x4c\x2c\x20\x53\x50\x45\x43\x49\x41\x4c\ +\x2c\x20\x49\x4e\x44\x49\x52\x45\x43\x54\x2c\x20\x49\x4e\x43\x49\ +\x44\x45\x4e\x54\x41\x4c\x2c\x20\x4f\x52\x20\x43\x4f\x4e\x53\x45\ +\x51\x55\x45\x4e\x54\x49\x41\x4c\x0a\x44\x41\x4d\x41\x47\x45\x53\ +\x2c\x20\x57\x48\x45\x54\x48\x45\x52\x20\x49\x4e\x20\x41\x4e\x20\ +\x41\x43\x54\x49\x4f\x4e\x20\x4f\x46\x20\x43\x4f\x4e\x54\x52\x41\ +\x43\x54\x2c\x20\x54\x4f\x52\x54\x20\x4f\x52\x20\x4f\x54\x48\x45\ +\x52\x57\x49\x53\x45\x2c\x20\x41\x52\x49\x53\x49\x4e\x47\x0a\x46\ +\x52\x4f\x4d\x2c\x20\x4f\x55\x54\x20\x4f\x46\x20\x54\x48\x45\x20\ +\x55\x53\x45\x20\x4f\x52\x20\x49\x4e\x41\x42\x49\x4c\x49\x54\x59\ +\x20\x54\x4f\x20\x55\x53\x45\x20\x54\x48\x45\x20\x46\x4f\x4e\x54\ +\x20\x53\x4f\x46\x54\x57\x41\x52\x45\x20\x4f\x52\x20\x46\x52\x4f\ +\x4d\x0a\x4f\x54\x48\x45\x52\x20\x44\x45\x41\x4c\x49\x4e\x47\x53\ +\x20\x49\x4e\x20\x54\x48\x45\x20\x46\x4f\x4e\x54\x20\x53\x4f\x46\ +\x54\x57\x41\x52\x45\x2e\x00\x00\x68\x00\x74\x00\x74\x00\x70\x00\ +\x3a\x00\x2f\x00\x2f\x00\x73\x00\x63\x00\x72\x00\x69\x00\x70\x00\ +\x74\x00\x73\x00\x2e\x00\x73\x00\x69\x00\x6c\x00\x2e\x00\x6f\x00\ +\x72\x00\x67\x00\x2f\x00\x6f\x00\x66\x00\x6c\x00\x00\x68\x74\x74\ +\x70\x3a\x2f\x2f\x73\x63\x72\x69\x70\x74\x73\x2e\x73\x69\x6c\x2e\ +\x6f\x72\x67\x2f\x6f\x66\x6c\x00\x00\x00\x00\x00\x02\x00\x00\x00\ +\x00\x00\x00\xff\x83\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x14\x00\x00\x00\ +\x01\x00\x02\x00\x03\x01\x02\x01\x03\x01\x04\x01\x05\x01\x06\x01\ +\x07\x01\x08\x01\x09\x01\x0a\x01\x0b\x01\x0c\x01\x0d\x01\x0e\x01\ +\x0f\x01\x10\x01\x11\x01\x12\x01\x13\x01\x14\x01\x15\x01\x16\x01\ +\x17\x01\x18\x01\x19\x01\x1a\x01\x1b\x01\x1c\x01\x1d\x01\x1e\x01\ +\x1f\x01\x20\x01\x21\x01\x22\x01\x23\x01\x24\x01\x25\x01\x26\x01\ +\x27\x01\x28\x01\x29\x01\x2a\x01\x2b\x01\x2c\x01\x2d\x01\x2e\x01\ +\x2f\x01\x30\x01\x31\x01\x32\x01\x33\x01\x34\x01\x35\x01\x36\x01\ +\x37\x01\x38\x01\x39\x01\x3a\x01\x3b\x01\x3c\x01\x3d\x01\x3e\x01\ +\x3f\x01\x40\x01\x41\x01\x42\x01\x43\x01\x44\x01\x45\x01\x46\x01\ +\x47\x01\x48\x01\x49\x01\x4a\x01\x4b\x01\x4c\x01\x4d\x01\x4e\x01\ +\x4f\x01\x50\x01\x51\x01\x52\x01\x53\x01\x54\x01\x55\x01\x56\x01\ +\x57\x01\x58\x01\x59\x01\x5a\x01\x5b\x01\x5c\x01\x5d\x01\x5e\x01\ +\x5f\x01\x60\x01\x61\x01\x62\x01\x63\x01\x64\x01\x65\x01\x66\x01\ +\x67\x01\x68\x01\x69\x01\x6a\x01\x6b\x01\x6c\x01\x6d\x01\x6e\x01\ +\x6f\x01\x70\x01\x71\x01\x72\x01\x73\x01\x74\x01\x75\x01\x76\x01\ +\x77\x01\x78\x01\x79\x01\x7a\x01\x7b\x01\x7c\x01\x7d\x01\x7e\x01\ +\x7f\x01\x80\x01\x81\x01\x82\x01\x83\x01\x84\x01\x85\x01\x86\x01\ +\x87\x01\x88\x01\x89\x01\x8a\x01\x8b\x01\x8c\x01\x8d\x01\x8e\x01\ +\x8f\x01\x90\x01\x91\x01\x92\x01\x93\x01\x94\x01\x95\x01\x96\x01\ +\x97\x01\x98\x01\x99\x01\x9a\x01\x9b\x01\x9c\x01\x9d\x01\x9e\x01\ +\x9f\x01\xa0\x01\xa1\x01\xa2\x01\xa3\x01\xa4\x01\xa5\x01\xa6\x01\ +\xa7\x01\xa8\x01\xa9\x01\xaa\x01\xab\x01\xac\x01\xad\x01\xae\x01\ +\xaf\x01\xb0\x01\xb1\x01\xb2\x01\xb3\x01\xb4\x01\xb5\x01\xb6\x01\ +\xb7\x01\xb8\x01\xb9\x01\xba\x01\xbb\x01\xbc\x01\xbd\x01\xbe\x01\ +\xbf\x01\xc0\x01\xc1\x01\xc2\x01\xc3\x01\xc4\x01\xc5\x01\xc6\x01\ +\xc7\x01\xc8\x01\xc9\x01\xca\x01\xcb\x01\xcc\x01\xcd\x01\xce\x01\ +\xcf\x01\xd0\x01\xd1\x01\xd2\x01\xd3\x01\xd4\x01\xd5\x01\xd6\x01\ +\xd7\x01\xd8\x01\xd9\x01\xda\x01\xdb\x01\xdc\x01\xdd\x01\xde\x01\ +\xdf\x01\xe0\x01\xe1\x01\xe2\x01\xe3\x01\xe4\x01\xe5\x01\xe6\x01\ +\xe7\x01\xe8\x01\xe9\x01\xea\x01\xeb\x01\xec\x01\xed\x01\xee\x01\ +\xef\x01\xf0\x01\xf1\x01\xf2\x01\xf3\x01\xf4\x01\xf5\x01\xf6\x01\ +\xf7\x01\xf8\x01\xf9\x01\xfa\x01\xfb\x01\xfc\x01\xfd\x01\xfe\x01\ +\xff\x02\x00\x02\x01\x02\x02\x02\x03\x02\x04\x02\x05\x02\x06\x02\ +\x07\x02\x08\x02\x09\x02\x0a\x02\x0b\x02\x0c\x02\x0d\x02\x0e\x02\ +\x0f\x02\x10\x02\x11\x07\x75\x6e\x69\x32\x36\x36\x44\x07\x75\x6e\ +\x69\x32\x36\x36\x45\x07\x75\x6e\x69\x32\x36\x36\x46\x0d\x75\x31\ +\x44\x31\x38\x46\x5f\x75\x31\x44\x31\x38\x46\x14\x75\x31\x44\x31\ +\x38\x46\x5f\x75\x31\x44\x31\x38\x46\x5f\x75\x31\x44\x31\x38\x46\ +\x0d\x75\x31\x44\x31\x39\x31\x5f\x75\x31\x44\x31\x39\x31\x14\x75\ +\x31\x44\x31\x39\x31\x5f\x75\x31\x44\x31\x39\x31\x5f\x75\x31\x44\ +\x31\x39\x31\x0d\x75\x31\x44\x31\x39\x30\x5f\x75\x31\x44\x31\x38\ +\x46\x0d\x75\x31\x44\x31\x39\x30\x5f\x75\x31\x44\x31\x39\x31\x0d\ +\x75\x31\x44\x31\x38\x44\x5f\x75\x31\x44\x31\x39\x31\x0d\x75\x31\ +\x44\x31\x39\x31\x5f\x75\x31\x44\x31\x38\x45\x14\x75\x31\x44\x31\ +\x38\x44\x5f\x75\x31\x44\x31\x39\x31\x5f\x75\x31\x44\x31\x38\x45\ +\x15\x6d\x75\x6c\x74\x69\x70\x6c\x65\x5f\x6d\x65\x61\x73\x75\x72\ +\x65\x5f\x72\x65\x73\x74\x0d\x75\x31\x44\x31\x30\x37\x5f\x75\x31\ +\x44\x31\x30\x36\x0a\x75\x31\x44\x31\x32\x32\x2e\x6f\x6c\x64\x0a\ +\x75\x31\x44\x31\x32\x33\x2e\x6f\x6c\x64\x0a\x75\x31\x44\x31\x32\ +\x34\x2e\x6f\x6c\x64\x08\x74\x61\x62\x5f\x73\x69\x67\x6e\x0a\x75\ +\x31\x44\x31\x32\x31\x2e\x6f\x6c\x64\x07\x75\x6e\x69\x45\x30\x31\ +\x30\x16\x63\x72\x65\x73\x63\x65\x6e\x64\x6f\x5f\x66\x72\x6f\x6d\ +\x5f\x73\x69\x6c\x65\x6e\x63\x65\x05\x73\x77\x65\x6c\x6c\x0c\x6d\ +\x75\x74\x65\x5f\x73\x74\x72\x69\x6e\x67\x73\x0a\x75\x31\x44\x31\ +\x42\x30\x2e\x61\x6c\x74\x07\x75\x6e\x69\x45\x30\x31\x38\x0f\x75\ +\x6e\x69\x32\x36\x36\x45\x5f\x75\x6e\x69\x32\x36\x36\x45\x0f\x75\ +\x6e\x69\x32\x36\x36\x45\x5f\x75\x6e\x69\x32\x36\x36\x44\x0f\x75\ +\x6e\x69\x32\x36\x36\x45\x5f\x75\x6e\x69\x32\x36\x36\x46\x0a\x68\ +\x61\x6c\x66\x5f\x73\x68\x61\x72\x70\x10\x73\x68\x61\x72\x70\x5f\ +\x61\x6e\x64\x5f\x61\x5f\x68\x61\x6c\x66\x09\x68\x61\x6c\x66\x5f\ +\x66\x6c\x61\x74\x0f\x66\x6c\x61\x74\x5f\x61\x6e\x64\x5f\x61\x5f\ +\x68\x61\x6c\x66\x07\x75\x6e\x69\x45\x30\x32\x30\x07\x75\x6e\x69\ +\x45\x30\x32\x31\x07\x75\x6e\x69\x45\x30\x32\x35\x07\x75\x6e\x69\ +\x45\x30\x32\x38\x07\x75\x6e\x69\x45\x30\x33\x32\x07\x75\x6e\x69\ +\x45\x30\x33\x33\x07\x75\x6e\x69\x45\x30\x34\x32\x07\x75\x6e\x69\ +\x45\x30\x34\x41\x07\x75\x6e\x69\x45\x30\x35\x30\x07\x75\x6e\x69\ +\x45\x30\x35\x31\x07\x75\x6e\x69\x45\x30\x35\x35\x07\x75\x6e\x69\ +\x45\x30\x35\x43\x07\x75\x6e\x69\x45\x30\x35\x44\x07\x75\x6e\x69\ +\x45\x30\x35\x46\x07\x75\x6e\x69\x45\x30\x36\x31\x07\x75\x6e\x69\ +\x45\x30\x36\x32\x07\x75\x6e\x69\x45\x30\x36\x35\x07\x75\x6e\x69\ +\x45\x30\x36\x39\x06\x75\x31\x44\x31\x30\x30\x06\x75\x31\x44\x31\ +\x30\x31\x06\x75\x31\x44\x31\x30\x32\x06\x75\x31\x44\x31\x30\x33\ +\x06\x75\x31\x44\x31\x30\x34\x06\x75\x31\x44\x31\x30\x35\x06\x75\ +\x31\x44\x31\x30\x36\x06\x75\x31\x44\x31\x30\x37\x06\x75\x31\x44\ +\x31\x30\x38\x06\x75\x31\x44\x31\x30\x39\x06\x75\x31\x44\x31\x30\ +\x41\x06\x75\x31\x44\x31\x30\x42\x06\x75\x31\x44\x31\x30\x43\x06\ +\x75\x31\x44\x31\x30\x44\x06\x75\x31\x44\x31\x30\x45\x06\x75\x31\ +\x44\x31\x30\x46\x06\x75\x31\x44\x31\x31\x30\x06\x75\x31\x44\x31\ +\x31\x31\x06\x75\x31\x44\x31\x31\x32\x06\x75\x31\x44\x31\x31\x33\ +\x06\x75\x31\x44\x31\x31\x34\x06\x75\x31\x44\x31\x31\x35\x06\x75\ +\x31\x44\x31\x31\x36\x06\x75\x31\x44\x31\x31\x37\x06\x75\x31\x44\ +\x31\x31\x38\x06\x75\x31\x44\x31\x31\x39\x06\x75\x31\x44\x31\x31\ +\x41\x06\x75\x31\x44\x31\x31\x42\x06\x75\x31\x44\x31\x31\x43\x06\ +\x75\x31\x44\x31\x31\x44\x06\x75\x31\x44\x31\x31\x45\x06\x75\x31\ +\x44\x31\x31\x46\x06\x75\x31\x44\x31\x32\x30\x06\x75\x31\x44\x31\ +\x32\x31\x06\x75\x31\x44\x31\x32\x32\x06\x75\x31\x44\x31\x32\x33\ +\x06\x75\x31\x44\x31\x32\x34\x06\x75\x31\x44\x31\x32\x35\x06\x75\ +\x31\x44\x31\x32\x36\x06\x75\x31\x44\x31\x32\x39\x06\x75\x31\x44\ +\x31\x32\x41\x06\x75\x31\x44\x31\x32\x42\x06\x75\x31\x44\x31\x32\ +\x43\x06\x75\x31\x44\x31\x32\x44\x06\x75\x31\x44\x31\x32\x45\x06\ +\x75\x31\x44\x31\x32\x46\x06\x75\x31\x44\x31\x33\x30\x06\x75\x31\ +\x44\x31\x33\x31\x06\x75\x31\x44\x31\x33\x32\x06\x75\x31\x44\x31\ +\x33\x33\x06\x75\x31\x44\x31\x33\x34\x06\x75\x31\x44\x31\x33\x35\ +\x06\x75\x31\x44\x31\x33\x36\x06\x75\x31\x44\x31\x33\x37\x06\x75\ +\x31\x44\x31\x33\x38\x06\x75\x31\x44\x31\x33\x39\x06\x75\x31\x44\ +\x31\x33\x41\x06\x75\x31\x44\x31\x33\x42\x06\x75\x31\x44\x31\x33\ +\x43\x06\x75\x31\x44\x31\x33\x44\x06\x75\x31\x44\x31\x33\x45\x06\ +\x75\x31\x44\x31\x33\x46\x06\x75\x31\x44\x31\x34\x30\x06\x75\x31\ +\x44\x31\x34\x31\x06\x75\x31\x44\x31\x34\x32\x06\x75\x31\x44\x31\ +\x34\x33\x06\x75\x31\x44\x31\x34\x34\x06\x75\x31\x44\x31\x34\x35\ +\x06\x75\x31\x44\x31\x34\x36\x06\x75\x31\x44\x31\x34\x37\x06\x75\ +\x31\x44\x31\x34\x38\x06\x75\x31\x44\x31\x34\x39\x06\x75\x31\x44\ +\x31\x34\x41\x06\x75\x31\x44\x31\x34\x42\x06\x75\x31\x44\x31\x34\ +\x43\x06\x75\x31\x44\x31\x34\x44\x06\x75\x31\x44\x31\x34\x45\x06\ +\x75\x31\x44\x31\x34\x46\x06\x75\x31\x44\x31\x35\x30\x06\x75\x31\ +\x44\x31\x35\x31\x06\x75\x31\x44\x31\x35\x32\x06\x75\x31\x44\x31\ +\x35\x33\x06\x75\x31\x44\x31\x35\x34\x06\x75\x31\x44\x31\x35\x35\ +\x06\x75\x31\x44\x31\x35\x36\x06\x75\x31\x44\x31\x35\x37\x06\x75\ +\x31\x44\x31\x35\x38\x06\x75\x31\x44\x31\x35\x39\x06\x75\x31\x44\ +\x31\x35\x41\x06\x75\x31\x44\x31\x35\x42\x06\x75\x31\x44\x31\x35\ +\x43\x06\x75\x31\x44\x31\x35\x44\x06\x75\x31\x44\x31\x35\x45\x06\ +\x75\x31\x44\x31\x35\x46\x06\x75\x31\x44\x31\x36\x30\x06\x75\x31\ +\x44\x31\x36\x31\x06\x75\x31\x44\x31\x36\x32\x06\x75\x31\x44\x31\ +\x36\x33\x06\x75\x31\x44\x31\x36\x34\x06\x75\x31\x44\x31\x36\x35\ +\x06\x75\x31\x44\x31\x36\x36\x06\x75\x31\x44\x31\x36\x37\x06\x75\ +\x31\x44\x31\x36\x38\x06\x75\x31\x44\x31\x36\x39\x06\x75\x31\x44\ +\x31\x36\x41\x06\x75\x31\x44\x31\x36\x42\x06\x75\x31\x44\x31\x36\ +\x43\x06\x75\x31\x44\x31\x36\x44\x06\x75\x31\x44\x31\x36\x45\x06\ +\x75\x31\x44\x31\x36\x46\x06\x75\x31\x44\x31\x37\x30\x06\x75\x31\ +\x44\x31\x37\x31\x06\x75\x31\x44\x31\x37\x32\x06\x75\x31\x44\x31\ +\x37\x33\x06\x75\x31\x44\x31\x37\x34\x06\x75\x31\x44\x31\x37\x35\ +\x06\x75\x31\x44\x31\x37\x36\x06\x75\x31\x44\x31\x37\x37\x06\x75\ +\x31\x44\x31\x37\x38\x06\x75\x31\x44\x31\x37\x39\x06\x75\x31\x44\ +\x31\x37\x41\x06\x75\x31\x44\x31\x37\x42\x06\x75\x31\x44\x31\x37\ +\x43\x06\x75\x31\x44\x31\x37\x44\x06\x75\x31\x44\x31\x37\x45\x06\ +\x75\x31\x44\x31\x37\x46\x06\x75\x31\x44\x31\x38\x30\x06\x75\x31\ +\x44\x31\x38\x31\x06\x75\x31\x44\x31\x38\x32\x06\x75\x31\x44\x31\ +\x38\x33\x06\x75\x31\x44\x31\x38\x34\x06\x75\x31\x44\x31\x38\x35\ +\x06\x75\x31\x44\x31\x38\x36\x06\x75\x31\x44\x31\x38\x37\x06\x75\ +\x31\x44\x31\x38\x38\x06\x75\x31\x44\x31\x38\x39\x06\x75\x31\x44\ +\x31\x38\x41\x06\x75\x31\x44\x31\x38\x42\x06\x75\x31\x44\x31\x38\ +\x43\x06\x75\x31\x44\x31\x38\x44\x06\x75\x31\x44\x31\x38\x45\x06\ +\x75\x31\x44\x31\x38\x46\x06\x75\x31\x44\x31\x39\x30\x06\x75\x31\ +\x44\x31\x39\x31\x06\x75\x31\x44\x31\x39\x32\x06\x75\x31\x44\x31\ +\x39\x33\x06\x75\x31\x44\x31\x39\x34\x06\x75\x31\x44\x31\x39\x35\ +\x06\x75\x31\x44\x31\x39\x36\x06\x75\x31\x44\x31\x39\x37\x06\x75\ +\x31\x44\x31\x39\x38\x06\x75\x31\x44\x31\x39\x39\x06\x75\x31\x44\ +\x31\x39\x41\x06\x75\x31\x44\x31\x39\x42\x06\x75\x31\x44\x31\x39\ +\x43\x06\x75\x31\x44\x31\x39\x44\x06\x75\x31\x44\x31\x39\x45\x06\ +\x75\x31\x44\x31\x39\x46\x06\x75\x31\x44\x31\x41\x30\x06\x75\x31\ +\x44\x31\x41\x31\x06\x75\x31\x44\x31\x41\x32\x06\x75\x31\x44\x31\ +\x41\x33\x06\x75\x31\x44\x31\x41\x34\x06\x75\x31\x44\x31\x41\x35\ +\x06\x75\x31\x44\x31\x41\x36\x06\x75\x31\x44\x31\x41\x37\x06\x75\ +\x31\x44\x31\x41\x38\x06\x75\x31\x44\x31\x41\x39\x06\x75\x31\x44\ +\x31\x41\x41\x06\x75\x31\x44\x31\x41\x42\x06\x75\x31\x44\x31\x41\ +\x43\x06\x75\x31\x44\x31\x41\x44\x06\x75\x31\x44\x31\x41\x45\x06\ +\x75\x31\x44\x31\x41\x46\x06\x75\x31\x44\x31\x42\x30\x06\x75\x31\ +\x44\x31\x42\x31\x06\x75\x31\x44\x31\x42\x32\x06\x75\x31\x44\x31\ +\x42\x33\x06\x75\x31\x44\x31\x42\x34\x06\x75\x31\x44\x31\x42\x35\ +\x06\x75\x31\x44\x31\x42\x36\x06\x75\x31\x44\x31\x42\x37\x06\x75\ +\x31\x44\x31\x42\x38\x06\x75\x31\x44\x31\x42\x39\x06\x75\x31\x44\ +\x31\x42\x41\x06\x75\x31\x44\x31\x42\x42\x06\x75\x31\x44\x31\x42\ +\x43\x06\x75\x31\x44\x31\x42\x44\x06\x75\x31\x44\x31\x42\x45\x06\ +\x75\x31\x44\x31\x42\x46\x06\x75\x31\x44\x31\x43\x30\x06\x75\x31\ +\x44\x31\x43\x31\x06\x75\x31\x44\x31\x43\x32\x06\x75\x31\x44\x31\ +\x43\x33\x06\x75\x31\x44\x31\x43\x34\x06\x75\x31\x44\x31\x43\x35\ +\x06\x75\x31\x44\x31\x43\x36\x06\x75\x31\x44\x31\x43\x37\x06\x75\ +\x31\x44\x31\x43\x38\x06\x75\x31\x44\x31\x43\x39\x06\x75\x31\x44\ +\x31\x43\x41\x06\x75\x31\x44\x31\x43\x42\x06\x75\x31\x44\x31\x43\ +\x43\x06\x75\x31\x44\x31\x43\x44\x06\x75\x31\x44\x31\x43\x45\x06\ +\x75\x31\x44\x31\x43\x46\x06\x75\x31\x44\x31\x44\x30\x06\x75\x31\ +\x44\x31\x44\x31\x06\x75\x31\x44\x31\x44\x32\x06\x75\x31\x44\x31\ +\x44\x33\x06\x75\x31\x44\x31\x44\x34\x06\x75\x31\x44\x31\x44\x35\ +\x06\x75\x31\x44\x31\x44\x36\x06\x75\x31\x44\x31\x44\x37\x06\x75\ +\x31\x44\x31\x44\x38\x06\x75\x31\x44\x31\x44\x39\x06\x75\x31\x44\ +\x31\x44\x41\x06\x75\x31\x44\x31\x44\x42\x06\x75\x31\x44\x31\x44\ +\x43\x06\x75\x31\x44\x31\x44\x44\x0d\x75\x31\x44\x31\x41\x30\x5f\ +\x75\x31\x44\x31\x39\x44\x0d\x75\x31\x44\x31\x41\x30\x5f\x75\x31\ +\x44\x31\x39\x43\x00\x00\x00\x00\x00\x00\x01\xff\xff\x00\x02\x00\ +\x01\x00\x00\x00\x0c\x00\x00\x00\x40\x00\x00\x00\x02\x00\x08\x00\ +\x03\x00\x06\x00\x01\x00\x07\x00\x0f\x00\x02\x00\x10\x00\x10\x00\ +\x01\x00\x11\x00\x11\x00\x02\x00\x12\x00\x1c\x00\x01\x00\x1d\x00\ +\x1f\x00\x02\x00\x20\x01\x11\x00\x01\x01\x12\x01\x13\x00\x02\x00\ +\x04\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x5a\x00\ +\x98\x00\x03\x44\x46\x4c\x54\x00\x14\x6c\x61\x74\x6e\x00\x28\x6d\ +\x75\x73\x63\x00\x3c\x00\x04\x00\x00\x00\x00\xff\xff\x00\x05\x00\ +\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x04\x00\x00\x00\x00\xff\ +\xff\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x04\x00\ +\x00\x00\x00\xff\xff\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\ +\x04\x00\x05\x61\x61\x6c\x74\x00\x20\x63\x63\x6d\x70\x00\x26\x68\ +\x69\x73\x74\x00\x2c\x6c\x69\x67\x61\x00\x32\x73\x73\x30\x31\x00\ +\x38\x00\x00\x00\x01\x00\x01\x00\x00\x00\x01\x00\x04\x00\x00\x00\ +\x01\x00\x02\x00\x00\x00\x01\x00\x03\x00\x00\x00\x01\x00\x00\x00\ +\x05\x00\x0c\x00\x14\x00\x1c\x00\x24\x00\x2c\x00\x01\x00\x00\x00\ +\x01\x00\x28\x00\x01\x00\x00\x00\x01\x00\x2c\x00\x01\x00\x00\x00\ +\x01\x00\x42\x00\x04\x00\x00\x00\x01\x00\x52\x00\x04\x00\x08\x00\ +\x01\x01\x28\x00\x01\x00\x06\xff\x37\x00\x01\x00\x01\x00\xe4\x00\ +\x02\x00\x10\x00\x05\x00\x58\x00\x59\x00\x5a\x00\x57\x00\xe4\x00\ +\x01\x00\x05\x00\x12\x00\x13\x00\x14\x00\x16\x00\x1b\x00\x02\x00\ +\x0e\x00\x04\x00\x16\x00\x12\x00\x13\x00\x14\x00\x02\x00\x01\x00\ +\x57\x00\x5a\x00\x00\x00\x01\x00\xc8\x00\x09\x00\x18\x00\x32\x00\ +\x3c\x00\x46\x00\x50\x00\x5a\x00\x76\x00\x92\x00\xa4\x00\x03\x00\ +\x08\x00\x0e\x00\x14\x00\x1f\x00\x02\x00\x06\x00\x1e\x00\x02\x00\ +\x04\x00\x1d\x00\x02\x00\x05\x00\x01\x00\x04\x00\x08\x00\x02\x00\ +\xc3\x00\x01\x00\x04\x00\x0a\x00\x02\x00\xc5\x00\x01\x00\x04\x00\ +\x0f\x00\x02\x00\xc2\x00\x01\x00\x04\x00\x11\x00\x02\x00\x3c\x00\ +\x03\x00\x08\x00\x10\x00\x16\x00\x0f\x00\x03\x00\xc5\x00\xc2\x00\ +\x0f\x00\x02\x00\x0e\x00\x0d\x00\x02\x00\xc5\x00\x03\x00\x08\x00\ +\x10\x00\x16\x00\x08\x00\x03\x00\xc3\x00\xc3\x00\x08\x00\x02\x00\ +\x07\x00\x07\x00\x02\x00\xc3\x00\x02\x00\x06\x00\x0c\x00\x0c\x00\ +\x02\x00\xc5\x00\x0b\x00\x02\x00\xc3\x00\x04\x00\x0a\x00\x12\x00\ +\x18\x00\x1e\x00\x0a\x00\x03\x00\xc5\x00\xc5\x00\x0e\x00\x02\x00\ +\xc2\x00\x0a\x00\x02\x00\x09\x00\x09\x00\x02\x00\xc5\x00\x01\x00\ +\x09\x00\x05\x00\x07\x00\x09\x00\x0d\x00\x3d\x00\xc1\x00\xc3\x00\ +\xc4\x00\xc5\x00\x01\x00\x1a\x00\x01\x00\x08\x00\x02\x00\x06\x00\ +\x0c\x01\x13\x00\x02\x00\xd0\x01\x12\x00\x02\x00\xd1\x00\x01\x00\ +\x01\x00\xd4\x00\x01\x00\x00\x00\x0a\x00\x42\x00\x50\x00\x03\x44\ +\x46\x4c\x54\x00\x14\x6c\x61\x74\x6e\x00\x20\x6d\x75\x73\x63\x00\ +\x2c\x00\x04\x00\x00\x00\x00\xff\xff\x00\x01\x00\x00\x00\x04\x00\ +\x00\x00\x00\xff\xff\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\xff\ +\xff\x00\x01\x00\x00\x00\x01\x6b\x65\x72\x6e\x00\x08\x00\x00\x00\ +\x01\x00\x00\x00\x01\x00\x04\x00\x02\x00\x00\x00\x01\x00\x08\x00\ +\x01\x00\x7c\x00\x04\x00\x00\x00\x09\x00\x1c\x00\x2e\x00\x40\x00\ +\x2e\x00\x4e\x00\x60\x00\x60\x00\x40\x00\x72\x00\x04\x00\xd0\xfe\ +\x1e\x00\xd1\xfe\x1e\x01\x12\xfe\x1e\x01\x13\xfe\x1e\x00\x04\x00\ +\xd0\xfd\xe9\x00\xd1\xfd\xe9\x01\x12\xfd\xe9\x01\x13\xfd\xe9\x00\ +\x03\x00\xd2\xfe\x14\x00\xd3\xfd\xfc\x00\xd7\xfd\xfc\x00\x04\x00\ +\xd0\xfe\x05\x00\xd1\xfe\x05\x01\x12\xfe\x05\x01\x13\xfe\x05\x00\ +\x04\x00\xd0\xfd\xfb\x00\xd1\xfd\xfb\x01\x12\xfd\xfb\x01\x13\xfd\ +\xfb\x00\x02\x00\xd0\xfd\xe9\x00\xd1\xfd\xe9\x00\x01\x00\x09\x00\ +\xcf\x00\xd0\x00\xd1\x00\xd5\x00\xd6\x00\xd8\x00\xd9\x01\x12\x01\ +\x13\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\xc4\x3e\x8b\xee\x00\ +\x00\x00\x00\xc1\x0c\x00\x54\x00\x00\x00\x00\xc4\xa0\xef\x3b\ +\x00\x00\x03\xae\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xd8\x00\x00\x01\xd8\ +\x01\xfa\x5c\xa6\x72\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ +\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x03\x2b\x49\x44\ +\x41\x54\x58\x85\xc5\x96\xcd\x4b\xdb\x60\x1c\xc7\x13\x67\xd3\x17\ +\x74\x50\x68\x91\xc1\x0e\xc3\xe3\x84\x61\xb4\x87\xd2\x26\xc2\x60\ +\xfb\x1b\x1c\xeb\xb2\x2e\x85\xa6\xf6\xb4\x81\xa7\xc1\x04\xcb\x76\ +\x69\xbb\x31\xb0\x30\xbb\xe9\x36\xf7\xc2\x8e\x8e\x79\x55\xac\x2f\ +\xa1\x5e\x84\xa5\x35\xf4\x50\xa6\xb2\x5a\xa5\x52\xa5\x5b\x34\x6d\ +\xed\xcb\xb2\xcb\x22\x69\x9a\xd6\xa7\x1a\xba\xdf\x35\xdf\x3c\x9f\ +\x4f\x9e\xe7\x97\x5f\x02\x41\xe7\x2f\x98\xa2\xa8\xd7\x1e\x8f\xe7\ +\x03\x04\x41\x1d\x17\x58\xe7\x7c\x70\xb7\xdb\x1d\xde\xdd\xdd\xad\ +\xee\xef\xef\xff\xf1\x7a\xbd\x1f\xdb\x29\x71\x0a\xe7\x38\x4e\xe0\ +\x38\x4e\x68\xa7\x44\x1d\xbc\xad\x12\x14\x45\xbd\x52\x82\x4b\x25\ +\x46\x46\x46\xde\xb7\xb2\x26\xa8\x2d\x6c\xb5\x5a\x1d\x3c\xcf\x27\ +\x0f\x0e\x0e\x0a\x8d\x42\x87\x87\x87\x27\xb9\x5c\x2e\x85\xe3\xf8\ +\x03\xd0\xb5\x41\x42\xb0\xdb\xed\x9e\x9c\x9e\x9e\x9e\xd1\x6a\xb5\ +\xbd\x81\x40\xe0\xc9\xf6\xf6\x36\x2f\x0f\xa5\xd3\xe9\xa2\xcf\xe7\ +\x0b\x18\x0c\x06\x43\x38\x1c\x9e\xf2\x7a\xbd\x33\xa0\x12\x67\xc1\ +\x4f\xcf\x3c\x95\x4a\x55\x5c\x2e\xd7\x84\xc3\xe1\x78\x14\x8b\xc5\ +\x8e\xc5\xad\x4f\x24\x12\x85\xe1\xe1\x61\x1f\x49\x92\xc1\xad\xad\ +\xad\x92\x5a\x3d\xa1\xd8\x70\x72\x09\x25\x78\x2b\x8d\x79\xa9\x09\ +\x7c\x72\x7c\x7c\xdc\xdd\xdd\xdd\x5d\x73\xb3\x4e\xa7\xeb\xb0\x5a\ +\xad\x16\x9a\xa6\x7f\xac\xae\xae\x7e\x5d\x5b\x5b\x8b\x22\x08\x72\ +\x79\x6c\x6c\xec\xa1\xc9\x64\xd2\x48\xb3\x1a\x8d\x06\xc6\x30\xec\ +\x06\xcf\xf3\xbd\xeb\xeb\xeb\xdf\x20\x08\x12\x80\x1e\x1d\xc7\xf1\ +\x3b\x0c\xc3\x9c\x34\xea\x76\x8e\xe3\x04\x9a\xa6\x8f\x2d\x16\xcb\ +\x6d\x14\x45\x87\x16\x17\x17\x7f\x37\xcb\x6e\x6c\x6c\x94\x30\x0c\ +\xbb\x0f\xbc\x03\xa9\x54\x8a\x2d\x14\x0a\xda\x81\x81\x01\x6b\x57\ +\x57\x57\x5d\x26\x9d\x4e\x17\x03\x81\xc0\xf3\xf9\xf9\xf9\xb7\x99\ +\x4c\xe6\x67\xa5\x52\x29\xf6\xf5\xf5\xe1\x46\xa3\x11\x91\x67\xb3\ +\xd9\x6c\xd9\xef\xf7\xbf\x9c\x9b\x9b\x7b\x01\xf4\xf4\xd2\x72\x3a\ +\x9d\x4f\x93\xc9\x64\xcd\x4e\x88\x67\x2e\xcf\xca\x1b\x93\xe3\x38\ +\x61\x73\x73\xb3\x44\x92\xa4\xbf\x65\x70\x23\x89\x46\x70\x25\x09\ +\x55\xe0\x52\x89\x48\x24\xc2\x35\x83\x4b\x25\x16\x16\x16\x7e\xa9\ +\x06\x17\x0b\x45\xd1\x5b\xa0\xd9\xfe\xfe\x7e\x3b\x68\x16\x78\x48\ +\x74\x76\x76\x96\x41\xb3\x30\x0c\xeb\x41\xb3\x40\x45\x92\x64\x70\ +\x79\x79\xf9\xc8\xe9\x74\x3e\x3e\x2b\x4b\x10\xc4\xe8\xca\xca\xca\ +\x91\xcb\xe5\x9a\x50\x0d\x2e\x4e\xb8\x44\x22\x91\x6f\x26\x41\x10\ +\xc4\x28\xcb\xb2\xc7\xd2\x89\xa9\x1a\x5c\xf2\x1a\x2a\x4a\x48\xe1\ +\xf2\xb1\xad\x1a\xbc\x91\x84\x12\xfc\x42\x12\x76\xbb\xdd\xc9\xb2\ +\x6c\xb9\xd9\x78\x8d\x44\x22\x1c\x8a\xa2\x43\x83\x83\x83\x37\x97\ +\x96\x96\x8e\x9a\x65\xe3\xf1\x78\x09\xc3\x30\x42\x89\xa5\x38\x8a\ +\x77\x76\x76\xe2\xd5\x6a\xf5\xaa\xcd\x66\x43\x11\x04\x81\xe5\xd7\ +\xb3\xd9\x6c\x39\x14\x0a\x85\x7a\x7a\x7a\xcc\x66\xb3\xf9\x0a\xc3\ +\x30\xdf\x1b\x8d\xed\x7c\x3e\x2f\x04\x83\xc1\x4f\xb3\xb3\xb3\xcf\ +\x20\xd0\x8f\xd1\xbf\x82\x3d\x1e\xcf\x9b\xbd\xbd\xbd\x9a\xcf\xb1\ +\x38\xe1\xc4\x6d\x17\x8f\x43\x69\x6c\x67\x32\x19\xf1\x17\xed\xfc\ +\xff\x04\x52\x09\x39\x5c\xde\x13\x52\x09\x35\xe0\x35\x12\xb1\x58\ +\xec\x44\x09\xae\x24\xc1\x30\x4c\x51\x2d\xf8\xa9\x84\xcd\x66\xbb\ +\xd7\xac\xdb\xa5\x12\x18\x86\xdd\x85\x20\xa8\xae\x77\x94\x0a\xd4\ +\x50\x88\x46\xa3\x9f\xf5\x7a\xfd\x75\x93\xc9\x64\x68\x14\x32\x1a\ +\x8d\x3a\xad\x56\x7b\x8d\xa6\xe9\x2f\x50\x8b\x0d\x07\x5a\x8a\x8d\ +\xa9\xf6\x99\xb7\x2c\xd1\x4e\x78\x9d\xc4\xff\x80\x4b\x25\xde\x51\ +\x14\x35\x05\x01\x36\x9c\x52\xfd\x05\xed\x5a\xa6\x43\x90\x43\xd4\ +\xd6\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x0a\xb1\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x34\x33\x35\x30\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x31\x32\x38\x69\x2e\x73\ +\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x34\x33\x35\x38\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ +\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ +\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ +\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ +\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ +\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\ +\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\ +\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\ +\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ +\x34\x33\x35\x36\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ +\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ +\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ +\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\ +\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\ +\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\ +\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\ +\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x32\ +\x30\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x34\x33\x35\x34\x22\x0a\x20\x20\x20\ +\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x7a\x6f\x6f\x6d\x3d\x22\x34\x32\x2e\x37\x32\x30\x35\x36\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x78\x3d\x22\x31\x35\x2e\x36\x31\x35\x38\x30\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\ +\x22\x39\x38\x39\x2e\x34\x39\x35\x31\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\ +\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ +\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ +\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x34\x33\x35\x30\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\ +\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\ +\x2e\x75\x37\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x30\ +\x2e\x30\x32\x32\x39\x37\x38\x30\x33\x2c\x31\x39\x2e\x32\x31\x38\ +\x30\x33\x31\x20\x30\x2c\x2d\x30\x2e\x34\x37\x35\x20\x63\x20\x30\ +\x2c\x2d\x32\x2e\x38\x35\x20\x32\x2e\x31\x37\x34\x39\x39\x39\x39\ +\x37\x2c\x2d\x35\x20\x33\x2e\x36\x37\x34\x39\x39\x39\x39\x37\x2c\ +\x2d\x37\x2e\x33\x37\x35\x20\x30\x2e\x31\x2c\x30\x2e\x34\x20\x30\ +\x2e\x31\x35\x2c\x30\x2e\x38\x32\x35\x20\x30\x2e\x31\x35\x2c\x31\ +\x2e\x32\x32\x35\x20\x30\x2c\x32\x2e\x34\x32\x35\x20\x2d\x32\x2e\ +\x31\x37\x35\x2c\x34\x2e\x38\x35\x20\x2d\x33\x2e\x38\x32\x34\x39\ +\x39\x39\x39\x37\x2c\x36\x2e\x36\x32\x35\x20\x7a\x20\x6d\x20\x30\ +\x2c\x35\x2e\x33\x32\x35\x20\x63\x20\x30\x2c\x2d\x34\x2e\x34\x35\ +\x20\x34\x2e\x37\x39\x39\x39\x39\x39\x39\x37\x2c\x2d\x37\x2e\x35\ +\x20\x34\x2e\x37\x39\x39\x39\x39\x39\x39\x37\x2c\x2d\x31\x31\x2e\ +\x39\x35\x20\x30\x2c\x2d\x30\x2e\x38\x32\x35\x20\x2d\x30\x2e\x31\ +\x35\x2c\x2d\x31\x2e\x36\x32\x35\x20\x2d\x30\x2e\x34\x35\x2c\x2d\ +\x32\x2e\x34\x20\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x39\x30\x30\ +\x30\x30\x30\x34\x20\x30\x2e\x37\x2c\x2d\x31\x2e\x38\x32\x35\x30\ +\x30\x30\x34\x20\x30\x2e\x37\x2c\x2d\x32\x2e\x38\x35\x20\x30\x2c\ +\x2d\x31\x2e\x30\x32\x35\x20\x2d\x30\x2e\x32\x35\x2c\x2d\x32\x2e\ +\x30\x34\x39\x39\x39\x39\x36\x20\x2d\x30\x2e\x37\x2c\x2d\x32\x2e\ +\x39\x37\x34\x39\x39\x39\x36\x20\x30\x2e\x34\x32\x35\x2c\x2d\x30\ +\x2e\x38\x37\x35\x20\x30\x2e\x37\x2c\x2d\x31\x2e\x38\x30\x30\x30\ +\x30\x30\x34\x20\x30\x2e\x37\x2c\x2d\x32\x2e\x38\x32\x35\x30\x30\ +\x30\x34\x20\x30\x2c\x2d\x31\x2e\x30\x32\x35\x30\x30\x30\x30\x32\ +\x20\x2d\x30\x2e\x32\x35\x2c\x2d\x32\x2e\x30\x35\x30\x30\x30\x30\ +\x30\x32\x20\x2d\x30\x2e\x37\x2c\x2d\x32\x2e\x39\x37\x35\x20\x30\ +\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x38\x37\x35\x20\x30\x2e\x37\x2c\ +\x2d\x31\x2e\x38\x32\x35\x20\x30\x2e\x37\x2c\x2d\x32\x2e\x38\x35\ +\x20\x30\x2c\x2d\x30\x2e\x38\x37\x35\x20\x2d\x30\x2e\x33\x32\x35\ +\x2c\x2d\x31\x2e\x37\x32\x35\x20\x2d\x30\x2e\x38\x35\x2c\x2d\x32\ +\x2e\x34\x32\x35\x20\x30\x2e\x36\x2c\x2d\x31\x2e\x30\x35\x20\x31\ +\x2e\x30\x32\x35\x2c\x2d\x32\x2e\x31\x32\x35\x20\x31\x2e\x30\x32\ +\x35\x2c\x2d\x33\x2e\x33\x37\x35\x20\x30\x2c\x2d\x31\x2e\x35\x32\ +\x35\x20\x2d\x30\x2e\x34\x2c\x2d\x33\x2e\x30\x32\x35\x20\x2d\x31\ +\x2e\x30\x35\x2c\x2d\x34\x2e\x34\x32\x35\x20\x2d\x30\x2e\x31\x2c\ +\x2d\x30\x2e\x31\x37\x35\x20\x2d\x30\x2e\x32\x37\x35\x2c\x2d\x30\ +\x2e\x32\x37\x35\x20\x2d\x30\x2e\x34\x35\x2c\x2d\x30\x2e\x32\x37\ +\x35\x20\x2d\x30\x2e\x33\x2c\x30\x20\x2d\x30\x2e\x36\x2c\x30\x2e\ +\x32\x35\x20\x2d\x30\x2e\x35\x32\x35\x2c\x30\x2e\x36\x32\x35\x20\ +\x30\x2e\x36\x35\x2c\x31\x2e\x32\x37\x35\x20\x31\x2e\x30\x35\x2c\ +\x32\x2e\x36\x35\x20\x31\x2e\x30\x35\x2c\x34\x2e\x30\x37\x35\x20\ +\x30\x2c\x32\x2e\x33\x37\x35\x20\x2d\x32\x2e\x34\x32\x35\x2c\x34\ +\x2e\x35\x35\x20\x2d\x34\x2e\x32\x34\x39\x39\x39\x39\x39\x37\x2c\ +\x36\x2e\x30\x37\x35\x20\x6c\x20\x30\x2c\x2d\x32\x2e\x37\x20\x2d\ +\x30\x2e\x33\x35\x2c\x30\x20\x30\x2c\x33\x31\x2e\x32\x35\x20\x30\ +\x2e\x33\x35\x2c\x30\x20\x7a\x20\x6d\x20\x30\x2c\x2d\x31\x31\x2e\ +\x31\x32\x35\x20\x30\x2c\x2d\x30\x2e\x35\x20\x63\x20\x30\x2c\x2d\ +\x32\x2e\x38\x37\x35\x20\x32\x2e\x32\x32\x34\x39\x39\x39\x39\x37\ +\x2c\x2d\x35\x2e\x30\x35\x20\x33\x2e\x37\x32\x34\x39\x39\x39\x39\ +\x37\x2c\x2d\x37\x2e\x34\x34\x39\x39\x39\x39\x36\x20\x30\x2e\x32\ +\x32\x35\x2c\x30\x2e\x35\x39\x39\x39\x39\x39\x36\x20\x30\x2e\x33\ +\x35\x2c\x31\x2e\x32\x32\x34\x39\x39\x39\x36\x20\x30\x2e\x33\x35\ +\x2c\x31\x2e\x38\x37\x34\x39\x39\x39\x36\x20\x30\x2c\x32\x2e\x33\ +\x32\x34\x39\x39\x39\x36\x20\x2d\x32\x2e\x33\x32\x35\x2c\x34\x2e\ +\x35\x32\x35\x20\x2d\x34\x2e\x30\x37\x34\x39\x39\x39\x39\x37\x2c\ +\x36\x2e\x30\x37\x35\x20\x7a\x20\x6d\x20\x30\x2c\x2d\x35\x2e\x38\ +\x20\x30\x2c\x2d\x30\x2e\x35\x20\x63\x20\x30\x2c\x2d\x32\x2e\x38\ +\x37\x34\x39\x39\x39\x36\x20\x32\x2e\x32\x32\x34\x39\x39\x39\x39\ +\x37\x2c\x2d\x35\x2e\x30\x35\x20\x33\x2e\x37\x32\x34\x39\x39\x39\ +\x39\x37\x2c\x2d\x37\x2e\x34\x35\x30\x30\x30\x30\x30\x32\x20\x30\ +\x2e\x32\x32\x35\x2c\x30\x2e\x36\x20\x30\x2e\x33\x35\x2c\x31\x2e\ +\x32\x32\x35\x20\x30\x2e\x33\x35\x2c\x31\x2e\x38\x37\x35\x30\x30\ +\x30\x30\x32\x20\x30\x2c\x32\x2e\x33\x32\x35\x30\x30\x30\x34\x20\ +\x2d\x32\x2e\x33\x32\x35\x2c\x34\x2e\x35\x32\x35\x20\x2d\x34\x2e\ +\x30\x37\x34\x39\x39\x39\x39\x37\x2c\x36\x2e\x30\x37\x35\x20\x7a\ +\x20\x6d\x20\x30\x2c\x2d\x35\x2e\x38\x32\x35\x20\x30\x2c\x2d\x30\ +\x2e\x35\x20\x63\x20\x30\x2c\x2d\x32\x2e\x37\x37\x35\x20\x32\x2e\ +\x30\x39\x39\x39\x39\x39\x39\x37\x2c\x2d\x34\x2e\x38\x35\x20\x33\ +\x2e\x36\x32\x34\x39\x39\x39\x39\x37\x2c\x2d\x37\x2e\x31\x32\x35\ +\x20\x30\x2e\x32\x37\x35\x2c\x30\x2e\x34\x37\x35\x20\x30\x2e\x34\ +\x35\x2c\x31\x20\x30\x2e\x34\x35\x2c\x31\x2e\x35\x35\x20\x30\x2c\ +\x32\x2e\x33\x32\x35\x20\x2d\x32\x2e\x33\x32\x35\x2c\x34\x2e\x35\ +\x32\x34\x39\x39\x39\x39\x38\x20\x2d\x34\x2e\x30\x37\x34\x39\x39\ +\x39\x39\x37\x2c\x36\x2e\x30\x37\x35\x20\x7a\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x34\x33\x35\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\ +\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\ +\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\ +\x00\x00\x10\x83\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x31\x37\x39\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\ +\x72\x31\x33\x37\x32\x35\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x65\ +\x66\x54\x72\x65\x62\x6c\x65\x5f\x38\x2e\x73\x76\x67\x22\x3e\x0a\ +\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\ +\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\ +\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\ +\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ +\x69\x67\x68\x74\x3d\x22\x32\x30\x39\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x32\x39\ +\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x34\x2e\ +\x38\x30\x38\x33\x32\x36\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x33\x32\x2e\x36\x34\ +\x32\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x79\x3d\x22\x39\x36\x35\x2e\x31\x38\x38\x30\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\ +\x31\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x33\x31\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ +\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ +\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ +\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\ +\x65\x66\x73\x33\x31\x38\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\ +\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x36\x2e\ +\x33\x35\x2c\x2d\x37\x2e\x35\x30\x37\x30\x38\x32\x34\x20\x43\x20\ +\x35\x2e\x35\x2c\x2d\x31\x30\x2e\x34\x35\x37\x30\x38\x32\x20\x35\ +\x2c\x2d\x31\x33\x2e\x32\x38\x32\x30\x38\x32\x20\x35\x2c\x2d\x31\ +\x36\x2e\x39\x38\x32\x30\x38\x32\x20\x63\x20\x30\x2c\x2d\x33\x20\ +\x31\x2e\x34\x2c\x2d\x35\x2e\x38\x20\x33\x2e\x37\x37\x35\x2c\x2d\ +\x37\x2e\x36\x32\x35\x20\x30\x2e\x30\x35\x2c\x2d\x30\x2e\x30\x35\ +\x20\x30\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x30\x37\x35\x20\x30\x2e\ +\x32\x2c\x2d\x30\x2e\x30\x37\x35\x20\x30\x2e\x30\x37\x35\x2c\x30\ +\x20\x30\x2e\x31\x35\x2c\x30\x2e\x30\x32\x35\x20\x30\x2e\x32\x2c\ +\x30\x2e\x30\x37\x35\x20\x31\x2e\x39\x2c\x32\x2e\x32\x35\x20\x33\ +\x2e\x35\x37\x35\x2c\x36\x2e\x36\x20\x33\x2e\x35\x37\x35\x2c\x39\ +\x2e\x36\x32\x35\x20\x30\x2c\x33\x2e\x37\x35\x20\x2d\x32\x2e\x32\ +\x35\x2c\x36\x2e\x36\x37\x34\x39\x39\x39\x36\x20\x2d\x34\x2e\x37\ +\x35\x2c\x39\x2e\x34\x39\x39\x39\x39\x39\x36\x20\x30\x2e\x35\x35\ +\x2c\x31\x2e\x38\x32\x34\x39\x39\x39\x39\x20\x31\x2e\x30\x35\x2c\ +\x33\x2e\x36\x37\x34\x39\x39\x39\x39\x20\x31\x2e\x35\x32\x35\x2c\ +\x35\x2e\x35\x32\x34\x39\x39\x39\x39\x20\x68\x20\x30\x2e\x31\x35\ +\x20\x63\x20\x33\x2e\x38\x35\x2c\x30\x20\x36\x2e\x33\x35\x2c\x33\ +\x2e\x31\x37\x35\x20\x36\x2e\x33\x35\x2c\x36\x2e\x34\x37\x35\x30\ +\x30\x30\x31\x20\x30\x2c\x31\x2e\x38\x39\x39\x39\x39\x39\x39\x20\ +\x2d\x30\x2e\x38\x32\x35\x2c\x33\x2e\x38\x32\x35\x30\x30\x30\x34\ +\x20\x2d\x32\x2e\x36\x37\x35\x2c\x35\x2e\x32\x30\x30\x30\x30\x30\ +\x34\x20\x2d\x30\x2e\x36\x32\x35\x2c\x30\x2e\x34\x37\x35\x20\x2d\ +\x31\x2e\x33\x32\x35\x2c\x30\x2e\x38\x20\x2d\x32\x2e\x30\x37\x35\ +\x2c\x31\x20\x30\x2c\x30\x2e\x33\x32\x35\x20\x30\x2e\x30\x32\x35\ +\x2c\x30\x2e\x36\x37\x35\x20\x30\x2e\x30\x32\x35\x2c\x31\x20\x30\ +\x2c\x31\x2e\x31\x35\x20\x2d\x30\x2e\x30\x32\x35\x2c\x32\x2e\x33\ +\x20\x2d\x30\x2e\x31\x2c\x33\x2e\x34\x35\x20\x2d\x30\x2e\x31\x37\ +\x35\x2c\x33\x2e\x30\x32\x35\x20\x2d\x32\x2e\x33\x35\x2c\x35\x2e\ +\x36\x37\x35\x20\x2d\x35\x2e\x33\x35\x2c\x35\x2e\x36\x37\x35\x20\ +\x2d\x32\x2e\x37\x37\x35\x2c\x30\x20\x2d\x35\x2e\x30\x35\x2c\x2d\ +\x32\x2e\x33\x20\x2d\x35\x2e\x30\x35\x2c\x2d\x35\x2e\x31\x32\x35\ +\x20\x30\x2c\x2d\x31\x2e\x34\x35\x20\x31\x2e\x33\x35\x2c\x2d\x32\ +\x2e\x36\x20\x32\x2e\x38\x32\x35\x2c\x2d\x32\x2e\x36\x20\x31\x2e\ +\x33\x35\x2c\x30\x20\x32\x2e\x33\x37\x35\x2c\x31\x2e\x32\x20\x32\ +\x2e\x33\x37\x35\x2c\x32\x2e\x36\x20\x30\x2c\x31\x2e\x33\x20\x2d\ +\x31\x2e\x30\x37\x35\x2c\x32\x2e\x33\x37\x35\x20\x2d\x32\x2e\x33\ +\x37\x35\x2c\x32\x2e\x33\x37\x35\x20\x2d\x30\x2e\x33\x32\x35\x2c\ +\x30\x20\x2d\x30\x2e\x36\x37\x35\x2c\x2d\x30\x2e\x31\x20\x2d\x30\ +\x2e\x39\x37\x35\x2c\x2d\x30\x2e\x32\x35\x20\x30\x2e\x36\x35\x2c\ +\x31\x2e\x31\x37\x35\x20\x31\x2e\x38\x35\x2c\x32\x20\x33\x2e\x32\ +\x35\x2c\x32\x20\x32\x2e\x34\x37\x35\x2c\x30\x20\x34\x2e\x31\x35\ +\x2c\x2d\x32\x2e\x33\x20\x34\x2e\x33\x2c\x2d\x34\x2e\x38\x32\x35\ +\x20\x30\x2e\x30\x37\x35\x2c\x2d\x31\x2e\x31\x20\x30\x2e\x31\x2c\ +\x2d\x32\x2e\x32\x32\x35\x20\x30\x2e\x31\x2c\x2d\x33\x2e\x33\x32\ +\x35\x20\x76\x20\x2d\x30\x2e\x37\x37\x35\x20\x63\x20\x2d\x30\x2e\ +\x36\x35\x2c\x30\x2e\x31\x20\x2d\x31\x2e\x33\x2c\x30\x2e\x31\x35\ +\x20\x2d\x31\x2e\x39\x37\x35\x2c\x30\x2e\x31\x35\x20\x2d\x34\x2e\ +\x37\x2c\x30\x20\x2d\x38\x2e\x33\x32\x35\x2c\x2d\x34\x2e\x32\x37\ +\x35\x30\x30\x30\x35\x20\x2d\x38\x2e\x33\x32\x35\x2c\x2d\x39\x2e\ +\x33\x30\x30\x30\x30\x30\x35\x20\x30\x2c\x2d\x34\x2e\x35\x32\x35\ +\x20\x33\x2e\x33\x35\x2c\x2d\x37\x2e\x38\x34\x39\x39\x39\x39\x39\ +\x20\x36\x2e\x33\x35\x2c\x2d\x31\x31\x2e\x32\x37\x34\x39\x39\x39\ +\x39\x20\x7a\x20\x6d\x20\x34\x2e\x39\x2c\x31\x39\x2e\x32\x35\x30\ +\x30\x30\x30\x34\x20\x63\x20\x31\x2e\x38\x32\x35\x2c\x2d\x30\x2e\ +\x35\x35\x20\x33\x2e\x31\x2c\x2d\x32\x2e\x34\x32\x35\x30\x30\x30\ +\x35\x20\x33\x2e\x31\x2c\x2d\x34\x2e\x32\x35\x30\x30\x30\x30\x35\ +\x20\x30\x2c\x2d\x32\x2e\x32\x34\x39\x39\x39\x39\x39\x20\x2d\x31\ +\x2e\x36\x2c\x2d\x34\x2e\x34\x35\x20\x2d\x34\x2e\x32\x2c\x2d\x34\ +\x2e\x38\x20\x30\x2e\x35\x37\x35\x2c\x32\x2e\x37\x35\x30\x30\x30\ +\x30\x31\x20\x31\x2c\x35\x2e\x39\x37\x35\x20\x31\x2e\x31\x2c\x39\ +\x2e\x30\x35\x30\x30\x30\x30\x35\x20\x7a\x20\x6d\x20\x2d\x32\x2e\ +\x38\x35\x2c\x30\x2e\x33\x32\x35\x20\x63\x20\x30\x2e\x36\x32\x35\ +\x2c\x30\x20\x31\x2e\x32\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x31\ +\x2e\x38\x37\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x43\x20\x31\x30\ +\x2e\x31\x37\x35\x2c\x38\x2e\x37\x36\x37\x39\x31\x37\x35\x20\x39\ +\x2e\x37\x2c\x35\x2e\x34\x36\x37\x39\x31\x37\x36\x20\x39\x2e\x31\ +\x2c\x32\x2e\x36\x34\x32\x39\x31\x37\x35\x20\x63\x20\x2d\x32\x2e\ +\x31\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\x2d\x33\x2e\x34\x2c\x31\ +\x2e\x35\x35\x20\x2d\x33\x2e\x34\x2c\x33\x2e\x31\x30\x30\x30\x30\ +\x30\x31\x20\x30\x2c\x31\x2e\x31\x32\x35\x20\x30\x2e\x36\x35\x2c\ +\x32\x2e\x32\x39\x39\x39\x39\x39\x39\x20\x32\x2e\x30\x37\x35\x2c\ +\x33\x2e\x31\x32\x34\x39\x39\x39\x39\x20\x30\x2e\x31\x2c\x30\x2e\ +\x31\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\x32\x32\x35\x20\x30\x2e\ +\x31\x37\x35\x2c\x30\x2e\x33\x35\x20\x30\x2c\x30\x2e\x32\x37\x35\ +\x20\x2d\x30\x2e\x32\x32\x35\x2c\x30\x2e\x35\x32\x35\x20\x2d\x30\ +\x2e\x35\x2c\x30\x2e\x35\x32\x35\x20\x2d\x30\x2e\x30\x37\x35\x2c\ +\x30\x20\x2d\x30\x2e\x31\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x2d\ +\x30\x2e\x32\x32\x35\x2c\x2d\x30\x2e\x30\x35\x20\x2d\x32\x2c\x2d\ +\x31\x2e\x30\x37\x35\x20\x2d\x32\x2e\x39\x2c\x2d\x32\x2e\x38\x34\ +\x39\x39\x39\x39\x39\x20\x2d\x32\x2e\x39\x2c\x2d\x34\x2e\x36\x20\ +\x30\x2c\x2d\x32\x2e\x32\x35\x20\x31\x2e\x35\x32\x35\x2c\x2d\x34\ +\x2e\x34\x35\x20\x34\x2e\x32\x2c\x2d\x34\x2e\x39\x35\x20\x2d\x30\ +\x2e\x34\x2c\x2d\x31\x2e\x36\x20\x2d\x30\x2e\x38\x37\x35\x2c\x2d\ +\x33\x2e\x31\x37\x35\x20\x2d\x31\x2e\x33\x32\x35\x2c\x2d\x34\x2e\ +\x37\x34\x39\x39\x39\x39\x39\x20\x2d\x32\x2e\x37\x35\x2c\x33\x2e\ +\x30\x39\x39\x39\x39\x39\x39\x20\x2d\x35\x2e\x35\x2c\x36\x2e\x32\ +\x32\x34\x39\x39\x39\x39\x20\x2d\x35\x2e\x35\x2c\x31\x30\x2e\x33\ +\x35\x20\x30\x2c\x33\x2e\x34\x34\x39\x39\x39\x39\x39\x20\x33\x2e\ +\x32\x37\x35\x2c\x36\x2e\x33\x32\x35\x30\x30\x30\x34\x20\x36\x2e\ +\x37\x2c\x36\x2e\x33\x32\x35\x30\x30\x30\x34\x20\x7a\x20\x6d\x20\ +\x31\x2e\x37\x37\x35\x2c\x2d\x33\x33\x2e\x32\x20\x63\x20\x2d\x32\ +\x2e\x35\x2c\x31\x2e\x33\x37\x35\x20\x2d\x34\x2e\x30\x35\x2c\x33\ +\x2e\x39\x37\x35\x20\x2d\x34\x2e\x30\x35\x2c\x36\x2e\x38\x32\x35\ +\x20\x30\x2c\x32\x2e\x32\x35\x20\x30\x2e\x34\x37\x35\x2c\x34\x2e\ +\x30\x35\x20\x31\x2c\x35\x2e\x38\x39\x39\x39\x39\x39\x36\x20\x32\ +\x2e\x31\x35\x2c\x2d\x32\x2e\x35\x34\x39\x39\x39\x39\x36\x20\x33\ +\x2e\x39\x35\x2c\x2d\x35\x2e\x32\x32\x34\x39\x39\x39\x36\x20\x33\ +\x2e\x39\x35\x2c\x2d\x38\x2e\x35\x34\x39\x39\x39\x39\x36\x20\x30\ +\x2c\x2d\x31\x2e\x38\x32\x35\x20\x2d\x30\x2e\x32\x2c\x2d\x32\x2e\ +\x35\x37\x35\x20\x2d\x30\x2e\x39\x2c\x2d\x34\x2e\x31\x37\x35\x20\ +\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x33\x31\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\ +\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x65\x69\x67\x68\x74\x22\x0a\x20\ +\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x39\x2e\x38\x34\x35\x34\x36\ +\x31\x31\x2c\x32\x38\x2e\x33\x31\x36\x37\x32\x20\x63\x20\x30\x2e\ +\x35\x34\x36\x32\x37\x30\x39\x2c\x2d\x30\x2e\x35\x36\x35\x31\x30\ +\x38\x20\x31\x2e\x30\x31\x37\x31\x39\x33\x39\x2c\x2d\x31\x2e\x31\ +\x36\x37\x38\x38\x39\x20\x31\x2e\x30\x31\x37\x31\x39\x33\x39\x2c\ +\x2d\x31\x2e\x39\x34\x30\x32\x30\x33\x20\x30\x2c\x2d\x31\x2e\x30\ +\x35\x34\x38\x36\x38\x20\x2d\x31\x2e\x30\x39\x32\x35\x34\x31\x39\ +\x2c\x2d\x31\x2e\x37\x31\x34\x31\x36\x31\x20\x2d\x32\x2e\x32\x34\ +\x31\x35\x39\x34\x31\x2c\x2d\x31\x2e\x37\x31\x34\x31\x36\x31\x20\ +\x2d\x30\x2e\x39\x32\x33\x30\x31\x2c\x30\x20\x2d\x31\x2e\x34\x36\ +\x39\x32\x38\x31\x2c\x30\x2e\x37\x31\x35\x38\x30\x34\x20\x2d\x31\ +\x2e\x34\x36\x39\x32\x38\x31\x2c\x31\x2e\x34\x31\x32\x37\x37\x20\ +\x30\x2c\x30\x2e\x34\x31\x34\x34\x31\x32\x20\x30\x2e\x31\x36\x39\ +\x35\x33\x33\x2c\x30\x2e\x37\x39\x31\x31\x35\x31\x20\x30\x2e\x35\ +\x38\x33\x39\x34\x35\x2c\x31\x2e\x30\x33\x36\x30\x33\x31\x20\x7a\ +\x20\x6d\x20\x30\x2e\x35\x30\x38\x35\x39\x36\x39\x2c\x30\x2e\x33\ +\x30\x31\x33\x39\x31\x20\x63\x20\x31\x2e\x30\x33\x36\x30\x33\x31\ +\x2c\x30\x2e\x36\x30\x32\x37\x38\x32\x20\x31\x2e\x36\x30\x31\x31\ +\x33\x38\x2c\x31\x2e\x34\x36\x39\x32\x38\x20\x31\x2e\x36\x30\x31\ +\x31\x33\x38\x2c\x32\x2e\x33\x39\x32\x32\x39\x20\x30\x2c\x31\x2e\ +\x33\x35\x36\x32\x35\x38\x20\x2d\x31\x2e\x32\x32\x34\x34\x2c\x32\ +\x2e\x36\x37\x34\x38\x34\x33\x20\x2d\x33\x2e\x34\x38\x34\x38\x33\ +\x31\x31\x2c\x32\x2e\x36\x37\x34\x38\x34\x33\x20\x2d\x31\x2e\x37\ +\x33\x32\x39\x39\x37\x2c\x30\x20\x2d\x33\x2e\x33\x37\x31\x38\x31\ +\x2c\x2d\x30\x2e\x39\x39\x38\x33\x35\x37\x20\x2d\x33\x2e\x33\x37\ +\x31\x38\x31\x2c\x2d\x32\x2e\x35\x39\x39\x34\x39\x36\x20\x30\x2c\ +\x2d\x30\x2e\x39\x36\x30\x36\x38\x33\x20\x30\x2e\x37\x35\x33\x34\ +\x37\x37\x2c\x2d\x31\x2e\x36\x31\x39\x39\x37\x35\x20\x31\x2e\x34\ +\x36\x39\x32\x38\x31\x2c\x2d\x32\x2e\x32\x37\x39\x32\x36\x38\x20\ +\x2d\x30\x2e\x38\x32\x38\x38\x32\x35\x2c\x2d\x30\x2e\x35\x32\x37\ +\x34\x33\x34\x20\x2d\x31\x2e\x32\x30\x35\x35\x36\x34\x2c\x2d\x31\ +\x2e\x32\x39\x39\x37\x34\x38\x20\x2d\x31\x2e\x32\x30\x35\x35\x36\ +\x34\x2c\x2d\x32\x2e\x30\x35\x33\x32\x32\x35\x20\x30\x2c\x2d\x31\ +\x2e\x32\x36\x32\x30\x37\x34\x20\x31\x2e\x31\x33\x30\x32\x31\x36\ +\x2c\x2d\x32\x2e\x34\x38\x36\x34\x37\x34\x20\x33\x2e\x32\x35\x38\ +\x37\x38\x39\x2c\x2d\x32\x2e\x34\x38\x36\x34\x37\x34\x20\x31\x2e\ +\x35\x30\x36\x39\x35\x34\x31\x2c\x30\x20\x32\x2e\x39\x37\x36\x32\ +\x33\x34\x31\x2c\x30\x2e\x37\x35\x33\x34\x37\x37\x20\x32\x2e\x39\ +\x37\x36\x32\x33\x34\x31\x2c\x32\x2e\x31\x30\x39\x37\x33\x36\x20\ +\x30\x2c\x30\x2e\x39\x30\x34\x31\x37\x32\x20\x2d\x30\x2e\x36\x30\ +\x32\x37\x38\x32\x2c\x31\x2e\x35\x38\x32\x33\x30\x31\x20\x2d\x31\ +\x2e\x32\x34\x33\x32\x33\x37\x2c\x32\x2e\x32\x34\x31\x35\x39\x34\ +\x20\x7a\x20\x6d\x20\x2d\x33\x2e\x32\x35\x38\x37\x38\x38\x31\x2c\ +\x30\x2e\x34\x38\x39\x37\x36\x20\x63\x20\x2d\x30\x2e\x36\x34\x30\ +\x34\x35\x36\x2c\x30\x2e\x35\x36\x35\x31\x30\x38\x20\x2d\x31\x2e\ +\x32\x34\x33\x32\x33\x38\x2c\x31\x2e\x31\x34\x39\x30\x35\x33\x20\ +\x2d\x31\x2e\x32\x34\x33\x32\x33\x38\x2c\x31\x2e\x39\x37\x37\x38\ +\x37\x37\x20\x30\x2c\x31\x2e\x32\x39\x39\x37\x34\x38\x20\x31\x2e\ +\x32\x34\x33\x32\x33\x38\x2c\x32\x2e\x32\x30\x33\x39\x32\x31\x20\ +\x32\x2e\x36\x31\x38\x33\x33\x33\x2c\x32\x2e\x32\x30\x33\x39\x32\ +\x31\x20\x31\x2e\x30\x33\x36\x30\x33\x31\x32\x2c\x30\x20\x31\x2e\ +\x36\x35\x37\x36\x35\x30\x31\x2c\x2d\x30\x2e\x38\x30\x39\x39\x38\ +\x38\x20\x31\x2e\x36\x35\x37\x36\x35\x30\x31\x2c\x2d\x31\x2e\x36\ +\x30\x31\x31\x33\x39\x20\x30\x2c\x2d\x30\x2e\x34\x37\x30\x39\x32\ +\x33\x20\x2d\x30\x2e\x32\x30\x37\x32\x30\x35\x39\x2c\x2d\x30\x2e\ +\x39\x36\x30\x36\x38\x33\x20\x2d\x30\x2e\x36\x39\x36\x39\x36\x36\ +\x39\x2c\x2d\x31\x2e\x32\x34\x33\x32\x33\x37\x20\x7a\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x37\x32\x38\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ +\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\ +\x3e\x0a\ +\x00\x00\x0a\xe8\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x34\x33\x34\x30\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x31\x32\x38\x2e\x73\x76\ +\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x34\x33\x34\x38\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\ +\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\ +\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\ +\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x34\ +\x33\x34\x36\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\ +\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ +\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\ +\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\ +\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\ +\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x34\x33\x34\x34\x22\x0a\x20\x20\x20\x20\ +\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x7a\x6f\x6f\x6d\x3d\x22\x31\x35\x2e\x31\x30\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ +\x31\x36\x2e\x32\x36\x30\x36\x37\x39\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x39\x39\x36\ +\x2e\x37\x33\x36\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x33\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\ +\x76\x67\x34\x33\x34\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\ +\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\ +\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\x2e\x64\x37\x22\x0a\x20\x20\ +\x20\x20\x20\x64\x3d\x22\x6d\x20\x36\x2e\x36\x37\x37\x37\x35\x34\ +\x32\x2c\x32\x31\x2e\x35\x39\x37\x37\x37\x35\x20\x63\x20\x30\x2c\ +\x2d\x30\x2e\x36\x37\x35\x20\x2d\x30\x2e\x32\x2c\x2d\x31\x2e\x32\ +\x37\x35\x20\x2d\x30\x2e\x35\x2c\x2d\x31\x2e\x38\x20\x30\x2e\x31\ +\x37\x35\x2c\x2d\x30\x2e\x36\x37\x35\x20\x30\x2e\x33\x2c\x2d\x31\ +\x2e\x33\x37\x35\x20\x30\x2e\x33\x2c\x2d\x32\x2e\x30\x37\x35\x20\ +\x30\x2c\x2d\x30\x2e\x37\x35\x20\x2d\x30\x2e\x32\x2c\x2d\x31\x2e\ +\x34\x32\x35\x20\x2d\x30\x2e\x35\x2c\x2d\x32\x2e\x30\x32\x35\x20\ +\x30\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\x20\x30\x2e\x33\x2c\ +\x2d\x31\x2e\x37\x20\x30\x2e\x33\x2c\x2d\x32\x2e\x35\x35\x20\x30\ +\x2c\x2d\x30\x2e\x39\x32\x35\x20\x2d\x30\x2e\x32\x35\x2c\x2d\x31\ +\x2e\x37\x35\x20\x2d\x30\x2e\x36\x35\x2c\x2d\x32\x2e\x35\x32\x35\ +\x20\x30\x2e\x30\x35\x2c\x2d\x30\x2e\x37\x39\x39\x39\x39\x39\x39\ +\x20\x30\x2e\x30\x37\x35\x2c\x2d\x31\x2e\x36\x32\x34\x39\x39\x39\ +\x39\x20\x30\x2e\x30\x37\x35\x2c\x2d\x32\x2e\x34\x32\x34\x39\x39\ +\x39\x39\x20\x30\x2c\x2d\x30\x2e\x39\x32\x35\x20\x2d\x30\x2e\x32\ +\x32\x35\x2c\x2d\x31\x2e\x37\x37\x34\x39\x39\x39\x37\x20\x2d\x30\ +\x2e\x35\x37\x35\x2c\x2d\x32\x2e\x35\x37\x34\x39\x39\x39\x37\x20\ +\x30\x2e\x30\x35\x2c\x2d\x30\x2e\x37\x37\x35\x20\x30\x2e\x30\x35\ +\x2c\x2d\x31\x2e\x35\x35\x20\x30\x2e\x30\x35\x2c\x2d\x32\x2e\x33\ +\x32\x35\x20\x30\x2c\x2d\x34\x2e\x37\x37\x35\x30\x30\x30\x32\x20\ +\x2d\x35\x2e\x32\x32\x34\x39\x39\x39\x39\x36\x2c\x2d\x37\x2e\x39\ +\x37\x35\x30\x30\x30\x32\x20\x2d\x35\x2e\x32\x32\x34\x39\x39\x39\ +\x39\x36\x2c\x2d\x31\x32\x2e\x37\x35\x30\x30\x30\x30\x32\x20\x6c\ +\x20\x30\x2c\x2d\x30\x2e\x32\x32\x35\x20\x2d\x30\x2e\x33\x35\x2c\ +\x30\x20\x30\x2c\x33\x31\x2e\x32\x34\x39\x39\x39\x39\x38\x20\x30\ +\x2e\x33\x35\x2c\x30\x20\x30\x2c\x2d\x33\x2e\x37\x35\x20\x63\x20\ +\x32\x2e\x34\x39\x39\x39\x39\x39\x39\x36\x2c\x30\x2e\x33\x37\x35\ +\x20\x35\x2e\x37\x34\x39\x39\x39\x39\x39\x36\x2c\x31\x2e\x35\x20\ +\x35\x2e\x37\x34\x39\x39\x39\x39\x39\x36\x2c\x33\x2e\x37\x37\x35\ +\x20\x30\x2c\x30\x2e\x34\x32\x35\x20\x2d\x30\x2e\x31\x35\x2c\x30\ +\x2e\x38\x37\x35\x20\x2d\x30\x2e\x31\x35\x2c\x31\x2e\x33\x20\x30\ +\x2c\x30\x2e\x33\x20\x30\x2e\x32\x37\x35\x2c\x30\x2e\x35\x20\x30\ +\x2e\x35\x35\x2c\x30\x2e\x35\x20\x30\x2e\x36\x35\x2c\x30\x20\x30\ +\x2e\x35\x37\x35\x2c\x2d\x31\x2e\x32\x20\x30\x2e\x35\x37\x35\x2c\ +\x2d\x31\x2e\x38\x20\x7a\x20\x4d\x20\x2d\x30\x2e\x30\x34\x37\x32\ +\x34\x35\x37\x36\x2c\x2d\x34\x2e\x34\x35\x32\x32\x32\x34\x37\x20\ +\x63\x20\x31\x2e\x38\x34\x39\x39\x39\x39\x39\x36\x2c\x32\x2e\x30\ +\x39\x39\x39\x39\x39\x39\x20\x34\x2e\x32\x37\x34\x39\x39\x39\x39\ +\x36\x2c\x34\x2e\x39\x37\x35\x30\x30\x30\x30\x38\x20\x34\x2e\x32\ +\x37\x34\x39\x39\x39\x39\x36\x2c\x37\x2e\x37\x35\x30\x30\x30\x30\ +\x31\x20\x30\x2c\x30\x2e\x32\x32\x35\x20\x2d\x30\x2e\x30\x32\x35\ +\x2c\x30\x2e\x34\x37\x35\x20\x2d\x30\x2e\x30\x32\x35\x2c\x30\x2e\ +\x37\x20\x2d\x31\x2e\x37\x2c\x2d\x32\x2e\x35\x35\x20\x2d\x34\x2e\ +\x32\x34\x39\x39\x39\x39\x39\x36\x2c\x2d\x34\x2e\x38\x32\x34\x39\ +\x39\x39\x39\x38\x20\x2d\x34\x2e\x32\x34\x39\x39\x39\x39\x39\x36\ +\x2c\x2d\x37\x2e\x39\x35\x30\x30\x30\x30\x31\x20\x6c\x20\x30\x2c\ +\x2d\x30\x2e\x35\x20\x7a\x20\x6d\x20\x30\x2c\x35\x2e\x35\x30\x30\ +\x30\x30\x30\x31\x20\x63\x20\x32\x2e\x30\x34\x39\x39\x39\x39\x39\ +\x36\x2c\x31\x2e\x38\x32\x35\x20\x34\x2e\x37\x37\x34\x39\x39\x39\ +\x39\x36\x2c\x34\x2e\x34\x32\x35\x20\x34\x2e\x37\x37\x34\x39\x39\ +\x39\x39\x36\x2c\x37\x2e\x31\x34\x39\x39\x39\x39\x37\x20\x6c\x20\ +\x30\x2c\x31\x20\x63\x20\x2d\x31\x2e\x38\x37\x35\x2c\x2d\x32\x2e\ +\x34\x32\x35\x20\x2d\x34\x2e\x37\x37\x34\x39\x39\x39\x39\x36\x2c\ +\x2d\x34\x2e\x34\x34\x39\x39\x39\x39\x37\x20\x2d\x34\x2e\x37\x37\ +\x34\x39\x39\x39\x39\x36\x2c\x2d\x37\x2e\x36\x32\x34\x39\x39\x39\ +\x37\x20\x6c\x20\x30\x2c\x2d\x30\x2e\x35\x32\x35\x20\x7a\x20\x6d\ +\x20\x30\x2c\x35\x2e\x35\x32\x34\x39\x39\x39\x37\x20\x63\x20\x32\ +\x2e\x32\x39\x39\x39\x39\x39\x39\x36\x2c\x31\x2e\x35\x35\x20\x35\ +\x2e\x33\x34\x39\x39\x39\x39\x39\x36\x2c\x33\x2e\x38\x34\x39\x39\ +\x39\x39\x39\x20\x35\x2e\x33\x34\x39\x39\x39\x39\x39\x36\x2c\x36\ +\x2e\x35\x37\x34\x39\x39\x39\x39\x20\x30\x2c\x30\x2e\x34\x35\x20\ +\x2d\x30\x2e\x30\x32\x35\x2c\x30\x2e\x39\x20\x2d\x30\x2e\x31\x2c\ +\x31\x2e\x33\x35\x20\x2d\x31\x2e\x39\x2c\x2d\x32\x2e\x33\x37\x35\ +\x20\x2d\x35\x2e\x32\x34\x39\x39\x39\x39\x39\x36\x2c\x2d\x34\x2e\ +\x31\x20\x2d\x35\x2e\x32\x34\x39\x39\x39\x39\x39\x36\x2c\x2d\x37\ +\x2e\x32\x39\x39\x39\x39\x39\x39\x20\x6c\x20\x30\x2c\x2d\x30\x2e\ +\x36\x32\x35\x20\x7a\x20\x6d\x20\x30\x2c\x35\x2e\x36\x32\x34\x39\ +\x39\x39\x39\x20\x63\x20\x32\x2e\x33\x39\x39\x39\x39\x39\x39\x36\ +\x2c\x31\x2e\x31\x32\x35\x20\x35\x2e\x35\x34\x39\x39\x39\x39\x39\ +\x36\x2c\x32\x2e\x39\x37\x35\x20\x35\x2e\x35\x34\x39\x39\x39\x39\ +\x39\x36\x2c\x35\x2e\x35\x32\x35\x20\x30\x2c\x30\x2e\x33\x37\x35\ +\x20\x2d\x30\x2e\x30\x35\x2c\x30\x2e\x37\x32\x35\x20\x2d\x30\x2e\ +\x31\x32\x35\x2c\x31\x2e\x31\x20\x2d\x31\x2e\x39\x35\x2c\x2d\x31\ +\x2e\x39\x32\x35\x20\x2d\x35\x2e\x34\x32\x34\x39\x39\x39\x39\x36\ +\x2c\x2d\x33\x2e\x30\x35\x20\x2d\x35\x2e\x34\x32\x34\x39\x39\x39\ +\x39\x36\x2c\x2d\x36\x20\x6c\x20\x30\x2c\x2d\x30\x2e\x36\x32\x35\ +\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x34\x33\x34\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ +\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\ +\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0d\x98\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x31\x36\x39\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\ +\x72\x31\x33\x37\x32\x35\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x65\ +\x66\x42\x61\x73\x73\x5f\x38\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\ +\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\ +\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ +\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ +\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\ +\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\ +\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\ +\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\ +\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\ +\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\ +\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x32\x30\x39\x36\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x30\x31\x38\ +\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\ +\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x34\x2e\x34\x35\ +\x37\x36\x30\x31\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x32\x35\x2e\x37\x35\x36\ +\x39\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x79\x3d\x22\x39\x39\x34\x2e\x35\x39\x39\x37\x34\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ +\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ +\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x31\x36\x39\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x33\x31\x37\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\ +\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\ +\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\ +\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\ +\x31\x37\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\ +\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x34\x2e\x31\x37\x35\ +\x2c\x2d\x33\x2e\x31\x35\x30\x39\x38\x35\x35\x20\x63\x20\x30\x2c\ +\x2d\x30\x2e\x37\x32\x35\x20\x30\x2e\x35\x37\x35\x2c\x2d\x31\x2e\ +\x33\x30\x30\x30\x30\x30\x31\x20\x31\x2e\x33\x2c\x2d\x31\x2e\x33\ +\x30\x30\x30\x30\x30\x31\x20\x30\x2e\x37\x32\x35\x2c\x30\x20\x31\ +\x2e\x33\x2c\x30\x2e\x35\x37\x35\x30\x30\x30\x31\x20\x31\x2e\x33\ +\x2c\x31\x2e\x33\x30\x30\x30\x30\x30\x31\x20\x30\x2c\x30\x2e\x37\ +\x32\x35\x20\x2d\x30\x2e\x35\x37\x35\x2c\x31\x2e\x32\x39\x39\x39\ +\x39\x39\x39\x20\x2d\x31\x2e\x33\x2c\x31\x2e\x32\x39\x39\x39\x39\ +\x39\x39\x20\x2d\x30\x2e\x37\x32\x35\x2c\x30\x20\x2d\x31\x2e\x33\ +\x2c\x2d\x30\x2e\x35\x37\x34\x39\x39\x39\x39\x20\x2d\x31\x2e\x33\ +\x2c\x2d\x31\x2e\x32\x39\x39\x39\x39\x39\x39\x20\x7a\x20\x6d\x20\ +\x30\x2c\x2d\x36\x2e\x32\x35\x30\x30\x30\x30\x31\x20\x63\x20\x30\ +\x2c\x2d\x30\x2e\x37\x32\x35\x30\x30\x30\x34\x20\x30\x2e\x35\x37\ +\x35\x2c\x2d\x31\x2e\x33\x30\x30\x30\x30\x30\x34\x20\x31\x2e\x33\ +\x2c\x2d\x31\x2e\x33\x30\x30\x30\x30\x30\x34\x20\x30\x2e\x37\x32\ +\x35\x2c\x30\x20\x31\x2e\x33\x2c\x30\x2e\x35\x37\x35\x20\x31\x2e\ +\x33\x2c\x31\x2e\x33\x30\x30\x30\x30\x30\x34\x20\x30\x2c\x30\x2e\ +\x37\x32\x35\x20\x2d\x30\x2e\x35\x37\x35\x2c\x31\x2e\x33\x20\x2d\ +\x31\x2e\x33\x2c\x31\x2e\x33\x20\x2d\x30\x2e\x37\x32\x35\x2c\x30\ +\x20\x2d\x31\x2e\x33\x2c\x2d\x30\x2e\x35\x37\x35\x20\x2d\x31\x2e\ +\x33\x2c\x2d\x31\x2e\x33\x20\x7a\x20\x4d\x20\x36\x2e\x31\x2c\x2d\ +\x31\x32\x2e\x38\x30\x30\x39\x38\x36\x20\x63\x20\x34\x2e\x32\x37\ +\x35\x2c\x30\x20\x37\x2e\x33\x2c\x32\x2e\x31\x35\x20\x37\x2e\x33\ +\x2c\x36\x2e\x32\x30\x30\x30\x30\x30\x34\x20\x30\x2c\x36\x2e\x35\ +\x37\x35\x30\x30\x30\x30\x33\x20\x2d\x36\x2e\x36\x2c\x31\x30\x2e\ +\x33\x37\x35\x20\x2d\x31\x32\x2e\x39\x32\x35\x2c\x31\x33\x2e\x30\ +\x32\x35\x20\x2d\x30\x2e\x30\x35\x2c\x30\x2e\x30\x35\x20\x2d\x30\ +\x2e\x31\x32\x35\x2c\x30\x2e\x30\x37\x35\x20\x2d\x30\x2e\x32\x2c\ +\x30\x2e\x30\x37\x35\x20\x2d\x30\x2e\x31\x35\x2c\x30\x20\x2d\x30\ +\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\x32\ +\x37\x35\x2c\x2d\x30\x2e\x32\x37\x35\x20\x30\x2c\x2d\x30\x2e\x30\ +\x37\x35\x20\x30\x2e\x30\x32\x35\x2c\x2d\x30\x2e\x31\x35\x20\x30\ +\x2e\x30\x37\x35\x2c\x2d\x30\x2e\x32\x20\x35\x2e\x30\x37\x35\x2c\ +\x2d\x32\x2e\x39\x35\x20\x31\x30\x2e\x33\x37\x35\x2c\x2d\x36\x2e\ +\x36\x32\x34\x39\x39\x39\x39\x37\x20\x31\x30\x2e\x33\x37\x35\x2c\ +\x2d\x31\x32\x2e\x33\x35\x20\x30\x2c\x2d\x33\x2e\x30\x32\x35\x20\ +\x2d\x31\x2e\x36\x2c\x2d\x35\x2e\x39\x32\x35\x30\x30\x30\x34\x20\ +\x2d\x34\x2e\x33\x35\x2c\x2d\x35\x2e\x39\x32\x35\x30\x30\x30\x34\ +\x20\x2d\x31\x2e\x39\x37\x35\x2c\x30\x20\x2d\x33\x2e\x34\x35\x2c\ +\x31\x2e\x34\x32\x35\x20\x2d\x34\x2e\x31\x2c\x33\x2e\x33\x32\x35\ +\x30\x30\x30\x34\x20\x30\x2e\x33\x35\x2c\x2d\x30\x2e\x32\x20\x30\ +\x2e\x37\x2c\x2d\x30\x2e\x33\x32\x35\x20\x31\x2e\x30\x37\x35\x2c\ +\x2d\x30\x2e\x33\x32\x35\x20\x31\x2e\x33\x37\x35\x2c\x30\x20\x32\ +\x2e\x35\x2c\x31\x2e\x31\x32\x35\x20\x32\x2e\x35\x2c\x32\x2e\x35\ +\x20\x30\x2c\x31\x2e\x34\x35\x20\x2d\x31\x2e\x31\x2c\x32\x2e\x36\ +\x37\x35\x30\x30\x30\x31\x20\x2d\x32\x2e\x35\x2c\x32\x2e\x36\x37\ +\x35\x30\x30\x30\x31\x20\x2d\x31\x2e\x35\x2c\x30\x20\x2d\x32\x2e\ +\x38\x2c\x2d\x31\x2e\x32\x30\x30\x30\x30\x30\x31\x20\x2d\x32\x2e\ +\x38\x2c\x2d\x32\x2e\x36\x37\x35\x30\x30\x30\x31\x20\x30\x2c\x2d\ +\x33\x2e\x33\x30\x30\x30\x30\x30\x34\x20\x32\x2e\x35\x37\x35\x2c\ +\x2d\x36\x2e\x30\x35\x30\x30\x30\x30\x34\x20\x35\x2e\x38\x32\x35\ +\x2c\x2d\x36\x2e\x30\x35\x30\x30\x30\x30\x34\x20\x7a\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x31\x37\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ +\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\ +\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\ +\x6d\x65\x3d\x22\x65\x69\x67\x68\x74\x22\x0a\x20\x20\x20\x20\x20\ +\x64\x3d\x22\x4d\x20\x39\x2e\x33\x39\x34\x36\x37\x37\x34\x2c\x39\ +\x2e\x36\x30\x30\x32\x38\x39\x32\x20\x43\x20\x39\x2e\x39\x34\x30\ +\x39\x34\x38\x35\x2c\x39\x2e\x30\x33\x35\x31\x38\x31\x34\x20\x31\ +\x30\x2e\x34\x31\x31\x38\x37\x32\x2c\x38\x2e\x34\x33\x32\x34\x30\ +\x30\x31\x20\x31\x30\x2e\x34\x31\x31\x38\x37\x32\x2c\x37\x2e\x36\ +\x36\x30\x30\x38\x36\x31\x20\x63\x20\x30\x2c\x2d\x31\x2e\x30\x35\ +\x34\x38\x36\x37\x38\x20\x2d\x31\x2e\x30\x39\x32\x35\x34\x32\x33\ +\x2c\x2d\x31\x2e\x37\x31\x34\x31\x36\x30\x33\x20\x2d\x32\x2e\x32\ +\x34\x31\x35\x39\x34\x38\x2c\x2d\x31\x2e\x37\x31\x34\x31\x36\x30\ +\x33\x20\x2d\x30\x2e\x39\x32\x33\x30\x30\x39\x34\x2c\x30\x20\x2d\ +\x31\x2e\x34\x36\x39\x32\x38\x30\x33\x2c\x30\x2e\x37\x31\x35\x38\ +\x30\x33\x32\x20\x2d\x31\x2e\x34\x36\x39\x32\x38\x30\x33\x2c\x31\ +\x2e\x34\x31\x32\x37\x36\x39\x35\x20\x30\x2c\x30\x2e\x34\x31\x34\ +\x34\x31\x32\x34\x20\x30\x2e\x31\x36\x39\x35\x33\x32\x34\x2c\x30\ +\x2e\x37\x39\x31\x31\x35\x30\x39\x20\x30\x2e\x35\x38\x33\x39\x34\ +\x34\x37\x2c\x31\x2e\x30\x33\x36\x30\x33\x30\x39\x20\x7a\x20\x4d\ +\x20\x39\x2e\x39\x30\x33\x32\x37\x34\x37\x2c\x39\x2e\x39\x30\x31\ +\x36\x38\x20\x63\x20\x31\x2e\x30\x33\x36\x30\x33\x31\x33\x2c\x30\ +\x2e\x36\x30\x32\x37\x38\x32\x20\x31\x2e\x36\x30\x31\x31\x33\x38\ +\x33\x2c\x31\x2e\x34\x36\x39\x32\x38\x20\x31\x2e\x36\x30\x31\x31\ +\x33\x38\x33\x2c\x32\x2e\x33\x39\x32\x32\x39\x20\x30\x2c\x31\x2e\ +\x33\x35\x36\x32\x35\x38\x20\x2d\x31\x2e\x32\x32\x34\x34\x2c\x32\ +\x2e\x36\x37\x34\x38\x34\x33\x20\x2d\x33\x2e\x34\x38\x34\x38\x33\ +\x31\x32\x2c\x32\x2e\x36\x37\x34\x38\x34\x33\x20\x2d\x31\x2e\x37\ +\x33\x32\x39\x39\x37\x32\x2c\x30\x20\x2d\x33\x2e\x33\x37\x31\x38\ +\x30\x39\x38\x2c\x2d\x30\x2e\x39\x39\x38\x33\x35\x37\x20\x2d\x33\ +\x2e\x33\x37\x31\x38\x30\x39\x38\x2c\x2d\x32\x2e\x35\x39\x39\x34\ +\x39\x36\x20\x30\x2c\x2d\x30\x2e\x39\x36\x30\x36\x38\x33\x20\x30\ +\x2e\x37\x35\x33\x34\x37\x37\x2c\x2d\x31\x2e\x36\x31\x39\x39\x37\ +\x35\x20\x31\x2e\x34\x36\x39\x32\x38\x30\x32\x2c\x2d\x32\x2e\x32\ +\x37\x39\x32\x36\x38\x20\x43\x20\x35\x2e\x32\x38\x38\x32\x32\x37\ +\x35\x2c\x39\x2e\x35\x36\x32\x36\x31\x35\x33\x20\x34\x2e\x39\x31\ +\x31\x34\x38\x39\x2c\x38\x2e\x37\x39\x30\x33\x30\x31\x37\x20\x34\ +\x2e\x39\x31\x31\x34\x38\x39\x2c\x38\x2e\x30\x33\x36\x38\x32\x34\ +\x36\x20\x63\x20\x30\x2c\x2d\x31\x2e\x32\x36\x32\x30\x37\x34\x20\ +\x31\x2e\x31\x33\x30\x32\x31\x35\x35\x2c\x2d\x32\x2e\x34\x38\x36\ +\x34\x37\x34\x32\x20\x33\x2e\x32\x35\x38\x37\x38\x38\x32\x2c\x2d\ +\x32\x2e\x34\x38\x36\x34\x37\x34\x32\x20\x31\x2e\x35\x30\x36\x39\ +\x35\x34\x2c\x30\x20\x32\x2e\x39\x37\x36\x32\x33\x34\x38\x2c\x30\ +\x2e\x37\x35\x33\x34\x37\x37\x20\x32\x2e\x39\x37\x36\x32\x33\x34\ +\x38\x2c\x32\x2e\x31\x30\x39\x37\x33\x35\x37\x20\x30\x2c\x30\x2e\ +\x39\x30\x34\x31\x37\x32\x35\x20\x2d\x30\x2e\x36\x30\x32\x37\x38\ +\x32\x2c\x31\x2e\x35\x38\x32\x33\x30\x31\x35\x20\x2d\x31\x2e\x32\ +\x34\x33\x32\x33\x37\x33\x2c\x32\x2e\x32\x34\x31\x35\x39\x33\x39\ +\x20\x7a\x20\x6d\x20\x2d\x33\x2e\x32\x35\x38\x37\x38\x38\x35\x2c\ +\x30\x2e\x34\x38\x39\x37\x36\x20\x63\x20\x2d\x30\x2e\x36\x34\x30\ +\x34\x35\x35\x35\x2c\x30\x2e\x35\x36\x35\x31\x30\x38\x20\x2d\x31\ +\x2e\x32\x34\x33\x32\x33\x37\x32\x2c\x31\x2e\x31\x34\x39\x30\x35\ +\x33\x20\x2d\x31\x2e\x32\x34\x33\x32\x33\x37\x32\x2c\x31\x2e\x39\ +\x37\x37\x38\x37\x37\x20\x30\x2c\x31\x2e\x32\x39\x39\x37\x34\x38\ +\x20\x31\x2e\x32\x34\x33\x32\x33\x37\x32\x2c\x32\x2e\x32\x30\x33\ +\x39\x32\x31\x20\x32\x2e\x36\x31\x38\x33\x33\x32\x38\x2c\x32\x2e\ +\x32\x30\x33\x39\x32\x31\x20\x31\x2e\x30\x33\x36\x30\x33\x30\x39\ +\x2c\x30\x20\x31\x2e\x36\x35\x37\x36\x34\x39\x34\x2c\x2d\x30\x2e\ +\x38\x30\x39\x39\x38\x38\x20\x31\x2e\x36\x35\x37\x36\x34\x39\x34\ +\x2c\x2d\x31\x2e\x36\x30\x31\x31\x33\x39\x20\x30\x2c\x2d\x30\x2e\ +\x34\x37\x30\x39\x32\x33\x20\x2d\x30\x2e\x32\x30\x37\x32\x30\x36\ +\x31\x2c\x2d\x30\x2e\x39\x36\x30\x36\x38\x33\x20\x2d\x30\x2e\x36\ +\x39\x36\x39\x36\x36\x32\x2c\x2d\x31\x2e\x32\x34\x33\x32\x33\x37\ +\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x33\x37\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\ +\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\ +\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x08\xfd\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x35\x32\x35\x30\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x6e\x6f\x74\x65\x68\x65\x61\x64\x73\x4d\ +\x61\x78\x69\x6d\x61\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\ +\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x35\x32\x35\x38\x22\x3e\x0a\ +\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\ +\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\ +\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\ +\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ +\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\ +\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\ +\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\ +\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ +\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x64\x65\x66\x73\x35\x32\x35\x36\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\ +\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\ +\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\ +\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ +\x69\x67\x68\x74\x3d\x22\x31\x30\x34\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x35\x32\ +\x35\x34\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x32\x32\ +\x2e\x36\x32\x37\x34\x31\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x31\x32\x2e\x34\x37\ +\x33\x33\x32\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x79\x3d\x22\x39\x39\x30\x2e\x34\x36\x31\x39\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x79\x3d\x22\x31\x30\x38\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x35\ +\x32\x35\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\ +\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\ +\x22\x6e\x6f\x74\x65\x68\x65\x61\x64\x73\x2e\x73\x4d\x33\x6e\x65\ +\x6f\x6d\x65\x6e\x73\x75\x72\x61\x6c\x22\x0a\x20\x20\x20\x20\x20\ +\x64\x3d\x22\x6d\x20\x31\x2e\x33\x2c\x2d\x30\x2e\x38\x31\x36\x39\ +\x34\x31\x37\x36\x20\x31\x33\x2e\x36\x35\x2c\x30\x20\x63\x20\x30\ +\x2e\x33\x2c\x30\x20\x30\x2e\x35\x35\x2c\x30\x2e\x32\x32\x35\x30\ +\x30\x30\x30\x32\x20\x30\x2e\x35\x35\x2c\x30\x2e\x35\x32\x35\x30\ +\x30\x30\x30\x32\x20\x6c\x20\x30\x2c\x30\x2e\x35\x35\x20\x63\x20\ +\x30\x2c\x30\x2e\x33\x20\x2d\x30\x2e\x32\x35\x2c\x30\x2e\x35\x32\ +\x35\x20\x2d\x30\x2e\x35\x35\x2c\x30\x2e\x35\x32\x35\x20\x6c\x20\ +\x2d\x31\x33\x2e\x36\x35\x2c\x30\x20\x63\x20\x2d\x30\x2e\x33\x2c\ +\x30\x20\x2d\x30\x2e\x35\x35\x2c\x2d\x30\x2e\x32\x32\x35\x20\x2d\ +\x30\x2e\x35\x35\x2c\x2d\x30\x2e\x35\x32\x35\x20\x6c\x20\x30\x2c\ +\x2d\x30\x2e\x35\x35\x20\x63\x20\x30\x2c\x2d\x30\x2e\x33\x20\x30\ +\x2e\x32\x35\x2c\x2d\x30\x2e\x35\x32\x35\x30\x30\x30\x30\x32\x20\ +\x30\x2e\x35\x35\x2c\x2d\x30\x2e\x35\x32\x35\x30\x30\x30\x30\x32\ +\x20\x7a\x20\x6d\x20\x31\x33\x2e\x36\x35\x2c\x2d\x32\x2e\x36\x30\ +\x30\x30\x30\x30\x30\x34\x20\x2d\x31\x33\x2e\x36\x35\x2c\x30\x20\ +\x63\x20\x2d\x30\x2e\x33\x35\x2c\x30\x20\x2d\x30\x2e\x35\x35\x2c\ +\x2d\x30\x2e\x34\x20\x2d\x30\x2e\x35\x35\x2c\x2d\x30\x2e\x38\x20\ +\x30\x2c\x2d\x30\x2e\x32\x35\x20\x2d\x30\x2e\x31\x37\x35\x2c\x2d\ +\x30\x2e\x33\x37\x35\x20\x2d\x30\x2e\x33\x37\x35\x2c\x2d\x30\x2e\ +\x33\x37\x35\x20\x2d\x30\x2e\x32\x2c\x30\x20\x2d\x30\x2e\x33\x37\ +\x35\x2c\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\x33\x37\x35\x2c\x30\ +\x2e\x33\x37\x35\x20\x6c\x20\x30\x2c\x38\x2e\x34\x20\x63\x20\x30\ +\x2c\x30\x2e\x32\x35\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\x33\x37\ +\x35\x20\x30\x2e\x33\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\x30\x2e\ +\x32\x2c\x30\x20\x30\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x31\x32\x35\ +\x20\x30\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x30\x2c\ +\x2d\x30\x2e\x34\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x38\x20\x30\x2e\ +\x35\x35\x2c\x2d\x30\x2e\x38\x20\x6c\x20\x31\x33\x2e\x36\x35\x2c\ +\x30\x20\x63\x20\x30\x2e\x33\x35\x2c\x30\x20\x30\x2e\x35\x35\x2c\ +\x30\x2e\x34\x20\x30\x2e\x35\x35\x2c\x30\x2e\x38\x20\x30\x2c\x30\ +\x2e\x32\x35\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\ +\x30\x2e\x33\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\x30\x2e\x32\x2c\ +\x30\x20\x30\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x30\ +\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x6c\x20\x30\x2c\ +\x2d\x38\x2e\x34\x20\x63\x20\x30\x2e\x31\x37\x35\x2c\x2d\x32\x2e\ +\x30\x37\x35\x20\x30\x2e\x34\x35\x2c\x2d\x34\x2e\x32\x20\x30\x2e\ +\x34\x35\x2c\x2d\x36\x2e\x32\x37\x34\x39\x39\x39\x32\x20\x30\x2c\ +\x2d\x30\x2e\x33\x20\x2d\x30\x2e\x32\x32\x35\x2c\x2d\x30\x2e\x34\ +\x32\x35\x20\x2d\x30\x2e\x34\x35\x2c\x2d\x30\x2e\x34\x32\x35\x20\ +\x2d\x30\x2e\x32\x32\x35\x2c\x30\x20\x2d\x30\x2e\x34\x32\x35\x2c\ +\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\x34\x35\x2c\x30\x2e\x34\x32\ +\x35\x20\x6c\x20\x2d\x30\x2e\x33\x2c\x36\x2e\x32\x34\x39\x39\x39\ +\x39\x32\x20\x30\x2c\x30\x2e\x30\x32\x35\x20\x63\x20\x30\x2c\x30\ +\x2e\x34\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x38\x20\x2d\x30\x2e\x35\ +\x35\x2c\x30\x2e\x38\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x70\x61\x74\x68\x35\x32\x35\x32\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ +\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ +\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\x5a\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x35\x30\x35\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x72\x65\x73\x74\x4d\x61\x78\x69\x6d\x61\ +\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x33\x35\x31\x33\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\ +\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\ +\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\ +\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\ +\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\ +\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\ +\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ +\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x35\x31\x31\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ +\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ +\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ +\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\ +\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\ +\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\ +\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ +\x64\x74\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x34\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ +\x33\x35\x30\x39\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ +\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\ +\x33\x30\x2e\x32\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x38\x2e\x33\x34\x36\ +\x39\x33\x37\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x79\x3d\x22\x39\x39\x39\x2e\x32\x38\x32\x30\ +\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x79\x3d\x22\x31\x30\x38\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\ +\x35\x30\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\ +\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\ +\x22\x72\x65\x73\x74\x73\x2e\x4d\x33\x6d\x65\x6e\x73\x75\x72\x61\ +\x6c\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x35\x2e\x34\ +\x37\x35\x2c\x31\x32\x2e\x38\x34\x34\x32\x38\x20\x30\x2c\x2d\x31\ +\x38\x2e\x37\x35\x30\x30\x30\x30\x33\x20\x2d\x35\x2e\x34\x37\x35\ +\x2c\x2d\x30\x2e\x35\x20\x30\x2c\x31\x38\x2e\x37\x35\x30\x30\x30\ +\x30\x33\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\ +\x61\x74\x68\x33\x35\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ +\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\ +\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\xf3\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x34\x32\x31\x22\x3e\x0a\ +\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x34\x32\ +\x39\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ +\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ +\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ +\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ +\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x34\x32\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x6d\x20\x33\x2e\x32\x37\x35\x2c\x31\x39\x2e\x31\ +\x30\x37\x36\x32\x37\x20\x31\x2e\x38\x32\x35\x2c\x2d\x38\x2e\x32\ +\x32\x35\x20\x63\x20\x2d\x30\x2e\x39\x35\x2c\x30\x2e\x33\x32\x35\ +\x20\x2d\x31\x2e\x39\x32\x35\x2c\x30\x2e\x36\x32\x35\x20\x2d\x32\ +\x2e\x39\x32\x35\x2c\x30\x2e\x36\x32\x35\x20\x2d\x31\x2e\x31\x35\ +\x2c\x30\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\x20\ +\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x31\x2e\x39\x39\x39\x39\x39\x39\ +\x38\x20\x30\x2c\x2d\x30\x2e\x39\x37\x35\x20\x30\x2e\x38\x2c\x2d\ +\x31\x2e\x37\x37\x35\x20\x31\x2e\x38\x2c\x2d\x31\x2e\x37\x37\x35\ +\x20\x30\x2e\x36\x35\x2c\x30\x20\x31\x2e\x32\x2c\x30\x2e\x34\x20\ +\x31\x2e\x34\x2c\x31\x20\x30\x2e\x32\x35\x2c\x30\x2e\x37\x20\x30\ +\x2e\x31\x37\x35\x2c\x31\x2e\x34\x39\x39\x39\x39\x39\x38\x20\x30\ +\x2e\x39\x2c\x31\x2e\x34\x39\x39\x39\x39\x39\x38\x20\x30\x2e\x34\ +\x35\x2c\x30\x20\x31\x2e\x34\x35\x2c\x2d\x31\x2e\x33\x39\x39\x39\ +\x39\x39\x38\x20\x31\x2e\x35\x35\x2c\x2d\x31\x2e\x38\x37\x34\x39\ +\x39\x39\x38\x20\x6c\x20\x30\x2e\x38\x32\x35\x2c\x2d\x33\x2e\x37\ +\x20\x63\x20\x2d\x30\x2e\x39\x2c\x30\x2e\x33\x32\x35\x20\x2d\x31\ +\x2e\x38\x32\x35\x2c\x30\x2e\x36\x20\x2d\x32\x2e\x38\x2c\x30\x2e\ +\x36\x20\x2d\x31\x2e\x31\x35\x2c\x30\x20\x2d\x32\x2e\x31\x37\x35\ +\x2c\x2d\x30\x2e\x38\x35\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x32\ +\x20\x30\x2c\x2d\x30\x2e\x39\x37\x35\x20\x30\x2e\x37\x37\x35\x2c\ +\x2d\x31\x2e\x37\x37\x35\x20\x31\x2e\x37\x37\x35\x2c\x2d\x31\x2e\ +\x37\x37\x35\x20\x30\x2e\x36\x35\x2c\x30\x20\x31\x2e\x32\x32\x35\ +\x2c\x30\x2e\x34\x20\x31\x2e\x34\x32\x35\x2c\x31\x20\x30\x2e\x32\ +\x35\x2c\x30\x2e\x37\x20\x30\x2e\x31\x35\x2c\x31\x2e\x35\x20\x30\ +\x2e\x38\x37\x35\x2c\x31\x2e\x35\x20\x30\x2e\x34\x32\x35\x2c\x30\ +\x20\x31\x2e\x33\x35\x2c\x2d\x31\x2e\x33\x37\x35\x20\x31\x2e\x34\ +\x35\x2c\x2d\x31\x2e\x38\x32\x35\x20\x6c\x20\x30\x2e\x38\x35\x2c\ +\x2d\x33\x2e\x37\x32\x35\x20\x63\x20\x2d\x30\x2e\x38\x37\x35\x2c\ +\x30\x2e\x33\x20\x2d\x31\x2e\x37\x37\x35\x2c\x30\x2e\x35\x37\x34\ +\x39\x39\x39\x39\x36\x20\x2d\x32\x2e\x37\x2c\x30\x2e\x35\x37\x34\ +\x39\x39\x39\x39\x36\x20\x2d\x31\x2e\x31\x35\x2c\x30\x20\x2d\x32\ +\x2e\x32\x2c\x2d\x30\x2e\x38\x34\x39\x39\x39\x39\x39\x36\x20\x2d\ +\x32\x2e\x32\x2c\x2d\x31\x2e\x39\x39\x39\x39\x39\x39\x39\x36\x20\ +\x30\x2c\x2d\x30\x2e\x39\x37\x35\x20\x30\x2e\x38\x2c\x2d\x31\x2e\ +\x37\x37\x35\x20\x31\x2e\x38\x2c\x2d\x31\x2e\x37\x37\x35\x20\x30\ +\x2e\x36\x35\x2c\x30\x20\x31\x2e\x32\x2c\x30\x2e\x34\x20\x31\x2e\ +\x34\x2c\x31\x20\x30\x2e\x32\x35\x2c\x30\x2e\x37\x20\x30\x2e\x31\ +\x37\x35\x2c\x31\x2e\x35\x20\x30\x2e\x39\x2c\x31\x2e\x35\x20\x30\ +\x2e\x34\x2c\x30\x20\x31\x2e\x32\x32\x35\x2c\x2d\x31\x2e\x33\x32\ +\x35\x20\x31\x2e\x33\x32\x35\x2c\x2d\x31\x2e\x37\x35\x20\x6c\x20\ +\x30\x2e\x38\x35\x2c\x2d\x33\x2e\x37\x37\x35\x20\x63\x20\x2d\x30\ +\x2e\x38\x35\x2c\x30\x2e\x33\x20\x2d\x31\x2e\x37\x2c\x30\x2e\x35\ +\x35\x20\x2d\x32\x2e\x36\x2c\x30\x2e\x35\x35\x20\x2d\x31\x2e\x31\ +\x35\x2c\x30\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\ +\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x32\x20\x30\x2c\x2d\x30\x2e\ +\x39\x37\x35\x30\x30\x30\x32\x20\x30\x2e\x37\x37\x35\x2c\x2d\x31\ +\x2e\x37\x37\x35\x30\x30\x30\x32\x20\x31\x2e\x37\x37\x35\x2c\x2d\ +\x31\x2e\x37\x37\x35\x30\x30\x30\x32\x20\x30\x2e\x36\x35\x2c\x30\ +\x20\x31\x2e\x32\x32\x35\x2c\x30\x2e\x34\x20\x31\x2e\x34\x32\x35\ +\x2c\x31\x20\x30\x2e\x32\x35\x2c\x30\x2e\x37\x30\x30\x30\x30\x30\ +\x32\x20\x30\x2e\x31\x35\x2c\x31\x2e\x35\x30\x30\x30\x30\x30\x32\ +\x20\x30\x2e\x38\x37\x35\x2c\x31\x2e\x35\x30\x30\x30\x30\x30\x32\ +\x20\x30\x2e\x34\x2c\x30\x20\x31\x2e\x31\x2c\x2d\x31\x2e\x33\x37\ +\x35\x20\x31\x2e\x32\x35\x2c\x2d\x31\x2e\x37\x35\x30\x30\x30\x30\ +\x32\x20\x30\x2e\x31\x2c\x2d\x30\x2e\x32\x37\x35\x20\x30\x2e\x35\ +\x2c\x2d\x30\x2e\x32\x37\x35\x20\x30\x2e\x36\x2c\x30\x20\x6c\x20\ +\x2d\x35\x2e\x39\x35\x2c\x32\x39\x2e\x33\x37\x35\x20\x63\x20\x2d\ +\x30\x2e\x31\x37\x35\x2c\x30\x2e\x31\x35\x20\x2d\x30\x2e\x34\x2c\ +\x30\x2e\x32\x32\x35\x20\x2d\x30\x2e\x36\x2c\x30\x2e\x32\x32\x35\ +\x20\x2d\x30\x2e\x32\x2c\x30\x20\x2d\x30\x2e\x34\x2c\x2d\x30\x2e\ +\x30\x37\x35\x20\x2d\x30\x2e\x35\x37\x35\x2c\x2d\x30\x2e\x32\x32\ +\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ +\x74\x68\x33\x34\x32\x33\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\ +\x3e\x0a\ +\x00\x00\x09\xd7\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x30\x37\x39\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x61\x63\ +\x63\x69\x64\x65\x6e\x74\x61\x6c\x73\x44\x6f\x75\x62\x6c\x65\x73\ +\x68\x61\x72\x70\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x73\x6f\ +\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ +\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\ +\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\ +\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\ +\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\ +\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\ +\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\ +\x22\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x31\x35\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\ +\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x75\ +\x69\x64\x65\x73\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x67\x75\x69\x64\x65\x2d\ +\x62\x62\x6f\x78\x3d\x22\x74\x72\x75\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\ +\x32\x31\x2e\x33\x36\x30\x32\x38\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x36\x2e\ +\x35\x35\x36\x37\x39\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x30\x30\x33\x2e\ +\x38\x35\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x31\x38\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\ +\x76\x67\x33\x30\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x30\x38\x37\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ +\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ +\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ +\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\ +\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x30\x38\ +\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ +\x20\x20\x20\x64\x3d\x22\x6d\x20\x2d\x32\x2e\x38\x38\x35\x31\x31\ +\x35\x39\x2c\x30\x2e\x30\x30\x36\x32\x31\x38\x32\x38\x20\x63\x20\ +\x30\x2e\x35\x37\x35\x2c\x30\x2e\x35\x37\x35\x20\x31\x2e\x34\x35\ +\x2c\x30\x2e\x37\x20\x32\x2e\x32\x37\x35\x30\x30\x30\x30\x31\x2c\ +\x30\x2e\x37\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\x32\x2c\x30\x2e\ +\x31\x20\x30\x2e\x32\x2c\x30\x2e\x32\x20\x6c\x20\x30\x2e\x32\x32\ +\x35\x2c\x32\x2e\x32\x32\x35\x30\x30\x30\x30\x32\x20\x63\x20\x30\ +\x2c\x30\x2e\x31\x20\x2d\x30\x2e\x30\x37\x35\x2c\x30\x2e\x32\x20\ +\x2d\x30\x2e\x31\x37\x35\x2c\x30\x2e\x32\x20\x68\x20\x2d\x30\x2e\ +\x30\x32\x35\x20\x6c\x20\x2d\x32\x2e\x32\x32\x35\x30\x30\x30\x30\ +\x31\x2c\x2d\x30\x2e\x32\x32\x35\x20\x63\x20\x2d\x30\x2e\x31\x2c\ +\x30\x20\x2d\x30\x2e\x32\x2c\x2d\x30\x2e\x31\x20\x2d\x30\x2e\x32\ +\x2c\x2d\x30\x2e\x32\x20\x30\x2c\x2d\x30\x2e\x38\x32\x35\x20\x2d\ +\x30\x2e\x31\x32\x35\x2c\x2d\x31\x2e\x37\x20\x2d\x30\x2e\x37\x2c\ +\x2d\x32\x2e\x32\x37\x35\x30\x30\x30\x30\x32\x20\x2d\x30\x2e\x35\ +\x37\x35\x2c\x30\x2e\x35\x37\x35\x30\x30\x30\x30\x32\x20\x2d\x30\ +\x2e\x37\x2c\x31\x2e\x34\x35\x30\x30\x30\x30\x30\x32\x20\x2d\x30\ +\x2e\x37\x2c\x32\x2e\x32\x37\x35\x30\x30\x30\x30\x32\x20\x30\x2c\ +\x30\x2e\x31\x20\x2d\x30\x2e\x31\x2c\x30\x2e\x32\x20\x2d\x30\x2e\ +\x32\x2c\x30\x2e\x32\x20\x6c\x20\x2d\x32\x2e\x32\x32\x35\x2c\x30\ +\x2e\x32\x32\x35\x20\x68\x20\x2d\x30\x2e\x30\x32\x35\x20\x63\x20\ +\x2d\x30\x2e\x31\x2c\x30\x20\x2d\x30\x2e\x31\x37\x35\x2c\x2d\x30\ +\x2e\x31\x20\x2d\x30\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x32\x20\x6c\ +\x20\x30\x2e\x32\x32\x35\x2c\x2d\x32\x2e\x32\x32\x35\x30\x30\x30\ +\x30\x32\x20\x63\x20\x30\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x31\x2c\ +\x2d\x30\x2e\x32\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x30\x2e\ +\x38\x32\x35\x2c\x30\x20\x31\x2e\x37\x2c\x2d\x30\x2e\x31\x32\x35\ +\x20\x32\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x37\x20\x2d\x30\x2e\x35\ +\x37\x35\x2c\x2d\x30\x2e\x35\x37\x35\x20\x2d\x31\x2e\x34\x35\x2c\ +\x2d\x30\x2e\x37\x20\x2d\x32\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x37\ +\x20\x2d\x30\x2e\x31\x2c\x30\x20\x2d\x30\x2e\x32\x2c\x2d\x30\x2e\ +\x31\x20\x2d\x30\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x6c\x20\x2d\x30\ +\x2e\x32\x32\x35\x2c\x2d\x32\x2e\x32\x32\x34\x39\x39\x39\x39\x38\ +\x20\x63\x20\x30\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x30\x37\x35\x2c\ +\x2d\x30\x2e\x32\x20\x30\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x32\x20\ +\x68\x20\x30\x2e\x30\x32\x35\x20\x6c\x20\x32\x2e\x32\x32\x35\x2c\ +\x30\x2e\x32\x32\x35\x20\x63\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\ +\x32\x2c\x30\x2e\x31\x20\x30\x2e\x32\x2c\x30\x2e\x32\x20\x30\x2c\ +\x30\x2e\x38\x32\x35\x20\x30\x2e\x31\x32\x35\x2c\x31\x2e\x37\x20\ +\x30\x2e\x37\x2c\x32\x2e\x32\x37\x34\x39\x39\x39\x39\x38\x20\x30\ +\x2e\x35\x37\x35\x2c\x2d\x30\x2e\x35\x37\x34\x39\x39\x39\x39\x38\ +\x20\x30\x2e\x37\x2c\x2d\x31\x2e\x34\x34\x39\x39\x39\x39\x39\x38\ +\x20\x30\x2e\x37\x2c\x2d\x32\x2e\x32\x37\x34\x39\x39\x39\x39\x38\ +\x20\x30\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x31\x2c\x2d\x30\x2e\x32\ +\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x6c\x20\x32\x2e\x32\x32\ +\x35\x30\x30\x30\x30\x31\x2c\x2d\x30\x2e\x32\x32\x35\x20\x68\x20\ +\x30\x2e\x30\x32\x35\x20\x63\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\ +\x31\x37\x35\x2c\x30\x2e\x31\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\ +\x32\x20\x6c\x20\x2d\x30\x2e\x32\x32\x35\x2c\x32\x2e\x32\x32\x34\ +\x39\x39\x39\x39\x38\x20\x63\x20\x30\x2c\x30\x2e\x31\x20\x2d\x30\ +\x2e\x31\x2c\x30\x2e\x32\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x32\x20\ +\x2d\x30\x2e\x38\x32\x35\x30\x30\x30\x30\x31\x2c\x30\x20\x2d\x31\ +\x2e\x37\x30\x30\x30\x30\x30\x30\x31\x2c\x30\x2e\x31\x32\x35\x20\ +\x2d\x32\x2e\x32\x37\x35\x30\x30\x30\x30\x31\x2c\x30\x2e\x37\x20\ +\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x33\x30\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x07\x12\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x30\x39\x39\x22\x3e\x0a\ +\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x31\x30\ +\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ +\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ +\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ +\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ +\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x31\x30\x35\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x6d\x20\x2d\x34\x2e\x39\x32\x39\x30\x37\x38\x34\ +\x2c\x2d\x30\x2e\x32\x32\x34\x39\x34\x37\x30\x32\x20\x2d\x30\x2e\ +\x30\x32\x35\x2c\x31\x2e\x37\x32\x35\x30\x30\x30\x30\x32\x20\x76\ +\x20\x30\x2e\x32\x37\x35\x20\x63\x20\x30\x2c\x30\x2e\x35\x35\x20\ +\x30\x2e\x30\x35\x2c\x31\x2e\x31\x20\x30\x2e\x31\x2c\x31\x2e\x36\ +\x35\x20\x31\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x39\x32\x35\x20\x32\ +\x2e\x32\x32\x35\x2c\x2d\x32\x2e\x30\x32\x35\x20\x32\x2e\x32\x32\ +\x35\x2c\x2d\x33\x2e\x34\x37\x35\x30\x30\x30\x30\x32\x20\x30\x2c\ +\x2d\x30\x2e\x38\x35\x20\x2d\x30\x2e\x33\x2c\x2d\x31\x2e\x37\x32\ +\x34\x39\x39\x39\x39\x38\x20\x2d\x31\x2e\x30\x32\x35\x2c\x2d\x31\ +\x2e\x37\x32\x34\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\x37\x35\x2c\ +\x30\x20\x2d\x31\x2e\x32\x35\x2c\x30\x2e\x37\x35\x20\x2d\x31\x2e\ +\x32\x37\x35\x2c\x31\x2e\x35\x34\x39\x39\x39\x39\x39\x38\x20\x7a\ +\x20\x6d\x20\x2d\x30\x2e\x39\x35\x2c\x34\x2e\x35\x30\x30\x30\x30\ +\x30\x30\x32\x20\x2d\x30\x2e\x30\x35\x2c\x2d\x32\x2e\x36\x35\x20\ +\x63\x20\x2d\x30\x2e\x37\x2c\x30\x2e\x38\x37\x35\x20\x2d\x31\x2e\ +\x37\x37\x35\x2c\x31\x2e\x35\x37\x35\x20\x2d\x32\x2e\x36\x32\x35\ +\x2c\x32\x2e\x33\x37\x35\x20\x2d\x30\x2e\x33\x2c\x30\x2e\x32\x37\ +\x35\x20\x2d\x30\x2e\x34\x35\x2c\x30\x2e\x38\x20\x2d\x30\x2e\x38\ +\x37\x35\x2c\x30\x2e\x38\x20\x2d\x30\x2e\x33\x2c\x30\x20\x2d\x30\ +\x2e\x35\x32\x35\x2c\x2d\x30\x2e\x32\x32\x35\x20\x2d\x30\x2e\x35\ +\x32\x35\x2c\x2d\x30\x2e\x35\x32\x35\x20\x6c\x20\x2d\x30\x2e\x32\ +\x37\x34\x39\x39\x39\x36\x2c\x2d\x31\x34\x2e\x39\x37\x35\x20\x63\ +\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x33\x39\x39\x39\ +\x39\x39\x36\x2c\x2d\x30\x2e\x31\x37\x35\x20\x30\x2e\x36\x32\x34\ +\x39\x39\x39\x36\x2c\x2d\x30\x2e\x31\x37\x35\x20\x30\x2e\x32\x32\ +\x35\x2c\x30\x20\x30\x2e\x34\x32\x35\x2c\x30\x2e\x30\x37\x35\x20\ +\x30\x2e\x36\x32\x35\x2c\x30\x2e\x31\x37\x35\x20\x6c\x20\x2d\x30\ +\x2e\x31\x35\x2c\x38\x2e\x37\x32\x35\x20\x63\x20\x30\x2e\x34\x35\ +\x2c\x2d\x30\x2e\x34\x37\x35\x20\x31\x2e\x30\x35\x2c\x2d\x30\x2e\ +\x37\x35\x20\x31\x2e\x37\x2c\x2d\x30\x2e\x37\x35\x20\x30\x2e\x35\ +\x35\x2c\x30\x20\x31\x2e\x30\x35\x2c\x30\x2e\x32\x32\x35\x20\x31\ +\x2e\x34\x32\x35\x2c\x30\x2e\x35\x37\x35\x20\x6c\x20\x2d\x30\x2e\ +\x31\x37\x35\x2c\x2d\x38\x2e\x35\x35\x20\x63\x20\x30\x2e\x32\x2c\ +\x2d\x30\x2e\x31\x20\x30\x2e\x34\x2c\x2d\x30\x2e\x31\x37\x35\x20\ +\x30\x2e\x36\x32\x35\x2c\x2d\x30\x2e\x31\x37\x35\x20\x30\x2e\x32\ +\x32\x35\x2c\x30\x20\x30\x2e\x34\x35\x2c\x30\x2e\x30\x37\x35\x20\ +\x30\x2e\x36\x35\x2c\x30\x2e\x31\x37\x35\x20\x6c\x20\x2d\x30\x2e\ +\x31\x37\x35\x2c\x38\x2e\x37\x32\x35\x20\x63\x20\x30\x2e\x36\x2c\ +\x2d\x30\x2e\x34\x37\x35\x20\x31\x2e\x33\x37\x35\x2c\x2d\x30\x2e\ +\x37\x35\x20\x32\x2e\x31\x35\x2c\x2d\x30\x2e\x37\x35\x20\x31\x2e\ +\x33\x35\x2c\x30\x20\x32\x2e\x33\x37\x34\x39\x39\x39\x39\x37\x2c\ +\x31\x2e\x31\x32\x35\x20\x32\x2e\x33\x37\x34\x39\x39\x39\x39\x37\ +\x2c\x32\x2e\x34\x37\x34\x39\x39\x39\x39\x38\x20\x30\x2c\x32\x2e\ +\x30\x35\x30\x30\x30\x30\x30\x32\x20\x2d\x32\x2e\x32\x34\x39\x39\ +\x39\x39\x39\x37\x2c\x32\x2e\x39\x35\x30\x30\x30\x30\x30\x32\x20\ +\x2d\x33\x2e\x38\x32\x34\x39\x39\x39\x39\x37\x2c\x34\x2e\x32\x35\ +\x30\x30\x30\x30\x30\x32\x20\x2d\x30\x2e\x33\x35\x2c\x30\x2e\x32\ +\x37\x35\x20\x2d\x30\x2e\x35\x32\x35\x2c\x30\x2e\x38\x20\x2d\x30\ +\x2e\x39\x37\x35\x2c\x30\x2e\x38\x20\x2d\x30\x2e\x33\x2c\x30\x20\ +\x2d\x30\x2e\x35\x32\x35\x2c\x2d\x30\x2e\x32\x32\x35\x20\x2d\x30\ +\x2e\x35\x32\x35\x2c\x2d\x30\x2e\x35\x32\x35\x20\x7a\x20\x6d\x20\ +\x2d\x33\x2e\x33\x2c\x2d\x34\x2e\x35\x30\x30\x30\x30\x30\x30\x32\ +\x20\x2d\x30\x2e\x30\x32\x35\x2c\x31\x2e\x37\x32\x35\x30\x30\x30\ +\x30\x32\x20\x76\x20\x30\x2e\x32\x37\x35\x20\x63\x20\x30\x2c\x30\ +\x2e\x35\x37\x35\x20\x30\x2e\x30\x32\x35\x2c\x31\x2e\x31\x32\x35\ +\x20\x30\x2e\x31\x2c\x31\x2e\x37\x20\x31\x2c\x2d\x30\x2e\x39\x35\ +\x20\x31\x2e\x38\x2c\x2d\x32\x2e\x31\x35\x20\x31\x2e\x38\x2c\x2d\ +\x33\x2e\x35\x32\x35\x30\x30\x30\x30\x32\x20\x30\x2c\x2d\x30\x2e\ +\x38\x32\x35\x20\x2d\x30\x2e\x31\x35\x2c\x2d\x31\x2e\x37\x32\x34\ +\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\x38\x35\x2c\x2d\x31\x2e\x37\ +\x32\x34\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\x36\x37\x35\x2c\x30\ +\x20\x2d\x31\x2c\x30\x2e\x37\x37\x34\x39\x39\x39\x39\x38\x20\x2d\ +\x31\x2e\x30\x32\x35\x2c\x31\x2e\x35\x34\x39\x39\x39\x39\x39\x38\ +\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x33\x31\x30\x31\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ +\x0a\ +\x00\x00\x05\x53\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x30\x38\x39\x22\x3e\x0a\ +\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x30\x39\ +\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ +\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ +\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ +\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ +\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x30\x39\x35\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x6d\x20\x2d\x35\x2e\x31\x30\x35\x39\x33\x32\x32\ +\x2c\x2d\x30\x2e\x37\x38\x37\x37\x31\x31\x38\x35\x20\x2d\x30\x2e\ +\x30\x32\x35\x2c\x31\x2e\x37\x32\x35\x20\x63\x20\x30\x2c\x30\x2e\ +\x31\x30\x30\x30\x30\x30\x30\x35\x20\x2d\x30\x2e\x30\x32\x35\x2c\ +\x30\x2e\x31\x37\x34\x39\x39\x39\x39\x35\x20\x2d\x30\x2e\x30\x32\ +\x35\x2c\x30\x2e\x32\x37\x34\x39\x39\x39\x39\x35\x20\x30\x2c\x30\ +\x2e\x35\x35\x20\x30\x2e\x30\x35\x2c\x31\x2e\x31\x20\x30\x2e\x31\ +\x2c\x31\x2e\x36\x35\x20\x31\x2e\x31\x35\x2c\x2d\x30\x2e\x39\x35\ +\x20\x32\x2e\x34\x2c\x2d\x31\x2e\x39\x39\x39\x39\x39\x39\x39\x35\ +\x20\x32\x2e\x34\x2c\x2d\x33\x2e\x34\x37\x34\x39\x39\x39\x39\x35\ +\x20\x30\x2c\x2d\x30\x2e\x38\x35\x30\x30\x30\x30\x30\x35\x20\x2d\ +\x30\x2e\x33\x35\x2c\x2d\x31\x2e\x37\x32\x35\x30\x30\x30\x30\x35\ +\x20\x2d\x31\x2e\x31\x2c\x2d\x31\x2e\x37\x32\x35\x30\x30\x30\x30\ +\x35\x20\x2d\x30\x2e\x37\x37\x35\x2c\x30\x20\x2d\x31\x2e\x33\x32\ +\x35\x2c\x30\x2e\x37\x32\x35\x20\x2d\x31\x2e\x33\x35\x2c\x31\x2e\ +\x35\x35\x30\x30\x30\x30\x30\x35\x20\x7a\x20\x6d\x20\x2d\x30\x2e\ +\x39\x37\x35\x2c\x34\x2e\x34\x39\x39\x39\x39\x39\x39\x35\x20\x2d\ +\x30\x2e\x32\x37\x35\x2c\x2d\x31\x34\x2e\x39\x37\x35\x30\x30\x30\ +\x31\x20\x63\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x34\ +\x2c\x2d\x30\x2e\x31\x37\x35\x20\x30\x2e\x36\x32\x35\x2c\x2d\x30\ +\x2e\x31\x37\x35\x20\x30\x2e\x32\x32\x35\x2c\x30\x20\x30\x2e\x34\ +\x32\x35\x2c\x30\x2e\x30\x37\x35\x20\x30\x2e\x36\x32\x35\x2c\x30\ +\x2e\x31\x37\x35\x20\x6c\x20\x2d\x30\x2e\x31\x35\x2c\x38\x2e\x37\ +\x32\x35\x30\x30\x30\x31\x20\x63\x20\x30\x2e\x36\x35\x2c\x2d\x30\ +\x2e\x34\x37\x35\x20\x31\x2e\x34\x2c\x2d\x30\x2e\x37\x35\x20\x32\ +\x2e\x32\x2c\x2d\x30\x2e\x37\x35\x20\x31\x2e\x33\x32\x35\x2c\x30\ +\x20\x32\x2e\x33\x32\x34\x39\x39\x39\x39\x38\x2c\x31\x2e\x31\x35\ +\x20\x32\x2e\x33\x32\x34\x39\x39\x39\x39\x38\x2c\x32\x2e\x35\x30\ +\x30\x30\x30\x30\x30\x35\x20\x30\x2c\x32\x2e\x30\x34\x39\x39\x39\ +\x39\x39\x35\x20\x2d\x32\x2e\x32\x34\x39\x39\x39\x39\x39\x38\x2c\ +\x32\x2e\x39\x34\x39\x39\x39\x39\x39\x35\x20\x2d\x33\x2e\x38\x32\ +\x34\x39\x39\x39\x39\x38\x2c\x34\x2e\x32\x32\x34\x39\x39\x39\x39\ +\x35\x20\x2d\x30\x2e\x33\x35\x2c\x30\x2e\x32\x37\x35\x20\x2d\x30\ +\x2e\x35\x35\x2c\x30\x2e\x38\x20\x2d\x31\x2c\x30\x2e\x38\x20\x2d\ +\x30\x2e\x33\x2c\x30\x20\x2d\x30\x2e\x35\x32\x35\x2c\x2d\x30\x2e\ +\x32\x32\x35\x20\x2d\x30\x2e\x35\x32\x35\x2c\x2d\x30\x2e\x35\x32\ +\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ +\x74\x68\x33\x30\x39\x31\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\ +\x3e\x0a\ +\x00\x00\x06\xc7\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x30\x35\x39\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\x34\x20\x72\x39\x39\x33\x39\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x64\x6f\x74\x73\x2e\x64\x6f\x74\x2e\ +\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x33\x30\x36\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ +\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ +\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ +\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ +\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ +\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\ +\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\ +\x73\x33\x30\x36\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\ +\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x30\x36\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x33\x2e\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ +\x30\x2e\x33\x36\x36\x37\x32\x34\x31\x33\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x30\ +\x30\x33\x2e\x33\x30\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ +\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x31\x38\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\ +\x3d\x22\x73\x76\x67\x33\x30\x35\x39\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\ +\x2d\x6e\x61\x6d\x65\x3d\x22\x64\x6f\x74\x73\x2e\x64\x6f\x74\x22\ +\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x30\x2e\x37\x39\x35\ +\x35\x38\x38\x31\x32\x2c\x30\x20\x63\x20\x30\x2c\x30\x2e\x38\x20\ +\x30\x2e\x36\x32\x34\x39\x39\x39\x39\x38\x2c\x31\x2e\x34\x32\x35\ +\x20\x31\x2e\x34\x32\x34\x39\x39\x39\x39\x38\x2c\x31\x2e\x34\x32\ +\x35\x20\x30\x2e\x38\x2c\x30\x20\x31\x2e\x34\x32\x35\x2c\x2d\x30\ +\x2e\x36\x32\x35\x20\x31\x2e\x34\x32\x35\x2c\x2d\x31\x2e\x34\x32\ +\x35\x20\x30\x2c\x2d\x30\x2e\x38\x20\x2d\x30\x2e\x36\x32\x35\x2c\ +\x2d\x31\x2e\x34\x32\x35\x20\x2d\x31\x2e\x34\x32\x35\x2c\x2d\x31\ +\x2e\x34\x32\x35\x20\x2d\x30\x2e\x38\x2c\x30\x20\x2d\x31\x2e\x34\ +\x32\x34\x39\x39\x39\x39\x38\x2c\x30\x2e\x36\x32\x35\x20\x2d\x31\ +\x2e\x34\x32\x34\x39\x39\x39\x39\x38\x2c\x31\x2e\x34\x32\x35\x20\ +\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x33\x30\x36\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x09\x7b\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x31\x36\x39\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\ +\x65\x66\x42\x61\x73\x73\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\ +\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ +\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\ +\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\ +\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\ +\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\ +\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\ +\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\ +\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\ +\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\ +\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ +\x39\x35\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x30\x31\x38\x22\x0a\ +\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\ +\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x37\x2e\x38\x33\x30\ +\x34\x30\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x78\x3d\x22\x32\x32\x2e\x34\x32\x32\x33\x31\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x79\x3d\x22\x39\x38\x37\x2e\x33\x38\x30\x39\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x78\x3d\x22\x32\x38\x38\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x79\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\ +\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\ +\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x31\x36\x39\ +\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x33\x31\x37\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ +\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ +\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ +\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ +\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ +\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ +\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x64\x65\x66\x73\x33\x31\x37\x35\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\ +\x6d\x20\x31\x34\x2e\x31\x37\x35\x2c\x2d\x33\x2e\x31\x35\x30\x39\ +\x38\x35\x35\x20\x63\x20\x30\x2c\x2d\x30\x2e\x37\x32\x35\x20\x30\ +\x2e\x35\x37\x35\x2c\x2d\x31\x2e\x33\x30\x30\x30\x30\x30\x31\x20\ +\x31\x2e\x33\x2c\x2d\x31\x2e\x33\x30\x30\x30\x30\x30\x31\x20\x30\ +\x2e\x37\x32\x35\x2c\x30\x20\x31\x2e\x33\x2c\x30\x2e\x35\x37\x35\ +\x30\x30\x30\x31\x20\x31\x2e\x33\x2c\x31\x2e\x33\x30\x30\x30\x30\ +\x30\x31\x20\x30\x2c\x30\x2e\x37\x32\x35\x20\x2d\x30\x2e\x35\x37\ +\x35\x2c\x31\x2e\x32\x39\x39\x39\x39\x39\x39\x20\x2d\x31\x2e\x33\ +\x2c\x31\x2e\x32\x39\x39\x39\x39\x39\x39\x20\x2d\x30\x2e\x37\x32\ +\x35\x2c\x30\x20\x2d\x31\x2e\x33\x2c\x2d\x30\x2e\x35\x37\x34\x39\ +\x39\x39\x39\x20\x2d\x31\x2e\x33\x2c\x2d\x31\x2e\x32\x39\x39\x39\ +\x39\x39\x39\x20\x7a\x20\x6d\x20\x30\x2c\x2d\x36\x2e\x32\x35\x30\ +\x30\x30\x30\x31\x20\x63\x20\x30\x2c\x2d\x30\x2e\x37\x32\x35\x30\ +\x30\x30\x34\x20\x30\x2e\x35\x37\x35\x2c\x2d\x31\x2e\x33\x30\x30\ +\x30\x30\x30\x34\x20\x31\x2e\x33\x2c\x2d\x31\x2e\x33\x30\x30\x30\ +\x30\x30\x34\x20\x30\x2e\x37\x32\x35\x2c\x30\x20\x31\x2e\x33\x2c\ +\x30\x2e\x35\x37\x35\x20\x31\x2e\x33\x2c\x31\x2e\x33\x30\x30\x30\ +\x30\x30\x34\x20\x30\x2c\x30\x2e\x37\x32\x35\x20\x2d\x30\x2e\x35\ +\x37\x35\x2c\x31\x2e\x33\x20\x2d\x31\x2e\x33\x2c\x31\x2e\x33\x20\ +\x2d\x30\x2e\x37\x32\x35\x2c\x30\x20\x2d\x31\x2e\x33\x2c\x2d\x30\ +\x2e\x35\x37\x35\x20\x2d\x31\x2e\x33\x2c\x2d\x31\x2e\x33\x20\x7a\ +\x20\x4d\x20\x36\x2e\x31\x2c\x2d\x31\x32\x2e\x38\x30\x30\x39\x38\ +\x36\x20\x63\x20\x34\x2e\x32\x37\x35\x2c\x30\x20\x37\x2e\x33\x2c\ +\x32\x2e\x31\x35\x20\x37\x2e\x33\x2c\x36\x2e\x32\x30\x30\x30\x30\ +\x30\x34\x20\x30\x2c\x36\x2e\x35\x37\x35\x30\x30\x30\x30\x33\x20\ +\x2d\x36\x2e\x36\x2c\x31\x30\x2e\x33\x37\x35\x20\x2d\x31\x32\x2e\ +\x39\x32\x35\x2c\x31\x33\x2e\x30\x32\x35\x20\x2d\x30\x2e\x30\x35\ +\x2c\x30\x2e\x30\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\x30\x2e\x30\ +\x37\x35\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x30\x37\x35\x20\x2d\x30\ +\x2e\x31\x35\x2c\x30\x20\x2d\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\ +\x31\x32\x35\x20\x2d\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x32\x37\ +\x35\x20\x30\x2c\x2d\x30\x2e\x30\x37\x35\x20\x30\x2e\x30\x32\x35\ +\x2c\x2d\x30\x2e\x31\x35\x20\x30\x2e\x30\x37\x35\x2c\x2d\x30\x2e\ +\x32\x20\x35\x2e\x30\x37\x35\x2c\x2d\x32\x2e\x39\x35\x20\x31\x30\ +\x2e\x33\x37\x35\x2c\x2d\x36\x2e\x36\x32\x34\x39\x39\x39\x39\x37\ +\x20\x31\x30\x2e\x33\x37\x35\x2c\x2d\x31\x32\x2e\x33\x35\x20\x30\ +\x2c\x2d\x33\x2e\x30\x32\x35\x20\x2d\x31\x2e\x36\x2c\x2d\x35\x2e\ +\x39\x32\x35\x30\x30\x30\x34\x20\x2d\x34\x2e\x33\x35\x2c\x2d\x35\ +\x2e\x39\x32\x35\x30\x30\x30\x34\x20\x2d\x31\x2e\x39\x37\x35\x2c\ +\x30\x20\x2d\x33\x2e\x34\x35\x2c\x31\x2e\x34\x32\x35\x20\x2d\x34\ +\x2e\x31\x2c\x33\x2e\x33\x32\x35\x30\x30\x30\x34\x20\x30\x2e\x33\ +\x35\x2c\x2d\x30\x2e\x32\x20\x30\x2e\x37\x2c\x2d\x30\x2e\x33\x32\ +\x35\x20\x31\x2e\x30\x37\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x31\ +\x2e\x33\x37\x35\x2c\x30\x20\x32\x2e\x35\x2c\x31\x2e\x31\x32\x35\ +\x20\x32\x2e\x35\x2c\x32\x2e\x35\x20\x30\x2c\x31\x2e\x34\x35\x20\ +\x2d\x31\x2e\x31\x2c\x32\x2e\x36\x37\x35\x30\x30\x30\x31\x20\x2d\ +\x32\x2e\x35\x2c\x32\x2e\x36\x37\x35\x30\x30\x30\x31\x20\x2d\x31\ +\x2e\x35\x2c\x30\x20\x2d\x32\x2e\x38\x2c\x2d\x31\x2e\x32\x30\x30\ +\x30\x30\x30\x31\x20\x2d\x32\x2e\x38\x2c\x2d\x32\x2e\x36\x37\x35\ +\x30\x30\x30\x31\x20\x30\x2c\x2d\x33\x2e\x33\x30\x30\x30\x30\x30\ +\x34\x20\x32\x2e\x35\x37\x35\x2c\x2d\x36\x2e\x30\x35\x30\x30\x30\ +\x30\x34\x20\x35\x2e\x38\x32\x35\x2c\x2d\x36\x2e\x30\x35\x30\x30\ +\x30\x30\x34\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x33\x31\x37\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ +\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\ +\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x07\x1e\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x32\x39\x38\x33\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x6e\x6f\ +\x74\x65\x68\x65\x61\x64\x73\x42\x6c\x61\x63\x6b\x2e\x73\x76\x67\ +\x22\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\ +\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\ +\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\ +\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\ +\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\ +\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\ +\x69\x64\x74\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x34\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\ +\x77\x36\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x35\ +\x2e\x31\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x78\x3d\x22\x33\x2e\x30\x35\x30\x32\x31\x31\ +\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x79\x3d\x22\x39\x39\x33\x2e\x32\x37\x30\x30\x37\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x79\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ +\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\ +\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x32\x39\x38\ +\x33\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x32\x39\x39\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ +\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ +\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ +\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ +\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ +\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x64\x65\x66\x73\x32\x39\x38\x39\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\ +\x22\x6d\x20\x35\x2e\x33\x33\x35\x31\x36\x39\x34\x2c\x2d\x33\x2e\ +\x34\x20\x63\x20\x31\x2e\x33\x32\x35\x2c\x30\x20\x32\x2e\x36\x32\ +\x35\x2c\x30\x2e\x36\x35\x20\x32\x2e\x36\x32\x35\x2c\x32\x2e\x31\ +\x35\x20\x30\x2c\x31\x2e\x37\x37\x35\x20\x2d\x31\x2e\x34\x32\x35\ +\x2c\x33\x2e\x30\x35\x20\x2d\x32\x2e\x36\x2c\x33\x2e\x37\x35\x20\ +\x2d\x30\x2e\x39\x2c\x30\x2e\x35\x35\x20\x2d\x31\x2e\x39\x35\x2c\ +\x30\x2e\x39\x20\x2d\x33\x2c\x30\x2e\x39\x20\x2d\x31\x2e\x33\x32\ +\x34\x39\x39\x39\x39\x2c\x30\x20\x2d\x32\x2e\x36\x32\x34\x39\x39\ +\x39\x39\x31\x2c\x2d\x30\x2e\x36\x35\x20\x2d\x32\x2e\x36\x32\x34\ +\x39\x39\x39\x39\x31\x2c\x2d\x32\x2e\x31\x35\x20\x30\x2c\x2d\x31\ +\x2e\x37\x37\x35\x20\x31\x2e\x34\x35\x30\x30\x30\x30\x30\x31\x2c\ +\x2d\x33\x2e\x30\x35\x20\x32\x2e\x36\x32\x34\x39\x39\x39\x39\x31\ +\x2c\x2d\x33\x2e\x37\x35\x20\x30\x2e\x39\x2c\x2d\x30\x2e\x35\x35\ +\x20\x31\x2e\x39\x32\x35\x2c\x2d\x30\x2e\x39\x20\x32\x2e\x39\x37\ +\x35\x2c\x2d\x30\x2e\x39\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x70\x61\x74\x68\x32\x39\x38\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ +\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ +\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x08\x4b\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x33\x34\x36\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x31\x36\x69\x2e\x73\x76\ +\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x33\x33\x35\x34\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x64\x65\x66\x73\x33\x33\x35\x32\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ +\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ +\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\ +\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\ +\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ +\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\ +\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x34\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x33\x35\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x78\x3d\x22\x31\x32\x2e\x30\x36\x30\x37\x32\x39\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ +\x31\x30\x30\x30\x2e\x34\x34\x37\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x33\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\ +\x3d\x22\x73\x76\x67\x33\x33\x34\x36\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\ +\x2d\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\x2e\x64\x34\x22\ +\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x2d\x30\x2e\x31\x30\ +\x32\x36\x36\x35\x31\x31\x2c\x35\x2e\x37\x32\x35\x33\x32\x30\x31\ +\x20\x63\x20\x32\x2e\x33\x32\x34\x39\x39\x39\x38\x31\x2c\x2d\x31\ +\x2e\x33\x32\x35\x20\x35\x2e\x33\x39\x39\x39\x39\x39\x38\x31\x2c\ +\x2d\x33\x2e\x33\x37\x35\x20\x35\x2e\x33\x39\x39\x39\x39\x39\x38\ +\x31\x2c\x2d\x35\x2e\x39\x39\x39\x39\x39\x39\x39\x35\x20\x30\x2c\ +\x2d\x30\x2e\x36\x32\x34\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\x31\ +\x32\x35\x2c\x2d\x31\x2e\x32\x34\x39\x39\x39\x39\x39\x35\x20\x2d\ +\x30\x2e\x33\x35\x2c\x2d\x31\x2e\x38\x32\x34\x39\x39\x39\x39\x35\ +\x20\x2d\x32\x2c\x32\x2e\x32\x37\x34\x39\x39\x39\x39\x36\x20\x2d\ +\x35\x2e\x30\x34\x39\x39\x39\x39\x38\x31\x2c\x34\x2e\x30\x37\x34\ +\x39\x39\x39\x39\x20\x2d\x35\x2e\x30\x34\x39\x39\x39\x39\x38\x31\ +\x2c\x37\x2e\x31\x39\x39\x39\x39\x39\x39\x20\x6c\x20\x30\x2c\x30\ +\x2e\x36\x32\x35\x20\x7a\x20\x6d\x20\x36\x2e\x37\x32\x34\x39\x39\ +\x39\x38\x31\x2c\x2d\x31\x31\x2e\x36\x32\x35\x20\x63\x20\x30\x2c\ +\x31\x2e\x31\x20\x2d\x30\x2e\x34\x2c\x32\x2e\x30\x35\x20\x2d\x30\ +\x2e\x39\x37\x35\x2c\x32\x2e\x39\x20\x30\x2e\x34\x2c\x30\x2e\x38\ +\x35\x20\x30\x2e\x36\x32\x35\x2c\x31\x2e\x37\x37\x35\x30\x30\x30\ +\x31\x20\x30\x2e\x36\x32\x35\x2c\x32\x2e\x37\x32\x35\x30\x30\x30\ +\x30\x35\x20\x30\x2c\x34\x2e\x35\x34\x39\x39\x39\x39\x39\x35\x20\ +\x2d\x36\x2e\x33\x37\x34\x39\x39\x39\x38\x31\x2c\x36\x2e\x34\x34\ +\x39\x39\x39\x39\x39\x35\x20\x2d\x36\x2e\x33\x37\x34\x39\x39\x39\ +\x38\x31\x2c\x31\x31\x2e\x30\x30\x30\x30\x30\x30\x38\x35\x20\x6c\ +\x20\x2d\x30\x2e\x33\x35\x2c\x30\x20\x30\x2c\x2d\x31\x32\x2e\x35\ +\x30\x30\x30\x30\x30\x38\x20\x30\x2e\x33\x35\x2c\x30\x20\x30\x2c\ +\x31\x2e\x38\x37\x34\x39\x39\x39\x39\x36\x20\x43\x20\x32\x2e\x33\ +\x37\x32\x33\x33\x34\x37\x2c\x2d\x31\x2e\x31\x37\x34\x36\x37\x39\ +\x38\x20\x35\x2e\x36\x34\x37\x33\x33\x34\x37\x2c\x2d\x33\x2e\x31\ +\x39\x39\x36\x37\x39\x39\x20\x35\x2e\x36\x34\x37\x33\x33\x34\x37\ +\x2c\x2d\x35\x2e\x38\x39\x39\x36\x37\x39\x39\x20\x63\x20\x30\x2c\ +\x2d\x30\x2e\x35\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\x2d\x31\x2e\ +\x30\x37\x35\x20\x2d\x30\x2e\x33\x32\x35\x2c\x2d\x31\x2e\x35\x37\ +\x35\x20\x2d\x30\x2e\x30\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\ +\x30\x2e\x32\x32\x35\x2c\x2d\x30\x2e\x36\x32\x35\x20\x30\x2e\x35\ +\x32\x35\x2c\x2d\x30\x2e\x36\x32\x35\x20\x30\x2e\x37\x2c\x30\x20\ +\x30\x2e\x37\x37\x35\x2c\x31\x2e\x36\x20\x30\x2e\x37\x37\x35\x2c\ +\x32\x2e\x32\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x33\x33\x34\x38\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ +\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\ +\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\x0c\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x34\x31\x31\x22\x3e\x0a\ +\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x34\x31\ +\x39\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ +\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ +\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ +\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ +\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x34\x31\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x6d\x20\x32\x2e\x38\x32\x35\x2c\x31\x35\x2e\x36\ +\x39\x32\x33\x39\x33\x20\x32\x2e\x31\x35\x2c\x2d\x38\x2e\x31\x39\ +\x39\x39\x39\x39\x38\x20\x63\x20\x2d\x30\x2e\x39\x2c\x30\x2e\x33\ +\x32\x35\x20\x2d\x31\x2e\x38\x32\x35\x2c\x30\x2e\x36\x20\x2d\x32\ +\x2e\x38\x2c\x30\x2e\x36\x20\x2d\x31\x2e\x31\x35\x2c\x30\x20\x2d\ +\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\x20\x2d\x32\x2e\x31\ +\x37\x35\x2c\x2d\x32\x20\x30\x2c\x2d\x30\x2e\x39\x37\x35\x20\x30\ +\x2e\x37\x37\x35\x2c\x2d\x31\x2e\x37\x37\x35\x20\x31\x2e\x37\x37\ +\x35\x2c\x2d\x31\x2e\x37\x37\x35\x20\x30\x2e\x36\x35\x2c\x30\x20\ +\x31\x2e\x32\x2c\x30\x2e\x34\x20\x31\x2e\x34\x2c\x31\x20\x30\x2e\ +\x32\x35\x2c\x30\x2e\x37\x20\x30\x2e\x31\x37\x35\x2c\x31\x2e\x35\ +\x20\x30\x2e\x39\x2c\x31\x2e\x35\x20\x30\x2e\x34\x32\x35\x2c\x30\ +\x20\x31\x2e\x34\x32\x35\x2c\x2d\x31\x2e\x33\x35\x20\x31\x2e\x35\ +\x35\x2c\x2d\x31\x2e\x38\x20\x6c\x20\x30\x2e\x39\x37\x35\x2c\x2d\ +\x33\x2e\x37\x35\x20\x63\x20\x2d\x30\x2e\x38\x37\x35\x2c\x30\x2e\ +\x33\x32\x35\x20\x2d\x31\x2e\x38\x2c\x30\x2e\x35\x37\x35\x20\x2d\ +\x32\x2e\x37\x32\x35\x2c\x30\x2e\x35\x37\x35\x20\x2d\x31\x2e\x31\ +\x35\x2c\x30\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\ +\x30\x30\x30\x30\x30\x35\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x32\ +\x2e\x30\x30\x30\x30\x30\x30\x30\x35\x20\x30\x2c\x2d\x30\x2e\x39\ +\x37\x34\x39\x39\x39\x39\x35\x20\x30\x2e\x38\x2c\x2d\x31\x2e\x37\ +\x37\x34\x39\x39\x39\x39\x35\x20\x31\x2e\x38\x2c\x2d\x31\x2e\x37\ +\x37\x34\x39\x39\x39\x39\x35\x20\x30\x2e\x36\x35\x2c\x30\x20\x31\ +\x2e\x32\x2c\x30\x2e\x34\x20\x31\x2e\x34\x2c\x30\x2e\x39\x39\x39\ +\x39\x39\x39\x39\x35\x20\x30\x2e\x32\x35\x2c\x30\x2e\x37\x20\x30\ +\x2e\x31\x37\x35\x2c\x31\x2e\x35\x20\x30\x2e\x39\x2c\x31\x2e\x35\ +\x20\x30\x2e\x34\x32\x35\x2c\x30\x20\x31\x2e\x33\x35\x2c\x2d\x31\ +\x2e\x33\x32\x35\x20\x31\x2e\x34\x35\x2c\x2d\x31\x2e\x37\x34\x39\ +\x39\x39\x39\x39\x35\x20\x6c\x20\x31\x2c\x2d\x33\x2e\x38\x20\x63\ +\x20\x2d\x30\x2e\x38\x35\x2c\x30\x2e\x33\x20\x2d\x31\x2e\x37\x35\ +\x2c\x30\x2e\x35\x37\x35\x20\x2d\x32\x2e\x36\x35\x2c\x30\x2e\x35\ +\x37\x35\x20\x2d\x31\x2e\x31\x35\x2c\x30\x20\x2d\x32\x2e\x31\x37\ +\x35\x2c\x2d\x30\x2e\x38\x35\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\ +\x32\x20\x30\x2c\x2d\x30\x2e\x39\x37\x35\x20\x30\x2e\x37\x37\x35\ +\x2c\x2d\x31\x2e\x37\x37\x35\x20\x31\x2e\x37\x37\x35\x2c\x2d\x31\ +\x2e\x37\x37\x35\x20\x30\x2e\x36\x35\x2c\x30\x20\x31\x2e\x32\x32\ +\x35\x2c\x30\x2e\x34\x20\x31\x2e\x34\x32\x35\x2c\x31\x20\x30\x2e\ +\x32\x35\x2c\x30\x2e\x37\x20\x30\x2e\x31\x35\x2c\x31\x2e\x35\x20\ +\x30\x2e\x38\x37\x35\x2c\x31\x2e\x35\x20\x30\x2e\x34\x2c\x30\x20\ +\x31\x2e\x32\x32\x35\x2c\x2d\x31\x2e\x33\x35\x20\x31\x2e\x33\x37\ +\x35\x2c\x2d\x31\x2e\x37\x35\x20\x30\x2e\x31\x2c\x2d\x30\x2e\x32\ +\x37\x35\x20\x30\x2e\x35\x2c\x2d\x30\x2e\x32\x37\x35\x20\x30\x2e\ +\x36\x2c\x30\x20\x4c\x20\x34\x2c\x31\x35\x2e\x36\x39\x32\x33\x39\ +\x33\x20\x63\x20\x2d\x30\x2e\x31\x37\x35\x2c\x30\x2e\x31\x35\x20\ +\x2d\x30\x2e\x33\x37\x35\x2c\x30\x2e\x32\x32\x35\x20\x2d\x30\x2e\ +\x35\x37\x35\x2c\x30\x2e\x32\x32\x35\x20\x2d\x30\x2e\x32\x2c\x30\ +\x20\x2d\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x30\x37\x35\x20\x2d\ +\x30\x2e\x36\x2c\x2d\x30\x2e\x32\x32\x35\x20\x7a\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x34\x31\x33\x22\ +\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x03\xf1\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x22\x3e\x0a\x20\x20\x3c\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x31\x30\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ +\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ +\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ +\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x64\x65\x66\x73\x38\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\ +\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x30\x2e\ +\x33\x35\x2c\x36\x2e\x32\x35\x20\x43\x20\x32\x2e\x38\x32\x35\x2c\ +\x37\x2e\x37\x32\x35\x20\x36\x2e\x31\x2c\x31\x30\x20\x36\x2e\x31\ +\x2c\x31\x32\x2e\x38\x32\x35\x20\x63\x20\x30\x2c\x31\x2e\x36\x32\ +\x35\x20\x2d\x30\x2e\x35\x32\x35\x2c\x33\x2e\x32\x32\x35\x20\x2d\ +\x31\x2e\x33\x35\x2c\x34\x2e\x36\x32\x35\x20\x2d\x30\x2e\x30\x37\ +\x35\x2c\x30\x2e\x33\x37\x35\x20\x30\x2e\x32\x32\x35\x2c\x30\x2e\ +\x36\x32\x35\x20\x30\x2e\x35\x32\x35\x2c\x30\x2e\x36\x32\x35\x20\ +\x30\x2e\x31\x37\x35\x2c\x30\x20\x30\x2e\x33\x35\x2c\x2d\x30\x2e\ +\x31\x20\x30\x2e\x34\x35\x2c\x2d\x30\x2e\x32\x37\x35\x20\x30\x2e\ +\x38\x32\x35\x2c\x2d\x31\x2e\x35\x32\x35\x20\x31\x2e\x33\x35\x2c\ +\x2d\x33\x2e\x32\x32\x35\x20\x31\x2e\x33\x35\x2c\x2d\x34\x2e\x39\ +\x37\x35\x20\x43\x20\x37\x2e\x30\x37\x35\x2c\x37\x2e\x37\x20\x30\ +\x2e\x33\x35\x2c\x35\x2e\x31\x32\x35\x20\x30\x2e\x33\x35\x2c\x30\ +\x20\x48\x20\x30\x20\x76\x20\x36\x2e\x32\x35\x20\x68\x20\x30\x2e\ +\x33\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\ +\x61\x74\x68\x34\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\ +\x00\x00\x05\x7e\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x38\x35\x38\ +\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\ +\x2e\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\ +\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\ +\x6e\x3d\x22\x31\x2e\x31\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x33\x38\x36\x36\x22\x3e\x0a\x20\x20\x20\ +\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\ +\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\ +\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\ +\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ +\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\ +\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\ +\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\ +\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x64\x65\x66\x73\x33\x38\x36\x34\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\ +\x74\x68\x33\x38\x36\x30\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\ +\x6d\x20\x30\x2e\x33\x35\x2c\x35\x2e\x32\x39\x31\x37\x39\x33\x31\ +\x20\x63\x20\x32\x2e\x32\x35\x2c\x31\x2e\x34\x32\x35\x20\x35\x2e\ +\x32\x32\x35\x2c\x33\x2e\x35\x37\x35\x20\x35\x2e\x32\x32\x35\x2c\ +\x36\x2e\x31\x37\x34\x39\x39\x39\x39\x20\x30\x2c\x30\x2e\x34\x37\ +\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\x30\x2e\x39\x35\x20\x2d\x30\ +\x2e\x33\x2c\x31\x2e\x33\x37\x35\x20\x43\x20\x33\x2e\x33\x35\x2c\ +\x31\x30\x2e\x35\x36\x36\x37\x39\x33\x20\x30\x2e\x33\x35\x2c\x38\ +\x2e\x37\x36\x36\x37\x39\x33\x31\x20\x30\x2e\x33\x35\x2c\x35\x2e\ +\x36\x36\x36\x37\x39\x33\x31\x20\x6c\x20\x30\x2c\x2d\x30\x2e\x33\ +\x37\x35\x20\x7a\x20\x4d\x20\x37\x2e\x30\x37\x35\x2c\x32\x32\x2e\ +\x31\x39\x31\x37\x39\x33\x20\x63\x20\x30\x2c\x2d\x31\x2e\x31\x20\ +\x2d\x30\x2e\x33\x37\x35\x2c\x2d\x32\x2e\x30\x32\x35\x20\x2d\x30\ +\x2e\x39\x35\x2c\x2d\x32\x2e\x38\x37\x35\x20\x30\x2e\x34\x37\x35\ +\x2c\x2d\x30\x2e\x38\x35\x20\x30\x2e\x37\x35\x2c\x2d\x31\x2e\x37\ +\x37\x35\x20\x30\x2e\x37\x35\x2c\x2d\x32\x2e\x37\x35\x20\x30\x2c\ +\x2d\x31\x2e\x30\x37\x35\x20\x2d\x30\x2e\x33\x37\x35\x2c\x2d\x32\ +\x20\x2d\x30\x2e\x39\x32\x35\x2c\x2d\x32\x2e\x38\x35\x20\x30\x2e\ +\x33\x37\x35\x2c\x2d\x30\x2e\x37\x20\x30\x2e\x36\x2c\x2d\x31\x2e\ +\x34\x37\x35\x20\x30\x2e\x36\x2c\x2d\x32\x2e\x32\x35\x20\x30\x2c\ +\x2d\x34\x2e\x36\x32\x34\x39\x39\x39\x39\x20\x2d\x36\x2e\x32\x2c\ +\x2d\x36\x2e\x37\x39\x39\x39\x39\x39\x39\x20\x2d\x36\x2e\x32\x2c\ +\x2d\x31\x31\x2e\x34\x32\x34\x39\x39\x39\x39\x20\x6c\x20\x2d\x30\ +\x2e\x33\x35\x2c\x30\x20\x30\x2c\x31\x38\x2e\x37\x34\x39\x39\x39\ +\x39\x39\x20\x30\x2e\x33\x35\x2c\x30\x20\x30\x2c\x2d\x32\x2e\x32\ +\x35\x20\x63\x20\x32\x2e\x34\x37\x35\x2c\x31\x2e\x31\x35\x20\x35\ +\x2e\x37\x35\x2c\x33\x2e\x30\x32\x35\x20\x35\x2e\x37\x35\x2c\x35\ +\x2e\x36\x35\x20\x30\x2c\x30\x2e\x35\x35\x20\x2d\x30\x2e\x31\x32\ +\x35\x2c\x31\x2e\x30\x35\x20\x2d\x30\x2e\x33\x32\x35\x2c\x31\x2e\ +\x35\x35\x20\x2d\x30\x2e\x30\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\ +\x30\x2e\x32\x32\x35\x2c\x30\x2e\x36\x32\x35\x20\x30\x2e\x35\x32\ +\x35\x2c\x30\x2e\x36\x32\x35\x20\x30\x2e\x37\x2c\x30\x20\x30\x2e\ +\x37\x37\x35\x2c\x2d\x31\x2e\x35\x37\x35\x20\x30\x2e\x37\x37\x35\ +\x2c\x2d\x32\x2e\x31\x37\x35\x20\x7a\x20\x6d\x20\x2d\x36\x2e\x37\ +\x32\x35\x2c\x2d\x31\x31\x2e\x32\x37\x35\x20\x63\x20\x32\x2e\x34\ +\x2c\x31\x2e\x31\x37\x35\x20\x35\x2e\x35\x35\x2c\x33\x2e\x30\x37\ +\x35\x20\x35\x2e\x35\x35\x2c\x35\x2e\x36\x35\x20\x30\x2c\x30\x2e\ +\x36\x37\x35\x20\x2d\x30\x2e\x31\x37\x35\x2c\x31\x2e\x33\x20\x2d\ +\x30\x2e\x34\x35\x2c\x31\x2e\x39\x20\x2d\x32\x2c\x2d\x32\x2e\x32\ +\x37\x35\x20\x2d\x35\x2e\x31\x2c\x2d\x34\x2e\x30\x35\x20\x2d\x35\ +\x2e\x31\x2c\x2d\x37\x2e\x31\x37\x35\x20\x6c\x20\x30\x2c\x2d\x30\ +\x2e\x33\x37\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\ +\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\x2e\x64\ +\x35\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0a\xfd\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x34\x34\x38\x35\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x65\x66\x56\x69\x6f\x6c\x61\x2e\ +\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x34\x34\x39\x33\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ +\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ +\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ +\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ +\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ +\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\ +\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\ +\x73\x34\x34\x39\x31\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\ +\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x34\x34\x38\x39\x22\x0a\x20\x20\ +\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x33\x34\x30\x30\x37\x30\ +\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x78\x3d\x22\x31\x30\x37\x2e\x34\x32\x35\x32\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ +\x3d\x22\x31\x30\x35\x32\x2e\x38\x36\x34\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ +\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\ +\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\ +\x65\x72\x3d\x22\x73\x76\x67\x34\x34\x38\x35\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\ +\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x65\x66\x73\x2e\x43\ +\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x2e\x38\x2c\ +\x30\x20\x63\x20\x30\x2c\x2d\x30\x2e\x38\x32\x35\x20\x30\x2e\x31\ +\x37\x35\x2c\x2d\x31\x2e\x38\x35\x20\x31\x2e\x31\x35\x2c\x2d\x31\ +\x2e\x38\x35\x20\x30\x2e\x37\x32\x35\x2c\x30\x20\x31\x2e\x34\x32\ +\x35\x2c\x30\x2e\x37\x32\x35\x20\x32\x2e\x32\x2c\x30\x2e\x37\x32\ +\x35\x20\x33\x2e\x30\x37\x35\x2c\x30\x20\x35\x2e\x37\x37\x35\x2c\ +\x2d\x32\x2e\x31\x37\x35\x20\x35\x2e\x37\x37\x35\x2c\x2d\x35\x2e\ +\x31\x32\x35\x20\x30\x2c\x2d\x34\x2e\x32\x35\x20\x2d\x32\x2e\x33\ +\x37\x35\x2c\x2d\x36\x2e\x32\x35\x20\x2d\x36\x2e\x37\x32\x35\x2c\ +\x2d\x36\x2e\x32\x35\x20\x2d\x32\x2e\x30\x37\x35\x2c\x30\x20\x2d\ +\x33\x2e\x38\x35\x2c\x31\x2e\x35\x35\x20\x2d\x33\x2e\x38\x35\x2c\ +\x33\x2e\x35\x37\x35\x20\x30\x2c\x31\x2e\x30\x35\x20\x30\x2e\x38\ +\x37\x35\x2c\x31\x2e\x39\x32\x35\x20\x31\x2e\x39\x32\x35\x2c\x31\ +\x2e\x39\x32\x35\x20\x31\x2e\x30\x35\x2c\x30\x20\x31\x2e\x39\x32\ +\x35\x2c\x2d\x30\x2e\x38\x37\x35\x20\x31\x2e\x39\x32\x35\x2c\x2d\ +\x31\x2e\x39\x32\x35\x20\x30\x2c\x2d\x31\x20\x2d\x31\x2e\x32\x37\ +\x35\x2c\x2d\x30\x2e\x39\x32\x35\x20\x2d\x31\x2e\x32\x37\x35\x2c\ +\x2d\x31\x2e\x39\x32\x35\x20\x30\x2c\x2d\x30\x2e\x36\x20\x30\x2e\ +\x36\x32\x35\x2c\x2d\x31\x20\x31\x2e\x32\x37\x35\x2c\x2d\x31\x20\ +\x32\x2e\x39\x32\x35\x2c\x30\x20\x33\x2e\x35\x32\x35\x2c\x32\x2e\ +\x32\x37\x35\x20\x33\x2e\x35\x32\x35\x2c\x35\x2e\x36\x20\x30\x2c\ +\x32\x2e\x36\x32\x35\x20\x2d\x30\x2e\x33\x2c\x34\x2e\x35\x20\x2d\ +\x32\x2e\x35\x37\x35\x2c\x34\x2e\x35\x20\x43\x20\x39\x2e\x33\x2c\ +\x2d\x31\x2e\x37\x35\x20\x38\x2e\x31\x2c\x2d\x33\x2e\x36\x20\x38\ +\x2e\x31\x2c\x2d\x35\x2e\x35\x37\x35\x20\x38\x2e\x31\x2c\x2d\x35\ +\x2e\x38\x20\x37\x2e\x39\x35\x2c\x2d\x35\x2e\x39\x20\x37\x2e\x38\ +\x2c\x2d\x35\x2e\x39\x20\x63\x20\x2d\x30\x2e\x31\x35\x2c\x30\x20\ +\x2d\x30\x2e\x33\x32\x35\x2c\x30\x2e\x31\x20\x2d\x30\x2e\x33\x32\ +\x35\x2c\x30\x2e\x33\x32\x35\x20\x30\x2c\x31\x2e\x39\x32\x35\x20\ +\x2d\x30\x2e\x37\x37\x35\x2c\x33\x2e\x37\x35\x20\x2d\x32\x2e\x31\ +\x2c\x35\x2e\x31\x32\x35\x20\x6c\x20\x30\x2c\x2d\x31\x31\x2e\x38\ +\x35\x20\x63\x20\x30\x2c\x2d\x30\x2e\x31\x20\x2d\x30\x2e\x31\x2c\ +\x2d\x30\x2e\x32\x20\x2d\x30\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x6c\ +\x20\x2d\x30\x2e\x35\x35\x2c\x30\x20\x63\x20\x2d\x30\x2e\x31\x2c\ +\x30\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x31\x20\x2d\x30\x2e\x32\x2c\ +\x30\x2e\x32\x20\x6c\x20\x30\x2c\x32\x34\x2e\x36\x20\x63\x20\x30\ +\x2c\x30\x2e\x31\x20\x30\x2e\x31\x2c\x30\x2e\x32\x20\x30\x2e\x32\ +\x2c\x30\x2e\x32\x20\x6c\x20\x30\x2e\x35\x35\x2c\x30\x20\x63\x20\ +\x30\x2e\x31\x2c\x30\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x31\x20\x30\ +\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x6c\x20\x30\x2c\x2d\x31\x31\x2e\ +\x38\x35\x20\x63\x20\x31\x2e\x33\x32\x35\x2c\x31\x2e\x33\x37\x35\ +\x20\x32\x2e\x31\x2c\x33\x2e\x32\x20\x32\x2e\x31\x2c\x35\x2e\x31\ +\x32\x35\x20\x43\x20\x37\x2e\x34\x37\x35\x2c\x35\x2e\x38\x20\x37\ +\x2e\x36\x35\x2c\x35\x2e\x39\x20\x37\x2e\x38\x2c\x35\x2e\x39\x20\ +\x37\x2e\x39\x35\x2c\x35\x2e\x39\x20\x38\x2e\x31\x2c\x35\x2e\x38\ +\x20\x38\x2e\x31\x2c\x35\x2e\x35\x37\x35\x20\x38\x2e\x31\x2c\x33\ +\x2e\x36\x20\x39\x2e\x33\x2c\x31\x2e\x37\x35\x20\x31\x31\x2e\x31\ +\x35\x2c\x31\x2e\x37\x35\x20\x63\x20\x32\x2e\x32\x37\x35\x2c\x30\ +\x20\x32\x2e\x35\x37\x35\x2c\x31\x2e\x38\x37\x35\x20\x32\x2e\x35\ +\x37\x35\x2c\x34\x2e\x35\x20\x30\x2c\x33\x2e\x33\x32\x35\x20\x2d\ +\x30\x2e\x36\x2c\x35\x2e\x36\x20\x2d\x33\x2e\x35\x32\x35\x2c\x35\ +\x2e\x36\x20\x2d\x30\x2e\x36\x35\x2c\x30\x20\x2d\x31\x2e\x32\x37\ +\x35\x2c\x2d\x30\x2e\x34\x20\x2d\x31\x2e\x32\x37\x35\x2c\x2d\x31\ +\x20\x30\x2c\x2d\x31\x20\x31\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x39\ +\x32\x35\x20\x31\x2e\x32\x37\x35\x2c\x2d\x31\x2e\x39\x32\x35\x20\ +\x43\x20\x31\x30\x2e\x32\x2c\x37\x2e\x38\x37\x35\x20\x39\x2e\x33\ +\x32\x35\x2c\x37\x20\x38\x2e\x32\x37\x35\x2c\x37\x20\x37\x2e\x32\ +\x32\x35\x2c\x37\x20\x36\x2e\x33\x35\x2c\x37\x2e\x38\x37\x35\x20\ +\x36\x2e\x33\x35\x2c\x38\x2e\x39\x32\x35\x20\x63\x20\x30\x2c\x32\ +\x2e\x30\x32\x35\x20\x31\x2e\x37\x37\x35\x2c\x33\x2e\x35\x37\x35\ +\x20\x33\x2e\x38\x35\x2c\x33\x2e\x35\x37\x35\x20\x34\x2e\x33\x35\ +\x2c\x30\x20\x36\x2e\x37\x32\x35\x2c\x2d\x32\x20\x36\x2e\x37\x32\ +\x35\x2c\x2d\x36\x2e\x32\x35\x20\x30\x2c\x2d\x32\x2e\x39\x35\x20\ +\x2d\x32\x2e\x37\x2c\x2d\x35\x2e\x31\x32\x35\x20\x2d\x35\x2e\x37\ +\x37\x35\x2c\x2d\x35\x2e\x31\x32\x35\x20\x2d\x30\x2e\x37\x37\x35\ +\x2c\x30\x20\x2d\x31\x2e\x34\x37\x35\x2c\x30\x2e\x37\x32\x35\x20\ +\x2d\x32\x2e\x32\x2c\x30\x2e\x37\x32\x35\x20\x43\x20\x37\x2e\x39\ +\x37\x35\x2c\x31\x2e\x38\x35\x20\x37\x2e\x38\x2c\x30\x2e\x38\x32\ +\x35\x20\x37\x2e\x38\x2c\x30\x20\x5a\x20\x6d\x20\x2d\x34\x2e\x35\ +\x35\x2c\x2d\x31\x32\x2e\x35\x20\x2d\x33\x2e\x30\x35\x2c\x30\x20\ +\x63\x20\x2d\x30\x2e\x31\x2c\x30\x20\x2d\x30\x2e\x32\x2c\x30\x2e\ +\x31\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x32\x20\x6c\x20\x30\x2c\x32\ +\x34\x2e\x36\x20\x63\x20\x30\x2c\x30\x2e\x31\x20\x30\x2e\x31\x2c\ +\x30\x2e\x32\x20\x30\x2e\x32\x2c\x30\x2e\x32\x20\x6c\x20\x33\x2e\ +\x30\x35\x2c\x30\x20\x63\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\x32\ +\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x6c\ +\x20\x30\x2c\x2d\x32\x34\x2e\x36\x20\x63\x20\x30\x2c\x2d\x30\x2e\ +\x31\x20\x2d\x30\x2e\x31\x2c\x2d\x30\x2e\x32\x20\x2d\x30\x2e\x32\ +\x2c\x2d\x30\x2e\x32\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x70\x61\x74\x68\x34\x34\x38\x37\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ +\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ +\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0d\x67\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x32\x39\x38\x33\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x62\x6c\ +\x6f\x63\x6b\x45\x6e\x64\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\ +\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\ +\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\ +\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\ +\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\ +\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\ +\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\ +\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\ +\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\ +\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\ +\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\ +\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\ +\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\ +\x74\x3d\x22\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\x33\x34\x30\x30\x37\x30\ +\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x78\x3d\x22\x33\x38\x2e\x35\x36\x34\x37\x36\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ +\x3d\x22\x39\x39\x31\x2e\x35\x32\x34\x38\x34\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x79\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x32\x39\x38\x33\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x32\x39\x39\x31\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\ +\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ +\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\ +\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\ +\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\ +\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\ +\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\ +\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\ +\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x64\x65\x66\x73\x32\x39\x38\x39\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x67\x0a\x20\x20\x20\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x66\ +\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x34\x30\x70\x78\x3b\x66\x6f\ +\x6e\x74\x2d\x73\x74\x79\x6c\x65\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\ +\x66\x6f\x6e\x74\x2d\x76\x61\x72\x69\x61\x6e\x74\x3a\x6e\x6f\x72\ +\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\ +\x6e\x6f\x72\x6d\x61\x6c\x3b\x66\x6f\x6e\x74\x2d\x73\x74\x72\x65\ +\x74\x63\x68\x3a\x6e\x6f\x72\x6d\x61\x6c\x3b\x6c\x69\x6e\x65\x2d\ +\x68\x65\x69\x67\x68\x74\x3a\x31\x32\x35\x25\x3b\x6c\x65\x74\x74\ +\x65\x72\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\x77\ +\x6f\x72\x64\x2d\x73\x70\x61\x63\x69\x6e\x67\x3a\x30\x70\x78\x3b\ +\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\ +\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x73\x74\x72\x6f\ +\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x66\x6f\x6e\x74\x2d\x66\x61\x6d\ +\x69\x6c\x79\x3a\x27\x38\x2d\x62\x69\x74\x20\x4c\x69\x6d\x69\x74\ +\x20\x4f\x20\x42\x52\x4b\x27\x3b\x2d\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\x63\x69\x66\x69\x63\x61\ +\x74\x69\x6f\x6e\x3a\x27\x38\x2d\x62\x69\x74\x20\x4c\x69\x6d\x69\ +\x74\x20\x4f\x20\x42\x52\x4b\x27\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x74\x65\x78\x74\x33\x37\x33\x39\x22\x0a\x20\x20\x20\ +\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\ +\x6e\x73\x6c\x61\x74\x65\x28\x2d\x32\x31\x2e\x34\x34\x31\x36\x36\ +\x35\x2c\x31\x34\x2e\x38\x38\x37\x34\x34\x34\x29\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\ +\x6c\x79\x3a\x57\x65\x61\x76\x65\x72\x20\x42\x52\x4b\x3b\x2d\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x2d\x66\x6f\x6e\x74\x2d\x73\x70\x65\ +\x63\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x3a\x57\x65\x61\x76\x65\ +\x72\x20\x42\x52\x4b\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x64\x3d\ +\x22\x6d\x20\x31\x38\x2e\x36\x37\x32\x38\x33\x39\x2c\x32\x2e\x30\ +\x30\x34\x31\x30\x39\x32\x20\x63\x20\x2d\x31\x2e\x33\x32\x32\x33\ +\x34\x35\x2c\x30\x2e\x36\x36\x34\x37\x34\x35\x33\x20\x30\x2e\x37\ +\x39\x30\x33\x32\x34\x2c\x31\x2e\x32\x31\x34\x38\x30\x36\x39\x20\ +\x30\x2e\x34\x2c\x31\x2e\x36\x38\x20\x2d\x31\x2e\x30\x32\x38\x32\ +\x39\x32\x2c\x2d\x30\x2e\x31\x35\x39\x32\x30\x32\x35\x20\x2d\x32\ +\x2e\x35\x37\x33\x35\x38\x2c\x2d\x31\x2e\x30\x36\x37\x32\x34\x33\ +\x35\x20\x2d\x32\x2e\x31\x36\x31\x32\x35\x31\x2c\x2d\x32\x2e\x33\ +\x35\x36\x38\x37\x37\x37\x20\x30\x2e\x34\x33\x34\x34\x38\x34\x2c\ +\x2d\x31\x2e\x32\x38\x34\x36\x37\x30\x32\x35\x20\x31\x2e\x37\x39\ +\x39\x33\x33\x39\x2c\x2d\x31\x2e\x37\x30\x38\x31\x30\x35\x38\x39\ +\x20\x32\x2e\x37\x32\x38\x37\x34\x39\x2c\x2d\x32\x2e\x35\x32\x35\ +\x36\x32\x33\x20\x30\x2e\x36\x37\x39\x35\x35\x39\x2c\x2d\x31\x2e\ +\x30\x33\x33\x30\x37\x34\x32\x20\x2d\x31\x2e\x33\x37\x33\x36\x33\ +\x2c\x2d\x31\x2e\x31\x36\x32\x39\x37\x30\x35\x20\x2d\x31\x2e\x36\ +\x39\x37\x35\x2c\x2d\x32\x2e\x30\x34\x37\x34\x39\x38\x38\x20\x2d\ +\x31\x2e\x36\x35\x33\x36\x34\x32\x2c\x2d\x31\x2e\x38\x33\x37\x31\ +\x33\x37\x38\x20\x2d\x31\x2e\x33\x33\x35\x31\x38\x36\x2c\x2d\x34\ +\x2e\x37\x37\x32\x34\x36\x35\x33\x20\x30\x2e\x32\x33\x36\x35\x39\ +\x38\x2c\x2d\x36\x2e\x35\x34\x35\x34\x36\x31\x33\x20\x30\x2e\x36\ +\x36\x38\x30\x39\x34\x2c\x2d\x31\x2e\x30\x30\x39\x37\x38\x30\x34\ +\x20\x31\x2e\x37\x38\x36\x35\x39\x38\x2c\x2d\x31\x2e\x39\x32\x31\ +\x35\x35\x34\x34\x20\x31\x2e\x36\x37\x30\x39\x30\x32\x2c\x2d\x33\ +\x2e\x32\x34\x34\x35\x33\x33\x34\x20\x2d\x30\x2e\x31\x37\x38\x31\ +\x39\x33\x2c\x2d\x31\x2e\x33\x32\x38\x38\x32\x36\x20\x2d\x31\x2e\ +\x36\x37\x34\x31\x38\x2c\x2d\x31\x2e\x37\x30\x36\x34\x33\x35\x20\ +\x2d\x32\x2e\x32\x35\x39\x39\x39\x39\x2c\x2d\x32\x2e\x37\x39\x32\ +\x34\x39\x39\x20\x2d\x31\x2e\x33\x30\x37\x34\x35\x35\x2c\x2d\x31\ +\x2e\x39\x31\x33\x34\x34\x36\x20\x2d\x30\x2e\x38\x30\x30\x38\x36\ +\x38\x2c\x2d\x34\x2e\x35\x34\x35\x34\x38\x34\x20\x30\x2e\x36\x37\ +\x37\x39\x36\x32\x2c\x2d\x36\x2e\x32\x30\x31\x34\x35\x35\x20\x30\ +\x2e\x36\x39\x31\x33\x38\x38\x2c\x2d\x31\x2e\x30\x32\x34\x37\x35\ +\x31\x20\x31\x2e\x38\x39\x38\x34\x32\x37\x2c\x2d\x32\x2e\x30\x33\ +\x37\x31\x38\x32\x20\x31\x2e\x35\x31\x34\x35\x33\x36\x2c\x2d\x33\ +\x2e\x34\x30\x36\x30\x33\x34\x20\x2d\x30\x2e\x32\x38\x30\x33\x34\ +\x2c\x2d\x31\x2e\x33\x30\x32\x31\x39\x35\x20\x2d\x31\x2e\x37\x38\ +\x30\x38\x37\x39\x2c\x2d\x31\x2e\x33\x33\x30\x39\x39\x38\x20\x2d\ +\x32\x2e\x35\x35\x39\x35\x32\x39\x2c\x2d\x32\x2e\x31\x36\x38\x39\ +\x30\x36\x20\x2d\x30\x2e\x39\x34\x34\x32\x37\x36\x2c\x2d\x30\x2e\ +\x39\x37\x38\x31\x30\x32\x20\x30\x2e\x30\x38\x32\x34\x31\x2c\x2d\ +\x32\x2e\x33\x30\x36\x35\x36\x34\x20\x30\x2e\x39\x37\x34\x39\x37\ +\x34\x2c\x2d\x32\x2e\x38\x37\x36\x39\x35\x31\x20\x30\x2e\x35\x35\ +\x32\x30\x32\x39\x2c\x2d\x30\x2e\x34\x32\x33\x34\x39\x36\x20\x31\ +\x2e\x32\x33\x38\x33\x39\x37\x2c\x2d\x30\x2e\x37\x31\x31\x32\x36\ +\x20\x31\x2e\x36\x36\x32\x30\x35\x36\x2c\x2d\x31\x2e\x32\x36\x39\ +\x31\x34\x35\x20\x2d\x30\x2e\x30\x34\x32\x34\x37\x2c\x2d\x30\x2e\ +\x34\x39\x38\x34\x39\x36\x20\x2d\x31\x2e\x37\x33\x36\x31\x35\x33\ +\x2c\x2d\x31\x2e\x34\x39\x31\x37\x39\x38\x20\x2d\x30\x2e\x33\x38\ +\x30\x34\x36\x38\x2c\x2d\x31\x2e\x31\x33\x39\x36\x39\x38\x20\x31\ +\x2e\x33\x39\x30\x30\x35\x35\x2c\x30\x2e\x33\x32\x33\x33\x35\x32\ +\x20\x32\x2e\x34\x37\x35\x35\x31\x36\x2c\x31\x2e\x39\x34\x37\x35\ +\x32\x37\x20\x31\x2e\x32\x31\x31\x30\x39\x33\x2c\x33\x2e\x31\x30\ +\x32\x38\x31\x36\x20\x2d\x30\x2e\x36\x38\x36\x36\x37\x2c\x30\x2e\ +\x38\x30\x37\x36\x39\x36\x20\x2d\x31\x2e\x38\x34\x34\x33\x37\x2c\ +\x31\x2e\x30\x38\x36\x32\x32\x33\x20\x2d\x32\x2e\x34\x34\x35\x36\ +\x32\x34\x2c\x31\x2e\x39\x37\x34\x33\x38\x20\x30\x2e\x36\x31\x34\ +\x33\x33\x31\x2c\x31\x2e\x30\x38\x36\x32\x39\x35\x20\x32\x2e\x32\ +\x37\x35\x33\x34\x2c\x31\x2e\x35\x36\x38\x33\x38\x38\x20\x32\x2e\ +\x36\x38\x31\x32\x34\x38\x2c\x32\x2e\x39\x37\x35\x34\x37\x20\x30\ +\x2e\x38\x35\x35\x35\x30\x36\x2c\x31\x2e\x39\x34\x33\x37\x39\x31\ +\x20\x30\x2e\x30\x35\x31\x38\x33\x2c\x34\x2e\x31\x35\x31\x31\x30\ +\x33\x20\x2d\x31\x2e\x32\x36\x39\x32\x35\x31\x2c\x35\x2e\x36\x37\ +\x31\x31\x39\x37\x20\x2d\x30\x2e\x36\x37\x35\x34\x34\x35\x2c\x30\ +\x2e\x39\x34\x36\x32\x30\x33\x20\x2d\x31\x2e\x37\x35\x39\x30\x36\ +\x37\x2c\x31\x2e\x39\x33\x37\x31\x37\x37\x20\x2d\x31\x2e\x33\x33\ +\x34\x34\x39\x38\x2c\x33\x2e\x32\x32\x30\x38\x32\x39\x20\x30\x2e\ +\x33\x36\x33\x39\x31\x38\x2c\x31\x2e\x31\x38\x36\x39\x30\x31\x20\ +\x31\x2e\x37\x35\x31\x34\x39\x35\x2c\x31\x2e\x35\x34\x36\x36\x37\ +\x38\x20\x32\x2e\x32\x38\x39\x39\x39\x38\x2c\x32\x2e\x36\x32\x39\ +\x39\x39\x38\x20\x31\x2e\x32\x34\x37\x39\x32\x36\x2c\x31\x2e\x39\ +\x31\x34\x36\x30\x36\x20\x30\x2e\x35\x39\x37\x39\x31\x33\x2c\x34\ +\x2e\x34\x36\x33\x32\x30\x32\x33\x20\x2d\x30\x2e\x38\x32\x31\x36\ +\x32\x34\x2c\x36\x2e\x30\x39\x31\x38\x37\x38\x20\x2d\x30\x2e\x36\ +\x39\x36\x31\x37\x2c\x31\x2e\x30\x31\x34\x34\x38\x38\x20\x2d\x31\ +\x2e\x39\x30\x33\x37\x39\x37\x2c\x32\x2e\x30\x32\x39\x31\x30\x37\ +\x38\x20\x2d\x31\x2e\x34\x36\x38\x33\x37\x34\x2c\x33\x2e\x33\x39\ +\x38\x31\x31\x35\x31\x20\x30\x2e\x32\x33\x32\x35\x34\x32\x2c\x30\ +\x2e\x39\x37\x30\x31\x37\x33\x39\x20\x31\x2e\x31\x39\x30\x39\x36\ +\x32\x2c\x31\x2e\x32\x38\x36\x38\x32\x39\x31\x20\x31\x2e\x39\x38\ +\x35\x37\x38\x2c\x31\x2e\x36\x36\x35\x36\x32\x33\x37\x20\x31\x2e\ +\x33\x35\x32\x39\x36\x33\x2c\x30\x2e\x35\x34\x37\x30\x33\x34\x38\ +\x20\x31\x2e\x30\x38\x39\x38\x35\x38\x2c\x32\x2e\x33\x30\x39\x37\ +\x38\x34\x35\x31\x20\x30\x2e\x30\x34\x37\x31\x33\x2c\x33\x2e\x30\ +\x34\x31\x34\x36\x38\x33\x34\x20\x43\x20\x31\x39\x2e\x37\x39\x35\ +\x36\x36\x33\x2c\x31\x2e\x32\x35\x36\x35\x37\x39\x31\x20\x31\x39\ +\x2e\x32\x33\x33\x37\x33\x37\x2c\x31\x2e\x36\x32\x39\x37\x32\x36\ +\x34\x20\x31\x38\x2e\x36\x37\x32\x38\x34\x2c\x32\x2e\x30\x30\x34\ +\x31\x30\x39\x32\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x70\x61\x74\x68\x33\x37\x34\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ +\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ +\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x0a\x27\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x34\x31\x38\x38\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x36\x34\x69\x2e\x73\x76\ +\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x34\x31\x39\x36\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\ +\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\ +\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\ +\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x34\ +\x31\x39\x34\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\ +\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ +\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\ +\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\ +\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\ +\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x34\x31\x39\x32\x22\x0a\x20\x20\x20\x20\ +\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x7a\x6f\x6f\x6d\x3d\x22\x33\x30\x2e\x32\x30\x38\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ +\x2d\x36\x2e\x35\x32\x37\x38\x34\x30\x34\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x39\x39\ +\x39\x2e\x34\x31\x31\x39\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x31\x30\x38\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\ +\x3d\x22\x73\x76\x67\x34\x31\x38\x38\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\ +\x2d\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\x2e\x75\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x2d\x30\x2e\x30\x34\ +\x37\x32\x34\x35\x37\x36\x2c\x31\x37\x2e\x31\x35\x33\x34\x34\x35\ +\x20\x30\x2c\x2d\x30\x2e\x33\x20\x63\x20\x30\x2c\x2d\x32\x2e\x38\ +\x37\x35\x20\x32\x2e\x31\x39\x39\x39\x39\x39\x39\x36\x2c\x2d\x35\ +\x2e\x30\x35\x20\x33\x2e\x36\x39\x39\x39\x39\x39\x39\x36\x2c\x2d\ +\x37\x2e\x34\x35\x30\x30\x30\x30\x31\x20\x30\x2e\x31\x2c\x30\x2e\ +\x33\x32\x35\x20\x30\x2e\x31\x32\x35\x2c\x30\x2e\x36\x37\x35\x30\ +\x30\x30\x31\x20\x30\x2e\x31\x32\x35\x2c\x31\x2e\x30\x32\x35\x30\ +\x30\x30\x31\x20\x30\x2c\x32\x2e\x34\x35\x20\x2d\x32\x2e\x31\x37\ +\x35\x2c\x34\x2e\x39\x32\x35\x20\x2d\x33\x2e\x38\x32\x34\x39\x39\ +\x39\x39\x36\x2c\x36\x2e\x37\x32\x35\x20\x7a\x20\x6d\x20\x30\x2c\ +\x35\x2e\x33\x32\x35\x20\x63\x20\x30\x2c\x2d\x34\x2e\x34\x37\x35\ +\x20\x34\x2e\x37\x39\x39\x39\x39\x39\x39\x36\x2c\x2d\x37\x2e\x35\ +\x37\x35\x20\x34\x2e\x37\x39\x39\x39\x39\x39\x39\x36\x2c\x2d\x31\ +\x32\x2e\x30\x35\x20\x30\x2c\x2d\x30\x2e\x37\x35\x30\x30\x30\x30\ +\x31\x20\x2d\x30\x2e\x31\x35\x2c\x2d\x31\x2e\x34\x37\x35\x30\x30\ +\x30\x31\x20\x2d\x30\x2e\x34\x35\x2c\x2d\x32\x2e\x31\x37\x35\x30\ +\x30\x30\x31\x20\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x39\x20\x30\ +\x2e\x37\x2c\x2d\x31\x2e\x38\x35\x30\x30\x30\x30\x32\x20\x30\x2e\ +\x37\x2c\x2d\x32\x2e\x38\x37\x35\x30\x30\x30\x32\x20\x30\x2c\x2d\ +\x30\x2e\x39\x37\x35\x20\x2d\x30\x2e\x32\x35\x2c\x2d\x31\x2e\x39\ +\x32\x35\x20\x2d\x30\x2e\x37\x2c\x2d\x32\x2e\x37\x37\x35\x20\x30\ +\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x39\x20\x30\x2e\x37\x2c\x2d\x31\ +\x2e\x38\x32\x35\x30\x30\x30\x30\x31\x20\x30\x2e\x37\x2c\x2d\x32\ +\x2e\x38\x35\x30\x30\x30\x30\x30\x31\x20\x30\x2c\x2d\x30\x2e\x38\ +\x32\x34\x39\x39\x39\x39\x39\x20\x2d\x30\x2e\x33\x32\x35\x2c\x2d\ +\x31\x2e\x35\x39\x39\x39\x39\x39\x39\x39\x20\x2d\x30\x2e\x38\x35\ +\x2c\x2d\x32\x2e\x32\x32\x34\x39\x39\x39\x39\x39\x20\x30\x2e\x36\ +\x2c\x2d\x31\x2e\x30\x35\x20\x31\x2e\x30\x32\x35\x2c\x2d\x32\x2e\ +\x31\x35\x20\x31\x2e\x30\x32\x35\x2c\x2d\x33\x2e\x34\x20\x30\x2c\ +\x2d\x31\x2e\x35\x35\x20\x2d\x30\x2e\x34\x2c\x2d\x33\x2e\x30\x35\ +\x20\x2d\x31\x2e\x30\x35\x2c\x2d\x34\x2e\x34\x34\x39\x39\x39\x39\ +\x37\x20\x2d\x30\x2e\x31\x2c\x2d\x30\x2e\x31\x37\x35\x20\x2d\x30\ +\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x32\x37\x35\x20\x2d\x30\x2e\x34\ +\x35\x2c\x2d\x30\x2e\x32\x37\x35\x20\x2d\x30\x2e\x33\x2c\x30\x20\ +\x2d\x30\x2e\x36\x2c\x30\x2e\x32\x35\x20\x2d\x30\x2e\x35\x32\x35\ +\x2c\x30\x2e\x36\x32\x34\x39\x39\x39\x37\x20\x30\x2e\x36\x35\x2c\ +\x31\x2e\x32\x37\x35\x20\x31\x2e\x30\x35\x2c\x32\x2e\x36\x37\x35\ +\x20\x31\x2e\x30\x35\x2c\x34\x2e\x31\x20\x30\x2c\x32\x2e\x33\x37\ +\x35\x20\x2d\x32\x2e\x34\x32\x35\x2c\x34\x2e\x36\x32\x35\x20\x2d\ +\x34\x2e\x32\x34\x39\x39\x39\x39\x39\x36\x2c\x36\x2e\x31\x37\x34\ +\x39\x39\x39\x39\x39\x20\x6c\x20\x30\x2c\x2d\x32\x2e\x38\x32\x34\ +\x39\x39\x39\x39\x39\x20\x2d\x30\x2e\x33\x35\x2c\x30\x20\x30\x2c\ +\x32\x35\x2e\x30\x30\x30\x30\x30\x30\x33\x20\x30\x2e\x33\x35\x2c\ +\x30\x20\x7a\x20\x6d\x20\x30\x2c\x2d\x31\x30\x2e\x39\x35\x20\x30\ +\x2c\x2d\x30\x2e\x33\x20\x63\x20\x30\x2c\x2d\x32\x2e\x39\x32\x35\ +\x30\x30\x30\x31\x20\x32\x2e\x32\x34\x39\x39\x39\x39\x39\x36\x2c\ +\x2d\x35\x2e\x31\x32\x35\x30\x30\x30\x33\x20\x33\x2e\x37\x34\x39\ +\x39\x39\x39\x39\x36\x2c\x2d\x37\x2e\x35\x35\x30\x30\x30\x30\x33\ +\x20\x30\x2e\x32\x32\x35\x2c\x30\x2e\x35\x32\x35\x20\x30\x2e\x33\ +\x32\x35\x2c\x31\x2e\x31\x32\x35\x20\x30\x2e\x33\x32\x35\x2c\x31\ +\x2e\x37\x20\x30\x2c\x32\x2e\x33\x35\x30\x30\x30\x30\x32\x20\x2d\ +\x32\x2e\x33\x32\x35\x2c\x34\x2e\x35\x37\x35\x30\x30\x30\x32\x20\ +\x2d\x34\x2e\x30\x37\x34\x39\x39\x39\x39\x36\x2c\x36\x2e\x31\x35\ +\x30\x30\x30\x30\x33\x20\x7a\x20\x6d\x20\x30\x2c\x2d\x35\x2e\x36\ +\x30\x30\x30\x30\x30\x33\x20\x30\x2c\x2d\x30\x2e\x33\x32\x35\x20\ +\x63\x20\x30\x2c\x2d\x32\x2e\x38\x20\x32\x2e\x31\x34\x39\x39\x39\ +\x39\x39\x36\x2c\x2d\x34\x2e\x39\x32\x35\x30\x30\x30\x30\x31\x20\ +\x33\x2e\x36\x37\x34\x39\x39\x39\x39\x36\x2c\x2d\x37\x2e\x32\x32\ +\x35\x20\x30\x2e\x32\x37\x35\x2c\x30\x2e\x34\x20\x30\x2e\x34\x2c\ +\x30\x2e\x38\x37\x34\x39\x39\x39\x39\x39\x20\x30\x2e\x34\x2c\x31\ +\x2e\x33\x37\x34\x39\x39\x39\x39\x39\x20\x30\x2c\x32\x2e\x33\x35\ +\x30\x30\x30\x30\x30\x31\x20\x2d\x32\x2e\x33\x32\x35\x2c\x34\x2e\ +\x36\x30\x30\x30\x30\x30\x30\x31\x20\x2d\x34\x2e\x30\x37\x34\x39\ +\x39\x39\x39\x36\x2c\x36\x2e\x31\x37\x35\x30\x30\x30\x30\x31\x20\ +\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x34\x31\x39\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x08\x5c\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x34\x36\x30\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x6e\x6f\ +\x74\x65\x68\x65\x61\x64\x73\x57\x68\x6f\x6c\x65\x2e\x73\x76\x67\ +\x22\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\ +\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\ +\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\ +\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\ +\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\ +\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\ +\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\ +\x69\x64\x74\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x34\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\ +\x77\x36\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x35\x2e\ +\x33\x34\x30\x30\x37\x30\x34\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x33\x2e\x30\x35\x33\ +\x32\x33\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x79\x3d\x22\x39\x34\x35\x2e\x34\x35\x35\x33\x37\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\ +\x34\x36\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x33\x34\x36\x38\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x34\x36\x36\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ +\x64\x3d\x22\x6d\x20\x33\x2e\x30\x33\x34\x36\x38\x31\x31\x2c\x2d\ +\x32\x2e\x38\x35\x20\x63\x20\x2d\x31\x2e\x30\x34\x34\x34\x32\x31\ +\x33\x2c\x30\x20\x2d\x31\x2e\x34\x38\x33\x30\x37\x38\x33\x2c\x31\ +\x2e\x30\x35\x20\x2d\x31\x2e\x34\x38\x33\x30\x37\x38\x33\x2c\x32\ +\x2e\x32\x20\x30\x2c\x31\x2e\x39\x37\x35\x20\x31\x2e\x32\x35\x33\ +\x33\x30\x35\x36\x2c\x33\x2e\x35\x20\x32\x2e\x39\x30\x33\x34\x39\ +\x31\x34\x2c\x33\x2e\x35\x20\x31\x2e\x30\x34\x34\x34\x32\x31\x34\ +\x2c\x30\x20\x31\x2e\x34\x36\x32\x31\x39\x2c\x2d\x31\x2e\x30\x35\ +\x20\x31\x2e\x34\x36\x32\x31\x39\x2c\x2d\x32\x2e\x32\x20\x30\x2c\ +\x2d\x31\x2e\x39\x37\x35\x20\x2d\x31\x2e\x32\x33\x32\x34\x31\x37\ +\x33\x2c\x2d\x33\x2e\x35\x20\x2d\x32\x2e\x38\x38\x32\x36\x30\x33\ +\x31\x2c\x2d\x33\x2e\x35\x20\x7a\x20\x4d\x20\x38\x2e\x39\x36\x36\ +\x39\x39\x34\x39\x2c\x30\x20\x63\x20\x30\x2c\x31\x2e\x30\x37\x35\ +\x20\x2d\x30\x2e\x37\x31\x30\x32\x30\x36\x39\x2c\x31\x2e\x38\x37\ +\x35\x20\x2d\x31\x2e\x35\x32\x34\x38\x35\x35\x36\x2c\x32\x2e\x34\ +\x20\x2d\x31\x2e\x31\x32\x37\x39\x37\x35\x31\x2c\x30\x2e\x37\x32\ +\x35\x20\x2d\x32\x2e\x34\x32\x33\x30\x35\x37\x36\x2c\x31\x20\x2d\ +\x33\x2e\x36\x39\x37\x32\x35\x31\x36\x2c\x31\x20\x43\x20\x32\x2e\ +\x34\x37\x30\x36\x39\x33\x36\x2c\x33\x2e\x34\x20\x31\x2e\x31\x35\ +\x34\x37\x32\x32\x37\x2c\x33\x2e\x31\x32\x35\x20\x30\x2e\x30\x32\ +\x36\x37\x34\x37\x36\x2c\x32\x2e\x34\x20\x2d\x30\x2e\x37\x38\x37\ +\x39\x30\x31\x31\x31\x2c\x31\x2e\x38\x37\x35\x20\x2d\x31\x2e\x34\ +\x39\x38\x31\x30\x37\x36\x2c\x31\x2e\x30\x37\x35\x20\x2d\x31\x2e\ +\x34\x39\x38\x31\x30\x37\x36\x2c\x30\x20\x63\x20\x30\x2c\x2d\x31\ +\x2e\x30\x37\x35\x20\x30\x2e\x37\x31\x30\x32\x30\x36\x34\x39\x2c\ +\x2d\x31\x2e\x38\x37\x35\x20\x31\x2e\x35\x32\x34\x38\x35\x35\x32\ +\x2c\x2d\x32\x2e\x34\x20\x31\x2e\x31\x32\x37\x39\x37\x35\x31\x2c\ +\x2d\x30\x2e\x37\x32\x35\x20\x32\x2e\x34\x34\x33\x39\x34\x36\x2c\ +\x2d\x31\x20\x33\x2e\x37\x31\x38\x31\x34\x30\x31\x2c\x2d\x31\x20\ +\x31\x2e\x32\x37\x34\x31\x39\x34\x2c\x30\x20\x32\x2e\x35\x36\x39\ +\x32\x37\x36\x35\x2c\x30\x2e\x32\x37\x35\x20\x33\x2e\x36\x39\x37\ +\x32\x35\x31\x36\x2c\x31\x20\x30\x2e\x38\x31\x34\x36\x34\x38\x37\ +\x2c\x30\x2e\x35\x32\x35\x20\x31\x2e\x35\x32\x34\x38\x35\x35\x36\ +\x2c\x31\x2e\x33\x32\x35\x20\x31\x2e\x35\x32\x34\x38\x35\x35\x36\ +\x2c\x32\x2e\x34\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x70\x61\x74\x68\x33\x34\x36\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\ +\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\ +\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x09\xf4\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x38\x36\x38\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x36\x34\x2e\x73\x76\x67\ +\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x33\x38\x37\x36\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\ +\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ +\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\ +\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\ +\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\ +\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\ +\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\ +\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\ +\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\ +\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x38\ +\x37\x34\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\ +\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\ +\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\ +\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\ +\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\ +\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\ +\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\ +\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\ +\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\ +\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x32\x30\x39\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x33\x38\x37\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\ +\x6f\x6f\x6d\x3d\x22\x32\x31\x2e\x33\x36\x30\x32\x38\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\ +\x3d\x22\x32\x30\x2e\x33\x30\x35\x34\x34\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\ +\x30\x31\x33\x2e\x34\x35\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\ +\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\ +\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\ +\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\ +\x65\x72\x3d\x22\x73\x76\x67\x33\x38\x36\x38\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\ +\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\x2e\x64\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x36\x2e\x31\ +\x38\x35\x34\x39\x38\x36\x2c\x32\x30\x2e\x33\x32\x34\x30\x39\x33\ +\x20\x63\x20\x30\x2c\x2d\x30\x2e\x36\x37\x35\x20\x2d\x30\x2e\x32\ +\x2c\x2d\x31\x2e\x32\x35\x20\x2d\x30\x2e\x35\x2c\x2d\x31\x2e\x37\ +\x37\x35\x20\x30\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x36\x37\x35\x20\ +\x30\x2e\x33\x2c\x2d\x31\x2e\x34\x20\x30\x2e\x33\x2c\x2d\x32\x2e\ +\x31\x20\x30\x2c\x2d\x30\x2e\x37\x35\x20\x2d\x30\x2e\x32\x2c\x2d\ +\x31\x2e\x34\x32\x35\x20\x2d\x30\x2e\x35\x2c\x2d\x32\x2e\x30\x32\ +\x35\x20\x30\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\x20\x30\x2e\ +\x33\x2c\x2d\x31\x2e\x37\x20\x30\x2e\x33\x2c\x2d\x32\x2e\x35\x35\ +\x20\x30\x2c\x2d\x30\x2e\x39\x32\x35\x20\x2d\x30\x2e\x32\x35\x2c\ +\x2d\x31\x2e\x37\x35\x20\x2d\x30\x2e\x36\x35\x2c\x2d\x32\x2e\x35\ +\x32\x34\x39\x39\x39\x38\x20\x30\x2e\x30\x35\x2c\x2d\x30\x2e\x38\ +\x20\x30\x2e\x30\x37\x35\x2c\x2d\x31\x2e\x36\x32\x35\x20\x30\x2e\ +\x30\x37\x35\x2c\x2d\x32\x2e\x34\x32\x35\x20\x30\x2c\x2d\x34\x2e\ +\x37\x30\x30\x30\x30\x30\x34\x20\x2d\x35\x2e\x37\x34\x39\x39\x39\ +\x39\x39\x38\x2c\x2d\x37\x2e\x34\x35\x30\x30\x30\x30\x33\x37\x20\ +\x2d\x35\x2e\x37\x34\x39\x39\x39\x39\x39\x38\x2c\x2d\x31\x32\x2e\ +\x31\x35\x30\x30\x30\x30\x33\x20\x6c\x20\x30\x2c\x2d\x30\x2e\x31\ +\x20\x2d\x30\x2e\x33\x35\x2c\x30\x20\x30\x2c\x32\x35\x2e\x30\x30\ +\x30\x30\x30\x30\x31\x20\x30\x2e\x33\x35\x2c\x30\x20\x30\x2c\x2d\ +\x33\x2e\x31\x32\x35\x20\x63\x20\x32\x2e\x34\x39\x39\x39\x39\x39\ +\x39\x38\x2c\x30\x2e\x33\x37\x35\x20\x35\x2e\x37\x34\x39\x39\x39\ +\x39\x39\x38\x2c\x31\x2e\x35\x20\x35\x2e\x37\x34\x39\x39\x39\x39\ +\x39\x38\x2c\x33\x2e\x37\x37\x35\x20\x30\x2c\x30\x2e\x34\x32\x35\ +\x20\x2d\x30\x2e\x31\x35\x2c\x30\x2e\x38\x37\x35\x20\x2d\x30\x2e\ +\x31\x35\x2c\x31\x2e\x33\x20\x30\x2c\x30\x2e\x33\x20\x30\x2e\x32\ +\x37\x35\x2c\x30\x2e\x35\x20\x30\x2e\x35\x35\x2c\x30\x2e\x35\x20\ +\x30\x2e\x36\x35\x2c\x30\x20\x30\x2e\x35\x37\x35\x2c\x2d\x31\x2e\ +\x32\x20\x30\x2e\x35\x37\x35\x2c\x2d\x31\x2e\x38\x20\x7a\x20\x4d\ +\x20\x2d\x30\x2e\x35\x33\x39\x35\x30\x31\x33\x38\x2c\x2d\x30\x2e\ +\x32\x32\x35\x39\x30\x37\x31\x37\x20\x43\x20\x31\x2e\x35\x31\x30\ +\x34\x39\x38\x36\x2c\x31\x2e\x35\x39\x39\x30\x39\x32\x38\x20\x34\ +\x2e\x32\x33\x35\x34\x39\x38\x36\x2c\x34\x2e\x31\x39\x39\x30\x39\ +\x32\x38\x20\x34\x2e\x32\x33\x35\x34\x39\x38\x36\x2c\x36\x2e\x39\ +\x32\x34\x30\x39\x33\x32\x20\x6c\x20\x30\x2c\x31\x20\x63\x20\x2d\ +\x31\x2e\x38\x37\x35\x2c\x2d\x32\x2e\x34\x32\x35\x30\x30\x30\x37\ +\x20\x2d\x34\x2e\x37\x37\x34\x39\x39\x39\x39\x38\x2c\x2d\x34\x2e\ +\x34\x35\x30\x30\x30\x30\x34\x20\x2d\x34\x2e\x37\x37\x34\x39\x39\ +\x39\x39\x38\x2c\x2d\x37\x2e\x36\x32\x35\x30\x30\x30\x33\x37\x20\ +\x6c\x20\x30\x2c\x2d\x30\x2e\x35\x32\x35\x20\x7a\x20\x6d\x20\x30\ +\x2c\x35\x2e\x35\x32\x34\x39\x39\x39\x36\x37\x20\x63\x20\x32\x2e\ +\x32\x39\x39\x39\x39\x39\x39\x38\x2c\x31\x2e\x35\x35\x30\x30\x30\ +\x31\x20\x35\x2e\x33\x34\x39\x39\x39\x39\x39\x38\x2c\x33\x2e\x38\ +\x35\x30\x30\x30\x30\x37\x20\x35\x2e\x33\x34\x39\x39\x39\x39\x39\ +\x38\x2c\x36\x2e\x35\x37\x35\x30\x30\x30\x35\x20\x30\x2c\x30\x2e\ +\x34\x35\x20\x2d\x30\x2e\x30\x32\x35\x2c\x30\x2e\x39\x20\x2d\x30\ +\x2e\x31\x2c\x31\x2e\x33\x35\x20\x2d\x31\x2e\x39\x2c\x2d\x32\x2e\ +\x33\x37\x35\x20\x2d\x35\x2e\x32\x34\x39\x39\x39\x39\x39\x38\x2c\ +\x2d\x34\x2e\x30\x39\x39\x39\x39\x39\x38\x20\x2d\x35\x2e\x32\x34\ +\x39\x39\x39\x39\x39\x38\x2c\x2d\x37\x2e\x32\x39\x39\x39\x39\x39\ +\x35\x20\x6c\x20\x30\x2c\x2d\x30\x2e\x36\x32\x35\x30\x30\x31\x20\ +\x7a\x20\x6d\x20\x30\x2c\x35\x2e\x36\x32\x35\x30\x30\x30\x35\x20\ +\x63\x20\x32\x2e\x33\x39\x39\x39\x39\x39\x39\x38\x2c\x31\x2e\x31\ +\x32\x35\x20\x35\x2e\x35\x34\x39\x39\x39\x39\x39\x38\x2c\x32\x2e\ +\x39\x37\x35\x20\x35\x2e\x35\x34\x39\x39\x39\x39\x39\x38\x2c\x35\ +\x2e\x35\x32\x35\x20\x30\x2c\x30\x2e\x33\x37\x35\x20\x2d\x30\x2e\ +\x30\x35\x2c\x30\x2e\x37\x32\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\ +\x31\x2e\x31\x20\x2d\x31\x2e\x39\x35\x2c\x2d\x31\x2e\x39\x32\x35\ +\x20\x2d\x35\x2e\x34\x32\x34\x39\x39\x39\x39\x38\x2c\x2d\x33\x2e\ +\x30\x35\x20\x2d\x35\x2e\x34\x32\x34\x39\x39\x39\x39\x38\x2c\x2d\ +\x36\x20\x6c\x20\x30\x2c\x2d\x30\x2e\x36\x32\x35\x20\x7a\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x38\x37\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\ +\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\ +\x67\x3e\x0a\ +\x00\x00\x07\x97\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x33\x39\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x72\x65\ +\x73\x74\x38\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\ +\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x31\x37\x32\x22\x0a\x20\x20\ +\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x32\x31\x2e\x33\x36\x30\x32\x38\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x78\x3d\x22\x32\x2e\x31\x38\x38\x38\x38\x38\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ +\x3d\x22\x31\x30\x30\x30\x2e\x32\x37\x34\x34\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x79\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x33\x39\x31\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x33\x33\x39\x39\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\ +\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ +\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\ +\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\ +\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\ +\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\ +\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\ +\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\ +\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x64\x65\x66\x73\x33\x33\x39\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\ +\x32\x2e\x35\x35\x38\x36\x30\x36\x32\x2c\x35\x2e\x33\x39\x32\x39\ +\x30\x33\x35\x20\x32\x2e\x39\x2c\x2d\x38\x2e\x31\x37\x35\x20\x63\ +\x20\x2d\x30\x2e\x38\x37\x35\x2c\x30\x2e\x33\x20\x2d\x31\x2e\x37\ +\x35\x2c\x30\x2e\x35\x37\x35\x20\x2d\x32\x2e\x36\x37\x35\x2c\x30\ +\x2e\x35\x37\x35\x20\x2d\x31\x2e\x31\x35\x2c\x30\x20\x2d\x32\x2e\ +\x31\x37\x34\x39\x39\x39\x39\x39\x2c\x2d\x30\x2e\x38\x35\x20\x2d\ +\x32\x2e\x31\x37\x34\x39\x39\x39\x39\x39\x2c\x2d\x32\x20\x30\x2c\ +\x2d\x30\x2e\x39\x37\x35\x20\x30\x2e\x37\x37\x34\x39\x39\x39\x39\ +\x39\x2c\x2d\x31\x2e\x37\x37\x35\x20\x31\x2e\x37\x37\x34\x39\x39\ +\x39\x39\x39\x2c\x2d\x31\x2e\x37\x37\x35\x20\x30\x2e\x36\x35\x2c\ +\x30\x20\x31\x2e\x32\x32\x35\x2c\x30\x2e\x34\x20\x31\x2e\x34\x32\ +\x35\x2c\x31\x20\x30\x2e\x32\x35\x2c\x30\x2e\x37\x20\x30\x2e\x31\ +\x35\x2c\x31\x2e\x35\x20\x30\x2e\x38\x37\x35\x2c\x31\x2e\x35\x20\ +\x30\x2e\x34\x32\x35\x2c\x30\x20\x31\x2e\x34\x35\x2c\x2d\x31\x2e\ +\x33\x35\x20\x31\x2e\x36\x32\x35\x2c\x2d\x31\x2e\x37\x35\x20\x30\ +\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x32\x37\x35\x20\x30\x2e\x35\x2c\ +\x2d\x30\x2e\x32\x35\x20\x30\x2e\x36\x2c\x30\x20\x6c\x20\x2d\x33\ +\x2e\x31\x35\x2c\x31\x30\x2e\x36\x32\x35\x20\x63\x20\x2d\x30\x2e\ +\x31\x37\x35\x2c\x30\x2e\x31\x35\x20\x2d\x30\x2e\x34\x2c\x30\x2e\ +\x32\x32\x35\x20\x2d\x30\x2e\x36\x2c\x30\x2e\x32\x32\x35\x20\x2d\ +\x30\x2e\x32\x2c\x30\x20\x2d\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\ +\x30\x37\x35\x20\x2d\x30\x2e\x36\x2c\x2d\x30\x2e\x32\x32\x35\x20\ +\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x33\x33\x39\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x07\x6b\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x33\x33\x36\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x65\x66\x50\x65\x72\x63\x75\x73\ +\x73\x69\x6f\x6e\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x33\x34\x34\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ +\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ +\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ +\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x64\x65\x66\x73\x33\x33\x34\x32\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ +\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ +\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\ +\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\ +\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ +\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\ +\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x32\x30\x39\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x33\x34\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x2e\x33\ +\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x78\x3d\x22\x35\x30\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x36\x31\x39\ +\x2e\x31\x33\x36\x32\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x33\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\ +\x76\x67\x33\x33\x33\x36\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\ +\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\ +\x6d\x65\x3d\x22\x63\x6c\x65\x66\x73\x2e\x70\x65\x72\x63\x75\x73\ +\x73\x69\x6f\x6e\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\ +\x38\x2e\x31\x2c\x2d\x36\x2e\x32\x35\x20\x2d\x32\x2e\x34\x32\x35\ +\x2c\x30\x20\x63\x20\x2d\x30\x2e\x31\x2c\x30\x20\x2d\x30\x2e\x31\ +\x37\x35\x2c\x30\x2e\x31\x20\x2d\x30\x2e\x31\x37\x35\x2c\x30\x2e\ +\x32\x20\x6c\x20\x30\x2c\x31\x32\x2e\x31\x20\x63\x20\x30\x2c\x30\ +\x2e\x31\x20\x30\x2e\x30\x37\x35\x2c\x30\x2e\x32\x20\x30\x2e\x31\ +\x37\x35\x2c\x30\x2e\x32\x20\x6c\x20\x32\x2e\x34\x32\x35\x2c\x30\ +\x20\x63\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\x32\x2c\x2d\x30\x2e\ +\x31\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x6c\x20\x30\x2c\x2d\ +\x31\x32\x2e\x31\x20\x63\x20\x30\x2c\x2d\x30\x2e\x31\x20\x2d\x30\ +\x2e\x31\x2c\x2d\x30\x2e\x32\x20\x2d\x30\x2e\x32\x2c\x2d\x30\x2e\ +\x32\x20\x7a\x20\x6d\x20\x2d\x35\x2e\x35\x2c\x30\x20\x2d\x32\x2e\ +\x34\x32\x35\x2c\x30\x20\x43\x20\x30\x2e\x30\x37\x35\x2c\x2d\x36\ +\x2e\x32\x35\x20\x30\x2c\x2d\x36\x2e\x31\x35\x20\x30\x2c\x2d\x36\ +\x2e\x30\x35\x20\x6c\x20\x30\x2c\x31\x32\x2e\x31\x20\x63\x20\x30\ +\x2c\x30\x2e\x31\x20\x30\x2e\x30\x37\x35\x2c\x30\x2e\x32\x20\x30\ +\x2e\x31\x37\x35\x2c\x30\x2e\x32\x20\x6c\x20\x32\x2e\x34\x32\x35\ +\x2c\x30\x20\x63\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\x32\x2c\x2d\ +\x30\x2e\x31\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x6c\x20\x30\ +\x2c\x2d\x31\x32\x2e\x31\x20\x63\x20\x30\x2c\x2d\x30\x2e\x31\x20\ +\x2d\x30\x2e\x31\x2c\x2d\x30\x2e\x32\x20\x2d\x30\x2e\x32\x2c\x2d\ +\x30\x2e\x32\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x33\x33\x33\x38\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ +\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\ +\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x10\x85\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x31\x37\x39\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\ +\x72\x31\x33\x37\x32\x35\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x65\ +\x66\x54\x72\x65\x62\x6c\x65\x5e\x38\x2e\x73\x76\x67\x22\x3e\x0a\ +\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\ +\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\ +\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\ +\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ +\x69\x67\x68\x74\x3d\x22\x32\x30\x39\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x32\x39\ +\x38\x39\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x34\x2e\ +\x38\x30\x38\x33\x32\x36\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x33\x32\x2e\x36\x34\ +\x32\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x79\x3d\x22\x39\x36\x35\x2e\x31\x38\x38\x30\x33\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\ +\x31\x37\x39\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\ +\x61\x64\x61\x74\x61\x33\x31\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\ +\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\ +\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\ +\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\ +\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\ +\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\ +\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ +\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ +\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ +\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\ +\x65\x66\x73\x33\x31\x38\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\ +\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x36\x2e\ +\x33\x35\x2c\x2d\x37\x2e\x35\x30\x37\x30\x38\x32\x34\x20\x43\x20\ +\x35\x2e\x35\x2c\x2d\x31\x30\x2e\x34\x35\x37\x30\x38\x32\x20\x35\ +\x2c\x2d\x31\x33\x2e\x32\x38\x32\x30\x38\x32\x20\x35\x2c\x2d\x31\ +\x36\x2e\x39\x38\x32\x30\x38\x32\x20\x63\x20\x30\x2c\x2d\x33\x20\ +\x31\x2e\x34\x2c\x2d\x35\x2e\x38\x20\x33\x2e\x37\x37\x35\x2c\x2d\ +\x37\x2e\x36\x32\x35\x20\x30\x2e\x30\x35\x2c\x2d\x30\x2e\x30\x35\ +\x20\x30\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x30\x37\x35\x20\x30\x2e\ +\x32\x2c\x2d\x30\x2e\x30\x37\x35\x20\x30\x2e\x30\x37\x35\x2c\x30\ +\x20\x30\x2e\x31\x35\x2c\x30\x2e\x30\x32\x35\x20\x30\x2e\x32\x2c\ +\x30\x2e\x30\x37\x35\x20\x31\x2e\x39\x2c\x32\x2e\x32\x35\x20\x33\ +\x2e\x35\x37\x35\x2c\x36\x2e\x36\x20\x33\x2e\x35\x37\x35\x2c\x39\ +\x2e\x36\x32\x35\x20\x30\x2c\x33\x2e\x37\x35\x20\x2d\x32\x2e\x32\ +\x35\x2c\x36\x2e\x36\x37\x34\x39\x39\x39\x36\x20\x2d\x34\x2e\x37\ +\x35\x2c\x39\x2e\x34\x39\x39\x39\x39\x39\x36\x20\x30\x2e\x35\x35\ +\x2c\x31\x2e\x38\x32\x34\x39\x39\x39\x39\x20\x31\x2e\x30\x35\x2c\ +\x33\x2e\x36\x37\x34\x39\x39\x39\x39\x20\x31\x2e\x35\x32\x35\x2c\ +\x35\x2e\x35\x32\x34\x39\x39\x39\x39\x20\x68\x20\x30\x2e\x31\x35\ +\x20\x63\x20\x33\x2e\x38\x35\x2c\x30\x20\x36\x2e\x33\x35\x2c\x33\ +\x2e\x31\x37\x35\x20\x36\x2e\x33\x35\x2c\x36\x2e\x34\x37\x35\x30\ +\x30\x30\x31\x20\x30\x2c\x31\x2e\x38\x39\x39\x39\x39\x39\x39\x20\ +\x2d\x30\x2e\x38\x32\x35\x2c\x33\x2e\x38\x32\x35\x30\x30\x30\x34\ +\x20\x2d\x32\x2e\x36\x37\x35\x2c\x35\x2e\x32\x30\x30\x30\x30\x30\ +\x34\x20\x2d\x30\x2e\x36\x32\x35\x2c\x30\x2e\x34\x37\x35\x20\x2d\ +\x31\x2e\x33\x32\x35\x2c\x30\x2e\x38\x20\x2d\x32\x2e\x30\x37\x35\ +\x2c\x31\x20\x30\x2c\x30\x2e\x33\x32\x35\x20\x30\x2e\x30\x32\x35\ +\x2c\x30\x2e\x36\x37\x35\x20\x30\x2e\x30\x32\x35\x2c\x31\x20\x30\ +\x2c\x31\x2e\x31\x35\x20\x2d\x30\x2e\x30\x32\x35\x2c\x32\x2e\x33\ +\x20\x2d\x30\x2e\x31\x2c\x33\x2e\x34\x35\x20\x2d\x30\x2e\x31\x37\ +\x35\x2c\x33\x2e\x30\x32\x35\x20\x2d\x32\x2e\x33\x35\x2c\x35\x2e\ +\x36\x37\x35\x20\x2d\x35\x2e\x33\x35\x2c\x35\x2e\x36\x37\x35\x20\ +\x2d\x32\x2e\x37\x37\x35\x2c\x30\x20\x2d\x35\x2e\x30\x35\x2c\x2d\ +\x32\x2e\x33\x20\x2d\x35\x2e\x30\x35\x2c\x2d\x35\x2e\x31\x32\x35\ +\x20\x30\x2c\x2d\x31\x2e\x34\x35\x20\x31\x2e\x33\x35\x2c\x2d\x32\ +\x2e\x36\x20\x32\x2e\x38\x32\x35\x2c\x2d\x32\x2e\x36\x20\x31\x2e\ +\x33\x35\x2c\x30\x20\x32\x2e\x33\x37\x35\x2c\x31\x2e\x32\x20\x32\ +\x2e\x33\x37\x35\x2c\x32\x2e\x36\x20\x30\x2c\x31\x2e\x33\x20\x2d\ +\x31\x2e\x30\x37\x35\x2c\x32\x2e\x33\x37\x35\x20\x2d\x32\x2e\x33\ +\x37\x35\x2c\x32\x2e\x33\x37\x35\x20\x2d\x30\x2e\x33\x32\x35\x2c\ +\x30\x20\x2d\x30\x2e\x36\x37\x35\x2c\x2d\x30\x2e\x31\x20\x2d\x30\ +\x2e\x39\x37\x35\x2c\x2d\x30\x2e\x32\x35\x20\x30\x2e\x36\x35\x2c\ +\x31\x2e\x31\x37\x35\x20\x31\x2e\x38\x35\x2c\x32\x20\x33\x2e\x32\ +\x35\x2c\x32\x20\x32\x2e\x34\x37\x35\x2c\x30\x20\x34\x2e\x31\x35\ +\x2c\x2d\x32\x2e\x33\x20\x34\x2e\x33\x2c\x2d\x34\x2e\x38\x32\x35\ +\x20\x30\x2e\x30\x37\x35\x2c\x2d\x31\x2e\x31\x20\x30\x2e\x31\x2c\ +\x2d\x32\x2e\x32\x32\x35\x20\x30\x2e\x31\x2c\x2d\x33\x2e\x33\x32\ +\x35\x20\x76\x20\x2d\x30\x2e\x37\x37\x35\x20\x63\x20\x2d\x30\x2e\ +\x36\x35\x2c\x30\x2e\x31\x20\x2d\x31\x2e\x33\x2c\x30\x2e\x31\x35\ +\x20\x2d\x31\x2e\x39\x37\x35\x2c\x30\x2e\x31\x35\x20\x2d\x34\x2e\ +\x37\x2c\x30\x20\x2d\x38\x2e\x33\x32\x35\x2c\x2d\x34\x2e\x32\x37\ +\x35\x30\x30\x30\x35\x20\x2d\x38\x2e\x33\x32\x35\x2c\x2d\x39\x2e\ +\x33\x30\x30\x30\x30\x30\x35\x20\x30\x2c\x2d\x34\x2e\x35\x32\x35\ +\x20\x33\x2e\x33\x35\x2c\x2d\x37\x2e\x38\x34\x39\x39\x39\x39\x39\ +\x20\x36\x2e\x33\x35\x2c\x2d\x31\x31\x2e\x32\x37\x34\x39\x39\x39\ +\x39\x20\x7a\x20\x6d\x20\x34\x2e\x39\x2c\x31\x39\x2e\x32\x35\x30\ +\x30\x30\x30\x34\x20\x63\x20\x31\x2e\x38\x32\x35\x2c\x2d\x30\x2e\ +\x35\x35\x20\x33\x2e\x31\x2c\x2d\x32\x2e\x34\x32\x35\x30\x30\x30\ +\x35\x20\x33\x2e\x31\x2c\x2d\x34\x2e\x32\x35\x30\x30\x30\x30\x35\ +\x20\x30\x2c\x2d\x32\x2e\x32\x34\x39\x39\x39\x39\x39\x20\x2d\x31\ +\x2e\x36\x2c\x2d\x34\x2e\x34\x35\x20\x2d\x34\x2e\x32\x2c\x2d\x34\ +\x2e\x38\x20\x30\x2e\x35\x37\x35\x2c\x32\x2e\x37\x35\x30\x30\x30\ +\x30\x31\x20\x31\x2c\x35\x2e\x39\x37\x35\x20\x31\x2e\x31\x2c\x39\ +\x2e\x30\x35\x30\x30\x30\x30\x35\x20\x7a\x20\x6d\x20\x2d\x32\x2e\ +\x38\x35\x2c\x30\x2e\x33\x32\x35\x20\x63\x20\x30\x2e\x36\x32\x35\ +\x2c\x30\x20\x31\x2e\x32\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x31\ +\x2e\x38\x37\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x43\x20\x31\x30\ +\x2e\x31\x37\x35\x2c\x38\x2e\x37\x36\x37\x39\x31\x37\x35\x20\x39\ +\x2e\x37\x2c\x35\x2e\x34\x36\x37\x39\x31\x37\x36\x20\x39\x2e\x31\ +\x2c\x32\x2e\x36\x34\x32\x39\x31\x37\x35\x20\x63\x20\x2d\x32\x2e\ +\x31\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\x2d\x33\x2e\x34\x2c\x31\ +\x2e\x35\x35\x20\x2d\x33\x2e\x34\x2c\x33\x2e\x31\x30\x30\x30\x30\ +\x30\x31\x20\x30\x2c\x31\x2e\x31\x32\x35\x20\x30\x2e\x36\x35\x2c\ +\x32\x2e\x32\x39\x39\x39\x39\x39\x39\x20\x32\x2e\x30\x37\x35\x2c\ +\x33\x2e\x31\x32\x34\x39\x39\x39\x39\x20\x30\x2e\x31\x2c\x30\x2e\ +\x31\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\x32\x32\x35\x20\x30\x2e\ +\x31\x37\x35\x2c\x30\x2e\x33\x35\x20\x30\x2c\x30\x2e\x32\x37\x35\ +\x20\x2d\x30\x2e\x32\x32\x35\x2c\x30\x2e\x35\x32\x35\x20\x2d\x30\ +\x2e\x35\x2c\x30\x2e\x35\x32\x35\x20\x2d\x30\x2e\x30\x37\x35\x2c\ +\x30\x20\x2d\x30\x2e\x31\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x2d\ +\x30\x2e\x32\x32\x35\x2c\x2d\x30\x2e\x30\x35\x20\x2d\x32\x2c\x2d\ +\x31\x2e\x30\x37\x35\x20\x2d\x32\x2e\x39\x2c\x2d\x32\x2e\x38\x34\ +\x39\x39\x39\x39\x39\x20\x2d\x32\x2e\x39\x2c\x2d\x34\x2e\x36\x20\ +\x30\x2c\x2d\x32\x2e\x32\x35\x20\x31\x2e\x35\x32\x35\x2c\x2d\x34\ +\x2e\x34\x35\x20\x34\x2e\x32\x2c\x2d\x34\x2e\x39\x35\x20\x2d\x30\ +\x2e\x34\x2c\x2d\x31\x2e\x36\x20\x2d\x30\x2e\x38\x37\x35\x2c\x2d\ +\x33\x2e\x31\x37\x35\x20\x2d\x31\x2e\x33\x32\x35\x2c\x2d\x34\x2e\ +\x37\x34\x39\x39\x39\x39\x39\x20\x2d\x32\x2e\x37\x35\x2c\x33\x2e\ +\x30\x39\x39\x39\x39\x39\x39\x20\x2d\x35\x2e\x35\x2c\x36\x2e\x32\ +\x32\x34\x39\x39\x39\x39\x20\x2d\x35\x2e\x35\x2c\x31\x30\x2e\x33\ +\x35\x20\x30\x2c\x33\x2e\x34\x34\x39\x39\x39\x39\x39\x20\x33\x2e\ +\x32\x37\x35\x2c\x36\x2e\x33\x32\x35\x30\x30\x30\x34\x20\x36\x2e\ +\x37\x2c\x36\x2e\x33\x32\x35\x30\x30\x30\x34\x20\x7a\x20\x6d\x20\ +\x31\x2e\x37\x37\x35\x2c\x2d\x33\x33\x2e\x32\x20\x63\x20\x2d\x32\ +\x2e\x35\x2c\x31\x2e\x33\x37\x35\x20\x2d\x34\x2e\x30\x35\x2c\x33\ +\x2e\x39\x37\x35\x20\x2d\x34\x2e\x30\x35\x2c\x36\x2e\x38\x32\x35\ +\x20\x30\x2c\x32\x2e\x32\x35\x20\x30\x2e\x34\x37\x35\x2c\x34\x2e\ +\x30\x35\x20\x31\x2c\x35\x2e\x38\x39\x39\x39\x39\x39\x36\x20\x32\ +\x2e\x31\x35\x2c\x2d\x32\x2e\x35\x34\x39\x39\x39\x39\x36\x20\x33\ +\x2e\x39\x35\x2c\x2d\x35\x2e\x32\x32\x34\x39\x39\x39\x36\x20\x33\ +\x2e\x39\x35\x2c\x2d\x38\x2e\x35\x34\x39\x39\x39\x39\x36\x20\x30\ +\x2c\x2d\x31\x2e\x38\x32\x35\x20\x2d\x30\x2e\x32\x2c\x2d\x32\x2e\ +\x35\x37\x35\x20\x2d\x30\x2e\x39\x2c\x2d\x34\x2e\x31\x37\x35\x20\ +\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x33\x31\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\ +\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x65\x69\x67\x68\x74\x22\x0a\x20\ +\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x39\x2e\x38\x34\x35\x34\x36\ +\x31\x31\x2c\x2d\x33\x32\x2e\x34\x31\x31\x32\x37\x34\x20\x63\x20\ +\x30\x2e\x35\x34\x36\x32\x37\x30\x39\x2c\x2d\x30\x2e\x35\x36\x35\ +\x31\x30\x38\x20\x31\x2e\x30\x31\x37\x31\x39\x33\x39\x2c\x2d\x31\ +\x2e\x31\x36\x37\x38\x38\x39\x20\x31\x2e\x30\x31\x37\x31\x39\x33\ +\x39\x2c\x2d\x31\x2e\x39\x34\x30\x32\x30\x33\x20\x30\x2c\x2d\x31\ +\x2e\x30\x35\x34\x38\x36\x38\x20\x2d\x31\x2e\x30\x39\x32\x35\x34\ +\x31\x39\x2c\x2d\x31\x2e\x37\x31\x34\x31\x36\x31\x20\x2d\x32\x2e\ +\x32\x34\x31\x35\x39\x34\x31\x2c\x2d\x31\x2e\x37\x31\x34\x31\x36\ +\x31\x20\x2d\x30\x2e\x39\x32\x33\x30\x31\x2c\x30\x20\x2d\x31\x2e\ +\x34\x36\x39\x32\x38\x31\x2c\x30\x2e\x37\x31\x35\x38\x30\x34\x20\ +\x2d\x31\x2e\x34\x36\x39\x32\x38\x31\x2c\x31\x2e\x34\x31\x32\x37\ +\x37\x20\x30\x2c\x30\x2e\x34\x31\x34\x34\x31\x32\x20\x30\x2e\x31\ +\x36\x39\x35\x33\x33\x2c\x30\x2e\x37\x39\x31\x31\x35\x31\x20\x30\ +\x2e\x35\x38\x33\x39\x34\x35\x2c\x31\x2e\x30\x33\x36\x30\x33\x31\ +\x20\x7a\x20\x6d\x20\x30\x2e\x35\x30\x38\x35\x39\x36\x39\x2c\x30\ +\x2e\x33\x30\x31\x33\x39\x31\x20\x63\x20\x31\x2e\x30\x33\x36\x30\ +\x33\x31\x2c\x30\x2e\x36\x30\x32\x37\x38\x32\x20\x31\x2e\x36\x30\ +\x31\x31\x33\x38\x2c\x31\x2e\x34\x36\x39\x32\x38\x20\x31\x2e\x36\ +\x30\x31\x31\x33\x38\x2c\x32\x2e\x33\x39\x32\x32\x39\x20\x30\x2c\ +\x31\x2e\x33\x35\x36\x32\x35\x38\x20\x2d\x31\x2e\x32\x32\x34\x34\ +\x2c\x32\x2e\x36\x37\x34\x38\x34\x33\x20\x2d\x33\x2e\x34\x38\x34\ +\x38\x33\x31\x31\x2c\x32\x2e\x36\x37\x34\x38\x34\x33\x20\x2d\x31\ +\x2e\x37\x33\x32\x39\x39\x37\x2c\x30\x20\x2d\x33\x2e\x33\x37\x31\ +\x38\x31\x2c\x2d\x30\x2e\x39\x39\x38\x33\x35\x37\x20\x2d\x33\x2e\ +\x33\x37\x31\x38\x31\x2c\x2d\x32\x2e\x35\x39\x39\x34\x39\x36\x20\ +\x30\x2c\x2d\x30\x2e\x39\x36\x30\x36\x38\x33\x20\x30\x2e\x37\x35\ +\x33\x34\x37\x37\x2c\x2d\x31\x2e\x36\x31\x39\x39\x37\x35\x20\x31\ +\x2e\x34\x36\x39\x32\x38\x31\x2c\x2d\x32\x2e\x32\x37\x39\x32\x36\ +\x38\x20\x2d\x30\x2e\x38\x32\x38\x38\x32\x35\x2c\x2d\x30\x2e\x35\ +\x32\x37\x34\x33\x34\x20\x2d\x31\x2e\x32\x30\x35\x35\x36\x34\x2c\ +\x2d\x31\x2e\x32\x39\x39\x37\x34\x38\x20\x2d\x31\x2e\x32\x30\x35\ +\x35\x36\x34\x2c\x2d\x32\x2e\x30\x35\x33\x32\x32\x35\x20\x30\x2c\ +\x2d\x31\x2e\x32\x36\x32\x30\x37\x34\x20\x31\x2e\x31\x33\x30\x32\ +\x31\x36\x2c\x2d\x32\x2e\x34\x38\x36\x34\x37\x34\x20\x33\x2e\x32\ +\x35\x38\x37\x38\x39\x2c\x2d\x32\x2e\x34\x38\x36\x34\x37\x34\x20\ +\x31\x2e\x35\x30\x36\x39\x35\x34\x31\x2c\x30\x20\x32\x2e\x39\x37\ +\x36\x32\x33\x34\x31\x2c\x30\x2e\x37\x35\x33\x34\x37\x37\x20\x32\ +\x2e\x39\x37\x36\x32\x33\x34\x31\x2c\x32\x2e\x31\x30\x39\x37\x33\ +\x36\x20\x30\x2c\x30\x2e\x39\x30\x34\x31\x37\x32\x20\x2d\x30\x2e\ +\x36\x30\x32\x37\x38\x32\x2c\x31\x2e\x35\x38\x32\x33\x30\x31\x20\ +\x2d\x31\x2e\x32\x34\x33\x32\x33\x37\x2c\x32\x2e\x32\x34\x31\x35\ +\x39\x34\x20\x7a\x20\x6d\x20\x2d\x33\x2e\x32\x35\x38\x37\x38\x38\ +\x31\x2c\x30\x2e\x34\x38\x39\x37\x36\x20\x63\x20\x2d\x30\x2e\x36\ +\x34\x30\x34\x35\x36\x2c\x30\x2e\x35\x36\x35\x31\x30\x38\x20\x2d\ +\x31\x2e\x32\x34\x33\x32\x33\x38\x2c\x31\x2e\x31\x34\x39\x30\x35\ +\x33\x20\x2d\x31\x2e\x32\x34\x33\x32\x33\x38\x2c\x31\x2e\x39\x37\ +\x37\x38\x37\x37\x20\x30\x2c\x31\x2e\x32\x39\x39\x37\x34\x38\x20\ +\x31\x2e\x32\x34\x33\x32\x33\x38\x2c\x32\x2e\x32\x30\x33\x39\x32\ +\x31\x20\x32\x2e\x36\x31\x38\x33\x33\x33\x2c\x32\x2e\x32\x30\x33\ +\x39\x32\x31\x20\x31\x2e\x30\x33\x36\x30\x33\x31\x32\x2c\x30\x20\ +\x31\x2e\x36\x35\x37\x36\x35\x30\x31\x2c\x2d\x30\x2e\x38\x30\x39\ +\x39\x38\x38\x20\x31\x2e\x36\x35\x37\x36\x35\x30\x31\x2c\x2d\x31\ +\x2e\x36\x30\x31\x31\x33\x39\x20\x30\x2c\x2d\x30\x2e\x34\x37\x30\ +\x39\x32\x33\x20\x2d\x30\x2e\x32\x30\x37\x32\x30\x35\x39\x2c\x2d\ +\x30\x2e\x39\x36\x30\x36\x38\x33\x20\x2d\x30\x2e\x36\x39\x36\x39\ +\x36\x36\x39\x2c\x2d\x31\x2e\x32\x34\x33\x32\x33\x37\x20\x7a\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x37\ +\x32\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ +\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\ +\x76\x67\x3e\x0a\ +\x00\x00\x07\x5b\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x22\x0a\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\ +\x22\x30\x2e\x34\x38\x2e\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\ +\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\ +\x6d\x65\x3d\x22\x66\x6c\x61\x67\x38\x69\x2e\x73\x76\x67\x22\x3e\ +\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x31\x30\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\ +\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\ +\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\ +\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\ +\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\ +\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\ +\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x38\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\ +\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\ +\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\ +\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ +\x69\x67\x68\x74\x3d\x22\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\ +\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x32\x31\x2e\x33\x36\ +\x30\x32\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x78\x3d\x22\x32\x32\x2e\x34\x31\x31\x39\x31\ +\x37\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x79\x3d\x22\x39\x39\x35\x2e\x39\x31\x39\x38\x39\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x79\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ +\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\ +\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x32\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\ +\x67\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\ +\x73\x2e\x64\x33\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\ +\x2d\x30\x2e\x30\x37\x31\x33\x34\x32\x32\x38\x2c\x2d\x30\x2e\x30\ +\x37\x30\x33\x30\x36\x32\x31\x20\x43\x20\x32\x2e\x34\x30\x33\x36\ +\x35\x37\x38\x2c\x2d\x31\x2e\x35\x34\x35\x33\x30\x36\x33\x20\x35\ +\x2e\x36\x37\x38\x36\x35\x37\x38\x2c\x2d\x33\x2e\x38\x32\x30\x33\ +\x30\x36\x33\x20\x35\x2e\x36\x37\x38\x36\x35\x37\x38\x2c\x2d\x36\ +\x2e\x36\x34\x35\x33\x30\x36\x33\x20\x63\x20\x30\x2c\x2d\x31\x2e\ +\x36\x32\x35\x30\x30\x30\x35\x20\x2d\x30\x2e\x35\x32\x35\x2c\x2d\ +\x33\x2e\x32\x32\x35\x30\x30\x30\x34\x20\x2d\x31\x2e\x33\x35\x2c\ +\x2d\x34\x2e\x36\x32\x35\x30\x30\x30\x37\x20\x2d\x30\x2e\x30\x37\ +\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x30\x2e\x32\x32\x35\x2c\x2d\ +\x30\x2e\x36\x32\x35\x20\x30\x2e\x35\x32\x35\x2c\x2d\x30\x2e\x36\ +\x32\x35\x20\x30\x2e\x31\x37\x35\x2c\x30\x20\x30\x2e\x33\x35\x2c\ +\x30\x2e\x31\x20\x30\x2e\x34\x35\x2c\x30\x2e\x32\x37\x35\x20\x30\ +\x2e\x38\x32\x35\x2c\x31\x2e\x35\x32\x35\x20\x31\x2e\x33\x35\x2c\ +\x33\x2e\x32\x32\x35\x30\x30\x30\x32\x20\x31\x2e\x33\x35\x2c\x34\ +\x2e\x39\x37\x35\x30\x30\x30\x37\x20\x30\x2c\x35\x2e\x31\x32\x35\ +\x20\x2d\x36\x2e\x37\x32\x35\x30\x30\x30\x30\x38\x2c\x37\x2e\x37\ +\x30\x30\x30\x30\x30\x31\x20\x2d\x36\x2e\x37\x32\x35\x30\x30\x30\ +\x30\x38\x2c\x31\x32\x2e\x38\x32\x35\x20\x68\x20\x2d\x30\x2e\x33\ +\x35\x20\x76\x20\x2d\x36\x2e\x32\x34\x39\x39\x39\x39\x39\x31\x20\ +\x68\x20\x30\x2e\x33\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x70\x61\x74\x68\x34\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ +\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\ +\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x09\x4e\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x33\x38\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x72\x65\ +\x73\x74\x34\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\ +\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x31\x36\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x37\x2e\x35\x35\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ +\x22\x34\x38\x2e\x39\x37\x32\x37\x30\x32\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x30\ +\x30\x34\x2e\x30\x34\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\ +\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x31\ +\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\ +\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\ +\x72\x3d\x22\x73\x76\x67\x33\x33\x38\x31\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x33\x38\x39\ +\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\ +\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\ +\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\ +\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\ +\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\ +\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\ +\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ +\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\ +\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\ +\x73\x33\x33\x38\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\ +\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x2e\x37\x32\ +\x31\x33\x39\x38\x33\x2c\x32\x2e\x33\x34\x30\x35\x33\x38\x20\x63\ +\x20\x30\x2c\x2d\x30\x2e\x36\x35\x20\x30\x2e\x32\x35\x2c\x2d\x31\ +\x20\x30\x2e\x39\x2c\x2d\x31\x20\x30\x2e\x38\x35\x2c\x30\x20\x32\ +\x2e\x31\x32\x35\x2c\x30\x2e\x33\x37\x35\x20\x33\x2e\x32\x35\x2c\ +\x30\x2e\x39\x32\x35\x20\x6c\x20\x2d\x33\x2e\x34\x32\x35\x2c\x2d\ +\x34\x2e\x31\x20\x63\x20\x2d\x30\x2e\x31\x37\x35\x2c\x2d\x30\x2e\ +\x32\x20\x2d\x30\x2e\x32\x35\x2c\x2d\x30\x2e\x34\x32\x35\x20\x2d\ +\x30\x2e\x32\x35\x2c\x2d\x30\x2e\x36\x32\x35\x20\x30\x2c\x2d\x30\ +\x2e\x38\x32\x35\x20\x31\x2e\x32\x32\x35\x2c\x2d\x31\x2e\x36\x20\ +\x32\x2e\x31\x35\x2c\x2d\x32\x2e\x34\x20\x30\x2e\x36\x35\x2c\x2d\ +\x30\x2e\x35\x35\x20\x30\x2e\x39\x37\x35\x2c\x2d\x31\x2e\x33\x35\ +\x20\x30\x2e\x39\x37\x35\x2c\x2d\x32\x2e\x31\x32\x35\x20\x30\x2c\ +\x2d\x30\x2e\x36\x20\x2d\x30\x2e\x32\x2c\x2d\x31\x2e\x31\x37\x35\ +\x20\x2d\x30\x2e\x36\x2c\x2d\x31\x2e\x36\x37\x35\x20\x6c\x20\x2d\ +\x30\x2e\x39\x37\x35\x2c\x2d\x31\x2e\x31\x35\x20\x63\x20\x2d\x30\ +\x2e\x30\x35\x2c\x2d\x30\x2e\x30\x37\x35\x20\x2d\x30\x2e\x30\x37\ +\x35\x2c\x2d\x30\x2e\x31\x35\x20\x2d\x30\x2e\x30\x37\x35\x2c\x2d\ +\x30\x2e\x32\x32\x35\x20\x30\x2c\x2d\x30\x2e\x31\x37\x35\x20\x30\ +\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x33\x35\x20\x30\x2e\x33\x35\x2c\ +\x2d\x30\x2e\x33\x35\x20\x30\x2e\x30\x37\x35\x2c\x30\x20\x30\x2e\ +\x31\x37\x35\x2c\x30\x2e\x30\x32\x35\x20\x30\x2e\x32\x35\x2c\x30\ +\x2e\x31\x32\x35\x20\x6c\x20\x33\x2e\x38\x2c\x34\x2e\x35\x35\x20\ +\x63\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\x32\x20\x30\x2e\x32\x35\ +\x2c\x30\x2e\x34\x32\x35\x20\x30\x2e\x32\x35\x2c\x30\x2e\x36\x32\ +\x35\x20\x30\x2c\x30\x2e\x38\x32\x35\x20\x2d\x31\x2e\x32\x32\x35\ +\x2c\x31\x2e\x36\x20\x2d\x32\x2e\x31\x35\x2c\x32\x2e\x34\x20\x2d\ +\x30\x2e\x36\x35\x2c\x30\x2e\x35\x35\x20\x2d\x30\x2e\x39\x37\x35\ +\x2c\x31\x2e\x33\x35\x20\x2d\x30\x2e\x39\x37\x35\x2c\x32\x2e\x31\ +\x32\x34\x39\x39\x39\x39\x35\x20\x30\x2c\x30\x2e\x36\x20\x30\x2e\ +\x32\x2c\x31\x2e\x31\x37\x35\x20\x30\x2e\x36\x2c\x31\x2e\x36\x37\ +\x35\x30\x30\x30\x30\x35\x20\x6c\x20\x32\x2e\x31\x37\x35\x2c\x32\ +\x2e\x36\x20\x63\x20\x30\x2e\x30\x35\x2c\x30\x2e\x30\x37\x35\x20\ +\x30\x2e\x30\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\x30\x2e\x30\x37\ +\x35\x2c\x30\x2e\x32\x20\x30\x2c\x30\x2e\x31\x37\x35\x20\x2d\x30\ +\x2e\x31\x37\x35\x2c\x30\x2e\x33\x35\x20\x2d\x30\x2e\x33\x35\x2c\ +\x30\x2e\x33\x35\x20\x2d\x30\x2e\x30\x37\x35\x2c\x30\x20\x2d\x30\ +\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x2d\x30\x2e\x32\ +\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\x34\x37\x35\x2c\ +\x2d\x30\x2e\x35\x35\x20\x2d\x31\x2e\x36\x35\x2c\x2d\x31\x2e\x30\ +\x37\x35\x20\x2d\x32\x2e\x35\x35\x2c\x2d\x31\x2e\x30\x37\x35\x20\ +\x2d\x31\x2c\x30\x20\x2d\x31\x2e\x33\x2c\x30\x2e\x37\x32\x35\x20\ +\x2d\x31\x2e\x33\x2c\x31\x2e\x37\x35\x20\x30\x2c\x30\x2e\x38\x37\ +\x35\x20\x30\x2e\x32\x37\x35\x2c\x31\x2e\x38\x37\x35\x20\x30\x2e\ +\x37\x2c\x32\x2e\x34\x20\x30\x2e\x31\x2c\x30\x2e\x31\x32\x35\x20\ +\x30\x2c\x30\x2e\x32\x37\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\x30\ +\x2e\x32\x37\x35\x20\x2d\x30\x2e\x30\x35\x2c\x30\x20\x2d\x30\x2e\ +\x31\x2c\x30\x20\x2d\x30\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x30\x35\ +\x20\x2d\x31\x2e\x31\x35\x2c\x2d\x31\x2e\x33\x37\x35\x20\x2d\x32\ +\x2e\x33\x32\x35\x2c\x2d\x33\x2e\x37\x35\x20\x2d\x32\x2e\x33\x32\ +\x35\x2c\x2d\x35\x2e\x31\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x70\x61\x74\x68\x33\x33\x38\x33\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\ +\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\ +\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x05\x52\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x32\x22\x3e\x0a\x20\x20\x3c\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x31\x30\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ +\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ +\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ +\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x64\x65\x66\x73\x38\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\ +\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x2e\ +\x39\x35\x2c\x2d\x31\x2e\x36\x37\x35\x20\x63\x20\x30\x2c\x2d\x30\ +\x2e\x36\x32\x35\x20\x2d\x30\x2e\x35\x32\x35\x2c\x2d\x31\x2e\x30\ +\x35\x20\x2d\x31\x2e\x30\x37\x35\x2c\x2d\x31\x2e\x30\x35\x20\x2d\ +\x30\x2e\x31\x2c\x30\x20\x2d\x30\x2e\x32\x32\x35\x2c\x30\x2e\x30\ +\x32\x35\x20\x2d\x30\x2e\x33\x32\x35\x2c\x30\x2e\x30\x35\x20\x43\ +\x20\x35\x2e\x37\x37\x35\x2c\x2d\x32\x2e\x34\x35\x20\x34\x2e\x35\ +\x37\x35\x2c\x2d\x31\x2e\x36\x35\x20\x33\x2e\x36\x32\x35\x2c\x2d\ +\x31\x2e\x30\x35\x20\x32\x2e\x36\x37\x35\x2c\x2d\x30\x2e\x34\x35\ +\x20\x31\x2e\x35\x2c\x30\x2e\x33\x32\x35\x20\x30\x2e\x39\x37\x35\ +\x2c\x30\x2e\x39\x35\x20\x30\x2e\x38\x2c\x31\x2e\x31\x35\x20\x30\ +\x2e\x37\x2c\x31\x2e\x34\x32\x35\x20\x30\x2e\x37\x2c\x31\x2e\x36\ +\x37\x35\x20\x63\x20\x30\x2c\x30\x2e\x36\x32\x35\x20\x30\x2e\x35\ +\x32\x35\x2c\x31\x2e\x30\x35\x20\x31\x2e\x30\x37\x35\x2c\x31\x2e\ +\x30\x35\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\x32\x2c\x2d\x30\x2e\ +\x30\x32\x35\x20\x30\x2e\x33\x2c\x2d\x30\x2e\x30\x35\x20\x43\x20\ +\x32\x2e\x38\x35\x2c\x32\x2e\x34\x35\x20\x34\x2e\x30\x35\x2c\x31\ +\x2e\x36\x35\x20\x35\x2c\x31\x2e\x30\x35\x20\x35\x2e\x39\x35\x2c\ +\x30\x2e\x34\x35\x20\x37\x2e\x31\x35\x2c\x2d\x30\x2e\x33\x32\x35\ +\x20\x37\x2e\x36\x37\x35\x2c\x2d\x30\x2e\x39\x35\x20\x37\x2e\x38\ +\x35\x2c\x2d\x31\x2e\x31\x35\x20\x37\x2e\x39\x35\x2c\x2d\x31\x2e\ +\x34\x32\x35\x20\x37\x2e\x39\x35\x2c\x2d\x31\x2e\x36\x37\x35\x20\ +\x7a\x20\x4d\x20\x36\x2e\x36\x37\x35\x2c\x2d\x33\x2e\x34\x20\x63\ +\x20\x31\x2e\x31\x2c\x30\x20\x31\x2e\x39\x37\x35\x2c\x30\x2e\x35\ +\x20\x31\x2e\x39\x37\x35\x2c\x31\x2e\x37\x20\x30\x2c\x30\x2e\x34\ +\x37\x35\x20\x2d\x30\x2e\x31\x35\x2c\x30\x2e\x39\x35\x20\x2d\x30\ +\x2e\x33\x2c\x31\x2e\x34\x32\x35\x20\x43\x20\x38\x2e\x30\x32\x35\ +\x2c\x30\x2e\x36\x35\x20\x37\x2e\x35\x35\x2c\x31\x2e\x35\x35\x20\ +\x36\x2e\x37\x32\x35\x2c\x32\x2e\x31\x20\x35\x2e\x33\x37\x35\x2c\ +\x33\x20\x33\x2e\x38\x35\x2c\x33\x2e\x34\x20\x31\x2e\x39\x37\x35\ +\x2c\x33\x2e\x34\x20\x30\x2e\x38\x37\x35\x2c\x33\x2e\x34\x20\x30\ +\x2c\x32\x2e\x39\x20\x30\x2c\x31\x2e\x37\x20\x30\x2c\x31\x2e\x32\ +\x32\x35\x20\x30\x2e\x31\x35\x2c\x30\x2e\x37\x35\x20\x30\x2e\x33\ +\x2c\x30\x2e\x32\x37\x35\x20\x30\x2e\x36\x32\x35\x2c\x2d\x30\x2e\ +\x36\x35\x20\x31\x2e\x30\x37\x35\x2c\x2d\x31\x2e\x35\x35\x20\x31\ +\x2e\x39\x2c\x2d\x32\x2e\x31\x20\x33\x2e\x32\x35\x2c\x2d\x33\x20\ +\x34\x2e\x38\x2c\x2d\x33\x2e\x34\x20\x36\x2e\x36\x37\x35\x2c\x2d\ +\x33\x2e\x34\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x34\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ +\x0a\ +\x00\x00\x04\xce\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x31\x30\x39\x22\x3e\x0a\ +\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x31\x31\ +\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ +\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ +\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ +\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ +\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x31\x31\x35\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x6d\x20\x2d\x35\x2e\x30\x35\x36\x31\x31\x33\x31\ +\x2c\x2d\x38\x2e\x38\x38\x31\x34\x30\x35\x35\x20\x63\x20\x30\x2e\ +\x31\x37\x35\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x34\x2c\x2d\x30\x2e\ +\x31\x35\x20\x30\x2e\x36\x2c\x2d\x30\x2e\x31\x35\x20\x30\x2e\x32\ +\x2c\x30\x20\x30\x2e\x34\x2c\x30\x2e\x30\x35\x20\x30\x2e\x35\x37\ +\x35\x2c\x30\x2e\x31\x35\x20\x6c\x20\x2d\x30\x2e\x30\x35\x2c\x34\ +\x2e\x33\x37\x35\x20\x32\x2e\x37\x32\x35\x2c\x2d\x30\x2e\x34\x32\ +\x35\x20\x63\x20\x30\x2e\x30\x32\x35\x2c\x30\x20\x30\x2e\x30\x35\ +\x2c\x2d\x30\x2e\x30\x32\x35\x20\x30\x2e\x30\x37\x35\x2c\x2d\x30\ +\x2e\x30\x32\x35\x20\x30\x2e\x32\x32\x34\x39\x39\x39\x39\x38\x2c\ +\x30\x20\x30\x2e\x34\x32\x34\x39\x39\x39\x39\x38\x2c\x30\x2e\x32\ +\x20\x30\x2e\x34\x32\x34\x39\x39\x39\x39\x38\x2c\x30\x2e\x34\x32\ +\x35\x20\x6c\x20\x30\x2e\x31\x35\x2c\x31\x34\x2e\x34\x20\x63\x20\ +\x2d\x30\x2e\x31\x37\x35\x2c\x30\x2e\x31\x20\x2d\x30\x2e\x33\x37\ +\x35\x2c\x30\x2e\x31\x35\x30\x30\x30\x30\x35\x20\x2d\x30\x2e\x35\ +\x37\x34\x39\x39\x39\x39\x38\x2c\x30\x2e\x31\x35\x30\x30\x30\x30\ +\x35\x20\x2d\x30\x2e\x32\x2c\x30\x20\x2d\x30\x2e\x34\x2c\x2d\x30\ +\x2e\x30\x35\x20\x2d\x30\x2e\x35\x37\x35\x2c\x2d\x30\x2e\x31\x35\ +\x30\x30\x30\x30\x35\x20\x6c\x20\x30\x2e\x30\x35\x2c\x2d\x34\x2e\ +\x33\x37\x35\x20\x2d\x32\x2e\x37\x35\x2c\x30\x2e\x34\x32\x35\x20\ +\x63\x20\x2d\x30\x2e\x30\x32\x35\x2c\x30\x20\x2d\x30\x2e\x30\x32\ +\x35\x2c\x30\x2e\x30\x32\x35\x20\x2d\x30\x2e\x30\x35\x2c\x30\x2e\ +\x30\x32\x35\x20\x2d\x30\x2e\x32\x32\x35\x2c\x30\x20\x2d\x30\x2e\ +\x34\x32\x35\x2c\x2d\x30\x2e\x32\x20\x2d\x30\x2e\x34\x32\x35\x2c\ +\x2d\x30\x2e\x34\x32\x35\x20\x7a\x20\x6d\x20\x33\x2e\x34\x32\x35\ +\x2c\x31\x31\x2e\x38\x35\x20\x30\x2e\x30\x35\x2c\x2d\x35\x2e\x33\ +\x32\x35\x20\x2d\x32\x2e\x33\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\ +\x2d\x30\x2e\x30\x37\x35\x2c\x35\x2e\x33\x32\x35\x20\x7a\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x31\x31\ +\x31\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x23\x15\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x30\x36\x39\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x6e\x75\ +\x6d\x62\x65\x72\x73\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x73\ +\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\ +\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\ +\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\ +\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\ +\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\ +\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\ +\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\ +\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\ +\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\ +\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\ +\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\ +\x3d\x22\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x32\x39\x39\x38\x22\x0a\ +\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\ +\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x39\x2e\x36\x31\x36\x36\ +\x35\x32\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x78\x3d\x22\x31\x34\x37\x2e\x31\x38\x30\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\ +\x79\x3d\x22\x39\x37\x34\x2e\x39\x39\x36\x36\x33\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x79\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\ +\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\ +\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x30\x36\x39\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x33\x30\x37\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\ +\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x64\x65\x66\x73\x33\x30\x37\x35\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\ +\x20\x31\x31\x2e\x37\x34\x35\x31\x32\x35\x2c\x2d\x30\x2e\x34\x38\ +\x34\x37\x37\x31\x35\x38\x20\x32\x2e\x37\x32\x35\x2c\x2d\x36\x2e\ +\x32\x34\x39\x39\x39\x39\x38\x32\x20\x63\x20\x30\x2e\x30\x32\x35\ +\x2c\x2d\x30\x2e\x30\x35\x20\x30\x2e\x30\x37\x35\x2c\x2d\x30\x2e\ +\x30\x37\x35\x20\x30\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x30\x37\x35\ +\x20\x30\x2e\x30\x37\x35\x2c\x30\x20\x30\x2e\x31\x37\x35\x2c\x30\ +\x2e\x30\x32\x35\x20\x30\x2e\x32\x35\x2c\x30\x2e\x30\x37\x35\x20\ +\x30\x2e\x33\x32\x35\x2c\x30\x2e\x31\x35\x20\x30\x2e\x36\x35\x2c\ +\x30\x2e\x33\x32\x35\x20\x31\x2c\x30\x2e\x33\x32\x35\x20\x30\x2e\ +\x33\x35\x2c\x30\x20\x30\x2e\x36\x35\x2c\x2d\x30\x2e\x31\x37\x35\ +\x20\x30\x2e\x39\x37\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x30\x2e\ +\x30\x32\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x30\x2e\x30\x37\x35\ +\x2c\x2d\x30\x2e\x30\x32\x35\x20\x30\x2e\x31\x2c\x2d\x30\x2e\x30\ +\x32\x35\x20\x30\x2e\x31\x35\x2c\x30\x20\x30\x2e\x32\x37\x35\x2c\ +\x30\x2e\x31\x37\x35\x20\x30\x2e\x32\x37\x35\x2c\x30\x2e\x34\x20\ +\x76\x20\x39\x2e\x33\x39\x39\x39\x39\x39\x38\x20\x63\x20\x30\x2c\ +\x31\x2e\x31\x32\x35\x20\x30\x2e\x36\x35\x2c\x32\x2e\x32\x20\x31\ +\x2e\x37\x2c\x32\x2e\x32\x20\x30\x2e\x31\x37\x35\x2c\x30\x20\x30\ +\x2e\x32\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\x30\x2e\x32\x37\x35\ +\x2c\x30\x2e\x32\x35\x20\x30\x2c\x30\x2e\x31\x32\x35\x20\x2d\x30\ +\x2e\x31\x2c\x30\x2e\x32\x37\x35\x20\x2d\x30\x2e\x32\x37\x35\x2c\ +\x30\x2e\x32\x37\x35\x20\x2d\x31\x2e\x30\x32\x35\x2c\x30\x20\x2d\ +\x32\x2e\x30\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x2d\x33\x2e\ +\x30\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x2d\x31\x2e\x30\x32\x35\ +\x2c\x30\x20\x2d\x32\x2e\x30\x35\x2c\x30\x2e\x33\x32\x35\x20\x2d\ +\x33\x2e\x30\x37\x35\x2c\x30\x2e\x33\x32\x35\x20\x2d\x30\x2e\x31\ +\x37\x35\x2c\x30\x20\x2d\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x31\ +\x35\x20\x2d\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x32\x37\x35\x20\ +\x30\x2c\x2d\x30\x2e\x31\x32\x35\x20\x30\x2e\x31\x2c\x2d\x30\x2e\ +\x32\x35\x20\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x32\x35\x20\x31\ +\x2e\x30\x35\x2c\x30\x20\x31\x2e\x37\x2c\x2d\x31\x2e\x30\x37\x35\ +\x20\x31\x2e\x37\x2c\x2d\x32\x2e\x32\x20\x76\x20\x2d\x36\x2e\x34\ +\x35\x20\x63\x20\x30\x2c\x2d\x30\x2e\x32\x37\x35\x20\x2d\x30\x2e\ +\x32\x2c\x2d\x30\x2e\x34\x32\x35\x20\x2d\x30\x2e\x33\x37\x35\x2c\ +\x2d\x30\x2e\x34\x32\x35\x20\x2d\x30\x2e\x31\x2c\x30\x20\x2d\x30\ +\x2e\x31\x37\x35\x2c\x30\x2e\x30\x35\x20\x2d\x30\x2e\x32\x32\x35\ +\x2c\x30\x2e\x31\x35\x20\x6c\x20\x2d\x31\x2e\x35\x32\x35\x2c\x33\ +\x2e\x34\x37\x35\x30\x30\x30\x30\x32\x20\x63\x20\x2d\x30\x2e\x30\ +\x35\x2c\x30\x2e\x31\x35\x20\x2d\x30\x2e\x31\x35\x2c\x30\x2e\x32\ +\x20\x2d\x30\x2e\x32\x37\x35\x2c\x30\x2e\x32\x20\x2d\x30\x2e\x31\ +\x37\x35\x2c\x30\x20\x2d\x30\x2e\x33\x35\x2c\x2d\x30\x2e\x31\x32\ +\x35\x20\x2d\x30\x2e\x33\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x30\ +\x2c\x2d\x30\x2e\x30\x35\x20\x30\x2c\x2d\x30\x2e\x31\x20\x30\x2e\ +\x30\x32\x35\x2c\x2d\x30\x2e\x31\x35\x20\x7a\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6f\x6e\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\ +\x32\x32\x2e\x37\x30\x31\x36\x32\x35\x2c\x35\x2e\x35\x31\x35\x32\ +\x32\x38\x34\x20\x63\x20\x2d\x30\x2e\x30\x32\x35\x2c\x30\x2e\x31\ +\x37\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\x30\x2e\x32\x35\x20\x2d\ +\x30\x2e\x32\x35\x2c\x30\x2e\x32\x35\x20\x2d\x30\x2e\x31\x32\x35\ +\x2c\x30\x20\x2d\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x30\x37\x35\ +\x20\x2d\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x32\x35\x20\x30\x2c\ +\x2d\x34\x2e\x33\x37\x35\x20\x35\x2e\x39\x2c\x2d\x34\x2e\x31\x32\ +\x35\x20\x35\x2e\x39\x2c\x2d\x38\x2e\x36\x32\x35\x20\x30\x2c\x2d\ +\x31\x2e\x35\x32\x34\x39\x39\x39\x38\x20\x2d\x30\x2e\x35\x35\x2c\ +\x2d\x33\x2e\x30\x39\x39\x39\x39\x39\x38\x20\x2d\x31\x2e\x38\x37\ +\x35\x2c\x2d\x33\x2e\x30\x39\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\ +\x36\x32\x35\x2c\x30\x20\x2d\x31\x2e\x32\x2c\x30\x2e\x33\x35\x20\ +\x2d\x31\x2e\x32\x2c\x30\x2e\x39\x32\x35\x20\x30\x2c\x30\x2e\x36\ +\x37\x35\x20\x30\x2e\x38\x37\x35\x2c\x31\x2e\x30\x32\x35\x20\x30\ +\x2e\x38\x37\x35\x2c\x31\x2e\x36\x39\x39\x39\x39\x39\x38\x20\x30\ +\x2c\x30\x2e\x39\x35\x20\x2d\x30\x2e\x37\x37\x35\x2c\x31\x2e\x37\ +\x32\x35\x20\x2d\x31\x2e\x37\x32\x35\x2c\x31\x2e\x37\x32\x35\x20\ +\x2d\x30\x2e\x39\x35\x2c\x30\x20\x2d\x31\x2e\x37\x2c\x2d\x30\x2e\ +\x37\x37\x35\x20\x2d\x31\x2e\x37\x2c\x2d\x31\x2e\x37\x32\x35\x20\ +\x30\x2c\x2d\x31\x2e\x38\x37\x34\x39\x39\x39\x38\x20\x31\x2e\x37\ +\x37\x35\x2c\x2d\x33\x2e\x31\x34\x39\x39\x39\x39\x38\x20\x33\x2e\ +\x37\x35\x2c\x2d\x33\x2e\x31\x34\x39\x39\x39\x39\x38\x20\x32\x2e\ +\x33\x37\x35\x2c\x30\x20\x34\x2e\x36\x2c\x31\x2e\x34\x32\x35\x20\ +\x34\x2e\x36\x2c\x33\x2e\x36\x32\x34\x39\x39\x39\x38\x20\x30\x2c\ +\x33\x2e\x39\x35\x30\x30\x30\x30\x30\x32\x20\x2d\x34\x2e\x30\x35\ +\x2c\x34\x2e\x30\x30\x30\x30\x30\x30\x30\x32\x20\x2d\x36\x2e\x34\ +\x32\x35\x2c\x35\x2e\x37\x32\x35\x20\x30\x2e\x33\x2c\x2d\x30\x2e\ +\x30\x37\x35\x20\x30\x2e\x36\x2c\x2d\x30\x2e\x31\x32\x35\x20\x30\ +\x2e\x39\x32\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x30\x2e\x38\x2c\ +\x30\x20\x31\x2e\x36\x37\x35\x2c\x30\x2e\x32\x35\x20\x32\x2e\x35\ +\x32\x35\x2c\x30\x2e\x38\x32\x35\x20\x30\x2e\x35\x37\x35\x2c\x30\ +\x2e\x34\x20\x31\x2e\x32\x32\x35\x2c\x30\x2e\x36\x32\x35\x20\x31\ +\x2e\x37\x35\x2c\x30\x2e\x36\x32\x35\x20\x30\x2e\x35\x2c\x30\x20\ +\x30\x2e\x39\x32\x35\x2c\x2d\x30\x2e\x32\x20\x31\x2e\x30\x35\x2c\ +\x2d\x30\x2e\x37\x20\x30\x2e\x30\x32\x35\x2c\x2d\x30\x2e\x31\x35\ +\x20\x30\x2e\x31\x35\x2c\x2d\x30\x2e\x32\x20\x30\x2e\x32\x35\x2c\ +\x2d\x30\x2e\x32\x20\x30\x2e\x31\x32\x35\x2c\x30\x20\x30\x2e\x32\ +\x37\x35\x2c\x30\x2e\x31\x20\x30\x2e\x32\x37\x35\x2c\x30\x2e\x32\ +\x35\x20\x30\x2c\x31\x2e\x35\x37\x35\x20\x2d\x32\x2e\x31\x32\x35\ +\x2c\x32\x2e\x34\x37\x35\x20\x2d\x33\x2e\x33\x2c\x32\x2e\x34\x37\ +\x35\x20\x2d\x30\x2e\x38\x37\x35\x2c\x30\x20\x2d\x31\x2e\x37\x32\ +\x35\x2c\x2d\x30\x2e\x33\x35\x20\x2d\x32\x2e\x33\x35\x2c\x2d\x31\ +\x2e\x30\x35\x20\x2d\x30\x2e\x33\x35\x2c\x2d\x30\x2e\x34\x20\x2d\ +\x30\x2e\x38\x2c\x2d\x30\x2e\x35\x37\x35\x20\x2d\x31\x2e\x32\x35\ +\x2c\x2d\x30\x2e\x35\x37\x35\x20\x2d\x30\x2e\x37\x35\x2c\x30\x20\ +\x2d\x31\x2e\x34\x37\x35\x2c\x30\x2e\x35\x32\x35\x20\x2d\x31\x2e\ +\x35\x35\x2c\x31\x2e\x33\x37\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x74\x77\x6f\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x33\ +\x37\x2e\x34\x38\x33\x30\x32\x35\x2c\x2d\x36\x2e\x32\x30\x39\x37\ +\x37\x31\x34\x20\x63\x20\x2d\x30\x2e\x37\x2c\x30\x20\x2d\x31\x2e\ +\x34\x35\x2c\x30\x2e\x32\x32\x35\x20\x2d\x31\x2e\x34\x35\x2c\x30\ +\x2e\x38\x32\x35\x20\x30\x2c\x30\x2e\x35\x35\x20\x30\x2e\x39\x2c\ +\x30\x2e\x36\x32\x35\x20\x30\x2e\x39\x2c\x31\x2e\x31\x37\x35\x20\ +\x30\x2c\x30\x2e\x37\x39\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\x36\ +\x32\x35\x2c\x31\x2e\x34\x32\x34\x39\x39\x39\x38\x20\x2d\x31\x2e\ +\x34\x32\x35\x2c\x31\x2e\x34\x32\x34\x39\x39\x39\x38\x20\x2d\x30\ +\x2e\x38\x2c\x30\x20\x2d\x31\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x36\ +\x32\x35\x20\x2d\x31\x2e\x34\x32\x35\x2c\x2d\x31\x2e\x34\x32\x34\ +\x39\x39\x39\x38\x20\x30\x2c\x2d\x31\x2e\x35\x37\x35\x20\x31\x2e\ +\x36\x35\x2c\x2d\x32\x2e\x35\x32\x35\x20\x33\x2e\x34\x2c\x2d\x32\ +\x2e\x35\x32\x35\x20\x32\x2e\x32\x35\x2c\x30\x20\x34\x2e\x31\x32\ +\x35\x2c\x30\x2e\x38\x37\x35\x20\x34\x2e\x31\x32\x35\x2c\x32\x2e\ +\x38\x37\x34\x39\x39\x39\x38\x20\x30\x2c\x31\x2e\x31\x20\x2d\x30\ +\x2e\x30\x37\x35\x2c\x32\x2e\x30\x37\x35\x20\x2d\x31\x2e\x30\x32\ +\x35\x2c\x32\x2e\x35\x32\x35\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x31\ +\x20\x2d\x30\x2e\x33\x32\x35\x2c\x30\x2e\x33\x20\x2d\x30\x2e\x33\ +\x32\x35\x2c\x30\x2e\x35\x30\x30\x30\x30\x30\x30\x32\x20\x30\x2c\ +\x30\x2e\x32\x20\x30\x2e\x31\x32\x35\x2c\x30\x2e\x34\x20\x30\x2e\ +\x33\x32\x35\x2c\x30\x2e\x35\x20\x31\x2e\x30\x32\x35\x2c\x30\x2e\ +\x34\x37\x35\x20\x31\x2e\x33\x37\x35\x2c\x31\x2e\x34\x34\x39\x39\ +\x39\x39\x39\x38\x20\x31\x2e\x33\x37\x35\x2c\x32\x2e\x35\x39\x39\ +\x39\x39\x39\x39\x38\x20\x30\x2c\x32\x2e\x32\x37\x35\x20\x2d\x31\ +\x2e\x39\x32\x35\x2c\x33\x2e\x35\x20\x2d\x34\x2e\x33\x37\x35\x2c\ +\x33\x2e\x35\x20\x2d\x31\x2e\x39\x32\x35\x2c\x30\x20\x2d\x33\x2e\ +\x37\x37\x35\x2c\x2d\x31\x2e\x30\x32\x35\x20\x2d\x33\x2e\x37\x37\ +\x35\x2c\x2d\x32\x2e\x37\x37\x35\x20\x30\x2c\x2d\x30\x2e\x39\x20\ +\x30\x2e\x37\x32\x35\x2c\x2d\x31\x2e\x36\x32\x35\x20\x31\x2e\x36\ +\x32\x35\x2c\x2d\x31\x2e\x36\x32\x35\x20\x30\x2e\x39\x2c\x30\x20\ +\x31\x2e\x36\x32\x35\x2c\x30\x2e\x37\x32\x35\x20\x31\x2e\x36\x32\ +\x35\x2c\x31\x2e\x36\x32\x35\x20\x30\x2c\x30\x2e\x36\x32\x35\x20\ +\x2d\x31\x2c\x30\x2e\x37\x20\x2d\x31\x2c\x31\x2e\x33\x32\x35\x20\ +\x30\x2c\x30\x2e\x36\x35\x20\x30\x2e\x37\x37\x35\x2c\x30\x2e\x39\ +\x32\x35\x20\x31\x2e\x35\x32\x35\x2c\x30\x2e\x39\x32\x35\x20\x31\ +\x2e\x32\x35\x2c\x30\x20\x31\x2e\x36\x35\x2c\x2d\x31\x2e\x35\x32\ +\x35\x20\x31\x2e\x36\x35\x2c\x2d\x32\x2e\x39\x37\x35\x20\x30\x2c\ +\x2d\x31\x2e\x35\x34\x39\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\x30\ +\x32\x35\x2c\x2d\x32\x2e\x37\x34\x39\x39\x39\x39\x39\x38\x20\x2d\ +\x31\x2e\x33\x35\x2c\x2d\x32\x2e\x37\x34\x39\x39\x39\x39\x39\x38\ +\x20\x68\x20\x2d\x32\x2e\x30\x35\x20\x63\x20\x2d\x30\x2e\x32\x32\ +\x35\x2c\x30\x20\x2d\x30\x2e\x33\x32\x35\x2c\x2d\x30\x2e\x31\x37\ +\x35\x20\x2d\x30\x2e\x33\x32\x35\x2c\x2d\x30\x2e\x33\x35\x20\x30\ +\x2c\x2d\x30\x2e\x31\x37\x35\x30\x30\x30\x30\x32\x20\x30\x2e\x31\ +\x2c\x2d\x30\x2e\x33\x32\x35\x30\x30\x30\x30\x32\x20\x30\x2e\x33\ +\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x30\x30\x30\x30\x32\x20\x68\ +\x20\x32\x2e\x30\x35\x20\x63\x20\x31\x2e\x33\x2c\x30\x20\x31\x2e\ +\x33\x35\x2c\x2d\x31\x2e\x31\x37\x35\x20\x31\x2e\x33\x35\x2c\x2d\ +\x32\x2e\x37\x20\x30\x2c\x2d\x31\x2e\x33\x39\x39\x39\x39\x39\x38\ +\x20\x2d\x30\x2e\x34\x35\x2c\x2d\x32\x2e\x33\x34\x39\x39\x39\x39\ +\x38\x20\x2d\x31\x2e\x37\x35\x2c\x2d\x32\x2e\x33\x34\x39\x39\x39\ +\x39\x38\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x74\ +\x68\x72\x65\x65\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\ +\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x34\x39\x2e\x34\x33\ +\x39\x35\x32\x35\x2c\x2d\x32\x2e\x32\x30\x39\x37\x37\x31\x36\x20\ +\x63\x20\x30\x2e\x35\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x31\ +\x2e\x30\x35\x2c\x2d\x30\x2e\x36\x37\x35\x20\x31\x2e\x34\x32\x35\ +\x2c\x2d\x31\x2e\x31\x37\x35\x20\x30\x2e\x32\x37\x35\x2c\x2d\x30\ +\x2e\x33\x37\x35\x20\x30\x2e\x34\x35\x2c\x2d\x30\x2e\x37\x39\x39\ +\x39\x39\x39\x38\x20\x30\x2e\x36\x32\x35\x2c\x2d\x31\x2e\x32\x32\ +\x34\x39\x39\x39\x38\x20\x30\x2e\x31\x2c\x2d\x30\x2e\x32\x32\x35\ +\x20\x30\x2e\x35\x2c\x2d\x30\x2e\x31\x37\x35\x20\x30\x2e\x35\x2c\ +\x30\x2e\x31\x37\x35\x20\x76\x20\x36\x2e\x33\x39\x39\x39\x39\x39\ +\x38\x20\x68\x20\x31\x2e\x37\x20\x63\x20\x30\x2e\x32\x32\x35\x2c\ +\x30\x20\x30\x2e\x33\x32\x35\x2c\x30\x2e\x31\x37\x35\x20\x30\x2e\ +\x33\x32\x35\x2c\x30\x2e\x33\x35\x20\x30\x2c\x30\x2e\x31\x37\x35\ +\x20\x2d\x30\x2e\x31\x2c\x30\x2e\x33\x32\x35\x20\x2d\x30\x2e\x33\ +\x32\x35\x2c\x30\x2e\x33\x32\x35\x20\x68\x20\x2d\x31\x2e\x37\x20\ +\x76\x20\x30\x2e\x34\x20\x63\x20\x30\x2c\x31\x2e\x31\x32\x35\x20\ +\x30\x2e\x36\x35\x2c\x32\x2e\x32\x20\x31\x2e\x37\x2c\x32\x2e\x32\ +\x20\x30\x2e\x31\x37\x35\x2c\x30\x20\x30\x2e\x32\x35\x2c\x30\x2e\ +\x31\x32\x35\x20\x30\x2e\x32\x35\x2c\x30\x2e\x32\x35\x20\x30\x2c\ +\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\x30\x37\x35\x2c\x30\x2e\x32\ +\x37\x35\x20\x2d\x30\x2e\x32\x35\x2c\x30\x2e\x32\x37\x35\x20\x2d\ +\x31\x2e\x30\x32\x35\x2c\x30\x20\x2d\x32\x2e\x30\x35\x2c\x2d\x30\ +\x2e\x33\x32\x35\x20\x2d\x33\x2e\x30\x37\x35\x2c\x2d\x30\x2e\x33\ +\x32\x35\x20\x2d\x31\x2e\x30\x32\x35\x2c\x30\x20\x2d\x32\x2e\x30\ +\x35\x2c\x30\x2e\x33\x32\x35\x20\x2d\x33\x2e\x30\x37\x35\x2c\x30\ +\x2e\x33\x32\x35\x20\x2d\x30\x2e\x31\x37\x35\x2c\x30\x20\x2d\x30\ +\x2e\x32\x35\x2c\x2d\x30\x2e\x31\x35\x20\x2d\x30\x2e\x32\x35\x2c\ +\x2d\x30\x2e\x32\x37\x35\x20\x30\x2c\x2d\x30\x2e\x31\x32\x35\x20\ +\x30\x2e\x30\x37\x35\x2c\x2d\x30\x2e\x32\x35\x20\x30\x2e\x32\x35\ +\x2c\x2d\x30\x2e\x32\x35\x20\x31\x2e\x30\x35\x2c\x30\x20\x31\x2e\ +\x37\x2c\x2d\x31\x2e\x30\x37\x35\x20\x31\x2e\x37\x2c\x2d\x32\x2e\ +\x32\x20\x76\x20\x2d\x30\x2e\x34\x20\x68\x20\x2d\x34\x2e\x33\x32\ +\x35\x20\x63\x20\x2d\x30\x2e\x35\x32\x35\x2c\x30\x20\x2d\x30\x2e\ +\x37\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x2d\x30\x2e\x37\x32\ +\x35\x2c\x2d\x30\x2e\x35\x32\x35\x20\x30\x2c\x2d\x30\x2e\x30\x35\ +\x20\x30\x2e\x30\x32\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x30\x2e\ +\x30\x35\x2c\x2d\x30\x2e\x31\x35\x20\x32\x2e\x30\x32\x35\x2c\x2d\ +\x32\x2e\x33\x39\x39\x39\x39\x39\x39\x38\x20\x33\x2e\x36\x35\x2c\ +\x2d\x35\x2e\x32\x20\x33\x2e\x36\x35\x2c\x2d\x38\x2e\x33\x32\x34\ +\x39\x39\x39\x38\x20\x30\x2c\x2d\x30\x2e\x32\x20\x30\x2e\x31\x32\ +\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x30\x2e\x33\x2c\x2d\x30\x2e\ +\x33\x37\x35\x20\x68\x20\x30\x2e\x30\x37\x35\x20\x63\x20\x30\x2e\ +\x35\x35\x2c\x30\x2e\x31\x37\x35\x20\x31\x2e\x31\x2c\x30\x2e\x33\ +\x32\x35\x20\x31\x2e\x36\x37\x35\x2c\x30\x2e\x33\x32\x35\x20\x30\ +\x2e\x35\x37\x35\x2c\x30\x20\x31\x2e\x31\x32\x35\x2c\x2d\x30\x2e\ +\x31\x35\x20\x31\x2e\x36\x37\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\ +\x30\x2e\x30\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x30\x2e\x30\x35\ +\x2c\x2d\x30\x2e\x30\x32\x35\x20\x30\x2e\x31\x2c\x2d\x30\x2e\x30\ +\x32\x35\x20\x30\x2e\x32\x35\x2c\x30\x20\x30\x2e\x34\x2c\x30\x2e\ +\x32\x35\x20\x30\x2e\x32\x37\x35\x2c\x30\x2e\x34\x20\x6c\x20\x2d\ +\x37\x2e\x30\x37\x35\x2c\x38\x2e\x33\x32\x34\x39\x39\x39\x38\x20\ +\x68\x20\x34\x2e\x33\x32\x35\x20\x76\x20\x2d\x33\x2e\x36\x37\x35\ +\x20\x63\x20\x30\x2c\x2d\x30\x2e\x32\x20\x30\x2e\x30\x35\x2c\x2d\ +\x30\x2e\x34\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x35\x20\x7a\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x66\x6f\x75\x72\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\ +\x3d\x22\x6d\x20\x35\x37\x2e\x31\x30\x38\x34\x32\x35\x2c\x2d\x36\ +\x2e\x37\x33\x34\x37\x37\x31\x34\x20\x63\x20\x31\x2e\x31\x32\x35\ +\x2c\x30\x2e\x32\x20\x32\x2e\x32\x37\x35\x2c\x30\x2e\x33\x32\x35\ +\x20\x33\x2e\x34\x32\x35\x2c\x30\x2e\x33\x32\x35\x20\x31\x2e\x31\ +\x35\x2c\x30\x20\x32\x2e\x33\x2c\x2d\x30\x2e\x31\x32\x35\x20\x33\ +\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x68\x20\x30\x2e\ +\x30\x37\x35\x20\x63\x20\x30\x2e\x32\x37\x35\x2c\x30\x20\x30\x2e\ +\x34\x32\x35\x2c\x30\x2e\x32\x35\x20\x30\x2e\x33\x2c\x30\x2e\x33\ +\x37\x35\x20\x2d\x31\x2e\x37\x2c\x31\x2e\x37\x20\x2d\x34\x2e\x31\ +\x37\x35\x2c\x32\x2e\x31\x37\x35\x20\x2d\x36\x2e\x35\x37\x35\x2c\ +\x32\x2e\x31\x37\x35\x20\x2d\x30\x2e\x32\x2c\x30\x20\x2d\x30\x2e\ +\x33\x37\x35\x2c\x30\x2e\x31\x37\x34\x39\x39\x39\x38\x20\x2d\x30\ +\x2e\x33\x37\x35\x2c\x30\x2e\x33\x37\x34\x39\x39\x39\x38\x20\x76\ +\x20\x32\x2e\x37\x20\x63\x20\x30\x2e\x37\x2c\x2d\x30\x2e\x37\x20\ +\x31\x2e\x36\x32\x35\x2c\x2d\x31\x2e\x31\x37\x35\x20\x32\x2e\x36\ +\x2c\x2d\x31\x2e\x31\x37\x35\x20\x32\x2e\x38\x37\x35\x2c\x30\x20\ +\x34\x2e\x36\x2c\x31\x2e\x32\x37\x35\x20\x34\x2e\x36\x2c\x34\x2e\ +\x30\x32\x35\x20\x30\x2c\x32\x2e\x33\x20\x2d\x32\x2e\x30\x37\x35\ +\x2c\x34\x2e\x30\x32\x35\x20\x2d\x34\x2e\x34\x37\x35\x2c\x34\x2e\ +\x30\x32\x35\x20\x2d\x32\x2e\x30\x35\x2c\x30\x20\x2d\x34\x2e\x30\ +\x35\x2c\x2d\x30\x2e\x39\x35\x20\x2d\x34\x2e\x30\x35\x2c\x2d\x32\ +\x2e\x37\x37\x35\x20\x30\x2c\x2d\x30\x2e\x39\x20\x30\x2e\x37\x32\ +\x35\x2c\x2d\x31\x2e\x36\x32\x35\x20\x31\x2e\x36\x32\x35\x2c\x2d\ +\x31\x2e\x36\x32\x35\x20\x30\x2e\x39\x2c\x30\x20\x31\x2e\x36\x32\ +\x35\x2c\x30\x2e\x37\x32\x35\x20\x31\x2e\x36\x32\x35\x2c\x31\x2e\ +\x36\x32\x35\x20\x30\x2c\x30\x2e\x36\x32\x35\x20\x2d\x31\x2c\x30\ +\x2e\x37\x20\x2d\x31\x2c\x31\x2e\x33\x32\x35\x20\x30\x2c\x30\x2e\ +\x37\x35\x20\x30\x2e\x39\x32\x35\x2c\x30\x2e\x39\x32\x35\x20\x31\ +\x2e\x38\x2c\x30\x2e\x39\x32\x35\x20\x31\x2e\x34\x32\x35\x2c\x30\ +\x20\x31\x2e\x37\x35\x2c\x2d\x31\x2e\x38\x32\x35\x20\x31\x2e\x37\ +\x35\x2c\x2d\x33\x2e\x35\x20\x30\x2c\x2d\x31\x2e\x36\x32\x34\x39\ +\x39\x39\x39\x38\x20\x2d\x30\x2e\x34\x35\x2c\x2d\x33\x2e\x33\x35\ +\x20\x2d\x31\x2e\x38\x37\x35\x2c\x2d\x33\x2e\x33\x35\x20\x2d\x31\ +\x2e\x30\x32\x35\x2c\x30\x20\x2d\x32\x2e\x30\x37\x35\x2c\x30\x2e\ +\x33\x35\x20\x2d\x32\x2e\x36\x35\x2c\x31\x2e\x32\x30\x30\x30\x30\ +\x30\x30\x32\x20\x2d\x30\x2e\x30\x37\x35\x2c\x30\x2e\x31\x20\x2d\ +\x30\x2e\x31\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\x32\ +\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\x31\x37\x35\x2c\ +\x30\x20\x2d\x30\x2e\x33\x32\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\ +\x2d\x30\x2e\x33\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x56\x20\ +\x2d\x36\x2e\x33\x35\x39\x37\x37\x31\x34\x20\x63\x20\x30\x2c\x2d\ +\x30\x2e\x32\x20\x30\x2e\x31\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\ +\x30\x2e\x33\x32\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x68\x20\x30\ +\x2e\x30\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x66\x69\x76\x65\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\ +\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x37\x31\x2e\x35\x32\ +\x37\x33\x32\x35\x2c\x2d\x30\x2e\x36\x30\x39\x37\x37\x31\x35\x38\ +\x20\x63\x20\x2d\x31\x2e\x34\x2c\x30\x20\x2d\x31\x2e\x34\x32\x35\ +\x2c\x31\x2e\x32\x37\x35\x20\x2d\x31\x2e\x34\x32\x35\x2c\x32\x2e\ +\x39\x32\x34\x39\x39\x39\x39\x38\x20\x30\x2c\x31\x2e\x36\x35\x20\ +\x30\x2e\x30\x32\x35\x2c\x32\x2e\x39\x32\x35\x20\x31\x2e\x34\x32\ +\x35\x2c\x32\x2e\x39\x32\x35\x20\x31\x2e\x34\x35\x2c\x30\x20\x31\ +\x2e\x36\x2c\x2d\x31\x2e\x32\x35\x20\x31\x2e\x36\x2c\x2d\x32\x2e\ +\x39\x32\x35\x20\x30\x2c\x2d\x31\x2e\x36\x37\x34\x39\x39\x39\x39\ +\x38\x20\x2d\x30\x2e\x31\x35\x2c\x2d\x32\x2e\x39\x32\x34\x39\x39\ +\x39\x39\x38\x20\x2d\x31\x2e\x36\x2c\x2d\x32\x2e\x39\x32\x34\x39\ +\x39\x39\x39\x38\x20\x7a\x20\x6d\x20\x2d\x31\x2e\x34\x32\x35\x2c\ +\x2d\x30\x2e\x32\x20\x63\x20\x30\x2e\x34\x37\x35\x2c\x2d\x30\x2e\ +\x31\x37\x35\x20\x30\x2e\x39\x32\x35\x2c\x2d\x30\x2e\x33\x35\x30\ +\x30\x30\x30\x30\x32\x20\x31\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x33\ +\x35\x30\x30\x30\x30\x30\x32\x20\x32\x2e\x34\x37\x35\x2c\x30\x20\ +\x34\x2e\x31\x37\x35\x2c\x31\x2e\x31\x35\x30\x30\x30\x30\x30\x32\ +\x20\x34\x2e\x31\x37\x35\x2c\x33\x2e\x34\x37\x35\x20\x30\x2c\x32\ +\x2e\x33\x32\x35\x20\x2d\x31\x2e\x37\x2c\x33\x2e\x34\x35\x20\x2d\ +\x34\x2e\x31\x37\x35\x2c\x33\x2e\x34\x35\x20\x2d\x32\x2e\x37\x37\ +\x35\x2c\x30\x20\x2d\x34\x2e\x31\x35\x2c\x2d\x33\x2e\x31\x32\x35\ +\x20\x2d\x34\x2e\x31\x35\x2c\x2d\x36\x2e\x32\x34\x39\x39\x39\x39\ +\x39\x38\x20\x30\x2c\x2d\x33\x2e\x32\x30\x30\x30\x30\x30\x30\x32\ +\x20\x31\x2e\x37\x32\x35\x2c\x2d\x36\x2e\x32\x34\x39\x39\x39\x39\ +\x38\x32\x20\x34\x2e\x36\x35\x2c\x2d\x36\x2e\x32\x34\x39\x39\x39\ +\x39\x38\x32\x20\x31\x2e\x37\x32\x35\x2c\x30\x20\x33\x2e\x34\x2c\ +\x30\x2e\x39\x35\x20\x33\x2e\x34\x2c\x32\x2e\x35\x32\x35\x20\x30\ +\x2c\x30\x2e\x38\x39\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\x37\x32\ +\x35\x2c\x31\x2e\x36\x32\x34\x39\x39\x39\x38\x20\x2d\x31\x2e\x36\ +\x32\x35\x2c\x31\x2e\x36\x32\x34\x39\x39\x39\x38\x20\x2d\x30\x2e\ +\x39\x2c\x30\x20\x2d\x31\x2e\x36\x32\x35\x2c\x2d\x30\x2e\x37\x32\ +\x35\x20\x2d\x31\x2e\x36\x32\x35\x2c\x2d\x31\x2e\x36\x32\x34\x39\ +\x39\x39\x38\x20\x30\x2c\x2d\x30\x2e\x35\x37\x35\x20\x30\x2e\x39\ +\x37\x35\x2c\x2d\x30\x2e\x36\x35\x20\x30\x2e\x39\x37\x35\x2c\x2d\ +\x31\x2e\x32\x32\x35\x20\x30\x2c\x2d\x30\x2e\x35\x20\x2d\x30\x2e\ +\x35\x37\x35\x2c\x2d\x30\x2e\x37\x37\x35\x20\x2d\x31\x2e\x31\x32\ +\x35\x2c\x2d\x30\x2e\x37\x37\x35\x20\x2d\x31\x2e\x37\x35\x2c\x30\ +\x20\x2d\x31\x2e\x39\x35\x2c\x31\x2e\x37\x37\x35\x20\x2d\x31\x2e\ +\x39\x35\x2c\x33\x2e\x37\x37\x34\x39\x39\x39\x38\x20\x30\x2c\x30\ +\x2e\x35\x35\x20\x30\x2e\x30\x32\x35\x2c\x31\x2e\x30\x37\x35\x20\ +\x30\x2e\x30\x32\x35\x2c\x31\x2e\x36\x32\x35\x30\x30\x30\x30\x32\ +\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x73\x69\x78\ +\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\ +\x20\x20\x64\x3d\x22\x6d\x20\x37\x39\x2e\x39\x35\x38\x38\x32\x35\ +\x2c\x2d\x34\x2e\x37\x33\x34\x37\x37\x31\x34\x20\x63\x20\x2d\x30\ +\x2e\x37\x35\x2c\x30\x20\x2d\x30\x2e\x39\x32\x35\x2c\x30\x2e\x39\ +\x39\x39\x39\x39\x39\x38\x20\x2d\x30\x2e\x39\x32\x35\x2c\x31\x2e\ +\x36\x37\x34\x39\x39\x39\x38\x20\x76\x20\x32\x2e\x31\x37\x35\x30\ +\x30\x30\x30\x32\x20\x63\x20\x30\x2c\x30\x2e\x32\x32\x35\x20\x2d\ +\x30\x2e\x31\x37\x35\x2c\x30\x2e\x33\x32\x35\x20\x2d\x30\x2e\x33\ +\x35\x2c\x30\x2e\x33\x32\x35\x20\x2d\x30\x2e\x31\x37\x35\x2c\x30\ +\x20\x2d\x30\x2e\x33\x32\x35\x2c\x2d\x30\x2e\x31\x20\x2d\x30\x2e\ +\x33\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x56\x20\x2d\x36\x2e\ +\x34\x38\x34\x37\x37\x31\x34\x20\x63\x20\x30\x2c\x2d\x30\x2e\x32\ +\x32\x35\x20\x30\x2e\x31\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x30\ +\x2e\x33\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\x30\x2e\x31\x37\ +\x35\x2c\x30\x20\x30\x2e\x33\x35\x2c\x30\x2e\x31\x20\x30\x2e\x33\ +\x35\x2c\x30\x2e\x33\x32\x35\x20\x76\x20\x30\x2e\x33\x35\x20\x63\ +\x20\x30\x2c\x30\x2e\x32\x32\x35\x20\x30\x2e\x32\x35\x2c\x30\x2e\ +\x34\x35\x20\x30\x2e\x33\x32\x35\x2c\x30\x2e\x33\x35\x20\x30\x2e\ +\x34\x37\x35\x2c\x2d\x30\x2e\x36\x37\x35\x20\x31\x2e\x31\x37\x35\ +\x2c\x2d\x31\x2e\x30\x32\x35\x20\x31\x2e\x39\x2c\x2d\x31\x2e\x30\ +\x32\x35\x20\x30\x2e\x37\x32\x35\x2c\x30\x20\x31\x2e\x34\x37\x35\ +\x2c\x30\x2e\x33\x32\x35\x20\x32\x2e\x31\x2c\x30\x2e\x39\x32\x35\ +\x20\x30\x2e\x33\x32\x35\x2c\x30\x2e\x33\x20\x30\x2e\x37\x2c\x30\ +\x2e\x34\x35\x20\x31\x2e\x31\x2c\x30\x2e\x34\x35\x20\x30\x2e\x37\ +\x35\x2c\x30\x20\x31\x2e\x35\x37\x35\x2c\x2d\x30\x2e\x34\x37\x35\ +\x20\x32\x2e\x31\x2c\x2d\x31\x2e\x32\x32\x35\x20\x30\x2e\x30\x37\ +\x35\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x31\x35\x2c\x2d\x30\x2e\x31\ +\x35\x20\x30\x2e\x32\x35\x2c\x2d\x30\x2e\x31\x35\x20\x30\x2e\x31\ +\x37\x35\x2c\x30\x20\x30\x2e\x33\x35\x2c\x30\x2e\x31\x35\x20\x30\ +\x2e\x33\x35\x2c\x30\x2e\x33\x32\x35\x20\x30\x2c\x30\x2e\x30\x35\ +\x20\x30\x2c\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\x30\x35\x2c\x30\ +\x2e\x32\x20\x2d\x32\x2e\x31\x2c\x32\x2e\x39\x39\x39\x39\x39\x39\ +\x38\x20\x2d\x34\x2e\x31\x32\x35\x2c\x36\x2e\x33\x32\x34\x39\x39\ +\x39\x38\x32\x20\x2d\x34\x2e\x31\x32\x35\x2c\x39\x2e\x38\x32\x34\ +\x39\x39\x39\x38\x20\x30\x2c\x30\x2e\x36\x20\x30\x2e\x30\x35\x2c\ +\x31\x2e\x32\x20\x30\x2e\x31\x37\x35\x2c\x31\x2e\x38\x32\x35\x20\ +\x30\x2e\x30\x35\x2c\x30\x2e\x32\x20\x2d\x30\x2e\x31\x2c\x30\x2e\ +\x34\x20\x2d\x30\x2e\x32\x37\x35\x2c\x30\x2e\x34\x20\x2d\x30\x2e\ +\x30\x32\x35\x2c\x30\x20\x2d\x30\x2e\x30\x37\x35\x2c\x2d\x30\x2e\ +\x30\x32\x35\x20\x2d\x30\x2e\x31\x2c\x2d\x30\x2e\x30\x32\x35\x20\ +\x2d\x30\x2e\x35\x37\x35\x2c\x2d\x30\x2e\x31\x37\x35\x20\x2d\x31\ +\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x2d\x31\x2e\x37\ +\x32\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x2d\x30\x2e\x36\x2c\x30\ +\x20\x2d\x31\x2e\x31\x35\x2c\x30\x2e\x32\x20\x2d\x31\x2e\x37\x32\ +\x35\x2c\x30\x2e\x33\x37\x35\x20\x2d\x30\x2e\x30\x32\x35\x2c\x30\ +\x20\x2d\x30\x2e\x30\x37\x35\x2c\x30\x2e\x30\x32\x35\x20\x2d\x30\ +\x2e\x31\x2c\x30\x2e\x30\x32\x35\x20\x2d\x30\x2e\x32\x2c\x30\x20\ +\x2d\x30\x2e\x33\x35\x2c\x2d\x30\x2e\x32\x20\x2d\x30\x2e\x32\x37\ +\x35\x2c\x2d\x30\x2e\x34\x20\x31\x2e\x34\x2c\x2d\x33\x2e\x33\x20\ +\x33\x2e\x34\x35\x2c\x2d\x36\x2e\x32\x34\x39\x39\x39\x39\x39\x38\ +\x20\x35\x2e\x35\x32\x35\x2c\x2d\x39\x2e\x31\x35\x20\x2d\x30\x2e\ +\x35\x32\x35\x2c\x30\x2e\x33\x20\x2d\x31\x2e\x30\x35\x2c\x30\x2e\ +\x34\x37\x35\x20\x2d\x31\x2e\x35\x35\x2c\x30\x2e\x34\x37\x35\x20\ +\x2d\x30\x2e\x35\x32\x35\x2c\x30\x20\x2d\x31\x2e\x30\x32\x35\x2c\ +\x2d\x30\x2e\x31\x37\x35\x20\x2d\x31\x2e\x34\x37\x35\x2c\x2d\x30\ +\x2e\x36\x20\x2d\x30\x2e\x34\x37\x35\x2c\x2d\x30\x2e\x34\x34\x39\ +\x39\x39\x39\x38\x20\x2d\x31\x2e\x30\x32\x35\x2c\x2d\x30\x2e\x38\ +\x32\x34\x39\x39\x39\x38\x20\x2d\x31\x2e\x35\x2c\x2d\x30\x2e\x38\ +\x32\x34\x39\x39\x39\x38\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x73\x65\x76\x65\x6e\x22\x20\x2f\x3e\x0a\x20\x20\x3c\ +\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x39\ +\x35\x2e\x37\x32\x37\x37\x32\x35\x2c\x2d\x31\x2e\x33\x35\x39\x37\ +\x37\x31\x36\x20\x63\x20\x30\x2e\x37\x32\x35\x2c\x2d\x30\x2e\x37\ +\x35\x20\x31\x2e\x33\x35\x2c\x2d\x31\x2e\x35\x35\x20\x31\x2e\x33\ +\x35\x2c\x2d\x32\x2e\x35\x37\x35\x20\x30\x2c\x2d\x31\x2e\x33\x39\ +\x39\x39\x39\x39\x38\x20\x2d\x31\x2e\x34\x35\x2c\x2d\x32\x2e\x32\ +\x37\x34\x39\x39\x39\x38\x20\x2d\x32\x2e\x39\x37\x35\x2c\x2d\x32\ +\x2e\x32\x37\x34\x39\x39\x39\x38\x20\x2d\x31\x2e\x32\x32\x35\x2c\ +\x30\x20\x2d\x31\x2e\x39\x35\x2c\x30\x2e\x39\x35\x20\x2d\x31\x2e\ +\x39\x35\x2c\x31\x2e\x38\x37\x35\x20\x30\x2c\x30\x2e\x35\x34\x39\ +\x39\x39\x39\x38\x20\x30\x2e\x32\x32\x35\x2c\x31\x2e\x30\x34\x39\ +\x39\x39\x39\x38\x20\x30\x2e\x37\x37\x35\x2c\x31\x2e\x33\x37\x34\ +\x39\x39\x39\x38\x20\x7a\x20\x6d\x20\x30\x2e\x36\x37\x35\x2c\x30\ +\x2e\x34\x30\x30\x30\x30\x30\x30\x32\x20\x63\x20\x31\x2e\x33\x37\ +\x35\x2c\x30\x2e\x38\x20\x32\x2e\x31\x32\x35\x2c\x31\x2e\x39\x35\ +\x20\x32\x2e\x31\x32\x35\x2c\x33\x2e\x31\x37\x34\x39\x39\x39\x39\ +\x38\x20\x30\x2c\x31\x2e\x38\x20\x2d\x31\x2e\x36\x32\x35\x2c\x33\ +\x2e\x35\x35\x20\x2d\x34\x2e\x36\x32\x35\x2c\x33\x2e\x35\x35\x20\ +\x2d\x32\x2e\x33\x2c\x30\x20\x2d\x34\x2e\x34\x37\x35\x2c\x2d\x31\ +\x2e\x33\x32\x35\x20\x2d\x34\x2e\x34\x37\x35\x2c\x2d\x33\x2e\x34\ +\x35\x20\x30\x2c\x2d\x31\x2e\x32\x37\x35\x20\x31\x2c\x2d\x32\x2e\ +\x31\x34\x39\x39\x39\x39\x39\x38\x20\x31\x2e\x39\x35\x2c\x2d\x33\ +\x2e\x30\x32\x34\x39\x39\x39\x39\x38\x20\x2d\x31\x2e\x31\x2c\x2d\ +\x30\x2e\x37\x30\x30\x30\x30\x30\x30\x32\x20\x2d\x31\x2e\x36\x2c\ +\x2d\x31\x2e\x37\x32\x35\x30\x30\x30\x30\x32\x20\x2d\x31\x2e\x36\ +\x2c\x2d\x32\x2e\x37\x32\x35\x30\x30\x30\x30\x32\x20\x30\x2c\x2d\ +\x31\x2e\x36\x37\x34\x39\x39\x39\x38\x20\x31\x2e\x35\x2c\x2d\x33\ +\x2e\x32\x39\x39\x39\x39\x39\x38\x20\x34\x2e\x33\x32\x35\x2c\x2d\ +\x33\x2e\x32\x39\x39\x39\x39\x39\x38\x20\x32\x2c\x30\x20\x33\x2e\ +\x39\x35\x2c\x31\x20\x33\x2e\x39\x35\x2c\x32\x2e\x37\x39\x39\x39\ +\x39\x39\x38\x20\x30\x2c\x31\x2e\x32\x20\x2d\x30\x2e\x38\x2c\x32\ +\x2e\x31\x20\x2d\x31\x2e\x36\x35\x2c\x32\x2e\x39\x37\x35\x30\x30\ +\x30\x30\x32\x20\x7a\x20\x6d\x20\x2d\x34\x2e\x33\x32\x35\x2c\x30\ +\x2e\x36\x35\x20\x63\x20\x2d\x30\x2e\x38\x35\x2c\x30\x2e\x37\x35\ +\x20\x2d\x31\x2e\x36\x35\x2c\x31\x2e\x35\x32\x34\x39\x39\x39\x39\ +\x38\x20\x2d\x31\x2e\x36\x35\x2c\x32\x2e\x36\x32\x34\x39\x39\x39\ +\x39\x38\x20\x30\x2c\x31\x2e\x37\x32\x35\x20\x31\x2e\x36\x35\x2c\ +\x32\x2e\x39\x32\x35\x20\x33\x2e\x34\x37\x35\x2c\x32\x2e\x39\x32\ +\x35\x20\x31\x2e\x33\x37\x35\x2c\x30\x20\x32\x2e\x32\x2c\x2d\x31\ +\x2e\x30\x37\x35\x20\x32\x2e\x32\x2c\x2d\x32\x2e\x31\x32\x35\x20\ +\x30\x2c\x2d\x30\x2e\x36\x32\x35\x20\x2d\x30\x2e\x32\x37\x35\x2c\ +\x2d\x31\x2e\x32\x37\x35\x20\x2d\x30\x2e\x39\x32\x35\x2c\x2d\x31\ +\x2e\x36\x35\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x65\x69\x67\x68\x74\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\ +\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x30\x35\x2e\ +\x31\x38\x34\x32\x32\x2c\x2d\x30\x2e\x33\x35\x39\x37\x37\x31\x35\ +\x38\x20\x63\x20\x31\x2e\x34\x30\x30\x30\x31\x2c\x30\x20\x31\x2e\ +\x34\x35\x30\x30\x31\x2c\x2d\x31\x2e\x32\x37\x35\x30\x30\x30\x30\ +\x32\x20\x31\x2e\x34\x35\x30\x30\x31\x2c\x2d\x32\x2e\x39\x32\x35\ +\x30\x30\x30\x30\x32\x20\x30\x2c\x2d\x31\x2e\x36\x34\x39\x39\x39\ +\x39\x38\x20\x2d\x30\x2e\x30\x35\x2c\x2d\x32\x2e\x39\x32\x34\x39\ +\x39\x39\x38\x20\x2d\x31\x2e\x34\x35\x30\x30\x31\x2c\x2d\x32\x2e\ +\x39\x32\x34\x39\x39\x39\x38\x20\x2d\x31\x2e\x34\x35\x2c\x30\x20\ +\x2d\x31\x2e\x35\x39\x39\x39\x39\x2c\x31\x2e\x32\x35\x20\x2d\x31\ +\x2e\x35\x39\x39\x39\x39\x2c\x32\x2e\x39\x32\x34\x39\x39\x39\x38\ +\x20\x30\x2c\x31\x2e\x36\x37\x35\x20\x30\x2e\x31\x35\x2c\x32\x2e\ +\x39\x32\x35\x30\x30\x30\x30\x32\x20\x31\x2e\x35\x39\x39\x39\x39\ +\x2c\x32\x2e\x39\x32\x35\x30\x30\x30\x30\x32\x20\x7a\x20\x6d\x20\ +\x31\x2e\x34\x35\x30\x30\x31\x2c\x30\x2e\x32\x20\x63\x20\x2d\x30\ +\x2e\x34\x37\x35\x2c\x30\x2e\x31\x37\x35\x20\x2d\x30\x2e\x39\x35\ +\x30\x30\x31\x2c\x30\x2e\x33\x35\x20\x2d\x31\x2e\x34\x35\x30\x30\ +\x31\x2c\x30\x2e\x33\x35\x20\x2d\x32\x2e\x34\x37\x34\x39\x39\x2c\ +\x30\x20\x2d\x34\x2e\x31\x35\x2c\x2d\x31\x2e\x31\x35\x20\x2d\x34\ +\x2e\x31\x35\x2c\x2d\x33\x2e\x34\x37\x35\x30\x30\x30\x30\x32\x20\ +\x30\x2c\x2d\x32\x2e\x33\x32\x34\x39\x39\x39\x38\x20\x31\x2e\x36\ +\x37\x35\x2c\x2d\x33\x2e\x34\x34\x39\x39\x39\x39\x38\x20\x34\x2e\ +\x31\x35\x2c\x2d\x33\x2e\x34\x34\x39\x39\x39\x39\x38\x20\x32\x2e\ +\x37\x37\x35\x30\x31\x2c\x30\x20\x34\x2e\x31\x37\x35\x2c\x33\x2e\ +\x31\x32\x34\x39\x39\x39\x38\x20\x34\x2e\x31\x37\x35\x2c\x36\x2e\ +\x32\x34\x39\x39\x39\x39\x38\x32\x20\x30\x2c\x33\x2e\x31\x39\x39\ +\x39\x39\x39\x39\x38\x20\x2d\x31\x2e\x37\x35\x2c\x36\x2e\x32\x34\ +\x39\x39\x39\x39\x39\x38\x20\x2d\x34\x2e\x36\x37\x35\x2c\x36\x2e\ +\x32\x34\x39\x39\x39\x39\x39\x38\x20\x2d\x31\x2e\x37\x32\x34\x39\ +\x39\x2c\x30\x20\x2d\x33\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x39\x35\ +\x20\x2d\x33\x2e\x33\x37\x35\x2c\x2d\x32\x2e\x35\x32\x35\x20\x30\ +\x2c\x2d\x30\x2e\x39\x20\x30\x2e\x37\x32\x35\x2c\x2d\x31\x2e\x36\ +\x32\x35\x20\x31\x2e\x36\x32\x35\x2c\x2d\x31\x2e\x36\x32\x35\x20\ +\x30\x2e\x39\x30\x30\x30\x31\x2c\x30\x20\x31\x2e\x36\x32\x35\x2c\ +\x30\x2e\x37\x32\x35\x20\x31\x2e\x36\x32\x35\x2c\x31\x2e\x36\x32\ +\x35\x20\x30\x2c\x30\x2e\x35\x37\x35\x20\x2d\x30\x2e\x39\x37\x34\ +\x39\x39\x2c\x30\x2e\x36\x35\x20\x2d\x30\x2e\x39\x37\x34\x39\x39\ +\x2c\x31\x2e\x32\x32\x35\x20\x30\x2c\x30\x2e\x35\x20\x30\x2e\x35\ +\x35\x2c\x30\x2e\x37\x37\x35\x20\x31\x2e\x30\x39\x39\x39\x39\x2c\ +\x30\x2e\x37\x37\x35\x20\x31\x2e\x37\x35\x2c\x30\x20\x31\x2e\x39\ +\x35\x30\x30\x31\x2c\x2d\x31\x2e\x37\x37\x35\x20\x31\x2e\x39\x35\ +\x30\x30\x31\x2c\x2d\x33\x2e\x37\x37\x35\x20\x76\x20\x2d\x31\x2e\ +\x36\x32\x34\x39\x39\x39\x39\x38\x20\x7a\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6e\x69\x6e\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\ +\x34\x2e\x34\x37\x34\x39\x39\x39\x36\x2c\x2d\x35\x2e\x38\x39\x37\ +\x37\x38\x31\x34\x20\x63\x20\x2d\x31\x2e\x36\x35\x2c\x30\x20\x2d\ +\x31\x2e\x37\x35\x2c\x32\x2e\x35\x20\x2d\x31\x2e\x37\x35\x2c\x34\ +\x2e\x35\x37\x35\x20\x76\x20\x31\x2e\x30\x30\x30\x30\x30\x30\x30\ +\x32\x20\x31\x20\x63\x20\x30\x2c\x32\x2e\x30\x37\x34\x39\x39\x39\ +\x39\x38\x20\x30\x2e\x31\x2c\x34\x2e\x35\x37\x34\x39\x39\x39\x39\ +\x38\x20\x31\x2e\x37\x35\x2c\x34\x2e\x35\x37\x34\x39\x39\x39\x39\ +\x38\x20\x31\x2e\x36\x35\x2c\x30\x20\x31\x2e\x37\x37\x35\x2c\x2d\ +\x32\x2e\x35\x20\x31\x2e\x37\x37\x35\x2c\x2d\x34\x2e\x35\x37\x34\ +\x39\x39\x39\x39\x38\x20\x76\x20\x2d\x31\x20\x2d\x31\x2e\x30\x30\ +\x30\x30\x30\x30\x30\x32\x20\x63\x20\x30\x2c\x2d\x32\x2e\x30\x37\ +\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\x2d\x34\x2e\x35\x37\x35\x20\ +\x2d\x31\x2e\x37\x37\x35\x2c\x2d\x34\x2e\x35\x37\x35\x20\x7a\x20\ +\x6d\x20\x30\x2c\x2d\x30\x2e\x36\x37\x35\x20\x63\x20\x32\x2e\x38\ +\x37\x35\x2c\x30\x20\x34\x2e\x35\x2c\x33\x2e\x30\x37\x35\x20\x34\ +\x2e\x35\x2c\x36\x2e\x32\x35\x30\x30\x30\x30\x30\x32\x20\x30\x2c\ +\x33\x2e\x31\x37\x34\x39\x39\x39\x39\x38\x20\x2d\x31\x2e\x36\x32\ +\x35\x2c\x36\x2e\x32\x34\x39\x39\x39\x39\x39\x38\x20\x2d\x34\x2e\ +\x35\x2c\x36\x2e\x32\x34\x39\x39\x39\x39\x39\x38\x20\x43\x20\x31\ +\x2e\x36\x2c\x35\x2e\x39\x32\x37\x32\x31\x38\x36\x20\x30\x2c\x32\ +\x2e\x38\x35\x32\x32\x31\x38\x36\x20\x30\x2c\x2d\x30\x2e\x33\x32\ +\x32\x37\x38\x31\x33\x38\x20\x30\x2c\x2d\x33\x2e\x34\x39\x37\x37\ +\x38\x31\x34\x20\x31\x2e\x36\x2c\x2d\x36\x2e\x35\x37\x32\x37\x38\ +\x31\x34\x20\x34\x2e\x34\x37\x34\x39\x39\x39\x36\x2c\x2d\x36\x2e\ +\x35\x37\x32\x37\x38\x31\x34\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x7a\x65\x72\x6f\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\ +\x76\x67\x3e\x0a\ +\x00\x00\x06\x40\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x34\x37\x35\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x72\x65\x73\x74\x4c\x6f\x6e\x67\x61\x2e\ +\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x33\x34\x38\x33\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ +\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ +\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ +\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ +\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\ +\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x34\x38\x31\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\ +\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\ +\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\ +\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\ +\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\ +\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\ +\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\ +\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\ +\x74\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\ +\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x34\x36\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x33\ +\x34\x37\x39\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\ +\x69\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\ +\x30\x2e\x32\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x38\x2e\x35\x33\x31\x38\x35\ +\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x79\x3d\x22\x39\x39\x38\x2e\x36\x34\x34\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\ +\x6f\x77\x2d\x79\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\ +\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\ +\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x34\x37\ +\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\ +\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x72\ +\x65\x73\x74\x73\x2e\x4d\x32\x6d\x65\x6e\x73\x75\x72\x61\x6c\x22\ +\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x35\x2e\x34\x37\x35\ +\x2c\x36\x2e\x35\x20\x35\x2e\x34\x37\x35\x2c\x2d\x36\x20\x30\x2c\ +\x2d\x36\x2e\x35\x20\x30\x2c\x36\x20\x5a\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x34\x37\x37\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ +\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ +\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x09\x50\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x34\x30\x32\x31\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x33\x32\x69\x2e\x73\x76\ +\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\ +\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x34\x30\x32\x39\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\ +\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\ +\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\ +\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\ +\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\ +\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\ +\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\ +\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\ +\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\ +\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x34\ +\x30\x32\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\ +\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\ +\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\ +\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\ +\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\ +\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\x36\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\ +\x34\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\ +\x65\x64\x76\x69\x65\x77\x34\x30\x32\x35\x22\x0a\x20\x20\x20\x20\ +\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\x65\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x7a\x6f\x6f\x6d\x3d\x22\x33\x30\x2e\x32\x30\x38\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\ +\x2d\x35\x2e\x31\x38\x37\x36\x31\x39\x33\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x39\x39\ +\x33\x2e\x39\x38\x31\x30\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\ +\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x31\ +\x30\x38\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\ +\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\ +\x79\x65\x72\x3d\x22\x73\x76\x67\x34\x30\x32\x31\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\ +\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\x2e\ +\x75\x35\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x30\x2e\ +\x30\x31\x38\x39\x36\x31\x38\x36\x2c\x31\x30\x2e\x39\x31\x37\x39\ +\x32\x39\x20\x30\x2c\x2d\x30\x2e\x31\x20\x63\x20\x30\x2c\x2d\x32\ +\x2e\x38\x35\x30\x30\x30\x30\x36\x20\x32\x2e\x32\x30\x30\x30\x30\ +\x30\x30\x34\x2c\x2d\x35\x2e\x30\x30\x30\x30\x30\x30\x37\x20\x33\ +\x2e\x37\x30\x30\x30\x30\x30\x30\x34\x2c\x2d\x37\x2e\x33\x35\x30\ +\x30\x30\x30\x37\x20\x30\x2e\x30\x37\x35\x2c\x30\x2e\x33\x20\x30\ +\x2e\x31\x32\x35\x2c\x30\x2e\x36\x20\x30\x2e\x31\x32\x35\x2c\x30\ +\x2e\x39\x32\x35\x20\x30\x2c\x32\x2e\x34\x30\x30\x30\x30\x30\x31\ +\x20\x2d\x32\x2e\x31\x37\x35\x2c\x34\x2e\x37\x37\x35\x30\x30\x30\ +\x35\x20\x2d\x33\x2e\x38\x32\x35\x30\x30\x30\x30\x34\x2c\x36\x2e\ +\x35\x32\x35\x30\x30\x30\x37\x20\x7a\x20\x6d\x20\x30\x2c\x35\x2e\ +\x33\x32\x35\x20\x63\x20\x30\x2c\x2d\x34\x2e\x34\x32\x35\x20\x34\ +\x2e\x38\x30\x30\x30\x30\x30\x30\x34\x2c\x2d\x37\x2e\x34\x32\x35\ +\x30\x30\x30\x32\x20\x34\x2e\x38\x30\x30\x30\x30\x30\x30\x34\x2c\ +\x2d\x31\x31\x2e\x38\x35\x30\x30\x30\x30\x37\x20\x30\x2c\x2d\x30\ +\x2e\x37\x20\x2d\x30\x2e\x31\x35\x2c\x2d\x31\x2e\x34\x20\x2d\x30\ +\x2e\x34\x35\x2c\x2d\x32\x2e\x30\x35\x20\x30\x2e\x34\x32\x35\x2c\ +\x2d\x30\x2e\x38\x37\x35\x20\x30\x2e\x37\x2c\x2d\x31\x2e\x38\x30\ +\x30\x30\x30\x30\x30\x39\x20\x30\x2e\x37\x2c\x2d\x32\x2e\x38\x32\ +\x35\x30\x30\x30\x31\x31\x20\x30\x2c\x2d\x30\x2e\x38\x39\x39\x39\ +\x39\x39\x38\x39\x20\x2d\x30\x2e\x32\x2c\x2d\x31\x2e\x37\x37\x34\ +\x39\x39\x39\x38\x39\x20\x2d\x30\x2e\x35\x37\x35\x2c\x2d\x32\x2e\ +\x35\x39\x39\x39\x39\x39\x37\x39\x20\x30\x2e\x34\x35\x2c\x2d\x30\ +\x2e\x38\x37\x35\x20\x30\x2e\x37\x35\x2c\x2d\x31\x2e\x38\x32\x35\ +\x30\x30\x30\x31\x20\x30\x2e\x37\x35\x2c\x2d\x32\x2e\x38\x35\x30\ +\x30\x30\x30\x31\x20\x30\x2c\x2d\x31\x2e\x35\x32\x35\x20\x2d\x30\ +\x2e\x34\x2c\x2d\x33\x20\x2d\x31\x2e\x30\x35\x2c\x2d\x34\x2e\x33\ +\x37\x34\x39\x39\x39\x33\x20\x2d\x30\x2e\x31\x2c\x2d\x30\x2e\x31\ +\x37\x35\x20\x2d\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x32\x37\x35\ +\x20\x2d\x30\x2e\x34\x35\x2c\x2d\x30\x2e\x32\x37\x35\x20\x2d\x30\ +\x2e\x33\x2c\x30\x20\x2d\x30\x2e\x36\x2c\x30\x2e\x32\x35\x20\x2d\ +\x30\x2e\x35\x32\x35\x2c\x30\x2e\x36\x32\x34\x39\x39\x39\x33\x20\ +\x30\x2e\x36\x35\x2c\x31\x2e\x32\x35\x20\x31\x2e\x30\x35\x2c\x32\ +\x2e\x36\x32\x35\x20\x31\x2e\x30\x35\x2c\x34\x2e\x30\x32\x35\x20\ +\x30\x2c\x32\x2e\x33\x35\x30\x30\x30\x30\x31\x20\x2d\x32\x2e\x34\ +\x32\x35\x2c\x34\x2e\x35\x20\x2d\x34\x2e\x32\x35\x30\x30\x30\x30\ +\x30\x34\x2c\x35\x2e\x39\x39\x39\x39\x39\x39\x38\x39\x20\x6c\x20\ +\x30\x2c\x2d\x32\x2e\x35\x37\x34\x39\x39\x39\x38\x39\x20\x2d\x30\ +\x2e\x33\x35\x2c\x30\x20\x30\x2c\x31\x38\x2e\x37\x35\x30\x30\x30\ +\x30\x37\x20\x30\x2e\x33\x35\x2c\x30\x20\x7a\x20\x6d\x20\x30\x2c\ +\x2d\x31\x30\x2e\x37\x35\x30\x30\x30\x30\x37\x20\x30\x2c\x2d\x30\ +\x2e\x31\x32\x35\x20\x63\x20\x30\x2c\x2d\x32\x2e\x38\x37\x35\x20\ +\x32\x2e\x32\x37\x35\x30\x30\x30\x30\x34\x2c\x2d\x34\x2e\x39\x37\ +\x35\x30\x30\x30\x30\x39\x20\x33\x2e\x38\x32\x35\x30\x30\x30\x30\ +\x34\x2c\x2d\x37\x2e\x33\x35\x20\x30\x2e\x31\x35\x2c\x30\x2e\x34\ +\x37\x35\x20\x30\x2e\x32\x35\x2c\x30\x2e\x39\x39\x39\x39\x39\x39\ +\x39\x31\x20\x30\x2e\x32\x35\x2c\x31\x2e\x34\x39\x39\x39\x39\x39\ +\x38\x39\x20\x30\x2c\x32\x2e\x33\x30\x30\x30\x30\x30\x31\x31\x20\ +\x2d\x32\x2e\x33\x32\x35\x2c\x34\x2e\x34\x35\x30\x30\x30\x30\x31\ +\x31\x20\x2d\x34\x2e\x30\x37\x35\x30\x30\x30\x30\x34\x2c\x35\x2e\ +\x39\x37\x35\x30\x30\x30\x31\x31\x20\x7a\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x34\x30\x32\x33\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\ +\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\ +\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\xda\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x33\x37\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x72\x65\ +\x73\x74\x32\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\ +\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x31\x36\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x33\x2e\x37\x37\x36\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\ +\x22\x32\x30\x30\x2e\x37\x38\x31\x34\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x30\x31\ +\x33\x2e\x30\x36\x30\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\ +\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x31\x38\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\ +\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\ +\x3d\x22\x73\x76\x67\x33\x33\x37\x31\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x33\x37\x39\x22\ +\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\ +\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\ +\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\ +\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\ +\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\ +\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\ +\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\ +\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\ +\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\ +\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\ +\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ +\x33\x33\x37\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\ +\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\x30\x2e\x32\x33\ +\x34\x33\x32\x32\x2c\x33\x2e\x39\x33\x32\x35\x33\x32\x34\x20\x68\ +\x20\x2d\x38\x2e\x39\x37\x35\x20\x63\x20\x2d\x30\x2e\x31\x2c\x30\ +\x20\x2d\x30\x2e\x32\x2c\x2d\x30\x2e\x31\x20\x2d\x30\x2e\x32\x2c\ +\x2d\x30\x2e\x32\x20\x56\x20\x30\x2e\x32\x33\x32\x35\x33\x32\x34\ +\x33\x20\x63\x20\x30\x2c\x2d\x30\x2e\x31\x20\x30\x2e\x31\x2c\x2d\ +\x30\x2e\x32\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x32\x20\x68\x20\x38\ +\x2e\x39\x37\x35\x20\x63\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\x32\ +\x2c\x30\x2e\x31\x20\x30\x2e\x32\x2c\x30\x2e\x32\x20\x56\x20\x33\ +\x2e\x37\x33\x32\x35\x33\x32\x34\x20\x63\x20\x30\x2c\x30\x2e\x31\ +\x20\x2d\x30\x2e\x31\x2c\x30\x2e\x32\x20\x2d\x30\x2e\x32\x2c\x30\ +\x2e\x32\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\ +\x61\x74\x68\x33\x33\x37\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\ +\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\ +\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x07\x82\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x34\x33\x31\x22\x3e\x0a\ +\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x34\x33\ +\x39\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ +\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ +\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ +\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ +\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x34\x33\x37\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x6d\x20\x33\x2e\x36\x37\x35\x2c\x32\x32\x2e\x32\ +\x38\x35\x35\x39\x33\x20\x31\x2e\x35\x32\x35\x2c\x2d\x38\x2e\x32\ +\x35\x20\x63\x20\x2d\x30\x2e\x39\x37\x35\x2c\x30\x2e\x33\x35\x20\ +\x2d\x31\x2e\x39\x37\x35\x2c\x30\x2e\x36\x35\x20\x2d\x33\x2e\x30\ +\x32\x35\x2c\x30\x2e\x36\x35\x20\x2d\x31\x2e\x31\x35\x2c\x30\x20\ +\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\x20\x2d\x32\x2e\ +\x31\x37\x35\x2c\x2d\x32\x20\x30\x2c\x2d\x30\x2e\x39\x37\x35\x20\ +\x30\x2e\x37\x37\x35\x2c\x2d\x31\x2e\x37\x37\x35\x20\x31\x2e\x37\ +\x37\x35\x2c\x2d\x31\x2e\x37\x37\x35\x20\x30\x2e\x36\x35\x2c\x30\ +\x20\x31\x2e\x32\x32\x35\x2c\x30\x2e\x34\x20\x31\x2e\x34\x32\x35\ +\x2c\x31\x20\x30\x2e\x32\x35\x2c\x30\x2e\x37\x20\x30\x2e\x31\x35\ +\x2c\x31\x2e\x35\x20\x30\x2e\x38\x37\x35\x2c\x31\x2e\x35\x20\x30\ +\x2e\x34\x35\x2c\x30\x20\x31\x2e\x35\x2c\x2d\x31\x2e\x34\x35\x20\ +\x31\x2e\x36\x2c\x2d\x31\x2e\x39\x32\x35\x20\x4c\x20\x36\x2e\x33\ +\x35\x2c\x37\x2e\x38\x31\x30\x35\x39\x33\x33\x20\x63\x20\x2d\x30\ +\x2e\x39\x35\x2c\x30\x2e\x33\x32\x35\x20\x2d\x31\x2e\x39\x2c\x30\ +\x2e\x36\x32\x35\x20\x2d\x32\x2e\x39\x2c\x30\x2e\x36\x32\x35\x20\ +\x2d\x31\x2e\x31\x35\x2c\x30\x20\x2d\x32\x2e\x32\x2c\x2d\x30\x2e\ +\x38\x35\x20\x2d\x32\x2e\x32\x2c\x2d\x32\x20\x30\x2c\x2d\x30\x2e\ +\x39\x37\x35\x20\x30\x2e\x38\x2c\x2d\x31\x2e\x37\x37\x35\x20\x31\ +\x2e\x38\x2c\x2d\x31\x2e\x37\x37\x35\x20\x30\x2e\x36\x35\x2c\x30\ +\x20\x31\x2e\x32\x2c\x30\x2e\x34\x20\x31\x2e\x34\x2c\x31\x20\x30\ +\x2e\x32\x35\x2c\x30\x2e\x37\x20\x30\x2e\x31\x37\x35\x2c\x31\x2e\ +\x35\x20\x30\x2e\x39\x2c\x31\x2e\x35\x20\x30\x2e\x34\x32\x35\x2c\ +\x30\x20\x31\x2e\x33\x37\x35\x2c\x2d\x31\x2e\x34\x20\x31\x2e\x34\ +\x35\x2c\x2d\x31\x2e\x38\x37\x35\x20\x6c\x20\x30\x2e\x37\x2c\x2d\ +\x33\x2e\x37\x20\x63\x20\x2d\x30\x2e\x39\x2c\x30\x2e\x33\x32\x35\ +\x20\x2d\x31\x2e\x38\x35\x2c\x30\x2e\x36\x20\x2d\x32\x2e\x38\x2c\ +\x30\x2e\x36\x20\x2d\x31\x2e\x31\x35\x2c\x30\x20\x2d\x32\x2e\x31\ +\x37\x35\x2c\x2d\x30\x2e\x38\x35\x20\x2d\x32\x2e\x31\x37\x35\x2c\ +\x2d\x32\x2e\x30\x30\x30\x30\x30\x30\x30\x32\x20\x30\x2c\x2d\x30\ +\x2e\x39\x37\x35\x20\x30\x2e\x37\x37\x35\x2c\x2d\x31\x2e\x37\x37\ +\x34\x39\x39\x39\x39\x38\x20\x31\x2e\x37\x37\x35\x2c\x2d\x31\x2e\ +\x37\x37\x34\x39\x39\x39\x39\x38\x20\x30\x2e\x36\x35\x2c\x30\x20\ +\x31\x2e\x32\x32\x35\x2c\x30\x2e\x34\x20\x31\x2e\x34\x32\x35\x2c\ +\x30\x2e\x39\x39\x39\x39\x39\x39\x39\x38\x20\x30\x2e\x32\x35\x2c\ +\x30\x2e\x37\x20\x30\x2e\x31\x35\x2c\x31\x2e\x35\x20\x30\x2e\x38\ +\x37\x35\x2c\x31\x2e\x35\x20\x30\x2e\x34\x2c\x30\x20\x31\x2e\x32\ +\x37\x35\x2c\x2d\x31\x2e\x33\x35\x20\x31\x2e\x33\x35\x2c\x2d\x31\ +\x2e\x38\x20\x6c\x20\x30\x2e\x37\x2c\x2d\x33\x2e\x37\x34\x39\x39\ +\x39\x39\x39\x38\x20\x63\x20\x2d\x30\x2e\x38\x37\x35\x2c\x30\x2e\ +\x33\x20\x2d\x31\x2e\x37\x37\x35\x2c\x30\x2e\x35\x37\x35\x20\x2d\ +\x32\x2e\x37\x2c\x30\x2e\x35\x37\x35\x20\x2d\x31\x2e\x31\x35\x2c\ +\x30\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\x20\x2d\ +\x32\x2e\x31\x37\x35\x2c\x2d\x32\x20\x30\x2c\x2d\x30\x2e\x39\x37\ +\x35\x20\x30\x2e\x38\x2c\x2d\x31\x2e\x37\x37\x35\x20\x31\x2e\x38\ +\x2c\x2d\x31\x2e\x37\x37\x35\x20\x30\x2e\x36\x35\x2c\x30\x20\x31\ +\x2e\x32\x2c\x30\x2e\x34\x20\x31\x2e\x34\x2c\x31\x20\x30\x2e\x32\ +\x35\x2c\x30\x2e\x37\x20\x30\x2e\x31\x37\x35\x2c\x31\x2e\x35\x20\ +\x30\x2e\x39\x2c\x31\x2e\x35\x20\x30\x2e\x34\x2c\x30\x20\x31\x2e\ +\x31\x35\x2c\x2d\x31\x2e\x33\x32\x35\x20\x31\x2e\x32\x32\x35\x2c\ +\x2d\x31\x2e\x37\x35\x20\x6c\x20\x30\x2e\x37\x2c\x2d\x33\x2e\x37\ +\x37\x35\x30\x30\x30\x33\x20\x63\x20\x2d\x30\x2e\x38\x32\x35\x2c\ +\x30\x2e\x33\x20\x2d\x31\x2e\x37\x2c\x30\x2e\x35\x35\x20\x2d\x32\ +\x2e\x35\x37\x35\x2c\x30\x2e\x35\x35\x20\x2d\x31\x2e\x31\x35\x2c\ +\x30\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x38\x35\x20\x2d\ +\x32\x2e\x31\x37\x35\x2c\x2d\x32\x20\x30\x2c\x2d\x30\x2e\x39\x37\ +\x35\x20\x30\x2e\x37\x37\x35\x2c\x2d\x31\x2e\x37\x37\x35\x20\x31\ +\x2e\x37\x37\x35\x2c\x2d\x31\x2e\x37\x37\x35\x20\x30\x2e\x36\x35\ +\x2c\x30\x20\x31\x2e\x32\x32\x35\x2c\x30\x2e\x34\x20\x31\x2e\x34\ +\x32\x35\x2c\x31\x20\x30\x2e\x32\x35\x2c\x30\x2e\x37\x20\x30\x2e\ +\x31\x35\x2c\x31\x2e\x35\x20\x30\x2e\x38\x37\x35\x2c\x31\x2e\x35\ +\x20\x30\x2e\x34\x2c\x30\x20\x30\x2e\x39\x37\x35\x2c\x2d\x31\x2e\ +\x33\x37\x35\x20\x31\x2e\x31\x32\x35\x2c\x2d\x31\x2e\x37\x35\x20\ +\x30\x2e\x31\x2c\x2d\x30\x2e\x32\x37\x35\x20\x30\x2e\x35\x2c\x2d\ +\x30\x2e\x32\x37\x35\x20\x30\x2e\x36\x2c\x30\x20\x6c\x20\x2d\x35\ +\x2e\x39\x37\x35\x2c\x33\x35\x2e\x36\x32\x35\x20\x63\x20\x2d\x30\ +\x2e\x31\x37\x35\x2c\x30\x2e\x31\x35\x20\x2d\x30\x2e\x34\x2c\x30\ +\x2e\x32\x32\x35\x20\x2d\x30\x2e\x36\x2c\x30\x2e\x32\x32\x35\x20\ +\x2d\x30\x2e\x32\x2c\x30\x20\x2d\x30\x2e\x34\x32\x35\x2c\x2d\x30\ +\x2e\x30\x37\x35\x20\x2d\x30\x2e\x36\x2c\x2d\x30\x2e\x32\x32\x35\ +\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\ +\x68\x33\x34\x33\x33\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\ +\x0a\ +\x00\x00\x08\x96\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x34\x30\x31\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\x34\x20\x72\x39\x39\x33\x39\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x72\x65\x73\x74\x73\x2e\x34\x2e\x73\ +\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x33\x34\x30\x39\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\ +\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\ +\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\ +\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\ +\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\ +\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\ +\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\ +\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\ +\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\ +\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\ +\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\ +\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\ +\x33\x34\x30\x37\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\ +\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\ +\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\ +\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\ +\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\ +\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\ +\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\ +\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x31\ +\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x33\x34\x30\x35\x22\x0a\x20\x20\x20\ +\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\ +\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x7a\x6f\x6f\x6d\x3d\x22\x32\x2e\x36\x37\x30\x30\x33\x35\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x78\x3d\x22\x31\x30\x39\x2e\x33\x38\x30\x34\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\ +\x22\x31\x30\x31\x34\x2e\x30\x37\x34\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\ +\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ +\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ +\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x34\x30\x31\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\ +\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x72\x65\x73\x74\x73\ +\x2e\x34\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x32\x2e\ +\x34\x2c\x38\x2e\x37\x36\x33\x36\x34\x35\x36\x20\x34\x2e\x39\x2c\ +\x30\x2e\x35\x38\x38\x36\x34\x35\x35\x39\x20\x43\x20\x34\x2e\x30\ +\x32\x35\x2c\x30\x2e\x39\x31\x33\x36\x34\x35\x35\x20\x33\x2e\x31\ +\x2c\x31\x2e\x31\x36\x33\x36\x34\x35\x35\x20\x32\x2e\x31\x37\x35\ +\x2c\x31\x2e\x31\x36\x33\x36\x34\x35\x35\x20\x31\x2e\x30\x32\x35\ +\x2c\x31\x2e\x31\x36\x33\x36\x34\x35\x35\x20\x30\x2c\x30\x2e\x33\ +\x31\x33\x36\x34\x35\x35\x39\x20\x30\x2c\x2d\x30\x2e\x38\x33\x36\ +\x33\x35\x34\x34\x31\x20\x30\x2c\x2d\x31\x2e\x38\x31\x31\x33\x35\ +\x34\x34\x20\x30\x2e\x37\x37\x35\x2c\x2d\x32\x2e\x36\x31\x31\x33\ +\x35\x34\x34\x20\x31\x2e\x37\x37\x35\x2c\x2d\x32\x2e\x36\x31\x31\ +\x33\x35\x34\x34\x20\x63\x20\x30\x2e\x36\x35\x2c\x30\x20\x31\x2e\ +\x32\x32\x35\x2c\x30\x2e\x34\x20\x31\x2e\x34\x32\x35\x2c\x31\x20\ +\x30\x2e\x32\x35\x2c\x30\x2e\x36\x39\x39\x39\x39\x39\x39\x39\x20\ +\x30\x2e\x31\x35\x2c\x31\x2e\x34\x39\x39\x39\x39\x39\x39\x39\x20\ +\x30\x2e\x38\x37\x35\x2c\x31\x2e\x34\x39\x39\x39\x39\x39\x39\x39\ +\x20\x30\x2e\x34\x32\x35\x2c\x30\x20\x31\x2e\x34\x32\x35\x2c\x2d\ +\x31\x2e\x33\x32\x34\x39\x39\x39\x39\x39\x20\x31\x2e\x35\x35\x2c\ +\x2d\x31\x2e\x37\x34\x39\x39\x39\x39\x39\x39\x20\x6c\x20\x31\x2e\ +\x31\x37\x35\x2c\x2d\x33\x2e\x38\x20\x63\x20\x2d\x30\x2e\x38\x35\ +\x2c\x30\x2e\x33\x20\x2d\x31\x2e\x37\x35\x2c\x30\x2e\x35\x37\x35\ +\x20\x2d\x32\x2e\x36\x37\x35\x2c\x30\x2e\x35\x37\x35\x20\x2d\x31\ +\x2e\x31\x35\x2c\x30\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\ +\x38\x35\x20\x2d\x32\x2e\x31\x37\x35\x2c\x2d\x32\x20\x30\x2c\x2d\ +\x30\x2e\x39\x37\x35\x20\x30\x2e\x37\x37\x35\x2c\x2d\x31\x2e\x37\ +\x37\x35\x30\x30\x30\x31\x20\x31\x2e\x37\x37\x35\x2c\x2d\x31\x2e\ +\x37\x37\x35\x30\x30\x30\x31\x20\x30\x2e\x36\x35\x2c\x30\x20\x31\ +\x2e\x32\x32\x35\x2c\x30\x2e\x34\x20\x31\x2e\x34\x32\x35\x2c\x31\ +\x2e\x30\x30\x30\x30\x30\x30\x31\x20\x30\x2e\x32\x35\x2c\x30\x2e\ +\x37\x20\x30\x2e\x31\x35\x2c\x31\x2e\x35\x20\x30\x2e\x38\x37\x35\ +\x2c\x31\x2e\x35\x20\x30\x2e\x34\x32\x35\x2c\x30\x20\x31\x2e\x33\ +\x32\x35\x2c\x2d\x31\x2e\x33\x35\x20\x31\x2e\x35\x2c\x2d\x31\x2e\ +\x37\x35\x20\x30\x2e\x31\x2c\x2d\x30\x2e\x32\x37\x35\x30\x30\x30\ +\x31\x20\x30\x2e\x35\x2c\x2d\x30\x2e\x32\x37\x35\x30\x30\x30\x31\ +\x20\x30\x2e\x36\x2c\x30\x20\x6c\x20\x2d\x34\x2e\x35\x35\x2c\x31\ +\x36\x2e\x38\x37\x35\x20\x63\x20\x2d\x30\x2e\x31\x37\x35\x2c\x30\ +\x2e\x31\x35\x20\x2d\x30\x2e\x33\x37\x35\x2c\x30\x2e\x32\x32\x35\ +\x20\x2d\x30\x2e\x35\x37\x35\x2c\x30\x2e\x32\x32\x35\x20\x2d\x30\ +\x2e\x32\x2c\x30\x20\x2d\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x30\ +\x37\x35\x20\x2d\x30\x2e\x36\x2c\x2d\x30\x2e\x32\x32\x35\x20\x7a\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\ +\x34\x30\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\ +\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\ +\x73\x76\x67\x3e\x0a\ +\x00\x00\x03\x8f\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x35\x30\x34\x22\x3e\x0a\ +\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x35\x31\ +\x32\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ +\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ +\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ +\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ +\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x35\x31\x30\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x4d\x20\x2d\x31\x2e\x32\x35\x2c\x30\x20\x43\x20\ +\x2d\x31\x2e\x32\x35\x2c\x30\x2e\x37\x20\x2d\x30\x2e\x37\x2c\x31\ +\x2e\x32\x35\x20\x30\x2c\x31\x2e\x32\x35\x20\x30\x2e\x37\x2c\x31\ +\x2e\x32\x35\x20\x31\x2e\x32\x35\x2c\x30\x2e\x37\x20\x31\x2e\x32\ +\x35\x2c\x30\x20\x31\x2e\x32\x35\x2c\x2d\x30\x2e\x37\x20\x30\x2e\ +\x37\x2c\x2d\x31\x2e\x32\x35\x20\x30\x2c\x2d\x31\x2e\x32\x35\x20\ +\x2d\x30\x2e\x37\x2c\x2d\x31\x2e\x32\x35\x20\x2d\x31\x2e\x32\x35\ +\x2c\x2d\x30\x2e\x37\x20\x2d\x31\x2e\x32\x35\x2c\x30\x20\x7a\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x35\ +\x30\x36\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\xe5\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x33\x36\x31\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x72\x65\ +\x73\x74\x31\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\ +\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x31\x35\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x34\x2e\x38\x30\x38\x33\x32\x36\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x63\x78\x3d\x22\x31\x31\x31\x2e\x36\x34\x37\x35\x32\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\ +\x3d\x22\x39\x38\x38\x2e\x33\x38\x36\x31\x31\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\ +\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x79\x3d\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\ +\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\ +\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x33\x36\x31\x22\x20\ +\x2f\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x33\x33\x36\x39\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\ +\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\ +\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ +\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\ +\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\ +\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\ +\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\ +\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\ +\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\ +\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x64\x65\x66\x73\x33\x33\x36\x37\x22\x20\x2f\x3e\x0a\x20\x20\ +\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\ +\x31\x30\x2e\x30\x30\x36\x38\x39\x2c\x30\x20\x48\x20\x31\x2e\x30\ +\x33\x31\x38\x39\x30\x33\x20\x63\x20\x2d\x30\x2e\x31\x2c\x30\x20\ +\x2d\x30\x2e\x31\x39\x39\x39\x39\x39\x39\x37\x2c\x2d\x30\x2e\x31\ +\x20\x2d\x30\x2e\x31\x39\x39\x39\x39\x39\x39\x37\x2c\x2d\x30\x2e\ +\x32\x20\x76\x20\x2d\x33\x2e\x35\x20\x63\x20\x30\x2c\x2d\x30\x2e\ +\x31\x20\x30\x2e\x31\x2c\x2d\x30\x2e\x32\x20\x30\x2e\x31\x39\x39\ +\x39\x39\x39\x39\x37\x2c\x2d\x30\x2e\x32\x20\x48\x20\x31\x30\x2e\ +\x30\x30\x36\x38\x39\x20\x63\x20\x30\x2e\x31\x2c\x30\x20\x30\x2e\ +\x32\x2c\x30\x2e\x31\x20\x30\x2e\x32\x2c\x30\x2e\x32\x20\x76\x20\ +\x33\x2e\x35\x20\x63\x20\x30\x2c\x30\x2e\x31\x20\x2d\x30\x2e\x31\ +\x2c\x30\x2e\x32\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x32\x20\x7a\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x33\ +\x36\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\ +\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\ +\x76\x67\x3e\x0a\ +\x00\x00\x08\x7d\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x35\x32\x31\x30\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x6e\x6f\x74\x65\x68\x65\x61\x64\x73\x42\ +\x72\x65\x76\x69\x73\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\ +\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\ +\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x35\x32\x31\x38\x22\x3e\x0a\ +\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\ +\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\ +\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\ +\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\ +\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\ +\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\ +\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\ +\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\ +\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\ +\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\ +\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x64\x65\x66\x73\x35\x32\x31\x36\x22\x20\x2f\x3e\x0a\ +\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\ +\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\ +\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\ +\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\ +\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\ +\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\ +\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\ +\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\ +\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\ +\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\ +\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\ +\x69\x67\x68\x74\x3d\x22\x31\x30\x34\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x35\x32\ +\x31\x34\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\ +\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x2e\ +\x38\x38\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x78\x3d\x22\x32\x30\x32\x2e\x34\x38\x35\x30\x35\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x79\x3d\x22\x37\x38\x32\x2e\x32\x36\x33\x31\x32\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\ +\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\ +\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\ +\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x35\x32\x31\x30\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x67\ +\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\x22\x6e\x6f\x74\x65\x68\ +\x65\x61\x64\x73\x2e\x73\x4d\x31\x6e\x65\x6f\x6d\x65\x6e\x73\x75\ +\x72\x61\x6c\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x31\ +\x2e\x33\x2c\x2d\x30\x2e\x38\x20\x39\x2e\x39\x2c\x30\x20\x63\x20\ +\x30\x2e\x33\x2c\x30\x20\x30\x2e\x35\x35\x2c\x30\x2e\x32\x32\x35\ +\x20\x30\x2e\x35\x35\x2c\x30\x2e\x35\x32\x35\x20\x6c\x20\x30\x2c\ +\x30\x2e\x35\x35\x20\x63\x20\x30\x2c\x30\x2e\x33\x20\x2d\x30\x2e\ +\x32\x35\x2c\x30\x2e\x35\x32\x35\x20\x2d\x30\x2e\x35\x35\x2c\x30\ +\x2e\x35\x32\x35\x20\x6c\x20\x2d\x39\x2e\x39\x2c\x30\x20\x43\x20\ +\x31\x2c\x30\x2e\x38\x20\x30\x2e\x37\x35\x2c\x30\x2e\x35\x37\x35\ +\x20\x30\x2e\x37\x35\x2c\x30\x2e\x32\x37\x35\x20\x6c\x20\x30\x2c\ +\x2d\x30\x2e\x35\x35\x20\x43\x20\x30\x2e\x37\x35\x2c\x2d\x30\x2e\ +\x35\x37\x35\x20\x31\x2c\x2d\x30\x2e\x38\x20\x31\x2e\x33\x2c\x2d\ +\x30\x2e\x38\x20\x5a\x20\x6d\x20\x39\x2e\x39\x2c\x2d\x32\x2e\x36\ +\x20\x2d\x39\x2e\x39\x2c\x30\x20\x43\x20\x30\x2e\x39\x35\x2c\x2d\ +\x33\x2e\x34\x20\x30\x2e\x37\x35\x2c\x2d\x33\x2e\x38\x20\x30\x2e\ +\x37\x35\x2c\x2d\x34\x2e\x32\x20\x30\x2e\x37\x35\x2c\x2d\x34\x2e\ +\x34\x35\x20\x30\x2e\x35\x37\x35\x2c\x2d\x34\x2e\x35\x37\x35\x20\ +\x30\x2e\x33\x37\x35\x2c\x2d\x34\x2e\x35\x37\x35\x20\x30\x2e\x31\ +\x37\x35\x2c\x2d\x34\x2e\x35\x37\x35\x20\x30\x2c\x2d\x34\x2e\x34\ +\x35\x20\x30\x2c\x2d\x34\x2e\x32\x20\x4c\x20\x30\x2c\x34\x2e\x32\ +\x20\x43\x20\x30\x2c\x34\x2e\x34\x35\x20\x30\x2e\x31\x37\x35\x2c\ +\x34\x2e\x35\x37\x35\x20\x30\x2e\x33\x37\x35\x2c\x34\x2e\x35\x37\ +\x35\x20\x30\x2e\x35\x37\x35\x2c\x34\x2e\x35\x37\x35\x20\x30\x2e\ +\x37\x35\x2c\x34\x2e\x34\x35\x20\x30\x2e\x37\x35\x2c\x34\x2e\x32\ +\x20\x30\x2e\x37\x35\x2c\x33\x2e\x38\x20\x30\x2e\x39\x35\x2c\x33\ +\x2e\x34\x20\x31\x2e\x33\x2c\x33\x2e\x34\x20\x6c\x20\x39\x2e\x39\ +\x2c\x30\x20\x63\x20\x30\x2e\x33\x35\x2c\x30\x20\x30\x2e\x35\x35\ +\x2c\x30\x2e\x34\x20\x30\x2e\x35\x35\x2c\x30\x2e\x38\x20\x30\x2c\ +\x30\x2e\x32\x35\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\x33\x37\x35\ +\x20\x30\x2e\x33\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\x30\x2e\x32\ +\x2c\x30\x20\x30\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\ +\x30\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x6c\x20\x30\ +\x2c\x2d\x38\x2e\x34\x20\x63\x20\x30\x2c\x2d\x30\x2e\x32\x35\x20\ +\x2d\x30\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x2d\x30\ +\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x2d\x30\x2e\x32\ +\x2c\x30\x20\x2d\x30\x2e\x33\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\ +\x2d\x30\x2e\x33\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\x30\x2c\x30\ +\x2e\x34\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x38\x20\x2d\x30\x2e\x35\ +\x35\x2c\x30\x2e\x38\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x70\x61\x74\x68\x35\x32\x31\x32\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\ +\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\ +\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x07\x91\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x33\x34\x36\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\x34\x20\x72\x39\x39\x33\x39\ +\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\ +\x63\x6e\x61\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\x2e\x64\x34\x2e\ +\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\ +\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\ +\x61\x74\x61\x33\x33\x35\x34\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\ +\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\ +\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\ +\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\ +\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\ +\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\ +\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\ +\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\ +\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\ +\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\ +\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\ +\x73\x33\x33\x35\x32\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x73\x6f\x64\ +\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0a\ +\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\ +\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\ +\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x72\x69\x64\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\ +\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\ +\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\ +\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\ +\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x31\ +\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6e\ +\x61\x6d\x65\x64\x76\x69\x65\x77\x33\x33\x35\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\ +\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x34\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x2d\x35\x37\ +\x2e\x39\x35\x31\x37\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x31\x30\x30\x35\x2e\x36\ +\x36\x34\x33\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\ +\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\ +\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x31\x38\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\ +\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\ +\x76\x67\x33\x33\x34\x36\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\ +\x74\x68\x0a\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\ +\x6d\x65\x3d\x22\x66\x6c\x61\x67\x73\x2e\x64\x34\x22\x0a\x20\x20\ +\x20\x20\x20\x64\x3d\x22\x6d\x20\x30\x2e\x33\x35\x2c\x35\x20\x63\ +\x20\x32\x2e\x33\x32\x35\x2c\x31\x2e\x33\x32\x35\x20\x35\x2e\x34\ +\x2c\x33\x2e\x33\x37\x35\x20\x35\x2e\x34\x2c\x36\x20\x30\x2c\x30\ +\x2e\x36\x32\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\x31\x2e\x32\x35\ +\x20\x2d\x30\x2e\x33\x35\x2c\x31\x2e\x38\x32\x35\x20\x43\x20\x33\ +\x2e\x34\x2c\x31\x30\x2e\x35\x35\x20\x30\x2e\x33\x35\x2c\x38\x2e\ +\x37\x35\x20\x30\x2e\x33\x35\x2c\x35\x2e\x36\x32\x35\x20\x56\x20\ +\x35\x20\x7a\x20\x6d\x20\x36\x2e\x37\x32\x35\x2c\x31\x31\x2e\x36\ +\x32\x35\x20\x63\x20\x30\x2c\x2d\x31\x2e\x31\x20\x2d\x30\x2e\x34\ +\x2c\x2d\x32\x2e\x30\x35\x20\x2d\x30\x2e\x39\x37\x35\x2c\x2d\x32\ +\x2e\x39\x20\x43\x20\x36\x2e\x35\x2c\x31\x32\x2e\x38\x37\x35\x20\ +\x36\x2e\x37\x32\x35\x2c\x31\x31\x2e\x39\x35\x20\x36\x2e\x37\x32\ +\x35\x2c\x31\x31\x20\x36\x2e\x37\x32\x35\x2c\x36\x2e\x34\x35\x20\ +\x30\x2e\x33\x35\x2c\x34\x2e\x35\x35\x20\x30\x2e\x33\x35\x2c\x30\ +\x20\x48\x20\x30\x20\x76\x20\x31\x32\x2e\x35\x20\x68\x20\x30\x2e\ +\x33\x35\x20\x76\x20\x2d\x31\x2e\x38\x37\x35\x20\x63\x20\x32\x2e\ +\x34\x37\x35\x2c\x31\x2e\x32\x37\x35\x20\x35\x2e\x37\x35\x2c\x33\ +\x2e\x33\x20\x35\x2e\x37\x35\x2c\x36\x20\x43\x20\x36\x2e\x31\x2c\ +\x31\x37\x2e\x31\x37\x35\x20\x35\x2e\x39\x37\x35\x2c\x31\x37\x2e\ +\x37\x20\x35\x2e\x37\x37\x35\x2c\x31\x38\x2e\x32\x20\x35\x2e\x37\ +\x2c\x31\x38\x2e\x35\x37\x35\x20\x36\x2c\x31\x38\x2e\x38\x32\x35\ +\x20\x36\x2e\x33\x2c\x31\x38\x2e\x38\x32\x35\x20\x63\x20\x30\x2e\ +\x37\x2c\x30\x20\x30\x2e\x37\x37\x35\x2c\x2d\x31\x2e\x36\x20\x30\ +\x2e\x37\x37\x35\x2c\x2d\x32\x2e\x32\x20\x7a\x22\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x33\x33\x34\x38\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\ +\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\ +\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\ +\x00\x00\x0c\x87\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\ +\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\ +\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\ +\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\ +\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\ +\x31\x2e\x31\x22\x0a\x20\x20\x20\x77\x69\x64\x74\x68\x3d\x22\x31\ +\x30\x30\x30\x22\x0a\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3d\x22\ +\x31\x30\x30\x30\x22\x0a\x20\x20\x20\x69\x64\x3d\x22\x73\x76\x67\ +\x33\x31\x37\x39\x22\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x34\x38\x2e\ +\x34\x20\x72\x39\x39\x33\x39\x22\x0a\x20\x20\x20\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x3a\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\ +\x65\x66\x54\x72\x65\x62\x6c\x65\x2e\x73\x76\x67\x22\x3e\x0a\x20\ +\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ +\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ +\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\ +\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\ +\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ +\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\ +\x3d\x22\x39\x35\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\ +\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\ +\x68\x74\x3d\x22\x31\x30\x34\x31\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x32\x39\x38\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\ +\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x31\x33\x2e\x36\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x78\x3d\x22\x32\x33\x2e\x38\x36\x37\x31\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\ +\x31\x30\x30\x39\x2e\x39\x36\x38\x31\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\ +\x22\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\ +\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\ +\x79\x65\x72\x3d\x22\x73\x76\x67\x33\x31\x37\x39\x22\x20\x2f\x3e\ +\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\ +\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x31\ +\x38\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\ +\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\ +\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ +\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\ +\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\ +\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\ +\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\ +\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\ +\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\ +\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x20\x2f\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\ +\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\ +\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x0a\x20\x20\ +\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x64\ +\x65\x66\x73\x33\x31\x38\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\ +\x61\x74\x68\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x4d\x20\x36\x2e\ +\x33\x35\x2c\x2d\x37\x2e\x35\x30\x37\x30\x38\x32\x34\x20\x43\x20\ +\x35\x2e\x35\x2c\x2d\x31\x30\x2e\x34\x35\x37\x30\x38\x32\x20\x35\ +\x2c\x2d\x31\x33\x2e\x32\x38\x32\x30\x38\x32\x20\x35\x2c\x2d\x31\ +\x36\x2e\x39\x38\x32\x30\x38\x32\x20\x63\x20\x30\x2c\x2d\x33\x20\ +\x31\x2e\x34\x2c\x2d\x35\x2e\x38\x20\x33\x2e\x37\x37\x35\x2c\x2d\ +\x37\x2e\x36\x32\x35\x20\x30\x2e\x30\x35\x2c\x2d\x30\x2e\x30\x35\ +\x20\x30\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x30\x37\x35\x20\x30\x2e\ +\x32\x2c\x2d\x30\x2e\x30\x37\x35\x20\x30\x2e\x30\x37\x35\x2c\x30\ +\x20\x30\x2e\x31\x35\x2c\x30\x2e\x30\x32\x35\x20\x30\x2e\x32\x2c\ +\x30\x2e\x30\x37\x35\x20\x31\x2e\x39\x2c\x32\x2e\x32\x35\x20\x33\ +\x2e\x35\x37\x35\x2c\x36\x2e\x36\x20\x33\x2e\x35\x37\x35\x2c\x39\ +\x2e\x36\x32\x35\x20\x30\x2c\x33\x2e\x37\x35\x20\x2d\x32\x2e\x32\ +\x35\x2c\x36\x2e\x36\x37\x34\x39\x39\x39\x36\x20\x2d\x34\x2e\x37\ +\x35\x2c\x39\x2e\x34\x39\x39\x39\x39\x39\x36\x20\x30\x2e\x35\x35\ +\x2c\x31\x2e\x38\x32\x34\x39\x39\x39\x39\x20\x31\x2e\x30\x35\x2c\ +\x33\x2e\x36\x37\x34\x39\x39\x39\x39\x20\x31\x2e\x35\x32\x35\x2c\ +\x35\x2e\x35\x32\x34\x39\x39\x39\x39\x20\x68\x20\x30\x2e\x31\x35\ +\x20\x63\x20\x33\x2e\x38\x35\x2c\x30\x20\x36\x2e\x33\x35\x2c\x33\ +\x2e\x31\x37\x35\x20\x36\x2e\x33\x35\x2c\x36\x2e\x34\x37\x35\x30\ +\x30\x30\x31\x20\x30\x2c\x31\x2e\x38\x39\x39\x39\x39\x39\x39\x20\ +\x2d\x30\x2e\x38\x32\x35\x2c\x33\x2e\x38\x32\x35\x30\x30\x30\x34\ +\x20\x2d\x32\x2e\x36\x37\x35\x2c\x35\x2e\x32\x30\x30\x30\x30\x30\ +\x34\x20\x2d\x30\x2e\x36\x32\x35\x2c\x30\x2e\x34\x37\x35\x20\x2d\ +\x31\x2e\x33\x32\x35\x2c\x30\x2e\x38\x20\x2d\x32\x2e\x30\x37\x35\ +\x2c\x31\x20\x30\x2c\x30\x2e\x33\x32\x35\x20\x30\x2e\x30\x32\x35\ +\x2c\x30\x2e\x36\x37\x35\x20\x30\x2e\x30\x32\x35\x2c\x31\x20\x30\ +\x2c\x31\x2e\x31\x35\x20\x2d\x30\x2e\x30\x32\x35\x2c\x32\x2e\x33\ +\x20\x2d\x30\x2e\x31\x2c\x33\x2e\x34\x35\x20\x2d\x30\x2e\x31\x37\ +\x35\x2c\x33\x2e\x30\x32\x35\x20\x2d\x32\x2e\x33\x35\x2c\x35\x2e\ +\x36\x37\x35\x20\x2d\x35\x2e\x33\x35\x2c\x35\x2e\x36\x37\x35\x20\ +\x2d\x32\x2e\x37\x37\x35\x2c\x30\x20\x2d\x35\x2e\x30\x35\x2c\x2d\ +\x32\x2e\x33\x20\x2d\x35\x2e\x30\x35\x2c\x2d\x35\x2e\x31\x32\x35\ +\x20\x30\x2c\x2d\x31\x2e\x34\x35\x20\x31\x2e\x33\x35\x2c\x2d\x32\ +\x2e\x36\x20\x32\x2e\x38\x32\x35\x2c\x2d\x32\x2e\x36\x20\x31\x2e\ +\x33\x35\x2c\x30\x20\x32\x2e\x33\x37\x35\x2c\x31\x2e\x32\x20\x32\ +\x2e\x33\x37\x35\x2c\x32\x2e\x36\x20\x30\x2c\x31\x2e\x33\x20\x2d\ +\x31\x2e\x30\x37\x35\x2c\x32\x2e\x33\x37\x35\x20\x2d\x32\x2e\x33\ +\x37\x35\x2c\x32\x2e\x33\x37\x35\x20\x2d\x30\x2e\x33\x32\x35\x2c\ +\x30\x20\x2d\x30\x2e\x36\x37\x35\x2c\x2d\x30\x2e\x31\x20\x2d\x30\ +\x2e\x39\x37\x35\x2c\x2d\x30\x2e\x32\x35\x20\x30\x2e\x36\x35\x2c\ +\x31\x2e\x31\x37\x35\x20\x31\x2e\x38\x35\x2c\x32\x20\x33\x2e\x32\ +\x35\x2c\x32\x20\x32\x2e\x34\x37\x35\x2c\x30\x20\x34\x2e\x31\x35\ +\x2c\x2d\x32\x2e\x33\x20\x34\x2e\x33\x2c\x2d\x34\x2e\x38\x32\x35\ +\x20\x30\x2e\x30\x37\x35\x2c\x2d\x31\x2e\x31\x20\x30\x2e\x31\x2c\ +\x2d\x32\x2e\x32\x32\x35\x20\x30\x2e\x31\x2c\x2d\x33\x2e\x33\x32\ +\x35\x20\x76\x20\x2d\x30\x2e\x37\x37\x35\x20\x63\x20\x2d\x30\x2e\ +\x36\x35\x2c\x30\x2e\x31\x20\x2d\x31\x2e\x33\x2c\x30\x2e\x31\x35\ +\x20\x2d\x31\x2e\x39\x37\x35\x2c\x30\x2e\x31\x35\x20\x2d\x34\x2e\ +\x37\x2c\x30\x20\x2d\x38\x2e\x33\x32\x35\x2c\x2d\x34\x2e\x32\x37\ +\x35\x30\x30\x30\x35\x20\x2d\x38\x2e\x33\x32\x35\x2c\x2d\x39\x2e\ +\x33\x30\x30\x30\x30\x30\x35\x20\x30\x2c\x2d\x34\x2e\x35\x32\x35\ +\x20\x33\x2e\x33\x35\x2c\x2d\x37\x2e\x38\x34\x39\x39\x39\x39\x39\ +\x20\x36\x2e\x33\x35\x2c\x2d\x31\x31\x2e\x32\x37\x34\x39\x39\x39\ +\x39\x20\x7a\x20\x6d\x20\x34\x2e\x39\x2c\x31\x39\x2e\x32\x35\x30\ +\x30\x30\x30\x34\x20\x63\x20\x31\x2e\x38\x32\x35\x2c\x2d\x30\x2e\ +\x35\x35\x20\x33\x2e\x31\x2c\x2d\x32\x2e\x34\x32\x35\x30\x30\x30\ +\x35\x20\x33\x2e\x31\x2c\x2d\x34\x2e\x32\x35\x30\x30\x30\x30\x35\ +\x20\x30\x2c\x2d\x32\x2e\x32\x34\x39\x39\x39\x39\x39\x20\x2d\x31\ +\x2e\x36\x2c\x2d\x34\x2e\x34\x35\x20\x2d\x34\x2e\x32\x2c\x2d\x34\ +\x2e\x38\x20\x30\x2e\x35\x37\x35\x2c\x32\x2e\x37\x35\x30\x30\x30\ +\x30\x31\x20\x31\x2c\x35\x2e\x39\x37\x35\x20\x31\x2e\x31\x2c\x39\ +\x2e\x30\x35\x30\x30\x30\x30\x35\x20\x7a\x20\x6d\x20\x2d\x32\x2e\ +\x38\x35\x2c\x30\x2e\x33\x32\x35\x20\x63\x20\x30\x2e\x36\x32\x35\ +\x2c\x30\x20\x31\x2e\x32\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x31\ +\x2e\x38\x37\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x43\x20\x31\x30\ +\x2e\x31\x37\x35\x2c\x38\x2e\x37\x36\x37\x39\x31\x37\x35\x20\x39\ +\x2e\x37\x2c\x35\x2e\x34\x36\x37\x39\x31\x37\x36\x20\x39\x2e\x31\ +\x2c\x32\x2e\x36\x34\x32\x39\x31\x37\x35\x20\x63\x20\x2d\x32\x2e\ +\x31\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\x2d\x33\x2e\x34\x2c\x31\ +\x2e\x35\x35\x20\x2d\x33\x2e\x34\x2c\x33\x2e\x31\x30\x30\x30\x30\ +\x30\x31\x20\x30\x2c\x31\x2e\x31\x32\x35\x20\x30\x2e\x36\x35\x2c\ +\x32\x2e\x32\x39\x39\x39\x39\x39\x39\x20\x32\x2e\x30\x37\x35\x2c\ +\x33\x2e\x31\x32\x34\x39\x39\x39\x39\x20\x30\x2e\x31\x2c\x30\x2e\ +\x31\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\x32\x32\x35\x20\x30\x2e\ +\x31\x37\x35\x2c\x30\x2e\x33\x35\x20\x30\x2c\x30\x2e\x32\x37\x35\ +\x20\x2d\x30\x2e\x32\x32\x35\x2c\x30\x2e\x35\x32\x35\x20\x2d\x30\ +\x2e\x35\x2c\x30\x2e\x35\x32\x35\x20\x2d\x30\x2e\x30\x37\x35\x2c\ +\x30\x20\x2d\x30\x2e\x31\x35\x2c\x2d\x30\x2e\x30\x32\x35\x20\x2d\ +\x30\x2e\x32\x32\x35\x2c\x2d\x30\x2e\x30\x35\x20\x2d\x32\x2c\x2d\ +\x31\x2e\x30\x37\x35\x20\x2d\x32\x2e\x39\x2c\x2d\x32\x2e\x38\x34\ +\x39\x39\x39\x39\x39\x20\x2d\x32\x2e\x39\x2c\x2d\x34\x2e\x36\x20\ +\x30\x2c\x2d\x32\x2e\x32\x35\x20\x31\x2e\x35\x32\x35\x2c\x2d\x34\ +\x2e\x34\x35\x20\x34\x2e\x32\x2c\x2d\x34\x2e\x39\x35\x20\x2d\x30\ +\x2e\x34\x2c\x2d\x31\x2e\x36\x20\x2d\x30\x2e\x38\x37\x35\x2c\x2d\ +\x33\x2e\x31\x37\x35\x20\x2d\x31\x2e\x33\x32\x35\x2c\x2d\x34\x2e\ +\x37\x34\x39\x39\x39\x39\x39\x20\x2d\x32\x2e\x37\x35\x2c\x33\x2e\ +\x30\x39\x39\x39\x39\x39\x39\x20\x2d\x35\x2e\x35\x2c\x36\x2e\x32\ +\x32\x34\x39\x39\x39\x39\x20\x2d\x35\x2e\x35\x2c\x31\x30\x2e\x33\ +\x35\x20\x30\x2c\x33\x2e\x34\x34\x39\x39\x39\x39\x39\x20\x33\x2e\ +\x32\x37\x35\x2c\x36\x2e\x33\x32\x35\x30\x30\x30\x34\x20\x36\x2e\ +\x37\x2c\x36\x2e\x33\x32\x35\x30\x30\x30\x34\x20\x7a\x20\x6d\x20\ +\x31\x2e\x37\x37\x35\x2c\x2d\x33\x33\x2e\x32\x20\x63\x20\x2d\x32\ +\x2e\x35\x2c\x31\x2e\x33\x37\x35\x20\x2d\x34\x2e\x30\x35\x2c\x33\ +\x2e\x39\x37\x35\x20\x2d\x34\x2e\x30\x35\x2c\x36\x2e\x38\x32\x35\ +\x20\x30\x2c\x32\x2e\x32\x35\x20\x30\x2e\x34\x37\x35\x2c\x34\x2e\ +\x30\x35\x20\x31\x2c\x35\x2e\x38\x39\x39\x39\x39\x39\x36\x20\x32\ +\x2e\x31\x35\x2c\x2d\x32\x2e\x35\x34\x39\x39\x39\x39\x36\x20\x33\ +\x2e\x39\x35\x2c\x2d\x35\x2e\x32\x32\x34\x39\x39\x39\x36\x20\x33\ +\x2e\x39\x35\x2c\x2d\x38\x2e\x35\x34\x39\x39\x39\x39\x36\x20\x30\ +\x2c\x2d\x31\x2e\x38\x32\x35\x20\x2d\x30\x2e\x32\x2c\x2d\x32\x2e\ +\x35\x37\x35\x20\x2d\x30\x2e\x39\x2c\x2d\x34\x2e\x31\x37\x35\x20\ +\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\ +\x33\x31\x38\x31\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\ +\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x09\x33\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x35\x32\x33\x30\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x6e\x6f\x74\x65\x68\x65\x61\x64\x73\x4c\ +\x6f\x6e\x67\x61\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\ +\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x6d\x65\x74\x61\x64\x61\x74\x61\x35\x32\x33\x38\x22\x3e\x0a\x20\ +\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\ +\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\ +\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\ +\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\ +\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\ +\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\ +\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\ +\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\ +\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\ +\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\ +\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\x3a\x57\x6f\ +\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x52\x44\ +\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\ +\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x64\x65\x66\x73\x35\x32\x33\x36\x22\x20\x2f\x3e\x0a\x20\ +\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\ +\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\x65\x63\x6f\ +\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0a\x20\x20\ +\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\ +\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\x20\x62\x6f\ +\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0a\ +\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\ +\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\ +\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\ +\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\x65\ +\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\ +\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\ +\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\ +\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\ +\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x34\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x35\x32\x33\ +\x34\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\ +\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x32\x31\x2e\ +\x33\x36\x30\x32\x38\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x32\x31\x2e\x35\x30\x38\ +\x35\x37\x35\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x63\x79\x3d\x22\x39\x39\x36\x2e\x38\x32\x35\x35\x39\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x31\x39\x32\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x30\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x35\ +\x32\x33\x30\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\ +\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\ +\x22\x6e\x6f\x74\x65\x68\x65\x61\x64\x73\x2e\x73\x4d\x32\x6e\x65\ +\x6f\x6d\x65\x6e\x73\x75\x72\x61\x6c\x22\x0a\x20\x20\x20\x20\x20\ +\x64\x3d\x22\x6d\x20\x31\x2e\x32\x35\x33\x31\x38\x34\x31\x2c\x2d\ +\x30\x2e\x37\x37\x33\x20\x39\x2e\x38\x39\x39\x39\x39\x39\x39\x2c\ +\x30\x20\x63\x20\x30\x2e\x33\x2c\x30\x20\x30\x2e\x35\x35\x2c\x30\ +\x2e\x32\x32\x35\x30\x30\x30\x30\x33\x20\x30\x2e\x35\x35\x2c\x30\ +\x2e\x35\x32\x35\x30\x30\x30\x30\x33\x20\x6c\x20\x30\x2c\x30\x2e\ +\x35\x35\x20\x63\x20\x30\x2c\x30\x2e\x33\x20\x2d\x30\x2e\x32\x35\ +\x2c\x30\x2e\x35\x32\x35\x20\x2d\x30\x2e\x35\x35\x2c\x30\x2e\x35\ +\x32\x35\x20\x6c\x20\x2d\x39\x2e\x38\x39\x39\x39\x39\x39\x39\x2c\ +\x30\x20\x63\x20\x2d\x30\x2e\x32\x39\x39\x39\x39\x39\x39\x36\x2c\ +\x30\x20\x2d\x30\x2e\x35\x34\x39\x39\x39\x39\x39\x36\x2c\x2d\x30\ +\x2e\x32\x32\x35\x20\x2d\x30\x2e\x35\x34\x39\x39\x39\x39\x39\x36\ +\x2c\x2d\x30\x2e\x35\x32\x35\x20\x6c\x20\x30\x2c\x2d\x30\x2e\x35\ +\x35\x20\x63\x20\x30\x2c\x2d\x30\x2e\x33\x20\x30\x2e\x32\x35\x2c\ +\x2d\x30\x2e\x35\x32\x35\x30\x30\x30\x30\x33\x20\x30\x2e\x35\x34\ +\x39\x39\x39\x39\x39\x36\x2c\x2d\x30\x2e\x35\x32\x35\x30\x30\x30\ +\x30\x33\x20\x7a\x20\x6d\x20\x39\x2e\x38\x39\x39\x39\x39\x39\x39\ +\x2c\x2d\x32\x2e\x36\x20\x2d\x39\x2e\x38\x39\x39\x39\x39\x39\x39\ +\x2c\x30\x20\x63\x20\x2d\x30\x2e\x33\x34\x39\x39\x39\x39\x39\x36\ +\x2c\x30\x20\x2d\x30\x2e\x35\x34\x39\x39\x39\x39\x39\x36\x2c\x2d\ +\x30\x2e\x34\x20\x2d\x30\x2e\x35\x34\x39\x39\x39\x39\x39\x36\x2c\ +\x2d\x30\x2e\x38\x20\x30\x2c\x2d\x30\x2e\x32\x35\x20\x2d\x30\x2e\ +\x31\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x2d\x30\x2e\x33\x37\ +\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x2d\x30\x2e\x32\x2c\x30\x20\ +\x2d\x30\x2e\x33\x37\x35\x2c\x30\x2e\x31\x32\x35\x20\x2d\x30\x2e\ +\x33\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\x6c\x20\x30\x2c\x38\x2e\ +\x34\x20\x63\x20\x30\x2c\x30\x2e\x32\x35\x20\x30\x2e\x31\x37\x35\ +\x2c\x30\x2e\x33\x37\x35\x20\x30\x2e\x33\x37\x35\x2c\x30\x2e\x33\ +\x37\x35\x20\x30\x2e\x32\x2c\x30\x20\x30\x2e\x33\x37\x35\x2c\x2d\ +\x30\x2e\x31\x32\x35\x20\x30\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x33\ +\x37\x35\x20\x30\x2c\x2d\x30\x2e\x34\x20\x30\x2e\x32\x2c\x2d\x30\ +\x2e\x38\x20\x30\x2e\x35\x34\x39\x39\x39\x39\x39\x36\x2c\x2d\x30\ +\x2e\x38\x20\x6c\x20\x39\x2e\x38\x39\x39\x39\x39\x39\x39\x2c\x30\ +\x20\x63\x20\x30\x2e\x33\x35\x2c\x30\x20\x30\x2e\x35\x35\x2c\x30\ +\x2e\x34\x20\x30\x2e\x35\x35\x2c\x30\x2e\x38\x20\x30\x2c\x30\x2e\ +\x32\x35\x20\x30\x2e\x31\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\x30\ +\x2e\x33\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\x30\x2e\x32\x2c\x30\ +\x20\x30\x2e\x33\x37\x35\x2c\x2d\x30\x2e\x31\x32\x35\x20\x30\x2e\ +\x33\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x6c\x20\x30\x2c\x2d\ +\x38\x2e\x34\x20\x63\x20\x30\x2e\x31\x37\x35\x2c\x2d\x32\x2e\x30\ +\x37\x35\x20\x30\x2e\x34\x35\x2c\x2d\x34\x2e\x32\x20\x30\x2e\x34\ +\x35\x2c\x2d\x36\x2e\x32\x37\x35\x20\x30\x2c\x2d\x30\x2e\x33\x20\ +\x2d\x30\x2e\x32\x32\x35\x2c\x2d\x30\x2e\x34\x32\x35\x20\x2d\x30\ +\x2e\x34\x35\x2c\x2d\x30\x2e\x34\x32\x35\x20\x2d\x30\x2e\x32\x32\ +\x35\x2c\x30\x20\x2d\x30\x2e\x34\x32\x35\x2c\x30\x2e\x31\x32\x35\ +\x20\x2d\x30\x2e\x34\x35\x2c\x30\x2e\x34\x32\x35\x20\x6c\x20\x2d\ +\x30\x2e\x33\x2c\x36\x2e\x32\x35\x20\x30\x2c\x30\x2e\x30\x32\x35\ +\x20\x63\x20\x30\x2c\x30\x2e\x34\x20\x2d\x30\x2e\x32\x2c\x30\x2e\ +\x38\x20\x2d\x30\x2e\x35\x35\x2c\x30\x2e\x38\x20\x7a\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x64\x3d\x22\x70\x61\x74\x68\x35\x32\x33\x32\ +\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\ +\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\x75\x72\x76\x61\x74\ +\x75\x72\x65\x3d\x22\x30\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\ +\x3e\x0a\ +\x00\x00\x06\x97\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x43\x72\x65\x61\x74\ +\x65\x64\x20\x77\x69\x74\x68\x20\x49\x6e\x6b\x73\x63\x61\x70\x65\ +\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x29\x20\x2d\x2d\x3e\x0a\ +\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\ +\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\ +\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\ +\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\ +\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\ +\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\ +\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x0a\x20\x20\x20\ +\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\ +\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\ +\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\ +\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\ +\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\ +\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\x20\ +\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x31\x31\x39\x22\x3e\x0a\ +\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\x33\x31\x32\ +\x37\x22\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x63\x63\x3a\x57\x6f\x72\x6b\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\ +\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\ +\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\ +\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\ +\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\ +\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\ +\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\ +\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\ +\x3a\x74\x69\x74\x6c\x65\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\ +\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\ +\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x31\x32\x35\x22\ +\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\x20\x20\x20\x20\ +\x20\x64\x3d\x22\x6d\x20\x2d\x33\x2e\x31\x31\x30\x32\x38\x31\x34\ +\x2c\x37\x2e\x38\x39\x34\x31\x36\x34\x39\x20\x63\x20\x30\x2c\x30\ +\x2e\x32\x32\x35\x20\x2d\x30\x2e\x32\x2c\x30\x2e\x34\x32\x35\x20\ +\x2d\x30\x2e\x34\x32\x35\x2c\x30\x2e\x34\x32\x35\x20\x2d\x30\x2e\ +\x32\x32\x35\x2c\x30\x20\x2d\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\ +\x32\x20\x2d\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x34\x32\x35\x20\ +\x76\x20\x2d\x33\x2e\x37\x37\x35\x20\x6c\x20\x2d\x32\x2e\x31\x37\ +\x35\x2c\x30\x2e\x37\x37\x35\x20\x76\x20\x34\x2e\x30\x35\x20\x63\ +\x20\x30\x2c\x30\x2e\x32\x32\x35\x20\x2d\x30\x2e\x32\x2c\x30\x2e\ +\x34\x32\x35\x20\x2d\x30\x2e\x34\x32\x35\x2c\x30\x2e\x34\x32\x35\ +\x20\x2d\x30\x2e\x32\x32\x35\x2c\x30\x20\x2d\x30\x2e\x34\x32\x35\ +\x2c\x2d\x30\x2e\x32\x20\x2d\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\ +\x34\x32\x35\x20\x76\x20\x2d\x33\x2e\x37\x35\x20\x6c\x20\x2d\x30\ +\x2e\x39\x37\x35\x2c\x30\x2e\x33\x32\x35\x20\x63\x20\x2d\x30\x2e\ +\x32\x35\x2c\x30\x2e\x31\x20\x2d\x30\x2e\x35\x32\x35\x2c\x2d\x30\ +\x2e\x31\x20\x2d\x30\x2e\x35\x32\x35\x2c\x2d\x30\x2e\x33\x37\x35\ +\x20\x76\x20\x2d\x31\x2e\x36\x20\x63\x20\x30\x2c\x2d\x30\x2e\x31\ +\x37\x35\x20\x30\x2e\x31\x32\x35\x2c\x2d\x30\x2e\x33\x32\x35\x20\ +\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\x33\x37\x35\x20\x6c\x20\x31\ +\x2e\x32\x32\x35\x2c\x2d\x30\x2e\x34\x35\x20\x76\x20\x2d\x34\x2e\ +\x31\x20\x6c\x20\x2d\x30\x2e\x39\x37\x35\x2c\x30\x2e\x33\x35\x20\ +\x63\x20\x2d\x30\x2e\x32\x35\x2c\x30\x2e\x31\x20\x2d\x30\x2e\x35\ +\x32\x35\x2c\x2d\x30\x2e\x31\x20\x2d\x30\x2e\x35\x32\x35\x2c\x2d\ +\x30\x2e\x33\x37\x35\x20\x76\x20\x2d\x31\x2e\x36\x32\x35\x20\x63\ +\x20\x30\x2c\x2d\x30\x2e\x31\x37\x35\x20\x30\x2e\x31\x32\x35\x2c\ +\x2d\x30\x2e\x33\x32\x35\x20\x30\x2e\x32\x37\x35\x2c\x2d\x30\x2e\ +\x33\x37\x35\x20\x6c\x20\x31\x2e\x32\x32\x35\x2c\x2d\x30\x2e\x34\ +\x32\x35\x20\x76\x20\x2d\x34\x2e\x30\x37\x35\x20\x63\x20\x30\x2c\ +\x2d\x30\x2e\x32\x32\x35\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x34\x32\ +\x35\x20\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x34\x32\x35\x20\x30\ +\x2e\x32\x32\x35\x2c\x30\x20\x30\x2e\x34\x32\x35\x2c\x30\x2e\x32\ +\x20\x30\x2e\x34\x32\x35\x2c\x30\x2e\x34\x32\x35\x20\x76\x20\x33\ +\x2e\x37\x37\x35\x20\x6c\x20\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\ +\x37\x37\x35\x20\x76\x20\x2d\x34\x2e\x30\x35\x20\x63\x20\x30\x2c\ +\x2d\x30\x2e\x32\x32\x35\x20\x30\x2e\x32\x2c\x2d\x30\x2e\x34\x32\ +\x35\x20\x30\x2e\x34\x32\x35\x2c\x2d\x30\x2e\x34\x32\x35\x20\x30\ +\x2e\x32\x32\x35\x2c\x30\x20\x30\x2e\x34\x32\x35\x2c\x30\x2e\x32\ +\x20\x30\x2e\x34\x32\x35\x2c\x30\x2e\x34\x32\x35\x20\x76\x20\x33\ +\x2e\x37\x35\x20\x6c\x20\x30\x2e\x39\x37\x35\x2c\x2d\x30\x2e\x33\ +\x32\x35\x20\x63\x20\x30\x2e\x32\x35\x2c\x2d\x30\x2e\x31\x20\x30\ +\x2e\x35\x32\x35\x2c\x30\x2e\x31\x20\x30\x2e\x35\x32\x35\x2c\x30\ +\x2e\x33\x37\x35\x20\x76\x20\x31\x2e\x36\x20\x63\x20\x30\x2c\x30\ +\x2e\x31\x37\x35\x20\x2d\x30\x2e\x31\x32\x35\x2c\x30\x2e\x33\x32\ +\x35\x20\x2d\x30\x2e\x32\x37\x35\x2c\x30\x2e\x33\x37\x35\x20\x6c\ +\x20\x2d\x31\x2e\x32\x32\x35\x2c\x30\x2e\x34\x35\x20\x76\x20\x34\ +\x2e\x31\x20\x6c\x20\x30\x2e\x39\x37\x35\x2c\x2d\x30\x2e\x33\x35\ +\x20\x63\x20\x30\x2e\x32\x35\x2c\x2d\x30\x2e\x31\x30\x30\x30\x30\ +\x30\x30\x33\x20\x30\x2e\x35\x32\x35\x2c\x30\x2e\x31\x20\x30\x2e\ +\x35\x32\x35\x2c\x30\x2e\x33\x37\x35\x20\x76\x20\x31\x2e\x36\x32\ +\x35\x20\x63\x20\x30\x2c\x30\x2e\x31\x37\x35\x20\x2d\x30\x2e\x31\ +\x32\x35\x2c\x30\x2e\x33\x32\x35\x20\x2d\x30\x2e\x32\x37\x35\x2c\ +\x30\x2e\x33\x37\x35\x20\x6c\x20\x2d\x31\x2e\x32\x32\x35\x2c\x30\ +\x2e\x34\x32\x35\x20\x76\x20\x34\x2e\x30\x37\x35\x20\x7a\x20\x6d\ +\x20\x2d\x30\x2e\x38\x35\x2c\x2d\x31\x30\x2e\x33\x32\x35\x20\x2d\ +\x32\x2e\x31\x37\x35\x2c\x30\x2e\x37\x35\x20\x76\x20\x34\x2e\x31\ +\x20\x6c\x20\x32\x2e\x31\x37\x35\x2c\x2d\x30\x2e\x37\x35\x20\x76\ +\x20\x2d\x34\x2e\x31\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\ +\x3d\x22\x70\x61\x74\x68\x33\x31\x32\x31\x22\x20\x2f\x3e\x0a\x3c\ +\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x06\x5b\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\ +\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\ +\x6e\x6f\x22\x3f\x3e\x0a\x3c\x73\x76\x67\x0a\x20\x20\x20\x78\x6d\ +\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\ +\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\ +\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0a\x20\x20\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x72\ +\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\x6e\x73\x2e\x6f\x72\ +\x67\x2f\x6e\x73\x23\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ +\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\ +\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\ +\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\ +\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0a\x20\x20\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\ +\x6f\x64\x69\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\ +\x70\x6f\x64\x69\x2e\x73\x6f\x75\x72\x63\x65\x66\x6f\x72\x67\x65\ +\x2e\x6e\x65\x74\x2f\x44\x54\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\ +\x69\x2d\x30\x2e\x64\x74\x64\x22\x0a\x20\x20\x20\x78\x6d\x6c\x6e\ +\x73\x3a\x69\x6e\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x2f\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x22\x0a\x20\x20\x20\x76\x65\x72\x73\ +\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x20\x20\x20\x68\x65\x69\ +\x67\x68\x74\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\x20\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x31\x30\x30\x30\x2e\x30\x22\x0a\x20\ +\x20\x20\x69\x64\x3d\x22\x73\x76\x67\x33\x34\x34\x35\x22\x0a\x20\ +\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\ +\x6f\x6e\x3d\x22\x30\x2e\x39\x31\x20\x72\x31\x33\x37\x32\x35\x22\ +\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\x63\ +\x6e\x61\x6d\x65\x3d\x22\x72\x65\x73\x74\x42\x72\x65\x76\x69\x73\ +\x2e\x73\x76\x67\x22\x3e\x0a\x20\x20\x3c\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\ +\x64\x61\x74\x61\x33\x34\x35\x33\x22\x3e\x0a\x20\x20\x20\x20\x3c\ +\x72\x64\x66\x3a\x52\x44\x46\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ +\x63\x63\x3a\x57\x6f\x72\x6b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ +\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x0a\x20\ +\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\ +\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\ +\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x0a\x20\x20\x20\x20\ +\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x79\x70\x65\x0a\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\ +\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\ +\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\ +\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\ +\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x64\x63\x3a\x74\x69\x74\ +\x6c\x65\x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x63\x63\ +\x3a\x57\x6f\x72\x6b\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\ +\x3a\x52\x44\x46\x3e\x0a\x20\x20\x3c\x2f\x6d\x65\x74\x61\x64\x61\ +\x74\x61\x3e\x0a\x20\x20\x3c\x64\x65\x66\x73\x0a\x20\x20\x20\x20\ +\x20\x69\x64\x3d\x22\x64\x65\x66\x73\x33\x34\x35\x31\x22\x20\x2f\ +\x3e\x0a\x20\x20\x3c\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\ +\x6d\x65\x64\x76\x69\x65\x77\x0a\x20\x20\x20\x20\x20\x70\x61\x67\ +\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\ +\x0a\x20\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\ +\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0a\x20\x20\x20\x20\ +\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\ +\x31\x22\x0a\x20\x20\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\ +\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\ +\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\ +\x22\x31\x30\x22\x0a\x20\x20\x20\x20\x20\x67\x75\x69\x64\x65\x74\ +\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\ +\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\ +\x61\x64\x6f\x77\x3d\x22\x32\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\ +\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\ +\x64\x74\x68\x3d\x22\x31\x39\x31\x36\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\ +\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x34\x36\x22\x0a\x20\x20\ +\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\ +\x33\x34\x34\x39\x22\x0a\x20\x20\x20\x20\x20\x73\x68\x6f\x77\x67\ +\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\ +\x32\x31\x2e\x33\x36\x30\x32\x38\x32\x22\x0a\x20\x20\x20\x20\x20\ +\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x36\x2e\x31\ +\x31\x32\x38\x35\x31\x38\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\ +\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\x22\x39\x39\x35\x2e\x33\x35\ +\x35\x33\x39\x22\x0a\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x30\x22\x0a\ +\x20\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\ +\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x33\x30\x22\x0a\x20\x20\x20\x20\ +\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\ +\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0a\x20\ +\x20\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\ +\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\x73\x76\x67\x33\ +\x34\x34\x35\x22\x20\x2f\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x0a\ +\x20\x20\x20\x20\x20\x67\x6c\x79\x70\x68\x2d\x6e\x61\x6d\x65\x3d\ +\x22\x72\x65\x73\x74\x73\x2e\x4d\x31\x6d\x65\x6e\x73\x75\x72\x61\ +\x6c\x22\x0a\x20\x20\x20\x20\x20\x64\x3d\x22\x6d\x20\x35\x2e\x34\ +\x37\x35\x2c\x36\x2e\x36\x38\x36\x39\x37\x30\x34\x20\x30\x2c\x2d\ +\x36\x2e\x32\x35\x30\x30\x30\x30\x30\x34\x20\x2d\x35\x2e\x34\x37\ +\x35\x2c\x2d\x30\x2e\x35\x20\x30\x2c\x36\x2e\x32\x35\x30\x30\x30\ +\x30\x30\x34\x20\x7a\x22\x0a\x20\x20\x20\x20\x20\x69\x64\x3d\x22\ +\x70\x61\x74\x68\x33\x34\x34\x37\x22\x0a\x20\x20\x20\x20\x20\x69\ +\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\ +\x72\x2d\x63\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\ +\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\ +\x00\x00\x01\xa9\ +\x3c\ +\xb8\x64\x18\xca\xef\x9c\x95\xcd\x21\x1c\xbf\x60\xa1\xbd\xdd\x42\ +\x00\x00\x00\x08\x06\x77\xac\x49\x00\x00\x00\x00\x69\x00\x00\x01\ +\x80\x03\x00\x00\x01\x12\x00\x57\x00\x69\x00\x6c\x00\x6c\x00\x6b\ +\x00\x6f\x00\x6d\x00\x6d\x00\x65\x00\x6e\x00\x20\x00\x69\x00\x6d\ +\x00\x20\x00\x42\x00\x65\x00\x69\x00\x73\x00\x70\x00\x69\x00\x65\ +\x00\x6c\x00\x70\x00\x72\x00\x6f\x00\x67\x00\x72\x00\x61\x00\x6d\ +\x00\x6d\x00\x2e\x00\x20\x00\x45\x00\x72\x00\x73\x00\x74\x00\x65\ +\x00\x6c\x00\x6c\x00\x65\x00\x6e\x00\x20\x00\x53\x00\x69\x00\x65\ +\x00\x20\x00\x6e\x00\x65\x00\x75\x00\x65\x00\x20\x00\x50\x00\x72\ +\x00\x6f\x00\x67\x00\x72\x00\x61\x00\x6d\x00\x6d\x00\x65\x00\x20\ +\x00\x61\x00\x75\x00\x66\x00\x20\x00\x64\x00\x69\x00\x65\x00\x73\ +\x00\x65\x00\x72\x00\x20\x00\x47\x00\x72\x00\x75\x00\x6e\x00\x64\ +\x00\x6c\x00\x61\x00\x67\x00\x65\x00\x20\x00\x77\x00\x69\x00\x65\ +\x00\x20\x00\x65\x00\x73\x00\x20\x00\x49\x00\x68\x00\x6e\x00\x65\ +\x00\x6e\x00\x20\x00\x67\x00\x65\x00\x66\x00\xe4\x00\x6c\x00\x6c\ +\x00\x74\x00\x2e\x00\x20\x00\x45\x00\x69\x00\x6e\x00\x20\x00\x67\ +\x00\x75\x00\x74\x00\x65\x00\x72\x00\x20\x00\x45\x00\x69\x00\x6e\ +\x00\x73\x00\x74\x00\x69\x00\x65\x00\x67\x00\x20\x00\x77\x00\xe4\ +\x00\x72\x00\x65\x00\x20\x00\x63\x00\x6f\x00\x6e\x00\x66\x00\x69\ +\x00\x67\x00\x2e\x00\x70\x00\x79\x08\x00\x00\x00\x00\x06\x00\x00\ +\x00\x54\x54\x68\x69\x73\x20\x69\x73\x20\x61\x6e\x20\x65\x78\x61\ +\x6d\x70\x6c\x65\x20\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\ +\x2e\x20\x45\x78\x74\x65\x6e\x64\x20\x69\x74\x20\x74\x6f\x20\x79\ +\x6f\x75\x72\x20\x6c\x69\x6b\x69\x6e\x67\x2e\x20\x53\x74\x61\x72\ +\x74\x20\x62\x79\x20\x65\x64\x69\x74\x69\x6e\x67\x20\x63\x6f\x6e\ +\x66\x69\x67\x2e\x70\x79\x07\x00\x00\x00\x05\x41\x62\x6f\x75\x74\ +\x01\x88\x00\x00\x00\x02\x01\x01\ +" + +qt_resource_name = b"\ +\x00\x0c\ +\x0d\xfc\x11\x13\ +\x00\x74\ +\x00\x72\x00\x61\x00\x6e\x00\x73\x00\x6c\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\ +\x00\x0d\ +\x0b\x0f\xc0\xa7\ +\x00\x61\ +\x00\x62\x00\x6f\x00\x75\x00\x74\x00\x6c\x00\x6f\x00\x67\x00\x6f\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0b\ +\x09\xc1\xce\x26\ +\x00\x65\ +\x00\x75\x00\x74\x00\x65\x00\x72\x00\x70\x00\x65\x00\x2e\x00\x74\x00\x74\x00\x66\ +\x00\x03\ +\x00\x00\x7a\xc7\ +\x00\x73\ +\x00\x76\x00\x67\ +\x00\x08\ +\x0a\x61\x5a\xa7\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0c\ +\x08\x50\xae\x47\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x31\x00\x32\x00\x38\x00\x69\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x10\ +\x0c\x40\xa2\x67\ +\x00\x63\ +\x00\x6c\x00\x65\x00\x66\x00\x54\x00\x72\x00\x65\x00\x62\x00\x6c\x00\x65\x00\x5f\x00\x38\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0b\ +\x04\x81\x15\x87\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x31\x00\x32\x00\x38\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0e\ +\x0c\x5e\x51\x07\ +\x00\x63\ +\x00\x6c\x00\x65\x00\x66\x00\x42\x00\x61\x00\x73\x00\x73\x00\x5f\x00\x38\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x13\ +\x06\xfa\xd2\x67\ +\x00\x6e\ +\x00\x6f\x00\x74\x00\x65\x00\x68\x00\x65\x00\x61\x00\x64\x00\x73\x00\x4d\x00\x61\x00\x78\x00\x69\x00\x6d\x00\x61\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ +\x00\x0e\ +\x09\x62\x35\x27\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x4d\x00\x61\x00\x78\x00\x69\x00\x6d\x00\x61\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0a\ +\x07\x98\x43\x87\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x36\x00\x34\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x1a\ +\x0a\x46\x61\xe7\ +\x00\x61\ +\x00\x63\x00\x63\x00\x69\x00\x64\x00\x65\x00\x6e\x00\x74\x00\x61\x00\x6c\x00\x73\x00\x44\x00\x6f\x00\x75\x00\x62\x00\x6c\x00\x65\ +\x00\x73\x00\x68\x00\x61\x00\x72\x00\x70\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x17\ +\x07\x08\x14\x67\ +\x00\x61\ +\x00\x63\x00\x63\x00\x69\x00\x64\x00\x65\x00\x6e\x00\x74\x00\x61\x00\x6c\x00\x73\x00\x46\x00\x6c\x00\x61\x00\x74\x00\x46\x00\x6c\ +\x00\x61\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x13\ +\x07\xa8\xdf\x47\ +\x00\x61\ +\x00\x63\x00\x63\x00\x69\x00\x64\x00\x65\x00\x6e\x00\x74\x00\x61\x00\x6c\x00\x73\x00\x46\x00\x6c\x00\x61\x00\x74\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ +\x00\x07\ +\x0b\x67\x5a\x07\ +\x00\x64\ +\x00\x6f\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0c\ +\x05\xe3\x2f\xc7\ +\x00\x63\ +\x00\x6c\x00\x65\x00\x66\x00\x42\x00\x61\x00\x73\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x12\ +\x0c\x32\x07\x07\ +\x00\x6e\ +\x00\x6f\x00\x74\x00\x65\x00\x68\x00\x65\x00\x61\x00\x64\x00\x73\x00\x42\x00\x6c\x00\x61\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x0b\ +\x04\x12\x15\x87\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x31\x00\x36\x00\x69\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0a\ +\x07\x6a\x43\x87\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x33\x00\x32\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x09\ +\x07\xab\x80\x87\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x38\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0a\ +\x0a\x68\xfe\x27\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x33\x00\x32\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0c\ +\x0e\xf7\x2f\xc7\ +\x00\x63\ +\x00\x6c\x00\x65\x00\x66\x00\x41\x00\x6c\x00\x74\x00\x6f\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0c\ +\x09\x61\xe9\x27\ +\x00\x62\ +\x00\x6c\x00\x6f\x00\x63\x00\x6b\x00\x45\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0b\ +\x09\x72\x15\x87\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x36\x00\x34\x00\x69\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x12\ +\x01\x8d\xee\x47\ +\x00\x6e\ +\x00\x6f\x00\x74\x00\x65\x00\x68\x00\x65\x00\x61\x00\x64\x00\x73\x00\x57\x00\x68\x00\x6f\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x0a\ +\x0a\x9a\xfe\x27\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x36\x00\x34\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x09\ +\x0a\x7b\xab\x47\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x38\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x12\ +\x0f\xfe\x22\x67\ +\x00\x63\ +\x00\x6c\x00\x65\x00\x66\x00\x50\x00\x65\x00\x72\x00\x63\x00\x75\x00\x73\x00\x73\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x10\ +\x0c\x70\xa2\x67\ +\x00\x63\ +\x00\x6c\x00\x65\x00\x66\x00\x54\x00\x72\x00\x65\x00\x62\x00\x6c\x00\x65\x00\x5e\x00\x38\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0a\ +\x0a\xe9\xfe\x27\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x38\x00\x69\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x09\ +\x0a\x77\xab\x47\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x34\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x11\ +\x0c\x93\x9f\xe7\ +\x00\x6e\ +\x00\x6f\x00\x74\x00\x65\x00\x68\x00\x65\x00\x61\x00\x64\x00\x73\x00\x48\x00\x61\x00\x6c\x00\x66\x00\x2e\x00\x73\x00\x76\x00\x67\ +\ +\x00\x16\ +\x00\xd4\xe8\xa7\ +\x00\x61\ +\x00\x63\x00\x63\x00\x69\x00\x64\x00\x65\x00\x6e\x00\x74\x00\x61\x00\x6c\x00\x73\x00\x4e\x00\x61\x00\x74\x00\x75\x00\x72\x00\x61\ +\x00\x6c\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0b\ +\x0c\x81\xdd\xc7\ +\x00\x6e\ +\x00\x75\x00\x6d\x00\x62\x00\x65\x00\x72\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0d\ +\x05\x49\x7d\x67\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x4c\x00\x6f\x00\x6e\x00\x67\x00\x61\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0b\ +\x06\x52\x15\x87\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x33\x00\x32\x00\x69\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x09\ +\x0a\x75\xab\x47\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x32\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0b\ +\x04\xaa\xce\x27\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x31\x00\x32\x00\x38\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0a\ +\x07\x46\x43\x87\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x31\x00\x36\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x13\ +\x0f\x42\xb4\xc7\ +\x00\x73\ +\x00\x63\x00\x72\x00\x69\x00\x70\x00\x74\x00\x73\x00\x53\x00\x74\x00\x61\x00\x63\x00\x63\x00\x61\x00\x74\x00\x6f\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ +\x00\x09\ +\x0a\x74\xab\x47\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x31\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x13\ +\x07\xc3\x92\x27\ +\x00\x6e\ +\x00\x6f\x00\x74\x00\x65\x00\x68\x00\x65\x00\x61\x00\x64\x00\x73\x00\x42\x00\x72\x00\x65\x00\x76\x00\x69\x00\x73\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ +\x00\x0a\ +\x0a\x44\xfe\x27\ +\x00\x66\ +\x00\x6c\x00\x61\x00\x67\x00\x31\x00\x36\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0e\ +\x0c\x53\x31\x27\ +\x00\x63\ +\x00\x6c\x00\x65\x00\x66\x00\x54\x00\x72\x00\x65\x00\x62\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x12\ +\x0f\x80\xf3\x87\ +\x00\x6e\ +\x00\x6f\x00\x74\x00\x65\x00\x68\x00\x65\x00\x61\x00\x64\x00\x73\x00\x4c\x00\x6f\x00\x6e\x00\x67\x00\x61\x00\x2e\x00\x73\x00\x76\ +\x00\x67\ +\x00\x14\ +\x0a\x6a\xeb\xa7\ +\x00\x61\ +\x00\x63\x00\x63\x00\x69\x00\x64\x00\x65\x00\x6e\x00\x74\x00\x61\x00\x6c\x00\x73\x00\x53\x00\x68\x00\x61\x00\x72\x00\x70\x00\x2e\ +\x00\x73\x00\x76\x00\x67\ +\x00\x0e\ +\x04\x57\x75\x67\ +\x00\x72\ +\x00\x65\x00\x73\x00\x74\x00\x42\x00\x72\x00\x65\x00\x76\x00\x69\x00\x73\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x05\ +\x00\x6a\x85\x7d\ +\x00\x64\ +\x00\x65\x00\x2e\x00\x71\x00\x6d\ +" + +qt_resource_struct_v1 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x01\ +\x00\x00\x00\x5a\x00\x02\x00\x00\x00\x2b\x00\x00\x00\x07\ +\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x01\x00\x00\x2d\x2c\ +\x00\x00\x00\x66\x00\x00\x00\x00\x00\x01\x00\x00\xf3\xe0\ +\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x06\ +\x00\x00\x06\x20\x00\x00\x00\x00\x00\x01\x00\x02\x7d\x8e\ +\x00\x00\x04\x22\x00\x00\x00\x00\x00\x01\x00\x01\xf1\xbf\ +\x00\x00\x03\x1c\x00\x00\x00\x00\x00\x01\x00\x01\xa9\xcd\ +\x00\x00\x02\x5c\x00\x00\x00\x00\x00\x01\x00\x01\x6f\x60\ +\x00\x00\x05\xfe\x00\x00\x00\x00\x00\x01\x00\x02\x77\x2f\ +\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x01\x12\xce\ +\x00\x00\x04\xc4\x00\x00\x00\x00\x00\x01\x00\x02\x30\x20\ +\x00\x00\x04\x70\x00\x00\x00\x00\x00\x01\x00\x02\x19\xaa\ +\x00\x00\x02\x14\x00\x00\x00\x00\x00\x01\x00\x01\x5e\xbf\ +\x00\x00\x04\x90\x00\x00\x00\x00\x00\x01\x00\x02\x1f\xee\ +\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x01\x00\x01\x2b\x56\ +\x00\x00\x01\xa0\x00\x00\x00\x00\x00\x01\x00\x01\x4b\x87\ +\x00\x00\x04\xe0\x00\x00\x00\x00\x00\x01\x00\x02\x37\xa6\ +\x00\x00\x02\x78\x00\x00\x00\x00\x00\x01\x00\x01\x77\xaf\ +\x00\x00\x01\x4c\x00\x00\x00\x00\x00\x01\x00\x01\x3a\xb5\ +\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x01\x52\x9d\ +\x00\x00\x02\x92\x00\x00\x00\x00\x00\x01\x00\x01\x7d\xbf\ +\x00\x00\x05\x3e\x00\x00\x00\x00\x00\x01\x00\x02\x4a\xbc\ +\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x01\x00\x00\xf7\x92\ +\x00\x00\x02\xe2\x00\x00\x00\x00\x00\x01\x00\x01\x92\x37\ +\x00\x00\x01\x2a\x00\x00\x00\x00\x00\x01\x00\x01\x34\x57\ +\x00\x00\x03\x00\x00\x00\x00\x00\x00\x01\x00\x01\x9f\xa2\ +\x00\x00\x05\x6a\x00\x00\x00\x00\x00\x01\x00\x02\x53\x3d\ +\x00\x00\x01\x66\x00\x00\x00\x00\x00\x01\x00\x01\x41\xac\ +\x00\x00\x02\xaa\x00\x00\x00\x00\x00\x01\x00\x01\x81\xb4\ +\x00\x00\x05\xd0\x00\x00\x00\x00\x00\x01\x00\x02\x70\x94\ +\x00\x00\x05\x26\x00\x00\x00\x00\x00\x01\x00\x02\x43\xd3\ +\x00\x00\x04\xac\x00\x00\x00\x00\x00\x01\x00\x02\x29\x42\ +\x00\x00\x03\xe2\x00\x00\x00\x00\x00\x01\x00\x01\xe3\x17\ +\x00\x00\x03\x60\x00\x00\x00\x00\x00\x01\x00\x01\xbc\x25\ +\x00\x00\x03\x46\x00\x00\x00\x00\x00\x01\x00\x01\xb2\x2d\ +\x00\x00\x03\xc8\x00\x00\x00\x00\x00\x01\x00\x01\xdb\xb8\ +\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\x00\x01\x57\xf4\ +\x00\x00\x02\x32\x00\x00\x00\x00\x00\x01\x00\x01\x68\x3e\ +\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x01\x02\x47\ +\x00\x00\x05\x84\x00\x00\x00\x00\x00\x01\x00\x02\x5a\xd2\ +\x00\x00\x00\xdc\x00\x00\x00\x00\x00\x01\x00\x01\x1d\xba\ +\x00\x00\x03\xa2\x00\x00\x00\x00\x00\x01\x00\x01\xcb\x2f\ +\x00\x00\x04\x54\x00\x00\x00\x00\x00\x01\x00\x01\xf6\x91\ +\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x01\xec\x69\ +\x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x01\x87\x36\ +\x00\x00\x04\xfa\x00\x00\x00\x00\x00\x01\x00\x02\x40\x40\ +\x00\x00\x05\xa6\x00\x00\x00\x00\x00\x01\x00\x02\x67\x5d\ +\x00\x00\x03\x78\x00\x00\x00\x00\x00\x01\x00\x01\xc3\xc0\ +" + +qt_resource_struct_v2 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x5a\x00\x02\x00\x00\x00\x2b\x00\x00\x00\x07\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x01\x00\x00\x2d\x2c\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x00\x66\x00\x00\x00\x00\x00\x01\x00\x00\xf3\xe0\ +\x00\x00\x01\x68\x8f\xc1\x78\x97\ +\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01\x68\x8f\xc1\x78\x97\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x06\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x06\x20\x00\x00\x00\x00\x00\x01\x00\x02\x7d\x8e\ +\x00\x00\x01\x68\x8f\xc1\x78\x97\ +\x00\x00\x04\x22\x00\x00\x00\x00\x00\x01\x00\x01\xf1\xbf\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\x1c\x00\x00\x00\x00\x00\x01\x00\x01\xa9\xcd\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\x5c\x00\x00\x00\x00\x00\x01\x00\x01\x6f\x60\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x05\xfe\x00\x00\x00\x00\x00\x01\x00\x02\x77\x2f\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x01\x12\xce\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x04\xc4\x00\x00\x00\x00\x00\x01\x00\x02\x30\x20\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x04\x70\x00\x00\x00\x00\x00\x01\x00\x02\x19\xaa\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\x14\x00\x00\x00\x00\x00\x01\x00\x01\x5e\xbf\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x04\x90\x00\x00\x00\x00\x00\x01\x00\x02\x1f\xee\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x01\x00\x01\x2b\x56\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x01\xa0\x00\x00\x00\x00\x00\x01\x00\x01\x4b\x87\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x04\xe0\x00\x00\x00\x00\x00\x01\x00\x02\x37\xa6\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\x78\x00\x00\x00\x00\x00\x01\x00\x01\x77\xaf\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x01\x4c\x00\x00\x00\x00\x00\x01\x00\x01\x3a\xb5\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x01\x52\x9d\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\x92\x00\x00\x00\x00\x00\x01\x00\x01\x7d\xbf\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x05\x3e\x00\x00\x00\x00\x00\x01\x00\x02\x4a\xbc\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x01\x00\x00\xf7\x92\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\xe2\x00\x00\x00\x00\x00\x01\x00\x01\x92\x37\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x01\x2a\x00\x00\x00\x00\x00\x01\x00\x01\x34\x57\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\x00\x00\x00\x00\x00\x00\x01\x00\x01\x9f\xa2\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x05\x6a\x00\x00\x00\x00\x00\x01\x00\x02\x53\x3d\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x01\x66\x00\x00\x00\x00\x00\x01\x00\x01\x41\xac\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\xaa\x00\x00\x00\x00\x00\x01\x00\x01\x81\xb4\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x05\xd0\x00\x00\x00\x00\x00\x01\x00\x02\x70\x94\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x05\x26\x00\x00\x00\x00\x00\x01\x00\x02\x43\xd3\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x04\xac\x00\x00\x00\x00\x00\x01\x00\x02\x29\x42\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\xe2\x00\x00\x00\x00\x00\x01\x00\x01\xe3\x17\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\x60\x00\x00\x00\x00\x00\x01\x00\x01\xbc\x25\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\x46\x00\x00\x00\x00\x00\x01\x00\x01\xb2\x2d\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\xc8\x00\x00\x00\x00\x00\x01\x00\x01\xdb\xb8\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\x00\x01\x57\xf4\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\x32\x00\x00\x00\x00\x00\x01\x00\x01\x68\x3e\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x01\x02\x47\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x05\x84\x00\x00\x00\x00\x00\x01\x00\x02\x5a\xd2\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x00\xdc\x00\x00\x00\x00\x00\x01\x00\x01\x1d\xba\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\xa2\x00\x00\x00\x00\x00\x01\x00\x01\xcb\x2f\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x04\x54\x00\x00\x00\x00\x00\x01\x00\x01\xf6\x91\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x01\xec\x69\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x01\x87\x36\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x04\xfa\x00\x00\x00\x00\x00\x01\x00\x02\x40\x40\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x05\xa6\x00\x00\x00\x00\x00\x01\x00\x02\x67\x5d\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +\x00\x00\x03\x78\x00\x00\x00\x00\x00\x01\x00\x01\xc3\xc0\ +\x00\x00\x01\x59\x79\x93\x2a\xc8\ +" + +qt_version = [int(v) for v in QtCore.qVersion().split('.')] +if qt_version < [5, 8, 0]: + rcc_version = 1 + qt_resource_struct = qt_resource_struct_v1 +else: + rcc_version = 2 + qt_resource_struct = qt_resource_struct_v2 + +def qInitResources(): + QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/qtgui/resources/aboutlogo.png b/qtgui/resources/aboutlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..d8f475a912cb15bd190fb8bb0360c72651aee370 GIT binary patch literal 11560 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 l{>!r4|Nr!^C+PqH literal 0 HcmV?d00001 diff --git a/qtgui/resources/buildresources.sh b/qtgui/resources/buildresources.sh new file mode 100644 index 0000000..57cfa52 --- /dev/null +++ b/qtgui/resources/buildresources.sh @@ -0,0 +1,4 @@ +#!/bin/bash +#https://doc.qt.io/qt-5/resources.html +#Resources are kept up-to-date upstream. They are not part of the make and build process. +pyrcc5 -no-compress resources.qrc -o ../resources.py #put them into the gui directly. Engine does not need any translation or images. diff --git a/qtgui/resources/euterpe.license.txt b/qtgui/resources/euterpe.license.txt new file mode 100644 index 0000000..f7c0eae --- /dev/null +++ b/qtgui/resources/euterpe.license.txt @@ -0,0 +1,94 @@ +Euterpe Font - Ben Laenen, SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + + + + + diff --git a/qtgui/resources/euterpe.ttf b/qtgui/resources/euterpe.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2ce946229fc39f3c9aea62ebaf08ca65bcf1cdcc GIT binary patch literal 50864 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
?0IJbR*pC? zXeQtkuXPT9iF_EOaAWpD#s=jS>qF2op!_i3nX+W#54q%--l&#qgW9pRBMo@~1^c?M z$9Gu+v9+WAVBd$jg7VwQt${SuCT49m0Zg>rvUV^@GTW`C{FZG7v*PO^|3)Z*cQFdl zzMw@wiV^li|BJOqOrI=eW^K^^F&pjxe_>*qjrU4r5BXejkaa1(m2aXgVkux2Z>dox zGUbRJN*Vbq_Y+#65c|G~;{)sk5Myi!ti>?7$hc1j2soNREydnvvfp+tyk#wry$m3AD&7 zC~Ve`A#_F!`jIS+_0%ii4*OoLk)>lhLJpvxiv8bOkmSYi482y?78&*NJsf(Y=VI^%cP#7o8p3A z`6kK-h7+@&C>gZ*Omd8N#8CE&WIs^ushK9QND%6WEH~E2Po#Q1Kt(%*dcbr+3wMkQ zXt89N7p6N_6Z3uWUiNe^k^B;71@Q@!9LBZqF6QmAXR<}Wa_9E?FfZy4>m#rwuceUX z(sGnQ&V&8knVvSY&1__IE^2XnJ+b%3y3ytjjE~r4KFgfK)+dh{d)c$c))ha>V0fXdFg}S9lQK&Ax3BYDGCNyDYa(uwM;+(ZH0I$T zC%?`30(IqlBMkJau+7F=9rGBljkA`Cl9Y7;V_55{w;#*T@n_SldM6ZKQ}`Vdd#PBEO>2o(E1v{2h9P7{5*mC$Zb5<`$5 z?HcyYvB(_a!eSI?n^C$O$2Bv?1N8i{*TL^qkRR(}y*_dh^?3PNp`+bFY_Uc>Grtq{ zaT%>m9xbw#5Tk%$F+d?>pO2O?MiujqY!dAgN8jrKF5<>KM!BANJ|kC=lj!dvTx_e@ zzcSByqHo1)>qe>V_$8}>{nmwA=eKDmthSi$o!g(*g6(3X;rP)78?m4iQ4?^ihI)xM z0Q*~%9L{54KaVX0ZQj{?z=?gH?9<8GfYxjy{GkprZ%X#`v}cXX$B%_%{by~1!C-wq zM&V*!GtS?jY~(Sg++R%e3Ya#cZp#|Nd%>EF2L-apcA1sg1C&s>H3R%m= zo)~41))6%TM|0TXv8~`0a%vg1bLe5CeDDeD<+K;nb_R7DXxnn&HR_w}1uca!E8=%C z;EFAb&8@}j(nRl%>A>0eabfL}OEK#hYe#42G}0{FA2~0JJzS{upgx`1dRYG&oS-+d z1kdapkz;3iM@$lD^PDh0vyvAY1)*nwF=X@xWxoJhDBhzDi1)Hl6HwaN5?PD;I#CM5 zMdop=rg$wp_t-TaKGQDLKc){Tk#qHzY&`Q#;$Fgceeid{Bf_CR?Css z^T)lkR0>!-_EECVpIaxG2KA1QWxBvd$nmZ7&DCMMXFev{IJ8zcgR(YGN?U=)7;Qxz zLJJe)e7wDx?CUUJR<_Fs87(c&z{s*@{X4@O$5=DL7Ip&GQ^8{3hzzlAgDZ>#$@60~ z;VKO2b08niFxhB18=Y_ZKc$@scpJxc$MIlMmez7COKO_-OP%@DG?iM2CT_rSTQ9H+ z5)}y0AZS_c*D_0BNp1vSk=+Gpw&|H(>7A?hk+$i5-`Cf}vE8O;?4-GRAMW8E>3u4; z`hW8l1VGtIzEl)ByR$Rz_vX!;H?zQC(ZYL`b=ur>eRdh;`R{3M=L}wGS`MpGzbyf5EmCX*g zT#M_m_|*=! z72hGRfz2hBp;t$1!6a@Smt?DSaNUGduFurVI#)Dfn{Y3)E>kHy*E3u6;CIF!h~;rK zEq}BR z46XN3ADH+Q%i`W)do;8a)?q&z`m-d-;dZn4uzy!$3vwQp;nuKKCuPNk@;U|g-~H%K zDIxNVBdy?eUC}n1T3zhS8nT}-aq=3-w2zs|I#2XrpJiW~jD)FGc$BdwOya)gGbSvf zm)Mh9uqj`gj6z|EHVWE{7fQRh-n@M$qh(TVQtyLB2$3~mv*%9R&h}(miiX_FVvP?i z7hknl^+yMRx3e3m3*C!~x3#1`xFV* z-QSM(oxoMdz++k6VTdZ@Vb2XzwCk$%dPB8F*d3&$G^9XE&Fqv}6k%~)7Sr`d9`7!4 z`~H4PIl~@jI{naB&K~v^Ia_^KwiP+5X5O!y=pG~9Q51FqZxn@#A$A{OW6|BMTEj4m zOCR|^L+ih0H&w0G?5IY)YB$&IS@qQ=l_{v2yA_O`;DAkB{C@$BwYF`pRvI?U;;J1V z?Nb_k4AnFX_~&;<(*#G(qy>X*r^q1Rh+KVa|d2m_e|d#?u%4|*s^Z3ixrVbAc{8@2=Z6V$w>yrJ6P^}4%Sn@|m$19ZF! zchRVx^!T$!gadiIe*9u^`kA=_(ilZUUzXbpsB)kz0Z+p9PQMo++4W z+=Gjy)WGj~+w5$t8Hi{};B8^oSx+n6KTr>wcKv<$PoTBsHbddS z?Yqu&h_f=f4^(t8a@oaVtBWxL_f=yraJBove_{@L0(lPla}p<}u|xHIXw5KZH0mE1 zD60+VcgI?ac1Sd39I|a;{8%Q0{`89@6=n(b>n=E{e2Rz&O?W7_zwF8 ziwRvlLbkm=_=l~8#rWc37&TVV?QU=(y!c$YvjMxXPXNCeIKegct5AjG?k<}Hjf8g_ z;u!$?GJNVT4G*CPiCVdJEHpH+1@w*fuMhO~9c8ae}uuqL=4P$s>Q{V+$xonG+hbgXpOJ z)S>;DxjGqr@pLfD)V)3(HUq>Q_Ft!`2UX;!(9?Z4f)}I=9v|Z^1fgim8S2udNw843 zq$7-vIRn|+UnQE(C@t~TIBEj)%7N97nr;aB~wwZwDa_5r8o+A7N1MAU+QGIC8tYL$B-fjs3vmUIbnS+z8H# z&e-4eVgKP_*oxhGPAA~k?DlGXeH{Zqy-ZbGO)DN0Yi=;`LcMDh{)u4fqH&-P5du>Z zw0Yh@INovf6u}mZ(f(G1K@2Mx4pbN+5{PBz*t!y;j|ANV#1fQ5;B~b?9rofde2|(8 zeKLn2wD#wsG{)Uw(1s{XHnUh`GQ5EsZ}G%78Que z+p@#JHIX)%I_8X~C$i_CFSKv*gd9&8u7in}I|PAY$ek%OCzc3U9&o;_9TASPaMMvK z;xINF<3kkGbJ--Y^;B$64t)_K*(C=PC{`%$!_g$#?T!b|@DkP*J-wLQ#Q}$6KVV~W zv_bF>{88ZXYGwc>F*2sb2X2Il5!Mu*+wX;XEy(p401;aVV_1nvB%hnUeJC5(iRWL; zWgdd{p6Bk%{K#;4Yk=O#!ZrMxy7T$_1l6?eb8*_>g|kc-i1VRxA0EMaUZi+9M_37A zEX@qSc;s<}k)Ru3K1Xcjpl4JMJ4B*rJgJ}rMt>ZdhrDFL%*o>-4h1kHCLT#2~ z_!3X7TxCY-K<*`wi`B!??lGp_1KZ@qHgiED4qm*5L?fobiI;$Sy~^1*M4axsDPu4W z^*U;Hl0-jXk%W%Bc{wCOP*)NY&dsh;Ue9SzKbRYrSi?N`+6(dG!&`f?XRz$aLPW)D zFJrp)nzIB9)ZtmCY4Un&{;qDzMa1NV-5Acmov`P7SkZ55KQeoS#prEA`GwYonu3qHQ)i zS8;=&%;r^fx!$x=hW#M!wAR;EtF7v*YmK^XrBuCHZERTe=CZ1wUbDq_e5>^igmzlG zYAmX5qh8H`F4YxCHY@c;y>m6CYV}T&W!50nRBL9tQ?G6`%(hzFXs@+!<7hT5h;7!J zwKgdBs@?1u(5l*6yV|ZVuXIwV)InxSb=sz7ubS=4Db}!sCbyL?vIs39L)j0YoLXNo z8x4i4#-R+g(rQ>JU9q9Pi91PA2MyQuODW4-HJ7;s6S-VWT3}2qz?NFJn|9l5q}2MF zU9Iy0OjmE)RVav(FgF^HTu8#2V%@%f0~si1#0d1kimg?L&L;j>*)_NyP#i5}Ih|I! zbEwLd`nsJ`X1l%)^BA>uYZb!L6{x|Tz5x@01s4;2xm!4oujw1~Lx(^qu5F0nEZb~A zApD|vb6LDhGXDvv`5l5ce?o)b9qXf#e2VGlYYzT4uHhe^bk6^7yasy`p5q_kQ<3=e zSu$}8CFvGAMhkQtk7qtXC-H@vx6vuO9UlR{gHF?(bcW8-IXrFjh4j(%BKjEmSUf@f z#q@D_c;-t;;rp@9)5p_G=@anT&rhTabdf%ZKABQ@?*Ag)O-q!f3}q=td3+alkxEpi zd+6nKFMSH0$nj}(ADL94Dp_RXsdLM;LUsCdx=amPr6#p#jqay5K1JD~4SImC(1Uc9 z9-_~{r!zm3K8rT#739zsb*V=#ZPO0zl1HzkYt*L!4auhwy@~<~DWWm$(LOy)2lUzW zIrM7!T>3oveEI_VLi!?l4Sg|v34JMj8GSjumc9btCGl1C)$}#=we)rLI(j|5f!;`O zqOYfKpl_saqHm^ep>L&cqi?70pf}TZ(s$8!(_83!=zHn===zYo8Ck3rT5Vv&>zwt(I3;F(4W$u(Vx>_&|lJ1 z^jGxP^f&ak^fdh){XP8y{Uf~}pW^*z`WO0F`ZxM_`Vaa~`Y-x#`XBmVx=tUUXXshF zkxV2hnM~f2JeFKY9#7tyJdr$^G?KR^PbF_pz5q`NIGw!nR=lW^DHNM~0OgB8tW7O@zX!|e1h$A>2(XKR!1isW*d^SI6SQhMoyn1e#R z$k_8Yw*!BGVtsembr-^Y+$WqG;Dwt_UJMO)LS4DCwCMDsxN_+ZF{Hg2r$^4MBj+^( zOPB3Uekp2nTL0a|%(dxka`s7mZM*M8ckrK?D?-aG#c4WD^Kn{|G@FUjtfaa4JZH*z zKCYjS>*wS8`D%P!yMw)yugQ5KE?0=<6yoxQ@^QBJ(vl=;NivdTCCN#Wm!u#`QIe7* zu@qCzDw0$su_Uo2sp%vwytMGr!b=M;Exfew(!xs%FD<;Z@Y2Fd3ok9awD8ixOA9X} zyo~TN!pjIRBfO08GQ!IUAtQv05Hdo@2q7bcj1aOy$O<7Vgsc# z3NI_XtnjkJ%L*?mysYqY!pjLSC%l~Sa>C0AFDJa5@N&Y-2`?wSobYnO%Ly+hyqxgz z!pjRUFTA|)^1{mtFE6~j@bbdT3okFcyzuhE%L^|ryu9!V!Yc@`AiRR`3c@Q0uOPgF z@Cw3<{kkB$g76B$D+sS3yn^tG!Yc}|D7>QZioz=juPD5t@QT7KO8bh!D+;eDyrS@m z!Yc}|B)pRFO2R7%uOz&Z@Jhlf39lr)lJH8xD+#Y8ypr%r!Yc`{EWEPt%EBuPuPnT> z@XEp~3$HA^vhd2nD+{kIyt44h!Yd2U6rL$OQ+THEOyQZrGlgdg&lH|1JX3h4@J!*E z!ZU?u3a=u(itsAJs|c?myo&HD!m9|cBD{+5D#EJ>uOhsP@G8Qq2(K!>|o+Ug>c$V-i z;aQfRfz5bYpFgY0+LUhGz*>}W!Vmtq55LL82|T6XIP&l1H*Rwq#7oVMce#9gR=3^wI& z&t>gT;OJ3(WZ>v=eZ>9nR(-_1aIcnd8pJzr^f<2Y^%vkdvs|8~^EK|pNAbh*Zp9Bv z#WOTuiBr1VZ93-|`s)mIybCGIdK_|?#q5*#5e@hW7q{Z!@)Z;`X5)?(fQi4k*Mn*>7x3VUvEo`+~9X!t`4-O6rjY5ZqhbOsQE`{Ux z1JJcWLa^KIo}8YZp3!Qxy@5dB$@ca(FAt^D>7vi)3m6OrLpU6s@_M~9pb}@nPtQD+ zN>yAg*M!62cod7pj>WA{Boc+;;b9+1lEJO5t&&+9>^AP5qG z9v#Q=I}F2|H0pMa;{=+fk1ZC9XD-jm8jMsOtwRp3&INF>5FgG(hA78ZV~1{VuO(OaO| z{{DVDXcl-#bar-@L9;Ln>p`2y9mD@zc>=*r5_iE!B*8FDQ7!nXgw1BV*R0#65*UWvg&?S|ca#d$P>4pOpY?kEb(6_t zXcRIUjXJGXdyS^)FHnmO2U?1asrH$-EYVJQoy7luOC{b>6g33_Hk?xZ1?^g + + euterpe.ttf + aboutlogo.png + icon.png + translations/de.qm + + svg/accidentalsDoublesharp.svg + svg/accidentalsFlatFlat.svg + svg/accidentalsFlat.svg + svg/accidentalsNatural.svg + svg/accidentalsSharp.svg + svg/blockEnd.svg + svg/clefAlto.svg + svg/clefBass_8.svg + svg/clefBass.svg + svg/clefPercussion.svg + svg/clefTreble^8.svg + svg/clefTreble_8.svg + svg/clefTreble.svg + svg/dot.svg + svg/flag128i.svg + svg/flag128.svg + svg/flag16i.svg + svg/flag16.svg + svg/flag32i.svg + svg/flag32.svg + svg/flag64i.svg + svg/flag64.svg + svg/flag8i.svg + svg/flag8.svg + svg/noteheadsBlack.svg + svg/noteheadsBrevis.svg + svg/noteheadsHalf.svg + svg/noteheadsLonga.svg + svg/noteheadsMaxima.svg + svg/noteheadsWhole.svg + svg/numbers.svg + svg/rest128.svg + svg/rest16.svg + svg/rest1.svg + svg/rest2.svg + svg/rest32.svg + svg/rest4.svg + svg/rest64.svg + svg/rest8.svg + svg/restBrevis.svg + svg/restLonga.svg + svg/restMaxima.svg + svg/scriptsStaccato.svg + + + + + diff --git a/qtgui/resources/svg/accidentalsDoublesharp.svg b/qtgui/resources/svg/accidentalsDoublesharp.svg new file mode 100644 index 0000000..5deb7c2 --- /dev/null +++ b/qtgui/resources/svg/accidentalsDoublesharp.svg @@ -0,0 +1,58 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/accidentalsFlat.svg b/qtgui/resources/svg/accidentalsFlat.svg new file mode 100644 index 0000000..34de82b --- /dev/null +++ b/qtgui/resources/svg/accidentalsFlat.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/accidentalsFlatFlat.svg b/qtgui/resources/svg/accidentalsFlatFlat.svg new file mode 100644 index 0000000..3873dd5 --- /dev/null +++ b/qtgui/resources/svg/accidentalsFlatFlat.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/accidentalsNatural.svg b/qtgui/resources/svg/accidentalsNatural.svg new file mode 100644 index 0000000..fa2c08b --- /dev/null +++ b/qtgui/resources/svg/accidentalsNatural.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/accidentalsSharp.svg b/qtgui/resources/svg/accidentalsSharp.svg new file mode 100644 index 0000000..357318a --- /dev/null +++ b/qtgui/resources/svg/accidentalsSharp.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/blockEnd.svg b/qtgui/resources/svg/blockEnd.svg new file mode 100644 index 0000000..255b2c0 --- /dev/null +++ b/qtgui/resources/svg/blockEnd.svg @@ -0,0 +1,62 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/qtgui/resources/svg/clefAlto.svg b/qtgui/resources/svg/clefAlto.svg new file mode 100644 index 0000000..ac18d51 --- /dev/null +++ b/qtgui/resources/svg/clefAlto.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/clefBass.svg b/qtgui/resources/svg/clefBass.svg new file mode 100644 index 0000000..dc2e744 --- /dev/null +++ b/qtgui/resources/svg/clefBass.svg @@ -0,0 +1,56 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/clefBass_8.svg b/qtgui/resources/svg/clefBass_8.svg new file mode 100644 index 0000000..9254876 --- /dev/null +++ b/qtgui/resources/svg/clefBass_8.svg @@ -0,0 +1,61 @@ + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/clefPercussion.svg b/qtgui/resources/svg/clefPercussion.svg new file mode 100644 index 0000000..46de91a --- /dev/null +++ b/qtgui/resources/svg/clefPercussion.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/clefTreble.svg b/qtgui/resources/svg/clefTreble.svg new file mode 100644 index 0000000..e9fe9e9 --- /dev/null +++ b/qtgui/resources/svg/clefTreble.svg @@ -0,0 +1,56 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/clefTreble^8.svg b/qtgui/resources/svg/clefTreble^8.svg new file mode 100644 index 0000000..fce1c12 --- /dev/null +++ b/qtgui/resources/svg/clefTreble^8.svg @@ -0,0 +1,61 @@ + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/clefTreble_8.svg b/qtgui/resources/svg/clefTreble_8.svg new file mode 100644 index 0000000..ca7ff65 --- /dev/null +++ b/qtgui/resources/svg/clefTreble_8.svg @@ -0,0 +1,61 @@ + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/dot.svg b/qtgui/resources/svg/dot.svg new file mode 100644 index 0000000..66f7b18 --- /dev/null +++ b/qtgui/resources/svg/dot.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/flag128.svg b/qtgui/resources/svg/flag128.svg new file mode 100644 index 0000000..6894cd4 --- /dev/null +++ b/qtgui/resources/svg/flag128.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/flag128i.svg b/qtgui/resources/svg/flag128i.svg new file mode 100644 index 0000000..f9b908f --- /dev/null +++ b/qtgui/resources/svg/flag128i.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/flag16.svg b/qtgui/resources/svg/flag16.svg new file mode 100644 index 0000000..a9f653e --- /dev/null +++ b/qtgui/resources/svg/flag16.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/flag16i.svg b/qtgui/resources/svg/flag16i.svg new file mode 100644 index 0000000..b0d2c6c --- /dev/null +++ b/qtgui/resources/svg/flag16i.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/flag32.svg b/qtgui/resources/svg/flag32.svg new file mode 100644 index 0000000..0ab0f5d --- /dev/null +++ b/qtgui/resources/svg/flag32.svg @@ -0,0 +1,30 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/flag32i.svg b/qtgui/resources/svg/flag32i.svg new file mode 100644 index 0000000..43a9e88 --- /dev/null +++ b/qtgui/resources/svg/flag32i.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/flag64.svg b/qtgui/resources/svg/flag64.svg new file mode 100644 index 0000000..820feed --- /dev/null +++ b/qtgui/resources/svg/flag64.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/flag64i.svg b/qtgui/resources/svg/flag64i.svg new file mode 100644 index 0000000..8979860 --- /dev/null +++ b/qtgui/resources/svg/flag64i.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/flag8.svg b/qtgui/resources/svg/flag8.svg new file mode 100644 index 0000000..80684b2 --- /dev/null +++ b/qtgui/resources/svg/flag8.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/flag8i.svg b/qtgui/resources/svg/flag8i.svg new file mode 100644 index 0000000..68d2519 --- /dev/null +++ b/qtgui/resources/svg/flag8i.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/noteheadsBlack.svg b/qtgui/resources/svg/noteheadsBlack.svg new file mode 100644 index 0000000..3876d77 --- /dev/null +++ b/qtgui/resources/svg/noteheadsBlack.svg @@ -0,0 +1,56 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/noteheadsBrevis.svg b/qtgui/resources/svg/noteheadsBrevis.svg new file mode 100644 index 0000000..e56fb00 --- /dev/null +++ b/qtgui/resources/svg/noteheadsBrevis.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/noteheadsHalf.svg b/qtgui/resources/svg/noteheadsHalf.svg new file mode 100644 index 0000000..66fb5e8 --- /dev/null +++ b/qtgui/resources/svg/noteheadsHalf.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/noteheadsLonga.svg b/qtgui/resources/svg/noteheadsLonga.svg new file mode 100644 index 0000000..bc56415 --- /dev/null +++ b/qtgui/resources/svg/noteheadsLonga.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/noteheadsMaxima.svg b/qtgui/resources/svg/noteheadsMaxima.svg new file mode 100644 index 0000000..ebe3bbf --- /dev/null +++ b/qtgui/resources/svg/noteheadsMaxima.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/noteheadsWhole.svg b/qtgui/resources/svg/noteheadsWhole.svg new file mode 100644 index 0000000..51632b5 --- /dev/null +++ b/qtgui/resources/svg/noteheadsWhole.svg @@ -0,0 +1,56 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/numbers.svg b/qtgui/resources/svg/numbers.svg new file mode 100644 index 0000000..06787fe --- /dev/null +++ b/qtgui/resources/svg/numbers.svg @@ -0,0 +1,82 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/qtgui/resources/svg/rest1.svg b/qtgui/resources/svg/rest1.svg new file mode 100644 index 0000000..3dfaf3f --- /dev/null +++ b/qtgui/resources/svg/rest1.svg @@ -0,0 +1,56 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/rest128.svg b/qtgui/resources/svg/rest128.svg new file mode 100644 index 0000000..6018bd0 --- /dev/null +++ b/qtgui/resources/svg/rest128.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/rest16.svg b/qtgui/resources/svg/rest16.svg new file mode 100644 index 0000000..803bbac --- /dev/null +++ b/qtgui/resources/svg/rest16.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/rest2.svg b/qtgui/resources/svg/rest2.svg new file mode 100644 index 0000000..4c8105e --- /dev/null +++ b/qtgui/resources/svg/rest2.svg @@ -0,0 +1,56 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/rest32.svg b/qtgui/resources/svg/rest32.svg new file mode 100644 index 0000000..35190f7 --- /dev/null +++ b/qtgui/resources/svg/rest32.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/rest4.svg b/qtgui/resources/svg/rest4.svg new file mode 100644 index 0000000..17e49d1 --- /dev/null +++ b/qtgui/resources/svg/rest4.svg @@ -0,0 +1,56 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/rest64.svg b/qtgui/resources/svg/rest64.svg new file mode 100644 index 0000000..56dc515 --- /dev/null +++ b/qtgui/resources/svg/rest64.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/rest8.svg b/qtgui/resources/svg/rest8.svg new file mode 100644 index 0000000..cac493f --- /dev/null +++ b/qtgui/resources/svg/rest8.svg @@ -0,0 +1,56 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/restBrevis.svg b/qtgui/resources/svg/restBrevis.svg new file mode 100644 index 0000000..5c0c958 --- /dev/null +++ b/qtgui/resources/svg/restBrevis.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/restLonga.svg b/qtgui/resources/svg/restLonga.svg new file mode 100644 index 0000000..9e65444 --- /dev/null +++ b/qtgui/resources/svg/restLonga.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/restMaxima.svg b/qtgui/resources/svg/restMaxima.svg new file mode 100644 index 0000000..f7e00d7 --- /dev/null +++ b/qtgui/resources/svg/restMaxima.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/qtgui/resources/svg/scriptsStaccato.svg b/qtgui/resources/svg/scriptsStaccato.svg new file mode 100644 index 0000000..bec9bc7 --- /dev/null +++ b/qtgui/resources/svg/scriptsStaccato.svg @@ -0,0 +1,31 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/qtgui/resources/svg/svg.license.txt b/qtgui/resources/svg/svg.license.txt new file mode 100644 index 0000000..caead9e --- /dev/null +++ b/qtgui/resources/svg/svg.license.txt @@ -0,0 +1,678 @@ +Laborejos Notation Glyphs are based on Lilypond - Lilypond Team, GPLv3, http://lilypond.org/ + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + + diff --git a/qtgui/resources/translations/config.pro b/qtgui/resources/translations/config.pro new file mode 100644 index 0000000..3eb110d --- /dev/null +++ b/qtgui/resources/translations/config.pro @@ -0,0 +1,2 @@ +SOURCES = ../../mainwindow.py ../../designer/mainwindow.py +TRANSLATIONS = de.ts diff --git a/qtgui/resources/translations/de.qm b/qtgui/resources/translations/de.qm new file mode 100644 index 0000000000000000000000000000000000000000..e629db0eabfbc7da5924049b307e36fa20b9f606 GIT binary patch literal 425 zcmZ8du};G<5WRpXotYRIjvvSuuuv&N-H=*|6*qC*Qxn@t9JSdP`2jW-c0Pawu_N&b zY~A?Eed%>wy0bs6U{NpX)z z)GjfRg@(YNW5RJ7KWKupT&|^OY-L&RRO=hf%KJu26~x(`i(SyRVhJ1^k8bF=k&RfB i^CGA&@M>gTNq~n-XKOLJA5S5Ca=mgx$R6=L%CcX+!C*uH literal 0 HcmV?d00001 diff --git a/qtgui/resources/translations/de.ts b/qtgui/resources/translations/de.ts new file mode 100644 index 0000000..b1068da --- /dev/null +++ b/qtgui/resources/translations/de.ts @@ -0,0 +1,11 @@ + + + + About + + + This is an example application. Extend it to your liking. Start by editing config.py + Willkommen im Beispielprogramm. Erstellen Sie neue Programme auf dieser Grundlage wie es Ihnen gefällt. Ein guter Einstieg wäre config.py + + + diff --git a/qtgui/resources/translations/update.sh b/qtgui/resources/translations/update.sh new file mode 100644 index 0000000..c166f03 --- /dev/null +++ b/qtgui/resources/translations/update.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +set -e +pylupdate5 config.pro +echo "linguist-qt5 de.ts" diff --git a/qtgui/scoreview.py b/qtgui/scoreview.py new file mode 100644 index 0000000..1cc58e3 --- /dev/null +++ b/qtgui/scoreview.py @@ -0,0 +1,253 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2018, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), +more specifically its template base application. + +The Template Base Application 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 . +""" + + + +#Third Party +from PyQt5 import QtCore, QtGui, QtWidgets +#from PyQt5 import QtOpenGL + +#Template Modules +from template.helper import onlyOne + +#Our Modules + +from .constantsAndConfigs import constantsAndConfigs +from .structures import GuiScore +import engine.api as api + +class ScoreView(QtWidgets.QGraphicsView): + def __init__(self, mainWindow): + super().__init__() + self.mainWindow = mainWindow + + + #TODO: Measure OpenGL performance impact. Make sure fallback works + """ + viewport = QtOpenGL.QGLWidget(QtOpenGL.QGLFormat(QtOpenGL.QGL.SampleBuffers)) + viewport.format().setSwapInterval(0) #disable VSync. + viewport.setAutoFillBackground(False) + + viewport = QtWidgets.QOpenGLWidget() + viewportFormat = QtGui.QSurfaceFormat() + viewportFormat.setSwapInterval(0) #disable VSync + viewportFormat.setSamples(2**8) + viewportFormat.setDefaultFormat(viewportFormat) + viewport.setFormat(viewportFormat) + self.setViewport(viewport) + """ + + self.setAlignment(QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) + #self.setDragMode(QtWidgets.QGraphicsView.RubberBandDrag) + self.setDragMode(QtWidgets.QGraphicsView.NoDrag) + + self.scoreScene = GuiScore(self) + self.setScene(self.scoreScene) + + api.callbacks.setCursor.append(self.centerOnCursor) #returns a dict + api.callbacks.updateBlockTrack.append(self.updateMode) # We need this after every update because the track is redrawn after each update and we don't know what to show + + self.xFactor = 1 #keep track of the x stretch factor. + + style = """ + QScrollBar:horizontal { + border: 1px solid black; + } + + QScrollBar::handle:horizontal { + background: #00b2b2; + } + + QScrollBar:vertical { + border: 1px solid black; + } + + QScrollBar::handle:vertical { + background: #00b2b2; + } + """ + self.setStyleSheet(style) + + self._zoom() #no parameters, uses config values + + def resizeEvent(self, event): + self.scoreScene.grid.reactToresizeEventOrZoom() + super().resizeEvent(event) + + def changeGridRhythm(self): + GridRhytmEdit(mainWindow=self.mainWindow) #handles everything. + + def centerOnCursor(self, cursorExportObject): + if (not constantsAndConfigs.followPlayhead) or not api.playbackStatus(): + self.centerOn(self.scoreScene.cursor.scenePos()) + #discard cursorExportObject. + + def wheelEvent(self, ev): + modifiers = QtWidgets.QApplication.keyboardModifiers() + if modifiers == QtCore.Qt.ControlModifier: + if ev.angleDelta().y() > 0: + self.widen() + else: + self.shrinken() + ev.accept() + + elif modifiers == QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier: + if ev.angleDelta().y() > 0: + self.zoomIn() + else: + self.zoomOut() + ev.accept() + else: + super().wheelEvent(ev) #send to the items + + def _zoom(self): + api.session.guiSharedDataToSave["zoom_factor"] = constantsAndConfigs.zoomFactor + self.resetTransform() + self.scoreScene.grid.setVisible(constantsAndConfigs.zoomFactor >= 1) + self.scale(constantsAndConfigs.zoomFactor, constantsAndConfigs.zoomFactor) + self.centerOnCursor(None) + + def zoomIn(self): + constantsAndConfigs.zoomFactor = round(constantsAndConfigs.zoomFactor + 0.25, 2) + if constantsAndConfigs.zoomFactor > 2.5: + constantsAndConfigs.zoomFactor = 2.5 + self._zoom() + return True + + def zoomOut(self): + constantsAndConfigs.zoomFactor = round(constantsAndConfigs.zoomFactor - 0.25, 2) + if constantsAndConfigs.zoomFactor < constantsAndConfigs.maximumZoomOut: + constantsAndConfigs.zoomFactor = constantsAndConfigs.maximumZoomOut + self._zoom() + return True + + def zoomNull(self): + constantsAndConfigs.zoomFactor = 1 + self._zoom() + + def _stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from here. + + The parent sets the X coordinates of its children. + Then the parent calls the childs _stretchXCoordinates() method if the child has children + itself. For example a rectangleItem has a position which is set by the parent. But the + rectangleItem has a right border which needs to be adjusted as well. This right border is + treated as child of the rectItem, handled by rectItem._stretchXCoordinates(factor). + """ + self.xFactor *= factor + constantsAndConfigs.ticksToPixelRatio /= factor + api.session.guiSharedDataToSave["ticks_to_pixel_ratio"] = constantsAndConfigs.ticksToPixelRatio + self.scoreScene.stretchXCoordinates(factor) + self.centerOnCursor(None) + return True + + def widen(self): + self._stretchXCoordinates(1*1.2) #2 is also good + + def shrinken(self): + self._stretchXCoordinates(1/1.2) #0.5 is also good + + def toggleNoteheadsRectangles(self): + """Each notehead/rectangle toggles its own state. + That means each GuiChord gets toggled individually. + Both versions, notehead and rectangle, exist all the time, so + nothing gets recreated, just visibility toggled. + + Rectangles/Noteheads are their own realm and do not conflict + with CC View toggle or other view modes.""" + + constantsAndConfigs.noteHeadMode = not constantsAndConfigs.noteHeadMode + self.mainWindow.ui.actionToggle_Notehead_Rectangles.setChecked(not constantsAndConfigs.noteHeadMode) + self.scoreScene.toggleNoteheadsRectangles() + + def _switchToRectanglesForFunction(self, function): + """some actions like actionVelocityMore, actionVelocityLess, + actionDurationModMore, actionDurationModLess, + actionReset_Velocity_Duration_Mod can be called even if + not in rectangle mode. We switch into rectangle mode for them + so the user can see the changes.""" + if not self.mainWindow.ui.actionToggle_Notehead_Rectangles.isChecked(): + self.toggleNoteheadsRectangles() + function() #this is most likely an api function + + def toggleFollowPlayhead(self): + constantsAndConfigs.followPlayhead = not constantsAndConfigs.followPlayhead + self.mainWindow.ui.actionFollow_Playhead.setChecked(constantsAndConfigs.followPlayhead) + #we register a callback in self init that checks constantsAndConfigs.followPlayhead + + def mode(self): + """Return the current edit mode as string. + Mostly needed for structures blockAt and other + functions that need to find the target of a mouse click.""" + if self.mainWindow.ui.actionCC_Mode.isChecked(): + return "cc" + elif self.mainWindow.ui.actionNotation_Mode.isChecked(): + return "notation" + elif self.mainWindow.ui.actionBlock_Mode.isChecked(): + return "block" + else: + raise ValueError("Edit Mode unknown") + + def updateMode(self, *args): + """Switch through different views for editing: + notes and item edit + CC curves + note-blocks only (without items) + + Which mode is active depends entirely on the state of qt checkboxes in the menu. + The menu-actions call this function. We make sure and double sure that there is never + ambiguity in the menu or in the program mode itself. + + If you want to check for the mode in any place of the program use self.mode(). + It is just above this function. + + Therefore: Every mode switch is only allowed through this function. + There is no direct setting of the mode. You should call the menu + action directly if you want to programatically change the mode. + """ + + assert onlyOne((self.mainWindow.ui.actionCC_Mode.isChecked(), self.mainWindow.ui.actionNotation_Mode.isChecked(), self.mainWindow.ui.actionBlock_Mode.isChecked())) + + if self.mainWindow.ui.actionData_Editor.isChecked(): + #no modechange in the track editor + return + + if self.mainWindow.ui.actionCC_Mode.isChecked(): + self.mainWindow.menuActionDatabase.ccEditMode() + self.mainWindow.menuActionDatabase.writeProtection(True) + self.scoreScene.updateMode("cc") + self.mainWindow.menuActionDatabase.loadToolbarContext("cc") + + elif self.mainWindow.ui.actionNotation_Mode.isChecked(): + self.mainWindow.menuActionDatabase.noteEditMode() + self.mainWindow.menuActionDatabase.writeProtection(False) + self.scoreScene.updateMode("notation") + self.mainWindow.menuActionDatabase.loadToolbarContext("notation") + + elif self.mainWindow.ui.actionBlock_Mode.isChecked(): + self.mainWindow.menuActionDatabase.noteEditMode() + self.mainWindow.menuActionDatabase.writeProtection(True) + self.scoreScene.updateMode("block") + self.mainWindow.menuActionDatabase.loadToolbarContext("block") + else: + raise ValueError("Edit Mode unknown") diff --git a/qtgui/structures.py b/qtgui/structures.py new file mode 100644 index 0000000..269f6b0 --- /dev/null +++ b/qtgui/structures.py @@ -0,0 +1,1214 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from math import log +from PyQt5 import QtCore, QtGui, QtWidgets + +from .items import staticItem2Item, GuiTieCurveGraphicsItem, GuiLiveNote +from .constantsAndConfigs import constantsAndConfigs +from .cursor import Cursor, Playhead, Selection +from .conductor import Conductor, ConductorTransparentBlock +from .graphs import CCGraphTransparentBlock +from template.qtgui.helper import stretchLine, stretchRect, callContextMenu, removeInstancesFromScene +from .submenus import BlockPropertiesEdit +from . import graphs +from hashlib import md5 #string to color +import engine.api as api + +oneRectToReturnThemAll = QtCore.QRectF(0,0,0,0) #prevent the annoying "NotImplementError" from Qt for boundingRect. #TODO: implement in each class for realsies +cosmeticPen = QtGui.QPen() +cosmeticPen.setCosmetic(True) + + +class GuiBlockHandle(QtWidgets.QGraphicsRectItem): + """A simplified version of a Block. Since we don't use blocks in the GUI, only in the backend + we still need them sometimes as macro strutures, where we don't care about the content. + This is the transparent Block handle that appears when the user uses the mouse to drag and drop + a block with shift + middle mouse button. + + It is visible all the time though and can be clicked on. In opposite to the background color, + which is just a color and stays in place. + """ + def __init__(self, parent, staticExportItem, x, y, w, h): + super().__init__(x, y, w, h) + self.parent = parent #GuiTrack instance + self.color = None #inserted by the creating function in GuiTrack + self.trans = QtGui.QColor("transparent") + self.setPen(self.trans) + self.setBrush(self.trans) + self.setOpacity(0.4) #slightly fuller than background + self.setFlag(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + self.setParentItem(parent) + self.setZValue(10) #This is the z value within GuiTrack + self.staticExportItem = staticExportItem + + self.posBeforeMove = None + self.cursorPosOnMoveStart = None + + #Display Block ID + """ + self.idText = QtWidgets.QGraphicsSimpleTextItem(str(self.staticExportItem["id"])) + self.idText.setParentItem(self) + self.idText.setPos(0, constantsAndConfigs.stafflineGap) + #self.idText.setScale(4) + self.idText.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + """ + + if self.staticExportItem["completeDuration"] >= api.D1: #cosmetics + self.startLabel = QtWidgets.QGraphicsSimpleTextItem(self.staticExportItem["name"] + " start") + self.startLabel.setParentItem(self) + self.startLabel.setPos(0, constantsAndConfigs.stafflineGap) + self.startLabel.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + + self.endLabel = QtWidgets.QGraphicsSimpleTextItem(self.staticExportItem["name"] + " end ") + self.endLabel.setParentItem(self) + self.endLabel.setPos(self.rect().width() - self.endLabel.boundingRect().width(), constantsAndConfigs.stafflineGap) + self.endLabel.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + else: + self.startLabel = QtWidgets.QGraphicsSimpleTextItem("") + self.endLabel = QtWidgets.QGraphicsSimpleTextItem("") + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + stretchRect(self, factor) + self.endLabel.setPos(self.rect().width() - self.endLabel.boundingRect().width(), constantsAndConfigs.stafflineGap) + + def blockMode(self): + self.startLabel.show() + self.endLabel.show() + + def itemMode(self): + self.startLabel.hide() + self.endLabel.hide() + + def mouseMoveEventCustom(self, event): + # All the positions below don't work. They work fine when dragging Tracks around but not this Item. I can't be bothered to figure out why. + #scenePos() results ins an item position that is translated down and right. The higher the x/y value the more the offset + #Instead we calculate our delta ourselves. + + #self.setPos(self.mapToItem(self, event.scenePos())) + #self.setPos(self.mapFromScene(event.scenePos())) + #posGlobal = QtGui.QCursor.pos() + #posView = self.parent.parentScore.parentView.mapFromGlobal(posGlobal) #a widget + #posScene = self.parent.parentScore.parentView.mapToScene(posView) + #print (posGlobal, posView, posScene, event.scenePos()) + + """ + #Does not work with zooming. + if self.cursorPosOnMoveStart: + delta = QtGui.QCursor.pos() - self.cursorPosOnMoveStart + new = self.posBeforeMove + delta + self.setPos(new) + """ + if self.cursorPosOnMoveStart: + self.setPos(event.scenePos()) + super().mouseMoveEvent(event) + + def mousePressEventCustom(self, event): + self.posBeforeMove = self.pos() + self.cursorPosOnMoveStart = QtGui.QCursor.pos() + self.setBrush(self.color) + super().mousePressEvent(event) + + def mouseReleaseEventCustom(self, event): + self.setBrush(self.trans) + self.setPos(self.posBeforeMove) #In case the block was moved to a position where no track is (below the tracks) we just reset the graphics. + self.posBeforeMove = None + self.cursorPosOnMoveStart = None + super().mouseReleaseEvent(event) + + def contextMenuEvent(self, event): + if self.startLabel.isVisible(): + listOfLabelsAndFunctions = [ + ("edit properties", lambda: BlockPropertiesEdit(self.scene().parentView.mainWindow, staticExportItem = self.staticExportItem)), + ("separator", None), + #("split here", lambda: self.splitHere(event)), + ("duplicate", lambda: api.duplicateBlock(self.staticExportItem["id"])), + ("create content link", lambda: api.duplicateContentLinkBlock(self.staticExportItem["id"])), + ("unlink", lambda: api.unlinkBlock(self.staticExportItem["id"])), + ("separator", None), + ("join with next block", lambda: api.joinBlockWithNext(self.staticExportItem["id"])), + ("delete block", lambda: api.deleteBlock(self.staticExportItem["id"])), + ("separator", None), + ("append block at the end", lambda: api.appendBlock(self.parent.staticExportItem["id"])), + ] + callContextMenu(listOfLabelsAndFunctions) + else: + super().contextMenuEvent(event) + +class GuiTrack(QtWidgets.QGraphicsItem): + """In opposite to tracks and block(backgrounds and handles) tracks never get recreated. + Init is called once on creation, not virtually on every update. + However, the track children, its parts, get deleted and recreated very often. + + + Order of creation: + init + stafflines + second init + update edit mode + -> then api takes over and instructs the following methods through callbacks + + Typical order of method calls for updates: + barlines + beams + stafflines + items + redraw + background color + update edit mode (not on every item update, but at least on load) + """ + + def __init__(self, parentScore, staticExportItem): + super().__init__() + self.parentScore = parentScore + self.staticExportItem = staticExportItem #This is not the notes but the track meta data. The notes are called staticRepresentationList + self.items = [] #this is used for stretching and processing of the current items. scene clear is done diffently. See self.createGraphicItemsFromData + self.barLines = [] + self.beams = [] + self.staffLines = [] + self.staticItems = [] #not deleted automatically by callbacks. + self.ItemIgnoresTransformations = [] #not literally colors. QRectItems with a color. created in self.paintBlockBackgroundColors() + self.transparentBlockHandles = [] #list of GuiBlockHandle in order. Only appear when the mouse is used to drag and drop. + self.backgroundBlockColors = [] #QGraphicsRectItems. Always visible. + self.lengthInPixel = 0 # a cached value + self.createStaffLines() #no stafflines at all are too confusing. + self.ccPaths = {} # ccNumber0-127:PathItem. Empty for a new track. We only create ccPaths with the first ccBlock. Creation and handling is done in GuiScore, starting with syncCCsToBackend. + + self.nameGraphic = self.NameGraphic(self.staticExportItem["name"], parent = self) + self.staticItems.append(self.nameGraphic) + + + + #Add one central "Create new CC Path" button which is for all non-existing CC Paths of this track and reacte to the current constantsAndConfig.ccValue + #This button is not in the CCPath object because those only get created for existing backend-CCs. + self.universalCreateFirstCCBlock = QtWidgets.QGraphicsSimpleTextItem("Create CC Path") + self.universalCreateFirstCCBlock.setFlag(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) #toggle between edit modes not only hides stuff but the track itself gets 10% opacity. We want to avoid it for this item. + self.universalCreateFirstCCBlock.mousePressEvent = lambda mouseEvent: api.newGraphTrackCC(trId = self.staticExportItem["id"], cc = constantsAndConfigs.ccViewValue) #trigger callback to self.syncCCsToBackend + self.universalCreateFirstCCBlock.setParentItem(self) + self.universalCreateFirstCCBlock.setPos(0,0) #for now. Afterwards it gets updated by updateBlocks . + self.universalCreateFirstCCBlock.setZValue(10) + + #self.secondStageInitNowThatWeHaveAScene gets called by the ScoreScene.redraw(), where new tracks get created. After it was inserted into the scene. + + class NameGraphic(QtWidgets.QGraphicsSimpleTextItem): + def __init__(self, text, parent): + super().__init__(text) + self.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + self.parent = parent + self.setParentItem(parent) + + def _editName(self): + result = QtWidgets.QInputDialog.getText(self.scene().parentView, "Track Name", #dialog title + "Set Track Name for {}".format(self.parent.staticExportItem["id"]), #label + QtWidgets.QLineEdit.Normal, + self.parent.staticExportItem["name"] + ) + if result[1]: + api.setTrackName(self.parent.staticExportItem["id"], nameString = result[0], initialInstrumentName = self.parent.staticExportItem["initialInstrumentName"], initialShortInstrumentName = self.parent.staticExportItem["initialShortInstrumentName"]) #keep the old lilypond names + + def contextMenuEvent(self, event): + listOfLabelsAndFunctions = [ ("edit name", self._editName), ] + callContextMenu(listOfLabelsAndFunctions) + event.accept() + + def paint(self, *args): + pass + + def boundingRect(self, *args): + return oneRectToReturnThemAll + + def secondStageInitNowThatWeHaveAScene(self): + """ScoreScene.redraw() calls this after the track was inserted into the scene and therefore + has a position, opacity, parent item etc. (All of that is not read in normal __init__)""" + pass + + def toggleNoteheadsRectangles(self): + for item in self.items: + item.updateVisibility() + for beam in self.beams: + beam.rectangle.setVisible(constantsAndConfigs.noteHeadMode) + + def redraw(self, staticRepresentationList): + self.createGraphicItemsFromData(staticRepresentationList) + self.nameGraphic.setPos(30 + self.lengthInPixel, -1*constantsAndConfigs.stafflineGap) #self.lengthInPixel is now up to date + + def paintBlockBackgroundColors(self, staticBlocksRepresentation): + """This gets not called by self.createGraphicItemsFromData but only by + a score callback for blocksChanged""" + for bg in self.backgroundBlockColors: + self.parentScore.removeWhenIdle(bg) + for th in self.transparentBlockHandles: + self.parentScore.removeWhenIdle(th) + self.backgroundBlockColors = [] + self.transparentBlockHandles = [] + + for block in staticBlocksRepresentation: + if self.staticExportItem["double"]: #double track, twice as high + h = 10 * constantsAndConfigs.stafflineGap + else: + h = 4 * constantsAndConfigs.stafflineGap + bgItem = QtWidgets.QGraphicsRectItem(0, 0, block["completeDuration"] / constantsAndConfigs.ticksToPixelRatio, h) #x, y, w, h + bgItem.setFlag(QtWidgets.QGraphicsItem.ItemIgnoresParentOpacity) + bgItem.setPen(QtGui.QColor("transparent")) + color = self.stringToColor(block["name"]) + bgItem.setBrush(color) + bgItem.setParentItem(self) + self.backgroundBlockColors.append(bgItem) + bgItem.setPos(block["tickindex"] / constantsAndConfigs.ticksToPixelRatio, -2*constantsAndConfigs.stafflineGap) + bgItem.setZValue(-10) #This is the z value within GuiTrack + bgItem.setEnabled(False) + + transparentBlockHandle = GuiBlockHandle(self, block, 0, -2 * constantsAndConfigs.stafflineGap, block["completeDuration"] / constantsAndConfigs.ticksToPixelRatio, h + 4 * constantsAndConfigs.stafflineGap) #x, y, w, h + transparentBlockHandle.color = color + self.transparentBlockHandles.append(transparentBlockHandle) + transparentBlockHandle.setPos(block["tickindex"] / constantsAndConfigs.ticksToPixelRatio, -2*constantsAndConfigs.stafflineGap) + + def createStaffLines(self, lengthInPixel = 0): + """By default creates 5 stafflines. But it can be 10; + 5 extra below the origin-staff. + This is NOT a double-system like a piano but just a staff + with more lines that happens to have the range of e.g. + treble + bass clef.""" + + def createLine(yOffset): + line = QtWidgets.QGraphicsLineItem(QtCore.QLineF(0, 0, lengthInPixel, 0)) + line.setParentItem(self) + line.setPen(cosmeticPen) + self.staffLines.append(line) + line.setPos(0, yOffset*constantsAndConfigs.stafflineGap) + line.setZValue(-5) #This is the z value within GuiTrack + + for l in self.staffLines: + self.parentScore.removeWhenIdle(l) + self.staffLines = [] + lengthInPixel += 25 #a bonus that gives the hint that you can write after the last object. + + for i in range(-2, 3): #the normal 5 line system. We have a lower and upper range/position. The middle line is at position 0 + createLine(i) + + if self.staticExportItem["double"]: #add more stuffs below (user-perspective. positive Qt values) + for i in range(4, 9): #i is now 3. Make a gap: + createLine(i) + + def createBarlines(self, barlinesTickList): + """and measure numbers""" + for bl in self.barLines: + self.parentScore.removeWhenIdle(bl) + self.barLines = [] + + if self.staticExportItem["double"]: + h = 10 * constantsAndConfigs.stafflineGap + else: + h = 4 * constantsAndConfigs.stafflineGap + + #if barlinesTickList[0] == 0: #happens when there is a metrical instruction at tick 0. + # del barlinesTickList[0] + + last = None + offset = 0 + for barnumber, barlineTick in enumerate(barlinesTickList): + if barlineTick == last: + offset += 1 + continue #don't draw the double barline + last = barlineTick + line = QtWidgets.QGraphicsLineItem(QtCore.QLineF(0, 0, 0, h)) + line.setParentItem(self) + self.barLines.append(line) + line.setPos(barlineTick / constantsAndConfigs.ticksToPixelRatio, -2*constantsAndConfigs.stafflineGap) + + number = QtWidgets.QGraphicsSimpleTextItem(str(barnumber+1-offset)) + number.setScale(0.75) + number.setParentItem(line) + number.setPos(-2, -3*constantsAndConfigs.stafflineGap) #-2 on X for a little fine tuning. + + + + def createBeams(self, beamList): + for b in self.beams: + self.parentScore.removeWhenIdle(b) + self.beams = [] + + for startTick, endTick, beamtype, positionAsStaffline, direction in beamList: + numberOfBeams = int(log(beamtype, 2)-2) + assert numberOfBeams == log(beamtype, 2)-2 + for x in range(numberOfBeams): + + if direction > 0: #stem/beam upwards + beamNumberOffset = 4*x + xOffset = 7 + else: + beamNumberOffset = -4*x + xOffset = 1 + + + #non-scalable X-Offsets are not possible via setPos. zoom and stretch go haywire. + #Instead we use one item for strechting and for the offset position and wrap it in an item group that is used for positioing. + shifterAnchor = QtWidgets.QGraphicsItemGroup() + shifterAnchor.setParentItem(self) + + rectangle = QtWidgets.QGraphicsRectItem(0, 0, (endTick-startTick) / constantsAndConfigs.ticksToPixelRatio, constantsAndConfigs.beamHeight) #x, y, w, h + rectangle.setBrush(QtGui.QColor("black")) + + shifterAnchor.addToGroup(rectangle) + shifterAnchor.rectangle = rectangle + rectangle.setPos(xOffset, 0) + + if constantsAndConfigs.noteHeadMode: + rectangle.show() + else: + rectangle.hide() + + self.beams.append(shifterAnchor) + + x = startTick/ constantsAndConfigs.ticksToPixelRatio + y = beamNumberOffset + positionAsStaffline * constantsAndConfigs.stafflineGap / 2 - 1 + shifterAnchor.setPos(x, y) + + class TrackAnchor(QtWidgets.QGraphicsItem): + """Handling all items as individuals when deleting a track to redraw it is too much. + Better let Qt handle it all at once.""" + oneRectToReturnThemAll = QtCore.QRectF(0,0,0,0) #prevent the annoying "NotImplementError" from Qt for boundingRect. For items that don't need any collision detection. + def __init__(self, parent): + super().__init__() + self.parent = parent + def paint(self, *args): + pass + def boundingRect(self, *args): + return oneRectToReturnThemAll + + def createGraphicItemsFromData(self, staticRepresentationList): + """Create staff objects including simple barlines""" + self.parentScore.cursor.clearItemHighlight() #or else the current highlight gets deleted while it is on an item + try: + self.parentScore.removeWhenIdle(self.anchor) + except AttributeError: #first round + pass + self.items = [] + itemsAppend = self.items.append + + self.anchor = GuiTrack.TrackAnchor(self) + self.anchor.setParentItem(self) + + metaDataDict = staticRepresentationList.pop() + for staticItem in staticRepresentationList: + item = staticItem2Item(staticItem) + item.setParentItem(self.anchor) + itemsAppend(item) + item.setPos(item.pixelPosition, 0) # Y axis is set by the position of the track. This sets the position of the whole ItemGroup. The actual pitch of a chord/note is set locally by the chord itself and of no concern here. + item.setZValue(5) #This is the z value within GuiTrack + + self.lengthInPixel = metaDataDict["duration"] / constantsAndConfigs.ticksToPixelRatio #this gets updated in stretchXCoordinates + self.createBarlines(metaDataDict["barlines"]) + self.createBeams(metaDataDict["beams"]) + self.createStaffLines(self.lengthInPixel) + + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + #The rects and lines here are just a QGraphicsRectItem and have no custom subclass. So they have no stretchXCoordinates itself. + for item in self.items: + item.setX(item.pos().x() * factor) + item.stretchXCoordinates(factor) + + for staticItem in self.staticItems: #labels etc. + staticItem.setX(staticItem.pos().x() * factor) + + for barline in self.barLines: + barline.setX(barline.pos().x() * factor) + + for staffline in self.staffLines: #stafflines start from x=0. 0*factor=0 so we omit setPos + stretchLine(staffline, factor) + + for beam in self.beams: #beams are part of the track, not of the note items. + beam.setX(beam.pos().x() * factor ) + stretchRect(beam.rectangle, factor) + + for backgroundBlockColor in self.backgroundBlockColors: + backgroundBlockColor.setX(backgroundBlockColor.pos().x() * factor) + stretchRect(backgroundBlockColor, factor) + + for transparentBlockHandle in self.transparentBlockHandles: + transparentBlockHandle.setX(transparentBlockHandle.pos().x() * factor) + transparentBlockHandle.stretchXCoordinates(factor) + + for ccPath in self.ccPaths.values(): + ccPath.stretchXCoordinates(factor) + + self.lengthInPixel = self.lengthInPixel * factor #this also gets updated in createGraphicItemsFromData + + def itemById(self, itemId): + """The itemId is the same for backend and gui items. In fact, it is really the + backend-python-object id. But we exported it as static value.""" + return next(item for item in self.items if item.staticItem["id"] == itemId) + + def blockAt(self, xScenePosition): + for th in self.transparentBlockHandles: + start = th.staticExportItem["tickindex"] / constantsAndConfigs.ticksToPixelRatio + end = start + th.staticExportItem["completeDuration"] / constantsAndConfigs.ticksToPixelRatio + if start <= xScenePosition < end: + return th + return None #After the last block. + + def stringToColor(self, st): + """Convert a string to QColor. Same string, same color + Is used for track coloring""" + if st: + c = md5(st.encode()).hexdigest() + return QtGui.QColor(int(c[0:9],16) % 255, int(c[10:19],16) % 255, int(c[20:29],16)% 255, 255) + else: + return QtGui.QColor(255,255,255,255) #Return White + + def updateMode(self, nameAsString): + """Modes are opacity based, not show and hide. + This gives us the option that children can ignore the opacity (via qt-flag). + For example we need the block backgrounds to stay visible. + """ + assert nameAsString in constantsAndConfigs.availableEditModes + + #We always hide all CC paths and reactivate only a specific one in cc mode later. + for ccPath in self.ccPaths.values(): + ccPath.hide() + self.universalCreateFirstCCBlock.hide() + + if nameAsString == "notation": + self.setOpacity(1) + for backgroundColor in self.backgroundBlockColors: #created in self.paintBlockBackgroundColors() + backgroundColor.setOpacity(0.2) + for tbh in self.transparentBlockHandles: + tbh.itemMode() + + elif nameAsString == "cc": + self.setOpacity(0.1) #the notes can still be seen in the background. + if constantsAndConfigs.ccViewValue in self.ccPaths: #It is not guaranteed that all CC Values have content. On the contrary... + self.ccPaths[constantsAndConfigs.ccViewValue].show() + else: + self.universalCreateFirstCCBlock.show() + for backgroundColor in self.backgroundBlockColors: #created in self.paintBlockBackgroundColors() + backgroundColor.setOpacity(0.2) + for tbh in self.transparentBlockHandles: + tbh.itemMode() + + elif nameAsString == "block": + self.setOpacity(0) + for backgroundColor in self.backgroundBlockColors: #simple QRectItems, they don't have their own updateMode function + backgroundColor.setOpacity(1) + for tbh in self.transparentBlockHandles: + tbh.blockMode() + def recordingStreamNoteOn(self, liveNoteData): + guiLiveNote = GuiLiveNote(parent=self, liveNoteData=liveNoteData) + guiLiveNote.setX(liveNoteData["tickindex"] / constantsAndConfigs.ticksToPixelRatio) + self.parentScore.liveMidiWaitingForNoteOff[liveNoteData["midipitch"]] = guiLiveNote + + def recordingStreamNoteOff(self, liveNoteData): + guiLiveNote = self.parentScore.liveMidiWaitingForNoteOff[liveNoteData["midipitch"]] + guiLiveNote.update(liveNoteData["duration"]) + del self.parentScore.liveMidiWaitingForNoteOff[liveNoteData["midipitch"]] + + +class GuiScore(QtWidgets.QGraphicsScene): + def __init__(self, parentView): + super().__init__() + self.parentView = parentView + self.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex) + + self.tracks = {} #trackId:guiTrack, #if we don't save the instances here in Python space Qt will loose them and they will not be displayed without any error message. + + self.deleteOnIdleStack = [] # a stack that holds hidden items that need to be deleted. Hiding is much faster than deleting so we use that for the blocking function. Since we always recreate items and never re-use this is ok as a list. no need for a set. + self._deleteOnIdleLoop = QtCore.QTimer() + self._deleteOnIdleLoop.start(0) #0 means "if there is time" + self._deleteOnIdleLoop.timeout.connect(self._deleteOnIdle) #processes deleteOnIdleStack + + self.liveMidiWaitingForNoteOff = {} #all unfinished midi notes (key is currently held down). We use one for all tracks because we have a callback in the cursor update function that iterates over all live notes. We don't want that to iterate over all tracks just to find the current live notes. + + self.duringTrackDragAndDrop = None #switched to a QGraphicsItem (e.g. GuiTrack) while a track is moved around by the mouse + self.duringBlockDragAndDrop = None #switched to a QGraphicsItem (e.g. GuiTrack) while a block is moved around by the mouse + + self.conductor = Conductor(parentView = self.parentView) + self.addItem(self.conductor) + self.conductor.setPos(0, -1 * self.conductor.totalHeight) + + self.yStart = self.conductor.y() - self.conductor.totalHeight/2 + + self.hiddenTrackCounter = QtWidgets.QGraphicsSimpleTextItem("") #filled in by self.redraw on callback tracksChanged (loading or toggling visibility of backend tracks) + self.addItem(self.hiddenTrackCounter) + + self.backColor = QtGui.QColor() + self.backColor.setNamedColor("#fdfdff") + self.setBackgroundBrush(self.backColor) + + self.grid = GuiGrid(parent=self) + self.addItem(self.grid) + self.grid.setPos(0, -20 * constantsAndConfigs.stafflineGap) #this is more calculation than simply using self.yStart, and might require manual adjustment in the future, but at least it guarantees the grid matches the staffline positions + self.grid.setZValue(-50) + + self.cachedSceneHeight = 0 #set in self.redraw. Used by updateTrack to set the sceneRect + + #All Cursors + self.cursor = Cursor() + self.addItem(self.cursor) + self.selection = Selection() + self.addItem(self.selection) + self.playhead = Playhead(self) + self.addItem(self.playhead) + self.playhead.setY(self.yStart) + + #Callbacks + api.callbacks.tracksChanged.append(self.redraw) + api.callbacks.updateTrack.append(self.updateTrack) + api.callbacks.updateBlockTrack.append(self.trackPaintBlockBackgroundColors) + + api.callbacks.updateGraphTrackCC.append(self.updateGraphTrackCC) + api.callbacks.updateGraphBlockTrack.append(self.updateGraphBlockTrack) + api.callbacks.graphCCTracksChanged.append(self.syncCCsToBackend) + + #api.callbacks.recordingStreamNoteOn.append(self.recordingStreamNoteOn) + #api.callbacks.recordingStreamNoteOff.append(self.recordingStreamNoteOff) + #api.callbacks.setPlaybackTicks.append(self._drawLiveMidiRecording) + #api.callbacks.recordingStreamClear.append(self.recordingStreamClear) + + def updateMode(self, nameAsString): + assert nameAsString in constantsAndConfigs.availableEditModes + + for track in self.tracks.values(): + track.updateMode(nameAsString) + + self.grid.updateMode(nameAsString) + + def maxTrackLength(self): + if self.tracks: + return max(tr.lengthInPixel for tr in self.tracks.values()) + #return max(max(tr.lengthInPixel for tr in self.tracks.values()), self.parentView.geometry().width()) + #return max(max(tr.lengthInPixel for tr in self.scene().tracks.values()), self.scene().parentView.geometry().width()) + self.scene().parentView.geometry().width() + else: + return 0 #self.parentView.geometry().width() + + def updateSceneRect(self): + self.parentView.setSceneRect(QtCore.QRectF(-5, self.yStart, self.maxTrackLength() + 300, self.cachedSceneHeight)) #x,y,w,h + + def updateTrack(self, trackId, staticRepresentationList): + """for callbacks""" + if trackId in self.tracks: + self.tracks[trackId].redraw(staticRepresentationList) + #else: + #hidden track. But this can still happen through the data editor + self.parentView.updateMode() + self.updateSceneRect() + + def trackPaintBlockBackgroundColors(self, trackId, staticBlocksRepresentation): + if trackId in self.tracks: + self.tracks[trackId].paintBlockBackgroundColors(staticBlocksRepresentation) + #else: + #hidden track. + + def updateGraphTrackCC(self, trackId, ccNumber, staticRepresentationList): + """TrackId is a real notation track which has a dict of CCs""" + if trackId in self.tracks: + self.tracks[trackId].ccPaths[ccNumber].createGraphicItemsFromData(staticRepresentationList) + + def updateGraphBlockTrack(self, trackId, ccNumber, staticRepresentationList): + """TrackId is a real notation track which has a dict of CCs""" + if trackId in self.tracks: + self.tracks[trackId].ccPaths[ccNumber].updateGraphBlockTrack(staticRepresentationList) + + def toggleNoteheadsRectangles(self): + for track in self.tracks.values(): + track.toggleNoteheadsRectangles() + + def syncCCsToBackend(self, trackId, listOfCCsInThisTrack): + """Delete ccGraphs that are gui-only, + create gui versions of graphs that are backend-only. + Don't touch the others. + + This is the entry point for new CCPaths. They get created + only here. + """ + #TODO: and moved from one CC value to another? + + guiCCs = set(self.tracks[trackId].ccPaths.keys()) + + for backendCC in listOfCCsInThisTrack: + if backendCC in guiCCs: + guiCCs.remove(backendCC) #all right. no update needed. + else: #new CC. not existent in the Gui yet. Create. + #This is the place where we create new CCPaths + new = graphs.CCPath(parentGuiTrack = self.tracks[trackId], parentDataTrackId = trackId) + self.tracks[trackId].ccPaths[backendCC] = new #store in the GUI Track + new.setParentItem(self.tracks[trackId]) + new.setPos(0,0) + #new.setZValue(100) + + #all items left in the set are GUI-only CCs. which means the backend graphs were deleted. Delete them here as well. + for cc in guiCCs: + self.removeWhenIdle(self.tracks[trackId].ccPaths[cc]) + del self.tracks[trackId].ccPaths[cc] + + def recordingStreamNoteOn(self, trackId, liveChord): + if trackId in self.tracks: + self.tracks[trackId].recordingStreamNoteOn(liveChord) + #else: + #hidden track. + #self.parentView.updateMode() + #self.updateSceneRect() + + def recordingStreamNoteOff(self, trackId, liveChord): + if trackId in self.tracks: + self.tracks[trackId].recordingStreamNoteOff(liveChord) + #else: + #hidden track. + #self.parentView.updateMode() + #self.updateSceneRect() + + def recordingStreamClear(self): + removeInstancesFromScene(GuiLiveNote) + + def redraw(self, listOfStaticTrackRepresentations): + """The order of guiTracks depends on the backend index. + This way it is a no-brainer, we don't need to maintain our own + order, just sync with the backend when the callback comes in. + + Also handles meta data like track names. + But not the actual track content, which is done + through self.updateTrack which has its own api-callback + + called by callbacksDatabase.tracksChanged""" + + for track in self.tracks.values(): + track.hide() + + doubleTrackOffset = 0 + for trackExportObject in listOfStaticTrackRepresentations: + if not trackExportObject["id"] in self.tracks: + guiTrack = GuiTrack(self, trackExportObject) + self.tracks[trackExportObject["id"]] = guiTrack + self.addItem(guiTrack) + guiTrack.secondStageInitNowThatWeHaveAScene() + + self.tracks[trackExportObject["id"]].staticExportItem = trackExportObject + self.tracks[trackExportObject["id"]].setPos(0, constantsAndConfigs.trackHeight * trackExportObject["index"] + doubleTrackOffset) + self.tracks[trackExportObject["id"]].setZValue(0) #direct comparison only possible with the grid, which is at -50 + self.tracks[trackExportObject["id"]].nameGraphic.setText(trackExportObject["name"]) + self.tracks[trackExportObject["id"]].show() + + if trackExportObject["double"]: + doubleTrackOffset += constantsAndConfigs.trackHeight + + toDelete = [] + for trackId, track in self.tracks.items(): + if not track.isVisible(): + toDelete.append((trackId, track)) + + for trackId_, track_ in toDelete: + self.removeWhenIdle(track_) + del self.tracks[trackId_] + + #Finally, under the last track, tell the user how many hidden tracks there are + nrOfHiddenTracks = len(api.session.data.hiddenTracks) + if nrOfHiddenTracks: + self.hiddenTrackCounter.setText("… and {} hidden tracks".format(nrOfHiddenTracks)) + else: #remove previous status message + self.hiddenTrackCounter.setText("") + + belowLastTrack = constantsAndConfigs.trackHeight * (trackExportObject["index"] + 1) + doubleTrackOffset + self.hiddenTrackCounter.setPos(5, belowLastTrack) + self.cachedSceneHeight = belowLastTrack + constantsAndConfigs.trackHeight + + def removeWhenIdle(self, item): + """Call this function instead of removeItem. You are responsible to delete the item from any + list or other container where it was stored in the meantime yourself. + + Other methods tried: + -removeItem much slower + -create second scene and do scene2.addItem to get it out here - same as removeItem, if not slower + -delete a track and recreate a new one - same as all removeItems + -just hide the track and create a new one. slightly slower as hiding just the items. + -item.setFlag(QtWidgets.QGraphicsItem.ItemHasNoContents) slow, but not as slow as removeItem + -just hide items, never delete them is fast but gets slower the more items are hidden in the track + """ + item.hide() + self.deleteOnIdleStack.append(item) #This will actually delete the item and remove it from the scene when there is idle time + + def _deleteOnIdle(self): + """Hiding a QGraphicsItem is much faster than removing it from the scene. To keep the + GUI responsive but also to get rid of the old data we hide in createGraphicItemsFromData + and whenever there is time the actual removing and deleting will happen here. + + This function is connected to a timer(0) defined in self init. + """ + if self.deleteOnIdleStack: + deleteMe = self.deleteOnIdleStack.pop() + self.removeItem(deleteMe) #This is the only line in the program that should call scene.removeItem + del deleteMe + + def _drawLiveMidiRecording(self, tickPosition): + for midiPitch, guiLiveNote in self.liveMidiWaitingForNoteOff.items(): + guiLiveNote.update(tickPosition - guiLiveNote.liveNoteData["tickindex"]) + + + def trackAt(self, qScenePosition): + """trackAt always returns the full GuiTrack, even if in ccEdit mode.""" + + if qScenePosition.y() < self.conductor.y() + self.conductor.totalHeight/4: + return self.conductor + + for guiTrack in sorted(self.tracks.values(), key = lambda gT: gT.y()): + if guiTrack.y() >= qScenePosition.y() - constantsAndConfigs.trackHeight/2: + return guiTrack + else: + return None #no track here. + + def blockAt(self, qScenePosition): + track = self.trackAt(qScenePosition) + if track is self.conductor: + return self.conductor.blockAt(qScenePosition.x()) + if self.parentView.mode() in ("block", "notation"): + if track: + return track.blockAt(qScenePosition.x()) + elif self.parentView.mode() == "cc": + if track and constantsAndConfigs.ccViewValue in track.ccPaths: + return track.ccPaths[constantsAndConfigs.ccViewValue].blockAt(qScenePosition.x()) + else: + raise NotImplementedError + return None + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + #The big structures have a fixed position at (0,0) and move its child items, like notes, internally + #Some items, like the cursor, move around, as a whole item, in the scene directly and need no stretchXCoordinates() themselves. + self.grid.stretchXCoordinates(factor) + self.conductor.stretchXCoordinates(factor) + self.cursor.setX(self.cursor.pos().x() * factor) + self.playhead.setX(self.playhead.pos().x() * factor) + + for track in self.tracks.values(): + track.stretchXCoordinates(factor) + + self.updateSceneRect() + + #Macro-Structure: Score / Track / Block Moving and Duplicating + #Hold the ALT Key to unlock the moving mode.super().keyPressEvent(event) + #No note-editing requires a mouse action, so the mouse is free for controlling other aspects. + #Like zooming or moving blocks around. + + """ + def keyPressEvent(self, event): + #Triggers only if there is no shortcut for an action. + modifiers = QtWidgets.QApplication.keyboardModifiers() + if modifiers == QtCore.Qt.AltModifier: + Alt + + super().keyPressEvent(event) + """ + + def mousePressEvent(self, event): + """Pressing the mouse button is the first action of drag + and drop. We make the mouse cursor invisible so the user + can see where the point is going + + When in blockmode pressing the middle button combined with either Alt or Shift moves tracks and blocks. + + """ + if event.button() == 4 and self.parentView.mode() == "block": # Middle Button + modifiers = QtWidgets.QApplication.keyboardModifiers() + if modifiers == QtCore.Qt.ShiftModifier: #block move + block = self.blockAt(event.scenePos()) + if block: #works for note blocks and conductor blocks + block.staticExportItem["guiPosStart"] = block.pos() #without shame we hijack the backend-dict. + self.duringBlockDragAndDrop = block + block.mousePressEventCustom(event) + + elif modifiers == QtCore.Qt.AltModifier and self.parentView.mode() == "block": #track move + track = self.trackAt(event.scenePos()) + if track and not track is self.conductor: + self.parentView.setCursor(QtCore.Qt.BlankCursor) + self.cursor.hide() + track.staticExportItem["guiPosStart"] = track.pos() + self.duringTrackDragAndDrop = track + + super().mousePressEvent(event) + + def mouseMoveEvent(self, event): + """Catches certain mouse events for moving tracks and blocks. + Otherwise the event is propagated to the real QGraphicsItem. + Don't forget that an item needs to have the flag movable or selectable or else + it will not get mouseRelease or mouseMove events. MousePress always works.""" + + if self.duringTrackDragAndDrop: + x = self.duringTrackDragAndDrop.staticExportItem["guiPosStart"].x() + y = event.scenePos().y() + self.duringTrackDragAndDrop.setPos(x, y) + elif self.duringBlockDragAndDrop: + self.duringBlockDragAndDrop.mouseMoveEventCustom(event) + + super().mouseMoveEvent(event) + + def mouseReleaseEvent(self, event): + """Catches certain mouse events for moving tracks and blocks. + Otherwise the event is propagated to the real QGraphicsItem. + Don't forget that an item needs to have the flag movable or selectable or else + it will not get mouseRelease or mouseMove events. MousePress always works.""" + + self.parentView.unsetCursor() #While moving stuff the mouse-cursor is hidden. Reset. + #self.cursor.show() #Our own position cursor #TODO: why was that in here? It shows the cursor after a mouseclick, even in CC mode (it should not) + + tempBlockDragAndDrop = self.duringBlockDragAndDrop + tempTrackDragAndDrop = self.duringTrackDragAndDrop + self.duringBlockDragAndDrop = None + self.duringTrackDragAndDrop = None + #Now we can exit the function safely at any time without the need to reset the dragAndDrop storage in different places + + if tempTrackDragAndDrop: #This is only for GuiTrack aka note tracks. CC tracks follow the gui track and the conductor cannot be moved. + assert not tempBlockDragAndDrop + assert type(tempTrackDragAndDrop) is GuiTrack + dragTrackPosition = tempTrackDragAndDrop.pos().y() + trackPositions = sorted([guiTrack.pos().y() for id, guiTrack in self.tracks.items()]) + trackPositions.remove(dragTrackPosition) + + listOfTrackIds = api.session.data.asListOfTrackIds() + listOfTrackIds.remove(tempTrackDragAndDrop.staticExportItem["id"]) + + #Calculate the new track position and trigger a redraw + canditateForNewTrackPosition = 0 #this takes care of a score with only one track and also if you move a track to the 0th position + for y in trackPositions: + if dragTrackPosition >= y: + canditateForNewTrackPosition = trackPositions.index(y) +1 + + listOfTrackIds.insert(canditateForNewTrackPosition, tempTrackDragAndDrop.staticExportItem["id"]) + if len(listOfTrackIds) == 1: + tempTrackDragAndDrop.setPos(tempTrackDragAndDrop.staticExportItem["guiPosStart"]) #no need to trigger an api call with undo history etc. + else: + api.rearrangeTracks(listOfTrackIds) + + elif tempBlockDragAndDrop: #CC blocks, note blocks and conductor blocks + assert not tempTrackDragAndDrop + tempBlockDragAndDrop.mouseReleaseEventCustom(event) + targetTrack = self.trackAt(event.scenePos()) #this ALWAYS returns a Conductor, GuiTrack or None. Not a CC sub-track. for CC see below when we test the block type and change this variable. + targetBlock = self.blockAt(event.scenePos()) + dragBlockId = tempBlockDragAndDrop.staticExportItem["id"] + + #First some basic checks: + if not targetTrack: #Only drag and drop into tracks. + return None + if targetBlock is tempBlockDragAndDrop: #block got moved on itself + return None + + + #Now check what kind of block moving we are dealing with + #If the drag and drop mixes different block/track types we exit + blockType = type(tempBlockDragAndDrop) + conductorBlock = noteBlock = ccBlock = False + + if blockType is GuiBlockHandle: + if type(targetTrack) is GuiTrack and self.parentView.mode() in ("block", "notation"): + noteBlock = True + else: #Drag and Drop between different track types. + return None + + elif blockType is ConductorTransparentBlock: + if targetTrack is self.conductor: + conductorBlock = True + else: #Drag and Drop between different track types. + return None + + elif blockType is CCGraphTransparentBlock: + if (not type(targetTrack) is GuiTrack) or (not self.parentView.mode() == "cc"): + return None + + ccBlock = True + if constantsAndConfigs.ccViewValue in targetTrack.ccPaths: #this is only the backend database of CCs in tracks but it should be in sync. + targetTrackId = targetTrack.staticExportItem["id"] #we need this later. save it before changing the targetBlock variable + targetTrack = targetTrack.ccPaths[constantsAndConfigs.ccViewValue] + else: + return None #TODO: Create a new CC sub-track with the moved block as first block. Mainly a backend call. Needs a call at the end of this function as well. + + else: + raise TypeError("Block must be a conductor, note or CC type but is {}".format(blockType)) + + #We now have a track and the track type matches the block type. + #Find the position to insert. + if targetBlock is None: #behind the last block + positionToInsert = len(targetTrack.transparentBlockHandles) #essentially we want append() but insert() is compatible with all types of operation here. len is based 1, so len results in "after the last one" position. + else: + assert type(targetBlock) is blockType + positionToInsert = targetTrack.transparentBlockHandles.index(targetBlock) + assert positionToInsert >= 0 + + #Create the new order by putting the old block into a new slot and removing it from its old position + newBlockOrder = [guiBlock.staticExportItem["id"] for guiBlock in targetTrack.transparentBlockHandles] + if targetTrack == tempBlockDragAndDrop.parent: + newBlockOrder.remove(dragBlockId) #block will be at another position and removed from its old one. + newBlockOrder.insert(positionToInsert, dragBlockId) + + #Finally call the appropriate backend function which will trigger a GuiUpdate. + if targetTrack is tempBlockDragAndDrop.parent: #Same track or within the conductor track + if conductorBlock: + assert targetTrack is self.conductor + api.rearrangeTempoBlocks(newBlockOrder) + elif noteBlock: + api.rearrangeBlocks(targetTrack.staticExportItem["id"], newBlockOrder) + elif ccBlock: + api.rearrangeCCBlocks(targetTrackId, constantsAndConfigs.ccViewValue, newBlockOrder) + #else is already catched by a Else-TypeError above + else: #Different Track, + if conductorBlock or targetTrack is self.conductor: + raise RuntimeError("How did this slip through? Checking for cross-track incompatibility was already done above") + elif noteBlock: + api.moveBlockToOtherTrack(dragBlockId, targetTrack.staticExportItem["id"], newBlockOrder) + elif ccBlock: #TODO: Also different CC in the same GuiTrack + api.moveCCBlockToOtherTrack(dragBlockId, targetTrack.parentDataTrackId, newBlockOrder) + + elif event.button() == 1: #a positional mouse left click in a note-track + track = self.trackAt(event.scenePos()) + if track and not track is self.conductor: + modifiers = QtWidgets.QApplication.keyboardModifiers() + trackId = track.staticExportItem["id"] + if modifiers == QtCore.Qt.ShiftModifier: + api.selectToTickindex(trackId, event.scenePos().x() * constantsAndConfigs.ticksToPixelRatio) + else: + api.toTickindex(trackId, event.scenePos().x() * constantsAndConfigs.ticksToPixelRatio) + + super().mouseReleaseEvent(event) + +class GuiGrid(QtWidgets.QGraphicsItemGroup): + """The grid consists of vertical and horizontal lines. + Horiontal lines help to eyeball what pitch the cursor is on, vertical help to eyeball + the rhythm or tick positions e.g. when trying to find the right place for a tempo change or CC. + + Horizontal lines have always a more-than-enough width and X position. + Vertical lines are always at the top of the screen and reach down more-than-enough. + + We only need to take care that there are enough lines, not about their dimensions or positions. + + Never is a line deleted, only new lines are added if new tracks are added or the musics overall + duration increases. + + Also GraphicsView resize event and zooming out adds new lines. + + A complete clean and redraw only happens when the tick rhythm changes. + """ + + def __init__(self, parent): + super(GuiGrid, self).__init__() + self.parent = parent #QGraphicsScene + + self.initialGridExists = False + self.gapVertical = None #gets recalculated if gridRhythm is changed by the user, or through stretching. + self.gapHorizontal = None #is constant, but for symetry reasons this is put into redrawTickGrid as well + + self.width = None #recalculated in reactToresizeEventOrZoom + self.height = None #recalculated in reactToresizeEventOrZoom + + self.linesHorizontal = [] #later the grid lines will be stored here + self.linesVertical = [] #later the grid lines will be stored here + + self.horizontalScrollbarWaitForGapJump = 0 + self.oldHorizontalValue = 0 + + self.verticalScrollbarWaitForGapJump = 0 + self.oldVerticalValue = 0 + + self.parent.parentView.verticalScrollBar().valueChanged.connect(self.reactToVerticalScroll) + self.parent.parentView.horizontalScrollBar().valueChanged.connect(self.reactToHorizontalScroll) + + self.setOpacity(constantsAndConfigs.gridOpacity) + + gridPen = QtGui.QPen(QtCore.Qt.DotLine) + gridPen.setCosmetic(True) + + def reactToHorizontalScroll(self, value): + if not self.initialGridExists: + return + + #Keep horizontal lines in view + leftBorderAsScenePos = self.parent.parentView.mapToScene(0, 0).x() + for hline in self.linesHorizontal: + hline.setX(leftBorderAsScenePos) + + #Shift vertical lines to new positions, respecting the grid steps + delta = value - self.oldHorizontalValue #in pixel. positive=right, negative=left. the higher the number the faster the scrolling. + delta *= 1/constantsAndConfigs.zoomFactor + self.horizontalScrollbarWaitForGapJump += delta + self.oldHorizontalValue = value + if abs(self.horizontalScrollbarWaitForGapJump) > self.gapVertical: #collect scrollpixels until we scrolled more than one gap + gapMultiplier, rest = divmod(self.horizontalScrollbarWaitForGapJump, self.gapVertical) #really fast scrolling can jump more than one gap + for vline in self.linesVertical: + vline.setX(vline.x() + gapMultiplier*self.gapVertical) + self.horizontalScrollbarWaitForGapJump = rest #keep the rest for the next scroll + assert abs(self.horizontalScrollbarWaitForGapJump) < self.gapVertical + + def reactToVerticalScroll(self, value): + if not self.initialGridExists: + return + + #Keep vertical lines in view + topBorderAsScenePos = self.parent.parentView.mapToScene(0, 0).y() + for vline in self.linesVertical: + vline.setY(topBorderAsScenePos) + + #Shift horizontal lines to a new position, respecting the staffline gap + delta = value - self.oldVerticalValue #in pixel. positive=down, negative=up. the higher the number the faster the scrolling. + delta *= 1/constantsAndConfigs.zoomFactor + self.verticalScrollbarWaitForGapJump += delta + self.oldVerticalValue = value + if abs(self.verticalScrollbarWaitForGapJump) > self.gapHorizontal: #collect scrollpixels until we scrolled more than one gap + gapMultiplier, rest = divmod(self.verticalScrollbarWaitForGapJump, self.gapHorizontal) #really fast scrolling can jump more than one gap + for hline in self.linesHorizontal: + hline.setY(hline.y() + gapMultiplier*self.gapHorizontal) + self.verticalScrollbarWaitForGapJump = rest #keep the rest for the next scroll + assert abs(self.verticalScrollbarWaitForGapJump) < self.gapHorizontal + + + def reactToresizeEventOrZoom(self): + """Called by the Views resizeEvent. + When the views geometry changes or zooms we may need to create more lines. + Never delete and never make smaller though.""" + scoreViewWidgetHeight = self.parent.parentView.height() + scoreViewWidgetWidth = self.parent.parentView.width() + + if (not self.height) or scoreViewWidgetHeight * 1.1 > self.height: + self.height = scoreViewWidgetHeight * 1.1 + if (not self.width) or scoreViewWidgetWidth * 1.1 > self.width: + self.width = scoreViewWidgetWidth * 1.1 + + if self.initialGridExists: + assert self.linesHorizontal and self.linesVertical, (self.linesHorizontal, self.linesVertical) + assert self.parent.parentView.isVisible(), self.parent.parentView.isVisible() + self._fillVerticalLines() + self._fillHorizontalLines() + #else: + #reactToresizeEventOrZoom without grid + #self.redrawTickGrid() #this happens only once, on program start. Afterwards it's user triggered by changing the grid rhythm + + def _fillVerticalLines(self): + """Only allowed to get called by reactToresizeEventOrZoom because we need an updated + self.height value""" + #Check if we need longer lines. Do this before creating new lines, because new lines + #have the heighest + oldHeight = self.linesVertical[-1].line().y2() #this is a bit less than .length() so we use that + if self.height > oldHeight: + for vline in self.linesVertical: + line = vline.line() + line.setLength(self.height) + vline.setLine(line) + + #Check if we need new lines + newLineCount = int(self.width / self.gapVertical) + if newLineCount > self.nrOfVerticalLines: + newLineCount += int(newLineCount - self.nrOfVerticalLines) + self._createVerticalLines(start=self.nrOfVerticalLines, end=newLineCount) #This draws only yet nonexisting lines. + self.nrOfVerticalLines = newLineCount #for next time + + def _fillHorizontalLines(self): + """Only allowed to get called by reactToresizeEventOrZoom because we need an updated + self.width value. + To be honest.. this is also called by stretchXCoordinates when shrinking the display so + we need more lines. That does not depend on self.width but on the newLineCount """ + #Check if we need longer lines. Do this before creating new lines, because new lines + #have the heighest + oldWidth = self.linesHorizontal[-1].line().x2() #this is a bit less than .length() so we use that + if self.width > oldWidth: + for hline in self.linesHorizontal: + line = hline.line() + line.setLength(self.width) + hline.setLine(line) + + #Check if we need new lines + newLineCount = int(self.height / self.gapHorizontal) + if newLineCount > self.nrOfHorizontalLines: + newLineCount += int(newLineCount - self.nrOfHorizontalLines) + self._createHorizontalLines(start=self.nrOfHorizontalLines, end=newLineCount) #This draws only yet nonexisting lines. + self.nrOfHorizontalLines = newLineCount #for next time + + def stretchXCoordinates(self, factor): + """Reposition the items on the X axis. + Call goes through all parents/children, starting from ScoreView._stretchXCoordinates. + Docstring there.""" + self.gapVertical = constantsAndConfigs.gridRhythm / constantsAndConfigs.ticksToPixelRatio #this is necessarry every time after stretching (ticksToPixelRatio) and after changing the gridRhythm + + for vline in self.linesVertical: + vline.setX(vline.x() * factor) + + self._fillVerticalLines() + + #for hline in self.linesHorizontal: + # stretchLine(hline, factor) + + def updateMode(self, nameAsString): + assert nameAsString in constantsAndConfigs.availableEditModes + if nameAsString == "block": + for l in self.linesVertical: + l.hide() + else: + for l in self.linesVertical: + l.show() + + def _createVerticalLines(self, start, end): + """Lines get an offset that matches the grid-rythm. + So we get more draw area left, if the sceneRect will move into that area for some reason""" + for i in range(start, end): #range includes the first value but not the end. We know that and all functions in GuiGrid are designed accordingly. For example reactToLongerDuration starts on the highest value of the old number of lines since that was never drawn in the last round. + vline = self.parent.addLine(0, -5*self.gapHorizontal, 0, self.height, GuiGrid.gridPen) #x1, y1, x2, y2, pen + self.addToGroup(vline) #first add to group, then set pos + vline.setPos(i * self.gapVertical, 0) + vline.setEnabled(False) + self.linesVertical.append(vline) + + def _createHorizontalLines(self, start, end): + """Lines get an offset that matches the pitch and staff-lines + So we get more draw area on top, if the sceneRect will move into that area for some reason""" + for i in range(start, end): #range includes the first value but not the end. We know that and all functions in GuiGrid are designed accordingly. For example reactToMoreTracks starts on the highest value of the old number of lines since that was never drawn in the last round. + hline = self.parent.addLine(0, 0, self.width, 0, GuiGrid.gridPen) #x1, y1, x2, y2, pen + self.addToGroup(hline) #first add to group, then set pos + hline.setPos(0, i * self.gapHorizontal) + hline.setEnabled(False) + self.linesHorizontal.append(hline) + + def redrawTickGrid(self): + """A complete redraw. + This gets called once after the main window gets shown. (in init main window). + After that only called after the used changes the tick rhythm manually. + """ + assert self.parent.parentView.isVisible() + + if self.initialGridExists: + #it is possible that the grid did not change. proceed nevertheless + for l in self.linesHorizontal + self.linesVertical: + self.parent.removeWhenIdle(l) + + + self.linesHorizontal = [] #like the staff lines + self.linesVertical = [] #makes comparing tick positions easier by eye + + self.gapVertical = constantsAndConfigs.gridRhythm / constantsAndConfigs.ticksToPixelRatio #this is necessarry every time after stretching (ticksToPixelRatio) and after changing the gridRhythm + self.gapHorizontal = constantsAndConfigs.stafflineGap #never changes + + self.nrOfHorizontalLines = int(self.height / self.gapHorizontal) #we save that value if the score grows and we need more lines. Initially we use the screen size, not the content. + self.nrOfVerticalLines = int(self.width / self.gapVertical) #we save that value if the score grows and we need more lines. Initially we use the screen size, not the content. + + self._createVerticalLines(0, self.nrOfVerticalLines) + self._createHorizontalLines(0, self.nrOfHorizontalLines) + + self.initialGridExists = True diff --git a/qtgui/submenus.py b/qtgui/submenus.py new file mode 100644 index 0000000..ce5f88f --- /dev/null +++ b/qtgui/submenus.py @@ -0,0 +1,601 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from PyQt5 import QtCore, QtGui, QtWidgets + +import engine.api as api +import template.engine.pitch as pitch + +from .constantsAndConfigs import constantsAndConfigs +from .designer.tickWidget import Ui_tickWidget +from sys import maxsize + +class CombinedTickWidget(QtWidgets.QFrame): + def __init__(self): + super().__init__() + self.setFrameShape(QtWidgets.QFrame.Box) + self.setFrameShadow(QtWidgets.QFrame.Sunken) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self) + self.horizontalLayout_3.setContentsMargins(3, 0, 3, 0) + self.horizontalLayout_3.setSpacing(0) + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.upbeatSpinBox = QtWidgets.QSpinBox(self) + self.upbeatSpinBox.setPrefix("") + self.upbeatSpinBox.setMinimum(0) + self.upbeatSpinBox.setMaximum(999999999) + self.upbeatSpinBox.setObjectName("upbeatSpinBox") + self.horizontalLayout_3.addWidget(self.upbeatSpinBox) + self.callTickWidget = QtWidgets.QPushButton(self) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.callTickWidget.sizePolicy().hasHeightForWidth()) + self.callTickWidget.setSizePolicy(sizePolicy) + self.callTickWidget.setMaximumSize(QtCore.QSize(25, 16777215)) + self.callTickWidget.setFlat(False) + self.callTickWidget.setObjectName("callTickWidget") + self.callTickWidget.setText("𝅘𝅥𝅮 ") + + self.horizontalLayout_3.addWidget(self.callTickWidget) + self.callTickWidget.clicked.connect(self.callClickWidgetForUpbeat) + + self.setFocusPolicy(0) #no focus + self.callTickWidget.setFocusPolicy(0) #no focus + + self.valueChanged = self.upbeatSpinBox.valueChanged + + def setMinimum(self, value): + self.upbeatSpinBox.setMinimum(value) + + def setMaximum(self, value): + self.upbeatSpinBox.setMaximum(value) + + def setValue(self, value): + self.upbeatSpinBox.setValue(value) + + def value(self): + """Make this widget behave like a spinbox signal""" + return self.upbeatSpinBox.value() + + def callClickWidgetForUpbeat(self): + dialog = TickWidget(self, initValue = self.upbeatSpinBox.value()) + self.upbeatSpinBox.setValue(dialog.ui.ticks.value()) + +class TickWidget(QtWidgets.QDialog): + def __init__(self, mainWindow, initValue = 0): + super().__init__(mainWindow) + + #Set up the user interface from Designer. + self.ui = Ui_tickWidget() + self.ui.setupUi(self) + + #self.ui.ticks.setValue(initValue) + self.ui.ticks.setValue(0) #TODO: easier to drawLabel this way. change back to given value when drawLabel is autogenerated and does not work by keeping track anymore. + + self.ui.ok.clicked.connect(lambda: self.done(True)) + self.ui.cancel.clicked.connect(lambda: self.done(False)) + self.ui.reset.clicked.connect(self.reset) + + self.ui.durationLabel.setText("") + + self.clickedSoFar = [] #keep track + + self.ui.D1.clicked.connect(lambda: self.addDuration(api.D1)) + self.ui.D2.clicked.connect(lambda: self.addDuration(api.D2)) + self.ui.D4.clicked.connect(lambda: self.addDuration(api.D4)) + self.ui.D8.clicked.connect(lambda: self.addDuration(api.D8)) + self.ui.D16.clicked.connect(lambda: self.addDuration(api.D16)) + + self.ui.D32.clicked.connect(lambda: self.addDuration(api.D32)) + self.ui.D64.clicked.connect(lambda: self.addDuration(api.D64)) + self.ui.D128.clicked.connect(lambda: self.addDuration(api.D128)) + self.ui.DB.clicked.connect(lambda: self.addDuration(api.DB)) + self.ui.DL.clicked.connect(lambda: self.addDuration(api.DL)) + + self.ui.ticks.valueChanged.connect(self.drawLabel) + + self.exec() #blocks until the dialog gets closed + + #TODO: better key handling. Esc in the ticks field should not close the dialog but return the keyboard focus to the durations + + def reset(self): + self.ui.ticks.setValue(0) + self.clickedSoFar = [] + self.ui.durationLabel.setText("") + + def addDuration(self, duration): + self.clickedSoFar.append(duration) + nowTicks = self.ui.ticks.value() + self.ui.ticks.setValue(nowTicks + duration) + + def drawLabel(self): + #TODO: with nice partitions of real note icons. + #Error handling. A too complex or wrong duration (off by one, not equal to a partition etc.) blocks the "OK" button. No, just gives a warning. + #backendDurationInstance = api.items.Duration.createByGuessing(self.ui.ticks.value()) + #text = backendDurationInstance.lilypond() + + text = [] + for duration, symbol in reversed(sorted(constantsAndConfigs.realNoteDisplay.items())): + times = self.clickedSoFar.count(duration) + if times: + part = str(times) + "x" + symbol + text.append(part) + + self.ui.durationLabel.setText(" + ".join(text)) + +#There are two types of submenus in this file. The majority is created in menu.py during start up. Like Clef, KeySig etc. These don't need to ask for any dynamic values. +#The other is like SecondaryTempoChangeMenu. In menu.py this is bound with a lambda construct so a new instance gets created each time the action is called by the user. Thats why this function has self.__call__ in its init. + +class Submenu(QtWidgets.QDialog): + #TODO: instead of using a QDialog we could use a QWidget and use it as proxy widget on the graphic scene, placing the menu where the input cursor is. + def __init__(self, mainWindow, labelString): + super().__init__(mainWindow) #if you don't set the parent to the main window the whole screen will be the root and the dialog pops up in the middle of it. + #self.setModal(True) #we don't need this when called with self.exec() instead of self.show() + self.layout = QtWidgets.QFormLayout() + #self.layout = QtWidgets.QVBoxLayout() + self.setLayout(self.layout) + + label = QtWidgets.QLabel(labelString) #"Choose a clef" or so. + self.layout.addWidget(label) + + #self.setFocus(); #self.grabKeyboard(); #redundant for a proper modal dialog. Leave here for documentation reasons. + + def keyPressEvent(self, event): + """Escape closes the dialog by default. + We want Enter as "accept value" + All other methods of mixing editing, window focus and signals + results in strange qt behaviour, triggering the api function twice or more. + Especially unitbox.editingFinished is too easy to trigger. + + The key-event method turned out to be the most straightforward way.""" + try: + getattr(self, "process") + k = event.key() #49=1, 50=2 etc. + if k == 0x01000004 or k == 0x01000005: #normal enter or keypad enter + event.ignore() + self.process() + else: #Pressed Esc + self.abortHandler() + super().keyPressEvent(event) + except AttributeError: + super().keyPressEvent(event) + + def abortHandler(self): + pass + + def __call__(self): + """This instance can be called like a function""" + self.exec() #blocks until the dialog gets closed + + +""" +Most submenus have the line "lambda, r, value=value"... +the r is the return value we get automatically from the Qt buttons which need to be handled. +""" + +class SecondaryClefMenu(Submenu): + + clefs = [("[1] Treble", lambda: api.insertClef("treble")), + ("[2] Bass", lambda: api.insertClef("bass")), + ("[3] Alto", lambda: api.insertClef("alto")), + ("[4] Drum", lambda: api.insertClef("percussion")), + ("[5] Treble ^8 ", lambda: api.insertClef("treble^8")), + ("[6] Treble _8 ", lambda: api.insertClef("treble_8")), + ("[7] Bass _8 ", lambda: api.insertClef("bass_8")), + ] + + def __init__(self, mainWindow): + super().__init__(mainWindow, "choose a clef") + + for number, (prettyname, function) in enumerate(SecondaryClefMenu.clefs): + button = QtWidgets.QPushButton(prettyname) + button.setShortcut(QtGui.QKeySequence(str(number+1))) + self.layout.addWidget(button) + button.clicked.connect(function) + button.clicked.connect(self.done) + +class SecondarySplitMenu(Submenu): + + splits = [("[2]", lambda: api.split(2)), + ("[3]", lambda: api.split(3)), + ("[4]", lambda: api.split(4)), + ("[5]", lambda: api.split(5)), + ("[6]", lambda: api.split(6)), + ("[7]", lambda: api.split(7)), + ("[8]", lambda: api.split(8)), + ("[9]", lambda: api.split(9)), + ] + + def __init__(self, mainWindow): + super().__init__(mainWindow, "split chord in") + + for number, (prettyname, function) in enumerate(SecondarySplitMenu.splits): + button = QtWidgets.QPushButton(prettyname) + button.setShortcut(QtGui.QKeySequence(str(number+2))) #+1 for enumerate from 0, +2 we start at 2. + self.layout.addWidget(button) + button.clicked.connect(function) + button.clicked.connect(self.done) + + +class SecondaryKeySignatureMenu(Submenu): + def __init__(self, mainWindow): + super().__init__(mainWindow, "root note is the cursor position") + l = [("[{}] {}".format(num+1, modeString.title()), lambda r, modeString=modeString: api.insertCursorCommonKeySignature(modeString)) for num, modeString in enumerate(api.commonKeySignaturesAsList())] + + for number, (prettyname, function) in enumerate(l): + button = QtWidgets.QPushButton(prettyname) + button.setShortcut(QtGui.QKeySequence(str(number+1))) + self.layout.addWidget(button) + button.clicked.connect(function) + button.clicked.connect(self.done) + +class SecondaryDynamicsMenu(Submenu): + def __init__(self, mainWindow): + super().__init__(mainWindow, "choose a dynamic") + button = QtWidgets.QPushButton("[r] Ramp") + button.setShortcut(QtGui.QKeySequence("r")) + self.layout.addWidget(button) + button.clicked.connect(api.insertDynamicRamp) + button.clicked.connect(self.done) + + l = [("[{}] {}".format(num+1, keyword), lambda r, keyword=keyword: api.insertDynamicSignature(keyword)) for num, keyword in enumerate(constantsAndConfigs.dynamics)] + + for number, (prettyname, function) in enumerate(l): + button = QtWidgets.QPushButton(prettyname) + button.setShortcut(QtGui.QKeySequence(str(number+1))) + self.layout.addWidget(button) + button.clicked.connect(function) + button.clicked.connect(self.done) + +class SecondaryMetricalInstructionMenu(Submenu): + def __init__(self, mainWindow): + super().__init__(mainWindow, "choose a metrical instruction") + + l = [("[{}] {}".format(num+1, modeString), lambda r, modeString=modeString: api.insertCommonMetricalInstrucions(modeString)) for num, modeString in enumerate(api.commonMetricalInstructionsAsList())] + + for number, (prettyname, function) in enumerate(l): + button = QtWidgets.QPushButton(prettyname) + button.setShortcut(QtGui.QKeySequence(str(number+1))) + self.layout.addWidget(button) + button.clicked.connect(function) + button.clicked.connect(self.done) + +class SecondaryTempoChangeMenu(Submenu): + """A single tempo change where the user can decide which reference unit and how many of them + per minute. + Works as "edit tempo point" when there is already a point at this time position. + This would be the case anyway thanks to backend-behaviour but the gui has the opportunity to + present the current values as a base for editing""" + + + def __init__(self, mainWindow, staticExportTempoItem = None): + super().__init__(mainWindow, "choose units per minute, reference note, graph type") + + self.mainWindow = mainWindow + self.staticExportTempoItem = staticExportTempoItem + + tickindex, unitsPerMinute, referenceTicks, graphType = self.getCurrentValues() #takes self.staticExportTempoItem into account + + self.unitbox = QtWidgets.QSpinBox() + self.unitbox.setMinimum(1) + self.unitbox.setMaximum(999) + self.unitbox.setValue(unitsPerMinute) + self.layout.addWidget(self.unitbox) + + self.referenceList = QtWidgets.QComboBox() + self.referenceList.addItems(constantsAndConfigs.prettyExtendedRhythmsStrings) + self.referenceList.setCurrentIndex(constantsAndConfigs.prettyExtendedRhythmsValues.index(referenceTicks)) + self.layout.addWidget(self.referenceList) + + self.interpolationList = QtWidgets.QComboBox() + l = api.getListOfGraphInterpolationTypesAsStrings() + self.interpolationList.addItems(l) + self.interpolationList.setCurrentIndex(l.index(graphType)) + self.layout.addWidget(self.interpolationList) + + self.__call__() + + def process(self): + """It says 'insert' but the backend is a dict. Changes are simply made by overwriting the + whole thing and the backend sends new data to draw to the GUI""" + tickindex, unitsPerMinute, referenceTicks, graphType = self.getCurrentValues() + newReferenceTicks = constantsAndConfigs.prettyExtendedRhythmsValues[self.referenceList.currentIndex()] + graphType = api.getListOfGraphInterpolationTypesAsStrings()[self.interpolationList.currentIndex()] + api.insertTempoItemAtAbsolutePosition(tickindex, self.unitbox.value(), newReferenceTicks, graphType) + self.done(True) + + def getCurrentValues(self): + """Get the current values from the note-editing backend cursor""" + if self.staticExportTempoItem: + return self.staticExportTempoItem["position"], self.staticExportTempoItem["unitsPerMinute"], self.staticExportTempoItem["referenceTicks"], self.staticExportTempoItem["graphType"], + else: + assert self.mainWindow.scoreView.scoreScene.cursor.cursorExportObject + return self.mainWindow.scoreView.scoreScene.cursor.cursorExportObject["tickindex"], self.mainWindow.scoreView.scoreScene.cursor.cursorExportObject["tempoUnitsPerMinute"], self.mainWindow.scoreView.scoreScene.cursor.cursorExportObject["tempoReferenceTicks"], self.mainWindow.scoreView.scoreScene.cursor.cursorExportObject["tempoGraphType"], + +class SecondaryTemporaryTempoChangeMenu(Submenu): + """Essentially: What kind of fermata effect do you want?""" + + lastCustomValue = 0.42 + + def __init__(self, mainWindow): + super().__init__(mainWindow, "[enter] to use value") + + self.spinbox = QtWidgets.QDoubleSpinBox() + self.spinbox.setValue(SecondaryTemporaryTempoChangeMenu.lastCustomValue) + self.spinbox.setDecimals(2) + self.spinbox.setMinimum(0.01) + self.spinbox.setSingleStep(0.01) + self.layout.addWidget(self.spinbox) + + def process(self): + v = round(self.spinbox.value(), 2) + SecondaryTemporaryTempoChangeMenu.lastCustomValue = v + api.insertTempoChangeDuringDuration(v) + self.done(True) + + +class BlockPropertiesEdit(Submenu): + def __init__(self, mainWindow, staticExportItem): + super().__init__(mainWindow, "") + + self.mainWindow = mainWindow + self.staticExportItem = staticExportItem + + self.layout.insertRow(0, QtWidgets.QLabel("edit block #{}".format(staticExportItem["id"]))) + + self.name = QtWidgets.QLineEdit(self.staticExportItem["name"]) + self.name.selectAll() + self.layout.addRow("name", self.name) + + #self.minimumInTicks = QtWidgets.QSpinBox() + self.minimumInTicks = CombinedTickWidget() + self.minimumInTicks.setValue(self.staticExportItem["minimumInTicks"]) + self.layout.addRow("minimum in ticks", self.minimumInTicks) + + self.__call__() + + def process(self): + newParametersDict = { + "minimumInTicks":self.minimumInTicks.value(), + "name":self.name.text(), + } + api.changeBlock(self.staticExportItem["id"], newParametersDict) + self.done(True) + +class TempoBlockPropertiesEdit(Submenu): + def __init__(self, mainWindow, staticExportItem): + super().__init__(mainWindow, "") + + self.mainWindow = mainWindow + self.staticExportItem = staticExportItem + + self.layout.insertRow(0, QtWidgets.QLabel("edit block #{}".format(staticExportItem["id"]))) + + self.name = QtWidgets.QLineEdit(self.staticExportItem["name"]) + self.name.selectAll() + self.layout.addRow("name", self.name) + + self.duration = CombinedTickWidget() + self.duration.setValue(self.staticExportItem["duration"]) + self.layout.addRow("duration in ticks", self.duration) + + self.__call__() + + def process(self): + newParametersDict = { + "duration":self.duration.value(), + "name":self.name.text(), + } + api.changeTempoBlock(self.staticExportItem["id"], newParametersDict) + self.done(True) + +class GridRhytmEdit(Submenu): + def __init__(self, mainWindow): + super().__init__(mainWindow, "") + + self.mainWindow = mainWindow + + self.layout.insertRow(0, QtWidgets.QLabel("Edit Grid")) + self.duration = CombinedTickWidget() + self.duration.setValue(constantsAndConfigs.gridRhythm) + self.layout.addRow("duration in ticks", self.duration) + + self.opacity = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.opacity.setMinimum(0) + self.opacity.setMaximum(50) + self.opacityLabel = QtWidgets.QLabel("opacity: {}%".format(int(constantsAndConfigs.gridOpacity * 100))) + self.layout.addRow(self.opacityLabel, self.opacity) + self.opacity.valueChanged.connect(lambda: self.opacityLabel.setText("opacity: {}%".format(self.opacity.value()))) + self.opacity.setValue(int(constantsAndConfigs.gridOpacity * 100)) + self.opacity.valueChanged.connect(lambda: self.mainWindow.scoreView.scoreScene.grid.setOpacity(self.opacity.value() / 100)) #only react to changes after the initial value was set. + self.__call__() + + def process(self): + constantsAndConfigs.gridRhythm = self.duration.value() + constantsAndConfigs.gridOpacity = self.opacity.value() / 100 + api.session.guiSharedDataToSave["grid_opacity"] = constantsAndConfigs.gridOpacity + api.session.guiSharedDataToSave["grid_rhythm"] = constantsAndConfigs.gridRhythm + self.mainWindow.scoreView.scoreScene.grid.redrawTickGrid() #opacity was already set live, but finally it will be used here again. + self.done(True) + + def abortHandler(self): + self.mainWindow.scoreView.scoreScene.grid.setOpacity(constantsAndConfigs.gridOpacity) #reset to initial value and undo the live preview + +class TransposeMenu(Submenu): + def __init__(self, mainWindow, what): + super().__init__(mainWindow, "Transpose {}".format(what.title())) + assert what in ("item", "score") + self.what = what + + self.layout.insertRow(0, QtWidgets.QLabel("Construct Interval from relative distance")) + + self.fromNote = QtWidgets.QComboBox() + self.fromNote.addItems(pitch.sortedNoteNameList) + + self.fromNote.setCurrentIndex(pitch.sortedNoteNameList.index("c'")) + self.layout.addRow("from", self.fromNote) + + self.to = QtWidgets.QComboBox() + self.to.addItems(pitch.sortedNoteNameList) + self.to.setCurrentIndex(pitch.sortedNoteNameList.index("c'")) + self.layout.addRow("to", self.to) + self.__call__() + + + def process(self): + fromPitch = pitch.ly2pitch[self.fromNote.currentText()] + toPitch = pitch.ly2pitch[self.to.currentText()] + + if self.what == "item": + api.transpose(fromPitch, toPitch) #item on cursor position + elif self.what == "score": + api.transposeScore(fromPitch, toPitch) + self.done(True) + + +class SecondaryProperties(Submenu): + def __init__(self, mainWindow): + """Directly edits the backend score meta data. There is no api and no callbacks""" + super().__init__(mainWindow, "MetaData") + + dictionary = api.session.score.metaData + + test = set(type(key) for key in dictionary.keys()) + assert len(test) == 1 + assert list(test)[0] == str + + self.widgets = {key:self.makeValueWidget(value) for key, value in dictionary.items()} + + for key, widget in sorted(self.widgets.items()): + self.layout.addRow(key.title(), widget) + + self.__call__() + + def makeValueWidget(self, value): + types = { + str : QtWidgets.QLineEdit, + int : QtWidgets.QSpinBox, + float : QtWidgets.QDoubleSpinBox, + } + typ = type(value) + widget = types[typ]() + + if typ == str: + widget.setText(value) + elif typ == int or typ == float: + widget.setValue(value) + + return widget + + def getValueFromWidget(self, widget): + typ = type(widget) + if typ == QtWidgets.QLineEdit: + return widget.text() + elif typ == QtWidgets.QSpinBox or typ == QtWidgets.QDoubleSpinBox: + return widget.value() + + def process(self): + api.session.score.metaData = {key:self.getValueFromWidget(widget) for key, widget in self.widgets.items()} + self.done(True) + #Instance gets killed afterwards. No need to save the new values. + + +class SecondaryProgramChangeMenu(Submenu): + lastProgramValue = 0 + lastMsbValue = 0 + lastLsbValue = 0 + + def __init__(self, mainWindow): + super().__init__(mainWindow, "Instrument Change") + + self.program = QtWidgets.QSpinBox() + self.program.setValue(type(self).lastProgramValue) + self.msb = QtWidgets.QSpinBox() + self.msb.setValue(type(self).lastMsbValue) + self.lsb = QtWidgets.QSpinBox() + self.lsb.setValue(type(self).lastLsbValue) + self.instrumentName = QtWidgets.QLineEdit() + self.shortInstrumentName = QtWidgets.QLineEdit() + + for label, spinbox in (("Program", self.program), ("Bank MSB", self.msb), ("Bank LSB", self.lsb)): + spinbox.setMinimum(0) + spinbox.setMaximum(127) + spinbox.setSingleStep(1) + self.layout.addRow(label, spinbox) + + + self.layout.addRow("Instr.Name", self.instrumentName) + self.layout.addRow("Short Name", self.shortInstrumentName) + + self.insert = QtWidgets.QPushButton("Insert") + self.insert.clicked.connect(self.process) + self.layout.addWidget(self.insert) + + + def process(self): + program = self.program.value() + type(self).lastProgramValue = program + msb = self.msb.value() + type(self).lastMsbValue = msb + lsb = self.lsb.value() + type(self).lastLsbValue = lsb + + api.instrumentChange(program, msb, lsb, self.instrumentName.text(), self.shortInstrumentName.text(), ) + self.done(True) + + +class SecondaryChannelChangeMenu(Submenu): + lastCustomValue = 0 + + def __init__(self, mainWindow): + super().__init__(mainWindow, "Channel Change 0-15. [enter] to use value") + + self.spinbox = QtWidgets.QSpinBox() + self.spinbox.setValue(type(self).lastCustomValue) + self.spinbox.setMinimum(0) + self.spinbox.setMaximum(15) + self.spinbox.setSingleStep(1) + self.layout.addRow("Channel", self.spinbox) + self.name = QtWidgets.QLineEdit() + self.layout.addRow("Text", self.name) + + def process(self): + v = self.spinbox.value() + type(self).lastCustomValue = v + api.channelChange(v, self.name.text()) + self.done(True) + + +#Normal Functions +############ + +def pedalNoteChooser(mainWindow): + try: + constantsAndConfigs.realNotesStrings[constantsAndConfigs.realNotesValues.index(constantsAndConfigs.gridRhythm)+1] + rhythmString = QtWidgets.QInputDialog.getItem(mainWindow, "Insert Pedal Notes", "Use duration as base", constantsAndConfigs.realNotesStrings, constantsAndConfigs.realNotesValues.index(constantsAndConfigs.gridRhythm)+1, False) + except IndexError: + rhythmString = QtWidgets.QInputDialog.getItem(mainWindow, "Insert Pedal Notes", "Use duration as base", constantsAndConfigs.realNotesStrings, constantsAndConfigs.realNotesValues.index(constantsAndConfigs.gridRhythm), False) + + + if rhythmString[1]: #bool. Canceled? + for baseDuration, v in constantsAndConfigs.commonNotes: + if v == rhythmString[0]: + api.pedalNotes(baseDuration) diff --git a/qtgui/timeline.py b/qtgui/timeline.py new file mode 100644 index 0000000..25d5e3d --- /dev/null +++ b/qtgui/timeline.py @@ -0,0 +1,492 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from PyQt5 import QtCore, QtGui, QtSvg, QtWidgets +from .constantsAndConfigs import constantsAndConfigs +from template.qtgui.helper import stringToColor +import engine.api as api + + +"""This file handles the timeline which can be found at the top of the +notation editor. + +Actually this is a rhythm-line since our linear value is rhythm, or +ticks, which is the same. + +That just means that the space between a whole note is always the same +in pixel. Neither tempo nor any other value can change this (except +proportional zooming of course). +""" + +class TimeLine(QtWidgets.QGraphicsRectItem): + + def __init__(self, parentView): + + #The right border of the rect gets updated through self.updateGraphBlockTrack + #Achtung! if you set y to zero and then extend the height in the minus direction it will appear correctly but the hover events will be broken in WEIRD ways. weird means the hover-rect seems to be curved and you have different hover ranger on different X-coordinates. strange stuff... + super().__init__(0, 0, 1, 15) #(x, y, w, h) + + self.setAcceptHoverEvents(True) + self.setOpacity(0.75) + self.setFlag(QtWidgets.QGraphicsItem.ItemDoesntPropagateOpacityToChildren) + self.inactiveBrush = QtGui.QColor(233, 233, 233) #most of the time + self.activeBrush = QtGui.QColor(200, 200, 200) + self.setBrush(self.inactiveBrush) + self.tempoPoints = [] + self.blockEndMarkers = [] + self.appendGraphBlockButtonProxy = None #filled in by updateGraphBlockTrack because it adds a widget, which needs a scene which is not available during init + self.parentView = parentView + self.lastTouchedReferenceTicks = 210*2**8 #convenience. remember the last tempo unit so the user can just click on the timeline without entering a value each time. + + """ + #Pen for the borders + pen = QtGui.QPen() + pen.setCapStyle(QtCore.Qt.RoundCap) + pen.setJoinStyle(QtCore.Qt.RoundJoin) + pen.setWidth(1) + pen.setColor(QtGui.QColor("Red")) + self.setPen(pen) + """ + #self.setPen(QtGui.QColor("transparent")) + + api.callbacks.updateTempoTrack.append(self.createGraphicItemsFromData) + api.callbacks.updateTempoTrackBlocks.append(self.updateGraphBlockTrack) + + def hoverEnterEvent(self, event): + """TempoItems can be deleted by hovering over them and pressing + the delete key. We want to prevent that the delete key also + deletes notes. This will happen if the cursor does not exactly + hover over the tempopoint. To prevent this accident we + deactivate the scores delete key. + And show the user a different color to let them know.""" + self.setBrush(self.activeBrush) + self.scene().parentView.viewport().update() + #self.scene().parentView.mainWindow.ui.actionDelete.setEnabled(False) #disable Score-Item delete + self.scene().parentView.mainWindow.menuActionDatabase.ccEditMode() + event.accept() + + def hoverLeaveEvent(self, event): + """reverse hoverEnterEvent""" + self.setBrush(self.inactiveBrush) + self.scene().parentView.viewport().update() + #self.scene().parentView.mainWindow.ui.actionDelete.setEnabled(True) #enable Score-Item delete again + self.scene().parentView.mainWindow.menuActionDatabase.noteEditMode() + event.accept() + + def mousePressEvent(self, event): + if event.button() == 1: # QtCore.Qt.MouseButton.LeftButton + self.add(event.scenePos()) #create a new tempo point by telling the api a position and then reacting to "delete all, recreate" from the callback. + event.accept() + else: + super().mousePressEvent(event) #call default implementation from QGraphicsRectItem + + #self.parentView.verticalScrollBar().valueChanged.connect(self.repositionAfterScroll) + #self.parentView.horizontalScrollBar().valueChanged.connect(self.repositionAfterScroll) + #def repositionAfterScroll(self): + # Dont use it. Only in here as later template for handling scrollbars. + # + #print(self, self.parentView.mapToScene(0, 0).y()) + # #self.setY(self.parentView.mapToScene(0, 0).y()) + # #self.setX(self.parentView.mapToScene(0, 0).x()) + # self.outline.setX(self.parentView.mapToScene(0, 0).x()) + # self.setY(-1*constantsAndConfigs.trackHeight) + + def createAppendButton(self): + self.appendGraphBlockButtonProxy = self.scene().addWidget(QtWidgets.QPushButton("+TempoBlock")) + self.appendGraphBlockButtonProxy.widget().clicked.connect(api.appendTempoBlock) + self.appendGraphBlockButtonProxy.setParentItem(self) + self.appendGraphBlockButtonProxy.setPos(0,0) #for now. Afterwards it gets updated by updateGraphBlockTrack . + self.appendGraphBlockButtonProxy.setZValue(10) #this is only the z Value within the Timline ItemGroup + + @property + def items(self): + return self.tempoPoints + self.blockEndMarkers + + def createGraphicItemsFromData(self, staticRepresentationList): + """The X position is, as always, a long tickvalue from the + backend. + The tempo value, has its default 0-line on the middle line, which is the track root. + """ + for item in self.items: + item.setParentItem(None) + self.scene().removeWhenIdle(item) + + self.tempoPoints = [] + self.blockEndMarkers = [] + + xOffset = -6 #adjust items font x offsset + y = -30 #The Y Value adjusts for the offset the text-item creates + + for point in staticRepresentationList: + if not point["type"] == "interpolated": #a real user point or lastInBlock or lastInTrack + p = TempoPoint(self, point) + p.setParentItem(self) + p.setPos(point["position"] / constantsAndConfigs.ticksToPixelRatio + xOffset, y) + self.tempoPoints.append(p) + + def updateGraphBlockTrack(self, staticRepresentationList): + """Handles and visualizes block boundaries. + Also sets the dimensions for the whole timeline-rect""" + #{"type" : "GraphBlock", "id":id(block), "name":block.name, "duration":block.duration, "position":tickCounter, "exportsAllItems":block.exportsAllItems()} + + self.blockListCache = staticRepresentationList #sorted list + for dictExportItem in staticRepresentationList: + blockEndMarker = TempoBlockEndMarker(self, dictExportItem) + self.blockEndMarkers.append(blockEndMarker) + #Position is the block start. We create an end-marker so we need to add the blocks duration. + blockEndMarker.setParentItem(self) + rightBorder = (dictExportItem["duration"] + dictExportItem["position"]) / constantsAndConfigs.ticksToPixelRatio + blockEndMarker.setX(rightBorder) + + #rightBorder is still the last item in the list, so it is the end of the timeline + r = self.rect() + r.setRight(rightBorder) + self.setRect(r) + + if not self.appendGraphBlockButtonProxy: #the append button is a widget, not a QGraphicsItem. So we can only add it after we have a complete scene. + self.createAppendButton() + self.appendGraphBlockButtonProxy.setX((dictExportItem["duration"] + dictExportItem["position"]) / constantsAndConfigs.ticksToPixelRatio + 10) + + def add(self, scenePos): + """Use a scenePos (from a mousePress) to instruct the backend + to create a new tempo point. + + We must first figure out on our own in which block we want + to add the tempo point. + + At the end add() calls the api to generate the new point. + This triggers self.createGraphicItemsFromData which deletes + all points and recreates them. + """ + #y + #y = scenePos.y() + #unitsPerMinute, referenceTicks = self.getYAsBackendValue(y) + unitsPerMinute = 120 + referenceTicks = api.D4 + + #x + sp = scenePos.x() * constantsAndConfigs.ticksToPixelRatio + + if constantsAndConfigs.snapToGrid: + sp = round(sp / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + + api.insertTempoItemAtAbsolutePosition(sp, unitsPerMinute, referenceTicks) + + +class TempoPoint(QtWidgets.QGraphicsTextItem): + """A point where the values can be edited by the user""" + + def __init__(self, parentTempoTrack, staticExportItem): + super().__init__("") #x,y,w,h + self.staticExportItem = staticExportItem + self.parentTempoTrack = parentTempoTrack + + if not self.staticExportItem["positionInBlock"] == 0: + self.setAcceptHoverEvents(True) + self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable) + self.setCursor(QtCore.Qt.SizeHorCursor) #this sets the cursor while the mouse is over the item. It is independent of AcceptHoverEvents + else: + self.ungrabMouse = api.nothing #to surpress a warning from the context menu + + self.setFont(constantsAndConfigs.musicFont) + self.setHtml("{}".format(constantsAndConfigs.realNoteDisplay[staticExportItem["referenceTicks"]])) + + self.number = QtWidgets.QGraphicsTextItem("") + self.number.setParentItem(self) + self.number.setHtml("{}".format(str(int(staticExportItem["unitsPerMinute"])))) + self.number.setPos(0,0) + + if not self.staticExportItem["graphType"] == "standalone": + self.arrow = QtWidgets.QGraphicsSimpleTextItem("⟶") #unicode long arrow right #http://xahlee.info/comp/unicode_arrows.html + self.arrow.setParentItem(self) + self.arrow.setPos(13,30) + + def getXDifferenceAsBackendValue(self): + """The problem is that we need the position relativ to its + parent block, which we don't use in that way in the GUI. + So we calculate the difference to the old position""" + + oldPositionAbsolute = int(self.staticExportItem["position"]) + newPositionAbsolute = self.pos().x() * constantsAndConfigs.ticksToPixelRatio + if constantsAndConfigs.snapToGrid: + newPositionAbsolute = round(newPositionAbsolute / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + diff = int(-1 * (oldPositionAbsolute - newPositionAbsolute)) + return diff + + def hoverEnterEvent(self, event): + """To prevent score-item deletion the timeline itself + has a hover event as well that deactivates the score delete + key so we can use it safely for tempoPoints""" + self.grabKeyboard() + #self.setFocus() #do NOT set the focus. GrabKeyboard is enough. The focus will stay even after hoverLeaveEvent so that Delete will delete the last hovered item. not good! + + def hoverLeaveEvent(self, event): + """reverse hoverEnterEvent""" + self.ungrabKeyboard() + + def keyPressEvent(self, event): + """Handle the delete item key. Only works if the item + has the keyboard focus. We grab that on hoverEnter.""" + key = event.key() + + if key == 16777223 and not self.staticExportItem["lastInBlock"] and not self.staticExportItem["positionInBlock"] == 0: + #self.scene().parentView.mainWindow.ui.actionDelete.setEnabled(True) #we never reach hoverLeave since this item gets delete. So re-enable Score-Item delete here. + api.removeTempoItem(self.staticExportItem["id"]) + + def mousePressEvent(self, event): + """Pressing the mouse button is the first action of drag + and drop. We make the mouse cursor invisible so the user + can see where the point is going""" + super().mousePressEvent(event) + self.lastPos = self.pos() + #if event.button() == 1: # QtCore.Qt.MouseButton.LeftButton + # self.setCursor(QtCore.Qt.BlankCursor) + + def wheelEvent(self, event): + if event.delta() > 0: + delta = 1 + else: + delta = -1 + api.changeTempoItem(self.staticExportItem["id"], 0, self.staticExportItem["unitsPerMinute"] + delta, self.staticExportItem["referenceTicks"]) + #super().wheelEvent(event) #if this gets called the graphicView scrolls. + + def mouseReleaseEvent(self, event): + """After moving a point around + send an update to the backend""" + super().mouseReleaseEvent(event) + + if event.button() == 1: # QtCore.Qt.MouseButton.LeftButton + moveInTicks = self.getXDifferenceAsBackendValue() #handles snapToGrid + self.parentTempoTrack.lastTouchedReferenceTicks = self.staticExportItem["referenceTicks"] #used in parentTempoTrack.add() + #event.scenePos().y()) is the mouseCursor, not the item. Since the cursor and the item don't need to be on the same position (the user can't even see the cursor while moving) we need the item.y() + unitsPerMinute = self.staticExportItem["unitsPerMinute"] #stays the same + referenceTicks = self.staticExportItem["referenceTicks"] #stays the same + api.changeTempoItem(self.staticExportItem["id"], moveInTicks, unitsPerMinute, referenceTicks) + + def mouseMoveEvent(self, event): + """Only active when the item is also selected and left + mouse button is down. Not any mouse event, no hover.""" + super().mouseMoveEvent(event) + self.setY(self.lastPos.y()) #only the X axis can be changed. Point can only be moved left and right. + + absoluteXPosition = self.x() * constantsAndConfigs.ticksToPixelRatio + withinBlock = self.staticExportItem["minPossibleAbsolutePosition"] <= absoluteXPosition <= self.staticExportItem["maxPossibleAbsolutePosition"] + if not withinBlock: + if absoluteXPosition < self.staticExportItem["minPossibleAbsolutePosition"]: + self.setX(self.staticExportItem["minPossibleAbsolutePosition"] / constantsAndConfigs.ticksToPixelRatio) + else: + self.setX(self.staticExportItem["maxPossibleAbsolutePosition"] / constantsAndConfigs.ticksToPixelRatio) + + self.globalCursorToItem("x") + + def globalCursorToItem(self, xOrY): + """Make mouse cursor movement not weird when going over the boundaries. + We essentially make self the cursor that cannot leave the rectangle.""" + a = self.scene().parentView.mapFromScene(self.pos()) + b = self.scene().parentView.viewport().mapToGlobal(a) + + if xOrY == "x": + QtGui.QCursor.setPos(b.x(), QtGui.QCursor.pos().y()) + else: + QtGui.QCursor.setPos(QtGui.QCursor.pos().x(), b.y()) + + def contextMenuEvent(self, event): + menu = QtWidgets.QMenu() + + listOfLabelsAndFunctions = [ + ("interpolation type", self.changeInterpolationType), + ("units per minute", self.changeTempoUnits), + ("reference note", self.changeTempoReference), + ] + if not self.staticExportItem["positionInBlock"] == 0: + listOfLabelsAndFunctions.append(("delete", lambda: api.removeTempoItem(self.staticExportItem["id"]))) + + for text, function in listOfLabelsAndFunctions: + if text == "separator": + self.addSeparator() + else: + a = QtWidgets.QAction(text, menu) + menu.addAction(a) + a.triggered.connect(function) + + pos = QtGui.QCursor.pos() + pos.setY(pos.y() + 5) + self.ungrabMouse() #if we don't ungrab and the user clicks the context menu "away" by clicking in an empty area this will still get registered as mouseclick belonging to the current item + menu.exec_(pos) + + def mouseDoubleClickEvent(self, event): + self.changeTempoUnits() + + def changeInterpolationType(self): + li = api.getListOfGraphInterpolationTypesAsStrings() + graphTypeString = QtWidgets.QInputDialog.getItem(self.scene().parentView, "Interpolation Type", "choose Interpolation Type", li, li.index(self.staticExportItem["graphType"]), False) #list and default value from that list + if graphTypeString[1]: #[1] bool if canceled + api.changeTempoItemInterpolation(self.staticExportItem["id"], graphTypeString[0]) + + def changeTempoUnits(self): + #TODO: unify changeTempoUnits and changeTempoReference + self.parentTempoTrack.lastTouchedReferenceTicks = self.staticExportItem["referenceTicks"] + unitsPerMinute = self.staticExportItem["unitsPerMinute"] + referenceTicks = self.staticExportItem["referenceTicks"] + ccValue = QtWidgets.QInputDialog.getInt(self.scene().parentView, "Units per Minute", "how many reference notes per minute?", value=unitsPerMinute, min=20, max=999) + if ccValue[1]: #[1] bool if canceled + moveInTicks = self.getXDifferenceAsBackendValue() + unitsPerMinute = ccValue[0] + api.changeTempoItem(self.staticExportItem["id"], moveInTicks, unitsPerMinute, referenceTicks) + + def changeTempoReference(self): + #TODO: unify changeTempoUnits and changeTempoReference + self.parentTempoTrack.lastTouchedReferenceTicks = self.staticExportItem["referenceTicks"] + unitsPerMinute = self.staticExportItem["unitsPerMinute"] + referenceTicks = self.staticExportItem["referenceTicks"] + rhythmString = QtWidgets.QInputDialog.getItem(self.scene().parentView, "Reference Note", "What is the reference note for the tempo?", constantsAndConfigs.prettyExtendedRhythmsStrings, constantsAndConfigs.prettyExtendedRhythmsValues.index(referenceTicks), False) + if rhythmString[1]: #bool. Canceled? + for k, v in constantsAndConfigs.prettyExtendedRhythms: + if v == rhythmString[0]: + moveInTicks = self.getXDifferenceAsBackendValue() + referenceTicks = k + self.parentTempoTrack.lastTouchedReferenceTicks = k + api.changeTempoItem(self.staticExportItem["id"], moveInTicks, unitsPerMinute, referenceTicks) + + +class TempoBlockEndMarker(QtWidgets.QGraphicsLineItem): + def __init__(self, parentCCPath, staticExportItem): + #super().__init__(0,-1*parentCCPath.rect().height(),0, parentCCPath.rect().height()) #x1, y1, x2, y2 + super().__init__(0,-1, 0, parentCCPath.rect().height() + 4) #x1, y1, x2, y2 + assert not self.line().isNull() #needed to do self.line().setLength(x) + self.parentCCPath = parentCCPath + self.staticExportItem = staticExportItem + self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable|QtWidgets.QGraphicsItem.ItemSendsGeometryChanges|QtWidgets.QGraphicsItem.ItemIsFocusable|QtWidgets.QGraphicsItem.ItemClipsToShape) + self.setAcceptHoverEvents(True) + self.setCursor(QtCore.Qt.SizeHorCursor) + #self.setBrush(QtGui.QColor("red")) + pen = QtGui.QPen() # creates a default pen + if not self.staticExportItem["exportsAllItems"]: + pen.setStyle(QtCore.Qt.DotLine) + pen.setWidth(2) + self.setPen(pen) + + self.inactivePen = pen + self.inactivePen.setColor(QtGui.QColor("black")) + + self.activePen = QtGui.QPen(pen) + self.activePen.setColor(QtGui.QColor("cyan")) + + def shape(self): + """Return a more accurate shape for this item so that + mouse hovering is more accurate""" + path = QtGui.QPainterPath() + path.addRect(QtCore.QRectF(-2, -2, 4, self.parentCCPath.rect().height() + 4 )) #this is directly related to inits parameter x, y, w, h + return path + + def hoverEnterEvent(self, event): + self.setPen(self.activePen) + + def hoverLeaveEvent(self, event): + self.setPen(self.inactivePen) + + def allItemsRightOfMe(self): + for item in self.parentCCPath.items: + if item.x()+7 >= self.x(): + yield item + + def itemsLeftAndRightOfMe(self): + left = [] + right = [] + for item in self.parentCCPath.items: + if item.x()+7 >= self.x(): + right.append(item) + else: + left.append(item) + return left, right + + def mousePressEvent(self, event): + super().mousePressEvent(event) + self.lastPos = self.pos() + self.itemsLeft, self.itemsRight = self.itemsLeftAndRightOfMe() + + #if event.button() == 1: # QtCore.Qt.MouseButton.LeftButton + # for i in self.allItemsRightOfMe(): + # i.hide() + # self.parentCCPath.appendGraphBlockButtonProxy.hide() + + def mouseMoveEvent(self, event): + """Only active when the item is also selected and left + mouse button is down. Not any mouse event, no hover. + + This does not actually change the backend items. The change is done on mouseRelease""" + super().mouseMoveEvent(event) + self.setY(self.lastPos.y()) + + delta = event.scenePos() - event.lastScenePos() + deltaX = delta.x() + + endingRelativeToBlockStart = self.x() * constantsAndConfigs.ticksToPixelRatio - self.staticExportItem["position"] + + if deltaX < 0 and endingRelativeToBlockStart < api.D1: #some musical sanity. Also prevents that the block gets a negative duration and the backends throws an exception + event.accept() + return None + + for item in self.itemsRight: + item.moveBy(deltaX, 0) + for item in self.itemsLeft: + if item.x() + 15 >= self.x(): + item.hide() + + #self.parentCCPath.appendGraphBlockButtonProxy.moveBy(deltaX, 0) + self.parentCCPath.appendGraphBlockButtonProxy.hide() + + def mouseReleaseEvent(self, event): + """After moving a point around + send an update to the backend""" + super().mouseReleaseEvent(event) + if event.button() == 1: # QtCore.Qt.MouseButton.LeftButton + self.parentCCPath.appendGraphBlockButtonProxy.show() + endingRelativeToBlockStart = self.x() * constantsAndConfigs.ticksToPixelRatio - self.staticExportItem["position"] + if constantsAndConfigs.snapToGrid: + endingRelativeToBlockStart = round(endingRelativeToBlockStart / constantsAndConfigs.gridRhythm) * constantsAndConfigs.gridRhythm + + assert endingRelativeToBlockStart > 0 + api.changeTempoBlockDuration(self.staticExportItem["id"], endingRelativeToBlockStart) + + def deactivate_contextMenuEvent(self, event): + menu = QtWidgets.QMenu() + + listOfLabelsAndFunctions = [ + ("restore to full duration ", self.contextRestore), + ] + + for text, function in listOfLabelsAndFunctions: + if text == "separator": + self.addSeparator() + else: + a = QtWidgets.QAction(text, menu) + menu.addAction(a) + a.triggered.connect(function) + + pos = QtGui.QCursor.pos() + pos.setY(pos.y() + 5) + self.ungrabMouse() #if we don't ungrab and the user clicks the context menu "away" by clicking in an empty area this will still get registered as mouseclick belonging to the current item + menu.exec_(pos) + + def contextRestore(self): + print (self.staticExportItem) + #api.changeTempoBlockDuration(self.staticExportItem["id"], endingRelativeToBlockStart) diff --git a/qtgui/trackEditor.py b/qtgui/trackEditor.py new file mode 100644 index 0000000..30ae541 --- /dev/null +++ b/qtgui/trackEditor.py @@ -0,0 +1,441 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright 2017, Nils Hilbricht, Germany ( https://www.hilbricht.net ) + +This file is part of Laborejo ( https://www.laborejo.org ) + +Laborejo 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 . +""" + +from PyQt5 import QtWidgets, QtCore, QtGui +from .designer.trackWidget import Ui_trackGroupWidget +from .constantsAndConfigs import constantsAndConfigs +from template.helper import pairwise +from .submenus import TickWidget, CombinedTickWidget +from contextlib import contextmanager +import engine.api as api + + +class TrackWidget(QtWidgets.QGroupBox): + #TODO: ideas: number of blocks, which CCs are set, review/change durationSettingsSignature, dynamicSettingsSignature + def __init__(self, parentDataEditor, trackExportObject): + super().__init__() + self.parentDataEditor = parentDataEditor + self.trackExportObject = trackExportObject + self.ui = Ui_trackGroupWidget() + self.ui.setupUi(self) + + self.setAttribute(QtCore.Qt.WA_DeleteOnClose) + + self.trackExportObject = trackExportObject #updated on every self.updateData + self.ui.visibleCheckbox.clicked.connect(self.visibleToggled) #only user changes, not through setChecked() + self.ui.doubleTrackCheckbox.clicked.connect(self.doubleTrackToggled) #only user changes, not through setChecked() + #self.ui.upbeatSpinBox.editingFinished.connect(self.upbeatChanged) #only user changes, not through setText() etc. + self.ui.upbeatSpinBox.valueChanged.connect(self.upbeatChanged) #also through the tickWidget + self.ui.callTickWidget.clicked.connect(self.callClickWidgetForUpbeat) + self.ui.nameLineEdit.editingFinished.connect(self.nameChanged) #only user changes, not through setText() etc. + self.ui.deleteButton.clicked.connect(lambda: api.deleteTrack(self.trackExportObject["id"])) + + self.ui.midiChannelSpinBox.valueChanged.connect(self.dataChanged) + self.ui.midiProgramSpinBox.valueChanged.connect(self.dataChanged) + self.ui.midiBankMsbSpinBox.valueChanged.connect(self.dataChanged) + self.ui.midiBankLsbSpinBox.valueChanged.connect(self.dataChanged) + self.ui.midiTransposeSpinBox.valueChanged.connect(self.dataChanged) + + self.ui.instrumentName.editingFinished.connect(self.nameChanged) + self.ui.shortInstrumentName.editingFinished.connect(self.nameChanged) + + + #Create a menu with checkboxes to allow switching on and off of additional channels for the CC sub-track + #However, we will not use normal checkable Menu actions since they close the menu after triggering. even blockSignals does not prevent closing + self.ccChannels = [] + ccChannelMenu = QtWidgets.QMenu() + for i in range(0,16): #excluding 16 + checkbox = QtWidgets.QCheckBox(ccChannelMenu) + self.ccChannels.append(checkbox) + checkbox.stateChanged.connect(self.dataChanged) + widget = QtWidgets.QWidget() + layout = QtWidgets.QFormLayout() + layout.setContentsMargins(0,0,0,0) #left, top, right, bottom in pixel + widget.setLayout(layout) + widgetAction = QtWidgets.QWidgetAction(ccChannelMenu) + widgetAction.setDefaultWidget(widget) + layout.addRow(str(i).zfill(2), checkbox) + ccChannelMenu.addAction(widgetAction) + + #action = QtWidgets.QAction(str(i), ccChannelMenu) + #action.setCheckable(True) + #ccChannelMenu.addAction(action) + self.ui.ccChannelsPushButton.setMenu(ccChannelMenu) + + #TODO: The callbacks below trigger quite often. If you move the mouse wheel in a spin box each increase/decrease sends ALL track settings to the backend which triggers a compelte redraw of the track. This should be measure on performance and improved. But even incremental updates should have an immediate effect on a running playback so "send changes when closing the track editor" is only a compromise". Incremental updates are not a a solution either because even those need a playback update. valueChanged does not have an editingFinished signal like text fields. + + #Set up the advanced properties. They should be hidden at the start + #Tab 1: Durations + self.ui.defaultOn.editingFinished.connect(self.dataChanged) #only user changes, not through setText() etc. + self.ui.defaultOff.editingFinished.connect(self.dataChanged) + self.ui.staccatoOn.editingFinished.connect(self.dataChanged) + self.ui.staccatoOff.editingFinished.connect(self.dataChanged) + self.ui.tenutoOn.editingFinished.connect(self.dataChanged) + self.ui.tenutoOff.editingFinished.connect(self.dataChanged) + self.ui.legatoOn.editingFinished.connect(self.dataChanged) + self.ui.legatoOff.editingFinished.connect(self.dataChanged) + + #Tab 2: Dynamics + self.ui.dynamics_ppppp.valueChanged.connect(self.dataChanged) + self.ui.dynamics_pppp.valueChanged.connect(self.dataChanged) + self.ui.dynamics_ppp.valueChanged.connect(self.dataChanged) + self.ui.dynamics_pp.valueChanged.connect(self.dataChanged) + self.ui.dynamics_p.valueChanged.connect(self.dataChanged) + self.ui.dynamics_mp.valueChanged.connect(self.dataChanged) + self.ui.dynamics_mf.valueChanged.connect(self.dataChanged) + self.ui.dynamics_f.valueChanged.connect(self.dataChanged) + self.ui.dynamics_ff.valueChanged.connect(self.dataChanged) + self.ui.dynamics_fff.valueChanged.connect(self.dataChanged) + self.ui.dynamics_ffff.valueChanged.connect(self.dataChanged) + self.ui.dynamics_custom.valueChanged.connect(self.dataChanged) + self.ui.dynamics_tacet.valueChanged.connect(self.dataChanged) + self.ui.dynamics_fp.valueChanged.connect(self.dataChanged) + self.ui.dynamics_sp.valueChanged.connect(self.dataChanged) + self.ui.dynamics_spp.valueChanged.connect(self.dataChanged) + self.ui.dynamics_sfz.valueChanged.connect(self.dataChanged) + self.ui.dynamics_sf.valueChanged.connect(self.dataChanged) + self.ui.dynamics_sff.valueChanged.connect(self.dataChanged) + + self.ui.buttonResetDurations.clicked.connect(lambda: api.resetDuationSettingsSignature(self.trackExportObject["id"])) + self.ui.buttonResetDynamics.clicked.connect(lambda: api.resetDynamicSettingsSignature(self.trackExportObject["id"])) + + #Connect the hide checkbox + self.ui.advanced.toggled.connect(self.advancedToggled) + self.ui.advanced.setChecked(False) + + def visibleToggled(self, signal): + assert signal == bool(self.ui.visibleCheckbox.checkState()) + if signal: + api.unhideTrack(self.trackExportObject["id"]) + else: + api.hideTrack(self.trackExportObject["id"]) + + def doubleTrackToggled(self, signal): + api.setDoubleTrack(self.trackExportObject["id"], signal) + + def advancedToggled(self, bool): + assert bool == self.ui.advanced.isChecked() + if bool: + self.ui.advancedContent.show() + else: + self.ui.advancedContent.hide() + + @contextmanager + def blockUiSignals(self): + """prevent loops by blocking all signals that react on changed states. + Revoked at the end of the calling function. + Strictly this is not needed for signals like .clicked() (compared to .toggled()) but it is + a good last line of defense to prevent future bugs. Those signal-loops are hard to track. + + ADD ALL NEW SUB WIDGETS HERE!!!!! THIS HAPPENED TWICED ALREADY AND WAS A NIGHTMARE TO DEBUG! + SIMPLY USING self.blockSignals(True) HAS NO EFFECT BECAUSE THOSE ARE IN .ui. + self.setUpdatesEnabled(False) doesn't work as well. + self.children() does not return the right children either, self.ui() is a python object, + not a qt widget.""" + + for widget in self.ui.__dict__.values(): + widget.blockSignals(True) + for checkbox in self.ccChannels: + checkbox.blockSignals(True) + yield + for widget in self.ui.__dict__.values(): + widget.blockSignals(False) + for checkbox in self.ccChannels: + checkbox.blockSignals(False) + + def callClickWidgetForUpbeat(self): + dialog = TickWidget(self.parentDataEditor, initValue = self.ui.upbeatSpinBox.value()) + self.ui.upbeatSpinBox.setValue(dialog.ui.ticks.value()) + + def nameChanged(self): + """When enter is pressed or focus is lost""" + t = self.ui.nameLineEdit.text() + name = self.ui.instrumentName.text() + short = self.ui.shortInstrumentName.text() + api.setTrackName(self.trackExportObject["id"], nameString = t, initialInstrumentName = name, initialShortInstrumentName = short) + + def upbeatChanged(self): + """When enter is pressed or focus is lost""" + v = self.ui.upbeatSpinBox.value() + api.setTrackUpbeat(self.trackExportObject["id"], v) + + def dataChanged(self): + with self.blockUiSignals(): + dictionary = {} + dictionary["initialMidiChannel"] = self.ui.midiChannelSpinBox.value() + dictionary["initialMidiProgram"] = self.ui.midiProgramSpinBox.value() + dictionary["initialMidiBankMsb"] = self.ui.midiBankMsbSpinBox.value() + dictionary["initialMidiBankLsb"] = self.ui.midiBankLsbSpinBox.value() + dictionary["ccChannels"] = tuple(i for i, checkbox in enumerate(self.ccChannels) if checkbox.checkState()) + dictionary["midiTranspose"] = self.ui.midiTransposeSpinBox.value() + + dictionary["duration.defaultOn"] = self.ui.defaultOn.text() + dictionary["duration.defaultOff"] = self.ui.defaultOff.text() + dictionary["duration.staccatoOn"] = self.ui.staccatoOn.text() + dictionary["duration.staccatoOff"] = self.ui.staccatoOff.text() + dictionary["duration.tenutoOn"] = self.ui.tenutoOn.text() + dictionary["duration.tenutoOff"] = self.ui.tenutoOff.text() + dictionary["duration.legatoOn"] = self.ui.legatoOn.text() + dictionary["duration.legatoOff"] = self.ui.legatoOff.text() + + dictionary["dynamics.ppppp"] = self.ui.dynamics_ppppp.value() + dictionary["dynamics.pppp"] = self.ui.dynamics_pppp.value() + dictionary["dynamics.ppp"] = self.ui.dynamics_ppp.value() + dictionary["dynamics.pp"] = self.ui.dynamics_pp.value() + dictionary["dynamics.p"] = self.ui.dynamics_p.value() + dictionary["dynamics.mp"] = self.ui.dynamics_mp.value() + dictionary["dynamics.mf"] = self.ui.dynamics_mf.value() + dictionary["dynamics.f"] = self.ui.dynamics_f.value() + dictionary["dynamics.ff"] = self.ui.dynamics_ff.value() + dictionary["dynamics.fff"] = self.ui.dynamics_fff.value() + dictionary["dynamics.ffff"] = self.ui.dynamics_ffff.value() + dictionary["dynamics.custom"] = self.ui.dynamics_custom.value() + dictionary["dynamics.tacet"] = self.ui.dynamics_tacet.value() + dictionary["dynamics.fp"] = self.ui.dynamics_fp.value() + dictionary["dynamics.sp"] = self.ui.dynamics_sp.value() + dictionary["dynamics.spp"] = self.ui.dynamics_spp.value() + dictionary["dynamics.sfz"] = self.ui.dynamics_sfz.value() + dictionary["dynamics.sf"] = self.ui.dynamics_sf.value() + dictionary["dynamics.sff"] = self.ui.dynamics_sff.value() + + if not self.trackExportObject == dictionary: #checks for keys and values + api.setTrackSettings(self.trackExportObject["id"], dictionary) + #else: no change + + def updateData(self, trackExportObject): + """Receives api updates. Change GUI fields accordingly""" + self.trackExportObject = trackExportObject + + with self.blockUiSignals(): + self.trackExportObject = trackExportObject + self.ui.upbeatSpinBox.setValue(trackExportObject["upbeatInTicks"]) + self.ui.nameLineEdit.setText(trackExportObject["name"]) + self.ui.midiChannelSpinBox.setValue(trackExportObject["initialMidiChannel"]) + self.ui.midiProgramSpinBox.setValue(trackExportObject["initialMidiProgram"]) + self.ui.midiBankMsbSpinBox.setValue(trackExportObject["initialMidiBankMsb"]) + self.ui.midiBankLsbSpinBox.setValue(trackExportObject["initialMidiBankLsb"]) + self.ui.midiTransposeSpinBox.setValue(trackExportObject["midiTranspose"]) + self.ui.instrumentName.setText(trackExportObject["initialInstrumentName"]) + self.ui.shortInstrumentName.setText(trackExportObject["initialShortInstrumentName"]) + + self.ui.defaultOn.setText(trackExportObject["duration.defaultOn"]) + self.ui.defaultOff.setText(trackExportObject["duration.defaultOff"]) + self.ui.staccatoOn.setText(trackExportObject["duration.staccatoOn"]) + self.ui.staccatoOff.setText(trackExportObject["duration.staccatoOff"]) + self.ui.tenutoOn.setText(trackExportObject["duration.tenutoOn"]) + self.ui.tenutoOff.setText(trackExportObject["duration.tenutoOff"]) + self.ui.legatoOn.setText(trackExportObject["duration.legatoOn"]) + self.ui.legatoOff.setText(trackExportObject["duration.legatoOff"]) + + self.ui.dynamics_ppppp.setValue(trackExportObject["dynamics.ppppp"]) + self.ui.dynamics_pppp.setValue(trackExportObject["dynamics.pppp"]) + self.ui.dynamics_ppp.setValue(trackExportObject["dynamics.ppp"]) + self.ui.dynamics_pp.setValue(trackExportObject["dynamics.pp"]) + self.ui.dynamics_p.setValue(trackExportObject["dynamics.p"]) + self.ui.dynamics_mp.setValue(trackExportObject["dynamics.mp"]) + self.ui.dynamics_mf.setValue(trackExportObject["dynamics.mf"]) + self.ui.dynamics_f.setValue(trackExportObject["dynamics.f"]) + self.ui.dynamics_ff.setValue(trackExportObject["dynamics.ff"]) + self.ui.dynamics_fff.setValue(trackExportObject["dynamics.fff"]) + self.ui.dynamics_ffff.setValue(trackExportObject["dynamics.ffff"]) + self.ui.dynamics_custom.setValue(trackExportObject["dynamics.custom"]) + self.ui.dynamics_tacet.setValue(trackExportObject["dynamics.tacet"]) + self.ui.dynamics_fp.setValue(trackExportObject["dynamics.fp"]) + self.ui.dynamics_sp.setValue(trackExportObject["dynamics.sp"]) + self.ui.dynamics_spp.setValue(trackExportObject["dynamics.spp"]) + self.ui.dynamics_sfz.setValue(trackExportObject["dynamics.sfz"]) + self.ui.dynamics_sf.setValue(trackExportObject["dynamics.sf"]) + self.ui.dynamics_sff.setValue(trackExportObject["dynamics.sff"]) + + if trackExportObject["initialMidiProgram"] >= 0: + self.ui.midiBankMsbSpinBox.setEnabled(True) + self.ui.midiBankLsbSpinBox.setEnabled(True) + else: + self.ui.midiBankMsbSpinBox.setEnabled(False) + self.ui.midiBankLsbSpinBox.setEnabled(False) + + #hidden position can be 0 as well. So don't bool, check for None explicitely. + if trackExportObject["hiddenPosition"] is None: #visible + self.ui.visibleCheckbox.setChecked(True) + self.ui.deleteButton.setEnabled(True) + else: + self.ui.visibleCheckbox.setChecked(False) + self.ui.deleteButton.setEnabled(False) #You cannot delete hidden tracks. see api.deleteTrack + + self.ui.doubleTrackCheckbox.setChecked(trackExportObject["double"]) + + for i in range(0,16): #without 16 + self.ccChannels[i].setChecked(i in trackExportObject["ccChannels"]) #a checkbox widget + +class TrackEditor(QtWidgets.QWidget): + """Created by ControlMainWindow. One permanent instance""" + def __init__(self, mainWindow): + super().__init__() + self.mainWindow = mainWindow + + self.layout = QtWidgets.QVBoxLayout() + self.layout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) + self.setLayout(self.layout) + + api.callbacks.tracksChangedIncludingHidden.append(self.updateTrackWidgets) + self.tracks = {} #id:trackWidget. As any dict, not in order + + #Upbeat Tick Widget and Action-Button + allUpbeats = QtWidgets.QWidget() + allUpbeatsLayout = QtWidgets.QHBoxLayout() + allUpbeatsLayout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) + allUpbeats.setLayout(allUpbeatsLayout) + self.layout.addWidget(allUpbeats) + + self.allUpbeatsCombinedTickWidget = CombinedTickWidget() + + allUpbeatsPushButton = QtWidgets.QPushButton("set all upbeats") + allUpbeatsPushButton.clicked.connect(self.setAllUpbeats) #gets the value itself + + allUpbeatsLayout.addWidget(self.allUpbeatsCombinedTickWidget) + allUpbeatsLayout.addWidget(allUpbeatsPushButton) + + #Reset all Advanced Views + foldAllAdvanvced = QtWidgets.QPushButton("fold all advanced") + foldAllAdvanvced.clicked.connect(self.foldAllAdvanvced) + allUpbeatsLayout.addWidget(foldAllAdvanvced) + + unfoldAllAdvanvced = QtWidgets.QPushButton("unfold all advanced") + unfoldAllAdvanvced.clicked.connect(self.unfoldAllAdvanced) + allUpbeatsLayout.addWidget(unfoldAllAdvanvced) + + def updateTrackWidgets(self, listOfStaticTrackRepresentations): + """React to the backend adding, deleting, hiding or moving tracks. + A track widget persists until the track gets deleted. No re-creation on every change. """ + leftOver = list(self.tracks.keys()) + visibleTracks = [] + nameLineEditsInOrder = [] + upbeatSpinBoxsInOrder = [] + for trackExportObject in listOfStaticTrackRepresentations: + #First are all normal, visible tracks. + #After that the tracks have a property "hiddenPosition" for hidden tracks that need individual sorting. + if not trackExportObject["id"] in self.tracks: #A brand new track + widget = TrackWidget(self, trackExportObject) + self.tracks[trackExportObject["id"]] = widget + self.layout.insertWidget(-1, widget) + widget.setTitle("id: {}".format(trackExportObject["id"])) + else: + leftOver.remove(trackExportObject["id"]) + + self.tracks[trackExportObject["id"]].ui.deleteButton.setEnabled(True) + self.tracks[trackExportObject["id"]].blockSignals(True) + self.tracks[trackExportObject["id"]].updateData(trackExportObject) #This has a sideeffect of updating widgets, which will change backend data and trigger a recursive updateTrackWidgets. We need to block the signals. self.tracks has the track widgets. + self.tracks[trackExportObject["id"]].blockSignals(False) + nameLineEditsInOrder.append(self.tracks[trackExportObject["id"]].ui.nameLineEdit) + + if trackExportObject["hiddenPosition"] is None: + visibleTracks.append(trackExportObject) + + for trId in leftOver: #track still exist here but not in the backend. Delete. + w = self.tracks[trId] + del self.tracks[trId] + w.setParent(None) + w.close() + + #Create tab order. Those work in pairs, linked list. a before b. And multiple of those pairs need to be in order itself. + if len(nameLineEditsInOrder) > 1: + for pair in pairwise(nameLineEditsInOrder): + self.setTabOrder(*pair) #takes exactly two arguments + + if len(visibleTracks) == 1: + w = self.tracks[visibleTracks[0]["id"]] + w.ui.deleteButton.setEnabled(False) #it is not possible to delete the only visible track. The backend will prevent it but we don't even offer the choice here. + + def setAllUpbeats(self): + for trackWidget in self.tracks.values(): + trackWidget.ui.upbeatSpinBox.setValue(self.allUpbeatsCombinedTickWidget.value()) + + def foldAllAdvanvced(self): + for trackWidget in self.tracks.values(): + trackWidget.ui.advanced.setChecked(False) + + def unfoldAllAdvanced(self): + for trackWidget in self.tracks.values(): + trackWidget.ui.advanced.setChecked(True) + + + def keyPressEvent(self, event): + """Escape closes the track editor""" + k = event.key() #49=1, 50=2 etc. + if k == QtCore.Qt.Key_Escape: + self.mainWindow.ui.actionData_Editor.setChecked(False) + self.mainWindow.toggleMainView() + super().keyPressEvent(event) + +""" +api.callbacks.updateBlockTrack.append(lambda trId, blocksExportData: self.tracks[trId].blockScene.regenerateBlocks(blocksExportData)) + +class TrackBlockScene(QtWidgets.QGraphicsScene): + def __init__(self, parentWidget): + super().__init__() + self.blocks = [] + self.parentWidget = parentWidget + + + def mousePressEvent(self, event): + button = event.button() + if button == 1: #left + self.setEnabled(False) + super().mousePressEvent(event) + + def mouseReleaseEvent(self, event): + button = event.button() + if button == 1: #left + self.setEnabled(True) + super().mouseReleaseEvent(event) + + def regenerateBlocks(self, blocksExportData): + self.clear() + self.blocks = [] + + dur = 0 + for backendBlock in blocksExportData: + b = BlockGraphicsItem(self, backendBlock) + self.blocks.append(b) + self.addItem(b) + b.setPos(backendBlock["tickindex"] / constantsAndConfigs.blocksTicksToPixelRatio, 0) + dur += backendBlock["completeDuration"] + + self.parentWidget.ui.blocks.setFixedSize(dur / constantsAndConfigs.blocksTicksToPixelRatio, 30) + + +class BlockGraphicsItem(QtWidgets.QGraphicsRectItem): + def __init__(self, parentTrackWidget, blockExportObject): + width = blockExportObject["completeDuration"] / constantsAndConfigs.blocksTicksToPixelRatio + super().__init__(0,0,width, 30) #x, y, w, h + + self.setBrush(self.stringToColor(blockExportObject["name"])) + #self.setFlags(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges|QtWidgets.QGraphicsItem.ItemIsFocusable) + #self.setCursor(QtCore.Qt.SizeAllCursor) + + def stringToColor(self, st): + if st: + c = md5(st.encode()).hexdigest() + return QtGui.QColor(int(c[0:9],16) % 255, int(c[10:19],16) % 255, int(c[20:29],16)% 255, 255) + else: + return QtGui.QColor(255,255,255,255) #Return White +""" + diff --git a/template b/template index 2efd090..f7cec49 160000 --- a/template +++ b/template @@ -1 +1 @@ -Subproject commit 2efd0901226c58dd392c296457667d46c35eebd8 +Subproject commit f7cec498f73fe1c96d77ae0829678702e0b85c0b