diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f804fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea/ +build/ +dist/ +.github/ +pybtc.egg-info/ + 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/README.md b/README.md index d2e8196..94742d6 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,49 @@ -# BitcoinCorePython -In this repository I work on a modified version of the bitcoin core pyflo. The goal is to cross verify message signatures between pyflo and ranchi mall standard operations. + -Repositories Cloned for the Project - +## Python bitcoin library -PyBTC - https://github.com/bitaps-com/pybtc +Current version is 2.0 -PyFLO by RanchiMallFLO - https://github.com/ranchimall/pyflo -KeySharing by RanchiMallFLO +### Feature Support -Standard Operations - https://github.com/ranchimall/Standard_Operations +* Basic functions +* Supports addresses types PUBKEY, P2PKH, P2SH, P2SH-PWPKH, P2WPKH, P2WSH. +* Supports BIP32(Hierarchical Deterministic Wallets), BIP39(Mnemonic code generation) +* Supports BIP141(Segregated Witness) +* Transaction constructor -Task - -The PyFLO library is a fork of PyBTC updated for use on the FLO Blockchain. -Standard Operations, is written in JavaScript and produces an ECDSA Signature on the secp256k1 curve. +### Installation + +To install pybtc, simply use pip + + $ git clone https://github.com/bitaps-com/pybtc + $ cd pybtc + $ python3 setup.py install + +### Dependencies + +* Python 3.3.3+ +* secp256k1 + + +### Documentation + +Documentation is available at https://pybtc.readthedocs.io + + +### How to Contribute + +In order to make a clone of the GitHub repo: open the link and press the “Fork” button on the upper-right menu of the web page. + +Workflow is pretty straightforward: + +1. Clone the GitHub +2. Make a change +3. Make sure all tests passed +4. Add a record into file into change.log. +5. Commit changes to own pybtc clone +6. Make pull request from github page for your clone against master branch + -The task is to convert the signature functions in the PyFLO library so that they can be crossverified with standard operations diff --git a/Standard_Operations b/Standard_Operations deleted file mode 160000 index 790db7d..0000000 --- a/Standard_Operations +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 790db7d2768c95a6143a2aaefb162cedd11ed911 diff --git a/change.log b/change.log new file mode 100644 index 0000000..88bd014 --- /dev/null +++ b/change.log @@ -0,0 +1,2 @@ +12094bf6a3badf1c2eccd4446cea3a89fa7220c4 added pubkey address generation to Address class with pubkey script field +28254bc38c46c33b04d8204a2117ed1091364998 bare multisig input signing diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000..8e254e6 Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..be4e7b6 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = pybtc +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/img/.DS_Store b/docs/img/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/docs/img/.DS_Store differ diff --git a/docs/img/address_map.jpg b/docs/img/address_map.jpg new file mode 100644 index 0000000..cd6036b Binary files /dev/null and b/docs/img/address_map.jpg differ diff --git a/docs/img/address_map.xml b/docs/img/address_map.xml new file mode 100644 index 0000000..ddf3850 --- /dev/null +++ b/docs/img/address_map.xml @@ -0,0 +1 @@ +lHzXtpzKsuXX7Nc78OYRbwpbULg3vDeFh69vckk6Z+97um93l6S1igSSNBEz5oxM9BfK9ac0x1Olj1ne/YVA2fkXyv+FIDAJQc8vUHL9KqFJ8ldBOdfZ74v+XeDUd/678Pd95VZn+fKPC9dx7NZ6+mdhOg5Dnq7/KIvneTz+eVkxdv986hSX+X8UOGnc/WepX2dr9bsUJuh/n5Dzuqx+P5pCfvcvidO2nMdt+P28vxC0+Pn8Ot3Hf+r63dGlirPx+FsRKvyFcvM4rr++9SeXd2Bs/wzbr/vE/8PZf7V7zof1/+kG+neP9rjb8j9t/mnZev0ZjXzIGDCoz1HaxctSp3+hbLX23VMAP1+XdR7bnBu7cf65AYV+Pv8682cIn96xxTisf7sS48Gfpzw/6zV4yqD/wn8fhb9r/xnNHLQX1Pj0a77+diE4DH+f+9XwPPuPuf33aPwxpngu8z9FKPavgX8MOh/7/Knzuej498zjv6er+tuc/ymb8y5e6/2fz4x/G2D5r+r+9QRrrJ/WINBvZ6FI9L8wkoBp6PfPXxX8dhycQv8LR1AKon///Gf1y7jNaf67xr9P8397yOOR/6iW+NP4PxX9GpD/qOiZ9vj622UTuGD5Hzvzz+eg0P+lXcT/dP3z5VcL/hz9bX7+XfRj0v978yb+78b9eOAEvtb9DyawP7+ZZfoFK8Cs4j8HRX0CO2T3fF7rByy0OMk7a1zqtR6H53wyruvY/+0CpqtLcGIdp/8PNwFGX9Rd9+fKYRxAw8o5zur8397zu/h3u/ksXuO/UObXISJOQ/kXwtUea74P6CWVI/N8DOdTCZ/y+eaDQ5HgmBB8GTTldT6/tb8QVup4G2ZVG9LLj6zuUd8tkc0wjtJ73pGFH6r1h2HdpVpQ1cCemNjWoLItn+/CFBqlcjlsxao1V07I27vZNWYel/Ei0d6IVxv4dfnRahIJ2Ev5vp7HrfURJq/+fB8ZipLonvYo4j7lIGCIz9+BH4ZbvUnUlhh6Cldh8+u+5FsuDurnMospz6/7MZj45IiSV74M/zz7Mt/K+3WHiLQwiGUR8J4somB1GOqJ22MT4j48P0hvSoPW4UtW0XQ7Cph2eGaF1XhG4lGTe50iw1OvpUruyXnhbHPZQqrLoYvt7Dm8CoE3U9zGBkJUGwEMHMNwfMk4VQr50SE+DRO4dykMHP2tzI+1aKb9qlhusJ9rbwtLTFyQnq9iLpx5MGPpChlL/zRLGEz4sWFxidoznCzjrmb26spP87brVqkuJAyes9E9Pzdn1K51NrKHtkBWzlNg1moh85aJvK70ucoZCVhxse+tluH4nFZIVrzEYHlARsQfIG9r3n/sRCzX9/lKp8Ue+3Qxa0/9fpRwUbG+wzo0ChcvZbCyYQ1NOSWJNnk6j9608cwPG5mdSmkfrO4KkWhlQy+1LVPtyvikZNZzi1J7xdwrA17X7ewGNasM38ZBVatVBWciNWrDyszypPFou9J/+iQqEUQtn4r6zHRWh5YycMbdFkcPrMGH9peLXTZ+JFfs3upkVtWwLBrnBZOODtzE2N5Qmw67fKzzCl5edJ5snnTVd7/qyNO4SuW8pPK5p9NsyDVZv1CF/N1ZvHXfiMpTpRTavNgzjPBmeCYt2URkoJsPxtVI8ol3XORrf89KVEZOSagXg/DQm08ceQmbKnnqDO7QKwlIFYuurJWWbw/mKf0wiuS0YEII3POH67u8sjo1MUwdCZGjeBxrzgMt32hZoks2sizFxZjAnzI+G4xacWU18DRp0ku0cDAer/cYfEyM2+nzcRWRy55HyHvjVw32OSpaaY0sGY4f/2EppDKZx0Cx10NBWGCmGDHrj6OLbxVfDMzcRJed3YSFwPmMFu8wPpxep9NNIhFd3ScNB06hUwkOrOYsC0E8ePaKnlIH5i2OJz8Y2Vrj+JH8cPY65zBYzaDcdQdGNjfhh+bezcWamLce0ffMtiOEd7t4iAfLq8ARY4b5KNUIn97h1qjp06i1qQ+lGqztHTIv/7nQ92SiBJZqiJWvsiJwkFeoC+hrpN6v3MYaX8LMecUY5+mkaF076CKEpNiMaITmPQcY4RzFfj6VVUhxXk268V6iBn0VPDGLhZLo2Gc7SG9GRxFZ7TFbHypcpjGbCeNFGI3Q9RKmW8Ly2g9Ww0pBBh4lLw7zVpnXVA+IBRoo6W9LZ+yV5ZyS/1IM8WF8pDThUqRLmR+VPmWdlNkKRg0YEWVcFEtJpGTzUgaohyuKUr4V5wWxIn8y12lXh+1hjvqc5MzK4W2nIeya+JS+0r7biz1b3XtJHWd4Fx+3/N5GZvhK7RorPVwiHbZwavKUrK8QOq0If1jrI1WIpneCL42ffuystybbkj/a/njttjPbEhouyPgtbAAnlbGyBl3aeMmIlkzz7H2zYhMuYsirsRT5ap2wuF93Xml4JQ2PLzjM8tP9HtZz84MYmFli7IK94XYRtHKQjxRl7lRfTziosk2IUz87YFTMNplMvfvwEuxED2svFTCQLiUOWF+UTsE888eyJMYWZwQQ8sd0CigtBetdTkH7Vsp6qqSbS3T1OuqEKxZVPTqPMxCJcTg7FipEKRY7VKZlVKPQNk4eFVrKnk+RrFlaIWr7butlatS3JEyK3zqTskGD7GSZckM1H0/T1+vBfMeN+A00j1sj77v64xpPhZevtnR5UyuRSmFGUup6uDLXbtBSwEdknC++r232iYr8UvnE0XbwFfOvDD/QIM40AWx5kmo3kQZWNPuP5HzEyMk61fxsuI163Oz11aS4sfH6OtuYZa4LC8WHv23iDlvfyS0HX81vHD48jXQCqR9jrxqXxm/j93t8oDWFtH6H4qcTfr9IManAONL58Um+9xeEj0IQpKv0gtLZ9b8EDNxt4+DBWMc5hrNviXjkGubkjsQ5vJltjE5M4ZqFK9LiTPjB1+JbWX4/Mk6Ft8GV8sIdM3MnCGSe123ZsAX15ywkv1k+1fnqEW3wJXNnRvh8LiBr6xNCs6C8mDXa3GEQ1UAUNM6qE6SG0a8SRiT6gIADuEqqHzDPy6nmVS0InryCX+/dk1LoczX3JxqaYpKI8L7k9BN57vzFXhV5futzDySK8u+GTJP1LPV+qpNKrV8u78SDW0w6/Tl4NzEMGB9zA+ABPOI73h+DDk/fTLc2Y0zXUg+UqAuPu5HxO3xaqSspPuDGrpsUJGgStrQ19AEDeEG5PylrH8VR1y+rf6HkG9+MoWGJeytpYEl09PXacy4qnyDQeDbwBIHrwX84LQsnM3D4pDdKAencSLPkZ5pW2E2YbIzWJocME1My6CLlZLIyMdg/6GLmCUyvBd2yWcFCAl8t6VwSbANcKcfOw9WREMGwzxuPmjLX8/PCButRnxPkme4H208My/s7Qp6oiyzA4TIrOu/B3zKSXMft8Uw/dx1s1x6jIDwMntd8MQ2ielq5AiKH5Ii3YTp5o8j9HJ/P1C6p0BCffH7jhaVB1BmR8DDD+Uiizu5GBOonX10yowsfhr2Qczsj7z2kiScSie5JqzIhWy5+0MXboDJ0/Ylf4p26SZObxvdEA9J/KPlTliR4Vow3MBuLXoE7oexUygtjfJkKk/0yuhg0FazeipZEjXK43Uv84k9BMOz8B0tCbWAnSj8+GmdDE2+2L9jGDe4LKUXl9UIUBiuXLxZ91IUcYBdTUW8xEQhsiFvHsYelJq6CvAMQKYfmhh6/q17196vkb3qVa8JI1C/jni0d6iBmsO/Xph5jZ+gO0+t9ZNy6EfZ0+bQOwJuQq/UTpZthickT3KAm0Faq0GkhKnpojTCmPmC/ouMmqtg5MalK1OS22+aiL0eYcKfPWioy+2afPt/p/a052AyRsJsuREHgMt2aNosMchoq/RV1V0zMBix2rgYddz+FJJlVUJMPCxEWDpW3E5HsrkUaDcIHSxneSqNAAIajs7yH2eSQh8FdCPrAGFvIgNOn9AVmUNN0mho2P1ideO7OHzEHBhvlQkX0QjVA3nLkk1qBU25L6kd0taiKRrR8tbtlXtpH3EIFmJKT4AuI9/s1XYLqK2ZfYLdYoiNMpWqGVbbzdtUUduSirFCOuDsHeWfvABNhOyjUOrIsy9ZecHR0w1oVsXgd30IMP4AUuHZi4Mu9ob4JyOwlpuTcL1u09VihX3gTmCt9FbtMDWVQcWi4qkBz6n7RzMqWiXi451qLR6ioLp/5Kjd5BY6rKrSa2E6aDuuU4BqwyAvwQEg+bCq9VuSTdAO04lGUa7K+fa+G3NUL2K/5srSGfhBEbGpIGQzxhGari9ZAeAbMo+FYTljCIzs/90Scxkc1PudAX2N/HhAy2b8Edwab6O1+SxcaPGT+u0uR5KzpMPOlGw6o77R7dhaQxjntgZaAWXGSbeq3hLmLILnl6DMnHQQnLNzsyTGnMNw1gScdQwJ6DkBvtpEtSX46GlmZu+nZ5ALn1FR304wbDOu16aiXZ4FPNkG+o4q1tTk6oe7akbhHK8UWEyc6g5vQAIFphGEvWy6aFQfNKZIT0c21ImoZhFxx5j0shAxaSZz31zkX7ZFN4qPwEfGDRHdcWIHyw45WLcFWPqEATU20+2sNb6I3iRMOc/WkdqvBoXFrhEMY3leCu36cEz6Ro2hDPZDjGDoqDuaCS4MLPxVo250SbuQj2HAXW24FO4enpl1TiPbYGq09GJyTNkhV5PsdQ6YcQUHzQJp2izk1a94DE6AeVsv5+JsvFfxwATGrtfMk8kTo4WxXM4RI0f1FphiJ8rtFAsTPi8DfMYMETNL+WBRDv2QERItZBgFPfDV9gAKQQH5gDgn65UU4QDYFMgc6vmeDiQXu9basPf1YxAfcG1Q9/b237WnqSMLV7mW/o+yZ3Mf+rikgRFswHXAB6sWgPekwlwIzjjT7QLsFBc1UvDUw1eRSgsYgPAAZmpgVQ1JmlaHzztLEp+B5IF2f00tDIVY44Zl5H1Ff1BE173RFx0Ub00XAfgzSbpVyjWpwMevyIZSeOiOSO6twMVfyNFeybQ9oPPuQI4VaiME2H2JnvczJr3NGunjA2+0pYri6K1kbtn3GdREIOSpGY33mDTrFbHNvZKL/xNAv/urhd7lxwxWb1egWPsPyAWOxHZzxdqijNqQWKyR2YBjvZfIMMmFUnlVGJS4KxiLBoBmRz3ErAzUXyJsw3eGI3Q3yKarNMGL9YR1PaSlwKoInT6wgX4B1szf2xMGrSKLryMGxJGB+ffgTM4dqTSW4yyShzCV4SQadyHmoDv33HvYfAhwnvgeFDlUrckk81xyZtNBK90hsjuUTVO0U/rMZHHYoDfZSOKa0ZLWNmsl5C+G/6kz7d2856pjJ78OsqT1DM1Qb0lvr6Su6qNN0W1y7mUu7lUsLnvtr+M59HAqDcn3ub/7U/bf6hSgwmrTvnvZ0e1I/klAKidBX9yywaaVW/nX9n39/2hIF1RQ1UB3Lbyjlx11D8KcdYpsgaqf9jBXd5VLXa7ew6RxVW+X493qoX/dPdhxUXSJWQuzDXTIYU4I8U8fq9+eyuF81mB075ZK3+MJ7ekZxS5GnpX/ryU9vJA+L/ZD4SB0W+Wf0lro18vE79unNanTU5I/9n0/s/tsTufp3bc+VYJzNFqCuccUBC/3U8qv9lIb+a17AXc2x5/z0WAO7RsG7ssrvYwZRAgxDljrBhW3wlWP+fDQI/PxJ5O3272Ol2sZNZqWDYWyGVd+C+MkZedntrsH1+Jy8PYs4+jtHYecnUetjO5oE9wNpv7JrDAJA3AA/t/k6QQYDUddudcl7w9G9rNOrZBRPkZd4Ug0veo0opzQCLkUsJjLK8AB0dtYEGTqIMJUvTFpZBU+ZPkcY+W71lfa3R+Z6pZpwoS2sJUfJdpVw8fU+1Cs5eWO4v3e1LGju9ABsWC1kdpHqEdxZWXl0EEY93PNOLibsFiYoeXu6L4AIkNMz2vHK7wACGRDfh9gfgQAdc2io8Mj1h1tmyYVM4+FabxtB53JlJDqdxE2aIIgjIM6lcIgfZAu7TQ9Gepeyb6TQbABgHxmAYU4Tt+oysqmljCVuqU8pdelAjPggXAkvaiN0ZXtwVFNljFUW+kl/cTfYL1VjRIx7wJYMV6tX1JkxjL7RZcOU7mZNfSBvWSwFpoNvNcTIqC4nr+VXwuathiz+TY93DHIDIAO62H5SyphqJa+1hWc1YaaPcSfIsR/BC8atqfGG4fBskm5IxMWqgtpuej4OLJvSbwPfdJuG1p6f9LjljqKsJU+9ZdddJ5Hn/ONV6vCw2iHJLAyfQq/PTJRY9VXg4Mo/inEue0/y+1eRkmNhG5bi8zwDmR0nk5hnTor+RcTrbr9KgY8gKKlKeASpJwdPs+zEl8NmUr8auTfEbozgZR0h364dzBH/1VqdxbYteDV6+DwxCwYbe0aDP9wLF2KUse6WXh8VsX2kE4JeoV2b86IzFhO/5x0EDZtvGI/iyZHfUpYGaUzZvuIrlKkoI+sEMK4URJfDLzmQyn/sZmeKGqK3Y7KAGfEYYebT3kKKcJku4BqhTboRLEZzXqJFd6E4ExZPUFquHEyXmJ+JbTmL+f30xae4FqwvzKFDl8GAo0H1rKLCPLzdQ2eog5X3WEuarQG7L/8nDSgVyJGkH1b12cNEuLPI3V5/7FTeZH4Py9hjxOjYQ5UhxxR+ZKUDybc3tkxo8wHIW5GAo6aBeS/kxShu8iEP7jAkjp71x95iTb17iM2ZYStAqDokSMaMGDddm8ECQqa36RMDD38d3M6KMSteJFQU4+tg3GF67Q2npvLV6AzKZDXDW/xGTmdCmsQTBg4yu3Dm514IK93qZXYSaZkoo52WKtDtUcXMQFUbckeElZRctcEPkLhCVbLLyPvKuzkgnzpecUZlEBqycD5LSJWH6CS9XRohN3Jh93kj8SOQtlPck0ITx/SHEJWJB8dfFHMy5cfeRoWI6f2jjsJZShtemSG/yENUKGxx2wNK0nBWNj10UBYsje5q3nA8oi+2XzQHVif3/ITae1/o7MCYZJqOboW4VA2q2D4f2ygf23iYQYtJbwFveP1UDAg1ZooLowTVa7i6tXKxsbEKoBdaOo9FfPk9WLMiiTRK5FbKNS331eFGfKbcNhS0XyT0h9uWo3XP5/PoFTfIJhNStMy0VLoXir6xqP4XGktUks9qqzN+KdCShZwJ9Hlm/zWUeum8+zZ9M7gi+vp2F/rdDSFWjMZIOz/64vmLYnJaQxnDh1nWLZ4gb3xCJ9PWbzS/phR80ngpRyy5nJrKF1nz+KZI4QUvLwc+djp8jK81WyC6X2kQnyQ8k4xuRTpZwYSVAfhqDFoO3w/VsTXr1Xr0lHBUVrYQ1/UVTlke8z3tfBFOfSoDCpLm+8h6OqfVjfFAdtmkcW0476jwISXV1rRDUSfGN8WkQKIsLlBUK2bGuWJIEyi+MnRISUzBVks5vSsBQycKnYSTysw5x9S+Ry/qJ6RY8quAd5Jx/IPVU/OrZ4zaCt+jsB5SGM44qwDngT+82l0ZExN9HGkfgqsxftnwoIh5Buitj5pj337mcm6QxrMdnP7dMmhgELpcVMf4eYCgsRsmJ3qRCRgNNel8yt/kbVhn+ECyjPm688O1HY/lvmETCgDl4+iUWOpICol+R2UgljD1AgGLKPrNwbcCGmZKiG320/dTS28IWb4sCCLw8CL2FSYxUv7A3w3qFqRMuEnTP02YXeJFpAEOULYgBD4QuJCiDk8ESXEwS3PhWx8Evt3OfPAdlPB1txMwORy2PunYURsVuo2yz1PXN5t27bRdxv8u8+CKBt8uNpsdjr2jB4djUmhtsNyItpIyMJMlHZkVl7al1I+abW6dtHYLiR+KCwHJEp/29qISXRtomdviGV3GOTHhZA4gn7wbKOV+IaE8d3uMQ1NpfxW+29zTLQ6kpdaeTfMndjKbSTFT8LVjksSMR7fTBaexqCxKj9WCvJ93qYOZF5nOYG6w3moPoCkUqBX4wc3B2+Gy0ukKKBKamv3MTtgOBEhKPNHbogca4OOUJAeElu6Hbec3lrMxihFDJc08WEFg44/8pUBySPQZoLcCUql0bcveS4yReJtEE8MQOfPAIGvakO2/Sb0uwI3KjYCFSXY1AdYe4ZvfGDLDPbBSg8PTGxCL1xPkmZ1RCVgetgbhFUH/cOJKyKZzkI6u3V6oRCJwmQRo0Z3+yZ64UQwtgvwR4hkXmrVN4Z0RmfwQAho3e2uVJxtpkrLzeS9JQ95KCYhu+7nUkNfUzgqeWWCxhQlgaJtWjPBW3BLRbs393Pci9iHOkjV5934+c3XfTfdnroK92+chaVC2kcWg4zG2nJ8L/etQiVhFGPtra6tW4ezBiDI0SQIYM05rfKVAqvZCj9H1Aqv7lDYhzV45xa/WpkLPhjEwJMICQYf4qj5mqwAZy8+s4jJweKXxNIshNc6vscRRFVpby1hhC++Y4VGOQHuy/ovovpE2gFkyLvuUrzrIbaCdWezlxMmjQtQm6Lo+Z0tes1AwoAV3WhzG+G46nr1blO6bJCXac7pZnZxst4XP9EAKK7/MywBJ0EC9+RMkoTjOO/V3FpAMR7oNWRkjgzisIgiD+QhLMOWvvCqZAGe7PCdmHXkoJX6FCHtpbgsCN3yo5+qBVZ5pyC1MMq1NDpvp/WIkOM43u81DuVprJsT6WF6uisuWvlE4fJ7rFUniD00SX9QMoMt21b3RkkpPf9iodcanXImuS7i8Z2SGBSYgPEh2jGIncppFlASjucAqns/nnCOd41Kq6882i7lsZIZH0HvEk6jLJ2wJQ+PzBZBxVuthwrhWdgs/rgKKW3NG3DvzUHLdYkCHcuBQATurr+PrKOymRTMroo/ebjnqFRNkxlJryVKx8XjtqPIpP6R+/nAStRmAXfHd4Q1xUi0KQp3loQ+IoXFZPNJsyk1PzcDPO15Kuu2HJy8cjqf7qeqbsx+oHUzfR+NcTc9L9itZGAZD8UjLbyleBIieM0isH9a+68OW9+/8FwxGLFinR+w7VlUYlTcL4knmuCSpcTPmWIxxGN5pU5umw5O2+QZr0ZflW7h5RGBbDouMkxsG8pp09NoUgYDSFBHkS/Jt0JlR8Qv/lhZvzk0Eg80LoYOW2jENe0sVcsLsfAN6BLlH0GJHmsZBKPXlqGlUxRiMHqO+LR1ZUlpb1/MXRgZgLxy70pHhIjQ3FPx1ho+ak/ctmVeP8nBiYNjGZYiluqcHbQFYVAFvyMfLXEUHi6kXd8bGmmTo8ego7aDSAcgLw6ZYNT/fVWtfip7bmr+LyqfQjPLuHsUgBm8jwjGmGlrsdvgme/TfIwddOS72dW6NZKLpCcRTcUceHgEt+bF8YizHuyY4lQq/kleoHZ2xcJT6bps6ooE3gVCYuj60moQ0hjIfwglmrK+S/QhIc9vRN6hyNGMfSqZzP8x+OxQGjnGPQwpKNLU4Hi30XY69Hq8mNB89MZNpklUDWOUlGIjzWqkMDPEOc1HfDFO2y91YTZDbr+GSxayTs65svND9awUHCNckpTcka2SNZD6E17W0ykcKP90FY9u9Vf/w7Kh8LN7HlJdu88IeV7bUW9dmpuHKqU91BJX0mDmBYFbE2X6bedp+oKG7vrnAZDjTQTsKre75whhTpCO06X/iQd3wccZfZQTACIZNi57fCYk07fKwPoV+QdX2jY5SWixPCLxAXMTLdwqTvSCZb71pg5BkRzfftTjUMqxwKu4Q+dJDIU4Ff9I+Iowkvh92zJBFtfaD+ilqgAfZ+5bcxMDvVR9Ovbh6Z7nVNmOMhu7g6dhraVjTh0gYRLqhTRV2xScdP/ch4MDJZbdq+nuWk1YAHl1xr8K8nsrnhG24x4UbR66IzIGQPfIabFiMRaSsueoD9JEwbrCtFfp4g8crirQ3ptJgTnsN4lZF8VREeXIgy9okjMtnJfD1O5FZ43uQqWZZu0G1WmkET0O59xLsG1Hj931Lu2GYeIy6wQL95jiG3GYE76RHREZeKRctcU2th1BQHsfOcuISbZw3hlJttydJtMRfXY6D4xzX6dE7NMYHGUBIev4iVfGIGdZSTQwkHyliKfIvNILZ89WSCXk3hp+JTAqbkSr1F+Wihds+dEqWKBFEpsVC+GzlduNl4YBbuvwPJdBspgiGUNaabljUXSppAiACGGAcXluChVHH6BFZn5PEn01aAsGf0jKa+dzDlb5INwkb4RvRmBeUX+riJwJklVfFOBDb3UH4ZFLPDxJkcBEZPq/49AZgZ7nrdzk+GxKT76XMIMqbV/BILRcqffpxojNVnz4E9NYX1XUpTQrY/uG0H8fDSkvjL7fyYdZU91fPDtdiCbUzECbrlpGLUaYYxVpDhON7onL0G/GfAsdQwj/4rU79azXBisnXxWFrx9K+nJlOFuiO8RkBqyKVuDKItK9yCLjyGZnd9kpcTtKk3Jk3XfJD7c7f/nIjZbySpGiP1aDis7FnJYXBUB/d/jmcnlWzexs+JKYTL83yE1vC1EvToBm7wSAWq8ywPsC/ZeNU7meSoqKvzVGl9bu5+bInqIXD3CZJOgmBSf+JHSC9jFrxz06Sj9H7JshOWUL2kgglcpfwXL+LlF+7RfrZBiO1baSMUxEkMfVDt0FtPo33J++XnIyVB9j3DibHlbEyIZKHOCOijtjrcMexnnmXBKOGxGvinKE5gMcRp+/qYKfYsb6A/6ZeB9Hvh05AlRZ0Bu4/iAx9fpu+aLbZYp6HPmKefOBIR3Vq1MOBtT+9ZZvIPIuj+ehJdxQhMQrxgGiDe5uAfh3V7NcEK9qMxTWvKodtlCGswUskdl2uOeYTbwHP78XXTXvbMFDiZI046Z5vk2AXFsrS2XydkDCkICVz7r8SHS+z1qBGBGuXl/veNjK+KzpHJth4sMlxDjbneMdc3nFgcrrQUgSLbj8pC9OMUuibsWPvXaHIsG43+uc3RMxL2JN59tJCMeEeX9zOnTLgkjFE7w4sq4UFFm2uzohptTj2Z5jFMNvjzLQLHV4tiIlKLVYwoyF0AV/ngtJdatGXJKW/VHUXA2MGAmkRWCo+YQ7kQ61XAlzHBqoyZyLhu7mEKEhAGRPRi7C5MMpNnSlnHycg5NEg3Jf3HpUkRmqXMklFvQRN23NyR9MF5Mta9fEL4nuW645/ldQLPQnngPvaYFW7UwyWBfyc7ZxUuhk0HyHV9bfe9iLVLjJcj0C2QVmIq6BA6urNs+k4yfFEzTDjfTi6UUVF+Dz6155Id+q8RuM+oeXgCPYFagdPabrf+0jsNxGOorFEKvSoHh1J69j6CNEN7BPQcgewQs9Ubyn59cBIVb8B93VvN7FglSvukklK1HYSwZN6qUX0UEbMN26LqtyHcPoSF/cBST9k34xxsXLypgQK2t8GMOoCok+10mNyST6331i+ulh9l3Qf8wOLEVkn6AxoVlxD95eewMqVEHUYMo1LHgf9B0+YplFtjAX8dFg8urXfi7k2M4TtwuN8hx3Ag0UsLdBrTLnFdCWAJbiicLvhIBkVEwguqIyG6X9lceHOFbiHdrMWHlkbC3vuKtXb6KNCRusMQr/179IzhhVlh4prmzp6MhdnXGYWxmuN1xrbtVKeayPpAcaYfRNEbpinVpFZ/A3l3SPSjf74Fu+S7wNV3hhqCPU5K6KPGeqe5loSeTB+QQHgzQuuovLTAHtPUH16W3trMVoFpzkPiyM3vDf5S3NPq0kuFKYPkBFiBchHDnZ4sA5s+N/9u5TJ7NmLl5hyN0PhcftVjOfUQXqDN3XJMIhc5gTWeCLdN6dP8/UqOAw+4h004aQq9AJKWqvoJ+wx4oqQD/iLFgtG0bjwmp51K6FW/KJnX34G+sWB9Kr/JljqDSNcNXEU5yOLTGk2x6f9msohk9+sM4WJLZtE0ZjUHSh7UtcnF4rD607n98NU2IlMLY3OxoIaCgoqbhi/f3gVAjc/QuP510jz434glh46LU8B0GZutLzWk4jGh2YSnu+HF9KeB/FlvHWjBNz42T/82kFi3TGMUM2QTeTTRyacAKso8arjmU4YlpxbyuwTW3ykLW8JMSa/bCvDS42SrUqXAsRRSUKFy6yIX/P95mTDMuFgW57Qe3CU6XVb9RBbsB6LaQe/xr8S+XtFBqKXf1LsZkVCf+WekEjZFPIAQo7qsUk1Omt2+YkzmxXeW/T093U96OhzFiR6nDQeG9iRHMWnxGnvbeG30g1ZiUG2VXI3oeFFQ/L5zjMpSoWVBZr1zxOmc2a63ifYizL/eIoN3AFABrsl2rHdENz0xBMZiSUOJtInnSJFSnmUhmbV7k4IeVb8EakJ8rIFt2mZ+ciDLjRvAV/ksR9OCmPKgyYg2eKNzt5wfxG7UdJdGTyp6CY8roZlZMnXNBjfIY77hHshARSdscYZ40QR6wTWsk+DQalCfMc4nUPfgvdZQ2g/euZ1ucy7CxHKU0JyaapJxOVQBvYGGy5FjN/zbthv8iHdYV72aVgykm/EvHMiOsAMheNe3N2N+/7glGkb2eTZpjRRkuqmS2bMNWZp+OS+dRX90EaK9zFYDGuOvBoMzIWXgdqxXWmCxTLlvW+f4wnVQHLrTiy+6biCl3HyXowAAixQNwMdYBsArqCCr7Aqep3lZbQSyC1a4xessxvY6Cc8cWT7NJNCsDafAjdHzPrzAUG4nh5AqTCXO7BqfThZP++L+aFTxrLoZFfL0sVvFsQQ4Qu2APR3/LJ4xcIXFjPmHJmJiVLP3odib91fM+FblXyPjEIsX5tSEefuEB4sXqgKAIx1xdtG2xovSo9w9g6tpROHQ9ZgKbzBMVmFAfsY3EdojVPb6NRxB3sPt4J8IxIF9/rPfilvIZOYfjA/Jrsm6ptQh38R4Z4vdFMCzRw+GfAE9sPc92t/NK1rgt0/vhT6VXo3GKR1+10hvqUDuvMYGd/V2/GzAWpr03RIYcl3m2D6OMX7kSjbrBqcoMEX1mrbGMe+cLzjeBI2ow8Sb13BYv8cLXvppE5p5lkAYmk4V0sL9/WcLSuj0NAjLxE/s8zbpTFiPYIye2txYmF+aRRael7M5zR67+OGlR0wQdWy53mDXTkOPecsscyoqD2M+IgfRQm4E8OUjCgGicgHSI06Z8TMglvq95FBejLkmtP4Jnaoq86tHRHxQdmZVq1o3dD9ZAPXaGjnc53z7InSBXzKBg+o8tDTX1UaY9JZnpEsop9RQ6SBecNl+9q+9Njuu/YEThoOX583yk2PQgccAtVEhIko6HIqPkM64W2ZIy373e19pZ9tz2/wYsU4flOptDYaLuV3b8cpL40FxKoSAvlklnzh0NT8bNL3qEh5WbE+JUL47HrLJ0q4/Fnd+9tp9sy3apkopTzx0jr1SgPuByqrAIc4lrmmIzyRgKX05UjsPVkU0cQkCP2NpQ8Cfy/M0+L82yfArUZ93VFPKLqO/2zcmGbX9X3vh3lTc0LHTEstjJGylzP4drofjfiTu7Xl4UtS6leT7l57R/ytML3pNdnkywft8pirkQSqTXSB+wz8uDO10lbuEXXTHTp7ygQJcjHFMxaPTras2dvFkb9dN/9w+UUxr3meIBKpdv5VW1HHB3Axr2a4R2G2bS4YS9O7+37ClFLC+DZC36WnuAw9XbiHfEHsgiBkTtYgmtH76gtzvkftXcSfNolhs1OSQ8ReokAvhfzwiiLuyNfz/ADwur4iKyUCZPj6RA+yebLURjCQprhhzsrB1wuSXY3L010OPMcAq5JquW4F8lZ/2jNMkGyD4qAkTXo7tEwvDC4/DAO7FkkSMxpYWd2yLfx6ZkVI3FFSHWHYNL6Rs14BfiHEgt6uF9jQ/jDNd54ylDB8kEHR8Xogj54oYPaqqlNT91bxSnYY8twJ7wl9C6OzcnmO4skbv+E2v/mPGxia2RZAAqv7VQo4rjBCdK9FEh8lHOruvlhJOfTlu8zXmt9a/ADBS6CZ6QziCB4K4tDzwOd6ORkHWt4+03qtCTHRrfKDLZvKYAXsk6Ms/Gh4jkx0uDj9zJTnW88Okn5NI55aLP+zGIJkuf+JVKAB/QRxGvm6LJpzoPNmg0Vd0BVIib26HXS9sWD19+ka9oqxDkCNQMvIFSLzofHp5eweoVxUEs9T5btHggHeCi9lIzljA/ZDycxwT8PypSb80InoeqVcyYopWipL+VaiRn8GtCGUBH20on58yIcMTZfrQo1M+2B/5xFoYFeEQO1W2uYQaT7xgNoyIE+81QSZBYov2d1OKjVD0fFkhONhgaze2BAS6Cyc3dzn/V2PodjDDrMJc6Z25uiTCYEITgTiI3/POwQx7NgITXW0iJLzjmMlIj7xC2A0tvOpbd5SpbSDG7yTVjxRImPbvnVw8Cc/1WDZvf1uTQuh4kOHRt9ERITydinJUGJ1cyhNWDw5E7SzfCa2uCt4pYGo2M3XkqQVrBtdR148hztJTdkms++eHJNKQPlvOWMq2OpXTKkSApt9teFxdnSkt9OFNicjHWsWMujNdKiaIznIl85i/vgSIDyvUjKS94FIMnchQEl/yjHTo5YXp2t5T+Vpi/eM6qU4F1Oh9+fP2xxvaDrrUgjNlJyeuGhB+KuwUeti1IpFjuhhaWk8NOR8C+3GhpxHWhoy5u7WzA0r4hT20HtNqu7lFZzSD3P77icvt3aofJCkGHyFbGI+YwbuhSUyBS9E9F24XQBbTmwVvRFGxLJYu1FyeQgUk820P79w91WcjcpQdb98KsdH7e/9ZsSS+G78azES5oW5eTxZ+Ne1toh/OIwZRCseUqOH9P2SCbDxOVABeifpVgR6TEkh01s/OlZ7f1YavRaBJvhoMeWbh+0bKIB1vNVwuvxiAV6LqGCF5dHsTX9Pt1rCPLNzMDzu/QVPGbZjn+2JCqG6n2Sjz3rMj4nlP6hdQzzbpLpKTF8UBLaHY8DNZVlekppgQSvCQNSO3k2Urd9PitazZrqFq4IoIh3Su6W/Nr8EFfmq72quGLkOcqjbuZVcwIghTjT472v3OYYWN8AiYiKPU+6HKfUOw/juO1sNnEL0SH7NAd6k3IeHF26WO03Ujejj0dmGk40JR+P51QB5ZErUGJgrovFdgpqbECgBfrwyQgM+lS5dBK8S8I23rfYghgww/kn2PiJu1j/8R3xd9nm603xsgRFbqZh9dcePEiPtKpj1lRVVpS376SFI+7G6fMgrqTeDgsr8cPdQlh1gFRkaDnG3HEMThvMiMl9/ZEnygZ6rsXAlb48rDIGgpbN0TZS6DwanHyGnjSsDQsK32iRM4ui2YhtriHbiIQhH1NDpq8FwkLD+phzb1w+sJ9SL8L/jZ0qBSQpOvqJ6l+3z5FYlg1N4k/3qVR6sIDYV/nqqeJwsaW+4TDcsWdE/miPTgvWciHy7aL6/BMK0RRAiazCeD9N9gbnnSpTqdBmBGuT63PHzuKGI0W1ogNdNdaMJ6lj3EVB1SMmFeShTpthgXMps+wUN7WHvMc4DTpfoImahPK7bLMUjkQyoD5vQv+gn4kCocPCzmKiUqWYatN7T1TFE+Dp5Rr0nLnW3TCCiTFtieYujaKuCYDEp4dwLZmcvDDDXL2iTiEkvfT2QdMnRJI7th+JIxhNu3wJ3QdF2s8zNCgjWlUYbmMfl7gPh39XgaZxwFMyjnHOB4Quh5Ivm6w09GMXPjso2C5Nmu8PsdCVHVYZLerwDH7z86n7JMmANHYY+viXdj4rzjq2/epmWiTyBrvcVY0EZmli6Mq9UHRdsiswVu0SWC8sqxOvzHUIW6r8UXwaY/Iwcdlh1gkM4jeAMvzCAj5nLWD6xI8HRGYgB4w0y0Ge6+HnNBHhZVBrH6tKblEin4eyBZ+P+l2WzjCz8KElrN6BqD8X9zUTnSmU4IH2+jKNGaFXLrMKDcVAu7MmWSTo2l6peZ9k5KvqsmMP7jgyayC0RTIqAjH6ArDK/DS+bTS53eDbPmwlrYCODtapFM6m4xQM93TA+/D24zrofUtGfO0ZJjNlCbkLNYD9F5QevyrL6XrRQWZ1g0sVAZj5NX4cYhLP8LuHUgmM4JSDIRLvDQlC8HANJvF9Qt8WkwnesGGsnqryZlw1e1JRQFpPEgN+WagI5sWuieQspnPk1NRja6njX6TBsGaab88j3+BoQA00QAkurMZj0gut44m+5QGD8+KhZoGq85DSVkrd8O6eI6Uqj4+kBZjLGTwrlol1qKWPyKwlfVafRZSVkiSfaFK57vEH7B4qiF1o4UIvpjGb5Im3xtL8G9gnuF4TdghQeqIpl9wyOFeX3O65vJtjMD8ojg8ikSiYIK782wzOv+YAEBWEOlFnYBJZFl6kDTGKt10bQ3vu+W9ST45bM1e0qU+NK76DMB42nPix1aYVjotcDis377Kjv+4hKw1Sy3hGv/D0ygzgeQi/nRJO1IiTW/PeGKxQ51oVRVbdynnh1hTp75Q8ZwJVDTvCy/BkEeYnMKPlZrWLIilrJ81FkGBMZ3qQn+cHaIBeEOlAXvhF4PC8EJeuVX5BquHXWo/MLy06X19k74mFJxyNEYrge4F2s175k3aVcLi4gEqzv0j051Mln5Jvar/txwnG8u1vZYPeprEBrwLuj4yXj5y2vfGv+enZw9CEGkY11Bwt/+aSksxiXQLL+GL5u8Cu8oUl9bgFJ9Tmt0NnnC4h87te1BmkDC72s3IBkER18aKhLYLj1a7N/diJ+0sqPOVg91X7Ux00l9AEfBrhDaG+O8Hvup21EMDPw3tD7IkzXfmxrSVCI2KC1OIj9FXHXka0Pi0QhNCpZymLMNGN8k6Ogz4yXnLDY/v3wHhT/ect9HMORIa5n7EzfqAP5VbS5V3xP5maGayiiZEWINalOjJ7rueUx7GMgj6AspzNNGC2DnPKF5K7NuC0SVsdaL9Uje8WSfilwYkBdpn77oaCLs3dIvJdVU7f5gbUCTFJTkG5JpTP5vrYLREEQupPp27/HB+c6jc88BkMZd24oi1/oMz34JY/mAbwmqVckxL2Fz6gr+pWkayw44YpaXBXjdbp7MXyzuEyaHSn3AVUzbEOSGJTANHgd9Yunh291h1fTeSWHPaWjJv78NolRbRSM89XgncRbEJV1Vx2xfq/yHsgZFOk31WdWhKRxxP+8aUIy7SP7+stibmOQsZTEZ9rmydYIL4tKh7c5Ja6L72JM9CWtL7mhPTrLJAP04ELacAT9k5dMrL9xsujShfS3CL3B/6rBzjK+NCNKqO3ZkiDAuT8ZtfmxgmWowIYvjPCJnqMmSGdQ+MZLEO+TVIbv8ilINEwnUzJ/Xby54vppFzbba+oTEgUyeVSQLDAYVMsHc2TlEBC6nG4U7cg0SbtwBrF2P5PnZSnwExGN/KahvpTCDQY4nerHw3FEXuicL0Z/wze8qJTwMRgNyJTRXbu2SP1SMG2QjN5kvv8y3XtbAhJ6MSKdW8YDk8DqisCRp4pxS5aU4In/gndgWQZBtM1sbEKymgW/QZ+FzDlk5vuocTqL80TTEvkSBIQcqKPSja79SACk6xXHv/fcnqmbVL6OQej+Wg5lLrYmeQ/t9PMfSfTSi4I/v4LYYn99fziWJ6r20wLl/NY1k0zA9qol6JXEAw29Il3QL2/+ehFTmOLHLFBqHnvzhRJphGf3Jbr3IsoXJ+FH0zhMRqfDEFarJH6z6AEt5AVe5FliynSV+Aexm7hniqfj1fwhzWzScT4pXwUpL2+QJSazDY1cHMu+HNgaxpuEaHCjLfKukl5KbrKBcqmkvnWi2SOkwerE7JYvY50O5d0YoSP58+Fwbxr7YLhDvS2Qu8XRGOoHGbK86cpgS79OFzsOZLtCd6UgHMwR06zwIMKw0flw4cKFGXkxohBD51bVNBrF8sKk0TL5XH2/fE2vUCV6R4BYJBDyYugk/J4Pjyd+pbqnBVYlqt+W1H8V70ke2E/uzC5w9AhexzbdTmC8zQBejZUqdDV2XhI/+hS3W6vRP2/cMKiWoQ6PS9JHI/FHWfecEkoblfYR3anaypUxoH/9ewLEZXtRu1uikQrhPnjlkH+dogiIghPUJNIExo/6qiVogUB6vUQdzUivmZDMO/osaWzQy09gaPNsdwQG7nj44cG2zGg39MHUMijZbBoDenare0PFLIapg4kowE835hPcQH+w+yMHvFQlsIHPbdOC3yLlcSb3Tkrk/tqDJZpZ8EVW+HFhHzddmNg0WAfJhW63xjC+E7sYVkDABEiq0nxfRvhKPnQLvW9CmiJnow/oLA8eqK+6xtar/EAXJnZ8FikYaXxkvrbEoGQ2Ycdj+6BavvvO5Ir98JVPxrURqXIbAvuRtmQ7VMN41jqf0Dlvw8hbORunPBTt1ByVOjCgeX+tYZ4BqAz4UGT4pDKyuEu8y/g6Iph6fYJ+ZBz+lneusXZ+e9mZS4QEHMkha/mBP9Gcml0jeAUwqUKFgJmgubfue5VSolPkrsfZxigMHh6/FklE3oxFfd1dTjqKMS1bJmG2QiCALqRTmJ4KxmrywGZD46uqRBxCxNc9D923dPVj87vOM8bVQfg8nuapv2Rmc+E1MeWXT8Vh5xUg+ptqmWGvPLcPFEVQhqlaw7myR5hGFQzJ1YrCbvTE080k3vCg9OlTo/F6p6WX5+7zPfMidtyZfvXTWZBYe3mD//kCB1sp808xU3y8xJ4+6g8v5h9dfcCaH8EGTKY8djmFCdNIVCr160hkGCZH5aGTboV/dM9i/xdP17HmqNIsXwlvloVHwoNwOzzCCw9Pf6mec/9ezEzP1y2hqqzIiHT1fVsNDVbyKBH3eKvs8mmywlU+08JHOoIlNTVN7uN22e7Sexs4FWfIrQkVSqjAdEMvZq+qN3XO+NHHN6MwvMLYkeRrGc0m0Tw16FiBm1WkX3GFyOwBLaykiqTA4oyyWAzAxYjfyiavtx7adUinsioEX5VbK+7Ie69PmLeEIF43X1uY5D05Sb4yC8lArvmhefoQwgx/XcMTKcUQDArxmAHrn1NKIE2MYgEMHXCfzTIuFScunURe3zIVT+f0HAnVfitlwlwc6OTiXkfHGT1zCL7TXc2hQ9Dm/UsO+pdiDfnb08Nu19JRWHVxGsw9KM/oUrtoUKTt4kylcAdo5MBX/IzV8l+4m+JFu5Ta54kuPWXdtU50UdDBYzfDvNjZX2FUHLR1ZkYTtG/jeJjEVfDueRlHqQ0IzIAHUG+uFAEiMB5KuSudhxM8vec1R73NRxgnf3HNIzu0oOHNzJcjZFgd8v1qMbxGbDs2C6piV9/ouzQtMZvKsHu4YVLSX/5W77v/Q9H8lN8i83Dh8p70D0o3ALhlWUUoIza7/4sNgUJrO5YjAWebuZJUQQb3lbOH5Z5/Jcvw0HzfpwNWA9YCuTZHJLoG0SNR2PFOxpmevlfIOYHMAvP6GCS9xWzDW49vn5aYOYlG/mz7fSD03PLP5ymTu3kfwSXBeRwZAgR+oDSqnY9blkiScrfXJjBXWgrNzW3850WTiJ+f7/BryXGqNAJ3pEA2t8gq7gKAQb75XS3Yic8fCsBVHNL+1XhW/MLHXl0OJNY3U9biMF3GaJGZOni5/b49GvJNz2UXIXL5AX0Fv6DlzdtptWsUhvmaZTEkN6ql4ROv14cL5LojMid2ZdKVgf9Ia8KsG6R8yWSO0aUopzP1Pbr9fjQ07bLSERqG/7mzVstRSrHSbdZdzra0lY5hlRpM79GgekGupXqh4mGI73nbtcfzZnR7omOIRX/w9jXJ5PzXRcuqSQ6k6h7MeL9UHc/BabeMAHgdj03Q2FKdMGqgSdSDofpMMtptXOexX9wcIo1VlHMGLF7NuO/Bo7j9Aho1dTCEyYAo+xsRJZRVtXb2id3XPDSeqZunxFBULYBxXYg9lyQtm15AgVG+2DNgdp+/vXb/Szu20BdTMmOO39M/SBgHt8MBo/hQQH1t+UA70lErNsSM6uRc801ZBsIahLpYJLLtEu4Wk/KOvdKw3K1fpETBFgn1i6HZu64Gcs4+a0N5SbkaqoAPO/4IOrE25E6uzUgr7XClx8v2L9hDILmM8pyWlqTZhMYc0yLJcFrY18kFvX/wWCbw2SzEoBLMvbV+vHv1/AeNfGKwl0qp9fmCEeIPyvR/lTnsF4YO2goQ2M+XmfTs8LhpcOMe2G0hB/KT3dRSlqKkWTRzwm5zy8q6BdCb64CLEpctqkMuPiSkS5G0LIHM6aJ8ywsLCvFVleQ0VpbEzdz9Mz4Z2cKJDxIzAKCH7eEFSSQQPLHuVvV6t68r8FJhkTvyIdPMlhIKxBgb/YuGMQX+ESINEw8kh0l6KiHudzDlj0GYcQyw1V649IqklQddFnDn+L8eny1KTxjtomjAtgSg8Q97aSjG5vO3nyLE6WrcH05DZpDIwbFno418yA1hQFYrPOZqD70JGbXml2SbFpMBthqWRVlNkn12jSfUnyYFkaYCVX+HrmvR3ya6tfoVXX+Pfe4kQUSaVYCZYkJRvHG/qV7qIEaCz2h+08zJcL4E/ivBeD2j+nA7lswiN43Oxt9Ag7vq4Eex0/umy1xxPVQbXRGxi0Il38awA5s3fRLQQKBuhCNs7uBgEsp4TjVjoO7nMBPtZ7mZCujbqepiGPNXNwwd+i3kxs2Xdo4ecQ4jyJAtljtH5i+K3aYHV2XqArIi7DUAyhukiF26OVAKuhPk/bHJ77m7+Y8tdpoiss1/Kwb7b83hsn+3fwICBg/w8x9ehxoempLc8zogwB/Zfds+4c0cEhIchhVFEaQn/YCTNpH/XmYfpAankfH+FmWZTudn2S2Y4DH6d4n8JSQXCs3xfFdf+5KDoThN5Po02+KdssI8D2vU+TkM9sMCz2FlsdY39Yq31jKrklT6uWFUKhN4kFsiPeoygcrd+PLeG6dvdZvmu43lqIb9YQvCZdIdGiaHfMlg44OV+FRfWcnYi3emuXqz07hevmyFaIQgphtmE9JLMYzqtkBg3fpmmv5xttGLHYFpGfciFsRF6D+TonzkQEdf2DLlTT08OapwXWPLX1AGGBwe0bGfKWN/Z79AookLLTNhdTDFxqO0V2ooj0+bzprJA9YD2MUmKhcxro8G0unf7LizNbXTK5OXCrrTbFxaoe8/B27fOwr8FdLBbRjos/jMHfWRKGb56a0O9iqtZp75hVYUlpmaBpFwfPCZAEclHPz/tlZWIfDuOP7oJScT74URPZ9CQPjAgPE7V/OFqZ9/m2/60SOx1MMJMX05z3mALlKRAzk70WqGfm0gk5vqwzc7o6vmRcWAIGSXe5C/bfRwPw517mlkLYZcMLHQg95FEyYV3V+dk6GYyBL5VaDRRhayy75I6b09FlmTZsPAV193QRXux8q/2+N9jvr7jkyWs0YglIbMY460ktS5WZ5fg9Hxo/fc1KSV5FYyfXGOPYzUHQARteT86BJ0ggxkqPSz+gHRyJkTl/15MPswyvGPcmuQFNLcBXVFs1NVya+sUO6Maxt/cyrATBwg/OaH5MaJW8ZVPJntpsyvIkcyDPewWOrpV6qH7z7eNO1wmeHfeZhDYresnc1U6+wSDcPXNz55BTbmiJnoPhsfgYLvERPbU0AJEXc1Qrd+j68ddXOEhpIZyUdVdnFVmoN7ZrDJUNq/yulCgGSiXbpxGvtgg6QR3gssQFJ5MiMVnd6iCKV+2pptHk1YJwxipDuoAn+nyDvlX7jAzuZyCMxnGIIM3bIBvNntA9s6NsZL/bIjywR9RzOOuoE7G0kdFyMv5lpcaZOSOwzxN08m+IV5uBYQ8CIIAZdHn0cJio3D3GspC7Bv5IKeQIyPNdQzZUgwBN8RqoElBLR4CQPKun9PR5K+If+a8FanpcTL+a3jOKrkxEOdPsZdyT0VzNHyfa20xL2qIMDlv05fwIAMl8LV8r7zEr7mzOlXllz3/2CNQsmMx2EeGAbXsP1k0wK23iTaeYy6L6pgH8GPsFqnOetk+d43ewLYFwOAMG88R0dYnf3G+FrVRTPIcS0iYe6hmTyLr3hwl0mEKc1yPwmFcP4fTjm9qN+lVXldoQNTz7xh2Lj+W8Ij8OH338UERZ5xzU+hgzJuDwWsIYYOtGlQOMt6ezS1tqAnO2BgfsqN1k3IdjV/aNzDt11aEMx5a8VivE1UN+O/OSeHBnIjLeSKg/vyiKzcXMRg1/N1ZQkMuE4pI9prZZKMR4Vy/baTzBy6+jIFzzDYNAODpdUrQstyGxenYn0b1TjSJbX4KmMfeT2oGmKNcktiOaJ8sX9psz29CWbZdgn6fJhUMsohvI5/WFNcHqKcsY3T9N3i6HWYsfh99ryK+ncYnlz9rAKHnh+m+Js7MmHW1KQQfGYJSBw6999ahVPRJH9bEbiobw0ZXmVhilKSQQYd0DdJThusWPi318SG4zg5M8Vvto7B4/IZ+hx7I09X+4sJV8rXsuy5X5TUlpjf8/mYjxlT/Y+CjDHx6KHieiH9sDUPpaV/W7EfRpZ5wl9+UHIhhPJR91jI6ln1sLTr8NGo+KgSWlp1/ewEV5BXU3oeS++tbRxey7NqNQIKTR25EZIrI0y5Bj0P+HPzA5in9aLQ+H5aoVGxfQJCEHBswMRu79DugRJShDEoPgxAGoPBKjrzjxfBINN7/suBdVAIdrCCSpEbFAgRAPuncly57pNb09L3hj0in2IuNT1S9mJUDMd/z6FXcNgex5nHbRjM88ZwASWIdeXdNxlvWbxiCVnGMMuwmoIhXxQciOW/39cS0ONuSQWGQPaA/03F8kskiS0DN9lFc75obd6efAzWhBS3zWv2ucqCo7cn5g2Rw2NEnhcFhp8/aDVssispTKCSGJNFacpULROeY/KqvoVYK8phUg9V+fapVc1SBSebhTtjnJ9CNzGGdZ1jB3MSsuuepv576GsfL6zfBxCPuAA8B8LWjm2Wb033HfK1Jrv5fMqk0t1nAkxK+sgiPsHZCAU+z4K/5BvF1dXDF0TAw1WeZQT4Bp9tRTjgPLowj1eBLXYv//fzXzD6Cnrp5i//rwmGi945/Ef1ftebQI7v4wWGhiJbY+CDRz9iR2B695cbStJkiNC39wm+ST0Z0IRBbDHb6Ix/E8HUP6etnRZf5hC6aErkrr9zzhazcWbZQ69eBE0jllTDCeecokQlNAmWrReOinFpYdiJy/TO+nA03amAqBbenZIP8xnnSGlwdMUlg9JYql0KdEC8UcFptMfiV0H/elsHt74EKXA9o5t9mU90K263jeMzMfrO6GFUA75vm83Vq8zBELf5GNZx3pzKl3099PxhHAYZf39mrZD31gPoYRUnQugUAsekJkWzAmkYHkNYl7Aec+3zkwrxEbqUAmvXJET/2KJOv3juPBzkZYKBSyc4PZuTDci9V1nUv4KIDoODa9x42DP2MEYChBMZjEd3y3SmAXmzf50yQYDhejX93d+8PILXxd1zhYMXJN7m9wZGJX+Wwd5G7qgBLbzhu2DnIKJTuEbBkGPodV8NoV5lxWpWxLWt1ZZ0xuzG5C0jjkzlwXqDacFQp32qSmmViGrCENbvRMTD+ALDs4OO/g8196babSakn6+GCRQFJz5TVcrCsCm71TTSwx9uBrqpsBcIYns/zpFNQ+G7n+U5ZPDhHo4+HSzpB254Q9KaMgGs25pqPMwTLVSgCY24pLiYYCklNhhc2JILThwuwuR+wbos/YGYBjX3gs23VbY4sfsSe3WDj0S18j9PxjKQOq3/1BlHG397jarfy/eKQRQ8pzrCURUiUmy4FMAsBOtEv80So3KFccTHIfUK/UPp/7TG6GP7fd2FrdyrzjII7QdwRC5nCFEwGQzKMZb5+yqPx8/XkB8uJ8vGmEGIMlMME8VbcyCtrqkvwBA/uXQZNOJjJ9FBQnE/3BUQsKmzoQSeYwaQkPQilTFVXzdbUI32GV7oiB0s5vtW/7kFu9i//XJl3fv7gIMlf12FvQdzKlIXrmDYjPJ7gf/CcemiIDy+H2IYLkYf3+yhHysEXhbIPLeAR6WkRMZiH9hNtVH0j4B1738V+hyxQsrAE+DfKvIArqIWL9uWSQWAEK7df8FFq/elM9vhkp9fjSsbtHjd299gl6sxtYCdx2/h/0KcPutsPg+ToPGwy0P2ctn69PxJj4Acs9oFErYNqeD1ezikJynxoAQWLSNNXtBvUA5nqcL3CIOAgH8z3r8Ha5jPH8PklYCXOXRBhQ23BuQkMxBXR3Tvcn7Cs6nUFtbmUrS9k9cVS7/DpIWy3ik6O+lamGYztvx7vxdIA77vT9BwbR2iVV220Kr7AyQEZ5oMleuiJrKvI+yL2Z/Lb6HoOND5zFZr06oiGvIrh4gvzl4lRGCUD1w3KUlUJUW9mWgf4cdtsjkS2YNDScvpMvpWVjm+NrimCx0d8xQjBuwlcUCEEPa7NFMbZMMrXX8F9na7lFFUB+PilQ1iomL3zLFkjbfL7g/9pYMrhE8mPHiyVKhZp3h0BsI51st6KH9TqWkF0A0ehzRxnm+wExO6z7tbvSAkkwtMHnLOI5PLG4Zw4fRvroawsPVD1L4LC89gAH83se6HPpoxQ/Z9oCgGOhG4L2jwvgZkrKISGPzvG5Xuw1hUxZCWIuO9EBvsvjOmRT0keiB3Cg9haRt9M8B51EuyYLiN0qS8wZcK7vO/Q30qxL9JTFLRWQtsSJUUL/0yh1Zm1JkK4XqARXW/xsdSBv0UBrM6/e8vemTgI6jNx4pjZ/7kRnzdeJ/hKcOTu4WIkYpIeAw5BFeJQ6Y3lj47OQZ4XXMq+x5CPilfJ+0xthA3nmELDXK0r8J0Ph1pOpIj4KyjytTd78njh9LFu219swpl1nuUjyrzzszMzleY2mt/Rcvt3Sm9P0UKjIx4v8IK0pkqpczEN5YNCsiPMqgPG7baY5T1vwkpmZg4+J11pe0q74z1+Lnqis/vwXoZQd34v/NtIYcROI1bFCNQD3UtSTDquRA0HmRfx1/2k1jgBucQ03J8OB9XOAHowxEiKrT/Ro/ROC1/Kxc1bhKhN7zpqWjTOsh5KKZ4dx1M2y3d1RfoFlFBq/Za+dWH6X1rjOtfaPnVvAE8vwyZWWFt/uxy1vPDHPc7QF55g1ouIOPc2hYlw+RpbND5z9HtkCXg3Y2zkLBZg1WiNGMHm6SHbLa9QCV8K0DL4rtl2Ign+TfIbPtaZDui1dRFEcWEFQDjPz4cK3qSPY48332zyPEj6FMleCgicxxXn9pJeL533vpmtGi+2X21TZ0nCB38YdwLZhA9JcgoswtVWsZ6FPRchgFZ2XH7ytOM98sbMLbHpOjICaG1WvB8rJwyuyfD2g8P1/+0jTBKhZMiA71fTgQn8r2st3zeh/oHL/zg9b8hYBrMelzEVQyY65ZLATZPmrt82LSI/yuJARiXYIkxicjnx5CvoRvFQ0O+1OKmU+v/kVkk74yxDJXXnDTt49OpuM4qQSSlD3gtJMsfbE5v7bdJE1h7FUkxh8HEEKPLyhcvi8LNl8Ng3y32EV4H/Q4d77DKMlsOTZIQ1Svjn5IZeEIP+zdDkD1ehGYbzgDvLjZv/YaREx0ym7lY6ZdODtcJmmXrGxBGEsFvzva2acfYKOzMj65qHJyY8T8Gff43Cj/rLJbTlPPzxc86BppFIUjQZ6XzN6k+FW5GeZSKHL3htzrAZD/dMlOKd5FjAK3iw71+yEMLZ1LvKZ7DTZCFm1J2I3qR5KtEpW/SILaS9zqVv7dxZGPvUXAzIz4+3kLKwkhRWxqNQ196S7jAdubWiFsrSbq2JgoM/XI//Z9csZrB9gwpJr6kUOrfYbK7Zbx0DnfO7+1m65H702PbcS8xpDkQ2sH30Kvq+OuvGBJcITZiWb5a8NBPS4K0K6UgKiOQVFKU2vpfNBJHOEYtNA3zrJeN2E4Z68/TVN8byVdYmyS8woiM7oCPFdYKttXAImnHtcphhYJSyjqSsSvVNj5SX3fPw5qpZKm079EZlnOvo8jk6+wGvab4AVDorvOLr5BemR0vBKFalgkbolQKxj+n8xYqQW+GushJ9i6EZ71x5y2WurYlUUCDHEmi2Sba90n7TADvfeG2hx2y6hFW+Kv21xoBgZkokCWMLve81r7wjLZMrU1+iXcpIJEaywQ5l7LJtw513zD/3Cdp8xuazE+Dqii4wHu5CN9ZY3kbVV9kdm8BE52HDxt9DK2zXs9uablCeMlfbz02xu+QMfufzek7BMcLC8GQN7dXAGERdACUdlet9ZFUJAuV4nckYMqj7RCCTvsPuA9WdNkCMSNKE3fP9qbE+HETMNPti2MjEmjkWxSQF+AX+IHxGJPdR+VeNc7QGzmpwzHb/h3fGNBsprL2P6UPpxxxpg5Blq4JKglCMApO8zYyaBpjgVDOSbxT/q62L8TcqZX7gprRiOnQPv/r4PE7Bn0dGLaVfqzR2Nv/PPuE5RQvXS/4uu3u7re4kGdhCGHIuY51bz8r4F5OqBwVQ6OYy7TPuzBBxZu0O6Ot+BFMqwCthYbrxrPABvhRlt3i2MWnY8xYrt3fexGp5qbJ7SB22OdXYZZsRfln9UKdAtL5nCGve+n75EkqwVzl94fPvWKRuNtQz558//YkGIpuxhSPfDvTIS9JKXiVIVot57T2q8btg/BA2hdMuV+c32rVcoqWKiOkfrTc+Ss6wWO65XAT0aYOLhKcfu1oDghmk2+3ZuFK67L2JKUdE3F1Ixy9gfXIN32NGNaAimf2GAMP5V9wIBrwRGbbiUTIifVWcdAC9M1CM/4gKDqfAweqfHuVZTDCwx8JNut5US0spnkD/SqUvrQoIbz93o5/86t81aRHSBVkeAa9mpTCguW19CNqbPIMpF/NXlisZ69WPotxlnGHQ8vWGXO7Kv1eufSPw++4Ev0+I7Ef7+Ptnkda5o+DDQnhB8ds8tCOv/sSwwKVkr4/rbRYI2ANQAFfREJs5/rHg9qYF+86olSa+KKpqQTio/HLN0jvCyDMmKZ6wdCigsv4NQCrXizjfImnhyJ8lJlUUgNoQVtOs7Ak1nqH+3Gn+sW28ruZ8sM8TkRAT0Y78nA00NsG1O78Dkv/mz0o9jBjj/lZ31Ypj0RbzNADs9hjMly/xy7LRwwEQCCEeY0ZVzJ7V9nAwj1e52UY/aLl/iuxuTTrdVbkl0a34ctVbar3uOcdBqTTriS2QPh96Pc4MM5UCAe3Mw7Xv+X0ylXo14aNXB++izqMN41l/BehWNEC3NzJNHqxpNCxT1X7rR4bOggXNGeiv6q9ikYC1IYsgsADfXgJ6t/gDw37GjrPtuNLcqHk5PPfxW/aX9V9FKoHEAwSXsrxfF/74DocrshHrn2ZyrTvFAUltcIua5ol/8ti9PPysm8CRlO7XJkImV+15S8uw9Q1tue6iUDr2+bqOefIRUHul+wvLm1P/EJkdSKLIk8exDOVV0nAABZRiP1F3+keRCr615hvmrgKYpi5VDByAigE3lsyxlk1Ki6hGaOQ70udRyoy0FfvJORFkPewrJ+B5nMqfin57HnVN14OcVSGV2AXNocKFTd+KmuDYJrZtZYBxdAWIOS7MObszY+Csryl+ZZqAhgRwyblQ02XcVXSNPzNdGFaFkEo2XZIpeSXB8ZLAHncvJdWUFfZR/Nls4V3H0eq2PCGA+lQggFs1mEOOmIBRcCiQO32DBfJRarCWhgLRsDJOC+bOjt1UYGRchMWHqJYxFqsNt9Qe0JuYVv2mizAe82KVJLRZmifRe5ekK88QC9r4qAm0yU6w6lf3m1qD6HOX61SfFXHY1UJZgG5FSqQwkMeSvbR3GOKuwMZfaaMqGVDyTU+0M73jBouv1IJAacNsv7jNt75pTNycNkLq6QpZmtRiCDEWFiNO+YJd5d6wfgS0Tod26vvfb5kT8xA6nO9vIsIhZ+J02+41r5jA2hdA51AMXuAtl6f3SS8QJkeyoesxZF43kY6b6CS9qv1EBF6nFFSVph7B4Es6G4koZXxj28VQTjafqNcMBWx+hRBaIYoUR7JDFES0h14I/797ElPiQjhccLhjQjuI7w4/X50Z1Wb4qKf3bndNrEsKrCI5RFDo77Ml3l4jYmExS0kGjtiOU/Oj9dsu95YnLxG/nD27QvMd2Jb8bA/O2swDHL/9RyJf4SDv1U7NbrznqeM7ZTrt1+4D3eLzuoeCuJNQMtyg8bvJrFTe0hRSDCAaNHlmpYeu+o0V4FAixggfelP3YOpYBaQ1zxbgcJkkI8h9OvnOpkOLzMyRorpEz2eaNq35RGEgl3DhADVA8904AMrOMb6Ha8CHCEVNe6MTXh4uKFb2Kbe7C+8hp4gPffkTDrPE5cca1hXGzHMrqCmjNoPNyurRfQIiwwroiZ63ic/nJOS12HbYgWUkaZp4Tl4Gkod8QZHm5DOPKd4mgzaNyHATEelJ+JAu/a9jJMKWiSzlPgXZm0ZFEh6sTeEgiKipDtv6julUxiFIu1c2N/YEiU5zP4eHmDv8PPvEpkVdX3WSQVYbEcotlW10te5KFq3u0vFIF4J2xW+H2pRlLKE6RLxEJFBF+a4YqOBPhfsVapY+RYsuxFx74/h6hiT7HVEZJWVw2XD6/R6yD/VpMfZouy3rWbVfHs4/UsWW9SqVo4U8Tg85LCi/XVKcz0l5w9Z3QNB85AIFDH95Q9VEwFwPw7na9/+l7yJ0oOW3U9FkoH3jtG5/sUt1XrldUgov0GGcEf+kHdwJXMiJH99S1vK7zvzC4v39IvDbRr/ZJXG33suVlmskFucEMEYkpWUlq9ovDkpZMs0JR+NrqJMr2o2YNi8LM8PgAPyJDWbbimW0+WXLSCOQPpB/qajKUaC7jGSapUAZFjRc8iFFYkgxnfhC5SDxN8FggVS65thm1t/heXnhGMK7X75XEZ02t+5v6aWL0xGrxVDdVeWG8xlnZpYtnkexw2NncRPnxh5lA/w/VqvOm1rPZH9K939OU27Y/u7UewUPPVb1aDXrauGy5L6i3EQr2O+FzfDVyFPsLWuR4KrtED+1PPhPwwJeNxccSIBjhHEz1OLIvfwcp70PNrNSHD3VpnmDt9z9CgJcAqXUPPbyu/Rg9avpPohbsBkly458kqhzjp4iDQK6Sm+zWGz0Vu7w4TnJj6t/PqFmv2SqSVXzWXLK9O4wMDU+4dEy/HpefSw3k1TOXjZYLr3407NjEU2rYSSOXPi50JMaKoDQE14uCndvIbfIaT5TwHxfFKCHMrDJ4U5iE82lkr0N56UToYqysmH9rcGnNFkfkqn2pHlzRd+ytGn2IU1LP6+qr1bGpjU+1iR/k2MkQpytcIJC8a9vijlAe45Irr5fqOHuFWk6zVH37tZoMiZFYz48bBTI8dgcUqyTiIfIfwwfcVrC+N8HYXVwQiXC7YBCkHG5TKOVaZhF1oY4QKvMvGFTGHjn0Ulfsl94GdkLTPfVhofpc7anP4drOynt6ijp94TFZsIVbGV2X/p7wfASrzN9eRANv6uBhG/xm41a1sESP47bxUJw2jbKJ2VD66ZiUfFcQqYVfjeCaHE7lkXuJbKhTqnqI9Oe9nlJrAWOFtWOvzCw7bvksy0X1QXy/aBfr3omUa3XMflAUvCyMip0nFx81/aIPHiZOHcwptOtig+D2Y3rqUHC8rauaUqOlsj3yITUq0Rlyt7WbJtDllWELFNjvFtkTMKO6CYCiWUNcmHWBCQmhDKHturQenuh7bpWAskRJ61D+Sur5oJnXGgx97MQDOIhfbzIr5u3wKuapF1+19iasP9l5zTla1Q+JFio/cLTtlZXqf6aIQfi4ij10VPNPvxjR/OMD8/91KXwtFHlOYza1OnawSod0OP/JwzZKhyuWZzvfuLoh9l1WJRKbtqcyXZX38FMgye1rrLgH13o+G74AP56LPuoN8JrNnf3+b0E5pIHo5HIYjRBDZX8XQ6HEI2xMw6oYgw3WwUVku4Gj/TdRHjo+icDF66S0dyDa+OfGSk9sIzjKRdTsB7guKt/q0weQovD3k8WUDuX6HE9L+4MrS0vCoIQ3NKaCbLZiZAAX1bZ1/vdrJK65TqORfisRw1vKaWA5WhIFlEhNPlg17KZIshEbtKmyyY+5YbHxyGUfa7+rhRoDjOgibEX6VLMr5McEkFZdRlDkfjcQZ2SfQhX1XvNkEKndIvFegq+g2J/IN6rHGc96w7Pp99E/HAyX19FuOukCl43bmL9t52GW7913hqyhyOyFR3hxA6R6DrjGYV+tQMlacvWUx6nQo/P0P9XizC4G/6K+dJMz7H6G0Wgrl9fqEnmjmclNJO5wZAJNPuhQ+iITlz1zRM/e6rx0lhFzMdhsmnb30qzlD7EUCX/kjZzx6ZM07OqjctQ3VLkXkBPSvEv1SdpO1J90JxJmwd+O2n5UGjzK5a3UDoVf1cX+qrrqSSQz5iNlSHHMHNiahpD5LcRqUfOSFmVRje2Qu8Mkx0WzPkEViQcOJ5EqkQlIwdeI1ESYwgWcpSHKK2Ekj/tewMINQvdipL+VpE1wRIz6db4qzaWa2k0lktU76l7WvJIjohmpPjETZySUxlic73R8KSQmVdR7y+eFwn14cLDRzpWQ9Czz9fWa2ysawtLtKR2zQa3vHLFcYiaRvslpYXEAiF2fsllZ/uutAxLeXgcW+8wk4bemVyZP7M/QbTOof5dceLqgitvAOjd6iNwgY0zemH0xcvtvKAIssaYrdnAqTU5sqh0A4Ka7DWvkGgjNyM8KHhHN+9PyrTh9mviCIyxCTK1SSxOYm1TlX+U2LdUCT+sVKpneniKaOUDJTqa0M+nF0sdMHcvZdi2Bb4rzwTHLWjRXun4yYyyUkjx/39/g5O13SZfBgnMaYSAGcV9lU9lKioALOnf0ozwhJYzH1fQ4WWI2B0eIgYxM8/d0rlEpuWmXa9bZYlWCvRp3QYp7Ag/J8Ff+4cNhcBOb4G6tBry5YJh5UdafHjm+2C9MCsyxC9To7NFLj/np/FTkf90SN6qPM9Gi3ZaG0gGfNvQ/zoFa9MdLtvIn3YjbBiUzAXtT7RKUtDZazeGn29b72FcSrlm6QREqpmOhmfTU/7xfrm38dveENuh41qD1plCRZF+h4HWnBQuVnXzte9jM04ky0pRjP8hDf3SnaZWplsq3FNuOJZ/kHLfiXwKQ33FTTXpqAFq3AezEtMadwSImW7xcuYaocil4eDQq/9jidq6HSkHeId6mXJsT82ftQ6YAfaRccpVjPTDOw4N2TYtUBweYVHaJgw/KMJHBRnPem8u0nqqcVK7JPeftGF/67PO06tGmmYYELZxUSF1YoaJBn1pIy57kAj4Rfvf7ZgwID+ADQh8K4PEJioZ9qgUKS0mDmZFlhEydwsdWuLhYwTBoqbFj8QnlF/GKU6zRQZ6rwNN6Fd4pFs1VgiG3BqOvSpOO2n04I5Z2fLMZZlGHzX/qXcuWknmrqY1S/9LivrsH7FX3KWVJNbIUOhObOzQITaqFW2setOb742/eFkZw/AXswJImAPuZwWBUZQSrsDShajtlNjXRIIP6gNt8d14Wx/Y4+se2wlev6s5o0ZS8DK1DS+ldMFb4opPJL/y01m6J6rwlLfmbHR49juOWL9gLS2wne+RhBx/Eqt4WczZhmdqZ5PhPoWuTHLHaUF8mh2UMLpiYiayMYUsjOVKo4do5E7+yhi58QTk5BCBtaNb4jZjuV6u6Bi3mBSj4aLxohtatDW5I+Rnawuo1bxTWafH92RiO6DYZrfzqp7b33YXcxovSxraV8uqjG0auA1WmYjbBghgekx2zuLv3j+YXSb1/mSb535gvUCIwHdhdRE1foe2vhWua+xVVz7/aQljv8qmHKJ4zd+GiHNs7tVJ8MJY3PUy7CkZ/+exy7D7zw8uutXvE5eI7pnU9jvmkjwx55DNhXF0J0fn2lgqwv3GYzC8wasj9u8xBHhxgK5gnHw9jU4sXl/FO+7+YrigsQzO/sS8EOHNTy6Z3/V7uWbUdjUY3e3ZMTFUy0RPyMbfGiIjeopmvxIhLAUvE/ZyY1nF4GreSOebwOO4Yf1ukr9KLtBgeGT7hsvnkfdv9zaXbJEEJ0C2TT1bXXGNdOFLuxZ8WYy/nv7NMu8/dDUmjWXqx3weFw2mwzkUtA+SPMNneSRiAMzZ3U374khceP2uVyTlBKfXf8K12/AKQn1iorRqNokblgKEGc4qgsqYUncKS+oxeMFZPZoaXLtHb8NfYuizKXK2+R4YQeYaMTFwazvlqTYF5FeuOotyqzLtzmgwk3pXw4lPCqS9goNQfy1lOHtspQrhYYR/tfrxtIYE4ZHx1j/vmf+RvxA7+o8ok8pSJFzS24r8lJIObLTj5nGsQ+ORYztr/tPC20YxvoO4RXDYmO7Ux3vi8i2+Oi/5XIv+ne8hqrRcxkDvy03J0+KDSIIQtaOZwfR+7zgs4EmCJvTb4eQlcFGIkQqP6xpWyCua4nHx+tLkggXsX/PRXLjAueCJr2wPFhQJlv62fp6tsQkXNCuxIiVuiGAWJ2QQoHOjO/ywyR0c81mzy7WzxTT0GSzCaIpvuizu8c3/Xcpz29gez3/m7X0kM2AQpT5rly15ZyRtFnz43ywlvTOkZQHrXwHCgh1vSW/ZJKZRNr605HyuP0OSthf9i6tN2aiM5NeKPXJTZu/HzVmYJHIPRwLfz9qDi1G5d77QpljWBAmYX4B9askYjDnNuA3EzzSnoahq5LCbzOHXaWKVZvpLP+Va5qfAeZf4UgUyShRJ7/COCIJbRHIo/KnXdjdrArgqcxUuf/mSrI4GVv+BG4WWqzruMJjgMryBaJ/xFGJoFF01aMwRwCHVlXHHpDUSB7D7VXgcy+gtI4k01wRyRdyoK0momnrDoeZ+CUpgeaFbCd/F5fsPfOqNeRmYYnTD809eSqEzEwRONDS8l2lF9pEFX+Q/bpWbuq4esoFYDjup6mMjgmhoQrRaxwIfUiPCi8vuJMzXAmHmMDbdMo3bnxW/u8mc2GQAQ+Z88r45ttiy/0+X8SO4/taMbkMe1y4lY6glnrlw+mtR08y0VB+elU7uBwuuaF81xwuozTBSgRJdCqB48pSnSUGH4kRqlm+9hGlQIEajGBhdD+Y331jXfFErvLUJ+Mnp9wrVpTlZRBUFHcWFVHQh492Dp+etgvnI8qD0L+IRx2UP6rfR4CbP5Xms08lD7TIeeHzdOdtqT+NeVvBYfbhUeb++iMtjDGBlp0tdWQryvwCbtf/Jm3/viw/ISrXBFuazco74Rgejp2SnBDbDy6S6IAQCZp8G5Ba7Q/J53UxMvFVlTkJ0NSkYSI4xMse7VT/Vd+/wPEDufPvv/IvCmbK4RoFGWCkvCwTRHkPBUpsiktMsPSgXZrtQ50UoX3h2vlkWWydBApmXj4DpuH0md1Y9SAqmWZf9iKkWsmENV6Wzb936WA9u4EI/GmGD338HB6pePg6v/GljhveNFCivaSc6vRuUxdW6ag3AV6NZp7YD+D053vuW8elBj/Qn46+eF39lh5ACSx83qrnYuYgXHo36wkow0+AQoTrhGZ65ysCaztWTThNsuKONxnUcT68M7FBeEW5y8N+tKqdTjDc+H4tm7I0bulHY8/5tBUfBLDhQkMbd7lHOyUi9kHWxVUGKuX8NWdn/GNSv/LrgJAHdIpnTfHrjQXpmyrRH89WeNvDoe642ifudGHeRC13ReoOyDdo+r7n9rCHh3G9F23BlBJFfv6wcuoXOA3D13zwWiBlnVVhx+gH2fG0VrC1q7VIRZWdDfXW/k0IGr2W2tXKg1mkjEIOMbUwHJn68GL7nUpsssz7lwXq9lSAuJgJLFwGQZjxmVFs9xCvOIwf/fhAg/UpX9LmMOavl30IzijvFBi7arkNBvVzaZOZzCmLHslKvse5gNMeYICJe8BnCdPfoRdzFbfVu94iVdTyK+xfKMtMKQeyzPydKd62UO6hTq+VyUwRavfckUmR0DResTbzt3sFv/Ixwh1Ok5VYFJLCvxsP9qiCEYgQHV/JVQP642GdR6AZqVkNSVfU9Dx3HEyE2+5O+aOt07opA2P2EIaY4HDfh1rT3eBQ5VrhYUFZgggLRjRVvN4B1RBAEKIfDG3ainHGW28n4tIrYzMPGCyff0wSBs0SS/JfCDu+M0ikEl18HSAmESaOuQiqbK9qQYbRG2DWTVZKSoGRxGAO5BB3bXDQFkZ7ENT8vwD26z7Cil92hhb2jNwbhUp1RSMbg/t1ZvNXRMyKJzkvCvZbCDb4iHEe5/CztIfccMzmL3INlJKVg7cIGmFjydfn2hHF9Pxt6VOCID6VMtCNjZ2FjcZzDrdYITgy9O2JKTRpIllm3Zv/6MGdEj2EheIqYWXQGYghKDoGGB/Efsf2p2+cuneWw4Z1/vWmGewDMHEy7K5DWW3vydjYqHKN5+pHqkQz+uasBmLCV9s8PEfH6WL1OyCz4tvi3J+QDBc/EqvNwYM0wyS+ndqvBffuKWZa79GtpG3ou/wzDUaE9wMOxzFIjFg4g8+YLDs9zuy19d1otDLHfIKzX+NgIXg6wObeuR7UK5//zqaNTHZWn284Ve2oEwiU+rPfzRAXqlAGRfVKjzRldtTAnL/O27n8eut6du3mRs8Kyuyk4pGw8GNQzwK2klW1SmFXxi0MCkgz98JHwNL/US64bS28wIlr4qAuz1lF6HduXSWtgfubSqUmcvHMG6rLyYWGouhfXtqM8R1mEpnnC3eXruIP0Z02cRRQRKUl/JJUboTG1OuqHOlToObZUXjfwc/Z2vrpPHrMQPsbCCCYQYyhuxp/CPXHQFlKEbuFBqWlA1qj2qb+9XQHhTakDoeyZwThoM5M+PWoQLV26r0xrQXM0kKyoie/WIOR1+c85Mr8oOygH7cswxOwv4lFBBBAEbU5Gzd8hJ7Dykr3SBvwh74uSAXKuJZoFP1tF5q42KmADSAXGY3CSbGqN2pcsMcjUDS/1m7sZfEAd2V2hAL1bVpW/Rc1wopIFWiWVQwW/4BkkQQsCDBVsL93DMk0/qXe+6lWRpmCDpZzyJdhon/Hv/ebOe94nPQhrv3NMBcZFMpEKf3u1vlR6bcYPsqt/9LtyI1FDpOJ9xfiNGIsxvx+mA/+yGww9EBhlEP9DaV5ze80OuMCedzzz80LV1LZwU43mzI62+xg673Gu66Pa3AhwGe+7+GX3ySVmQ8u5Ls34ZHioZjCWr1iGb0VMVP/wTqUNDMbteZfHyhEGjDRlzBgzAmz/pp6fvf52y6W+xUVajFJi96NxJHyNfj6TQXzJdXeRno8GjpshdjhOtbs+v3IhIQSWSEfnJd/LiD0Qvx301hvyAA79ehRFaPCNN13PD0JieIzfUUGgLiwpuwbrv8VpYt+OPjzVRaCufzdoPciOfbVY8Tx9U2sOQCzW8P6KcSbcyNVoe+eZZZyp7WQ8S7j8c2cAg/GbpBQq06n+vkm3SPsFbyrhLHn84GSMnrirYCqko8CZlqgR3vsos9L2/XXeEgNS/hwS0GWW/wIoA3e6ghgVIFRjeL0MvHQ3GmddiLyMeZOvz2jaSxM/TV9bOSYR3zWuRmYZnz1WiVYSbZkQUbVv/Sd/obs0VZOPzVfJDfysMijo1N0sClyJvTIu9JCuiriIpnZYnhezTRGrVk90syxtvR6S44EP2s+ZiX76HG+QWybGPe9eKXiG7HU/Qph/oGE5+nCgyLWTo/LzeW4kUH0CA+T7Fsu4wnLtTlZJChfUiZB0OWD2eQHKch0t8J5PfN9t7p+Vu/qouvpY+Q0Tl/BLGhkd6tkRqZKZLxHNCYAyXgqWABQT9ypNF62Uk4XGTvfM0OTaY4kzNXyXiXsJAN48WvT3FW+f62M4dSgY4kndKs/ykb2wMJnFdzySWSLZjBi+cIIbrNio+k/Iq1IaxQzCBDTkiiIP0Tjovmh1tPY1GZZZ+jeW1zExw3ozNKGScV584fK3NfgzmXAVZ49kNfAs90C5kdxlkWQXo3vgLLc3Ve4CUQwbBQ+lZBz43bG8y9D1FKFFKMfqqxBgfDMpCE1PjT3nfnpTqqT3RaJmr/t/bfFohzUrNdURLzzI+QW75v9+LH1Kjb/FVvfJCTJQOKV4tW8Dz2/XVOT26/lZwynvn+aDDTSNB+1N6Cx0yZtAcMbwnPefpWwva1ufKTTDD2axVNpni5uV7De1SfmI2TZhW3UwiYblVbncQVmRvwKs6pXxHgdFMgY9a2fr/kzSX/XgIDi3L0qYxHYEs8qsmxJQT7DxhDgQYmkBH9z3EaXqRct7MKQ0aL5kG8BcTe4rrEmx/+Rewjy0n9ND3DFH75J/383oMk3Z/zw/TcSGib5+gvgdoncgCWI8INzq2vMKEbkih7ejcax+2zFNsy/3oWG/+Xt8v0tnJ2VqDwv/sozg41HumHpa6055QpF0SPgR+SQiuawBT2yZCCXY/DW6JsdS0kpEsf2ANe/bSUM4YgpaQbG3fz8pHSAYIr3nuDHj4Ghb7p12JXHkvmLBKpMjV74YTzjQ9RY9JwgqfgbzdV+Gi4omt/KDEEUxNltZo+O9SsDOjX6h99t/zWdF+QaVUQc3TvWc+4mxFwWsUhlsAp6hj06Dxp8XzpOPBIx1GimDA7rUh4Trgxs5ZNg3Ho05hBuWN/FQ8tZyWVhWEVC9igFOl3iuIU2jHstdcGZZhw0MP1Y7CkoY5J/S4ixnsTIF4VEO4/CCqD2UryT/RNke9n89bBSR2Fu60o7yqnprt//WJJ2NhPuo/h5FQo7LmDNgprTUdd4gagVrSOYvz3C1BT1opfVsvN5RQMoYKY6odeXF1PWTxi+md3ZQxz0ZRH11Nvo/j7zgbWPSr3SatHPqJQM5hy+u0utKEoLYpFomTRyKdTP3uD8MZupgQ78138SaBuDfVZ89GDdMWq7Np4I5mRemg0iPgwGvTVhYzqLEgmFSw0q/3rUPJq+d43cVlhy/zwo0F6bEaPgdZf1y8J+VT6xtJ3Rybbv3cAw/5UPSwDG89E/IUXTxNAyzlCMIZnO0C5XHKuNIVrF7j73bsJawOXVOjvLJIbhUJ9MtuA4ejNUBlc6sG4MqhPOwHODiD5GORmiLyiLmYkLXaXL38Dfby+kX8EG8p5Puh+Gi3dWFrdXE547ZiJ8d4Xjg0g1rmAM/CEn7uq10rmTxEKnnQcL8lVvaCI9gqUi4UiUQO0MdAyXN80k+W+hMq+jaI3YSXIdXQ6l/6aT9oh6v9Ks3oWaQeqmbbKlnmU1e2k3HaPlkeQ78Zw3AgS0/GV9Y0CsIMO2gC4O86AzRRRYSIiwmTiBGfvW7Gi2FsbVu+WBGXlEWqKqicF9FNJw6MhXPLTJIreGKfhf7dM1YcqbNE2z6Q5jK9wfD6zoGgIJRbMPC6MSRUGvBY28MX3fZKBAXvWY9S5UKrHWYQ0B5nRC5DbpL9JYVvLFD+r/u1xMBf9CEcMwZXHKXw2rUUAHNuKkjOWcBg+Q466lW/oy2//xdF1LjjLN8mnOPd5cNt4bCSHgDo8Q3sPTH1qz3x+xEbOxs8Og7q6qzKrqrAFRyhGMe2x+9bVUkrCgzcmEWbHOSF8wv4T1PNJZDGgl9xT7WrMQdCW/zgO1KI+xftJ0yAUe1Fo1GfkNokgj/U5ApRE6kY8sWgmQ6dop1g6ivSXrWL7rX/2iMcNvlImfrZ4I6DX8rGbC2cDC9bKkt5G0YI//bgGcP1n09dEQntdLgbm8lA91RClGgOMl13avLyBJ+g3s4ivG+Hkmv8r8awR0/btWJiEOwZK3L82t/AkPeoEg3RVs0fr0m63EcBhpQuNHG7/Y+az8NDYY/HeFMvt5j847VnikWa+ZduVI/5w92zmcNcUyojpUcfvGJ6m88Be3C031G9cpHqUnhtiHZ8xnwYzWqy3aVsWRm27W3UZZRnCkzyH0bWNgqTdO4s0jYeWHnCHRVN2Rq0o/dZc2O2jp6NClUNENT1s/ezLWMOfGse1300HeK63TZc86fpgwb1+cZB6uit89aooNVZOMW6Y5V+Mm7M3Urkx2cOMycCZV4lQjwKpeiSSbSex9lGeIg28iZ9rpQ8g7Rls4whjNOZXRzdiVkCKMRwlwEVNfDlWH4n4bR8C9+MVzq80wORE9IMoqBxgA47JNGOWQ3s9fNIQLFloR1JOKx09Ju1Buj2OMwWYHimmm+ddhuBR193//9bwqCpwvILGisLYYs3Lnp6Jig+VKfrr6/MMRHB75WzlfFsO9TNRQYpTd7qgHfQ6koPZrw+84wcY/b5RcLLvMY3qRt0mA4pNU4zPhSa65vc9blJPsA4y0URuZr52j3CWzMgXmVN0lJ5uF7NMzRNqqYt6eMA7vUJ5cmfhpHJIATV7qUwU2/JTv11vcP9F48U8816qiQxc90E8WmRiBLRtcIpoYG9lMhOnWKXiWtPah6H4lo8/9bexlvJliaOqP/nXeH4Z5b3jK5SJY38KIUC5fvc05C6iAc9pnBjrwTSYquj7rY2z8p/fgHCj9OTc3YKwuEL8fD3RCVTQ546rr0ekLh/Tgjn+jhaRsRzusisQ15TWUtp5aefNV8Gt2JhP4qC3OlYIELgmBBmNNqaQguOoUgYpFp7xbpV6q4Yu+HigohVopNopHiM2nGRpOWJOEHg0a8n7yjYltXs6mm8WCtHcQ9DgYJlmOoniW9d+p8JWFPwH9B9y5FiXNv78dvo7kbB+GZwHYs+VMfY6I3s5BC9tVnPARldlCWzZ3gVWAIxGlB7/dLuEfGqMD+hUTWzpmmHSUCTwQWRKczfA0o6LnVFcGes6uMs+5uRKv/HYH+XcsrlKOGyKTnaMgv7Xvo047jJJ+BQJDkNAnJxH6i4nVzcgV9ZIlaXsS7PP9Mor1PQfnFd0grDaz5qMgMKHn4EzDCoUF1euk3Hvupg3Sq/5l7RgCqQ7n2uMEHwIWEThNWWNnxg+XMgQXZ2aDCBv5uaXrRikV9TYd6grSeLiRS40zZVS30+FPU7Tp06+qb4yMLaSxouNOnuukFI17qjJ4ioo6sp9xu3F7bcXYmtIKMPmhX/PTlDsZLCudb0AGsFUZLl6SDRALy5ZFYlxamYBX4NTdvKPaVx3NXcQ+lliIlW038IueVuNvwbO/L3nx2VzogIPmegz1CQPll9ECjXm2Gu3tl9vKMKujCe912YWUSNH3k8+1qHjKghBMf7a/QO58VgmzspVS9ix1s6PjJ2RYQiAttryUghuzisVYRI8jf9VzRWjiDsJCC/mafoswNeZvAqKNf08saQ8xgHQymbnHXEh+fVTOWbyoi8PJ1l49+xsQCenizO6V/ERRAQWisE5Oq5uXm5rMjk/I6fdzutwsakTZkngKu8e56bOjQ0yfso9b0ZfatO+av1MyJ8mik7jrXEDEqkAOtTsMs22UoBvLFl4J3npfaMAVWtTWxdt9qM3VcFoJi3RP3LugWgEMX6+dnhDHaS4GLnQs5XZafGAWDa29UoQe8ssBg+p9ghW+x6tQ5U4TduH9uPqNShFyqza8+Z03zeXDLhPX8Xni/B6VBywMnIQ+D9+VE9We5vwdECJpY9WcUisVSTkQwOkR9E09M+HXCMbsSqa5gnLIpYfkL0Am9LTwwcNHCiSTN6DtK7hdLoLvOQrVoGJZjsVzMZEmQL4KcFbKEYPwWF4vLjHXGmv1Vpx0/HvS47sIpy44/DeatGkmEv7fxs1C/nraF3dISiSYXIlM0rQb8tsinoIy3IxUJoxCZnuFKCefppyjWkHPLN9a7RsoemO4Qv7NZdV5KitutF0RKlvFdR/kl1+BRxbWbOQbRRfxg1U9Thi4eL5YC9fKIE/62f7yIQz5yiOZVTtbrbXHb7alM22wiGFoBNVQfnl3rHNxwGKkXl2zsVIuFTeHHocD4n+MdvHlADiHdHwzFv5v9HQ9K/rqsy/V0MTv9mH6saoEab8Sfd3jufuoc7b9si9snEPxR27CvlQ0fU/bwePMul006dOu5g1bPT++VuvEpa48DBzCpmyzfgN03wxGxEaQdvwSWXkinPNAYqmdu3TNXI314oZEbbbWy3B/IV7yJNa6F4y2EHJDc2YLwEDDNwcJzHSNrRzd2Q6Fnqx/KzBjldglQtyeQ9253snxvpEjnjUekCMXq9MS33XhC1px2F8G1vwfTU7YT+L9Mrgf4cvjfQUujn0OwxqbRhjP7wTPMohluRsBl3ohIfxls+O/S8ZXh6gC2XY64z1TsJShaUCzJxHZsY8UOl2k/hzTerg40MzBt/ti0ZDg+TUis76EMR+p+G1pKEXeGKS+Gc3Uno4j/Sa+le9SsnIoavS+8fJNp/S1SAGXX/1iy6ZDDK33m4BBVkA5HBzPaT0FYgmXJEMrwuVCXtHKMseAXGLNoKhqD7t/JK6h5193toH+nk7uzJ+ED/fvC261kJUaNO4yAZpW96FAx1zDHDPwvM+7LDjgHZ9aJjxJzk/GrF/Mn3Xsl+JCHuVMVBwAMTRu2MeIIfeWsP6yQk79sghs4X4tsfdmqyEXseZvqBsR3e4oELm+6F0J/3WUulencCGietN2KUmvXFr0nEcJhQAZHXoykl8waNs4fOvs5b23ZHAUwRaGqO7IWRstJX6skywk1VuQv48R/ZKBfHzvFYFstnKLn5DUFB/f7J00XlC9VzS/LmsnFuyiPzeCgXRoh+0MDzybqCE86PyOxPCHyPlQLGU6gbADVlFmlf04PkraL6zJju+ceMtUJ+X6JECE/wq4SBoz0JHr0naRJN5P9BovI5cI7GWf1EUssGm93t7HpB6uMc5BNrkMB37CR398mFucTx3MEQBEnDcPrt8B2DvPX8v5k7CC6D1sdJZXHeLA12kEOP3MHsM+PKVa/oEZM05Iao9g0sk8fTAL9hMZ9LzXPKMul3PPrAYJ7ak1s9BlYVMVKYaWpKhIWswXYr+zhfQur8u0vrZAIrTnMK03Dlde4Rf2D3NDKX/ET3Hg1mT0bS5sUfY437Bz/TsX6bd7YC+dn+i2eKr5PrWVpfbZFdyxyAm5raOXd1sDlvZ41fPKtxrLWa9bzbM4mHoGdVvQNqwj3/+DyA9DFLAPtvQraOqlLN7W4m3btsIE9hPOR3BL2MEpHYSNwhrYE41M43FG5SeT/W7NRhvd1rPKf3xqeyigAIVfqnvksp+y45SUJq+9bbfrRaV9nweK92zTq1p2uV487iBSVzr4J3gDjn4jeeGNzrawI38m14jvhaJQGMPlKslYUGI+fn7nSR+vFU58gUl9jruMlO1Tua1vB5bD/hLFZ9CNg+fNf+bWY6/TulNekwlpu5QQ+KJcsgbFgkN0log0eY66aLW836P0A6G1AbJFh87xh7sOfVxKRYWB+3Ugcno2z+f0iyzb0dWPtnTqEX2uP5WEq+5wZZ9TYmMz/5uYcqh/CK2AvRWPmMn6xVvipkz2dBKGnSKB/Jj3mIDUgqW3ghosySBcC4MWwffuSwitPUK6rgbG+XIWjKUdIcbclq9TkmQH6UF/ikfMn3iRUKGbv0/iOVevuTWOZrj49A5cb1QFavImM7SFvhPtNhffNXNsmB3U/Z/GvqQJDdNL8Uty3Y2aG+qJmG3cdMUw2D3IYN6l9T4H5bTDpkG3PgKe4biXLLysvnosGHr8rusl8gq7vxIXVUTcn9kXNo3UwEzW080gITJn6tV8tCyYSAEI7xOWY3L5ozivrKyt6wxmL1ojDtt1yuSB9tEpP833UgE+xaa308ulqD752tBAQ5piUd4wdy7Xhsbmzye3FE1cNxVgyD/X+fa45oIVv2nJPXiOaSLE8JChXwh1rEa6G3l0LyIUuTk29TTCKbfd/EO1CGH41k16+G15bjH2TxluDerjeGQK4KrlnT9GC/ApvF3WyHARnS70CV9tTim3hB1LnCdi3GZQWWWeElaqhszHm2GxRQOTqs2ANo55ercDlyLhWp/boMDS+dB93SjrBhwnMgT3pnRMxhLyXUfm7CyQkuMNawvt5SqQg0/De0m8hnx3DSdTMJGI2MnYQqpF4qRebgLFbg+jTgs4wIOzSaN491ePxCTropzZvZEqPAGfOc2AVsriX3qFzK4HX9P7sPj5cHV29Iw8S4nF4ncvZKRS/673NrmfO1zyQCCw+gVsE/HGO0bLuMY0ItsQp3v4GDCaz1cwGS8IYJKSzUVmUn86BhCs4hKMk8NOXr/eGWkBVxF7DXZznRvWRgIyKXiCVG9vr47XE+5ep3m7fvO/upZ+YM0bb8q9LLsZfBjBRgDQrq51LaLDhJofnnyGEk4JNhUVpRL7KFusW4TZNk+AxsR4mqxHucjTcwHd2+uzyveTXu3EDpAEwz3LCqiOR4B6OjhCPxnrE2zUY/yiZ3kdrEGx4/UhrtPxmByGdd0kLDZlB4rYPze9rqC1UwkWnuzZQwXyC3nR+Wz6Trbv986HuEg83qZbmdCWbjpvb8+i+6rWnv/qcJ1Ue6CmRLcY631LW1AIDRk/mWP8wLIsWoUXzpkCBI+ryZbB74JZmgt6TPK0Ksg+aeFRsWVOwng5VF2Tpgp/4B1NJ28cVj4mewd+Clg46uYmCNke73z4q2ULyibK6QDXP+CEFI3oDGCdCvzCLHTbxATdz7gPfMbNilN3l7ZJP8a9GUsLw+o4rbBybKQOWxQTnA/Yx1wtHhWLC0Llj5kZmJsSaRiF1pjYMpbTU3DUgzQm+iSs+Bjojo6jo2cl1FcosqPZueJ2yl2ohmSf2dAlh5FvDDVYgfjFD6Gy50n+M09RboXoJ3WQ49wOttHyRex87lhYt/wXhMBHmPLGiY38fubOBC2XycgeXtGIIfEqf/ILMKuafX5TFqfbYQ7qTyMQ6wSv+qmXwUJIuXX7TyaTjNJ3Ql/HoxT2kfpzOmL5ewXwFWScy25X5sGpWAc8suZ3d0mBBVQuPt9bpmu40v2ugXl5b50P/q1mhIj5ARV55ht7RTtCvGdD/9g68VpTLnRvkMJfpCHfMUeLj/l3e8hsrRfF2i03bUkFO61i7wG0bd2azadgeEuowr1YbUeE2NWsck+OiLxCslkS33pCTh9/L+ycE830wmOKQ5lWdNrGLthixsXKG4QJ92IAkJ0kcr/xHauiao7WWPnd7xeoSY3VIku+D+BYu1BV4kxT8GQ+5V3/Y3hSVqP5qyDFloYvNGHI6JC/KZHGNz835Xn0hJh+5UIp9d/t5PrB3KGfGXNjYUkKIkul/QHLscndgCHmGEAosnGJtMnRMFJsC9AIwivEeSmte/+y/FHs1ys3SHASUk6MiWGok6ZwO1ourwPpCsEugLXfCGoIH9nKvrPM8OmQDQ3B2l6ncAhHzyHvEhqoY7jAGTwznzDr7GStjTvYf2omjqhLX5z5Jle8qu2BGk3O1juq1TMTrh7seoKX2YWfEqW7gqXfPq1NhbtW0nwXFpV4AvXKpE1oVGO3SyDlWeeq/ZVOmsedOoF7YeRgOTv4giu0htdhTcsXH/FfKg0zjj7dXQXHGSo3EhoSHEWptG5xaWLNc4RjPMM5QrAdU/JK/t0baLdDLOONJ2nvxWyM2sfvmnGX6s0ZTfqcTtEEQ0uhvUul8kp8t/Lpyjenhsnb2+b8yqSvED+GJR1Ou+a5FGQN/VSfCDC8oHwPkS9bAEbMapTTZYfYbFOYNW68kkWXvf57DnzVSTHUWEu81cJU+Pi6uYMakrUDVpxPZ2a311sb6vVAN9dj0WbaafklJww1ZlTSZE55PgCAiGYwnGIitpBxdpytgE3WCGjmiHrD9S9/yk13QF8o2IlJwSmZoudhIs+gwVIKb2AWhlxqhxvCrZa0dAA9Tm1LKL121kAwuo/CY9voOcVWtutw5gFMeIFIDObz7V3XxftsuVYKj+zuRNNU3O3w1EcGVuWcnvnkxLbqFoLOtFauLStufzxXWkH46knVPMxdicSAET+JeTcWqmHp30bnOJuQmQWMm8lT+hAx0z/i12YYl+ODG6mI76dnRPuaBwx3v7BDVjLypWtr5lNt5NG5WaVPOcMwNFNJu50W5XLptb29yPalNzkaJsIRUnMGVhcblWkSwBMolyJPgQxc3gULbtI3ebIVP84+c1c2825v6uOA9hsViwRtTUZgtR4Y/KqN3bLIfu+7ju2TenW5FiC/csqXAcyDfF+W69S0jhbouun+8XhHWkvo5W2px5kr96JicYAE9HTHPZQmvq/92dAP+61ERQD5ScsLy8UhryfD6cDGhHHQkJykLFcwAJh5CudJU/lKaazzA4vY1dlPtrbPhGEPbzS+iWHza75CVV5hQdtzS75OpRC1c0R+iZQ98SCh2UxJpBvy9QOpx6lRanKQQxkG6ZJeMTOZzvGpJuxzlTrPuedBEJsNQwUgi1kigTp8M1dl8dfb6l/AZAeBRgxgmdvFM4IpBw7lKunxIoSkzUj6funEr2JKRxMLM0gZZj0/9Lp47tXuyEgkA+uygbogaKlPf7USyfgcpkVwbwjNhFLcyg//pYmttAM/eoFwFm9I/UZItscIw5uhWUQVb6wVp5iba6wdh+tQqpGLjp83Ehq4sAnZ82zFOzdnCSomMxdVeyLfdv1yhdUCD15YMHuwW22g+9Woaa/2+yxNDB9PwdbjIZaaSb7Mt3WGtyMCMG8L2z/W907DADBN2pAq74wR3UfT2z1CyotD3ND+oOMM9x/475oHGZjF9JrGTUz8R8tCuP7TfNjneSStPBdzHZqG10r1FMhLMkV3lFHr/RvkVDPEGTlVJxpwXpZ69CZXVgOvInOf9eHZbW6GHRnDwOyR0TPsURJNbqSZBMinRCPAx4W4LtwBfyeuxXu1x6PhZEG+NUJuIiCxenvzq2wnABMGF1ZW8HYsQQn6r21dcNXdE5p0LND3O0tn6zkNMV8mVHZ5t0OaZXqL45TD18px+SBkOp8rDsATkC0klBE8UUGCaUdhoZ4E9rJgR0JmW67C3Vin/Kjo48no84cKZbhOBrdVCNI+BvwsBJywEDrcPabGqzo42EpCIjg3BOZzN1HllPitOhzC8i/XhTDbWEFuvz/JOajbTF3d1VrdVF+0sFlpsasjpVTH1bjOkVqA5ppvcgZR+oAzUEhmG1AbSZeEkRT+g0z56a7pPjtwj6TwJmtR5NRp/HQq8v7COwvpv6Mbj9T4SthoHLDkgJ2jsd2QLnB0aWb1vXtH37FrJxJtQghAhpShF0GcMrkpyH0yc0n215kWg/ReeEpSGF527E0RKj2Ud2enYeKwJ/zS/kqTX7sxk+IJLWr1zsEBZ26pvhk1JABC+Xsm6eKKtjlM0n1dNm2+rVF7ginAAm4ap0WhmREmy8tn3YUcCZDdAbgqbpZQ3+fnLALn8bZZky5QlBpye2m94QZjL8Un+wHoBNK84A46v22M37evf8+hU7J1EqiDRDAMhvAiDAezLi8z2qpnHpN22+BX+dQctAznvO8F5RzHz42NPHgzhPZYT7EH3M5mknQo1A7kwum6gn11V26nz/zoxt1vwTWQHFND1VWpObYm4VaXxC/aeccqbUkylPmRXIu1OQUYAAm1uCo9pS2vHiNTOAGFSw0ezVDL6tM7VDFvlcYffAikVcjW2e0cNA0WU1R6K3dvqg6sjLsP3ft0tRSv+Hn0uy6MUke0jtGjA/0zHQOSx2lP6wAoG+bpCV1/O2Z5XRpj2tMr0E5Ujziag8M9JQi6nzaLjDVg7kh1YANZDC87FESwHpQ/mFHTZZxxaViNbyjMN3GhIxM3gvpdXWsKZFzrhkzx2uoLmXk3QacIxGHosfyYM8ZrfrW5ivGAMzMj3HyGcb4/cC+9vopm++DGU8O07RL24uY9SfnULqFsRIYcOtIeCIiZb6j1XxKYt7Pzd+kV/Fqknj2CVAfe5qEQTH2eZeNaPsrqQCRJVL2Au890W2oX4CoKN4AQk/v2Yh+E8JPVHUEwgZXtfaYbm+ccWQESZtVVPH5dNEDh79V7WBzDsXadijgm9mM3nyD55LvvEqRXoXjT6SFu6xVr31zZgWhqjPpj+hZG52cQlUb9rlEBhQ4ui8tYYGM0bUwYp91uqA7O4P1AhB5kqItPvMu1+No7xFnrvPIWtPxixTseUKKYMn6CYYJfFr6uWqlAgTKMGQlZHpidnGv57XJkFBFXCm/ccFNX8eiuDrupohfNWZWCmDe6i9ELHuVwkikZfucpJWELKJM1IKjPCdBJl/EO5rGC+Q3JlV+RP98GaW/E+/cvIixHwd4Cm1GxfADRrMgTt60R/pa/bVUs6P7M0uIUCXaFQTLoCDPIib0xVNb3gw8zxWo1MQ3SdtrN501U4Y/O62aMY3gKQwhf44ZhzW5/ev9wjjxd9pWPjh/ll8DTpIB/CSdg4DgZzsVlAMe77VLp36jme0bMBIR5RFQcZ31zW9tWe5d8gPDhxRqK0XZZSQ4++KmeR4T0chhV5akGqWu3cE+EeD60XjQ+klNnMKLEvO/czD8OiymVOobapiL6zuXzMEVfuklr/dp28uUsxns1LL1TSZYLH0X3Wl2Xikp4W8c4av969NznpmIN4rIrRADSWaCqf0Ciiz96oeQ8e056S1vYwotke72CndXNJljn+NFD15N94Rwnf3CktH7SB/ZwgXdh4nipWPE9odQGF3WOsVWcJ79q7Qi49sbPxW+eCONyjI0n1lEEE+Rmj89RB1J3vj+g0zFcJjKXT1Vrl1nt43ZC0jwuJJubugQeqOM4XjJzRrh3KKRc8rHIm+XmNmhZ2T64Y3GysVHq9hld9A3wJCJAbwZ5HQXCVp0pi0JWXz27i/vlPd3uIgA7dXiUrc5SONvw4586cNhGluagQT2Jhku2XC3TctuE6wlxAamIrRj9JLCEhV3I1K9Yu/whr6vNnJXSwKf8yM4Jeb/6z4+IALRPIO5q+cqxH1m+UTaFIAQw6s35XQ0bU89Er2+Su5XSY8CM7kDs3CH+/nOffqOU2VENYBPWThb+YZR8R/DYbgbMXCeDlh3kERjhIqOF0EYwV2NFyG4sxhdeezHgWAz4W1T3mogTrTuJyjrQ2Zy44BhRn65uhbqlBSNm/SavYugkTB/HVO9/ccwPc2+fblWljxYZYZW69phaozROJoMb+hQe82ra7/rhslzyGFd92azikfzQC0JmFP39Ho8j3/HvfnSLVxj6igYIPl7oSJoheBtHquEQd9eCFwfx1rwUnL9+YoB68Ol3jgdYgB7SDmzhARsGshbLbagTzf0ZvlTHy0MfXey63nw4NeHKuCogP29zZNM1PnKEYiepVvFwJ9yMDbSJcLSHfaKh9bETlyYHXfLqHQc7HVBy9Pq0l0ea9nU6fzFI5xo34wC4Gu0R+16Tf9Qn1r5hOol/bfZUGl8yOoaH9SDplSkiw9Ne5TMbaPbksu3GUmI+40YqcAGRHJSBNecB3ux5ueCzyCGa/0t0vkVhlt+od55CJTRI5u7OBxak6wfTdF3Wgkf7TnzE0OYVm2A4n/QHt8WC64ASVfdGffA+rVFuOj8LvAIfbl/g4liI3JE2DKQIoAEeIiF35e92yXoT3KzO/s0Vdxvo3Nbgpxphydzbpfntl329P8TjjnHCZwGPtIs9flu33b3qcd4EqAAsWe9SeaZUfgULz0O6Z0qreWMUd+3tT8LFRZBE6FfO7bUsk6m0W0OVCf5V5GZcNSZMEKJUpN6WirP2ZtfPjZbf2OMTmr/COCES3oMRLh6sqnjYLxxLsQuw8HQssKHkN0MZOvUXNXVYeqVFi97uWNtxnIDfv9HqQg0pUegXdqAPIujm0TGi4xV0dnwGSeq9mJbvLzjVRcK1tnbNLaSi+fEnrWVBPSmpdXXEWzyx2EeR2xGJltee64Ac4hl3BvBWAsBB4xXV8ozVMJT89EXp4qWCfheFXewJseTb5BH/xkIGS+dq5bmAiueWjJWgztxLuLpgh1pHB+fu641RHjXQLsTOeRmIZ/6cXxvpLyyAKdrDcHnoXTh6m/7qxlwuLxo9EB3boF2dshMsocjL9ZII36NbJ39dZFRtDm/FJJYczksFw4Ra3pyauzI79IdaA+M7CzeR3z6IZQMljFuyX5G5cuj+Zm5dIHykFFL0p7M+ReCytvjUSk510R3LosqZugt/7NZ6s8GV6Wl2Q7Ffy+j0E68irfjh3yyK9cgcrAvo/OhQijIoT0twXsBeC21MUXIuye1hnNpZqLiBBno8Ouo3ZrTjNmwxS01qEVCTh8maT7qWgp2aJyuYIvE9joLA8q3D99tGczc9LEyZhRsBdRdFltxffU5xpd1ElD3+iO3HRLjUyg/uUfs/cZCNdh453tWOSd9A0z4EzJ0nZ05lRyIFh74jKDGndVI3oeAP6gBi5H7l/AS1U4Z68ySH9Fs6CIr4cg2w0M4U+d0B6C1PGYJKN0MbrH1mHCMYa5OK5MpvFGSrXNQkb0cghgP9mughWCPGWCIWOET6EwS/f3CC9nlT3fNXXRt49zu7/lI185/b4HDp8ofh5nCX8dan/i8W7Z3ulbYdaJhBsvBB87zfiwEj1R3MLdHcLXBBmq8QHEgKeJwwb8XJuloVMDpJ1rxJfbJgDVMfL3gN6F/nJquzrezZmujZpFZj4ewMCONdeZfcxhL5fjta4HH7ysfNOZ7dAL3KVxrTTTD/ZiZBFgek0iGvLw4sZ5DnvZGnlnyYXIzIPZARtL/2AgjmgZTOcu0yohjgN5FoEZUm2ooloboDVxHq1T0TkZecmzZgymmTZVRS9GZ6VR0XyuN3DYkBC1rOsNPbPt5kVIxLU5OoC4LfrbWcnfTXngsz+7Ing2JQvjgW186nQavrJ5bwSSiV+sIM75uoxk/0Dn+o0PMkp6LXDjqwBvQ3yRzWLQXTP0js+Rdm4XnbnP2/auDRIyFcv9elvlWRaJJvztVw4/hTpZyYcC+clYDnWvrY6ZCDJ0NvsYpdDy6n71L9AHql1mb8nGs6YfpKCaHz+35uU0YdmJEYJQ1H1vodjKtq5URbTVOsfc3JYtFha5cDkcc4rQTyJZFX9biqQEtBy4srhaVynoz+6sjrI9mt3cFIH8NdrUZbCEjjxzYfxu0+thk162W+5m6Bq7rYKVrjQ7iQG52/Di6csPUGz3BYOyKk0KEnDYZuFjygmrKDNMYIa5+iORzjxYiPJs6MLwqiCzqIdaTPFHTwc/iVWJipI1g29lMjuDmeo1U3aN5yj93Vp3ZQ5oiwc+o+sn0C6N6ByuYZoB71efLp8nhXsHN4eoA5LW8E+Vash6QjJJjyYbEE6QUroZKJuER4BgIvUh8MycthNTW8C+woLm4yZ8ChtRInN2nli9TqvRqSXPIsnwJhK/0KtgtE44UDQ0iCdHUkZN68bFk3iqGX5FKusvHiJCC3gCpCpPkQhwuW1WIx0sMPtYxssknMcK8Z++3WnxeeRaeiKDHBt+rEBjTGzAesdth04J9MZzN7dxYZ6938y8u9wS4BobRrUlPKS7jBNdiEZaWL+Nc/RdZTGh8IEooQeOVcAOGJEgAjPDBVuzGigZoow5mUL4dcC+TEm5qGwBzLuT0plWZz1ITmWIwvw2VRxsGcWHtddHJuB0EV1SdMnjcA18oSf+8YWFynVeU1uaYOKu0KxwBBjKKhR5xcWAdLMzCtEOVqCQK7oL4rS3tfBRrilmJBTJxPDIlKa2sGGUmTd6Zlv5k/7W338m1N+i50Qg3BjxTAYvUilBmkJ9agoNuQsCUHb0tonHOzgB2euNNfn3/Vb2tIVGk3apGwMfJGsaTB9ALNHesQbOT9PYGCENourDO4pGv+SoTx5WX4SwQkT9NM46csvHfXHDerUR70KXnZzsWsPhR6NatY7JsZFbOb8s5exM+B7k5U4fH+PTmzY84bcgvQbUK3v7Rq3njEF8/nfDCyq7Y7abyj6glXqwuxLxzRvpyQUvkQbGWUrhV+Ym6fM9pzaD+fraU+GXKpW7Xece0G2szLYU9/TM0sLeNC7xzrocNSeWDZeJDw3fdXkpQCdaEiaFW0uEWB8v1AUIG3mdGX9DeaYvD5iXxZawx/McowgAwBd22N2iVfPqUJZwaEhHK1JdV0Rkvt2RA8JD0TDFtiSmgzzoSaCaSaQ+qtUitVrJEW7jDvXo7K1D+1+fqI8Lo5Ap155b9R2jx1wo/KPS28oaZvzEFPo9QPufJOqS9mtXNV72REWa5wdL2jvhZItjYO+qdiRKy0zHY+xQbyshb7IMZJ8M7YDN8SH756LW3mV3tl5OVWwXEFBsxLL0hHgCToH75Eji7qPL2LAhe8COAOwfnnohv+JqMt7368OPW3D2yYlGZ4+vzUQ+mpWcuxOCd4C+R6dgG7Lswae+3fz6ZZ20d2vhLFh9rM5lW8oxzqBnBtsiC5zF7WyDWr0YkiCrhpTifVygL/PZ99v160WoUQwK74pS9wThKH0Rpb6DPTYN3LUhr1SNV4SQdmciRpGqLf9K+cuumrKh+Z083+dK3qIjtirYhsiKpSidP10x9YjA55vDySrLaFU6j1/O91BZr+qXn/RaoES3KSodKzftAH/5RYT7zK0yw9/YunqjKmYzUJfjYU/fY11+g+f7S5Z5n5sE7Ganfl0kg5v5mxIOvH3qYD8QkXDbZgDN8tSknTAidi2m0XAbNnWBc0xOSvGjwIQOsHxTjTyS6d13kREwwGHz+kYKZq4wxo7efRKQWfrvganmgyTN1SDJ2HtRDPvPxCyV9fefXhcHfOtzwoAClpXCejnWJ9adciyWyxyZdYRwduXPb7TRXvKdEx+Ghx2E7i4Xg6lyasRdqGL8QJ3NFzpGGxynDWL35U7NqDWQ6t8fkuuHI+NGw5Aw31/D8D5zwNxz6DfAWtwab2dqCZ7zv93lGIXS6okuC64XAzT8gaLX4ZduVKWIl3XuSvtPIFpkyL9a4dXQ2UUiJv5qrakUKwwiUQZcmb2vUOh7EQMHP9NvV6tO1CsU+tBobBf68H375g7d2TXyO4LdmoxIt30vzEiqWWgzCbkFI3IHTC5PPkWh7VuObLXZyDvYrDe0OqDyCYSBj/hMcwHx3bCLJj/GLyliHnii1xFt/IuokjetJ9ZVyErIiqeWULSMQxXIIWZCRzUOrFlVDU4ngX8y4yTUfc2wpXIZ6Kke3k+yTBqoMGeFipfN82ylQ+1o3+gCAexSWXfYWY90uwaTt3yaVKZjPn43Vsp9P0Drh2uvYNhEUEMfRykA3xjWHHxch9wdsG04QfNskqO9X1zASkop/zPBNdgR2pj45pQWjln9du6uj18rZKPmc6ezsWwSmwP1TFZrZ9HqbnYfV7OKoXWj5BhAnyDwblG5c5u3TRhI+J1IJ6C6WcBH6UNbvKHIsAGSYppdrONT39drqek8XcKegYwTXCr9GgyQUanYs183AV2/tMfi3NpJ2ga/CeJqX7kk2WD29sY0Z+CkafXv0pb+aFDR6lQlsRly3LOwnaiOzf75NoCaGmm9ittPiDO1SMO4BEraTW7alwxgfDXnL8eSoxst08yBaGunOfoMYJusvpd2bZBO4zyWju4r7UTcAKYnGYxPAR/odfeefXomKnCPZmGR7kBSys2wjR9nhb3W/+Ouswy/iAMsROecqJUtg9D3idCrkba8QsvLy1cz0zhMmJB2mYPVJ4CcC1aoQwbzjBVoUbBsaH976YoJZ+bs3r4vRyELw/pZOE1hfB7mP9khmgl3zgUWNUKk0OhKsfvkVcdjBkS5e9sD/QZ1xpAw8YTV4FnPDDoVHl/yQV4HEzs7mtoA4XAEBVv43o+h7ZLCydyHhEKVgI729xZANWsHp5VqA//UWW9SOClq8JjmfnYhl+JPmr4OZK42bWLxPGlANLTq2bwWeH9ISfG+s+btpSl4fMVJsa5ykDwOyM9eL76E+i9onQwR1MK9QpgV3afCRcO/Rgjj91pcNoLa1+7AzkVpokSG9/3gdh21ioVF+QhQFM+7j6zrHOg1Kdfi7F0IaWa357mkzpL1hVyUwgy3rIn5dFV/zGc8bC94KmvRx7WmDvElv+16joS03MImwmUuSMcKZg98tb3n+5oA4Y3LIY0XfHAmWfaH6ivYau7Y24/doUyBd01GGxPt8Utnw+I4EsmA9B3+SmAIfxdf3dIXoXfi8Teq9c0VU8p1EaZ2Spid/mFWjMUbjgWh91PLCcs+tTnGnjZFZG/hpseD/6Ssf0yr1M2oVfMpXFdsDtTt+fpZbXOr0U2Sydj68IvbYAe3Glm4BauP71gJnrEWx+/L6DBNtsEqxlNry9EUgfo49pRvmCeSG7bqKSscUMWEJYXm0r21Ani2svBT9EyBMrgDFjBTJG3m/w/SB9DytGe6EPdKPGlbTW72dyABYnS+X4M0ZPe560ndZqel3or6fz3M5+nbbmSR2pkoZHM5LrMz66mzCNWY6R2XUl/lDkOQu1RFYYWOpmzaCLWrIpQoEtLBSd43T2eN+4YJ6sWS92teF0mnr0CEo9X6jc5eZjDlMz2qmU9NHOtHGH9APqBq/cOd3HcfWIJ67SKv8IfXKnoES5NMJZRTCC4CAFBfElflMaheSmD6xc8hNB8BwI87TwXVqtZyKTn9rQEqsWCJb/cHOrxXBuEp4fZwlhAs2h01pkvZO4z/zpfjr8c3vuRCQzmAiQmDx1DIUJhrmbqy0Yz97kn3uJpBS3Ol+he+sbhnQmHsQD0AH8UEDeIW6JU2A6ceopM5PXZHMiAp5ukCJq/juBOc4hjoVhR7t4odCLuvSWM2sxbFbSXbNHyOgriw3k0K+xQkPwEWKPd82WKIpFRhJESegTdpb5WwLkg/2NvPSbLwNC+3qt2mIDkXI3r0oPHVdoFXChpQucDXDIQ4I9dTcCT762VdFA7vluT+OHme6b03+BofnamMM1JZ9APIASeB0jlnJoVzEMf0ulC89C/b6ak5nNAA83dj92Mvzzw2X44CzEfvQKY8GeJIlIBDjLT2LPwpGIIFV2QxVyPpEO6iPQ4+enb/ACwoy9Fob+WTChsjVA0LMLrANmBQPTuYKNTukhR84e2isZNfR1wlBVu11t/RKMTqZ52y9eg5arRzuPEPXQuu03wUwEZpyHf3GCARvnAac+9S/Lqcqy3Z+ypoi2PBTo7NLHjXAInt4myvYPna3htHSOOGMzfBVY+V6BtMshAVOdB7oniWU/tht05YV/pXk82bMKUxoY+6rcYR9DtOuW1soYFGlJooPtGn6enbvtenWR4unbV6fuImNOUq5ApU/7N97R+fwypLCtGcjgfBkp0SSQ78mTWOXKHA3lyzMpY9j5K7GeEn0RYWdZoNAqZ82UsQgu7TkpOok/hKcazf78OrJiSMOkVlH81JbqQovHVTnhA7IfT7dwKjnmTLucEYb5bYkIJd21x+tIkK1q14h/mYk0Do2ls6kopzhnLkn7sJ9v6Jbrtx98yAEbcqxGnkN4ZCYzh9a7nojQZ8ydJ2rpocAS220KrNB1pXzzL4L9ja/ZQYZ38Hs+m4FYgc+TD5gTlKRWN/odXt9ZMocxrNZeQjGqGDoStrK0QYXdsS9BlteE+G1QjaYjqF/yYxvA3K3hGBEtG54IEzzgNcPNLCUc0dY2XOMtp6htXpNImKb2k5KOs2myZOBvTd2O3gs5L6cT7udXuJL3tl9okP4uP2lBoRmfD+kkWJAR0OlmfuDj30iAx19YufiRMsJcwcPJ5JqMwHYhzmkYtEhNSg9eerLYfFUEMDOaLzoXFWjVRxTvGjemJOYIZtSFud49WbYeWNzs36FqYJOA97ZP4UR8B036IWOabX8Dnh2kmxuKjvXNdp34dMKvNANBxDoHICJ5D5YcpJmQX87uGGk+E7cvMDEC735Zox1cgCCaNp/nOFdOumZqfS4Fh44Pp0w2K34XXncjpBiaEeWNBQCpfb+485us8YV5jDruPwnmSAcfjTzWJaA0XmycktvN5iZ0pxj4SftxCgwPdty+chufyJBKG6PeE/PV1US0899xZomTlB5+S9l5lqktblSR6pLPTWpQu1IpYCESYRGN+FNSXveO1Kr7czvTrwtT8H6SEXCjHMMYmRvPuHyo/AT+t42mGMdIEphLKwrHsrqepRSZOVALIT3GDErvN9/EPqJGcYYxs4nodyKRC25e8+idNbc8USyrkqCnEuk9bgWtinaahzXfp+HbnW0dFgRv27lsKWaxPBp3yFoGbbckfD3iUzO2HjBq6m03s2Ynml9PT8zXwhECN3wo6vL7JCM/PWfiuK6fCElJKNAa3YGxbuAl5UWR3OExLbdrHmll4fYCLLtMrWVI0L1OJy5nEo72LQju4DqRkJ9TyZSeOospIFAd4QDK2xr7nU5pUB7V5EscsgXWN9GdUwAfzA3JIK9Kp+RvED1E6A1zi7jCEaiQzJGnVJY3hsh+5xPHf361RvGtI7Jgwonfytd1sRN/588RBCK/3/gOwKa35N3MIVkRfBjrp9l4kf+krnC8ItMtOKjc+ZEtprhOxrnOG1nVngC3tuM2+3sh8da/xR/GueNoW+LxzhxIQU/S0dAE95O/CHbc5ebgS2OTtsVzjRHb14/FTZXWeXoxiZDiJEz9PZuV9Ro2Z5fXffpJ4v0eL20MWep0Vqi3y/kjxM2+MviXbaVZu7wSId+7ZUXM27XE/GMv+xxuNjYYbXd15gOrO2JgjNL4PkrWYjpVI6R6KX/NAyRwYFrpxvF/46QlVrUkxwbghvbiD9fPW5Z7ip+/7wjXu9VLrzcAniEQPyVQRcVboo/+/cYkiYTmh9V51aasx6JTKz2w1M2A81ZuBKvEewLU2+tBN33+AwQdBf0G9sxeuA+kL15Q+qXPNJrAbyObT5FLOqc3ew7wrSFfBpsE41o4HZpfM+v4+6wxS/JEfB3ipLcU2BTdwwVstWxja0H38rdSvBcZbss+oWmdBQfPoWjTvGaaCbaMtDpKzJN9EbP+sDt8xhylHuuK16MbXH4WvAgnBN465raDwr0QpVZUN9jFxt8/0dy+/81m+bybJRmPMGioobuoeLTxYvWXfMOpasWTIbtS2vRju1bZIMSM2kReFYREjlBR20Wm7DtJaDJSvAGZrRFPUAa1JuIiekyx456KGBSrjRPCldWC8dfU7EqTVUlGH6pAR9NkWD2GpTzHPjpe/wkF07MKqMG8ULIVqCZOtrp5RhgLPQxG47P1ZdM9TSaU0pPh/qgHcuJ5jNf0CsE9SWlM+towg8rXidl+o03bV4pa8YM2oH2dj5P+JEc02QpvjanfPPTt0ST8hx7Sy9Ls2Wkni7ciprA/cdc949d4fawhvCIGA2QiYphJH9R2fMJmLOQjsDzjydR0vduPo/3EF/I14FW2gaOqY2qnz6feqEc28S8QDJ9iwqJ2KAORZ2+82+moVPJpD6xKSAWe2Ho9G0ftSVm50PO0D48Shb8N5iQ3XskyMcWrbPaACvCTLHIxMOYrxrEw4dBlk7sjBkq00WpFAZObxr0DKe5caILSLLVOPsX696lMx4P4FQRc4LyUO0AwU9G8FuNkA4K+KdvfZEGJbQeUWp4DtXmDxRjp9s5xYHzGbKXT8bG1IyHj4M2jjyAqTJEJnhb2Fsyb7IBK9sbEWYxntvAI1Lg3HTXH8yQ5FJ+KMQu59wb6cut15DvzrJQFJYKieGe/KVzb9aDY9sm6LBJsT03WjfHUboqMxNiE58tXAj8n0+R0HIh0AVN/O2wbkoxB7sgEs+K967nWMAzmO9OO8PlwyCe4mBJHWsQDNhNiz66K0Bx9Yqar6iHDlLk6vmxsPPZCRtc2Wl4ZeqzY5ALGuuYJaNSTNZZwiqnVb7dJp4YUbMBOU4qiFUUK99eHCIwOIXm0IWNgMlau9SJh5+UFM9slbFyI3i1CtiGEqBt5KEHsweBJvkQ3p12whJF0gZfw+NZD3ibF0vIstsjBT2zjiSquvI/nypN0cBtx5w3s25KvfDJompgnCF3pZMp1OxQ3zvHvTQQUQ8XR8J2QTeBKilXFmiyKQuBy9n2ETMrnXOP1lA2mfBzaPcNOqnarzWN2Y9cGW/IWPf8qOzfnC4R3npjFgIP+NkDkWoVEn/li8uXhAk72jZP80tsXXtCZz25NNBA7Smc33cfJrZnFnZ9EEYSPCt6hx7ZEnpKgR800FPLR6tc0c/OfKkiMRRZSYs616VplJ8kneSpk6T0aPMIgLklbGBbDhlcZBAOFoFJaLfeAI1DCk1H8g3yK88I1eM8C4o1L8jyEYb79E5eoywWbQdnyR1UKtwPP1BXLpxuyQ+6VqvkkNYoVEToBpza55tNZdz/qp9j8KEz0qFWBt4zNmx96UETXYy8KtH0hxfSixeUxJDzD2famfQ8XBEuauGxS0QtKo35WFL7FpkVnvGCad5704yUeFl3uSp/KxDfgiTwthel3AyznAZ932jkL5cc9mEJhTTcXgrcIHv9P1HUtO8r02lcih8smG5Mz3JENmJwMT3/oPd9fZ6Ym1Mz2Nu5WS2stqaU6cGCiVcqiEn4lXRhLiHD6pyEzSGVktWgoPEkBnVNMjaiG9SHGqcsTFKd3i97/Jd84qAzj18j+DZ5MZupq6ZDWCA0WvIa1YL4KDbOqQAZb1oY2D8Vgzx3pnm5Hi4+YgmEWlADF99aRnb5GoWM+Lucy09FmZP6OPzaQjs/1OkWYQLrO+3eyKDbZSiqNlQ53TuDUnwiwzzDNuXQaOne+6w7dXeUvQfDXRq6eeY4i3YCbE2EzbN4kWXdPzcvwNsD9XSZmzFPvXz/oBVj4qWZcbQMwAdb0Kp4bgQBX5HGqQ92t79eB+UqVSikOiHXDzoPvD7fHDBWJfs4Di79AcZmHt2/XqNUbAxluC6fkcdCtHNHqHMOBR62Ugn2J4fAOENDuMtpUvJxUiadXuT9wmpqf2Ee+VfwHvD8+9XpghzVISkFPBhalc9iqNrboBpZTOlx8hQICYJ2C6l1bPX8rxWR8YdZHUFmnILxoe1l+UEHMSYbOXybM5j3oM2Ok0EnCJrAuJ/0gYbYGF552ahwxBpDPlL2tz8QgQOZI6bfnrsGYr/Svg/jC3Jax60Wc5qCUVXzzN5cR6WS218c8vOFli4S7Pb4EQcBtHrff+rRq86HwqQu10Hb+cjQqljLiO6RvUYocSRbkJn5r/TefByW9vXvyujd2u0OLoTlszSzlVOkV+GeXcWXmtCPqHHC6gX4BaFe2RyTS2cWKe7QO+TzWF5ckwet+D117NfHc2t8XlHGuS6Ei/l7B/Vc4cTZWpmFV+ECjfXnfclVGM1ouF4myL/4g/2oRnl/KNZQdthhDRNqWT/zgbIcm0kQPiZ06es/IpIQIlZucCCqR8HK2HtTWSV6CL07Hx6aDUy1s25JgYfEpfHnkkDehyxQ3w2YBevQjeI6pYm77ANKJb1NlRz3kQ3n83jZ2IvwydyqjMBFnuNnwxCbRZyowBoUWfBjnTX1pxcU/2xDf9Z+lyW8PTEshwlQU+fIPT0wbvRed49Wji2gh/vQABfm2zZ/Vel7dB4Atv7zZoKcLpEsvcntHu+T3V9njFUcnssPqZVSzZAhUMXe8Lhb6oewQYO5+miNtb4aCklVt4vwcG7FfJYMuFKS3bvenOpAb5+RRveTczSAVw59//YSqYxe/shsxqUAU9I49PF5a531p2HBFAXP7nd4BdQfGsNI/xG2w0VqTpH0OThyjq52j5lk38bQG9n46p/b4HViVMFPbQg2v/lSaeUyN0G1k3zyBNzs6+uNbfT7eUsqGMW5Kf77LN3NemmZuOGvGEpZIbSX9Y4kY0o7u8xicGfrPMf7M4Zcsl2WBWzZZx7HCKDNmfcyUlj3bOP1AZPLT8S/OVVZMkQN+WZj5ryENs3SjZgWffI8MXsSfHYfQBE2lTFqi99qyX48PrUhlqA/M1I0C1WunVgunTOKBRvT02phsjT0AAkLtbeWM7Yn5GHqLpy3esLMx8pDqm7b1waSD78YYVMlg0d0ghVXeX5w0VzJSZfbCIn0cIMPZzt1TXj/Pd8qQZ3mfvpzl0geF5Erm5U+npGC3lSnitl0LhdWhH605LDm4F+3Ew7awePayxdZZsCZ4UxWPJHDe4+o0nOMy3W/60OxyryuRj/brq19J6Y5m8aJcySehBWu4niC/W9c2jLbpCXLHhyjUE1uwOQY08FK9SKAOlTc8KwMtL9IbuQdGp04FblDWkmSFRZoK5K8wOIv1GaPIY7VAt3EA709wb/b9eQ3Ilm62+HrVXVvEBNit0ODAHbfh6gocKKWzMa8M8UYu5pduf3OfdnJqPo7GvDgDDJhyms2l/R6So0ZYR2X9LviYY41Xw9AN/7HnyvOoaTvEkSNJePNBosmA4FUgFcFURYmyORWCKPW3YN5NifzXJAzGngmlt5ukZgzH58l0IYJjrlFh0ZJgRWoUyj37uq/N7PWv6fBC+mo7qgd/s2/nND+MBx8ECJhG6fVLUZE/Bbz+ephvv/81NPo2GBRz66EJ+zBgt7+W45S5fWmfwr9V7wGFBzYUTbAsCKoPecDZ2dyHt0TTh2lL+4aquseeh6hVH8YPrc8xfCsQAxyYUVeVTsG22tH5dP5rCL5C1vhfF0ziGwgt/MbZbUwZQ74+WedaR9zdAG4+7CcDQtCfMLb2gL8nOuvD8W/yHJrebAZA8jHpUs1kSgkVXFeklKgxDORCwUwyiBlVe2trPzuPx51JFF5FNFKrzXEDrYwV/5nVE7h96GCASSkBdPZbheRuiGur+OkalmBvlz8tUB6TOPQ6WMH0b9DSPOWEDh5ktGyVh3pbyEUt98p8cVEm8UdsoQUcAoacFvlr7rF4N0066vsMOGAp5zJyuUALDzpsDffFiRdpcY68ibZs5PNbVdoQTAypo3+jGaosQ5NB1dnoJzIlUoA44F4X+R36Mdrbb+jsjE/qfxxzHmASLke1pl8ubeyKs2j/RlxITJva07JqJ9fhwGuvRvHe8LatNnrOLqEw49rXrHq88T2ZFtdbBjcq9gd2MuzHWOD9UiiFfsg3IAq8bt83pysBEvm7VzWL9x0yBS4jdcaEkGgoglM1w52qw2F+p6XbVJKrxTv4newLMAADpgwrD10iWvx8g9NWQ4u4oyekmFAZnv5qz9g7i1fxQc+Y9iBU/hxioF4BNQVg/0Vb0dw788DRv7kqCOQIz0fdOqs2ComwnbpOWZDiX3JKlmDf1sEjSV/4EUwDBnFyA/V7veZTC4abpGfpITDmFrIwDBVhyQJhjAl7BPB7j/FjxZL3wHXp1IVTAozHOHH5bmyhLmx5yA1rG0/c/yX5X32v9tVODwzY6NLjAdMaB06PZVWoz/PvTfW2YfYZCiBXY8nBwgzzUVoqag3tL/mrV6PrTiAq8X7RxYh+VjWNEz9uvFCfx3E+Zy/vjffuXijUZ4537y0tKp9mXfGRVmouygVKs52cHh0fCLzXUzEYhquNe8rErGvfXEUJKnSFd6ym3cPeD21sCzEbdt+GNbtH1V9TYd0jeFjiSKFV2lwPVXCjbceGLWgY3bOYB00ph305515hLdJ3alPJ4Wc+vC6kPK96TXQaZtsRIt5yR98YGKdod9qbTLW8iJPqTXOy8M6Hwb+rBLJUC6ol2JkBSOiKgZMT7+X3FxyaxB8pjWHTrvCtYLzb7B3CGLCEqAfEbFu1OEUg0fAmeMpgXzHuMtGNLmcOet1/bQnJgONoI20oGqfZfYT+reNQ4miWNc8wzBBbkHsttnuAlHawCrOK4kuI+1kReAIrv0+f7bS+yx4CvMny478FxX0FvGocf614NZV9CRWaFQ9yxwn4NFn/7IA81c0pEd9VJmLJ/ms6u6nvY3kVZjQjfXu1kiNH+DyYg8csUu7taeehjq32ZQIlMu7LREDecO8E5xt1r6iNtfeYosM58r/ByXTpwaebDbJYPU2E47NUJpjHF37VbmKGMj6GiNF7ciro1tDnCxFZEjURFJYrfJ+IYKTbphYoxtzwife+14q/a8s2z3Qem+Htq8DlLLdP8fQ/2ngx+1oK6uifxjk3HJ42Kl1Q9cffsTDDwz4OekgSJXCRS/zgj2X2l+drUcu4sxx4ejgmSpfl0o8MaG/ZoBaL51FsNTuLxOm0+ho/VJxIP0xWKoSzI/c4mofdrd5sBUs/g8v7kGG4LUlIXDpxq7KwV9WBBRSrre0PGs7goBHg8exf1Cx9Udb5Gl6xdRyK4J1qNkumPwIxcq+lg9UynMTh+PfafEBof6Kuy6Ycfi6P7wIv/HvLMefYF0BHsmyWTQUfa+qOK2uRv4loz3uwFI3aeVV9OA1ZE/yNXksgQq865fAOJ1fLU6gaS7fOBXwDH2sLHacwJHC4zbQ0CVcc1ms+bZu5yV+itbaXCbk+m88J7N8Ftyz54oZWfrcl3XeZ2HFyo40M809IvPgtZqutlLB7u5h7Ey+tcmpAP8d3u36OPrrmAgvqoyjJKiFeuRm9a7M7QOLcfzXP3whbNyqeGbTCMN/6vE+pEaa4O18L6ULnt2AjZOldnHbpVom1Wooag4OxyLoiSb6HzWjJBkouAJXA3ILOYYPzOl98/j6zMe8qAehRXx9d5hAuvmxZX1lgokNMB178kqNcO5f79z0FvbePKMOvJcvYiIvuKnji9JlKZafYYwVxTOduto0BeUdRSEuPZGQqN4US9o92TPumVQe10jfygCAZY6lkfvnyq9xhmkwje2zHdFWXkEuDwEV+fmKn/VeXjOOI751xKQkrnsGaRo4QFFXDGnCmgPj5DzrLHPAQ0spsbaJcGvNXLv86JEo9iqrCIdF/0wX596l0P0rPw6SSHPTd03yjZb6hJt8gr87oky/9zmfnAT5Sx2fH+gIdUEREM4ePHx3loNbMrg8p/amWbaJ5Wtsm9t6Mja8rnO6dHo//Zhp0cXYSiLy9PFK8hfRNYf3zgv/uReQXdHexG6UhTMiY9vt8z0vazCL919LxR1cj7W7fEEMZs5YkqxETPlF4fo0F+2QQUeHXjyzDuzKRRmsrRGlav63Cye8amt8+gkHV7+Ht8TRkkiC4ey4lp241IZOcSmpnCXf7BMN8H56q38UZ1iBwY+H31+HgC6WWN1o++Lzco3QNC7W2OZbutAA71OUrsv4Hcia9dmoYihc03NKoEmbGsQI/7VqhbuOi3sUwZLT7+IQGkrBRmHf30vpQpG+5iIrhQRtcDCRNkZvNf9kZHmo9XPPJed80inkbIiGE1Tlf1FYFOXNPzj75xDg98+UIxMDSWn+j/x1yeitcm7yW9vPXk6N+LKNukYN6vdD0h6Hdts9qdSxwqSHj3/n+dQM+UbfpQPqwLNp8gvTa/XEGJqNqYWCVXdIuTnyCvduZa2HdP54FtNMRQBalCv8yxR6RnbvUKHdNseExsmoxkPuvRHoEvZYR04SxGw/Wv3CIYbm5jz6EFXzS7Cp8cnmvXidQdYsgxu161zUwhavN/0219lEyu8QkWEEpBov3Lkvr8/qLvnW3vXwgIZvHfaao1x7ukUYZYDRxa/vRi/UXIZy/Pe8ivrBdXQYSpuAUFeZcoRU7/nFers+kOkmmJY83AKOdt/2emwKl51HncdNSWrQcvIUoOxRX2g8WNJ22ADYgDxn3kpFzNPuSYz0Q0IXdIYKW3sMRqYHDdzHfpUV0IJTYrfZpgr+eHfNzBJbhGxRF7d9/ycTyEpat1X4qYD7O87bPZ0Q3hy91yboo1YotGLW/HFv+FaFRIwxb26iSGdZsyvxFPtl3BokFqld2+R1Dv1P0wTRmxSDvD9sjf5QsgPyN1xns3UmU64aZxXZJUwGb062dOm7NUJFM6oYSTQxKwshVxxTg+UWIt1v/LaResStzXy5lAyTPSWKRhYuL4GoJGv/LLjLE/VxfFHJF5NafBvugjA7uNc7Z1oZhbLwpdJwuccXGyxee2JfDDxfCFNE+T5ysTH71shhEyHNH3v84Y42R08DkrEtKuqArdM1JxftAZ16tOVkqRKt+faPvONBJSkVg59282HiUOr7TE4qv1KK7hhuK5G7iyTnAK+MA9hPjh2DehWqeDQE6hM2CNjUMcTgfh/w8E5F74kC3neshtSbT4Isv5TGEf2JW0x6nDXDWxCC902iUN0LB9D4GMlnfs9fDQAF6wh2HJclFmelUOaMoSnviszphb9dVOslQ5ZLw1YtDIMXk35wQ6RpZ825ScOnIbsFZBNIbp8ouWWwY8yIL/7Ww9nc9jvtyKdxEZIJIy8V2HN3c9dQ1yNDJ/D3N41H+Y+FfFn0oqwwa+r/+8D+crZTE8u/Vy+gNR/1o4b4FZ9OOD3o0JTB6/5r3VP+Q7lbZOpdoNqZiSfprAk+13gHVQnOagdDexTDp2P5evELno9+wl0KmrU/EJ2czvhZmewW6WzxOp/j2wq1S17jU65I+lFS/WDQIe9lx8RCFy1ByJPR9ubaiJ+9bGdXKKVKMPfo9CtSEcGTsvin5g4XWt8czQpFOEXnKu+OoEgTgP+QzcvbEZXTxnLYRRX/4+RW0NZLfZiuTWYUcM4G5E3Ew5pZetEjbtllowOPJXvpscblRnhMDi74OyXYz4IEaM2f+yguSTbeix5nDj/sM+VaUSdJGNXT9qfmuDgQdy338oNGkqryhfU52GMdyp2ll+/NtRcCU6lPUEecf9Kv5Rrz540fVECbT6+5RZh7cR+rtB8gPVerPQURXHjri7wAIYfIN25tby6U8ACyhxEV5B4gtVcdwkfuA0950BrfwIrCPWM+4plPYY0tcc5JUb0jaTxGJ4BgSDLrW1fi3/VYVpFRhNlN/0TPER77gBQ6cMsD5oth5odIwH0I/VcmVPQg4KBsHdF01ifCwIbHF0sfmmbz7wrDgLKdTPUAWT//opyznWdEmOkpZRN8rCVuyuK0NuIgt4+UlEM7hD6RVZLGxU7ELZL2/IyIFIh16Fjks40sDYiydwfG7HwQzJ7X6efa16r/TMSwMoVDoLtgR0kQfdbCFqg1/CIH6WLfIf3dmYE6mf8FPmzfLoR+XC4GEa+pnT/hIkX4isZudCliNrO4wucTq0Ef/Li+PMZQCxg9zi1K4m9xafyKYWSLv6v7cv4hSGK1B5YOHDQHmzetDSrrv23lWunavNRB8SJYR3kUAic0WJ+uj/NfKcFH9tQWlMfDRB45q5Ph/WKfKMl+0urZtp7oM8f9acT//pza4hnAt5JWu8LYADlDOUiv/ovC2Ki0pYnf4mXALhfP4KCca6sbox3pKdYFcRfDSl8BGj/GXBCSKu4daCoj6++udNXNqh7x+fjkuMJfNncNAoddNLnZRT9zUGXc5vnp60NZ3lvdH9dY1jceraImI4gOUT3v1dHme3BkM0XO2L6xNQ8w6BDbYCku1JTxNrG2C31sSbeE+JVs5i/wL4Axp7nsXCqf6uUwYo9ldVWHo5vMaYZHpXm0EzbGF2vnTytPm2Ozud5oe1Z+wQJIHrpUfVhr8KWCXIt5vBkGobAV//fzfKBJJL+I51wNffSJJtOZqe0E9Z/nskRcAi/9veR0HWKB9uNe3pQk0ag+EfR2R+KC0N6RdBWgdi9BEimjDTWuhu2SXYb7V55wmWWzlytIMLlrzuuTWo+lJKsV9ad/5pXJQnwf1baM/CJXlBSfg/03XfBm2pcAdY/LyevdkXyI0jL4c06Ha8dZu58N9Sae2EcQd1QbBmi+rwYoMBT5085cLkVP05eWjb9E2gfzee0cGbuD8glrLuOWL7u/xKD85kK9PvTaEzEgoR/zd9YWy//y314o5iWLI3r9YVeF2GHb/7Efx6iDEpLsqhyf9LnRtbz0zmAp0yorT1tnEmBQtyODO7BGbGVXqwqIo1kyCD3TKeJUelG9QlpDz2fZT0gbkDbLHVsvC962N/CJhkzEpCWxbd0YNdgHDwKBx6i1b1/ISRmOo8+AIo+xzpF80BaD/0i9gtsUBZGwHIQeuQ3QrVULyBxe3gqxyv0/zvGVcSJ0cTascvypcJ1FleL17Xmw+rIj5uK3U2RkB5ezBgl5k2GJEdbGgGn46VReleXI1cO71lN7IkLx1zFfk0sZasOQPUgR0iZEu9HAdVSAiTWbnmiUVT9QCHtbYw8g91cGZtM6/DSqcnBr2sdj+DdkBC+K9yiuiYZg87Pf/Y3g0feAjZSpR39sPk5o56xptL+/IkhOx/8b0vA9lhpYDMQbL+iR0GcySD8J5KqDmTy/3W6ChXrjzcbSbzU3XuPAJGA4qo+PbVZVf3/Vts3pjmTCFqdvEVwRG5ZBFqMp/M4G0o/iisCLIlPu1tDL1r5vPJ8LvN97HpuynGLMy8B99D1cdQ/45XwjJMWUurOphk+hp8pIa8qonKJiYNnYtKdOvWIx+YpQiUck44Ij/BvQeXA7UYTg1oYaez7+wwwKsfcfjeeZK10HpM3D1LtBf1F13+vseeCDL2UeFtaAuuDPSXJHF8HnP4cRvArXVB+VnaPoAwF4AqH5o6Hv8fKuU2QNOoMhtrqZYqwl1hdUP9Wnn0ZB6kUBwNb/mD9JG/e2bDl3qb1Rqc5+CPsiI/ZYD3tbBziAEfKTqPG3rh8ZLoVmGa/Lji5RwDCqMukkYIdULQiGy7pItpb4faDCIOKe1n8elQwj3J8c0URVtvXIJwv4hDscn01wlRWmRp3biD8qVsOZMFW9iZmv5Lje1ast9tx352A76AHJeNtIHhb69uqhCK0BEcUi5IPet5Xqz5cEernywoT0+3pNP6STyWYa/KfX3+GJnqLwz+OSapJqpX2x/lwaq0oiwDzrkpFFe1zFhdKbSA/k1qZ86s5Si3n8Dbk281+12C1g6nL0MigyayGFWtCNjmjrZmvCi3CpozreDPPK1i7kmVz928LmD7vybKLHp1kf2t5jBr6IWKWYDzx+vv6YXqdUowbsXosfXw+xctVOy+yNPDJjbXfODFBnJIS2NxuxSb1Hs6urlXzWPejs39vwAOI++pBM9I6/YNOpdP2DhHe7Uw+nM3M6N3DZA9eftD37oH9g0EQ+AHZRevcaX8f3a0+iJmGnXhpp171uyknD1+dyTZ8xIoS6yhv7BZQltw2yu8nn1yv4dHutKY/4jgw44MCjov1Rk/hq+nQhgkbRnuscU4BE51Ok1pX8fjcQPsiK93P0MHi8VOfc6ro5DmSr+sR+z/AL3Yeo4m/ZNwVJsIKLm8ZEm0y+IuC09HrMoYUPT+3JyDUWX+u3+5sBWzabc3q6edAP9jbe8qjC0SoRZEc/SgJBBIiH1ij9EheypZJRaisJtxclf9Hq4x1pQRZ0SCMMrIcomwbY/vO6hY7hbFpNxtL+HCxv0/N50vdn3i3tCDsTmrAc8AX2ze1L0TQt1poX5nUkdJwahM+nfFRL3l52gbJKAZxTLoCUoGN9oiE0Ie0Z/6TCgtqZ6mBewfnX0pbUB2qXujm9Gq4pGF4YfD6q1kY2+qdrrYWf3O6k75Dm+4BAkoDuBkumv0XQ62YQqpTVKsfhJ3YFomkVaz2AyKTaeQn/IisjUBmIfxVibiCCuTsYI+oDjXid/4/tg0cV8Yhj//ZZ/YboJ0PNQiRFcDydJQqQxRy7ygDICHassemh1AT/+cnp94b4bDU3LjIswnCCnV8kZs0rRb5vd+dBpvs8ylsvMhdjfOC5yKTFiIkcXo1AVZqnMxy6I3ZDtIzU6jLGisVmRNClWfUXA3uQGsIk0VujiGq5cgqVqHka+hsBnjucdWO7na+B9Yg/K/qJ1Xv8SLr+/K4ZF+ze8PmZf3PYgPHwLOxTIS+nzuh90AFe6eeLv/nCbL94ogyCU2zqWhbrrdPu1omOdI+4PK/deY8JKlKyENTn4uKzl1JlESi/YFhMIWfwGV2fODA/IzM1+4TGt335dclikLNRCjqG0/PbcpqKk+YvS098MCyWUtLKS04cmWmMt+Od416LxtW2rBW9gxnT7Prmsqep9wVZi3Jfth0onn4WjLcRUvvLxC4iYFLL6ys7E3oRAPh/s6yNzLVOgBEU3CUmdpC5Nvcy/ojftNKyf4n0xREe1TyoXkTQd3CnsaPYngHpTmaeM+XexkS7wEuiuoC+inP+cdQHeDdbfGuPf83dqvBi8Ymgm5UejlZ8EnsCjeIKGaLTP3X/V/NV327L3uGT4LOrzR1ikzr2xtzB8AugMyrrb6gm1vYEvjf7xHepif/+XIJdu8vH9fw9i5Q8Zi2HeOPxLCYa6ffkckAyC/L3E3wNk7egncRr7HUISC4kckuHiP6DXH2j272/Y525SZgzGK1rqWd1Cc/yd6AVz0AndcwJwTniVANZKvSUgi6Vk7f53D5C/igJiUvouy6jZtjWq2I2ixs4KSGmjtuRX/3w1igWXwzMiJkOC0wlsRL/9AwgtMduUxusTtzuve/Bl9RIiKtB6aFfLq++MyUp9R8zHj4Z/aUyW585/hWjq/vUt/4gpuf/qwSZagIWOfZ/+afTIqzSD7f1+vMz+1wlJy9SNUM8X8cP422NhhfS3mCa4aN1D4oacfpw01D1+i/9ZtDJJblnZEb7SB21IRATGZpToDB1PluYlej/dX3qEXhBmbGfaI17vyhiEHA+Pt/jVE/6oer5yQjwHq0HBeOhOF7pGaKdZFppsx3B+2EOLxdhQgSEXJbYbaNTPIlb0E7XRLHapz+kipM7p7Voccr5Icxtkp2bvolklv3SYQsqhx+Obs+Udb2gMutjCNyx74jV+WsErtxR7ZMlRhoSV9vWUZH1AagzLjRVVd85bolE0kH0OdUXyDdOmT2z5/aU+LuGnryUIJH7Pde6xmXPAGcStSC5U1Z44bkoDpIpWGhK1wff0dJS8J1GPpxWrafL1sE5H98jq5yg5LZQ7r9HoNeLtfSdDYLvsc8rRUAnVVN7ecxe9k8++TdUTlvWTMDARIl/0VPXBQ3SIi/5BQlhsJrFh5X5RDkDRwKf+aK+HpkmTFV99VqRNCikRy2pcmZZrxtwv4//1FWfKh51NbjB9TqZEajtnbJ9JN8vs3g7c2GjKoGXP4GtKkd69IQlcR7z/dx1bkt0iQ2+EUd3Q73cCBc4Igu3r65a6NMRNfVg3H9I0LHnhvYiF586GChldK9OZPscdhnw/k3zsE3PpC0XhEUolE/Hn5yMVSVXG3SjYoJbz29mAL0wtoL0qLGfdMZ19iruQWpM8M+MgeMi+x7p1/Wd6/9Q6suogzSaJGVgcCuprUiHrpv3WvaeZwBoCR5LrJ2TdMs7cxXM2KJntF9voLrY9vU8vw6hMozbLLM+ygQ08SI/9CwFi2LEAw83pSyrFCFpWsA4FEc7X6ZSCqlF6v11FGurQUdNZCI+idnKm/mAhILIRC+2ohiDMT7pdUIjsYfS6jgDepFAiGtzGVFlWaSdSux5MAhvd7UMLXyTNgp7gB5Ya60EoB/IAqimM2dAhiBJp3yv4U8etlNx27ieL7DY77uf1LGGLqy/s5U17dMRC28+pnZyROekRa1d1c8FqUduEwZRKy2grlQ9/odL+SysfXYI1Jv5OQMeFUBWcsD7NfgjSh5rYfWKW8Df6cyLlbLAs4/+MQkJeUSU1oJWAqtmNJdnV2eXLwEDJhNX2h7GK+QOJqhzmFCWr8AWGDY9o/jPjCvI0SBOPe7CYgvyVL/9wlHOKD7a13dxW3cVD24JQraTT4yMCPNAYL0yj7Ldm41/dik7KE3Rj3WJyU2jXtIJwJjfbsdMP6iJQPbMJ+UNW1YXWBG6pQWYo6jGrXdwIx+bWM8wjpinrh5RbL3Xg5afxMJGVw/82M2V3UsmPRGoPrq9fiV7y2p2GXy4y5146U1azBfFjRvUP3iL5rQmMRPfGTnQUZ2PgGJpdoYYD3ySjAPPODvrkVr+4tr8v37DIWM2TZ4N3NX5F0kXkn/K3dM7unryc/TjTqVUmpokvUGsOTwwPZ+cgeQgJold3eernQPFVnwyuPw/03Fh1T2qxMGIiN/K/BvsS+yEETTkkn3KevOZNT6SvoHhEoTicziO1TCi/mdVF1hkY58LHzMPUU7Ktd9CSuL2EQQVtDu1T3gKjm4tew8V8UObBQykbgZcqbuTm9d2G31hvlZETAYmYwoLJK3+4CWWN/XaQl9AwXoS0/ctWFjS2mPItrLjauXDvgF0jyKtBqNgCTG6qjTJCn2PLnYbzIWopn304T65eYs62ErkBIQy11iYfHVUfQL8kbH6JX6p065aB0Nn6EwD+ejEJznivuM4TUtlFbT0CM+U6GQAC8R73gx/txqmAAfm9Es7XBqeLba+TMDl2kGVORq5GAlFv9LV0UCg/agyUR4kNCLDI2T6NMxFJuUuqSfTsWr+RP76lf+mJE+u/QXc9rE/iWHk4xeGSG7pmMP2x6xFmbQY6j4uY3dO3Do/dALEXqVeCEHdxd8Ib2g330y3X8cchIaF3uNWQlEFwUH1HaM06bdjOI+abRZylFi7cHGdYkxdqUFxCkuR4/5XPTeVBM9xqTVDAAP+8+Yli+ouJZ6RhwC3k/s8O/zrzUeQCO9RBpQOme78EEEzzGsAa/Ax9eJYX0UX/MtzXK2Ezd1Ru6YI3//Zbp62gMLyVjYQfLNKbQxJGkwXFaL/AbdtrrMIDlN93Xz5q8L9Gk+DobI6HSM6RXmdXmZrIeJ+aPHjHRufPqPoPXdOkflsdISNAwvGx7cAilloRCp+TndNuCL0CY4pOVZ5mzP2vp5AUyTPsuwQ8+zBsm3qJH+sYbp8bvtLUynnroFLz2ssEVCHhJf16T1AqZedzP/wenbZR0CN7eNCjYJzAOyl/RZZnFbYaGB1xlXTpowgZv5xSNuHOrVjQvQA5WWiWJays0mG0YPZLU7nx8o7p5l6kagIRJcxUBS64qe/+I4iiYZD8wZVdUrw5OwavAu++q/FXz186ZpVZZs8NFV1K3C8Jt1HFxAS/P7F0NY41Lgo6IDCtAsRDbIrW/kVDb//w0m9zeqWEbG/f1rYfHyiwV13oNfcvnqCM5Er6FXmUh3XDuATsuf5O59wFf+hifjtiGqaypTl3fXL8KKMaVZ0IZ8JzLCIaydywxCjuyyTpfI66oBj9b8WMGAEhOcwkpunvr4V58avTsL9faXsyojkwxlTjLgGmjUlyms6F6cAUJtUfzv15tcmPeAfI1wzZFjg6N4DKkI0c6Lyu5Ym71MquOKyBxOFX044T32xKAnxk5nY9B4fm1olpnSaYSIL1ff8rxSkyE1JLvFGDW3uXWxUdf5/d7faTxpEBzlJUFGBs8UW8WCvn5J5FcoxsWzl3KTdib1UnEV78kQpdVgSIjn1VOdfijR1HlcyuruiUXs38S3T8Vuji33qmmHN3+ss8tHqG9Qj8eLqgm8DjvQ9yx7OzmK9/2QvOfC2VM7TZw5gz3a4TwD0gAkgrsVle6AKQC28OnU/f2l/tPIn/LHrnvsNVmNUWojx7yj14Iis9HfzKGT+sr96fPuJn8XPa0WCzo2VEArXNaEqLS7tZWans4J3HiJ83nQKPf6nKkMGgzhckHn7fE0cgUNkugwS3g8ogp8e9k6LO8cnUzHH5OMkJUiVVKOX0VawgyE941ryuT2IgJi7pwq60JYW1TszwgtGZcBV8IaN0/0f5d9gLpG0tX59drf589wzMw76tgwwEVq08Zl2Zw4KgJhDhAX/HfaTWGw2k7xddaTvOT1IX3sbxwWm7a2DKh7u9Crwx09Wes2iBBU0JZ07DuERBTkzhAwDRHk8bSigldytn7Jp6jIWf/W8CaSOctTVTY+URQvPmAnbLQ6QCYmUZ75AUvDSreXG17hhwUEV+DzcS+jr+04UYUD/U2XLit0oDeqBbBg2k/+5ft/mODzvPM0UDSh06+EupgU7wL+OyHcTwtPqjCTeWnAkVr5UVTSleRPj9hR87UpWdLbMNQ1XtBl9GTXwVV7kO1jPLH5C/V3OoYxoWNRm4evl94SjJ+6IZ07W0XPFhPMEE3tkZBLGB8wYC/wBsX+av+O92EflaK3+ZOwF+Ya42g5DJe7ZV1fFFD1OF5R+fxrVy18qoetIYIFEPnM9LL2y5i/ECKrfWGCMS4xjeMMGCcvl4TzBbNTEPPLEfCjt+VaDfREMomioRrPz+tmnO6C844JzF54YeV97jH2JXtFHFKRDnMF/rCwmuZ2i0a2FdMmruac5XqbRn/KA9HJ8Wv1kRoZ5ycQSGtPwoPfydGIw5X7+txk/E6tb2EJN2GkIJxq0JwDFl0jvYdP7+ORqSFo72Il3uYHY0TyR54LdFJlAdEb6wsVzbttR9I1ndWPDuq6t81d89elTpB/U1FiH5AzorxPeI+lglj2/WUTFbbXBjaKLPb43UI+gIXcIPIyDyI9KpxAoY36Lnepjq0ELbwHl7+kuO0leK+Rm1UY6yCdKV4UxtI9gbXYyWYvpWZLMlU/oOpVnUTpk62nf0zJICiLeAW7lPDFmMS8Kp/tUiCTYYLFSqfg/o163z37zWb/85yK3YRZrNQvpsgfoy1QSrUM2rOca6882cBU4/bdfhVQi8c/5tqS3tXtT+YP4rNpWWgrUbu2QUR0VuwALbUNXoTIhcLRIvxGphORdZy6DP99WUuR71nb/627yxu+PkWjuujkNpsakTSQUN9x+VihzBO5YB+WSCPyeieyXiMgfnfbnGX528gcLijTuIT3iZqL7tO2iim19HwP2oAx2lOAsETULeus7cNjrsbDp2DHwNY9dgrcqNW4q5Zlj+Jne7EN4dxX/p3E0DVclRBGTkpeMgtvkLzl17vJL/kFKCpl30r2yCfcOnCNgSaUJH/Suji5HmUnRGB8cLvJDPWee7wkMUr/Tg/TlFLD0poJ5XANSLf0IwOdUdlmVS95ZBydvVp5/iQd0RQkDywgfCexOgthDLhdnfBH8akh56Pt7rqegbH0TcKEpO9i8efqG/t24ps6Y5nVW4suWVPgzwqI3Hz8a2pRbB8APfO5dVFfMfvB37H1aPSoAHQh7hLQmFrOrN8izEfkegqlQsKQeZuLqM12xtrplkTCrEaIQudA4sLOKXnoK1lTcvgl1pHiLMtCXm2Jh+EOitmh3jbKvRiYKs/EKubtLP85DdZwkL6nyPn9cCfkRLxdXDWcwIwtgdwCZBXN7FulD/SRmYss4cSwit6v90zDBe+S4w4DFnIae74e2YM/s+kEU8uA3Y+9F00FygwhGkrT02p1QK4PKJhbrozXvzy98wStMEOT6aLgWoepx48VanMBfybxz58sTZHznV1dOk8uo1ORJGI+e7/piW9sO2aBnjmSiPYB70QXuJJuXEo5GrJezXInWdHs6b/lfDL/AV4mQXlu80//n9C+HKyTGUypXhGZV60KL5q1ZEQveBmVhFa7xjar5A7vlhFLXnB6FSGiHPh3VcwCywI/u7fYqq8w3ljo6lGdf/oLqIj9oZUrCp9/PPo+Mvq0E8PpaF1Nnl53yJ5prXR0lcgF9+WJuxBHMMmXJSdy0rUYGdqGq0uBz83Mk/hiCyR/4b0W4UXVrfc7cNMuUBKyl+9rLnnT/IWbnXRKSdzDDoVTf99HGPG6UMqcVtVhqYihvIa9NdPeB0noaFb5wx/QMkan+WAcYE8gvQABa9Qu3UIEdbIP4SWfA3spobeFd0ABkHe29zsyGGCOYKgweYjW7f7MuEAlCNgZBdAOwN1c2pl6/gpXt9rBBRhZQZnGri1oquyqNoQFL+iks1+ArE7fNRPSkRAI6BurR2PzCaW6TcdYVeV1KJE36v2qHAq8udWJy2eyQnTqfrHOBUv0favv+1D4nme0tbeq9Px3pnp5iaNMJrwAOuuvs/l0Ji/DKIzZ6E+LxHx+q3agbnK1bNUmoRlf8JWc/LYlCkWcE93NHizpcrYjmH0xAZrPTC/Mror0AUe5fX9cDIUJbeW+S1pCD8AHdKZ1t23EnyxvfFd0K5FqYC1oIxhpukwtuaBWo6Z4EMqNKTtagP6i8yyRgt/F1JTnuaIipEKJuVFz5uulXL5trEXcOsOGkY1gwB6BqkyTFyw99Qy+lkIbtzqEV5rPd8Kz9L42wnACHtySB8jYJ49m1V+tJiq4yUJtNhf64qMc3MW1+J8XZ0R9AVkx4/eZs9hwphEiks89GNU2fTGnErc7cVTz60HHoA34N9IuUZjb1qeJnMvwT004JgfH8NK5rpsvlMX8ZCw8S/jconju11GZeJnqx2d2/NaYn8bT/27eUBeckmzcqS51Unf3+t5mZyPgdkYQ706ihRf7+HGda1XBGOpkdD0udkdkrmLNTMI19gmOX3myJvnl2XHEIhGcEG3Pk0A+XqUfyXBpSbhSel2qSoyq9fOxVE6ecMauzDVCRnb6GES77tMn4Zv3lR+5AF/ath/hJ/r8f+qdFLOHEAuPffpFsxaOueMH1sXh2fBFJTWXXBvC7SXciMGl/ZGfQCiPEppHCmSm1tZ7+oehoFIr6ILhahd7aSHLnd40GH+FgUw3VdzgN9SfEEoh17LKaJcnxlnwj6xcARcy4f9vVWpvD5VlM9IjVlZbk5P86aejGi1wAEeVeHIkm08iOqBaUu6fF1bWOnPNc2VMhVjG6/15p/l3d8aH2tk8Vfe5yCmn6++P5l+IqF5KvWnoWcYyFlt59huMj5mESEK7mul1vmhpuT6YK9uBXsYnz/l7IZy4A2KE/eXZY1J0MH+vs3MlUj6+OdMLTItK0vbK41RZHOWqbd0MuY2YaKaks8AwtNTcqv31JF33/X+42GUZKcOJEW4GPjPIRqRWqYtJ1e4eDRToXaTf1TdxTzG8rV6NclXoBYK9PeJpZiCHaOyZ3H24PDWMMt1aITp7UIgzKvohMZTW+I17o03aV6PMrrlS8g5369dr0Tt+pzypmsgruCK8luvPhXMy7998fftCuIGMoOabtweYzpS9PfJVdB+8dCCEEtMm1iawkp1PJl/ClAjF0q08Cs9Zo9hITP0ytkKMZoEblOwYeZtYfn3caFW0WBrH6rh8bYIZ5AfL5qQDIGb1hNPcvDw5vW62/8gJ4wlDwjaPMZuPyXjSuSJJRUJTUlFQrMiSwI6EEP390WatlBUmtm5MepJw4AJ2GsPKO8GWLFR6Oa1EyjiNc+4NS18vG7A1Jrf36bMWyXJ/Oe+CCK5X5lv98kg6LTTVMdqbfF36x2jS9gfdA+PT2u9wh5jEY1/Abd2L+SQUUb+3Xb4aZP4hLWlPouK60Lywb8TdLuursu6GR4YNi1U6D9OsMJ1McjBF9yFAUdlkdIHEaliwP+xsXgc1CCBzMiD3R+wyZNXKGD75ee9l6OqcJvfMf1E49RmHkuv/FxxTu8XgHvQHGe213lzJJ/HU3NbGAa0J1crMrvLjJsdzAzeRUoDuqTu/mxA0RX5N8T9kbKh4oTjIKHyJnGOB+zss1jMp6HO2S1eHQYRjKNPWBfgJ8Ku5JLPyXxnXuQKXPfYOptqB6ORoRIZf8TBQQppDHo5GvTZNlEFpxqazvmHlfdCjbKQgGN1+KXDE5n2slG+09Mh6i4Qh8QfsDAqQj7OxHt8olTGU9OFwHzgPcUWpdw0JmQc9+w+EjGQHkJDcy8QozaNNj3yceoj5DTvgai+dcn45AGwHC9bo2PuYucLuS4+NPOpiU1Sdod6pT9lBCWIgcpEH4Pyvp9w8nAoEjvfVw3+4ARZnv3YCn2ASZbOfcSJWH9RBMJhOss3n11/vay7nwgnW+9jVmfO8L3PU1BRAslwuxCR7Ev5a9kf6BVrlU0nq8n3+Z6YQ63NLMTAhfUjYpBli1S8sGNF1yQsKwqZ1nqSZwRR7bck/m7rjmP+t2E2vaaC8qp794Gozbg7vmSa6mTYrsjHhsDsZQ4swS13xeVZ9+yl1Yul4xjire7eY50utDNrRutk2jZOMSRVusp+D5nZ4jErEfHMSTOb74JRf4WhINzOPutj8O9DsHqnD1LqyFvbxnVBsdX+Mu7nquExgvE0CXpPmay27rSvYOPR+XG1ZX4YWcdlQPmdfuivFH2C52wohV7S2XOYI3frbBq7Vg580cQO9dTyUZ/n3KsP6TtP8f0Bz5/RXkwwuLD66ByOfdMo8j1T8ZTv1gyrUyyYjPBG3qQty15zpFfC+5Bg6K/j5smfh+WiuENM+7ImDyoioeYw0i1Biy7/2sU+nf/bFKatPqSJkBDJhVZjBSHFk3OA+y2s4UjFKSDptStoFDWemzUO+dr3ufALz55EhkVQABy/Ru8cnu/5K9zeVAbY9JlGiJ6JF+K/IBPyuMwD790PjJ/HvGOL1abjPzL5gjDfJzVXVoKNpufaeZ1fE9Z3uDRE7x8STnRzzchI7131FOpabGpqc71Sdk+J1lwYI2YagsNPmyxvV2zF2G4MH5OrjbHmx6NeF5/SqvlWD7+smSkQ3KNyVg4jZqUfSCLyULV3we3ncZeud7ukrZtL30G0HIJlN/IVV87f0mE8h4tOc8ez7QyH50DD3j41lz9qnOT/AniTdv8IF+WVfWd1Jr9XzcXj24/wuzyNkjCozr+0Lc1XSW5YU1f2pVmleGuw5uktIq5i9bUifUZ+qW9Pwj7A0rFnWp5f0xywTfzXffXwAKc0bNE+Q4HougsbqcZy6FfAJvCvZwauIhK3Pz4z4agViihoiIvj6NxY5CMmmfwvoXUhHaKHbrhzdmHSKmoxCed1n27DpbZqilLkk/krcuHzr5NSxfmDCkIW2IwmA8iFyrIGO1Zv/zNR99Q7ssWP0tYhf1SVQLaTNAAVKvQx7u9PqBag30Kge8r/sifeixk1JplET79Dd75ouMDAu8pm3c8QPLfatSY69u4a50fh2/BxDmzg8YFvcMOsv6r6NlxiED1ippWgDqBZy5ZxucIyBLrIlzxTYfItcJFBeD3ymTHxXYd0x1Z4fRueUOZraQFj6YtwyIIG5nM5xS4X8kjPj5fgtm4hrVLIA2Lwf2i2AK3y5/aPzuQhN1jWY/fgS7g78IBz83HjhjvU5dtVJLDmc8NeHdFIhvvSOgVXdh0KhcKSy/V58qunUDPO4X6XfkNOzxTTYhO572G85P3rLx8dTvMB+SE+aCAroBH0xPAAHxX+r4IK/xO+/K2OjGoNTudOhD5rKkgu3ll32Mp71A51delbktsKkZFTr+QaO/AabjQWsAqTqqVyi+jqudtYOZWQX8V1kN/MEJHm7zhxHTOM+uNGlq/tEUmFs/qaF7oDR+EgoySFRIczeeR0khEK6Y4Tw04yE3S/o+lq1iQFVuCX/P2uCxxd2eHu1vB1z/oO5tZzO3uog55IiNSV7KuuQ+lUreP53F4XUqAimlwYmVNUoTmwktFv+J2LV7/GWXdWZEGLGW6dAnw5gY/GuBgBrtZN1WNyLyjv0Fd/TBuNwzVDvSbPke/NhsecboDJY+D8ip0/eKf6N4vE600xJIv4YWhV9VR5SLK7QRQMIcznRddolReG20Yc9CGOY2fIEiWQLhWwiUqCXaqYFoHXnHZmQT+9efQocLFMHbcDBAKOwnY5YFh8qHfe87bo4X/jWCaAIQySu/OCyAdjRKkPcauwFcTR6Nxs5qdQg/ein8JdapnmS6i1IgjzVb+TnlgTgRhiwV/mSofs8qPseSlcyv+6CZ3lpi0KvipES2T4m8sAxEMAchp2voP2klP50SC4kLmq7sKaI8jC+mGw/HWxQTxnvzlAHf+rySbrtYsatOCVjA3ihWEji6OwInkowr0REQLNzR1lwx+rqzzvpmURi2bgb3qrwCs909eTJrwzrSSboF/xMmXGtfIYtzhR89I8W69z2QAoS+71ldzU4y1hKxADX7L+mjReA8vRiRjpcDRefJWqhiYRmhfn1xHhUi1YgAz4m3DeYkZ2nGamg/INa/PB1v4/gXIwp7DwAOIt7C04Co7D50KRHqXyAzDk7g/MByXuakwGBO5MG2SGK2DQf007tVlv3Ey9HTH5y1MluKexRXUO4F1q3FUEEsslKbJwBdZYBgE0L+oRv7ezbV1gPbeLrMKKWNz7cYx6xQ0yikvGvCg7Eb2/xgd0ynaw2x3qwlsrRd4jF78lHwLlXQcI/0QRkn3m/FWHP6XWgaZge/tnEy/blDefr8wZ6Ax3kY/hU/4lFqpwXEt+/eTbDedfgKHFUULfKRYtSHlB/fEX6J0OMQwAeztodlo55WLhj8UojQ0dK+oyuMnbCYU/6wEXaQDVUrmPPAByPukk42NKSu0i1/mmLSRCNyXlXUgXixh+S/ZzI97wx79t2fBNCkLKP6GYleJTvPXiT5qO9h9Owmpj1Qwg8Stx0TxRr8gUNTuHMVfpRznlgwBic5P2qgF0ggnsKjfDLgu8cX8nfgvYvYAkQcsG5bG+ite3O+jXT4ygJzUrZRbrvepw5C+KLb5JkvRKhkLsxFj60YWpp0i8PJFBM5QaI8FlHW4MVf0qPJxqfdLNOYYCSlFU2mCZWdJSEPViU2jLuFmtkyHziR6FLIW1ckTh/4r1oKM0RxcxiSpFaPWiotyoIcBkh84IC7TXgrpJ/zhqUjH7NVTvC5QUtsYMqyz2YgV1NVSXhaXuQoVnEcW44MZUypjRCZEZmWQmW4w4Uvt9N+P9v99YEvxiF1LEsVcqLXdPLvXjmDpInVVc92l00sPLCdC5zXbOfbFB44n5Ip/WbhkT4nPuYW7eqPf4xSF+9ddUSrrcSqqvTCLIvjnqr/DLld8t9WmplhkZzGt8GcV6NAJel3agzpUTkaORpkFBXAb9D4QWIg1Zxwe6jFn8rLiXcP6QzTHfPPDb+4Xv0ihOKIHbHmloTS7hU8eUKsyx7ay4AQCePnK9ntmEF/g2X9ZOb5zULIhm34Z/pxwwAtz3GOf8LJsHjWHKu9b0heVBkULZcs8oyPgFB9P1khZ6ux1VvXILi7p6wp/zFb81ZHQYChyFjkZxvnc69KTTnwvegRKZladQth4l5asLgiK2dDLELKs66zuS386nR7Q1TJ4JKU9oUMmAVkk3cvn4dcIWuTpwXxrQQyeqwYkujVCpMZMLvQbdOOO2ZHUYGUxqtF1Nng3pBRPqCuXQxQP8PCg3YvUKdlbc3ets8P5gMnYGfhvQur631Rwl2wdmzD9Qn3oTiyt+7x/28t2uB3QIOCCXQR74T8HrL+2JZMTfwyV6bGrKor2/b5jZqYvCOnqir9LgRY5THeXBxHLOFldQKJSxb7F2bmX5z9w+4qWrEkKgCAoS+6hBYbqaZClTNbpKhqp/7z0F32hrchFeGoyLpYB3lc21ZHeWn9gzukU5h3huLqVcllyve/VOXWtF+WN3mPDyLmvrPrGd0SsQ2PsEA+MVj5ThazvyadAJ7Imk3etQ6RffQ/lpWcDiBtzmTR38/cdayWsDd6drVjiEWTvFAylKfmoOTxsQ4ffpR83BGLB/zeZoO06VKaJDtHv5eSOhSWQ3VwmeeiL9c562bWwopNcI7mXVdYbY2WjT92IWrPKOftEdySglWHUKZEGu2TuitshTB68IB1PXRaHFFsezT6dUMNb1Hc0zld9f61jpt465heFYuw24JynSsF055sk4V9sUKA65eFl8snA79DnSC9f7VovCnSEoF+WSvcYpDU+KEKCu9DfuNjEPqkVrGzLYMhZMw5SZnU0V7Qi763wvQEaVMwV1w6lLUYQVzc1NZ4qTRgEIQ2GP5lOAn85+bLyJ8QFunBT/oru4R9BQmZ/uHLsahnpkc4XX3Vj4fPEof44kE4vFsEM5X1/5de8aILKvbPFpw5beATQNYI/nscfZeMtxnFRlEXRss3xntmmCzCRtQEK4p0c8BkDWnJkX0CkdLaqZ/NBPWs9/82d3zMndmDoS6bWoWnSnzc723JMaAGl8/Pg/n8xtxVlMYRVH4FvqIfCdsgn+xPnGyAETwvlpyzGDOyLlUC6WAtRyyPkZNxjWUGaqsXIVfyEj+F/PkdoAPgYfGC97ZNgutukqUzCk4GVRe+afyXfN4zuGMDv9YgYQYr6iU2buWp+T7YkcBkt4cs+crUlV7MHuv1MbWapGk0k9ffpKLqhMUsFpWtDvslBtJ7uAbjes+HfwYII06PN/XMaO5PEcigmWRhnX24qePmh1W19zSq1p2DoQF98QMJNhOw1OA/7tB1QdXHYDGDUYi/JfuxYByqevq/6Lv+d0Jx8K0j4VyFJl+yex2w5mvYXNV82DvzKwnlBngjCsOiGy/V/TpxSChB4bVQn7fBo3JQxKj4nuWISmSTgttjQ/9YHkln5Wtq+fHt46MlN8188SFveqWIfkNL5ZUTSB+DJGD0Pxhhu0Xe4017OsVso9BFqn5KuYnwxXSNxrXiNuGZNj124kx/g6XuyJ4Kt+iNyxRqe2GdkyNeTgImQdrMzwtUvO1cTqPnlXAKQfZ0OmoDtJeDx4fRLkhKDUcA9W1dcsC7gq9ZNnE0Cks8kuGGhceCeB9Uv7W+Uw8tx3bRdHuXoHgCPqwSPW6vGE9Dcp7D8u5236FSmOZZPcT4q1rPxImZrQFPafLDmIb3gNuyZdPHPFW7d7Q3Itnr2aQijKu4sQjGmagmRc9Y35T4gmzHPh6Yjk0Qy51H/JmBSLROZuiII+EZZ/8LojUOfUwtp+YzZytk9BJnnJQY5gEB67hPgZoLTE0/ZV+ZEnHsnlKDEY/bimDM9PHbJ5RMwa2qp14DKghH9LcZNRSpAHfWlDVygF1+ErrHt6Sm9Vfil1MgcdUMdOmI4cVBvt9hMxK884BVwKe0X+L5l95pAqxH1XlIZDYtwfe80Wj0L53YjiAYi86vp6TfGC3gFCTTgbq7jTq0kIDu/pO8rO0APov3K3/KlUC7uq+SkbyGYWjXLJDvdNT3T9jDV8ldFyJxv5C1BgaY17DOFl+0s9zNHWM9+Hjx8sDV6+6B56rXTrkiK4dOPnWhCAlIQ28aUDgPwkD46u65PugFhKwE/mudOSr+/YoBsH9fLlQwi6eqBeXX0JBM28HVh8kzzV9hJ25Dq/WsU5lJK/5sKHhgzQhS+gsMkdpbnuIZgPspNsTI2iIDUJODpXEKbu7+qOc0IzXf9PKP2n73v5TFL6DR3LaClPNopo+h47rYphuKMW5SH8W4mMo4MvEodRZI5Rn5qdWNQ1FCGh5+m2vddXnwHtZRAguvQgaNioSVVQzWQuWUBchTB9JKcQ3oZoL/EVCdOtBZHuGsVg92t3MSyCWmUcDvvwurJIrVQj39300w71IT6nLY/Q1XTeScqliHz8B3DlORFC4MZ0S1FDPe7JYG/uX3YBzxvUHL0F7Bse9UeqRaO2CEd85gMSx8fKfgB9xfewnT0sOXLk2VlKggQKdEhd7ykiG1U7nHLNdQSK66ss0o2GYBQjoCxqaJ4uPHqdM9YOE43yK4r6pfUJXEU1UaqpMbwEvSB1s6pjshrLa1zTEg5yLZ/MLszxb7vSFt6dhai6gv43Ph1Tpwft+X2BDLInnLbx7k77K8C4Pn0okPsSRmFahzcS0Co9Be5xOn+W3k1jMVdU7vEpn0Hey0lYvr9507Zdfs4ynLuUYLnB/wVqvNhXG2/nsA0cOnPotac5v4Cs7LAzoSn7dNLI6mD9l0bcz7vC4Ey7wnXC20de6I+r9zEkpVFYlLic36jkujRmV+l9aH3r89L0XnFmUCCr8Y7yY/qTN9oB5jG0lcyhl9hND8NUI21VaSfFEM5goG7uiTEweeSzuXV9xxL4GIGhiNBRC8Nt4PhMOY0m0YRKEGwILnMXVOOulRkOr4Kcv9vNhHw1fvhIb0xzLQ2t4p49lQZ62h8lAAeHQRT9e0bTUW/iOU2L27JSArNubdRcuv5W+RW1kAv7CeX42FPXk5iyfqTLGcZYYe8IJTpJP0E0D9TngY/oNLX9t8/HX1k4R778k9oZlxZNXSoTc/PyOMpLNiqc6yKZZYIlSRFJ9IqYistr4zwhFKuZSpGWLlOUvoBeeSC4qK0ZEGRwjNK10D5wKJcmkNlCAJpoJvH+ptYqFaTgXGeVQZ1qWDNjk7wg+/mrnGjlX1tzoEq1iKW/RJWsUmcOCgEGhBmV6kLAWPjL1GThN9GIX7/5jHSCJM6pL4b67oVAbey0wSHVhDA4WmFlsKfhRdcHA9zCqUhf+NWX+eoIHi83wpPUZtk2PWhPtxdRfnwGcL+Xr9Pram+54ePmAL96ckPufkFBuMANvwtAP0YiHMSr+9BfwjyNw4XBSqzIen8DL0nqR1nO5cvWibR6cLkKY5OSf2JBu4qy3Pfry+VdJKsMJwFsByhHogjyzXeoJng9d70evicM8Of0w8vQMgg9J1Ymxbr6l7kefGsJ1j3uVZpHeY+us+x0VLEZTKQH3zao/yY4i0VUSaf5uD9o+tfAFPiijg9cZknKbZ2jfli8BG1r6YBKX4kacd6qOd/BFV/bxRY9ncN7i7yExyeLwyENijMr0E8w7TtU1BGlBa1SoUM1TCzaoUoTyNUiC6vwDNq1zwugnsJorDKPS8DKVZVB9DS8I9irydChmdYyLKFzGqw/Z+gy7/ocIKBmgYRIPwXMt9vdN1fNw8/EFQbMh0blyUC9YmsyZcsc+TVWdCr0L4q0UNAuMhYmTSJRFkVXXlifI3BiYAJaPPJWChMOrmQaHLhb0+HJ1Pf5NdHItry0OrxYJnbQcTfMLF2LemabYmIjMMkK1R+rAadvBcW7vAS3VOHoOTLcOm+6Bry/pvGy23yIXXty5dmmVSg99/BmYK69bu61zaKww9ZsYojBNUBjh940cVOmubZeyOUYMK8XYCRMde32pxOJIIaaM9aTDkqpw/ZTFVpSrZteNETHLIddHcMzfapV8zNl7P6udjTJtqaa8UIXVZ5MvBT8t5fPrbCxb+GCtr0rTT/C3d5Sgd+kQ5gpewahoK08egIXiAB80FIJzgEz4IVQxpuNhc6JNs4w5GqPhgVzGHd6wa7RGPVSdOv8mq2j8CXABhUB81DUwsDCKwGFduc/R/BJmn19zPff87Mc84kSF4DqBhtmE32rD9mFnFnGj/OVXpntNJ9D8UnrxBfWSS10BSdHpVBRcIXa8pY7iUFP2ydz/ASfp3WX9SmsdF37/hoCCiKQhw7ltH5oz0DbOzhqhDgQUAQUvwV3A4iWnTTJAiBFyMMo6SXlnZNJhLAzyCWQNMh2WG/LbC0T7i1SS/h5bCcDvO3xLjskNWHB7SHcD6Q++ilWwAim83IrPxtfDHNDhVjdF3Kh799BWpzMNsBSTUAsvN2kRDfx95flZrSo4AC5XzA3Odcfqyz0Tu8OLwUmp0RE04ln8R3MiGLFX/lZcIrPD/dr6x+yau/J4kp+qs95zHw3EuYyLLyB7lTK0fSb3Ji5MDtShG+oYZeVP0+f/GHeDtw9Sp4iZtaDNTQ/A30HshpSx8Wk2mB+HBpfkmo4N5ui+GJa3xEMln/ylyRX5T5Njzelx8WiRZxl3E72+p2+lCkQcVAJwAzsItTypdy2HzmUNd+eoJajnVpRALhrNjXfX7uZrB69iUqzfU4zuJMJumDmw8NmCONw8vjDEHVOgRGH2XbfaN8oSC39XNLt62P4Apn7pYMr4TywvGAZq9EBjc7duI+USKqhC7hXYlCiMiQbnKifxJlmjBQlT8n64Mp6ukZOBzu83NrlVmcf+kQtZn2yVJLMJkcyDRuhT3lmUxdQgHhuH8LjYa+/05FwkXQRzR9Whks+qCvKFPuZSF3R5mNR/HVypmp3CJCFOIC74UGRYqOBux6zfJqQmW8OvXa0ZOnln2v10HwqMTsxywsA4A17EwuRL005FR28dN4/OSfBoodGhahhpgGsYvqZ1RTfOu16525j0yooMZcHFRwvtjntyVSYOPoQPH+xiifX5SEDmyF7Ak7bf5WtSCVSKKFdy5f4G1VblqDNHwFmKiopGnL9F8uxmwS4ySw/1VUoDwznL5Mt96e+AGWVIahwmUvSxV+IIkDGAngxo1ncLDoVUImc+1Lpb4SECxXxb+dJ/9CbMUPWkgey+StYPsYCoPqeLHFLwMSOhMPKUk8wfsLPfg7Ljdve8Vj/GUzCZ/UP+yQT9ApD077A2cS/GUbMW2jrVZODvhcM8dT87dPb+9vZMIgH/8e4dl/3uO2hQF9m8Lp9GOz2NTchyN+MY4pBbsQ9Of9KeS/8ckcbUjWpIbl94PORykWZeP3MkTm8aNoWTVE8zzYW/cSWCpiEqgoH4Bcd/IVCbnwoIkKxVucA5VXmoEbDH9/yINXjUy29eFptRnii+C76pxlAi1W3VAwR/1tFMg8LTW5Nh1lwMr3r96yrY+3OmdRssjgV9eDS5cs0IXsFSAd1lzLTlFlbDRA5RLsYym8/Gi4GCJiWoyuynfrUTqTO4hcsU9s31qcafQh8/5WxH7kipyE0F56FI4M9lACcgDImB65lEQpCpa1YUpO3UKEoJJ3okk04a+rLcuiWLgaefnWT/IsJqQIX/RXjztO5WrIWB2UUZY1MRTh8t9eeuIjzj7rAGLJYCDvVD4LUcakZwRlwoYzW61XlxZJUomeBYzckfEvk9hx1MixA0g/xjICZVU5GdODj51MnPIQJxGSBFUwPM8Ty/o6ICRYNHIccbppWDjLGk2vKLYd6vUgwNoXgD48KvRf9evS3pMQyWVo3mIH5mA/BkVHI08dUqtE3+5TzU0xQ8u9M9Cz01mJTs2RZU/PpowIMY8icGHW9jiIgnBBCOpFrVyhoac92w8xK3tueKYcNP9AuyLYy6RallyzQPcOy/3gFli/TJFiMWnl/WThqAVui9FjvvgXpbYucb/CN1PaLm7kv9yR3HAXdxFBpSQx43WRjfaFnfmkZe14+BoFCl0gRObLgX2ts6RdygEzB3jXJVsNjXByMgiTTRo1KAQnXVybujRt/V5I+Zzh9Q0TuMLcFhCogzKaGqLmdFGbsQox/mx3cPIjPVYODeO2n271SzSsQaNUZQ9l7hcNv3sI5lUA+fUnLmUQsX8oc4R/AykBjuL1Yu62KjkV67wERH5VNcX98iODN4jz61d+GPacY81nksPWiANB/A37/1QQ8m2r4wV1bT8GPDmeonzeCLaHlUPQSbZ+KvVZ10RPFVohJvE+2pp1aSX89iUXX3EFA/XXP0rDl3xQtntNczIhxSFPutuj8orlPPFe1xSRRBjWExCkTj53tIHJnKvN473MT+ELihkD3xo8NpkUM1MG41WSPkzBUtn9cwnhfAGO1X1ReQsvWPF5YRmqLVV/OF366/7/psLyIUXSygM0pFJl+fK6SAzQ9d9wMgx7D/hJP2E8pWRuaVdKlgH18jgCcrTvvKc6yJVqxKFQPMEmNa3X1xaEFnQ37Ty05M7SFd/ab5skflPdxGU+xtzzr0+9YsKTKpd5PYDMM500obS4Gx9X0opEOGczBsSsMF8ggI5vJwON+j5WHzPljcJr+1o2Mk5pYHpYJRaPeEfOjLoFI6cDxirkbK0PhkpeV+HguehINvJnMRXXMVZKNaQDROoBxO0Mp68aw9Ix9vrBw3XmbNnKfC0tLtVjCT75ZtKgFVZGN7v8gIcLSEZDXK5/ImluIbvS70n6DKoXz3BtX1gYB2VyhKxEZR6qhLTr8eyZ9LZTo14keGULaE0hGB/+F3I1zYX954QwGoZgHJwy2+sX2aD/BkamYnBSVCR+rRzNh2vyDzwCcXYyphQnJDKrBckwOQDp5e4bPrIgCGS+vjPcOhWSNLG+EDds+kE+JlF0+MOGn97VYOYcmTd6BvieT2tfAVaxPQlAAF6SekZW9f7VEPK1qtSL9YVGGAujv0tp/3EtaAq42iQcP6Q9RqKyyXrqw0mJdqoNF55/JveBA4R9GehpaT50Xno29b6AtNYkDr1P05kpn6zDXK3DnpneJR56Feo8YOffgnTxy/Zmw3Taj9W8xKsI8PfhFgRWPpcdiUWaokOQ2fLB7N+j3n9jJUxqbSHEurmSQsKJbl+RtN3TAaFgdfHZaeEQUTITq0b7FetDp3xRKTbcKX22rDKeRL2FkztMatFIfkp+3msuADuabRxBaXcSWQDCptbofnJvrmRsNCazjuzHyQCjXP+a3T6qL3YXwfa6w5kfxeWqkb/KRy7skNQWhom1QMIFirv82nQo41XdQ8lVezadBpbsxdeJ2BoeEo8bZYX84kSRmU/cVjxTLpkB8ivFDh034H7ERISyj3EwBGVsQJdBBw0t3NIhS/E5JBtEBsCdyQGxEaHi+2Ym9t6bMfE8TSGm6S5MmZGkDp3N6DWpr4XRv8tZsEcCzjFIsVWHGNunI7V09ciuQ1GMxmxU3K2AUGM6GrAE5Bd6jCe3O/tvMD7d9hBLqV3uOcLTRVnZfXnR6+Wrr+MtHA0XwwcIHJKxJqUbzQynIjgmfGaRiNYDsFz/3j1/2n8Dlo4Ks+REoSy44MsNdC2L46Vzk2MqgZX5ILzuBQ8geV3eg63Wq4wMQOLOV7cnDBbXZvZ6QxRSgoNaxYIW2sVaft2XEDYNm8rlv4H8MNZj6R581xdOJmYuu80QfnRRPKf5BJLOYRlspndiDmFiWVSmKm0iTLSdump8twqQ1bcrwQ+6XXnl+0Z1idJ+LkPvf72WJDYKbYqYMxaypA+8TN2+UvoX2C/X8WfaE5F2Cm7uz2lxX9RyMJ9p8mMe1pVaudSqINU8S5E1BOiqdYpSFtRgIHtlX5gbP8vOCaHOIw+bKuRQV5nolTprdquIzN5512Y5qG1F3KyEGKRuFNrU1/zPL0AkiyN2fB2tvFYn9TB4ueJCJ7+RlRuwUxn/zL2n2CaF4zhFa53PKTZCgn74dguwvaaDDGJi+NJQFxv9h+gvCyApxKLH1jP4mKY09gJW12PEayO/WDvGvbi8gK8HQh23n9G5SaQBQumMPMhaTKPOL4cni0zfsM5kWe+JKaSesZK1W5r5YyaavNLg+MuelP+04pddP8UQfpp5v78slLxBMIFbUniRH7BOHeb5mYBBtXTpY7G1IHgTxvUFQmDNQnvTrG47V4fmjJqC2KijpMDLziYfnuJqa9aalr1wQQRCcbwXIIPyd2ml+Gtdk8rPevh50bn9zXWnLQNmuXiS777KkJjkpeyquaZ+8X7NMqgP4eyRVZI3gBnAx32wDwrG/JSECMoWnQM4xnIWxCY3Unb/0o5fyu5nQFW2C+XrWI/cuDkgRCiBxZi+B6hnjceTu9HzQ+VUqgS1zb/4SbBtbnBPfOWQ44YpRmCknHJ6P9Y/nUuiY8w0IoCaqHrnAERxnoHU4Sf+G0lhoblGFe33mlJGAkZa1FSdpsmRO15k+2Q4vac6DKMvhzWUVOh+J7ZtUanx0Ps/92agfJqitnqx3W6rZZwTugwpU5XujAK/MdabP2h+jv2GTUA8c5Pa2H0TqTxMs87ToI5onnUYeVl5BXFapFejZwbUJOd7037WozuSGwRFLIfh3J2E86B1DcGVNOzwUqn8GuYFj6SRgn6fkqQfo1I+i/F9kiSDYBNAwlVMYbk1Dadn1oihVJTVUaBcREGh1u0LKq5iqwBPil8g20hSTxsRAJvR7Qyl61mSg4jm40fR09PWtF+AQb7IZKXms+PjmMifKatL4PStoqHh9uddhjdZ5ijN0k8+93X39eQnQQLVDE8unbVr/HHQ8W+C2Su9w9lr1NZjlt0gC+PBoaTh3CoyPNOqhrW26NqSi37QXZmiHlzzUNsKa945GuvjBxP0Q9Z0qi7nyO/KKlKTkxha5rlKXKoolw78V9EaTGRyDS+U9hPHfD+1c7IGwnygkNzYi54AIpcDlpB5mS52GH093WwIbtu6iu9ny2/2MneJjDHQ12fgeOrnOuHyjWnQFj9PqjO9iMKM+DAXKe3Z9KhsCG6Sr0vZVJbAFa4bTGAHglrVFQdIjTrWbsWSNbLSpKmNzvKwAc2BAgurduWsvg2NdPiBSkXiNWFXmr+wqW7zeLEnQJl8Yhj++GCT7tJwU8wia1+/ecX1Hd+S19/6ePIpL/l9ZZkzRYKSX9lPM2+7xhWCAkcyx/AZBa+PuPdpGZPkfA60AE9V88u8FPSrX1IoHldUDBYejJzSisp7DnnytHcTSsKN9imRGZTcxhI+1sv2Qcs5R/sBbHWOoiYpqoC0jIvWoOJgXA/yyjijHfHM9raiHI2R9pdcut5MeM3KkNKqDnZG5DRdBOZIx2g4zKpRAPM8svNdvo8bDp0ngszZ3cn2pHCT2Yiq4CVTU3j3/uP7NajqldNmdEe1EO8vbgxJRxkEFZiZnlWj8W/O/QJUNJrpm/H72xhpUerP119T9SD0FI0le9Ux8rv0JCoZRJpqILM1l5IiY8tta6ky40s/Spe4S2JbbNqWGSeM/c0EBZIPjSDEpKRMsWrfr/Am6gXTkUDP9uDF7ylrpQ9183vMLF4uyEwyeOEDwEBpd+pE/IRS+wXzeMdyP/h+6kLcU7NtF/+1+gM7CT3JZlekU4nDE+vVukxx/Y4zFiQCi67apNwd7sW/0WZZt7fb2cSIDXTIyIoFqmrlkWWa9CvCO6Vjus39Wq/GCkwWQhRe3xigIvbVliSvRrZlTG3x53Tn346bP487WxAFLbLsf2PdtURTxiBMiCpmK2gkIPTnBGCTt5+sv0JlYr+eS7AanGkK/tgUCDiEEOx0ig0qJE4AoGM3uASx1qzF+JA2LSsd9wnFQ+5YRGC6CskLrmyKRcLXHztBePrn4BA6cE/W9n+IxcFLJF0ejchXYdco2vGuU3uism2lZioTAlLki/ExCXmvq0/WcBka2pyL9E4rKnQx8G+YlkY0XeeaTXnE1szY6GZzQn8di37LptNbZQr1YkiY6wf/R+YWC0PMi261xM4Z8mgR60J2B8LGUn0CvM9SOoHIgLcazxPPd909fzEY+oFJ4RY+6zAvjYobV5CM0Xb2769+F7m2iqo2L7R+ftDGCMB3ZNaSw2G6XdknIsKrQw4CUB/FUH98+2Ub6OyvHFSS3etv9WZgazftLotAdVXIb7BOVQgeuCDQRX2e7e6X32088b2QgqBnDNaU5HRFLZPPL02ImLTUZP4O5PaUg52I+tljtUR1ZzaPt16QUx5vYuynrT8N+OImhZh79wqZYG92LYWza6SbOwZzYe6snxdbh9pzMiXlTxjoJQh9SIV74ocKuZYt2NIUv/wiT4/rYznTykX52DRHxEe7rHEAvHbVb4y/YvlFlBrcmFpybHFuicw7d69/e0CoGBNibNbHGmMKq5kIRRmvPIbtkrNKh/1ii7jYUPiAyl8ljpGYEHPXERemwIjBfFAQGSObi6k4vfIRAJlaL76sRFr+flX9auX/ljsHMx6gblwJkY7Y/v1KP6QaunRHxjOlMdBIEvHuKhSNtKqsqI3KXonSGgi9EVJogFK3ow3RIYVkVowmaz8efT3A//6mvw8KjvmF6UxnTbUWxU/5pSCmYHPEWv+wOznJ0OOm43rpLlXcJm7qcwjts5dDKEWd9JiPhnahvgiTk1QCYDCkFhMdtGi4QKQxfiOXJvLlP3uCGqQNM747uaWXjNAC/rwG+nLCoZMoprWRHy+QQqpNNfLKGJtSNTbxBiczbo2CaVC+t0HSDE2XY3cVmI0u4DaGmVhyv+HbhSIEs9jvkUzVpI2QRWMX51OF1EAPjC8Qrxen5D8FGLfM4dJmkDO3jKdUV2wp1W7OBWY+hdySieImDWejSAQ/gZ6BsiYHzRS7iUdL9g+x0tctre1q7GM+NLAbWDIUj+j+K2BEmuVuweVG40SnatvMZdSediF33hn4NMzJtvhlYVhgaDB9cb5w9RljZwINibzHyF/wIbxKQC16IwEqN2+Z+PAC/xfRlBniqMUNJOu10LYeQ6cB0LYVC/3iEIFUi8zi9EuvDnJnrvlT4RdgNOtsPxfrg7IK1c/CmAPPVHAB7mHflux3pdWK/KsxzlK2L4AVmixsCX46qbqsrCgGvyJcC5C4J4xnZ9ByjO7Rt9qTHi6sslCLOVFdrJMokgvuuaz8deTWR2R5T0lKQI/jfzM49wzll9I8eUF30JAxzhZx+ayk/gZtA55Bg+tUwn4GLKXLnsUIbldceT5L2M/59A2XACv+wTKu2s2tdwRZf6X727678OkkugmVREnhll75Dk3xXuzPxOaPt91og1/cpBwNZ/ztWKD5cM7z9uIYNag326UBShWGyH/MlfKH4jds8XIPxZ8boW7fu8Q/wApz9clOyujuXdLHH//Cwjbas8Sx2yj4E7nJ3ecoOwGsCKpQmARyyx8Z/U32ZiM2f4a6pTJa/jpIpo9xnpaIcHfa6nf6kBE1mo4BMx3tgBfVB13x1blx2sTFmM0QyglVRhWDpSoW3uhoI+ThGoWOrczz65KVLRT9i5/zPVrt2T2RijXbRW5Xz2tSCQ0BKZBEp/eCnDsRzEcceLVhy8t1FpWOtOiLuwSBcqXHkrHXsxnukJbDe3lDq42VKicK0dOokAoGCVp/ZjI3jucKgwg/+rHYXWGG2LSVXAWzvwjSQvFMEtgxpZwhIaDvfcEMx5ebolihUEsUXZc5MV9/Ej/dN+bDap/8i7gd3rmc+jmSxnj6qqJfzAhNHCQnrHueT3d0y0wD8dyPcf8pxxHULrvq19FZ2cZzVoftO/CkLXak/Bml5tXrR0KnjF9BSMzP+G0DOLF4ZjQMExiXQ8sFKGAohOdnEsYhd00XX8sXF5H0wX3RSSKBHkfJekO+pTm1NG1Fr8t44Gaj8c8l2KDDkNttsPLP+cGphlZGhDNRxf7+dpGXWcs4X0nf3P82qfBByMRlHKg2sJW1Tkagj79pTpsKfB8c46ksm2hoNjj8N37Mwcc6/7rTliAPvWRAvkt1C19DWsIYNk0qonda40sx/KTYkoPSfIgjeMqpMLPncSqvgDqMUQ+JzLSSlC3V067qU7SaqMtyoFIExFAKHSKl+tXxN3DTbsj6ZojQGqDonq6tFYcltbmG8ChtzDTOPk7cnBeSOl1CFQ9jHJAjT0luwdGoZGnHnbq8nu1W3GhTR7Qnugf0y+d99fnAY5PoLRsJyHlg8J8fdJaDHxceA9jOJ0gVv47dkykMWk4t6TyGPVsVCdzfV/SV2qptgP3vRzL3ejurloUjQ+bFUmLH14FDLuv8ah4wUjwnpQh2JWIWBcXBdkkHTBLodr8Kp7SWc+iVvIci68stYn/eTx+TdSvifAUurDjiyglMJbHk6sFi/gGjCOAJeiZrbhF2FP9c8a0gU6wslFs54MeQuS+Tgn34CadxCE4MvMrVPzZFDxyqTQt9RZbRcPgXg0IUqI9WhMT6wAoELnKNYB5Aj1JIIbmamAMPPuL34/YacDc1KKG7mBZpqpYO8Z6p1wtH2hNqvxpw5ZrSmGh+2OYvX3UDvxJjISwgYIWlu3Bm7vanFkg1294tQo4lfSUHg0Cl9RYNmUUUpUoE4JcyCN9HY77wLspdJsKXRc0GuUIfJ4kjtxmEMLi/lhN/B70wHYPqM7IzAq2S2veVeGtcFdT+6WbVFa4kCYoh8Xa4bVpaxIKINDk68kGUVgerKk1HDsKvBHe4otoJkV4wKE7Ssx/EjdGfxqHuS0erMFfsiryXDyt/8phwK9fSxLm4vpmdr7cd9fR5nCw54N0NsWcBU9A2goBb/6TmF+Tuobm3fZVkHvAyJCsfKWj7a/Xyrd/LzYz6HlzKS/0hiCu68MhenCWErT7QbVe4zk6Thvbv590sqe1AUcXKMwGmeCl0HRu9KJpgmZaSuAI2RYi6dzkW8mUERF/qshLj/c+pgSgAclIQEsAr+jsRA5TUpPGw+u2Yu/w4XTw5piuUZi3JVhFnomp2z7wqdPpaAOhRTstCa78WRrzEc72iB5yy9GZEVIkCrLoV0Z/00W1kGeMvyNLF70VC1SpWNg0WpFpYKSw8Oewcr096+niu2QwYMpmQIL+XEDUhy3FExTZlssDJ9H3bsadB7nBCOgv+sukcBqWCaX1z1M8Jzv9GwOfrKYQQHGsQAVD2d+A7dIUUSm+WN5fyZPwtjSq/5ca8NX0vI5suYx12GRJZKmRcB3Pgv2mXXjVa/aWnpKoS1EtSNyxmf9orE8Dvd9e2+jhdJnAf1BdA+L4BolVWcmerDk0UZFHLG22+4nqYa7NRyLc73uWt74MPu5uiW3EYKbSRCGE6AP864/t6qS9f30du2IIoodNH+VI+bHBwFUXvjfe3nUl3HA2sL8L/Vg/y6GYZ+2rn06u0nyf7frgk2t76FrTzg06ZbfMrFks+opeOdik1KOxXPjD+FWQgAsiSuTH79XcQQLLDlIFoG0koUklXyTJYqyryfzs+8XX19VWnf/2f2StJZn9zZf3VsKLnh3gNpYpUR6EHgPoAdaWXi5CV/tL9AP1viv65V8xXhMFogtJZl5RUS0V0cPi7qVO5pcKcvfDXGHi2bt629nrmmLs49wip3VE7xLDcw9Cq/62EXoSqMijuZWghTVshtbtyoPewdsP5xQQ2A+8/HURKN6PkmbhxnGVlGjBwLaWfAPhrUtn/9swDXET1TuZxT09CwRCJvcw/gf47HHK6ydFiMol/RuZmaVqdt3irv8oBHszVS9cgBxM5O8MpWFkbyN93tu094ZF7zFIbDwalL+68/HAJAU8bQy152ZkiUcWHa2ocOL/G3OJnqsqBKsz4oGiogFPYGX5jDlbw6d3NpBTqJXjZ8NefTKum2pu2Mtys2Cz2XMnNDUjeSNGEQ3HbZ+kbeCKzrtTINwBJ4FyI4zMuK2P8+FaO0j1rwHdstul+Yn1M4cwyY1ueo8cg2C8HRJhX0EbiAXefbdjdMzj88QMCRHqF0EA3iOcHelLqBo+wNLeUOiziCAwBbEQvfhvlUZr5j8Zxik8VCR2nRjKs2KsgajUVZCH4CsyDmS0DwXB/+apkP05S0na/defhw+6Gak+LPDBr5KzqFjKOy+X2gAk3AlQnDI465KyG1hVCeVK9OKGourofBZyE5l8i/OFLv2IZPKShiL8qiJ0MSvqVhXto3le0SDMUM8B4renETRAYn9djuB8igJ45eIzk6ZJZnv/qTqgkvoQ3nEMqMIx7iLYr5tfrDtj7S3WbMToLbEG+7/rLK8Z76szYJHVQ6uHNACcZpbXD1AazDGISjAakU32812u0vPuiKIbhW4IXdPRmqFLr3M/C+4xJt5GRZYdXI4aNDtwBW/PTugIqUPWsTrYvGlOEKeUnhuBovyDKd9NquFcu3x+lIEz/r3WnYLiB7pUX+EcpI9/vNbye4HP+9rm3XF5dTGQ0FpVc+71GkmRUPVsevxW66CiNJtWaqwjzdOqusEuF57z/TJ2LnP7TgHz1fQRdD8iuXVtAlg6pAvyvEDxNRRG0YHcsRg5joPxzBm28K+LkdVvbvT5WCf+Os6fkFlB3EtULJKnYEuGhASND85VTrpCMYouWv91YaACCcDezIjrTEhafaOZGW6j9LdGlzVtBDdG5TYEuvocYu2ybYHAvUfkMHc7fNgI0FWKwa9DYXqIFL0aXnEX3r1qqZNKKYq24AnoaGCjxbwCQ/+WmdcrNEMrg2pd5vIBVnLCg2sCVe1qZh4CFVRIkp5zWxqfPHjvGII9sHzGv83EE2iJITWzPEcQiLBkOLdBva1K5mLLlp8b908t1d4pc8jWHCDP61Xvg7cfHZmBAGJxv+c+jB1DYG7X5hbE5hHHrAYOTIPy4W3/ETEanP2/BUjt59XFDNXmx2zABp9mcMWGWFeyJ7zAcxTpBX2Y3a2VkTF97boL3X9BWQkfiQb8LPeZ8xQxJS5dF3FWdrsMpSxing5TO9gPP+o7MDDrklrO9KRl4wAVp4Qf2qKKQoQiFNNA1ONVl3UrHq6z5YqwkTg4kt2TSBC15r4qd3Vcj+0Q3yNGF5CAY3OsrjfwQtDsgc15EgYY0/plF6/xVsUAXdNsdenQXjAtQdsx2pACL9PUM0KdgfzoisphIf3myfp4WdUtic6ooW9FZTE5RWgLpigjBWhhCq5wANXxNUL+ivY6BoHro8FuSUjiKnymxtpXq7/pte03w+RlShDzQnqmAS8AkBHV+rILP+Jm7kA1cpCZYFcSDLENSY4XVkSlIUUHIPKueA8brRFe/ZNGpAaf/NgG9ByLWv08tCVSm47mRYBQTvs/phuRCwharWdCyfu4AIIxvRS1NoS7p7Uv+jOh8dURc7XstW2z6SXSP/dfhBVNxRdwWyn2JNvTQrvL6rj6DrCiQNj3i1NFj05Nf7CA1jjEVjvRq2lVD+JthiHiS4XSmxt2315yXGSOMzDbhApS4Yfm6QEqWlepvwkqhGIiKhPzmFmFFwXNdBkg2rS/bhl1ZzcGvwnXmwdv/pF7GzgT+CIn3BdHeN4j9zQ7+4gWyD3NQ+g2CkDh6MNXpxh9yX52XTUPnVoG52LTs35BLfLCoi/iV0rwN7rVuFlPRf1MLGWzs6F+uuFQO9qq8fx/4YRBV8muNkf4Mhj6JF8kNnhsZq0v0kyg+9JaPZWKOd6HLpV50JgvKEA/hEYylKM80HWEmjrWnxJa8R/+C8maHIdFQyhTJkCa+MyB5iyWe9giR8bdReuNmIk4NLbqXQOkOL4M4TS67ZlkF2EUzPAdLZ1eaiggGEQ+ZUxCY4fdURgrHh4h6tEGRLYo9TzKnVjryLVDVtgJlEQBRXmKbRDhwiffKAEOkQuvGGeaPNS3fhS88WbU6Y8GJcNM6AMEwDCrb31L2OQIC2MO/6V3e6wn38YMHBKQEIvjGj4KXGz9FvLg7oY5sKqZuf/ggcn1Fap9y8joLu9G5aKy6DxuipZyi/appEMGj9IvoJkgzvxcJkA0mz+6+i5V9Pz50ptewA9gNFK0YvgRUiBjbUY2MNiiPqR4qFerqGiD7hU0HI9AFvaOSP9um+TP2LR/TzFOro0kiOf8tDc4Ext2d+TQxE9eyFMufVdHoha83GqksfoXVLfOyPUqiflhkuaW7R9Iw3M13dw9ALk24d5KpUL1OIHwU+Mcr4ZiYpvFRK4WarRIy+talW/OEqyREUqAO8B4x1LDde3JDSeBctfykcLJP5LEgWxenHhr4duYF4FHcib4Tt5E5GksWutyTur0P3+oCvqFsTcxOuvtifKIpUWOOBrI2y0CT6StPHhqFOKPYlyq0h6xKGbp+iU3u/bL22csBXp/5uUU01ja4rJ8+HPx8yvnZUERD+5sL8tEEZEDYwFsTkCyg/RPzDWzIMXit2nFDYZKzKAQh1yc7dAfpteEpW/B3t9F0bPrWdYHn+u/NPXX5IPd0+G0CbQrqr2nWrNGFfuEQieu8TwemoyaHyXVrO1scgp2tjlgjpHl/Af3+FLN+AghuFRObBVE2TF/9f+cF1ZSwVlkUg4L0RNum3VDIVcujj0M+sxVrj7/3/W/ucyhr1yKeYm6gfG1k0ZYsNC1kFrZR4W2Pl5jbWOUKFEbRMEM+1sIK1skQjlbFfFJPutCsn3vxsXD4xoHRhsj2yZgXGAwXIF2O+37/7akaodZYLLaGUw9DEt/6HF4qBbBeHswOhPDncOewxutSFAFnLNm/TiyMczWkN+8AfJ/mKGyLOWINF2TptWI8NYkwi64uDM7nrxBFG0J3ZigjRarajRG90HQIShcihE7xuikImekiMnZzVWY9zKzmaxM9+syhXlr4dX4m7VmwgB9Bs08ri1TM7NMb2SB6xBpu317Veq3GvNwceoA/VWs/M/yFgWU++sAyFeG8OKK+tk7S9+caiHYi2VY+u5vdjL9d9F+fQgf46TwqkVvk9jFAsBByzYTAqE339m1dafy+f/OihZQ5VQfePGEBrok8taL5agJmEb7Sj54nV8ll3hadeBCSolqGPEWpJS/kvyj6ikYYsUht4/9EfdWS3EqU7dfMuxgexVBilt7EVIISS19/le1zZyLcYbvdriplblhr43vra8j0qfkVvPv96L/mM8yD10h0sh8LXFQgqIzA3x9D+1Xz2YJ9EapUTx9TdJmX0Ai5gHAT3XcMMwKpdyF3quUsNQeKetbY1f96RURYEv0YsoiWbqGzPOkLAZbuZ76sAwLA7aYrlr8wauH1ix7WpRhxVn4x/uh9pRIA/nyN0YyBgu/AEoOQZvTUgK3EIstbhHNvhVog57pRLnm81jYe5X4W5Z6wUm99P1cV3gjE1k+dNSICMTI/JBmxAtW7lGuilPPTboVC8EaP2ihy75zyUWS4Zs9SIHVSJ/60V7V2YvaudXM9Kh9PPEqY1i8/B6vImwlrrs7k8kXe4BBYjGuS6yg5ihiKwrg2v8SkiM/YnBVlcl1h6rvDVDAQIU0mq3FEE7BKDQftf06SNb47hShi8/0OG4hebGEZM1kXHWCwRRgz5NQ/KsN6XzQBAOtgmEjNIripqqrJGU3E/+Y3uYLo+uwgCAVLSmKuM738WUtT961Tg+mXiB0BgQcg0mZ/8ftr6O3Op/2HhKLUyr3WhOdQichvi7UYE0rcYuSSBtWrjN7HPvU8bvrckvUMEyZZWvsbC9sbTYRmVKujlasQXUIYAAL68Zu2mBmf7krn29J/oLpTDKStiFHkdCpDMnsxBsDGbJUHjtEfZp1XygPGohfqdD81CDrCron/pidI0bygOHR7HRuro9cUfh+BDmDyo+j6BLB5/u0EejAVj2avbtKheHByZyPmBF/C4ngojlFXxqzEQXYhPYk1hmX4mzrAxODwseCXhYBbOJvmw+VrY+rc+VINV0j9yLzZrgUQo0ZWyg4TWSB5TdczGoGzFwlfxoS8poUKWiIivBkcrKu6VGlh3Vyu2JhB+DfvU2q+9u2jl6roaDgXJu44tkzMACaB0kWjOLRqLUGxEn0R/zi9Uq0XgZThSw8mbjhKOAMRnG387iPxXvhDEBmLFvt+/IbeZUTK9yqmeqKRc6LGJsmomSadi5o9AwXErDzyI3kgH42c8x3/LfKVQvQIjeP5V9D2t+5B3qpIs9q+n3yJWIVIg+uOPznQl4K8AktovlDp7P2pu5mrwosFsRfGas0tjX6tFqf5nSFXfBzBX+qHEkQ4GVV3hE9CElQzA+GPiCmNa030g1Vt398UTxHSLYDKS03QCyGCSMg8FtkRWP+hG6RN4lN7QtYnPoCQgV5GEflTN4tSf+5fYys28DdGfrJql9kn0yWha+HNA85REGcvCW/yqv7CrQnYE82r6xMeZd0RIHYu2hVhuvyo6YThApeSALwz6Jl5OzrEkDLB/cyoUIMJ5eWinD/btq1d0qyHg6c3eBpw1SxTMgh5P2C5qpRFzWH5wK5lxarOZCa7gQhjoZ/oH6v4TkwnLfY+GMGFcHNGvQzH4AwGBDzNfkjUTip63uAUy66Y3LNC5e5BakecM/yLxu4e4kVFaSvICpUHpkNC7H9AkeBWbsaPPWqHCVVTxXsa0nP+NeL4D2SQ/iZALLuEgiZ16LUN5mJE5ZfedFq5bzI8qQciS/YXSMdtNTqSqNCmX/UXCwhnGGjd3E5fVZLnWbnnZGNvLh9c3IDeRj/DNlRie3AKn6HXshVBNvgREnIwx9LLNeR0skFiz2jgtM4C3bq5pxiP3TugsN0cKW7Czkjd+cRXQw8hzQ/oq0EJw5qRyd7DZUShkf4sgJO7B0PPF/XDC/bsBegRpfpHqr2UBNHZ+NXA84X4d1aPeH0/MZeb87MiOgo3S6scQcqsmHmPtT19EnxLyaPU4Wmmnz90sd2uLl4qJ3k8osaqJA0fgZVmaoTIzrsbNjgRgoJvshM8870lhK+Smjf77xM6azwTjzl5HSUwVn78DXsOGZ6nRQatv+Rv5AC3XBTtv3r/9y9IwUWUb9DZPqDQqHKu3ThcSIIRMHr5774AbT7fE/nbKgy+tl6fdaGvGVYY0/P00vjfDz4WFJjfz1hlWXYUeur0AbR/j9TtZggrZH+cl4czan42MUBZIbnhhYu0+SKbQIEOa/z1sfw1xwFfB+8EXoGJOyxp+I1vZ879C8vQ0erTP3lwi4ydr68H+s02mtGv8ExrZR9gpBz7/3+JHaSLrW6aiXWIlsywL2cwV1fQa/07P809uQlx1YKV8ml7oUUQYcprmNWmYEyJ8QOBzH0FTGgBR5VYmghZHZaaljVNnoVhRU+fqCnt5gf+gMPabHM938v9d7p1LQ8q8RnavxG1m58VbNJ5uAEoF+wC9NP/CIr4xoJ3oDLun5W5aeZMYG5F4ohFvlwpq/Vzk2Z+b36Mf1ocWcgSwJB3sQ25cFphnTr7EaGD8mWSSfrVdn5tVvNhE8D7w+8VZp28NDWnHpZO2nPKnwOhqhMyeyZ0TRFSNlt9aftN9DdfkUjq7Ri1ji0Y08BeyygLsEJhXu2wlgtY+xJR0aZ3fJy/DNiTl+dxZQRNAULf8B25RJnNDO4HfjQ1xSFiJy5rrRYl4rpiSHZ3VWJJBbFfjx+eysBcQSxYxc4Oc5ox3WBQe0/4uz6uyKNJc2U+wjeVgRMr1Gwkt+T5nkcOagag1bYasdLkAta0jiTwHPalFv0TLPHiKwgHMvQ51ekZus62WH4F1a4zq2w801d9BxWwxLkPZTN3kmclPyhEyMmEDuWH++L1Z95peWz/rglU0KAoLr+2hirHEbrzPHLwfI+SLKeJExlB9X5nBva9wT01ta/Rzo68UcFYjr9ysc/4F8SoLTMRMP65i6Wqxh1SQiOHFI4a7dcEzA9HljBJGpO1T5n6O+BfQcWj5xwyVjSIQFHMKGP4LQkMg7HwYoxNXl+0BGMs44z6mZ9BbUC4a3d4IQhyvv1MKaxmi/iEJ50GMtAX7gUTjB5tAiTX7NrDWfGCVMZ8aIU+G0SLsqw8pABlO1l/H9T4nH04VNnLvfrQo5YU0op8g5j0CqIEzl72mDAR709nxWTed/vbE8uauhxliQovz7cmWuDwxChhzUNHaPyYYTLJeAl8FLp3yCxbLj8x95s3DAtHqr+h4sSiYRF0za/ZAz79RqeOx9Km1rbv9Vg5ZDaWgVASjR3I+T5YNV7VdULsKXQJX88USHvXfYuYqcLvwzfcXmYIeQLDS7gAhNoznUuRcmZVsNmuz2Zg3ZjTGRFRr+dvkvlL6P+rzaDRcTrXanT+5o/QJDlMDWnfACPJhtmHFzEzV0H50hwuw6qdzAiKSjxXfxkgSMW4Px0BcW8trjP1uhZyLNL5wIoI21lyQwSAmokE1ttOt4hsx0iZ53HDkjx56j0Pjj65OPTvEVZ9aV10KVKT0VIu2PAj6nDO4IsQC+L1+5LdKhLvMaPP1JYelObOLM23VsSlakaIyfxR1GzBB5fqFz5k84gNpv2QVSvfNmEHAoq+VxZlR3es05IDdSPDy4qRL/9h5DNxv4JW/T65oqKt+oUzGPW6hhiXTdRfzF865HBn0sQuFR3+fkEe1XL/g4aEwOkXXtidPMEhr2OpbkkwsPBaV9HFTg7Ex0TOoocxCEOjLqhyYWY4mOVLLOqd+Q5dRIGEIPVGBJ/SSEaxDiRIKiBnx0XSlIVYyNj9ajcLWJ3nrKWrJ3jKqTg1XXn2eiSYdJnzIRm/cpwQsLM9GvqjJdimSgrotQ6fWwksPDHTQt6s68TBPVuC+MrlM+RsxKLsBzi/0g5ATauXM6Y6m5HkKQMj3LA3YE5sHHTdb7gYznJnYXCJOHk6I6dkcmUqj91V+JtkZgVt7r8m707VberabV3g6X0pKTjK1/Oa+hJbFcCoXT+5EleECzz3NfqU8z36kGy+6Mfhcd2aiRT6SN1X4rtuSIdYOA0vqYlkW2XRmg5MjVdEkpyNFxLtG8v9cNEgsQyJ6rdlxdeI//xCuMp7etrVbLAs7X4AzeiTen7U4YL1NLID+nQdg9e4b/23bpiLz0MN0Eu/Mw7gv4s2/XHh0hKaUvlWXhs5qkFd18YJECtwuT+XY4wqbL2lG8MRoooQ+1ue0MqELEbVEWWvgkCJY122QHbiEpAroSrCL97ymhCuilf+KnerBFCgJ64wqUj7KTF60EgFdLTPjr8iGX1fBEwmmJuqW4Ry9+jUfTWUR7TmAAboi0/iKMyj5qlK+kr7ngdhmeMrTtDr4b90zZweRTi2UED+IWZmzyNaiQbvgzGd1bC8w5HDg4QvB+4Ia/zF+B886dJN2e8aaoD6Vu1lFiR+Urk2QXuggdPWq8ppydEW+sf8yeYc9PfzVIDYZEYwyWtxMWJxcpglMYLIDn9TN5x5HfMFEgHYya0yLlcFTOQYuV6ScMNrMTGYao2LVcp+pgybh56Cn6HGK8dwmJVXyCl6/+nziTiR8Nljg73a9H+iTjSZWEgjoO9+hktutfjLysaWZmhkqjdn/X4Mv4/U1SI83aLmOxpcgXmI7iNoR6bYTaEPgqPQW5SPWRhFMl/wAyaE3NeZ4rhnX5gcl87OJZz/uaPVwxCTwowoym0jAwQbYDnYvOAK33kcB6U3h2FrjdBy2GgULyl0eTDRie1rWN27pL/WfQZgPlmowBl/2Mi5sb5xoDrEWAgDjSxP3f5KXm6EC7u2GwOZl0koE4GHNUdC+C5K5x+Rp0Egw9PQUloMvViUarHCZLCPM02d22oYgInNhwJbo/7Eexh4ya6c61r/JqFbzWjxsyMCfkrE/1Z0snlG/jUReXjw2Y0s2xBaBeai/NlWm0FBNDMWTeFkBpV0fzpUVXPMK7v28dez4KnYM/01K3f9yzs2Rw05KGqnhTxHc3EZnSZKolSZxzNGtJGAoNHkhFaV1a04nUt/genjwaFkeEgMMmUP+htxCJv1LGP1tB4nwYxEjRUfAD5pqLYkSMzsoKhsYGq0ViyqbinBOFm2sihSS6U4FtTSNyt7EGj3/eC3zoIIaOb0MKP5O9dk2g3Ch68hQB57jPIWACgogz7x9DGKra4QqhwOtrAdbhdaf0LQzZTGxo7oKCssl8BwVPtHMnjs9wNE0TxyjjkYlLlMqbS6hiKk2kloxRw+XlaA4z6Ad83ZnO2xv6GLySEPc7fbsfLE0J4eBiqO4V5N7jd5+lKVSXzPffuT7MFqahVrjxIZ7V9jNrjiyWAJIy5B9hieZUQgVvTC1/hF+VsRvgTt+2NyuVFZQbg+gtc/sspL3Fg9x2tVrqLNcYhuTR4BWWqDQO5MT/OUPPGy8mzxBJhP7CHetZOD4Wt27F+ZgLGGdccaPEPHvH6xYl8mBvyVgzsgklQ4ldZi3UCQWdWSQp4qZeDsKKOeoJ831cSm2yE52goXcRAb37eI/N5J5Rl/nEGQXslCagTyXIx7QUucepQCffhApKeOWTnxqqWthqfrguUnw0KKxiyHvRSS0Z3jQOF0tKwZygQvHABiF4k65icGjehTNZQACeSyvCKSLkCvRyXe2F81Trwpd+U56H7i4mK5XlOZySPUxZlZd4aXVhyYCaUmeO5vP/ukl4CZNeW3ZcsYrqO8DDD1pGpZfOtW4uK8w2qti/Scrh6lEvTFYTgqOreAbnBb9i4Jf0FberJAUwL02HaMlr5WidjZdmMVYjaKN14aDVmYLzJZRu4KzCJbxHQcJEPl3rLMqiLq+BMqlIQmmizJacptx0MjJcG49CVS3695xU02pXw+9SyPYKHNDUexmneRjVUzMU0/cLGxsc+ntKB1sZgnqV5W43E5z74EbS17jNclqecC1S4PbfpbnVUF4jWCcLf799GLBXUkfiR6FpG/onLAENkMPbPzOy6eh9d/vRk1MsRNjlMF0hEmXcJ4fOUT8AtmZ+zPKdcc1d5fq935baTA/KL46m/buh91M+wPZj01bXZjyieY1fqaq+hHnH2f+wMcY6p75j6SS2Ec3UoUJdD6fUUqszNwisLQuFDyILJW09WNBhQMvC5u09QXDusKgX2LTK3QioZNE1c3ASUO0dYpx3VwKOqYk5PygpVOWEZBHlDFRmQGoJsJrrs9iTL9qTZEvEbOYBnJyveJfQn6JZGy1iKq7OQ+lJ8T2hZQ7XXyaawSK3qpi1Bso1JW+PhmmTbHYsFLXzEUc5rJy92ek9E/aGIQKkxHMGT14snJtmQSw/XXdO81ftmVz1LipdAtic03un8pmvf6TzWMO1IuxSMaGn7fXrwQhD5p6b/+1Gdd2ZT+iW9l1w3htay+SY6t/Gk5JP/MwoUJsy2qbvRIeUkb4U/F2IAZBRgvMlrzjcgrMjAFRFRJ8s6DjnCAGrPBp9J/MVZNGQQJ2UiZwF/JwHZuh1lyrztLzQNM/311SwSlF/vHluPUNXndownsaJ7eNMa+1Fl0lFr5F+y7+bf2cGStSLqqMk8a8jtwmtWFS7BfEqMzSU/XdDexL/OPdikBBCZlQOeHGCCqA8BQ+a2ZEnUgtzG2hPLmfFnE/X8DJRLFabf5EYruJKuPo2/m97vB1R1lCDKgWDk/aEevKYJQf7uNSwMHYK/lpuOhJB/AQkX/2QfFhIfwN44/G5liihBGZYKj9a57+vxpB70whCqbR7WvCVZ0BwVE6Hj98cfV7sgwSzgxmcxlSHt8JY9WxRFP15FB+G6+bPAY44Ip/MIqOt+1YK0i21UiGqE57SKojR/kEaxev6EYoDyrbLCjDpZdiEroZrRQgP+wkxBJkF1tCj13Z8J65u+zt5x3ufL9yHD3NBHf47FwXXqwsuq8zx9+OntnErle7pGDX0Wg6aBNDKNB1GqL1ptRDZ75tkyv9IQ+pbWUnXiIEflLKyW8Tln7ai8hXlybav0X++2uRE8JUDzITi6RbURxrHT8w9DcMqFLOq8nquEVgWFxnwcDUzT4DgY1v74ThNr0Kd5hax8XxnnRwBdYi8ojP0XxVTAycY/XWAKnK/YMIzCM6ztsoDwAL1i2Osfn0zX6pQ+qcNJ0UwxWZLMXCFW85JQJSizmMheTT8c5ecbj/nY2d1LL9u9dnvzYdIw8l+Kp16RTice4a1BHyejzBEYaTNcOSqNU5aoPjPk+SvyRl6parZvCrZR87SKR6vlfZ21TN8exEt5v/+Awf1LVcuWMODGh2mn5sIY14ZUrhPcaUBScUkTfqUKKVCz2zI74rzzvRN2nlSjbsni9w2MGq/R4EV4A7mjE6D9PCWPHIJfwWAnqTeWmzCacbNixz2IM1FD0s/3FRHIysl41BfgctSxEkdVPJF7N+UthkC6Nu07j76M1kO1reId+7S/UQgpXuOqS0YV+ZVRP0V7mDZ1xCOu9NZvufj4QbOaVgz4D/5vwJuPFOjU4182qB5kInRkBU/DKKonoQZcJXMiVfPZORBoWpok5TFKlg8QIJxc8nZgcBsEr3m2l/Ks+6MOETsPGHM8IPoZ8Ppn+ITLkTugyv9cGQam8As1Ki7e1zov0GY3/l3d2GCApbW31+bxC4/WVILO9Xchn7k09DJp5Rds0tnByyjUSkjBwsnE1LzkscwSR42Nv5AuD1fnUXlfW/1pdv7HoOQjl2Pqyg4lc7ao8uNjf5zVV7kSlwdDtd49ryIiO5/MC/PiPTcemYGOby7SWH+cDhfXfdDZ/dm7bjwdQWkzJVcEIX2s3HfiP57VHrGqUEPNNoa1ciEMuWWdMRA0e19s9HnWstUWyraASUaAknkROBOr0wRIZFu35Y+/29cpvnHbVhWCI3n6f1WJvR1R/XfxAddcnkYXjZJkg5HbKTK6M3oVlY+F8wLgOT2yZWj8736BQl1GJ7EDJwVoTs7W5mYt+AjtFsVjz21XDKUE6tkhavLXURm2NpotRh1QzHZaZpoCY7AqnG6SY1ee0xxdlVTqX71RS9v4W9cxotoNUsbBNF3vLD/Xe75fn/dCjbA45MVliw2qDJ0G8UTLW4dhFE55C1aWW6Y7Ue2faDwtG7dWtSfDbYvMliF8qpqR6LFRu7MAL5tT5zBde/rYdcTXswSCkL6E/HH6WbqudwpkYY5GjsliNOK+0GR+EHKojzvwRpp3QL3AtyKGl/wa4M69A626dAds8SNZO1O2kH9q3XTHnEhhj4MSidm7IqdKzvEX+x36XWtmFHrwpQzoym81y1/doEJx7LG+2zKnNHAcgAnAxbAQH9pdsRiZuDDRL4RI+serwn16C7YUR48LaOHK7eld2wScwmLuEiROpTi6eMtlDPs3NQ4WmTzjA5KB5dnf07Gnp2dM+GlZYYgJrFkbwxSz+hWgP4fV4E1cvN/P61esFPMRSNCZFa2JLvh43J6gcngjoO7tLPF1W/XDzIP+6Vqg6C+3mv111eqI1XP7RF98AnjiPOYkhv7wxvwJyvZ4M4Oq/xaIjGUDyqbkHcrqg2QD3oUJ2m1h3Klaq0hTVGE5/z++IxkLK5054ztcoYXCyE3Kvmjmy7JbPe5TBiKtgF73txsrRX4kLWvKiBqKr309tf2VKFQmjsphQ1G7ylZzqwvBFb9Wh6QNI6TAMJZlv90esP21ze9ukoQVMcJFMjx8cKG1yLWgl+UIUPox538T4Gb4gehNClrodGHt1tu7pJ3Wy9a8faT7DpFgsq2qPxUcTeY3wHcUAMwG7uGSqFPnb6kA2AlOH4fWCdNpfaU6bH3LcmxIkBCqsYch2Jl+wbbM36DzIyIbt/LuUkumAvg9bpo7kzM8LAN5nq8v4ldCaLcs5HquMOVj3IBmRCEPZ/HgRj+YtrXYhHkzs0bKdqLySHBRUsgkcnf/gu81scoji3/G+RDdRpXlN+D6iD0GUnec9RPjbUHIiK0Fy/4wrtp9VkP26ok8ZkPu1uOxvih6nMOSSOFL41+YKhPj9rWggBsao0uGUlrNEnv54jFdMts/sFSk1rGUk5Y8sQMdz6lmTthNf/Jyjvbcj0A7vSpKEfeojjPIpa4xby64TOvlTeDi1al0Vvojo6PFfTyF5RqDkA6UosBCUoG7ISfld3tUD4hDV+Clfiz+DzVgWKXdKffve64Vfm+15S1Li/I0nX+zFHxcgq/+LQKIzZ4xqbkXnxeGEJuuTlnUQs+yGXBehhdAYYhc6Q8kzbmz949Vb7GT4F7OywqueNhfh1cQfMg/ywvsbf6NRSqfRshBt8hg1tQK9zOLMw4/hdfWRqbwKl2x5egwRAGQJ0WWj42vuKkyy5E40Fb/qGEUy1o4SkUHP754Q+18TsZC++KYinE7r1ZZdumqSInBbNi4vSK0NA8dTKMpE74uZLp8dbWHweKKBsAf4sc9XFtquoeRAG+PUJ3Q7/r6EET5vJut4aVx/tvbcgu7hBexOLUOZN5mQYUSFxTWtldhRmFYblM1wFZqexF/z4p2xIe/2V7F1zpRGVz+0IYgcfr4FMwVglFW6v/i2vCR5WiVtFZVRUc9+ROof1yeT1j5e/GJ709TqT27D5/clI2KcS/MhXV7UJYT0Gk72FuPrCg8+f7XOD4Zk9M46bOpajzwWjQEPSAdrM3e0ur6FhYbP8xMCdoPu6yR/PW0RftiKBxDk1uK5l+N3PT6pFlZj9qwfk1v+zFX62jKrHzcnta4lsTkRV1+Y7h40kd2v+pf7WO/PkH1p3Q3+Ta4HBheDaellPMo00vNLR4M4Vyi1Gm4PA6HOdZqOGc/nHcoL4xt5e3kuwl8n8J6B4NGEVwiaRSNHQXBPLe/3GfcqAOfbd0agOflgnosvI9nttSRtI3q+EmtXBt46b+VcP/PBO2eUIq+ROowiPTtjJP3AFl4feSBR71TuQke2dfW52yMMopb4T2boX1lla9orw0f+x49UYoS6sMVSPvjuOj0tPHqtR+NcB+lZL1Bk4ajwH+p6bL1UlItXrdmq9O/8BbtzkqpakhmVaoIrI+1VphWm7hhPNfxmN5CnTV58Cwjex6YjFN9UzA8Ya23+JJsjSXoHNANJ/cR0/GVLRvmHR4LCzuplVuY3LY6fncBnpV/ClNf2ZDs0oWVb0Ew15IgzzF2I8WQPjf7YnYBw4RJ4tQ9rMnZ0WKs5Ywi+fAKV+TgiAJWms7X/lY1jU2Wx2W/fO/xlR4Cs8DVPtMUaucndEuOe/8uTSTw0eSTrC0F7XokAXPeBs0bUta0QywVrEfzZgcprhgVliKMfgnyxcv7772xKQ04N1TyjlsjUB7/4BGO2tLB4VjNO0wX50aC2nztAER/Mpvk+gRTY35on/mB+JQFCMCts88nWQFXFFOkHwEhEZKtaYuQ19xUTThqFgV/2Gu1PdzJ2JlCeUpH++hE9Q+7ohi1/nKFgtlE8wQfIF7oZ6PAELUjFvHIyrjTUrsjv2D2kXY7I3HjHWjqKGi4frKRhd5pTtD/c/aGQ2T5rmfdd+tMwjVx+k1RQ6to0rJ36BdpE5rAU9i/eTjtm4KywmP7GicGv+COyZRNMHL10RgYhU/B95TejmvgU/3wJxYBg4Qasi2Udvl10ivGdNASrFVZm18ZjGMBzfVCTJP7Cjxm9aLb/6e2HcB10lgJY4MC5R1pwXa8SMyfI2FsQ6gb2yJgacFx8LUy8U9F2EkeL9+Icgiz8yvnmwqmV8cqy8qJeYqXOE5TsiXASMRPR1qjzYksvGZ3AqMFKTRiJhtOcrs0big9tXJ77CYWocwR9vvNgKhCAoK5Kf/TfuGiC+8movjUfBN3o/q8L4H3kqtVzXacP6rOwcIlfxtCfUOh3tUu1nGEeyJfi5l7TJFfHMfuDqR/XUmocQc0p8p2n3tGeKQ4kMFVCtHonv5r8vftQkU++SWgV2YHdcoBFRskXWPMIgTraH+clU44XWpcrdWc2Eg1fXjhuXz44HmHWXh/acDeER3QATjue1p9GSh76RDjfcSA47Mu1WsJ/OYILu8sPb7Ue5BRVxQ9EIQqMZvkQo7YX4dJRyrP9Lc9qn+XHWJtolu34cgqYuoB6VtF+GRcj1sjvY8gEBKxB/jw47guxlQQ346c0R1RtrQ6C6z431U7ZhhBStH4Iyvhchi9i6uxRxe6zA0VO+xbW/BMSuKI7TKKHkf1LPF7r3MnNOw1pKvRHAP23Xk4Oog1YmyKlG9esfuE6bml3aJp8QrjEXlgNIz8WsSdkBIkcoFufoj/XQbufnJqW1GkX5adkaUsCJRWznkZePjj42sZQ+YsDOA4WumpH+ZXdRUyPih0ZugrUidERMsAIY1EcxHjWrtkh9xJOswGBndObPs81YTTkwXRzNh+apRAZXJr7mlpEDYtcM/AbDchy4xQ2CZa7HbGiFQZMK/ixIrd4S71ZwRn+tOqEmkNSYq3mqcLhQxAscnBq7sSL0xU/Bae2H/sXjj1xD7d35FTU/iLmfr1Ad5DYAjAvMuDCEaQsu/bK95QZkfBEMWlicXF6nwTubTybt7VFwN29TlJ5cO1kgaWUFBb/BVL0k369CnRaB9o9midNBIwB/ryAshdGGu+5J1iJ5WadHXuetNK8+OvedokJQ1YZGb4oqwrnfj/S/DN5CY+GzDoVG8J30g1DpnlUKKaO3zoM9eWJseIVj4txR4I41cOgC/vPmlPALBeBZ3Re19Qy+EiqJXAjMLITQjk/a0GCDlqHSvwBFK8JbEuRoOzmhR+mO36Py2i57dOjbSMjwXvcTPYbKi9SSPJ8yNclGrOhRYE1vgxrR+HCbLiUCoOUUjjYguUtwBU4DUHdomcCR8FgzDVXKO8UtP+3FdqlKbcbMAY7R5Ff3a/EYTRctVk0IPnCvbah7BmhLqeX03Ncov3D4aj2r7eD3eWUTkDyloWCKis7zNqsCNVU/0nI5T2u4Jes23qpAVJfvdgdg+/1Sc0n/17G7/wopuye1rmMwYok7BF0pxVazi6wAQ8TqH/v4jk+1HXRX5lsaEaHLo2scZHECErv2O5EwISVUpdmb2B4UBwlXuxAP/UvEcUe30T/2z4vjIs3RgXElhiSmRGbw+t+7Ad+mSGjMtnsUmFsmu72o3eyhP2d2HeRKfK2TTLF1lZNuAx5ontdsdofz8TbjRem0/eI1P7cTqZstv4af40iTfXSO5o2qkUDggy2v7CHnHYvsbLhblLqv33GrLnhlCxYNUN48xnYzY2UpsyxkSzISJvg/RiYT88Ezev0VOl5xCFtcwo59p1UztRha2bP/FCD9RSqC9SuXSUOze2EGmkEgpxRw+G6la2aVNLvT5OnDTrdsuLeJqwPs/P5G0q/QteLor5TPzGhvoJq1Z0QhnAz0YBiMB4Wqy+ouI2j4cMS1rKh9i8nvx6/YyiSc49atMmR1mnqqBsczDpnxxOs/BUzR8IUN75R6tqLreQdUoYGyingokIJ/poirX598iQFfqCvZUNGQPUbqIO2VKoA0G053xZid7Ll8ZY1LD5eYEzXP8+hQxPlU9H51re2jjSYU8V6PshoRPrFJHLSvO/+8WdvhIPEyGXI6726depuCqY6Zdzqysszq8STrw5i9VjbkzLV4zSJngTVNg2WJ7Wy/TliSdj8M6Ncz0isINiA1jTV2vnmx/4rSPonm+DXaEHJP0GlP1Wttt1BCZJ/Zv53bLOGHjbtTOov32ItTExVD09pjypVlNUvH2U0rWlaT+3jfZbmoU+SbKrS5UDlnTJRS93lskxE7hM38TIWwQjCB+qKL1ptDX+JCE/CjJj0i7j6q+1EfVJXXcZq/I7/NP0QTZ3Ziu+5QFjCEErCpq7EIuTi335CEM9CoL9vV7Q6noepxsbyY7x+l3QVbIkxtN1TEDDukP1e/2r3mljVBy7COg9N6Y9MK7ZJ1dEgJ2dIy72Bn6fMwXeM2Q5pPrJ4QQfHZeiPQ6SEcq3P0zSX1zfJbrlqBFAlNp5HFMbN9T4zVaIrwTAZ//XzXECzYvqzx3HxLf1zUHuizofsYuCXZIEEjoF2snr/TUyHXm5Mt2U1einZ1pZJzpN+6vC4Xb/P/Pupn2S2mDs0rIOKNhcvGnS7+zpZIHhwHL0k+/u+c5ZMuOTFEr3+0mfm1E9sGgTjqLnnjvCkRxv7vyXaOqjCuzqQQ84BHoFbfOeJBl7k9PPckqrYGHNaCiyEPI9nWIMULf634sXSvv/4jyXPVWSx15KobUXnPDCFNs7a/KEj0lL1E2+H6mjNY5XwlfVzUi1BzWy3CaEooCKeaOiFKn0aYTyj3/zwTc8ULeZXxY9uX/8+YTMsULSY8BjLPrP3xfkUSe31QEJuQI7SJNMAJKySLV1fYo6JSDgeywvJI6C9HVZGSUkgXlVF0/CQJT75zbopeFvZ+GeWN5kt+hKKacBDvOhzNOwZ4332yNXShohSNv3R1cx3pi2v8BaHz3e4bQR30VljBb5oSGBgAv/m4SiyNR4IWohqlt+gaFtUU1h3lROJiBzeWhglcdwA5wa1aCOJmHTxOkNRkeouTeznhxbXfJ1pC/Elq1DlFPhOh1myYQMnp8dusJVSdhMS19eysPRTPOWOFtFK4Fbdm6LC1CNfDdCchTV2knq5yUk7F3T4LeGdN5mXEtpWU71WmKVzXWEZ5gQ9++Z/bA2JIMwg+B9v5cvn3+2O3FbyqpqsvjZZISrw9l8Zl2gcQ3ozJcOP9ZnDv4AZHgjxKe8idAOYPPHr3Iu3UVzR5pzwMXpLUyrZja6yyt0HZ4mkaGUpzkh6MQ67HMmK62h6WyljsU0N3dwPu0Iv+B6yLPA8VY1j8li1qT7HE6bVUDX/8pfyEnf0pVgG+n2kmF/0/dkZ4nnRBud4cJa4LihvIm3lJAoZTaKR8ik4Wk2+7b4pSP5F/IaAKsf/bB8eJvRCC7IeP1qv5FREr6Pq/aihl5avJSD90tdA03sWOxnr0mtr0+MbTDIVEg4+Tyt7sb8/ZVQafiw1451UPjSSxOyap9y4S9FxWchCvgStmMfeyH+UHJGgOhy5PiStsA3eREKe7TzT5kVcn8bA5AlbRWjrwHD9lTlPnYY9YRX8KYsxQGWmGjwP+XlDqgzFYMExNa06pMwxvMzQEqCR09Y5nxvCuah+QnvDatu+9IRpst6apBgKITJEU3cfeez3KnDQZd8/YDkZ7K8/E/fSGdgHzWF0zbFeoA7YLAjf7LlVva+m5g+lTAqmsvCrkJZyXh3KRUzTf90EurYqQ9HwjiyXzI60s442iYnaBHFvw4XIr6OeGCYYa8RATbKGrfl7mUphbbBVL693vmxh/toSSr1+uCbUdJou6W6E7ijpTz8lCFYp1INmqeqgcD7j6tmxYWGAtLG4ztWzmX9z4KKDzKgk/Hr78CwGYsJataAgy+gIcAfsbfNZjNTUrGUeQSCjJo34C4oWRvYL/W2bpzX3szN8Lqv6yZuqotZnMlHynxLvkfa3Cor9I0XZDGQqTkxi4/bkp32Za9IcvMfEmpezESb28FunZg+o0zNPv+yDRYfaQPcXQvGRaupd4gVtVQDkYbuwJkUoLKp9958lI0vL/TJsfV3qF33qhvKgep2RKEHayR2ij26HQd1/7M0rQKRBOZ6fMZBHEHHJIbk4CFVY2493DUhJayvsRuOHPwP55+ZPEZuQNHY+DmxOddC9PryVra8gFJNL8aKTIHunEKf1y20y0yydR9wI9IOxBys+9USZOIOawazYfXekxh7i2tbh11oeX257+UIMJKYKj+pC6fE/Rasf8jCUfX0eCGOYuvUoK8CvmwlPFlvuWFF4NdwvNHQMeM58ECHXRCgPLQ3ZrZC3W0Pta/5obVvtYKrzHSSE2qKA0wprA8OwqWoHEIfsH0W2edNUCM0LcLx739S5omHuhMR7hMc/Gk+my7nNOslPZXFY+EteSW97VQkcDajYCYMjyPoTa6lioECFNzvmyRbTuwjLMojEsWg5vbAX27wrAqOuxGziDoYV9yL41kfTZqTpmZl7Qzs3McehbQWhk/1fATs0u9qcCwzFyc6nWmB8UyM2c9ZF09sBlNiGpbwOYfVe4PeKW9bWncKGXz8MAg224ZzycaSHD0hUW620eukZGODA3q/fJuGJTzQc2z/FIQb1A8S1+iV/4xZfZZ6iEJpTK1WRQ6eyTLAFkroJnOVH8izNPlsMfIfpjhHwuynasr3r0qLFpjm1+v1q1XR0KCuWayVoKLfnXLAJ0DdeQo++5pgsb1U9IRKk4lFRGFiTND7Ba814Kl+VDsveV/knCDsY0sDWmOpDSlPj59J/x5Gu4qKnGJ4p9Giq+xcCYhH8nC+ojcRjjOfqkzRf8tRLJCrbNgwp3VE/knuNAZ98PiQ/Cy7c/m7nr4cXm0fvGUoto9eXejoqc0vjX7eafpxwhLzvkv0+qnHAS7kP0BhoPo1hj+7qosfqsrl6Ph4pVUwoDKVqP1pxN9X1d4x8xJEEs2p0m6dez1wjkur2oVVxAYk0Z9Cz584rQowQx+VGHHZH95fkJvvLXdm59hXad90PUxSHwYbUiSGXuW69hroK/ny6jvQexC2rin8I11RgulYHrPsi9ctHMQ8HY7DF+YsSmLJX4/OXG6oKti9aAvqy7MDAQrH0L1niweHKKskzbD4Mv+fb/GVvIq/FP8pCM4a8L26/lZUrhClO/SyZhvwe6nX9FHYx47nw2bYKXc6P8m0Fhe9DtpCAR7BJU+BU0VQcQ1aYGOt14cw/f1PA/gf0QxDWP3hZ6hUeYXHeJWLfXZ8bZ8UMxHofRT9lnrdYuuUFbLXajHHcaOunDsbWQIPmw7+2QMZ812UgDJfANsb0MnMiXvaC5HNGZxG8tPUCUdyn1JqXZKeOF51/iyrM/FdtayR3mwGhCfR5oSpnui/bxEllYfoUbeRzZ15eyknie6HVeMDuUXUR6WM/YWSG6NdYNStNUHH3zgixUubY4tDxCoaGQeGe3EWomJqBQiE24FFeppjPXGdYG6J0WKr3Ce3jc5171zb20TjN2p5i2TJdPCKrMVCnVGo+lDVyr2y4la1Z5kXFHJXl46l8maF7Low6WzywkM0ESuM7ANqZN9a46Uxu35gNR7vYw1sNKckrnykw6D9mSQMArFVaYIEVGl5WFAlieOBKaO2FdvjLU1HlaESEVKITiw2vCtnFUI0T3Cf9X7geMACA7lFS1zudib8q0yPTemmMUv/OeIDOsmdKv4RbLw/Lvh+zmdoj56IE8XhoAqM85yWY4c35zEYoCnxZWU0DgsmcvOfiKxo4pSYN7qehN/RVExQM8GTp6lOp3DXdHL8eUOcziz62IgGw23V9ghfg9hK60hHI+iDA9jXkL6EbC7eoL46iMevW/vmFneRRE41FjVI5c9xuyo2L8GmCZEiJIuqR6z3JJaY4J67sr9z6PYCTQVjhkCRJjGqeR9jijN4B1xrP4TyHPAJ9lmm1TeXvTHIiqTLl2ZC/btpOlGT9pY1Mi0WxyFkgfc1lFaqf6PVzVu4VjX8AOuZLhfS3b8c+VHvfGFOs6Ef3uJaz35MEuViZOyQZxFoOK5oRsyI2XdsL9Cp4+sLH62TNVTyZ3y3EkNZ59IfbZbnD6VfFPTb9NjU3uJTAC+K5ehLpNnzzWiuG/g0PLlauGJGPFiF3FTkNbY7jiEF7ZDXKDgXz2qs3ZrKfL4cpG+0eEYiOlBdgYoaeDk8uZrfVFDUX89IvRaLLQBrPw1Wr5s5GXlzzspPxe0GnsmAzX32c7wVsEUi3FgRmHcvV/IuMAdGKsEPXiK1x8sPgRulSV0SD8/CW96RXzLKrWz/0T+E1Qj7GG7P9PAE0gMLHzUAIX/q1tElMveQhGFK45CSeJHaC0LzZFHeU/+Ulup/8RZgieZG5a/CQWcsDU9Y3Qj/Rada40ll3ZEO8U621N0ubufeIRdD5tdyQ7AkVEFOvd07zXMaL4AxMPuuetDGu7rq/RbSKCSkG88W261OdfpYiqlDtaZZ/4CWuc6A73sk4k0qtvytgV0GwMR1jm4L+2btx/A0/zgh9CVJYBZHHOxCEi88F771CEO7N2eS4feYYXmsLIKUnOBsQNSGHTln8KUD6wQ0iB4iVGNr0mF/P/W3WBxWMliNDZuR9+BssRAcxuaH3A6oywpM1GkuCmw0Sw0Jg2sJGiVg0UMmtAakj3dQ0wxefniIwI5cgsySILdMcD8GgyF8jSAj5i47+4EKCZaCxivZU/eGcSvltHsH+fELlYYPbgsqvW18dGUIm8nsd4tgf695qX1wVoE9tlY7Yc5vL+l4thELze1AFGe+RP9A6J8gS1jNyPk1GqR42Zh9Zaqk0vw0GAcGKL31IxoEjMVnsXsppna/C/dljjNHVKb4jP8PEOnlMl8dnIJxVa5G8zolVac/zoRL0fYtjFaWbq4ZSGKz6SkKSodRIoRyik+0dqgvOXt3xLqG8Y1tUZU7N38jLUtb9/4uOBYR0zMFGYLln+ZXLgRyR4nhlLm4vjBNfvacwWMn9aM091JDWxbJYnWt0ok8ShYSXWo4dNcB9Xiw/4ZCT54s/ZtlAvMh86h/zi+X5ypLFiF/jLqXkSIG0QJWtUmyop+Eqyt8cubn+p1nNdJdXYpESXR6gjcjx5cXc92C1WJXh7kw5PsHtZqe0MY3x4nrRfTEDc3UqhSn92bJXnQVGhfW9AdVRzPdUzVDW5v6iS4tQq78TGUoazI5f9vr+23aAMKsYqDWvghAn6gCCtIOA+YksPvD5jMU3JwLAnasFRukteoz4TCzOG4fEKTYao1rIX20IzlPn3FwgivWaZLUgQmRFOIcVKeMQBodCpbyFsFB50Txp/03WHUM4jUHI9bVCMy83OfzgRiSEEYrCGgwiiVKAeFnrgy2RLEeAYPqx8SbrzXhn93+zveryjGS/Q3wstMNQM/Qy/Jsf8xUX9iRAcTJG37FkGSerh40RwLOV8jZD8QkKRMDrQLmEO72EGvzhg6WMVqNMrnOaC0+3Ri/j7yNnG0L9jR9/bcsYQP6d4+sJ+pTEdMI/0x5tWE0QbJqQ+bcbJZYyLZVQN4H/zRjejTbUl8q15jFgo2MJAxNA4Zk7iSJ6pThJFRB+SZ7SqMzZpLwngiaUeOnwNP7lAVtCPEn7QJPR2UTCZd/OCzk6lWEqM1EOrtbP1LtCSySK78LiA1y6DE4MfcLTc2sHqxgeBEguWx/WjtdzS5Y8u7BAtWyoiCUMo+BE1ZQ6rdvKEORaYC/kI/u/mrzJbOknt7SZU+6YmrOoHwjOgWnqQHFCEnqIfy5RHlEUDcJCHf/msDH7OZ+PD8wKE7YGlRs3CKURC/Q7f8Cyfz7fqm/J18PTlLG8aKQK0TlvTZkdOWU7Jaz7sEhOC0iWPxYYMO8KvG+vMH2BrW9iXfIWBirtgQgkj4ZZ/R8iQfgQsscguu9qp9qUA2QhMYYlHb3lNQvoULj/lnFu0U6P0jeSiPLKqj8JHCMC6YFRRa319hFGqsvBnIv2afTvDBuczUCrZnfe57M0YutIsfwHh5luE5L0g5qCwyD1Ymvf7WPv61r+jevklYLyPywdtopkWzmdZ/C46RScDwzyDZXL0RvqTszjwOZyqiq7+jJJrqv7j14kL6LOY5RRMB8Tu8yB811VvliWZuQ4K19Aba3wI63aqcmEuvyurEh8eaBYiZfZF+z3+m+V+zrnr/5I8Xg0uVjzVLwldLt7Cb034l90E3dIiFm11Wo90+YfzxH0BxgjtQJxFDoLQUUu+6OQjcScqSZBVPHE5ZezOz/K/6vLpkP6x+UDwHCchAQdscp2jCTPeN8gAwGKNzRiJswHm2rHLuxnp91R3ds1cdS+6SX/4TBPAOEZw4tq6qFbUWJGxksuBYTRha6LNBW6HqVAd2n75d+s+pTa0NGyljpH4kOAn3/yeeg+yK+mNjzScvnJaBAyWdH/x9p3bLmqLNt+zenjTTPx3gkkoId3wggvvv6SqnXuuOO139pjV5WokoQyIyPmnBEZmSSD0KMw/cZhshDiTzhnJVh8bgye7JRyl1SC1jz2okET2CDP6p97zoc4+RwEATQLQUbK6TLQIWbXpJEag+TIzdQs3iFwiPzIeDNIa52wV2nvT9kwDJV+cDD/PaEARU7bUL78xiQjPd/Y3hRyIH3xV7D+RNqYSckZ219vev5GkRjcLKytQLtLr7M7X5GN7BfahtELM+lyYM5KiEbRDBu/JcWjVfYKc9bnGRdIUg1j1Ni57/rgCp465m6d9VmvzWgrZAOUGtYE6E/jOaNUYDEBmjlYPzu42xHJwRE550vabaC7qjKuXUJXYzTPVwBT/PGNmh/4Z2FYNDeXcEC2J0md/WhJZ6wkIR/EJs8Ad4sQLSMPsxfc6ER7B2B0IwBhmXp0YVG8NbPYQ46Zm/Rh3azh19rH5uJ+fdwkXdyO+Aba3luivcxxxOUEzegH+vyE/kUN0pbNLtB9FS+0xJxXlk66jYZkVrVTomVGVL/idczXCFriuBXuGwcG+GhV3lFt00hJxSVmxVjUHGZUdcUCebxDpdssLOQ1rGKpgcNutD813HtMrsEPXnoFZMaC/uv9O7bR93+4aUEdRy/nmoEd1qQ5kCJNTm2xoRY/kTrGMk4up6lND2iutN9IkLC0Rwrkdju+ZhAzobkxw7u9kn17W0eGKIEsjCuav7+VLmrZ01G25h/HcH4L8JROlUgICT0OCO5ktynll1ZjMu/XmWHGoDMNtqxFpq/5snTmk3KKP5aOa/AkTtxwObxxN54Y1DxMGa7SLagbSqi/9WGeOzfArH0oeRTSwdI/mfEnkKWrtQumIFqe0LYfZPyih2KZbIHNmbRbxS/0fm80IL5WV6LTrf+kj1LiffNV2GL55r7RHTV8sNZtX3N9MN4Qo/t+j/LVlx/2NezyU4O1HZIqR9zqcwExtSUwW1Q9wLaCjf8urnpTI8FaUdmF8laxzWVNHL9uUYfyDGCm6JWIalTZK7KKdloj+4SNdMnGeI6/FuvgDSXslicwYrzlD9WtCZ5ickepIsB8u9dG5TCSBMchNZzp7Qj3tBihsKEjIrpi0LxW6ArKS6We9u33+Ib9WaWdI5rGYVVJUa7p3M7QsV1YcyApk+7bJ4gnlyUyjq9ciZAPYWSd2YBnx0nbmedd4cvr9F/c+et6c8NTp/S4jCu6yoCOV1IPRg2lr0gRBcy5rI3A65oicXvBTe9FVGH+DKfOU1631IeTTaTluAFtqVWOPDeHv1p/GfoBDhoYGCL0Gjn8ulhBgf3oglzJ/Izn9xRR4qq+OiAbI63WONrdY3MzD05E0UZVSR2txrUnCe+VQNTFlyYAokXTN4KoSVn3enGpKvu10132WsU1SWf0d57jzmSlsy7WZcgNGn5MYZBtsRC+LZw4hcm7rI9wIiuRy/WNs0gOXi5Q7/pQ8hdGikQuLQt/xPwZiDbgroLZjSNSx5Y2LN9t5reUBEXVKqSqvIYWVo1JJYEygslhSuVVVdaRq1eF62d3l52MZc7eV+JxRTcv52NPte3nS1Ue+htINXmj6blsDMok9SnMXRGHYBdOSsE2ho8JlboipSv0+560ZWUqyu3SKJiKeLyLrc+gc9hlqgsp4YEVjOTjdDqNRYdh4Qju8LJtFhX2nTdX/hs3EYvtqhX1M+/9ZY0pjrszCRtSRbVfvzq+wwZFK+M+Iqiq3Ou6tVNFlhxfmZxfffzzw2kdEcHVqJ3rwY1tjP36twkBbyH1d2jFt6mc11ywX/RRzvZMU+avRX8P03488hK9thZmuo9xB5gcyjO0O/i/qgFHUzzsOWgQB802S8llYzfDmKrVFgoNqxtv4YyIqsIyBGK3Uq73z/Ilmh23z5NtzAP4bXVFpzqmi4H+gbJHwTEi83Dxg60qKOFpeJdy8oYqputecSJ9Bp1xec4kXQQslwlPWeR+yhb+t0DCimPCiQ1LWX8GKKW56Jn/TnEKYcY/GAalDeybWKybad5BJ5n6hbeMqXjRH0Hp57ZgVxST0ywNJ7AGeHx7eL6iqaM6zRcid3YshYqgiJ0YOw8UynFK/JGGvCK76EQImGa6fW5280471k2abl4afwrs3Pi0rz7RN8OOu+F5S/3pngTg2eB9jq6b2FLaSOaHM/ICOYUOV8Ldzy/EJ+l2kV/sHKjuaR318TtP5fdxbs9M4ocMHoxjY92Y+E6VcwyfM436HbAn03a8qGuQqtxUCgZDHVO9ELNn/5yfjI4mrnyxI4EbwDM81uFEfslplR6gvEr9sC6poUVeVLC6SlpFxRGKTjyxNFS7j/r23p3FkeZb6DgNI7nCdQAF9Mu4QNOoDKLGRVk9MK5PuaxmauX5utiP76AjS22l9bHN46aJVI4l2WWflle5EaQuK40/3XVG5Pu3uu9wb7ri7Upe4nrlVyBY+8YzK1qrkyDWmWudgWD+tQ6QDO1avBPRKkKeIgeKQQOPJNq7liJBv2qB05NjEqXuDhIxAa7hgbwC2yCYjP7CKWu0ka/4zX7ejmKMqNXLfPT4UZJO74a0zt7rskJIUWfbnLY5jg6/DgRJ8xUCzFGUF/0C1x1g1ePB1xYLh53pO7+xaK+9vG57KsLJfp65kHeVVXnT9xESIchAIEdqVQGpEWXE7ZvOecboW9lnYbKSrPvz90+nZJPbJIqElVpXwwR9rDnpxnPxl0q11+HrGgthpgeOJmki/IKJNYQoINRYeaHFQTncPleGyeX4MkEiIrPXcAuPzY9ysz4nW+9TrA6U2XbXzOqjyvv6L07biB4OH364Hoe2Sd9A8dSJUJoCt96G/LRs51uyCOiVWBNNYt9pfDzHNeh5YCw8blYogNt/F1emIJ+S1SFsXBSWlnBvHB+HF6IWhnR1jV+yvMUsayHxlUwee2XOPRStPmt0DRZ4qbonu09b7WdWndgSpYB4RGwwgnR4ga9ffo0hFNvoTb0Fg3pvDvQEr/x3/tHImwCBxdEvHjS42LvdMojcQppCKp41zX+xY1FXhbvQsWbFg76Dnk1wti0/L6TmrTJz64P3wNsDSB2gE7JuZKtdL5Z+5u5zLbSFapHQ2OXv3Oy5fRkl5eGf+ElUhvD1PMzyE4eszTvWM9fNk3UBKx434SUH1qFIFslLXoVGhirUB/DMjTiF03zmj0Zf+ue8KyAFlWV+GqSTVcnlFZMkvgTiEsJPTV0m5fpm+Kwz6nci+r+F4FcFsBBR0IzXROA+mxTlq7Pzj+gw9bQeJTO+2i+a+Pq0mUUfxSL6eibpalKkFahlPMBgHJ8Ltph9qai+GzfENdhWFcOYkJgy/Uyn6lmJgVLhjFsX+SmQxOEFPhrxKyLyUcWPwPFSC1ZlYB7ybg+vSviA/gCPh5VWLkRgXmiv6SWOLBlPwdVsmusLkEKXAWyiNg4K9S3NqAtJfVFE3AsnquUVaL83QPnsT6pT3Imeb6w0XtE1xp3r6G27HCsvqdDmuJArl3VU7A3GwDGt63xnhxB1iXABivMyGqhtpqUUS/RjUk4Z2unafn5tMJNB9JW1a4r6Q79ZdiyrN/7ob1inoCk2fn4H95hif7+p2fABCAnyET1X/VnHPwUsHEa4GHWpelRXKUmiRFgL//48ZANn2LBGNc5VOVe4iUMtVbzM1DZgHowYgticRkTso933OsqHQfUjDqOdMU9UxsimE2Zn1Z0Xy9BBfpOiO5KlDSdtKOUv+CmlV68J9oVxdCg8FCxMskOXvgiR3gyY/kUAgI0qVqbZLw2EgIi4ak/Y7qE+BBaBtJKRPZ4UDtDXm/5k1NpxpAIbY8Yk4uKYnEzMbJLkpnLvnYo2BurlsQvMKm75vdp5KVF9jaG8/PlqeLXE9sSNwBPq03TGIl4ukDsRNwFiXrvJvHcaez+EjeuSVHItlhZZDnflzh1g3rDewHi049cXedssjHeVSA/mt5NjzX6+Nfm1y9M9TigTiGWf8vWRCOO3CLR6jRdRMtsn1hS6Ko3ERkzm7dVQlC00BvNKglb2va1INQQKzjMSCvxGQzP/TZLLGzhOd02lkqE9oZG/AH/jfih6Ow87+2IE6+N5SlkyK7hv5rghyP4sxcFSPwwlwOJygfZnMx3LeIW6qCVjSAQvH1HoCvJK4CGsG8hYwg9D3E4QtAvolSz56BK6l9xSqnGmlWIxJJoqUH5Ao1mVa2fvGNqrUbkDqbwcz8/B7VXDKsIm3tChrhRBK2Kh7aFa31t8/DFQjEkq+V2LWJiLj/j+sx38Kg/vuEOjnHqD5POlae+2nhaBUdR7uTnZS3Shxlx799Jf/S6s+OPgCuHXe3YmKHIWK/K3j3HfVzes1mLzIPgNgG/iLFcVS4Gdr2PCw/mthj9I9/AWlx6f6wREipQIuyEfPuNbdTZ/TbiUzv4aS/Mn2RoHPGFjPdYNofccUfccFlhxfDiGDT9dwbm3g5e4VZGjjv/ZRzFXSCxL8Nkrqu8Me4pxRtIbjxtfOQ9ZwX3njNuamdFGdxmdtcL+me4fe4WdjhhcdYB0UttGqCImgkXjg0c0vvXEbKsb0gwp0toyFvPuahdBIHEorpsgrsmb8NV9xkUClepq/sy2OgKLjq/WPNYwym3nTZUpttjPRLW4TucXzU9bXD9Pxwko25C+lHl/uf/Svib4sQO5lPb4Bp6my/1aSCWViDQsHCI6rIPkzfd9AD6z6uHIA7ZNcOjvHYL5yuBzOFew4SbHbfGvP6ZOitKwHdNnANSFu95C2eD94cpSML/zt5Lp6/Wl9WKm5VH4nRvyIjAHTlNGtrTDqAKJCJZnEtQNcewe3wwsFELWh2uIJdpxX3lUypUCHrjIWb36juVrTyESSvPyhHSVJTc3A1zTzP7Hqf1HrfnmFVKrZS5vFi4iJLvUOv6oguEOtWIaD8C/tJsKVYnnKTHpRafWISJTcrB9kJi+SKckkNxZxYH2KWuH3uG9sabtPOlgp0g0qsucJ6qP2nQ9GVBl0W0XPqsknIuwRe5l+HISE3q3kZxiqg+EopBp4yL9WIj2j2YLvtIKRJFZWfgIbK5HLq0K9tRo1AsqNw+IwFL/OlIrr/N2N9cdwdf1pmoHwK/c2x2WpatxosOv97Vt+L7SC45EXcWit0etkEDq18JqsCvNjRrzRe2q0sQZCsPBSZigiCUlkapgW1XfE4nJWX2IWCwyC/NZ24fsmkeK1YUfACUXhVDoue9uJ0+pgfR92ZIOJEcYBjqTBY6y6NcnJT1udUcmMyTymrqfj765Abkj5rjdbJGsnyvHtIWI1fIiVkLhA8PVSJ0idL8n2NEo92nFrRmOtpWUpiLfRvMWQuW3Pa/zooHEDldOwSXU6Oi9I+jpcluGWOZXxChRvEUZVd5QfYkUeHuxFPPhzmPtXOQhsOiuX99aolSXHIS0S1oGsShYIKv+JBuYK7hdiLBBpeexhTQVoEVanN1+xJkeF50Ssm549Df48uXQDFn2170serBEZBYySig5+0Zx+soBA0LjifkvITbdASTCKC76LIgP+/APf/i2SCAaP6jSBeTS1eqcH+ahGwqoXJkTqq8rnEitybj4IJvoZezDHqn7J7OKnr7ZNgJateJbd33JqZwr32lMRDmz97Cn9Md2nJqx2K4/fg6NuSfnUB4wrfRFlDXIfmoZh6PZO80MWofarg+FIqt0cSAMOZ2NTO1P45ZxqUMqPmc/UXbREe66Cb29zEcZ4MKSckJIPsD0U+bmx3XjRw8ECdn+jmkhscZdN4vGwtfqPGYGIxeagPU/2Brk3x7Dg+MRmH7videND4Pb5dpEGLjeN7q/2HkVM0r3LJovKaF9d2i5xi/zNz416gyu8Xj2VwIB3UyzwDgXnLvJB60WDDXGWO9385KJPoCY7TFem/Gwh0zIAEat6RLgtUBRzE3UiWuz2Z3EgQm2P/w6W9uH1g7xSIv36XJfesOwTPPA6wKeCF2cTRDsYR/fuLSlUyxMtMv6GqgW+SHTX4Ks8GKUwOnHK0rYQAljVC2gVcF9PUDhJiL+HNuEPSpr/p1WP0ecWS1IxYsKMmWH6WYFUkcmppcep9emRAHpzcuN1H6/kVvIJvrq3bj+LpEVH4d7nApt8/7DTbjR84Xre8Y0x7hPmsCdVUtpK5aTxVDCDTmjT99RFb577besNcWpvy9pdiSxhRkob9rpT54Meb858q7MW3TWCg61r8ufWU9lk98OU4bE6h5xKmuhdKF4XRkNPBuh5VfR4+GE89QsJEOZ/8vmF3Q/mdkY50u/axGXIWykRBQ9NbgUKK0MJSuXnERT1rwjzF+XT27q+9uY0KEP+EF6JOVxRWybdJlvXjF8FOyA6hUjuugwZZHyxQvqRi49jqfgnsLUakTxRFTj9ig4na32l8JpaSLg1svjpDtwY/dH3QFHfOl8obFGe9ZXYK1a9/4di82znbyJfb59zYshg604/MCMXWV/n3Ru9gi+k57mWNtw41ivPJeehGzhd0Irhj+JWLyK5xC4hJgmYAEjllqpdFuBETXqZsrOgL/YxHJEKslxeV1i516/G42qAVXs+O0dwlzYUUz+AUpjIYWlRkLv/L7LZy1cFD68ivW5sRjirRihUfGwuCjutTI9i/tB3N/57ZoXT/XcU44O8UfGxkX3J05+epHlvfPpmlOJynzXWSvZBARAEsvtVjTLgE/K+Rc8Dnd/hjq7dACnmvSxx5GG+xYH8kPY+huZ+Ao4gt/kvq63RJ+20hMj6DLntL58mnktmQnPiAhE1xN5VKeG5e8oKy4MgCp4hLylMEBJwCyFBOJTif3eE7ceQud8ODbZy1kwAUhf2M3wYKNjScGoj6tEKxdWH9wXT5el2ERXOeudGapUnr1oTkFif4kvD17ixRXdyc5FGvdHULgEcPT3O6yhXgUEHymDZ0AP7tx/bZ0QuHu+T5bZmtN6QyRkP9IHZtTUziZv8kt6ImzwyhFX2xsuIOz4p4cAr5IXU2xPZCjCunItnhKH01BcmCJ3N6Gq9Lev5OnrXsg8exLdxuGbUFegAFyFEMbqjCjo0AsTzvFJh6aTFq8nK7c2Ohg5u+yWYHpJAJmq5Fujdum0oVkr2nswwnz2ylEcIDvuPZxIdHw5KRd/qG2sm1HbHviXVDlIoe97htmk7D2lYrV/u2FNbsI1ui/9qJ1oUu8F0bQUYLUtfnGulyycaJoIxbPP1RnUAO4O002K+QK9Sjm7m4MpOoRTV6I874HNY457iCusFFrLCSEju6kJibWk2+YzO2oTGIh9oY3DbP7AAvfx+2ZaEVfzj6g0aGKKgDa8ji6ftqpoODbcH3Qu7ZnBhyf0xSnLtaKZGIhEuFH8OpuaoadRflX8JR5m+hTw8HOWGF2k45fqB2eKSVlcvdEWcWzy28oJ0kiE8j+Ryd4HrM/IjAtJF/c3hTDIUXPs4+ZuhfsCFHqTUsV/6LLWPSb8MdOhIpYEOKx3cX8cC8whncPTE4mthCAjwzbrLacn2mqVn6pgGxpy97UT7LLCWQUpuQ5GO+VOwEoUST7ibybMg5MPBcFVQjlKZ/1sfiesPxePM61rWAeMdIHVgC/neeh2v5dH84ZNVJVp7UF5gDI2pbL5HPGr5XDsOJIAshJHnt508Suu0EyYGaP06mLTyI3U9sjDGw+uRyHQhi4HET6kJuhgXq74YOZLEMtXzW0mk8H7sDBEE+lCw7shVYfT3Mja7bmIvmbH2LdWumjiZVbn616HWaDlNzVGbnQTTA3h17bNrI5T4mqGQCPM0IYajM16QtxzO9m9it7kMWvgJR2TbnYAqA+POzLwoH1Amg99/bAdnCZZQbacZaWa9vr6IQwsF/dn+ynaG2dCfV1wcer2NHgjEgUwgC5l8jAwQXDDf/50IhQ4QqfdmEVMTLnJZ9YeHMjtfHKEH/qQw8EmcWtdEefFHrRAOqP1O/4myXB7bl12vPEeukdG7F9VHF/XkwA2mPp1AYIqitXjtgPuCAdDGesUaWwj4MuXiKiIpry04yiQ/JjqNBHcDDXvmGzdLu0qIyA/gcXa6PmY3NQD5ahWW40YwmOg+URXMIdOfSyBPIH8jAtXvjkB9p2IpyPgLYdfWAKerXh9GDq6ZDRO80JHz0sdBaHRHnTXpRWPJILRv9UrxSmb6qWR7vacOxBurD6vwrMPFNuW9zzYMhmJ8cce/IxuTQcIXwh2Quoqq7iSG16dae/+mFhNORu8hUzQZnx43ASvBKauwtO8whqMBtagLeYNoJ2ArEnytOasyH+bG5frgN9EQ1ZXUrvqpnZOIE75Vr3X4ddjXsS/fi8uH6IuXWtR0nvWa9NXMaGyidR6uQWyDOSnUy7F2gVJ/qTna3o8oHuBN2rfv6oYmmt9mFKS7ttNjTeJ9axZRKu2o+PM5jsNqSlpOQSJoB1eigbcTDbOSZRj2NK6OCo3Y5Ws6GtACNt9u9VINYXTYs9NLMMgBXLscCuNejl2VoqMvR3dLjxu+aqBSbFx9rr2cTt2MM1QkcGd8FLDJEAhqMP4lbi9MmfaDRou3nAQShKu8bQuocBDjksXb6RthoULQ+e3JVF/CLAaiGulh+x5n2ZOfHBAcnowUd+oIxjwtmMsxOtbrkyJzA8nUROPVaxwYQRPaeW3ILOIRymEnabSTMNkpirKhJwIqaL2gXtlj8ga+gPXE4uIXqfmWk31CXGQevqH/zu1xIZ+GW/mWtKY3Eez+I0pUZT+uv6kOnmb3+nV127ZGtweon0x5NyeDGOyhvnecn+8mPcnBEUqkw5pTW6k6M9505eyGuhtffBilvLKmF5SnEZAqOb0Dgzb22TEC4yxIe8z4ygr5TlOU7tC67Rfm+SO172EzGpzHXg2Cfe4Z9NcOa6AKRIOnI1pWomdgly4eHAv0eh7gANf5kGV1SB0I8oHAtAX9kHvrmo86aEC2crzK1jGMseeOxJm68NaYLqqOvAGStgsTb5GylC8vaQF5g6qaybBAj8/mPCBsChSgpHbjFfsxAi7t2LV/N7Rlynx/PnZnntCFN/40V3VJcpBhb12k7vjG1W1G9cRp93xi6YaFtjtfDPekbiAa1SCt8u0L/i6iq6gOBpulHOPb5Hai1dKIl2Z/dVeyHKGlLE+CAGquR+9rNAowKFOfPrmZljo9zt5d9zTETkM71Xk5ONiYfSvN8NOeG8NuYrAZqgfhIKREEdHQwA8s4ZR2jMfoRZ5FR1t4DzUlwTHwqZXjP0EPVnTomfjSu1ytWo+eQS476wBMnFVJmBHYPj1yyRj7bQTZO3sYN/sjKsM+znt29vHzg8kCgDhL9MCSmlcJYlikUsqynzsJabWUIxEKhOR/RuFRpIvZ6I1iFBVddZs5EeLvrqclnM7pI+YXPnjuFGcg1lGzuU14Wr9gyD059vPPhqP04cLFlRpEb14sEp82fPti2agklwQgAq5dJdQgZFTOhe5vG0+Vfnx8W9fNNgfN82xClkyeD+qysfoVm4rvdjwNIzHZPgQcImMcDgo44sOIePcCVM6FAEbzIzR0J4Eo/h55xTdssq4psI8pfpm7YK2IOAcUnqzzLTuMVcVfo0JRit+E/xBQl0nDwQtdcJknp5KoCC02tksfbRB5uXfKApVkvYflhRV35qEY3NDhcj+yD04n4vPcnsMG4qNVKraB2e7whHPE77ey6Esegpz4isTGSJXTQuxjd4cCkPGmTK0BtfbJOQMcoi8G+XzGtZN3kXFJJmXDDjC2xCTOy4PuzjXkdrDxZ5DHj61w9yx96uWFk2m75gd2ONFIGMFdR0+AoAytK74+gdhju9GvZw18t37v+zGDA+BPQ5LeXU4+Vl02Dade36ytzxBw8RrUl5PBJxcs/XPd7m30uRlNyWHSOtkicHu7KLBxyhEb05AVKFmafdr4NgZ7I1hqMZnctfZ5yUt5oZPge7ho9QV87LXm0McgvV5HtXLbUNo3S2lQZSUSV7lwBgXre8hahhRWdSMjjKIMl7qhjCJ8BoGQpcSxEA4OeR/hcTdqAiCIF1sKbt5Fy889PvVbQgc93kPvzPrCWJc/T3NSEwMjkRz68fF+XYY5Tukhxbx13B7yCql2t+soFLq0FpOW1fxR77KGh/Ke/jlqbbe1j46ce9FEbg5Mu1OCo+J+Cjl4CYK74e7oLWGNbGfTlEkyhuVccfSqAFDzHYIuKc+SUojCsZoKvlxNaYrLMcr8zhgs3N3o8rD6bVYdPw0Sj+U5HHoMztHvlQ1g4wRAvo+/fmdQsrPFpxKTx7GqX3iNCwMfs6khRIHyeBvujNyDFrh20oYWCjx6ryeuo4WxuiF8YOCO8AThY58nVnBrWjB7935k3KXEVpwOIruiF1nuTGdMDjZkf/ztmK8JqjCk/YZzZpCczchqkbiVw0SbrjTva8ppvfZzSpmVmRfVN0pGqAIHVrkb2NhX3/E36YvOe7A51IdB7AqGBxa2/zKfmCz7z+QuDI5EvjGs0m5rHyIeCQx8udZ8qLvNJ41W5DCAOLQxV5JLF6sR2qfkJSZun7GbtDvWB07hAzWYda2Z/FAPxD7mwpJbC1QPvzM3KKbn7OIT9ExIRcXHucjyRlcLLuaZYWCb74voRLCyS0yt3xCWvxI87T74q9WWtll7hwmea4VsLnphX2EwjLB4iStIHMtUOSH+V5fzqTJnLENhg9hpPrmCr0+jopt01/+vz6KU9t3vKk44eRHlbeXwQBXmwPRoDSvGlQOYDd2TvzxxPScQD/Wc0NBcDNoK+/G11/6HyrHDK8zUIzl9FF6pgBXhipFRT6t7B3PzyuDMhtl/yZhP1Ea2MK6WjSGHATYHQRrb2QD+Hw4v1FX52tX2aNjTNH7SzC/7tj0djtR1Tk+mx7F071ws0yWsdq5OMTAHhH1sI2vkFWfRaFMwK0XWnXyyqLzaCajHzCvDQ+xB4MZxtOk6DbSbAfK2vCsM2lQiTIz3zOrDQnfd4latB8UztBvI/CTTSL8drDZd6EY/caX1/N6Ocv6KvmzwLo5UTMce2Hgpv8YHhV+dfgRaR/RNGiiHI/cJKxVCDb5rXmoAjOm+ZbKMilpo4dtZ+6eIYgDgUcO42WWQlWrHwKioW+CWl8zbTbwdQAArty9RffpsV3DHCRqKDQ9Xl7NdqEbQ7twNSTsF67nsoFZp0D0rZ+9C2k2v+30uqNgqi0BSyy+BnUMw1FTZq0zGDl3Y8D6uqGVmffVCrIhTRBFlfsKrwDoL8aOM4RFbgegYNcvL67UWnHM94QJCol1vcS7RtaGWzB1hTMMVcUXqFWSPuv2Vige+Y6nkMB5nzHVbNF2XK4sWkIMqIL5mEL/fKCNDJF4FVjUmMCirXd9nKr9PUZQSq3/fa4NpahDql/6lg0JTIB/SHoHJrioTnQO5/VFLu5lQj/U67IAua96jb6hrtTlWpVT/s5qXB6ef3luzBrEMJJPhPwefmXc1kR9GnQcBe3gKq6Y6efAMdy9iHMaUOOX7neYwpI6kbvZ1OfmfjdETsCRkeuWV6QIbXPv6t1kaCdKnzkU9VM2torIIdnnBNcmuQ44FwC0fifjHJtGM0wgbDZTyjj207lpIrqL4R+620HtvfnlFohqkfm4UtOdyNMtbIG5Cb4TXDes3wbwGJJLT270s3CRTc/N5Wf2hdNUrjmVjkv8ouR3nJV7nWAL/Lm0iHuje6q91gzQbYMpeYkba4nDfS/o56aw4HBuiz4SoOcuGPi9BtJn02JsU/R8esDZi56hPerHq5Mq8ErOAMyamFkQkblxpvXgt38Qin4x94H2aJcu2uXld7MZ8eVQFHWFljD56EPK7ekwMfG1TEgfCG386vxfuaj8RIW+htotPmjuGyEz+8M4QnAx26/XtvCnTRw3gIcr90sLFednkMOL1WUVygP/yLyDwcDNZVvxfKdwam7WAalJlRTnt/gS6RvmazZbXcEsOB42ynlxRCPDtm//fourLjgEj4m4/ca3I5rFt95R10krH/e6PNL3bIWkk4lg8y2ZfFyOC6xeVusQX1vDNvW7KHm6iAVESpiXYOY3L78hBY9s36XevhQ9v5lnHMKtHVqD3JAVZPap9ug3lcvoNCqil6fmvzvND9JeVGOMCdmiv6Ofo2Fuu95AV4rw0X19RNQzetHEbhKe5+k8J8wz+pQeCKFbasOlCr+6akmdKiUug33oX3oMstCzJF2svfwTPKDnluuzOE0HJaIws7BdjYiJ+TT150gSt5TKydmJG3ajh60bv0NczVp518/xHazNUHufiD7T29U2v25iriDHUleiq1286yjRT/BhhFPiOj65Jtf/PAEfseMxNzDPeUwYLAExHfFJT7+IrtJ5/Y1jucxOZUPttsoq7iO+BTYteaIrgCzZz4HohKgfgo5pDSFOsYddSVU1uLxfkRtQKiD+2zUTcDLEnQBixGSCwIM3ckKTlISRIsD3QphlVMNa5CN1aL8DxofW6qrb5+H0ED3ZnuQiqxL5Vs8lRmnT8r0S1ZrrEzJ8WLAjShoZ/3T5SCUHjArmp1mmgZckafN1muT7uGc6nl9njPac/zo/Uw4F7ik9T3gwVnYzLMCcOL0AQ9CNZ/sqFV1ud6Cyvmm9VDTdLFryPPT8C60QmCLRGT3XI7RXomB99yOMXAWQsEEnQHI9H8nYMpSC4RgVEARfkHBXKdvYJm3or4HRyWxPxCFk7QfAVBBfKP5UcGbzpQ8CK/AI8aPjmq2ShqNRUt76So/wqcptAwfzju0NXcHKPrevAOvpOU1GvxhuYOlnxuk4vbC3uuXrj8PbZeo+AZe9m/36psvHut/k9ejDvhYfXlEXUHdWtUOXpM7lmnu5uQ9ARIHcc9oRo5i7NeX2CEuBDbXVCcqOi6pBT9MTK5pXph2Wzb9SksGWT2oS6UWGb7bXK+4qu6QUOw1zJkMdlXCQaWohOvKXX0+9rXy+p3EjWRzHmZmdBB3r1sKNhwKH3uTXgaL8upypPb48EL68xQSDLYw98eYM/hRezynaT2/YO6/lFYGvNozd6UmVbu4QAS0CDYKYVEsAHslYJEgYxWlAghLyphPquOB+8XIcfgT+V9ONubzxkJvQM8fs8vZJUze83U0FcP3jdDF505NjLufUGdYGwXlVAVbT1FfFqpvhDe1xxcljArmGZnm10AKMha/CxUlDon8YRBiwy3fBZfM+B/OB6HHGJ/eOsshPguIIGd+vswKm+jldFAnBc4IwHs7n63br3ws9p3uo7xe4PrnLE0rpan5HhYsc2Bt08L28PfB95Jgy5xYG3UuyvF4NE16L33l5Qu1l/fk8t0xR9ZJZ30h2JJ2HDw4Ht2HE4lCH1fwhsfCa1hcdkneoZIv+wsopJtM0XdTyJpm/T9Fj+VGA7uyMsxlPQ+jwKJpAReDpwOx9z1uvY8NCW1ZRq/9rBsDtnjZrcSpxwBcQwp4XrEQqwW7OnLSr4hO00fkxM7BYghJkar9fFM4dhalGjNmyi4zf62Rb313N40z3zqx+sr+3xVH7jqouirOgu9lzLQ6gZpiGj4V0oAX+Syd16z4pfXwFpW/0+nNRGPJUaYEhpCK8qd16+tjW6nhnUv6vvv7P70MsXHGEo6I8W8OQVYEFeiuuAa5ydFmHCuryfU7E3nqkDkev8bQtKR6ny2GCVgmZIILjWs4L6bk9kIF2CAMyvc9SLzbyK/JE/Z280Bg5C2tQMVixpxAuJB40adCcGXdjZaMsNqL+tXzPHklCbUT45PfWLzDZrvCtnCF+rHELg7L9T+mwyLNMmRxKRfD/wf/Kq87KP/UFJmQ5ZMovd90oAL4EAMn0fPGMy4q/fpyDgRS28vpQS4L0X6II36QL6u+Xno/XfnIRAxMN0wIIERbuFKgedCH1ZhZ4ghTX+sBEMrBWLR9m+SW/rzTO+MSTbFZI6T5XOtk5V3QlN6bvCw8qwrFTPqnQWqkNISjHTNEdbgC6JuRAzpBGflpGewNfJic4QqG95MjOgVFIPb+iboZyCozCEF6giZsxmxBtYjEkeFWCKtr5YwMPL1Ii4+t4RqWByENEWP2e7nbhtD0a6WAT3xNIPE1OnZnYp4ZGAtyvEvyXtoMCGAZDYUUpLQb7vkVylhbbA8Vvu+zWrLfIuuDj9HO7mebJVS1EYQ8da15I+SVknxQGbTUZUv9Vw3Wsvb+xUZXRqRpPqAs0rTRN12bKvZFGcmRy/mCI2A1uvavvACPb+eRIpk313rUI/QqSwgnX1G8YUGOHjhh0xgF+blTyDEul/Jx4as4twzbmrCW8nvmoppxFAnfLToYpHjb6krsjQCPQf+cG27d1e1JwHmb9Y7JrDCKAfxqp3vk8VUWuUopvnhYutBrtBT9a10AOcFX+u4PoCHxheX+4xgpNbIa/DGaCoUXv3KBvblCmOMBy8EfTwGPAYdESBhLO228vp5rIDUq8FgjpSEAVDWgelCyevH3HNfkkhraFhSfEKSf9+xAoeYje2jA5NGIF1tyWbYcWycuVjsLjBputBZ75jpwbgeEtCVfzSav3s10+C/eSyemh36hAeHc3i0p0TIM+cpGMi0xFw/uIIELEfUN4U7OOxBWeRt2Sw4xU5lgRWhplZO+fpiekQlklldkprh2SxPOEfkLjaCP1jeqDkYG50VeA0cpCpK/rJlctrLnM0wkdK5Rzj315gMUExtFe6YzC490WxxL3ajuYdrhxvbrDJmBjFvM0h3CqXtgG3B1GNZGfci9QklWHoCP3tq5Y0b8dITglqYihiCjdqM6/XRbjyAUf+nfaN3AimpG+uOeTsuBaBdc/bm+1nQR6O4iCpnGYZFHwNClhTuDXjdoFuzVWrgxIVtH7b9NWaKgdSuzzNJsAKREJXi9hPZqDaVHXSr2z8yKZkm8I4g5V/PJ+/uK6L0a0Ff4G4vy6TWpxCdB8bfzxELq5esKnAwDz2T3vsTDR7luTNekvrTJxZ/1Qq6S5afbgnLOJl7BwlYwizCFzM7uXouKyyRXeYY4OpQ9wACTSe7qOb1vpSOX20L4i0V4cmmiq9shPEXBJ8PxmiHYj7xa8kbT+GKo1HTXBv6vEb87Q/hr2XoKeSQP8GUSKTtHRiNDtbSRrYVCytNtp87hXDl9U0vF+liX6Jwj7n3/Ij5TPQcSbthCFL3aIXxg5OHu1R4ypDiAzJfkcOkxRAFhunMDrlOw4zRSb0nEM/UEinw6rCfD46vPDb3TKOLLHgAD3OI3Oxcy1ul/7uCpvk74MOs5h1x5SwetQdYuMw+ZG0w1xdlx5Pc3Djz8xQOZxpBd2tP75l5ANvjdnjuteaOgHit7BiNYqfrFlJ9N/Wmk3zElXPvSCHx8kMNNKZcVR5VhgcG8j3f1dJqw0G5G1Ewf2cWkxQFHfoaY3o73yi0+ayvUavcLHYmOzyioVdvYbrvTQz1N/Dcmefq0a7eI9DUa6nf5JUeIWw2wInaMsbZKxjufnPT3WXplGKviGf4NvkcIZKb1oQtqG7Max4H2DCDECQDzPiPGVx0OPeLv0blv8NeoNxDJPtv1kikeIdT1/evVRNNkHvmM7SYzVlwlX1zawlzwqzCc8V2xMFyu/4cAb2acq4kzWVwSD+5Xfpm9SwxpuP/ndvVw0Z5OKuB9aiTzBfhHJItxo+/5B7ONWnRjYnEFKVJn88XTFWul3F3D1o+c6t4qW7gF0UhqW1fiSquKckWteMv5RMPF5qBXIhKDt6mP5RKKI6+sGeDeBlb36RxgszjjEY/L9aaqaJ5W+PxmYUOq1FIMkkvP71LHDHIAzbIM4C62ElQf0MxdsNUfVoXuAqHUdArE5CYp7EtmwR/D2vQAFXJXyac8IxR0PDDVsFW6PJsHfeHQIuFGo7W1VsZB5H8BWuTCqxh5R1CmTKdBhYtoc8vecbojtUYL8vFc39OMciLhy86jFLgRUh44lOvaO3/tajRTbGVqurrjm+8qkD6BO1piqY7NdMd7UYZNVAV/eHmB0CHwzPGGl9+8cw5ayYog38pu7UPn6aYz3H4628NQ6rY9WcdvKMX3GcLZgAX6zKy07e6C4ZJgqgkTfvrys+PXARnD2MLS/aWkqHmtzcGyb1ksKReYN+iUdTxZmGmBBX+BQUfTqxeDHBRs0yZKT9gEtVEY/yhfckC/19CFsNywUJE70bQm+gjyCeUe0D1RLog8Crd36bGcWvun0TzRItB1bLv66+vcrr4evLK318tP4rO6FHeHZHc7Lk67xHWE7LKuQSBCM8MlCHYNrZ+ooP75alSBAJ6QoygkRJUBpUkav6I/tNnA7fpKIlbUOmsGKTj/HYTC6cInYYKHlp+ZCOoeMHt4c3HMtfbEnPlZVJC9DD7y0EiLySUFQEzdSB96pcshihpPdAUv69rT2tkZ9oFQmt4cVw6L+F7E48huinGt2hMK2M/cePAH/rQdjw9Nv+ppBeJuwzH+P8AD6jB76aKs4YXXzKy3UCkLrJT53R4aKs79/qXbAqZm9No9E09n8uOmr5+efd5DilH7npnUgAGVfqfQ5zB72s0y+pX/sNsEaYfHCwz0k2PW20U4hx6rs0Z8uhe1zH7+QlysU6aL44EkYh7WsKfI7M9Pk9sm9sbpyc4NrJC/tYHqkRLk7BHjfxYnL4/WzPak4ULykxN8Z8ZplchmcqSf8yiHHbYUyHf5qGdccbALHgILLse+bf4/uC0OAKgCogNZISK8agDsYJHZkTc39u4fl1UP77hECPS/Z5Yh5QVhJSJBDpX6fwmYTxCbL834qjdKxcHWmcRmmxFV8EWO789EPrpLLoBNN7EYfzPenZfE7DqTUCKlCFc77Rr7om4gR99gW/PhtIofvjh6bik3ANAH8J74lv3tsbs/z/8G5eVyTtRmH/+ACjtyP/4PdoQjZi3ktzvva/RD9uzQlczGs/+cSLv4H5/tTLsa+WOfbuyH/nkDAA7/gU75/jynq7+HR5Gv9dwn2VoWX6qKp6n8vijN/15Ll73H1vy8Mg+Pf28EVevLF+/3fd//9jCFN/vcc+t/tJ++t+Lvyd2FZv+9/F5Y6meCPTZ9U93fu9x0sU5HB+4BDkPz3Qdmcxf3CHByNJkveRpIWb2dcmn8Dlo7rOvb/5w/Au6ngL9Zxuq8u6zx2dxR+j/PvrXHk9+9/f/P6Nx7ofaVs3u///uUwDvDGqjnJm3vI/5/L/+5byJM1+Q8O/h7edGC4jZ2/KYvtHYguVyOcausR1GJQ3T+F8LEM+JsQAMC3n2TY4e77z196g8C2LxuTVYDmKRxsHEL3/afqcf7Vyg+4A++RMcdB3oRLfMRqwLsjP1Z148KNQ6B5CP2sNVc3KSapnfTWlMMhAOhHJsJhfxvbn+mL/lAbHZ9jJBrCK4fiajwDxMHmjY2Lgvrbp80Bpm0Fged52zRNVVWJ4ziq6v//NaPpNkWAuxdtGZ6EnDk4Y0tfEiFsQ+LPf20qYYw1+Cwuz7/Xabhq49lf64ZBYBmizC+wTUOWUK1U4KvxqtcE0a4HjboAnRKZlbC1GlYSnUnLy/Z84cFeS7IsK2LuwZjCo02549zrdqqSGpBuin0/XmC1QgIl1NGbUPb5vOkn1pPt+OubDp2yXEGwB8Ll99kae1muCZY5wFRXm22pSRR0+qTWSqMr/+zXUX8OT8v22Jn6TjHc7iXBc2ckTasMartv2VNcAzvfP84GR8pWqUalbKFS8AWrt7SL4UmXibyNIi7v0ee11sZtbjPOFk5HDFw7cYg5NEQXCqi31jUnyaFjQgvgZ8hIvSvB1jFiAGIJSbPOwdMS0gF/fDYBRRau1IM+fVkXu8zXOpnggEeybbUY7dez9X+zt93oeQ+N5mDKixTmB7a2RtSTn0S2aZQNgw8hr274RNan+vpQg1qb1Nav01XPmZCvng8watvm8bMLWzvIKcD/rKDSx7TF8vtzSv2a1B/BNuHQfmLp+XpX67NZsg+W4SH6Ttpl+fBM9fFtLY2PmBRXap0N/kvRxSlGyrYyAz5T20xwojnAaABTmaf7Zzf8qH9CHqI4fFQupUBHh72R2RTLFpiUMCimO0ZlVDNyVDLq7KN+/44KuhKNuhrNBl6ImkBCiFLSVj96GkjGVKi7hAb6DF9MMAi1ShbXXAcmxjI++4YzINsS1JGcYagjJPykFEt8D+qaX82UdoUfYSjYCFSQRn7hwuz9eFxSToV35KauHuzui4FcEJsDlM10DzIl4aSSnlvoGMGimYAL1vlZi675KE7ZR0hhczTUxiLZqhYf2qeejwdRz9EL0/Egpe3lqcGl4970uloZpcic+F4Lsii65LFDL8nNirClLxi6MewrbaT+0NOCD92VdArwLq3blZQkbas2C7eiC+mBUvy+0B9a7JFnJ9jD7ZN/iQjaq+v6tJgHtXrfSvrSNyLEKK+STi14xs/UK1MknXDfIv1f0Yv35GKaw+niO89yl/LhrKOsfd6m79EFunr1rMDPer+ys3DDT5lth1lbBe/YZ6zep0+tZ1IRvKjvo9Lue0WMcsNnUt5QyM7ZLG7X3NjOOcH826bx5RHMcfwwf73doaXcBnnbYztV6EmfdPdKGOqGgvShCTzsw1yLseGuboFhLsVwikftTxrZHHrGnzcTUbLhJl9+GMkffZCXT6pShftm9GBuAy43x9/GQjGIoiy3ibybnoiodmuZvQ8NXWGLBRlpFX8zh6AZX8j5pgUkM3IHeTQOhWIMuj8NXVhhaoP69ewiQ34f04dvvZ7P/l37x4Zg08FOoWzmROXdY3+6R7Y6nBFhhx99Sl2MxNxe7xhwNNRw04s5jkKrCvYKo/IltbvMbt5jiq2OWEeDMTPXFums/X1F7IcsKn/lhjbuH3nlk/wbdUl+2A+ZLLu5lbWA+M01QP6HpevaklOJgb9EDo+EYcgZBuaNnHPm603P+px7ru31eha6pVKVpG4FLEdurN5HN8fU27tnfRjbenETkOT9dSh2DuIvRIpDEeEg0E2xZeFP4Pq1MqvuK6A6Ez+bktyoXiD6/APDI22fKzhe5PYOmFIkjKT8QepeZ6bU6ZL3tlcqD4vUr6ehwcW3ljwxBiEY+HWIX2XP2zHsIqQrWXbCYWxQKoyjOh/MRo4nrPwwCMVtv2vSDUuhxIftY71Xk3nsOCa9Ix+552HPCDoClfBoK1qcC5quASEgyEqJ8A9CmsQQgI0XlOODu2LApwUIXr+hOJTZqKR7plU6X/oqVMr2yYmjHY6l//hcqR/TNIzYeVCG+4O904+i5BIDVu1DOSEppr21Xmjx0Pu8/C2oZ7LZZNBvxOrQhyb7mfYp9wgmuk2suvTorw9/SJrbAg4dgscbth4h3E+zFjWyhna9a3+xZeez4ZXFcar3iMx2uJXB5HTB+EMSnrhUtKE/Ruc1ddy4yE0bXJTXJjJGn2l7K4uc3KMivbfSzcaJZ34py/Y7SyoVs1aA58JMvGoUz1CuKI/P/gVPe+8xTe01CYEqdjNAN3mZjm0ywqCgbVKtEmqs/Bw6VNvjhrocNikh6f6LYrpR3MPu7Tj0TgX2VjufXZM4qmBITdEu/j7UnfvGlzdlQEyxcUE7TcgFgxwcEmL5M/cplCQuTUvO7paCZQLS9ZXI59EIJq1ep9zyUtCKFmnC7n5RFbT1uAWMf1DRemd4HzVzS20dCp2u+IuDQwAyFjleFw/fcKTx7AZ6IgPr7TTj18Y4XPgd4IVkt8WdbH+iO9uDsdkBR2jRqt3sW1655ssFoZKQW/4snXwlt2K1306hVet2Xs2vI8K6QcaylGhYd91dWDOXIpVfv1zZYIasDisWYbThVYFLtmSXxfZ8epi/jSGpDXOQvDNRPRHR07dlVI7x9kwMh8ENJe/0vUErmQKaiTrcdt6W5aJ+5Jai73u+Ui3zxp0Oh2py+k5qmpxe+we3/e+KthjXr9L02k6b7duLZM3tC1G/yYardfaAzrGslJhkou3mb97CDARdVAByhObaTRDLblKGF4BOS7lGUZSUg19uxV0S02TmuoToR1fwt3SARosWu8jIoD8j74OqrIpCDnlsFamuJl8l8CMaMRkAOFkn3svzHeorWRWwcUWBbgliwgZMTWfxtF4/7tLA+dTFFohcnKOpScBntgU9uEagjIG7b26XWj9o39PYYZ4NsuzsxHzo1KAuHvzJVV2ptSgiRvnil/auAX+1bjgmwTv0v6kQUJjv2AShwBqfBSXjqsyy/Eh1M0449w0SneJZICb1FZ/wAbA8+twAUQoZiUXqS5LkzY4UQ28oXXmUk6qKhSlZPkC/VIscNwjxsWWTIRkUDhY5U5cnDqKx7m0eSPKrR7wAzla9FkPZ3vX6YtUKBwHIf+v6RRWyq+H+YXtQUihuuk6OsJ0OzQ8xxn+sGXYvWh+n99ESZua2UrcaaT3MCq4V+SmJ9E5NmImNaH/WMo7TeNMtOXqsfk1QvJns/UDhy8PngEXArib2jiEdqXZItX2cZW0/fIc13zX1Tb3rW+DDOX7UslDXaPuEzaoi5BtIRpa+B7A0h4nnb3Py0Omdyzj01+ngkJH9edMLmfFmlo8KsM84ns62ix97NNr/78+x+UliK4BVTLjJCOLeGkTlUYc7DijR6MmSKi8H6V8jKD5wOFdGkWAzY4dj0/qVEeTtCE98xt+jsTeyDuNO4J1UXFRuu0NLclW6Wk2dIrcUozcZo4+G+YWI/FDfz7s6Eo2o5ohTEuD52D4/9EcYlg86ZDJGpQVs8g8QDF5JOK835wrnxZR6qdhYIh6Aon1eJwU6O56g6bkEaFigs3rWrZplYkKqLVL8iC+u43FYK/FQZ2nTVB+aR3n+8U1JcxHLAt1s6Zd8retn/xk/2z61KhOfSxodCyJA6om9IMy7RoV1kfzFB207ndPowpzrIe3QzW06odHjUmK781YDMkJhGKktvP50KkuemR6Vx8OvWe6hj7lwggrfTnMsv4kRAk9jjS48jTvjTKzggky2VuN8J/oNhTbFdzfX+DoZ3sFuooJ+2LjeQsf2akvIdbfDuk+aPT+l73mvS+TveDG1af+/5jkveHPfmxd5ndmdIHEKpkyxudmFydRcdoGkPOdghRuGhGK92U0YwvZ88w3ERcabTyKrFKoXm/f8B+PTAaVyGsBLypDotrE+iu6D6QOVBtKEYF4ta34e3iI+DD5b8EagSF+8ddNSiQiOtsOMfnOqlVi9SX5JNLGRv0S3Jvxl+K640o3SOKBRz4TUCpW+tGB/ZWVTM0mMbHsR/EPXenCmcpoamQ/vT7AI0vi7ZRAX2ps6MI7+cUclT6cPtDIbqaC680t4zbqqa4qQkciw5HN0bZuWVSrpMbt3+8o2hFMUK3b30Pxnxw3MeLzioRG1mx8obz5+/PanmyfRtgk1ZIDsAQqL7JHlHT+NUocBGxm9W15g5tj7O4lB2T7QvzSFZFXSc6STC7ajQRBYfVZFxBwA/TeejZHGEXQATdGrwRtzzMEYkBeLmiOHeT56lzK/dLIfWL6bWsdvN9l9Xs8zt0nvG8l5q64fdozJGLnePphczz8+wwQQ/B7XCdLVqJDIO4445F5CEn20JOgX+P5vJDOrn+JydrB1gYbBNPGGHyaYOiWig5yg0M4ye/LB4PgwwJRu4oMKp/AtbUGaK0vq0W2guwSw+RuMCr5o1SbXAvatqTh3swDJGas5Na9WKsk5sFA7Q/cMjyD5tZrYJf4F1ySyholNjV7DG4zFb/hZ3pNZDzhyLwBxDshVxmi8449mIyuLM92W9Dr6ZLai7E1s/XsjIyfNgn800xEmpzSLOLa5tU0+cU5su9K6uqRYpF+7fimPidoCczrm3jrFJMiLjSUR3kK8fWqrJjaCRcnwLYn6gynquFMZh+Tc5Mow/fYdkLhMIyYcJrZfYNViHRN1pov4XmYQ36336EksoINDJLRRd/apWmsio3JhnLQtb/7nbbY3cqcUgK1kRwr7HB6SgPEgySgIgvdiigIlCdQ3zlhr+Eyc62y+Lho0LyZx38IIti0tjFO/iy2WRwg/ulLC20fQChLxygHM/G7T5GyRJ8aerHMfP17ZVD1Sfs5ORGNGjPuYATAH8D5HZsxlMCUP1YLsLC9DpeolzIeo6QmefYj4bZcsj37E3p1oKdkhYts+KmqbtMiH3WG9iMPE1lk0vcgtIZFVMNzEiN4EfMxElin2dCDwSbUWkJsrU1M4Qx5kM5/x8A3wrG0F52shbWzG+4/k73vcxDwBh+feY6dZgM0ydyL0/l/EvfMX9bITlzk6175M3FKhDvDSrNQzdMckNEXQfqDd7jfM6rUUySdMFezxXYPHxL5Q8c/CmtKVIq6iBLXiYZz8mkuedaqf8AKk4++Xg0JfZ+MXR348jB3U/aLf9OknvuiXhjPz79m2vmLzmSM1onnvgPIgbc15DaTnHyQPt5dxxB0y4WwY2MryevQXeTQimlyxOB8exsg4q4J2V1Ywbmj/Blt6R3DOZQ4YPiRYr+wrawhVpNPWjpcLOCTJAyBhNR1F1Bi2H9PUbb22B/j5qVJVPK+pvWvGEgtN1JzNrJozqGvk4wMQINiJ2g1PIMV5lbMT+35X/0bIqGIDrk4pOLHvaljUUo+5XMitVyI2zWKulh7iByU7PQDq1Kyp3rsr/vy8bEwTwiWgZABmV2pwetmPsSTRszU42HbDxZCgCf7doxX9wpLPgKVNc8lLSWOfJtpWej6que9g2+uBeXK65uuOH9Cmz3EVZLDBc93WCi86xruCL2Ap+nzSYGhzAVQ9l2Yw7vqLcv0MPlf13mbcElFVv40PxWYLKEiNRDg8QmLfd8y5EaA+hD7Vu8QpxEfysG+lDunaz9CVONI8BmHjkRXfAkuL66PKs8kRyR732PsD01jdfFAlCO5DU0lEF0VbsiPRfWyXqY+kfn8Og+x1q2DREqdGbkji2Df2G6M15ddvDl2JxsTxmfQNDIZns9Z7jiL/+0nLie97FWrVYVzIr66IXtjpkk+yCBMQK9NvrNFUTaLMW9PH+vt1WyA7yAb8gmuDRBZfmOh/CU1yGbquG3ycDT5esEfXI9ayjJ5CQA1IPZm4QTRD6BduAdxQQtahUbkMwQR6yvQhNEkq8wKQMeAXDaKBQavFyYuzAllUajJuOXxeEmU+6phJflddvUazDO+xQdmp9NXM/h0d/CTIktWIdFDPvir4crPdKXAv9sgOh864vkzL8wMRTF66cYzkOiTxOfuqbGk7W8XowXbOKBn22Z7hj1CRtJgiCWxYzcSJcVaWXbeSag0LXAB3bufQn8tB8vXlTvHH8C/1LaxGCFrZHh40LrhzjISW6K9HnWBHF70evhCjLYL4UdnNSeQKPhsfifMWY9NvRxaBBWFeoszc+60hH8L2cJd6Ju6O3Qmq22LotYwZdMcglBHNp4mJrJBpgaZ+AhQBJd5Es0H9odKW8SEM7GbKqe9NIOJJ1ZkY4pD/cA2XuIfBKIbIUyJl5GlFRpOI6I2LK82vNi20zv2QyRUKtQQkXTU/6mLEWk0XNiJ74fKPLUmKyhV7/7JUpk9v2trMNjM/tPh5F0VbE9ibBayZZnGjryfFQzJjicB5OUG9XiaLpDQlnRt+CsQt0x6R/VI4vysYmshm+rW1L4T+iTDafsfsWxir8tcMp6X3SLUDYMssjJlpNnl9an7mUVgG2wkQGf8RadVckEI8sqH/kQnS9XeUaB3GhdIr9WcLZBjsfrjzurw5/+cZ9U8WYo9WOFy3HtgByoxjLs7w7gSLZEzewllHYJifpKPYb8kbPHITKoaThhrMPiGfdLRg+03R6tKFeV2wL+fNzgI/4iPOBRMHDvQJL27NNxljMgzUAfjfFAOdN0wBOYqHC6posKnzpb9Edi8LKJHBmpgcn6I8oOTv99t0UOW1FWOemG3bfYM9AH8j3NEWqBdCDGExE0+I+c4fzpvF645qP5Rsu73mQVuHop5h5d3OHsVnCFckv6Gg50ygj+JER1e16H2+YyugWo4UAlDzdYSHkKtarTuZKyIb8ke+8PKmN/WtVEQGPT9AfggHt+Q8+nBrpj7TvVZH8mrcTFXBiCRh8BZnXbXedbOt2T5o0OdBWVvjleRTRGRCV4zqSX0IKQmZPA8rgTfw0xxC2o2PXzqPYmvv+dzmdyXcb1DJ33PQoFONNdDBGiEsxygf5JocPOt2Nav8vi4gFWM79qxycK52M0acxhY5/iBr9L6mhdrGqN0RZVZDPhuPcRu3Yj7Aif6vBz5+m7hgjS0FDaC3+zsSXLkgYu/D3cK50d1LfGCJYfunpgKy8Pb2QK/eIr+FwO80RzA2Ay9Ys8c1uRZrezYme+BMPTBv8ibVlYRsfk2vb+cORALxbot9uguc3Sctt20lCNcxmeZfE6a0SglhmWxMv1GG+VzlFaYoBIjLGU+vqNjoRwDhRi1f3m6B5tG5+wxytu3z+yy+m+ahqaM09/RQw0eiSHFhkVtUIWsdl+i7Zdev+MCFXs+W2awuGqO+jxYxdl8CHT1ARFrA/bhBSAm0tKPfnEAreicLHRel/8deZvWmSwjXYs1Ato04yHBrpYFLA/GE/CIRz8QPD48A+x3KtOy+h9jVMbMIy75i6isjU1Q9WfHxFP4R8TW6dlUgiqcXnTo1S07k/G17pL1lVTrxatAYS/ZvuqNFdgPx4x5H8FzXcNM0XldXQitr886t9vwmFO3oQz1uuofuFqbQTRKex1DM7kIN4LTTd/CYVA8ViRW9OaeLsS1edtoGgdfPuuzKCWBe43Qp8DdoTGq2AFnqhFdmz73W6q6r2kH4UZMpO6LO/aWVwNaA5ElBR6OoiYES2JWjy2Vqxj1ZqgVmvz5v6XohyDhWg23pdJyUEEfny1inptvToUjlZT2yD9tGcGOQaeY3S2DAPsHWwlTmVnD2HQ5cBTowXwFYYw7WMfXr9L4VOV5fRO1rIfilFv0ES3IJneepPNOaKrp7Pqve1YMYojdEB9n8nnYMWu1qv8gFRdcMyQn4TYcnzeTrFjXCt2y2PHR8JbfjhkkZXGX2jXBljHvOmvC2ne6u/AwIOjSLqDtl+rmHXQ25hNRvp94X6USi31McFi0R2zSBpI72y0xZ4a1HnYj2c5yBpZtFUcuN7P299hGDXf/9ldPcsgdH5GorOx4qHdYnhnS6hsCSCHKBRXAjMuTeTL+wD3O4fTMqVwmGjUsTQB13fAinvUtY4RINKPCUY9RI8OPZ3FvW/BJanDMzr1N3r6U054+Htm3WRJeQOxe1fJttDh/hMIc+NV4EXR6NsvU0kZyrZj3U82IMTEiNO/XdjqkWbR8dam5ke7p9qnUsg8KKpD2lUbsmRb9T22z68PFatBFo4zuz/SjI/oMyJIcWX5yAWHNJUAMg3fMSzKMFsHzJMa3R37dAIysiVZECNp836wOrXq/t8JDx3cz5LPxuCeATeEAtwwi+UaIEHh/2jp7bEVN3qcjUUKtl5uthsCIP+4TO37SIjlvUunIvb/maGz4JnBmlKKqsf12A1tXHTim6B2rgUgQyISw60BEXzCOZgW/4debb36F2WTCXjc3NiVwf6Z3xag/jcTfSuyWjZT2vugI7mI+Ng/AdWffWPQJZJK7nDfuBnP51Jg39kKgxodkpHugk1+Ns3tBqQ9ajxU0qguR8sgR6cFPIw43kwrhO8GA5qXgD3OXHiszeoxiuGOYiijzbXD9kYhG8HZFTExSpPk7hNdkNOKSau5AtlG8+Idg3FlME/eHZXa++To9vkse4WJYYQTrjzlbFzK+xk6Mm63gASyakbWZFoX2x81CfXOmJL9KoJA2jMk2Qf5Oz/h8E25kgz01NqEuILGWtB5pIfitPsNY6qO7wzW93DJ6+G2FUjZxRwdejiGxuKt0lCzuHzSDvXjUcJy4GfCWPodQdYDVHGyYXzMGCfaduu6jzVuPgCoVkhK1FSuTyyhftt5+y1qtZqahARDg1Mf0u7m4B4F0iTe9BqIOI6neZEojH9tqESGZNnZwm2+g0FBk+NyMO3RiR0KrsQfPPW/nqnYSLtCcycvboB12sGgmEY9G50DuZdSzn+JY4wCy4yjRP18g3zf2o9iG5j1WCNawby76YDyCuTG4UIEkvPKL3W99yYXe8jL+WUIa0/G1X75fQ/aZ1CbfghG/DstSmyA/YnA7GhClgavtSOi/mR5IOj3uQ/mG+pSiHyye01g+o0r9a8P8V86YYQlIDe11XNy77q0raCRx6eMAVeu1BwLdsDC2lz3X5B+Qa8T1iF2Gw1bUgfaetXkJO+rYyExqRZvhiAnraI/QaJ6kwxJ/7hV4+9pC/HadBlJrLzxp7ELWF6YQqjeeVXSvfOMSseAR9DLjNxpvZXP/TinPBPHGVD6bcRRtj3QlyJLVtMumEHlJA7sJirZGuzDf/CgCYCRskWdbvvWL6YV3ICqEJIsrHlLwLt3WlWR890p7Cpj+V45fm4Q+BxjNn/8xAN4tIoHdhqniOXRBhWVRlopmvBaM0vpDCRNHPK+lCoz6GsJLByJaAfKQXS5kxfFa/LqEixbOdtyEqUYOazCiG0qxXGb4VuQ5vloJftdbznhqdeFrBKbpLw+9S2kYpMSw5xs6DoNp0mrRzi+9F1Yr9wR2eKUcmrEaG897Z1YTr6R51C+GNzASXvrKzS9yGsKgrfU8YAcpCntIKqDeP1herLQi2lumc4tYgghrPyM0+a7HCCyiCG4ZAaBIUCuNrhB8qKhP5ZZPtMTVcNhh4pNtBp7ZBy5pywO7z85V7nR1DmkHotH63kAKfsWTic36M2H1AUspcVThg3lJxKkr35WMGfH0BKeE2CzjC3hzkiOHM4yN1w75c3uFKbjF5Bmadl4UVi7/mh/CXEWPFiD1qhj4hjDGhB5GsIgbQhbFWcEWI5r7u3+gUxtW6OjGnxzLKMUNJiu0DlGB3KzExzfl6UC07r+z9SAhpbEEuAsvUu+p1W2Ee5GAjRkAZFPpaIxOUapk0SlbuzXwHwwQHFmgLls9S9Kh65ULvHbxc+/8Mx33n7HECSfV8FxLivgUKuxDDe8sd+g2PAObbrC0DGXUOWsrjufZmUkQP8XGs8AmFEs00wFmNa9PRAJ6uqtt+t327SRGLD7EWwSHCHQkXKugRM3iT+4maRrwE8/pewULgjKh9biZP/ihgXNLtjR9VkAPm091kIUJEnNefHn0QRyR4z5zhSf7iZFzLCJluBl/f5PtRqlSNPcoXrDh22RrWB8f7ivpn1VrVbr+GPIwK1wpa5MTTmFBGsN8b7jwyMN+GXZDY3Y6vzwJ0kRCxgdzaPnUGyxbiHyAMv29ULdkYJritd9dUbZWEy/u4D9auRCbBIS+cOdrJmluZ40yqbubdcM6rhyXnZogL8ciG3BnynmmQ1n6ibNkvdIJnBXD6jlKanS/eefilkd8zsPoLk3v3pLkmMx8t/3wFPMV+3k/IwRbDNCll+41Hqkc/zb4zShHVtsR/PFooOTReO3V26O3In1C3m/sfYxXqhbp/t6oOSb78HWoQLPvGSQe4/nxr42Wph+IVj1LGSP1cBDtvJlxaXri0+f3zV9mj3VSHmC1KIgvyusEn7z47Q4njFL3PdgfIoijvD8y1ZeoYFAFpmSgt9Dv+rCdqxfDtxB3nhHt9cwnf0dqOaw+FOqQiAU1coXLIzTTGo4SSZbSKDlIZPZZ/gDaC3mupQgEjk4xLy54QsMDx3Z0NvsvaJUAwflH9SJhMSr5vu5Vqj65tCHsMJ69LVABlFtZYwCRwAYuSHIkCl3oYGEif8DGKgjKBGJBAeTlJYoi2lefQKbIe0X9vDb1WUKWKMTyL3eJT8UywSNMTp7P08boTlX1sjvBn3x1JpFYLtDp5vqbx5xjgCzbdON0BzLnDTyQhWD2YyhkVXlOE+6VigBOOFyluim8MBfmYGhbMPaV2xtHcS91eoWgJq4eJWZcsMDecsZdtpY+oyBaRbYSI3k4GGl3Az3dAqJk9tthGePbB5DH+tsyKbSorFeo7KRy6ascpOLWbOplvH34OnE521B2pmpCDZs1tCk+TjAJpMxNSYCB04gAv9zTXXtlX64LErHb+SB24+LA9/B3vHo8OksDb6ROLunbSEWI3+PyurROrn5eaLbL1Z7rfvC1Pbbds5kcJGo1ewTV840wfv8f4kZE4xa0xIJ1cvGIG1aiQ9Y0CfCOVsOrO6fRRdjvVMr7rkVNv19KJ78Or4bQJgH9ciez1GEV1xcZwArPUzVb0Spa3+LH1vTQkSfZQUj8AGka/qSCzfByrPxGOtLXfPj+v2F+tJ5183jzELXjR2KZMCU0tFvO/4ZT9JMP05iWOQqZt8FrbmEoH3VD3IdFZvvGTsY9hambBKGfFuHptcGTJ/ma3qTYLtaBnGnrgPNqTWb5ZO46Z5J7eIH1KwAe6tzaDTt9zFXuc/Bwt0sRqVvgyyOYzfXslGwHy5bg+eKVIuI2y6xYOyxnqHxrGZuaGUcHHI7ekDyLRxJCZWqdvyQQvifSW4P6Oug/GtrGZ8oRe+fzIL0zIaLFiGfEPeBmeTt9f59MOY625tBjAa/RZbgDDD/r5EgAqmYRNVYgt8Hslq5gRvjF7rTHnUUVlHtG8KqowUjBtygbmd4yLaWxeGNu/te1ZK97IirxWFVRwOANCjSYyYVkvZoXa1qH4VgsIU9pEY9drn4lWIu5chHu3xR9Bo9wPm2pZP80jFgMHaIXNdpAmeH8fBkOEc88jHeojY0nC67SaMIMOK/ng7D7t4pjV+ewjEpyTNJjhx3r9qTPy+fbWSBWvZVTmjOuRy314T5OI3yCAUK0zl7m/fhB5INJo4T2WBWo/4f1FsWFrfwx+95DNyujMIruZySdia0ZYfr98n+BlqpOExxmXUbq/C/RN0sdA4jc2GUGCj5oBk4++/Xk85WroICDZWhGHL0/b3EJccIixdFrjWHgEKeWamsCsBMoNgnzZRkgYq6/Jn/GOEAi1+zH5QONgOQ8/h1hvwZP0CczhNfXLMQC8uwG06GNQiDwXMA8D+lJfJM/lU0eRNv0LGMYoPgDmNNyuPN7dIDWqPlvYi9foTuBOK2FWCTue1hfCuf1cNKeFBogP05aNvRqQaVw8LA3e6rPsxZxmF9aZvPi7rhZALUqcog1+kontj84dj3kxO1RAdTeGPIhf41wPuGD6LtlLAAkni51NyurgSJjD57UUOCr7ccu/Gbxau85W0KJuTIr363yXD7wJUcHrSqE1L8uXZvtQ2MQmXNIvfdPnGFDL3r5yQe+Lt343bYYNzKAnWP6dXXECJmh8Whhd6fXa+/z2H0QDD375ye/88HdDEyEbIprrZ0IUlAk2KjWk7Ja13hmmgyRuvc0xQduPoJjjwdCjZF38appVw06JydIIYzAoVr2pQZfb9OzwNDDO9Tu/3S5us/BLVZZ8oaMgN5glwbytO4xP9MVvQG8XTjBquvaIOXDsuZDhd+I9OR2eqdUyHrVzZwzn5M2xaci0MM2sJ3+yOPiN7gqF3d1nAf9ubXW3ozGM0eH7ZTRe7mfjr1b2HpHiSys+y8lco9bDwvevGUliLmQ3PKgZb8a+/FKYfoE+h47E5rsXZCP/+yHCdj06kod3Q84/RAa6plgYKgUMtVps24QBkr/SAwxqR80hjHuyWAAwYX+TIuNHHKRNOGn122r6mzBQoB50PM8p2zTRiydJkn6N/69fKMUMdPxTKxjV+WeydbkBbMTqDGV/R3OvxrNj2qMewqxAvuE31pt4XPYhrq8Fr778DVjz8srS5SUvabKT+4aW7w0+9+H+kIvk8jQeq7RZRamsn/oxXmGscLvKhtMWTcV+nn1AUal6bam6FA7x/szhASA1QTXXJYpLeX9fIySOXaCl6qcgEaqCQSnAeoOcLbftybEmeBVPgGopSdQV49+r9LyptsLngyDdkZLvD2qBtHuDdVyv3B7nFB+86Bnwo/x6dxvvLk+a5wxRr0DJPf6/RNovYfwr6q6gEZtTHYoqKdg0sa7v0YMjAPdki80zUaCCW/66uWnIPmGmuWBLxO/Dql8J9ZDGYn/+lRGsO6T+eroJ/ksD/VMJf0+ceWLZ4wRS9hnqddXr6Nl+/M2dEl3vaMnp6sC35SGYWSVYcJ0fQXGdN2LS5YQ1yBSS6SPGxqgITt8P3mhBEnda5kSZzkb4pmfgeseLLmdLISa0rjQoekevEJs7nppZ4KDaCm9uNuUUgbuvdX2bVsBxhp0pf+GM5SyGGBDj+FDiigdc367X8G2XyN9kw1Zh6fWgQjtegEAaliJYbjsobkmRxQzKGrmUPlZ4mPFRYTupwsFxw7K17+D070mOnfjEpy7Uu4aSByqtszf/uhlML0ce67Qz2gurZim0qhLHjeFZ6uJEOz0VB5Kf7VbPDKlNBWxXzEDdRaim38hncJtUkZtoFAYxltQVfNO0mna3pW6Ib8hlhvOgz0vOO4x9SJ76nlz969WWjDeFik+HQICeAjzlUB8NNWqt6w9Nxp9iBlKjHAtrRxcuj98QK9WkpETV7+Acr4/r+KzT5F3Y1zb0j7bWiJwGArepfqKmDv2sCe4qojfkqPWhJ9TRU1NHBiF1DVa9Vq1WLBwSvtL26pBcGvGbrTxQ+0Uy0CcpEtdjUlgq+h91Lszlig0bRl+pPX5Ee9A0lcpZvsIx2AoQ6gXpnGpZZkHejbWXGI8ZGvwSgav3RX3Q0LcoGJqzDukwuMZIIeRbSM/Kdmo6AF1TtN/seXf61xUuNhUwpIUjs0t0KBa0UMfr6q78GgQNMs6Uc5gf2hIJsh6+vvghYcGSgYhCn23zvgcJv6chMuRMgs/ompxV9ZkYmjsxwXfJNtj56kdN3irpiSGmB0cbTbC5rXihSw/iI/Zf8RFWG2wSvqMGauvLvvWt8GqRd4UavBeufewgRtrmLeTep5sfTVEATSzgz+aLUm8E4JViaNATMvsgcMn7q4TwcgMqUgZ2TV/TmAKrRk2PokDJPits0ty3N3od2ZllCMlkzi9rCw79WjJ2s9v15rSHG3VaKkg1cz5QX0jhIHEvWyxKlM3Fw8azhOvjk9KIvumzFTi+gs5JXqwEKjYzOd+1sAIYRm76IC7QzVLcK4C6KyforWFVimIdqTLP7XwULb92o49RGJL2WtJf2vrZGZv+RF0dECX8ULQtBJtVFyuWwiljASwirHmFoJUIAQFDvk7vMp03B9zEVagDd7DvfJZ3IWLRLmbzhA1bNvo6PA0bql3Ng9pzbOT+5In7B1pCF1HDF1VzIcxiUEyVuLJNn/z4lFXDuswNm/oXzzxBVUe9Pk2odR9mbwfQ3cRr5FEMOYCEr7PB9YHnVDdiN/6ZvuJgZFD16qYplnFq+EbD0BqXuAnhr6VGIMjMCHCcZKfL0jjK0E6pwj6O/7Lz38UVOVd80GDZ4eqMqyn/zImnvu+8QJwkO8nBf7RggZZN2OCOlIhUnpnuWj48g2y4HK0sNu/f8QDqmQxQ4ChYJ8r738P2O9Rnar+QGfy6XN2hRoXfoBXl0Wt5df5FUdbyvoQ2r4DG9A8m7t9fVxI9nQSU0UU8qKBmA8Fl8+LFTm0e+ImdZzPBN03FiENpNG5Gu1nkZzzh4ktkALKBybVpHr4yYn5rznjWxhSVppbOmax7jlh8BvtaDo40POp50VJkXt2gMnlrlZ/FNDwYNw6Z3u4N/krQ/btn7WQ3nJQlJvzl3ScykUGVs8LZLyNwAzTJm9PK5Fjadu8u+JcQFiZ1a/sgq91NUSxr9BoRS1JuQhORhhGp3/xvJGdGpPqBjUJFChvsTCCEmg+peqOqv93hVkDkenT0zn7Aim4PURL3Rkqu0GRE/jVJNmFk4PDADhODmO8Izc30r4YCk1TPFuRyQBmBEmY/Z/WXuKMSod/3797zg96/L6+VKH+CCU7cH9yUXBnDStN9yIvbfXshqmhWTrOUXT/tVkyngZ8Tqz+LK7zlOVHOGqL8FbIRtI5+FxvGWrQkbjeiSEDSRLIZL+wdksQL2AcNRzMJp8/z/ygDOuBGPhuHToxRtRGo4PqeQNcoWJN+8SPJApaFZ5u4dPh6zDOqJyZo3nZpNkf08pzbDpCJ8DOvpXVg3PJChbZFLPWwpnDx5W830Io3YGUm0Sdtx82bLoNJKsM1mRtAInpZ0I3RNFR2qu1tHlekZbbLV7ZiLs0N1MkPF182iWsF9ft9Yx+VvLtv5NVkcsokUBUtex97YAaOnWtHktvH+coEyQ0pQdHePBUt2x9XeUvU+sGMptc7Xlzb/KAXMiiDuLxtNKaSyPBJsR4dONzRyDc4QTuWqqSsQqcfhLFi1AYsjUqfp0PBjbQ/uXSzBWheECCR5tTQo0Xvj8qxpuVCMZTtwcOmd5TOa/bARWN/tYn8EFqEl6DEqKJNjxXSxQEjZZ8Y+lmKIF9LNOd3J+pjkiDHa5NLlA48Ns9in3mwihgnbk+sHII9nJmJCn8olA+v4Uvrf51TOb4NYFXuY4mRBUOr2zGLoyMyCdin3ii0JX0oYfcZ/3HTxIzBEjvYO4KrvpkwQUn3sFXHlTVCnx49P9VVU8a3Wr6/2UE81LAK+JvZXWHldf+h86Z7I/rwvA2mLbSIiELTfDBA9uRQ1vy3pLn5+wIbbTaVVC2qx9kGgD0TaxHTxV40SO+Snw+1fzYUMhaOWreToD8BpU1qNRm58YEquyBUG63CHuUBebdcLSNYs6e3V6nsu3PzOxs+BpmJs3aAz9tL8qDKYXCLmoaUFHXp87pAzq14wifrWSoCekHLhvqfJmW+2J6r92tsLyMbDVQZraWMHjCaUqEc/I7dUeLWGRX6nUFZ2N01w5W0IMrAvwMccCj48N9ABZ1/gvXs+VotCcbnRJrIzFzVIXVrsN60Png10EyFL4T+x4eeL3yOYynQOOHIYLtIuLguSIOqcZRfiCaAu4F//DnPQy+dEZQnxa0Ld+ewX47IOiqTnTxlMmGlcgwjYZ+5v9NbaKM9Y6tYf3bGJx+ZA9qe2W98EbTnLwM6E+P9sI9YErU36nykIxSlTfL4XzHBfAK/9KLZjN1tmOLyL0VqHsegYCb2S+Fy9vV5VVyy3zRXFGYB+Bgig7wbZd0zjapoJfd3CyWckqEm86IBGyBLL2+hEE/EmSm/b4T2ZNUc5KQdzkh9FDXYmS0q0iNH2K0iyx52QxyJFoQS6Ki4OLNEp7jCM4ZY1fjR48hx4tYMThWxTcQFoxo50Tw0TheT0pc2/BZ7GAL8WYJY631QUj1mp6/7IYCCQwNM6pCINXmhHxLon+js5AhSkqannLJA9/PI1z2kHi10DKh5EnVZhYVaK54YIzl+Ma9MbEq5OpIXlJlnfn6Ts0ZcYADn61FawD6vLEcGt1/Jw9Cj/RN6orDcwsmLvOaAC0xe3ZtFd/4kpZVl0LGydIqEACDnol2H85VQ7P5lC4kSj0bjX6yX3dKk803qRVKJ7Vb67HlUptizN1H5S88Cthgdc4aokFsC/9otdHwvA0cx/apgJ7/IObOmjW7HKh+sCIOA7hZgzmcLUo8xfFvpEZNlEUVoG+tGvt7iJz9xkP19lwq4fwV0pqDU70R31Uz4u1A95lsIV3WFu3q9dst5sB0RnOfXZE+75dLJ70TxAW2dJz0JyDr6GfjXcXtW+nf3lLghaqf8kVhQaqVNRA1u3znjrSyfGPg7Hi0IvMYfY9u9cmHjxMeJ9tKcyRBlF5OL9HeYCKBtLq1uT5uXrD/poAQPmxlUkU224K0nSpyk9v5iUqlU1iku+PHeixg6J4EyeWMk5ft4USr0ptlXQWJJEUD0i+OTXLDDZi6vhxFTvmQ7gsOI5CQzFm/cLnvD2+55lIDFIjyRnVNe64Rn6lLZwaBkXZxOW8/Ew6+6KAV/S/1YeEBm+wsjAW8q4aJdv/iKWasv/GpLABloWaHAQqePHhMWPvS/lKAVj8LSJ5wJLjzZvYBBq2tjtOFFsXCpnung4Df0FoVdJz7I9+7hkk4N+ZJFF4FEr9UNLSvzR6DHQkWExdW5Z6dWiPEKdVQa7OIyBJozrJdtvSTgLY9tc8epiRiOjd7d/tijG9lHsIiIac3w9QgqvUcH9Am1kvU+3y8L5CRYyrjz5hJMqhQMdKFvxrxodpjcgn04LhAFr+qgOVcsJOzBq4yFCrOWHMd9nZwpwmfIZrvNNxj2PA6Ftmvx08UuIpHyCbE12hIZzMRXB0cU0bEk6iPgyXQroH+0dc46hUXpsXj4qk0g1VLjFJHFgA9X6mwFeZ1edJ3Cwa+47c8HrrRMdwhw1L4bAVT92lHSWjaPQ4E27pV+qcF0h4pSb4x0eGfX6SFcT1Rkc6RjHELqDdECQYAJWE33kWRtnD1q4sNXX4yyKw2JSS7GDsMkF04d+q4T56Ul2hFlh+Syx81Mxluu3y8JM/gyXQwLkSFVeyxa+wDMXN/+RLInGulYrkETS//y8wfBzSgP9YV6yTz1uyyV3XnMJbJK1O5zs4uAkHgLfhfg+lSxeGKcK0pcc1UA6c4we0lUHtqgFhvw9bt1qYSMN1QsMACmlGLsGpQtZPIZ2RjPOc1j90LHdUj8cYvjCSlCH0mvxp2muuU+yN/cLmC8CRTjVPDdFQIRldgR5UdRLGyS9V3hI1ye0l0BJHjxnbd1tMhUhXXyZF8Hl3vfjhuwzMAcFKU7/bHwDYiN4jxuoaQFVnu7lJJCUPjQmNru2CHnr8qitBf5MgCxwDBnrhcDuvK8tD1T1YS6Jm5uIJbsWHRVhFm2xyrs0bugQB3sHEpo+27OcPHK8l9FFZ0Ymsv540uVr+eFb6KTmeKJQknEVO9zsSrNkRwue9m8OR4mSp/hzrO4KNTLZw9+I25hEoQVaoPVtn7g79ZfJEsibvAwhqx4lOTBEj5uTG8z0tc6rl97rQziu/YTWefzKYpmjdlDFuYsMTFrehdGBhWInPdGi3XI99Q0l1dlqTbazSB4mXNZJNHq4MbW531Kam6I8ajbtlJaniw7DAB6K9dICRql3V/n/NouUvEysw91OZ4L2msFihLgBVUZQzqcwT4u43gcxzrco7zN4cSopEoFvjzmQr4kxJQlON1L6ZYp+A1KsMuHw4FT3wyZTXP4wKsH/sgU4sPX+beDOVC+m0S1w0nnDoNKsZnzRLLkIz1igDcbLHGlb/flJC9s5YqBZDs4XywbGx22oija/DUA/5Kat8IFrZteFNP6aFa7+hy6/Y7mtkmjCWbfiO/xXeFc+ap/npiI7qKadgqIKj3Xer2HdEmXI6oZaJP/iUfhxVs4RmdkKIuhJO4wBfUmrHfqOFqoD3chByeG07ZihhZfrJyPD63M+kEjQUX5SvlqPaBrmRlaMP/68PEwofDF6pxH5uhW+NjDoFSWfQ3ct/0i74bIjGHc971JDBLYyikR2VXpIj80AVkfMgaFhgcBmVWb5r1yTCyeD9RYrdzxYymN4dJJFMwTz+bc9I10llZPJpFB1CszP+KNsRlphF+aJemNf4iaixGGxPivU5XmEUvMyH/isG8+KtUJsUTD89U9n8g67h8zobXbAZl4m4QmIxjkrG0zZ5W5HTIhmlYengAxh/V3Y+qOK2FGLXlkNHE1wjFIUc6bDeFjwEj06L61pMQekU74KylHhUGrQVC/d+urbLX77L2A6O38PGdbxlBNvLttAt0rrJNylibrToku5EPJx8+RW7WQRNy38huM8FZde9DvzxZ+6SVUxS/1ynRxmZa8rSrGvCsb9CsWY+4ZD21xrNC6yVIpwvpVRLXcuiSlKHK4n5BkohhOkHIlnfJwsuRlJiYYT8r+DqjH2OtdANV+mdSLzW1WbB5Q4O5UO5W6slKaMurf7NxLsZqa9fr2LZxUcJJEJAvZe0fViSCMgKw48JEsruw114FAH8zfUG8eYFGJ23/h6CY+S33ug0JcNJn0vxO201vokpbk2hwwoavYw74KxEXlkUfTphjtH29a7mBXrh6FV7iQvL/CgiQ9eUJm+B7JJ2zhvDip42NmcLoGk8i5g5oNg54YtBKy6A0ysL7bsJ1YGwoFY3fSq4um/jETqeezd69+q98JyRt/hDOkOfHbZtbLfhTv6UiX8V2eOK1cTaIUnHyHlDXX9MsvKfQ8frrok2xlF72kwGI4+nf49NKZGN6/sAjzflDajEtK16hZMj7hl86VL8mWTit+J7GvN92pZWpvByZ8J9YJAgvv/dr/QDBw0xzLf4HbKw3j08LU6DySNNvJyN8LE3+iIAI/lpXRDNZ2DHyp7/fDmayy8EkumBfsd3UkKiEAESHIIQ1xczc8KlRUA0m9WKlSuVAFWxwu2LXa0+m5TwXOIubYVi+EN7JFjEQznbNB16LgdjLH+U7sBNzA/vXlcLTDopO9YN/w1kbzvH7lA2z2f5fIGCwbaMd3Lwv5ZYtaX9dSJWPS9/uKR2x61BJv3QylWML9XW993sm/fQlM7IES153XiaXYeBPHvb7JQyBTviAPW7Sj12QyBZM/S6Y9wR1+0U1iv8tKu2S2Lg8P9KgK2yvUPs5hiL0G6hbbvofxb/5fXNJKWwcs1Dw8C8++XdySDGqJdP34O2DR+rJ9cfGDWD1rZNcs8B9HWT/1oy7gqRvX1i3f+052FR+fIjSNwgMFKxh3Jq/wwCf+6Lesew3z8pAyMbu/iLMd6y9oLcRtoMWj14ZHsMUtoUPMLl6PUieYfahjwX8Po6hKr/w7Hvf8V9l6/uN9ZDeP6ldNGzEqOgYimzoYhDPLLMms0hbpVfqDBL5ZViJNvHQDHLumU3cudxVqIkCjHj17Wl518JQMFG2GD7SEZV8e9IQ80tqeGEIrrEfOCZIXgWjn/cqwI8s8/v56A5Y29KRwoQxcpvmhpnmONe4JEuD1kBnQCxzfOQ9aTVRFqeTV/r5+POBZWvJeNazahlhZe1shuX2VDBpe0Th809oUz+VAftp+Nzv/lZpugipOd4GuzoGjdcufWImJEWYLf9cyBO9JyG3iCyL87krIfZN5R8A9B3/ToIuHl+lCfe8ibN9YoyiqyGt3vqweNK+7+g3wSynK/G6m+oDz52v04VhyYb9ggw5UrMH3WBKAdkfB5iqZ2jdUimSyPMgZCc3OS5pNql8s5JdaLVmSA7bIeWGPfT0sj0wu7XYH4LtPUGwUmhUvO+Cs/nhY5sN7h5rFocZZsr0o49+tjUJ+Y8cTz/PtQHu+vZtq4yNO+GxHNc+xa7etFw0Ark7QUcWmG4qRv1uz2rE/CNAZHkhsWih8dq/gcIwwiozyMLEtj/+mkKSUjoBeLAtygEdqFNpZ1T64TqBY0/6544XLA+Gsev6jhMQBQwAYNqHOYHIkEMfoCy3xX1ut+5+Pogz+LMMvwrGDdFxSDVum2pYvz9GCTiqdiBvZvBkyaijvRvhYVQkN4SODbg+Mbi4RQwSBxlBcnhRgCgmp9e3IjEmmHX8ippJuR2HwTwyiX1ldl0llWdIR9hL/sIVvSUpFI2vR+8FSbhMTYOoJUyS+eoiHtZMomYx9zRQ6edBlJ70MERsQk9OCUjK5ryFK+3f5C6hCA9HbIa87uYQP57p/9//VLtQqVtfP73n/sLeGqlvfAiOIfyg/UzvxDur92oT8oc/Beu0gPDOsFfuwUO+WfsdfqH649TL7FzySW48isbTbVC6/+QcRfIjND+Wxe8OSISWNLZA/tr40138awdS2lgkI+6T3qHCR3HpsVPUhGqbrvgIqz1MuZTtAEtDRGfUxLvWeCA1amDy9Ouj0Mk8zNuHA22K2mofnD4tYyMUnGxM1/Z3Qv5uGqgKn/DJintdAnVdkmuYnbM46wsPWtZwJPafPo0KGmfXD59s8u26/5cGqHpUz2QYvedLpPXGOz32+EflfXvGd8Q91v1Gc4hlItXS1+LyuyGRj9P6N3fvH0nUsO4oEwV/CmyMe4ZEQ7oa3wvuvH5o3Ebs7ETtO6q6uyiyTVcLJelyWZb2+27ZUfJ4DP3gkEgiTuJTk7BB6WcddURoaUD28Po+K5DEWBsRv3BanbjgOaf6GujMi4fQTrbkqgew8+ygohk3rOxCRPfl6ZxIKaHs5kXSsrskDbRiRw9YDB7kn8AR+t8k1Y1zWEGnGjnyTnrOh3E9jDqsIf1q9r26T0iAlDVovdFU3/4UW6xZjA33xQ/8Yzd4i/oVzPbcNbeGfIuOeIqsQyy7r86xlg/RqVjyxMI8B/XKn0PrVIXE/1vNLajOv7F0oqpNM9g48N/+6ceqLyZ/ucQnkSsiwwNMsZyVrchH+PqbtGM5QR3lrUX/Y/aoaR+l3djUk/v6dQAYilgquLE4lIJhOqZqKvnAQJIQ6MZGZkNuTkJQ1y4oXmZKImtI4LeDAqKn7S8vXj/kSmQXs+BcZptOOOdqNDmXZMQEV8ob8mG6WFrl/j91JtS8p6z0igIvt2FsH3sfZJZWYdicV1bt8ACsgxG6Ddc9YzWB0u4bqFEtiFxP5xpd1U7EJNDeB77nQWYfA4fb+DZ8Bvv0y/Hk0aN6tt+iDqza2NpmlH511zSW1J36JjvMzInA93EH6yEx+7xKorHvtHEO+nBFyeTMb3+4QWsx9CF+ReS2Pjx3ubfHbHcaxtaYeGZ/iMNvmaH1JtKz99iKpL6oOl78vEUpezH1DX+oc3U9FeGAPEp2zj+meTo+2hfxKkLcibhKrB7NVw79EY5z9pCbhDAyhZ7N1G98gjJoHJbJ+83Io1KO4DJ+y3+ujL6z3A4oDJ8H9H++08FgurvNYZ5JKBs0j5bZMYIweWgOxeMwcDzzkXG9CsSA66LT0PcsKblIPeuVF4dg8PS1zVHuF09+fl9U9yOrnxV/anHJpksFzCXwkmGq6AT/2UcUGrQ2Y24C7T7mOsyqcX1vEkLr+Oez3Qw9jOutYtMNgkILbHc35LDSBhZqGGZC1fMgRcp1HFdAHoSh2rh0gQNHg4zHppSxb3O4XqJLvNYrUbhHkFyC3V8Y4BXtjDW/jeC6CdO7pSYbqKNebJpJ0Ecea8a2u7eVdQ+sMydnejAH68jVibylL7jXpsD5ifse1W8WOvwpc0bakX2HiEzH+3JZ2XEa7SDDoD6mySebhMPIrT9cY7WzWtyiWVjGdCS50BcjXOV3QzjeqHvIfbooNKBrBNzA15RjiwIvsywcj5vWfrsC+gSqE8cx4IB87Jy+NpkEg3V/AZGeRzwjYtnCDKn5b/cnHUVo6uWxfMDS3GiTcXwt9F+ke4qu/BYyFuOCK8LPsBuAjZgo275+HbRpLd/cksw0GWFVaJliO3XSBDcNluopZQVVZbG+P+BnS2ZDkhAPYvhtpHz5uQC6Lv8IoFqywY6OKkM3YBDb6dspwA6gbkX2dm6KhC/PwgW08JXcsAZ3nwxwpZnU92xFOGOcc0fZ+wxF2PyPxw9irvH/sN850uBfWPZn78c36GtAztNrXcIBOBQUiqeM2DM58D4SXB+PNG5X8+60Q3DG+sDktCuEBc5lrjrc0G4echQh/eFakAG0pEsGiIAA7oI1yQVPeb1GlpXCJqOtYHiNZJWrRgSUQbgS3SEzsE651e3Do0H2h11nDu5xIWZvtLf5Fb6SHGAJmaDSLdHz62Or3UQfIxVK2FieqBjXT00l799484LRji9R6g++KEY/AW4fgRuxbMcf957c0RbEQM9v7lv0jEJDP2/Yb/CzkfZIJ69/hSnRXIPsmCh3Qj3nKtnmLmd3uAIKUpY2nLi1n3lGholMTElN6Wd8zwg96tDouPcc/8YN5OEIJVD3dfzcxY64N0opvP79krwtc57aJ5BdbPk9r72KAcphwMVrT+nW4IoMSpgTliavhNgdQvOBb12YALvaZsEDoIYJSsdwtjJjI8l32iu/i6Wl8j/c3HVyGhD1vLS/1k/H+7/cOVOQwjgQvHrZgI2/vWxcjaXk2DPVEXr7wnFXYDsM+VPHGmBppM1+5ZuJMlcovlsDgca5kQoRDR0J7D9KXKNDFb/gUhEMRDKT9qcGw5U4N96NgVIRfd5tyvqejVqQ6Q7gFkUBrhnUGwn+mNqBZyVR0stbvNBHc05k5mFm3njE8QTeed7/KlRxG5O1oAGaTbr5Bb16hjqMw4od2Tt9B3BJGBn2OHH7/+LZjRfuk5fS9GnM3s8zUWi5zI/dnTwH7nfdos2BvYWNgnt64ord1xWifOhptn4lUTDRguKbzx8w+YzEZBYssvfnbblYmw8tmeXx4dotonungTdDqBTytpBHn6/gQ8pGAbD4YQ3DyEapZErQN9u0wSMqY3ozYx6b1PEwWbfkXjY/T7vgrs9Ch2qRmH6rFfROIReglRqHGlWjhcvz2DSbrCzwQU0bwafqmbehIanUZ71FA4JXZQNQw7dWObkSJkQzAkYoWpukceT/zy5FaqE+d4x7qAI67aMFMGIs7N/cPTzp8dT66D/rR3gyphDqycPX0+yoRLxOPRT5B2e3Lnw0qaVPfNLlp/Aibp0TgsOZy0Ldl2qzF/1rZ7f1akCkEOfc5LFdtPYWFTgMoI8v48GtTo2E73GLqBfd+pQ480w2ZYXdy63Hst+Wowsd5raaNRfVH3QdvztYI7sSc68imsXIFCgyAykSrYsypprPyjiJ+5U5/RMNZCad1FzEiG353eLlPsbJslWQ3UWM3IWbQdKYfrSdJvq1kig7USomv4dzsUxoD0s4oj9Qa36mjaeDeMhvDcwTfLMdyiKrwWxtOf1PKD441PnNvCNeip0kRXpQEcZSroD7vkDiCqzKPjylQYwD208zyZmvkuMOPfKmiDtg67s0nqAqnYOOPxhq7ltQKXkOp+a7GExrU98/vpchLzdfqf5NnIwsIs4sp14iOgZ6E+b2VKD8+a7ZYi0NxxVA+TnUftmOfOqzaDY4Af8vfgGSm2wX83TRT8W/uKYejS+hRcV2Tire2PYZna7ef6fc2uOx2jULG2zDMW+cVwquB3r6pJ4wtjrp29mnxnXUzocI4/Xk9nQFKg3+KGysPJlNMjXLzrEn8Aow/nZRKVSSLTiISLvpSksizpY2e4aHB4a/VBda3rWkwCyqSnyEWeGHkekHIl0ow2iZZvIvY85yotnJlDM1NmGxbqdkywJrY9hdRLSG1Pg7/Hc+YTHfYzHM/ZNGl5VW2VzdxQJpwrtwG3qzvFZ9CWiho4RyvPUcCAGctYKr8o7bXAXwl7kK+bYA00qOR0jTV5QDPPqsLivlpa9thoIooWCh6hx6QGcGZIDHJ2TvAjPCruYF7/51t5cXptBQ3uGQDkXl2aIS8A6VwWrNaEvqc2qZ9Mui8PtIs5+b2Vd2F3tKDGSL01UREls7zBze3CeTW29c1EfRmQ7529PE4YhOkJRCMvozstovfwHABo0BVwFKfTAgpOzTwwveFm0SDN2p8SIG14jer/wo3ISAy1Mqwk79SHv/gblK8ZfElFnCoX7uULgNfzEwg7zdE+couNHExL+/QyU3X91CL7K/VAGQ/v1xNOmCNjzdr9DNAOgD8z7lZDWc8/dngaNE5yChi7yP8JkXtqL21aRhfT/zyIMa+ZpgDCxHXjl+PnVwOGsu32feZhdxIg1DAHA4BS1+Kpt61Z+Wv3a2AuTTi8tNIcIGvMFj9mY0W7zXAT2OlNMyI9SK7bkGEGAyqqkQKMLS2LDApv//3BVZ/ajBP9usqu7N/Bjkg6tyMLiS+4FeZHfrtiDy3SDoTkdLnTXnVp2phJxlKIXIijS1Sy/YU1vcKhqm/ofwmt7e6ygTjQ/JvWMbVeuYa2UIzIt5y0EDNFmxPbe/RTIe3j44bNe+vMHRGnnKEk/jZLQg+8/5yEoPQvH05bxwhiBZg1e6FKyPMEYd4Y9zXScFC2vanPigWljpvYJz35VmEAzrZRTail+xQ44dQ8EW//TCcwBWJNyjuFQvHyZlIS8gs96JOlgIZ6Bp7DXUnYh3Opcwb9b7QZzqAC9aYxjl6lKOlnzP7zwTq7VfCys2QLdhy7ul0AjdFW+cN8+SLWNNI9HvADeTqaI84FMObdy8Z/sWQsvRhOi/Inni/Nei64RzK8M9bvLm39vR4TCyLTBTxBq/rkJVJCN8du6gsA3xXf02myun4KWtwyE4Uny214W2INOq3tyknuPYQi1YFpT21erwZoCZb2rdFwzDuwWePGjnznGkJC5UWNyV6Q7Rc1Id7Ddw0bDs+uNYHosjisuR8tnKZpCs6Ro9Ze8f6+k6cAzuaWchk9qNDO5tmAM2NlU9RJGRuiIfyMrAkSgZfCd0ANJXyvyIPeB5P/Pr75xnSfIbkH21QgC23jBR2jaC9l0XQQfhUqMidelcMZwIWb1b2GzpDaxcMTaaY2Hy0/L++7NpSU12gIVAbsfqz18cXQm9mECSnmPYwpJgrGL9nXYwifuqG1voIksusP0dvtEK2Z+IN4PPlBQq+J9yrmRT2sMuPzHax6Q4/Eg4OfVmOH4Ca+nw79s2rYqZF9++JNuizZroFHwEdoktDvScbCZLMrjciHQhUQ/yLbR8ictpbD0AyQvXppS3JodIWTMpuu2rf2ef9Euh9wPwPqR7fZ6zF6asRPhcSJpolAEwteF/ahsr9nhlDAayPpWDupQsL0z2t4L7wuX97/Ndenq+mR8s1mHsSi6sFqLPFKCGbsA1+GWtEv+VNIQryBOzJR8udUUNdem1dR3dCliP8I2j4M2yBs6Kb7l/11b5ComUGF8ahNYVNd8YDJWvFXOYmShdvHA3LVD6KqS/hbqK4WmFzqJwVCsV4HZs5Vi+UDKhM3giMEITVNWB4/nED0u9q91OxijVPuKnRGffsMfQFBEQha6xov8TqvnD7xkpEf2i/v2umH2WvlIppcQq8c5kMleketSkLN22FVuwcVCTHYMdy5Da4jUYZM19h/rzEiSg/+udV8qHIMMwEUUDElmFeFHtKX6g2WEMGcaESPNRGEfrILVqPShRQorfb+9S05tef5Uw0tYkIlvcPBUcF0X6UWyE9lzXylb3UILtegQt8RcjLWYbM6IoOJw07ZYNnaR/t9e81zngiqfOVkIsw7AqG1GW8IleLx8PHjHsRpXaifjTyt6rY6hqmPS/Bv1oRYsxTvF5Ofl1skehVEH2ghOY7k6Z2PN45HDq7CZeK4dCNj72QYcJi9dhTBMYeYYrPVaLLcIsELpzF/muxxF9E4i3nT+Ec0MZNRbQvs2mmKq/56C8MiexFq8K/pqczzqrmS/yk4EW/om2jR75LNMUilUrNiNBiJaXJhJfQ86iIMV3DpUIpydVpSsHDkVOPd0i/3vd4J24HkvgckhuHvg/Nxa53qAQYxUcMdhfzNO+FtNNO1urJ0gQQj3z/XUDtArvGwXUA3g7+F2GBhmfx6WLKOkNVeJCaYIvpd1FGPJlX5YLb9ZIj76oEfieBAQ8nOtOwgYBeiyFQyN85JkWIAx38DEHl8++6b7vQEPi6zJT8VMscc0oAdkGxeXSbODvZj/SnCnH5CxG2p4otntZDqeyJEZN62DYcD0nOb4yc84eN+377VfSSzXcQfhteyWr+PrZBDbjouu57LbbDsUEuaq3zCvUYd1+OLpEJDklJOXZJyizeXzrLRD99cm80uH4L7iK6pBNLS9JMmL+VXjXcqz5yUDuU993k+08Deh1l6Bp+FjwXOTguRY8pS7suRJbhMjsSeva2Df0GGF0dmSry1lVSsUyl6bPSE0wti+RBzqg8K5iVflDnYLsDYHawWWY2qVrmiVSSd5pFtN/CtVhAZZOvmlts8OpiEufi5zA9sWh4+xGm02JbFrt+0/RhDaNrAX1qrAJJ7VGAE0ZmcAxlzy6mVmmMSDDeF25d1U6hnvFFL2M1iNn2GFL8hoNkIEIqsid7Q6orJPiNlBxmQp8VEfWHPF37DAkaWqurqF3CbT/uuPZekiktCXbX+Msa8gabc1mxGLvcx+4X7oLbzbegfJd0DrZurkGbSkBbVt4IGs5+Dvtso26XacH4fhnmx71B13SmY/MEltiwLSf9mRDu+ZRBTsCG5eNB2BUIhnm22+lGzjEigujGHJMH4Jvv1w82aCfEsmnySbDbDkN8y0FO6Cd2yuFy5TmOuQmW4Zt7pBvhYAtu9QoCMnmRccz5ls+etl9dNehvPPvhK9J300LSzm1mfG10XL4LKa5SKK1E4BWF12VfTzs+Oe8aXeLmud2RJYkOIS9qZc1x1rqm41V4OIs2DRugGhBxiO0vrQauQAwwp9oCQYZSV7YNm/UCcEJzY0eUu1+EayC7Oy7M5t48s98rl3e9EGtMd/oS3XcObHew/Yqh2z5g6SavGLFYFEJY+x9+qV2KVMlc8vjBom8UCCFBqwEdMLD9clnrF4peaKpYz34oKLd/MKBlfuy6Xhx/6whe0bLrw5CKkk0HFRewKQLloQUzEpTEZyKHAgOIQSYS2wl9CKuJz9QQrQs7RoudQ87PptIDvBFwn6m9gVtZIbDk+tGQI8htp7f4vmfth5PAj8Hfft7k5PeukvY1X75EYxzxMgi0/4HZggbYisc4j0QFts2GPTB297Wlas4J7vMIWdAAV+obT3JGahEVwsjH91MZX0vLTMN7d1XVWyTR1PYHTvOpuKgmo2mC+IzShnzVbrMj2me+93nDTkaN357NuxtNuUMs0Xeg76+LKNTFzqRJNk58nm7UBWef4IzvsFLhtPBiaeQ1EY/K+iNlogT3UzmW1jHH1EaVtMJxulOp7IsVsD+u75qavjM68u47069XrBPEwnPBXl1fjzTt4Nu2sBt2fapiuaZg8Txu/ofWcecmzwOkAkCFdJYEd5Ic+THqoeAM0DRNFYxWrHQmY1l2LEu86LJquzgIWoJrU+DXuaZlEOAzPn9lWcsw0BAE4AV2VjOgFZ3J9xz8Asr6BqwK+i7Ft/AWX7bSQ2GJzmeYSTXwiX69VjaMEXFn7LO77Qm2gOKzHP3XmeaoY0awRW7VC5hAVzZBF1aCzlLg077Wjc5IR9qtbWNROp5msdidndmdYj+LVhEchj8KiFEw8E41AJcfDVaR32VyK7QzDz4kedImY+i/evZMsAsDsvC8UTJnj/DMH2S7yfH02nCrS5CyzY1nb9c4kakTfHVjjMYTHievLVL/4wMM/htqwNe7HzwxpceD3UPugUL4TjmEuo5V3fhdRRcexbWNmrqQYph+Gfd0DKqWDiWVWQFTWpZXg9sWExkzMiHf3ljMI3cuJ9kDTaEBaBH2PM+5oR5Ps98fTnjuuu0U46qIfPK2fNGIZG3gufRFCvYxitKi/hxdOvpXqdTBwYRSoVhMBtC/FXwdkWKtqu/YVhPrBJxtsvqlacvIBTGLFc+q9yh5s9yx5scrlN2fhRe9F5hec77noHtxfcHoN30pwKIEMROmToPvx07u/WcVihx6E6vHJve3SUyZAAd10AKnrRDUMvZAmFviHotVpl3Xnlb8LB3prCZUwxA53y/IAN7cudZumRbGQZkO8mBimlqlAKlbeXVjKollvrBQt36UEwDDGXb6d9KAJ1dD3uIKGl6zaH2aV4E2QMsAgHPEXFhynxCkkwRvYTVEM0kcfpuVawXgieQN/023wiCbxZwkzyeyerLxatmPwSN6loL+b5EBrYosfbyeTbbiKykrR3idQSUz4EGjGw/fX7dPrEqBUiEw/eIGYcAz1oavtYjF/2oXwzcZZMc6GZ2TCPNi/zomY8Uy4yBqoVTfAhtJnEjlTL6wnKqeNyV+EiYbinvmfkAsQivAO259YXBfO4kT7aQDBd1osk+pbCFAKftKlwPsWhGpQqtf3xEO5j1J8u2F6PDN4YvhZUBZnb++wgbDBHBHov2hthfsLWVuAuboqdpK/UZ2i4il1Q2NUzDwJmah4LNCxrBtd3Lu0r/w55tgfftgtiA5ehGrSUX28u07TCLyWVkrcs9zXoYmjoNpzknY1mj/EvQeXUCmPJAz/wNePRyxqFFXAhBNX0dpbcbUkjNT/dHIFlN34M2T+7sEH86R35NRvzgGtBD4kt0UKN7n/NMGzbOx0QUYBMwBNyYZ8V8QKsPQzw1My8icm3g6hUurT0f/+8VlPn+Hv5HO5SNOwacQkkPjLO4OHMHPDlT4xDJMpf/rvGa8Ne62SFGzzKxo114irFgdySM7LpLMfZ457zIT5lF050LMr5zizIbqRRixzyR26BMjoUXjA/NtizRTER9KkmY+DwUm9+SMu9nt6tyRAvHytOBpMZGzKSbhetVfZPrCQnvqtTvgTpPU8e7XxT8u8iNugE2Q1NxZ0A1v7w+pjQya2i2RbDebs1T0tec7Oi1bsMhcFlQm9zMxYK2FfFD5oX8HxrxejfRqDt2+CCQ1O1Cc6ri3W11B8c3A0/u+ZMD/ce4OpN7rJTLbG71PW8Ni8agYTH8rFWpg5n2aZxtDhXCzNqxVMYXO4wYWYCoDHeNUUtj5Nd8REEAMuTHtF5C6Fo8E5I8WPLBkCkGXkWaopqtRyRUUpKBVzo8OLb0ZxEKZ/qW3tHVtBAU97kud/vawsKqeXgnq8kIwPhLXGa17A29NFMrqevZBe45612XadJ79Jr4/GVGdzSYQOUdsdTEitGatzwp2G7Ctae/x8qwPUQnOl4g+oIfBcEOEJ9eA3fxtAInC+catRJsSWEsY6P3ajaWoL9aflpDYdDDxB792+iCqoDLY+o150qvGbhok2rdfchp7B/NLlFvmwt/U8Upl+pFSgW5p5f5yg83DcJi/4PlJMZZ6LL1oK5VHJfEHBGsIozMAxQomxq/VCzZaZ6pyA7kp2lFD9mFUB3OHbwG82G4tL5xAXhwo9ktU5Wk3bgbTDT/YEie2G8MeTX5MjYBMiXfGieVKuY+igOyRlefYsOuLhtmbGSPOlQ1SCQnzoVkHZ7ZTFoQ8uK03JrB4pwkaEbcrRSYwD8lt6/mt0Xl8D/IYSyhywbGabfPlwl/0doR+gCCakbi4SvuQtl7Lys2u9R61OSCkS61kd69LtAdC6wi0uE718Vsi+tW4epDDab6NehfZS96Ds6SFozMr0jyEtxB0w+cVBD/lxyurbMbWr/fcD55WaKJPs68pBVlvXfkLzNvk2SYVX5fG+GSJOLttLqbfKZk9GAflYq+st/nbn8+ewHKvQWkUCoXLQy9aPlOY+61fBMhK9GkNHfxAvb44R/Mr8VnghE9ZrRc2RS2fLs00/C1ahkrkzaCmon+0zwJPukFk9MOUF0pCilm7+EUltoxjEM7kVG/SL2JPgc9g3WIhDhjD6on3maeIDDrV8vODmmv61V2HyEZVC9dx6iMID3Toqaf3HH2ZxZHU4wo51ct5I1uefcQx4gLU8VHyeqdPPwmzBZfAJnEdsUwOfYTyfJVaH1+0/SaTrWqgryknxSiDjLwYPAm+ov+4mi5bp8icVgWlesLUDys+8dRQUR+mBN48rdezjcetcqsHOaYzPFOLI6XDXp2spN7y62yQ73bOgvCWWckq89jajxH3HxHJraZPsutw/yb4rZ7HI55VcPQGGucRrIQJ1EVje9Ob7iqboTOxxz/TSyRVPaYTtrDZLbPZZ/oxniyvvH1ELyBu1KU803YjqU7bzSlp0yV4f+jY1zx6R2r5ERqbSAfKJj6/Ob7Z+bW/eeoaLkjv4vFtqaNuDtRvidpCI28M7JjlffBgR8/JlGwDvzBWZD5rFls0eupXQtEF0jrDxTc20R6S0xG6LMXS8BNLVMbxlBNYY6ezt+qhj2Cp3CK40NyWmmjNNzLFz059ChV4O5Mx8XIhpvRRyORuF4itSAmDVCj5bWcx3gPadrBS788pIjS+KOtz0AUFehdoVhaIpWERiiI0Szy5JoDngHdJafeLXjWANqmT91yuEJAI1BHY+7kpN7zK6HCnU4RQyaiWnC8cpsen0PtpzCHWTWGbd1CN64a4HjAvqPz+Y3+jU5s/T3tPrPDP8i93KnyozzM40ebznHqK9kUk0FZNe3ldrEC3tX57PIi3TErHP2zHxr4BgdBrku3NTRYfD1VsaonZ6dVtAJ4/zOELaQESJ/wWJiOnPbpgdxQmnOGdLIfAjblujkkhqxWQBBVp+rZ6Kvn6OkgjrDHnCMepMKbMfjyp2EFz3Lj3t/UiO5V3LyekoeNxtSIzoG+zeT27cLd85h6KlCt0xsvLST9DVF17uMIhA40S9hcRJsOkm/q0S1cMKVOqjSm6K7+cS5ApUz4kS4TmGw9Sd8zVQE40JD5tZzowK/T4GcAfpLkvSrQ8Lj1bxfxsN6yqXdRwXtiTy4qbcIqQhbeuC8dgtZMwJn+bfLdNsmpAVXxe9opqUNiZpny/nRn0wZQLE1ekTZA54SM3l31gjY6JmXWwCbxo2u2xQqEXEuv+xd/KkevDmjfK9m40KgJ6ldaIwbMcc+0FSM77f1UwNhqiPoHGsrQvEcWbw0QPfh4gJHlGsJlrhPYMkPN8YtJnMI7Vxyhzvj5I6jWRszSvXQSYrFt2avCgF93on+BiS5IpbsjBsH6HDj55vO/LfxdQaVnJt3td/QDdb/77WTXyFcnRhWneXKJs96SRPzNQLUVaPThQC3KPqb2c+yS/9kIgNQsbXzYnJKVuo+38dHl3hYMqWxYUen5o142evxaRCFq+F9PCpz6VX1fI8YsRQf211rLDuJNABL8C0GjcMPqzBehNR9M9JJkJTdys1+laNZqbtBWt2Tkr33Xo/VMtRFIWz6sX+7u4QvgS+nlBgp5LFJsIU+0oM8XZFL0y70nusBdNw6S2x/Ixa9a+6+AM/b4+jdmBMmVSTH6Q2G6+sHVx+45sPIklzahzSkJ+H7fHHNDYpzQURQlWoBKzwnUrDt8q/hD6HPCKBZL5FkUi5EOnENs1CyHCLPpDbYO+ORihUFbcEXVBPCsmIfftLyRw69kSfaPpMgR/5H2IjQ+W6Cq0eOqFnrSKW7gW8K7l8mYjiLLo3meaZ/gp/ojtjavmz/L92U5Cr8YCcH/0NgZhkKhOXVs4xTN4exsM6YE/zub30W+MrEvk8jfJvM4an3liDi/69SdfXkG5P9peDG1ZU8POSJ5XhMg3JZOJBfBw8c39MWgP9GPUyGGVRVtDFkUcYYUpOUu+imdkditqhMrsL5/59ZlKMgUdoUYQ1kDBtmBr5807StLUtt+l878rmnd02bYTN3UQzatDFkRqa/Gfs1OdDIIk8l1y0DjxgV1ES7HMSYt4r46kcXB2frYfwUVMvPcJSLj/0MJgQnga7Shr3Gf/iGMSK7JwJNDgG+ipxbSsaklE2hxTd0fpfhVoW6ycgeu9nM0ccDqwRABXq3ngVQeYlWGVkvtIuFQEn98ANy7fos3t09koGdhJxp6Jpn66AX2NOHazw9mMwZwVKSmFTOHJnB3ak9smFm3eP8fVXfjPKMF2wy2gaYTnCPH2bS8SjOS9mU17p5xjc5Ans51KlJt2YFBgHKGt9JTvX/NHOui0gDHCp3QDBUBSC+I9s3MzCOwL21p0Or8GTG2b3wxaib+pivzh+Y0QfiSf915G38xd1NWS6lc+LfNw+sCwL6WZK77LYsJD850rKUM2kAESQB+PQdd4/B6oqgnIz2Gz/YLdUoN17AjHZEsatRlmkVaxAqSI67HQsOuZhXj1JqXTPQHTt50J028Yhw/jw6O+jwpVdvAa1+HJWsylL8pOraArQLSmx4fXZ3XB2AcCNzh4cExZnxvrViCalTe1lfbhaacRfwZKd0pz6aKZsGp4g9FF6aHkxSdZM3/0I0964VIomtnv43hTsdyuBo6TWaHcbDgx/IdN6uhObjYc/jgACNcr+f3YXxhi48c5Ts2OjjQPP7823UQXwLNBu2/BjXHlfDoqG0x58nt3EDEKC2kP66tFBDyE8XQxswaR7Y0CPOJMnqW5GfJkrGb7cMoYiYHok/ihk9sbtwTI4y6hZiZg68rAmXStSd0c7Z1aFzSOs1AQ4/q8KG4cpHg+B1lCxc9UUJGSFQWyDQmcjyAJIaehAXthhf569sk3jOrb3jWCuUl78OPAO4/I2/HPuOC1o5oYZ5cIAwgo9P+23PUHjnc/7XzDnlTnhFhovaJPx2U/ZZI/ib8DZLnqds63QbG05bBCMqX4KgOpNFtYapCZ4uVwy49fnm+MqZHOn1wO65Iy32EqROTmS9PBHGYGBj29TXVe/qgrbkXWtKWcT3vJU/V2v2aR4p4FQ1rmhSv/wSLqDkz3oRtva4yWQ2sxKCsR4v3obpDnPgcu61NVcR3mfuNHv0UDjhbf/PRMDx789wa2E/nZObrUkIkr90gViYqvxves5S1pmbPotOo2kTbXLdFPDUaFHZdMM5lt1DghV+e4iJ6M2bG9Fjbn1gu+BtwxM2VzImYz7J/bRqwgv+7XcRNvNfScplMl2Qd9vuMJLabdhKoOG3qXZFPwfe9kzlQyvaLi9mhSgn25+Wyzff6M+1EUsZhU1/Hlyai/rq6Ei3Y+p47fl3vimcx0UBT9Osl6i0fc7B42vL9eW7lu5OpJPaCERVlwdTOarDB3i3Z963QabhN3MbdbOuz5L+LGXQiMOaawLP5JRXh7cilibqLPbp/ONfj4QzfQkHAEJKBMRMmrJYNiHx6x6KSuKEtC3v3iixbx/MOJbRjvQ3q4QdBkagBfelGMhdUuZmPDJuMEM0V8Ntsc9aTt0lngGuJgo1DrJG9CA0ATxlEWDd1eBNkJ8K+Ct/vq+ZDwWvgs8Cg1xafPt33bmpAlYHfRO4uH8Gl+zHlXtPupe1+NsBUONHufVaj5PDev79E2UtZ1mVjnbRBRnSl4b2vtPmzeKpSYED8smWtrrge86I7jc38aENpuAy0dtrPwlFqpbU9xG738fj2hLd5z4n1/1YhYP+Ovnb7wSTXT2rkCwScWaHmw7jiHZb7URvBztfIGurXY8AwcA9GPdV42Hbyv6muYQZWa2H3vJd4edoFbP7YzeB3Va2kcEA/RyZTXO9AmseL0RrosMrjq+LkZ87ni0DTl3ixMXjMsNB4NlMFSfn1g1H8FZiVYt4sES7rF4lRFc9F8DyppSQ0k+mdhe9Xy1ndOOGq5gnXoKSxnwyX94nbtukj+loGUl/qsgjtv8/F4DqOmUFpxvpHg3IqWZ72u8iEknu+7j/ZaiPEDEZ1QcsMaUheYCN++1KR+lhsvNaS2KUieQvNvr2rVMiY8X3jmZKHI+0V+HBpaGlvf6ZqiADD2Qrlp50wG4s805i9NzYfFVjionojirslSCpvD7eJ+/cXUsL6V0UoJPRr3CF0dADJR/gR1m5NBDb4oNPCY3xtnPJKONd41NPKBzS4ohgjpdLW3ID2D8Nz8QsG0Hq6vXkBGh51M3/qB0/Suj/p91UvJjb94VbVomfAoNIkX5FPGZwp1Hc6uZquDscBuA/tlvimN4aK96OKKUEJEdvib36iJ+eA8ujhmK2UVbTj+lVsYy+RIbd9k4E3BMJROWGWWoD0IyvYtFnzIom+olJhpVzHbLNwBA0d7siRvRLgQqjsC6jebWSGS/s3L6eRzvCq0b204cu6oogfvU+REa1iHeYJSNCR0e8fxjsh7IQ8T9TlGKqZP4ChRrKxj08Znput9WFnTZkpj4AkkniFGc4kpaXDAurvoqWsCHD9B6Ag1Gb4YGwC57+n1SGmwJ23EPs76w3Z48qKutosZPWX/bpbAtST4zNO1ODJEUL6kfhelRJ2WNDYXxQy+oYMhhxMTvfGyvPEEEBjrhS3wUP/Y5hfiNo8EHUiV9H8/Cr1ZvQl4srB1ehYIaDIf/EolsaJZyv6UjaIixm4/URkMSjC34a9sbrJsvB9kSvPoo4681hMZyrn9oScF3ZytP1MX1c09Po3fE85SveMIEoaxeWvEjdo3aKukzWy+btNEBUwO2Jucta24ULF85ab3LhqK9z7xoJIepOTxDa9ThLbhlomV4fbcPyxSbYs8KhZt+wMxGf6GKrSE/4bgcjyoqLHs1/iM4Btxxfm6lSExogFhi/SGbT5t56e7fk26t8zi8/7wsu9VmaV+U9KaagzL6GB+g+at+LpuBKjfIO+FwscnMWhO07EdRSzjLYQm86XZDdG+yOppUItIC0Nib/p9WnRCOr00sjgDErh2b6Vu+WmvLveKlChLJic7UMTgJrvFYUTXlOQ8A5lTtRcIFJ++t6Wac3hG06ovuqR4i6BnnlSEUTfYKKo8OuFeelk2f7Ax9OUB9h+XO/Sr/bVe75syXL61DFPbrYhTL3MnhZjz0flS36/3udNflWBu71UdeSHldLK+XvmGtiGm0UKcg1frEJn1nhtwc+R5ELScRLVvR9xmrb9ion2JFuCyQ/KAiF/bLN0XD//EPJ5lku/oyfgtyRL0ucox2+ImXYRIQ/601LhkDfFTYl/Jh2LVcfJ6widmFX0HXHaaKV0nEDxy2WEkId3AIxxF35qRrzTAtPl0sNBNJSRzbbM7D05m+8IlLPF4hcKicn55x/3+Qzt2SvwgygC7bIzLoI8Mo1WA01LknOOFaHs6HT+7m/iuR5XSBtPeyJMA1HYjn2vE97WjP2fDXhAJmH380tMO17XioPy4JvI9QSMDWoFx0KfE5CgCNhWCMLwj5asjxEbFmcXk1toIQrpDljiYXhmtZkX82YHQObuHnwbucfCRMEvEqkz1EXZTGGZjttObKi1hdr6FRNM2U50vwpvPIO53hwwYCFyynJ+vHUXy+lQ5vXcuJ52GqJqKdFv5UIW97GkvKD0que6M10WcYEzMeBSpdZ3IhfyzdrItktsiLv18v4y5TgkqzSMQfTPcMNGsujJuwaB6gckcjnppKS2Ys+Gb4XGWQkCWsSDZGGzQM5V/swF0Q08E63jChNe3t1xwcN/6GJznuc0EMVxbQiRt/Ppui8T6BU1aOQfPJmVLTiGA8EzIO8Fu6UHt8RLI1psrDGLcYeATD2g3Mg7NpMl+rzNoV5JDr0DHL/ircWxu2TaL5f6TEEsqd5D/xRFzep00BraBdsOKS3EXyFVfX4fM4oTvum+s3V+SNX1oe5MnGN8gm81jKx6vutLt+tcBFF3B/Xu+lBNmQX1N3qJsjM1smDXYtyiGRJDLtRdiJn9rbneOBKhDny3JwWF4tg9EeTWgpN51u5Wvp4ViFk57hO9jVP5txFz98rl3Q01WWEx1rej9Bho4xh45xG9/ih2+jMg9RhZj65hr61tjJ6LXlHa3OYy5vZ8ECCJOi4pHHpQSM2DpxltN3+KdxFuBkp54+Oxo2Z2Fpnd8Rsmd/aEkIdc0TV9/wplspji5NT0dT3XRxfl+DeuGRagPr5LhwiQH+pxY6lGtyvM9BQ0tIqYY27Vrcbh4PUWbZFCB0XFqFc2w7YkRZIfbaHxattDhddkRMU7GzS0i3uC2l5xFv/yOCX04YtmyoieP1iY8U7CAjuIK2jRYCp1B4grawEekDKodmR/V+rmIaXnRklJMljSulb+TT40wzZ9EkZAXqjcljUMzU+PsZL/EDMqQ8E2zVs7qQf4S+c6v906TPM05SOOybYx1zrwyBUzEOEEYuzeX0/5UFUSyDz9fUeU29Q2DiMzXGkLqDkECNMgO/7vyFcC62X0yLCzrZJmS+UeVnV/pGGwcuW87nyayiWD4gNnokcdv1dL9rOthjPEKxFXUPNPwmCSJ+SlZaAebDO7PbrAu+lSkp75zOyb2doDpHGSWVDL0UwGUW/jJrkEBjV3YuHlo5O9C5S9Nxmw2o94MFyCzEv+WmN9OLJqa0HqitJMVHL0BC79g7L2GUflrVjK88FSm+7p83ez650I9ml/qGc8XbywhG5PBgUCq1oof512RRXYNVBZSwlYrAaq4J3LTzQEiflHrxFJnwZqWqhEnv0aS3+Zy5vbRRWpIrsOOQTtEa9RfWOl6H2ystTuOzx2OESBx5ws+P5n8wdfT+ur4hM/nVQLQU8aPR4qs9LJMBFlhsf2B3DCpq6LHs53yCw0nMXU11HfF+SpnLhyfV2Xur0/wkSW92gf5BbBO/8GxoptSAGPL8z5yv4i70cCf9CQD5BVuY5fUZDJsz1VfUQeQlvkkd/WrI8WKnF+3LzKMmA285Qwz0g6PXPRqxZyOMDQdx4B/9/W64s2BmbG2oNupCYU0WY+KeXCyZII8kgPkRpmyOSFSQNql5NKiQ+IVBVTXtATLYBq+TBU0iG/21VIeEi+zoVtD244mnGTEW8KxCjFEW+eetZCq8YZWFBTj7faoiIxEp5AuSdxISDuhFmH77Mau0L89v+96JlyjBIbMKv0d7lB4SkerG69f86tR71hc3qgR3fMF1Na4mHwk5/zpusjHyS3ZweqWhXGwQRPMiadZxTcCKfwUKqg0XrD6nyIEOnq+ILMsccQKVi8tTwNA8oNmbyjlPBXdIsoXMsRAw3oppEZJOE2p7oEV6JM2EKaLE3jVgkRQ0sqIltIqNPXXSyxRiNMcB+SRRD2KPpONGGR1ZlpdgFULT9dM+bYLMLkVv9HcaPaUiEgOxZf6/m8/oDi/JeqSLbZCxMTvs3V3ZN43l2UmUIyZhie6NstNEIDFxPpOWFR6ade7sPC9PmscxrTMcvA8EYYb/4aklt1R/pFqgcSM6DTwEEbad0W53BWKzcOR0xObNqHotGYt2/ISoscbfKumY781zh+lXHYN05umVj/DYjvmUPU3IZdRmsYpPngOgaXXtYvaSKJuC3qpwnwfNY8Tih5ZkhkIjz8S264LxP8N7rjfyfkPxRzTzPTNtBYAViAKuGoH3OOzYcK6cH8HWQyz77OkTLY9uAQirpTFm2aGYDYS9dFTQq0bUXVp7sHCeFUEaATY84hkj65wvzbNCPzmNlqB648GisBlW4MXI+/7AZYRjdJ5p3l/8OHtw9bcNvn2jNwa9iXTLAm9ScsrwPJlH5I2NCzcZLHtXBrTCLTfbtBVkqkzujOEcDttKSkaqKnvRiyJXC9h2vAVWXkX6AKxXnhSu0NIhUKFrjd8pVZhUg0lS+egyDTLjsa6PSQ5TR31vU1G3xdHqJIiW/egZpf7cgLTBFW2GvRspNtLj+V4fmFZoiLk1SSyFczMRbAdJmws1b0Tdn7zdgJFebrjn34091C/46xsaVJ3IWS9vdA4lXeNGFud2gk59UHW9/Y3BJ59wLohsSU7lNlbIkLh1QEPxGZJBS5AZP+eX45FQWQLfpiUPYMhLPRCfwnQrrr6hLc1yGvyXKQZ+V3/fgU03RAuptkYdZDg0Rj3leITQCAQo31H8jPFjX1zGbOb+nbfTDnJyNOAT7+tNkvoFCFFQmYB1xpmHCOEKT1X+RSTBimZ00evI/6LeWTjJ1k2R5q4QEwU/JTzdejF6+Ct7rqg/AVx0ku6KJPKpBKolR26I2SsLGFOST0++NcjxvcUCx2UhNO5s1I02V4CHVuP4bIthRF/y2SfVFY28iCfgeXyNOeGuoM2QMKEsiwD/SIytI4yXyLCqH0q1I8TVSZJ3NzCFcGuapN2NjeIRnw3uGVVnIGzbmWHUwS6SjO6v094FeTTWKlwSoMiBhUK5YfN43Fzq16XLwXBn7VxMI/ecUO+odb2Oz9c/3r2uvj2nhCQRGzpkzmefo59G3JM6mhFu1NA7z7kLaWGacmHFLeFlXG5Dbl6Snslo3O7KYOU4PzChH1Yzp3o/TOqbynLeNntHWtZs98QyVL9NvUVvBMXRzSDNK+nh1HQqRx8sHSVriEYHeFAeGpWhSChCZxjm5NlBaDR+XGY07sUQsS/q49p/TRRzALDiOYRdF5m63ZTr0kjm6A98ay6WbpyPtsvxUp/PWIF1XIRAqMRJuA2uIZf6ELSBaG0XWU8PUvp/6uqKd3MzE2SO8R7l1ZF1f0Mfl7y5HGDlbL3Zf94+3U5frI9Tw1CAFa+fVFrkyCYufD1LGyVphPimyOkTV9J0+8+HbwkCt3gCagTiXJgRAbZKXt+bZG3brYLDOS3yk1KSOtEnfeVDDOCONSb5JYrD7CCft0g36k6GfRctIjaBJ+lqpzdzwAas78IHRsR9JJwBzbIUqtAo4toZ3Sp7YExw2u3Wicrl17sQ646btpXHLxKOylN+VukqYExd1YlWjctr8VR9smV65IQuUwsf8ovqVXvChELplYXw18YOZvkAFAbnwE4KFbN0x5dBQ++LpZty/eqW5N32mXzkUyaNkvz8mpfFVPyh1K+JZ6mVD0wLZdKbCjQBTqVm1XPnaeV7DT+nlDVgazu/0DAnrxlHS+QTgSOG/n7v8xT8kMxKVh/M5a/NPD7TFjEcR4fiHQ0ublT+3NIv2u472Eh3u7WpgRChvlNhytT/6KHer8M9eBQJaOWvV5jVHLkFbgbu3alKLzJqEO5C6vNwuac8/5mJ3JOCFOSwt+oYeWAQjdjcQ6/zxM5g4xuQn0otwEdfEfAdq4QXhS6e/mkgjzyTZuYqiRigLhQkLDzvcE+eXuuac4QYiinLyxm1We1fhBtoFV+PWqDdKKSSqk0H/GFvYobIuPqW/8klpys7k0jwvterDieM1IBoycg7TEC03h51uDLKMJoF03J//E+bYeAKiXZlZnVapJ8Bf2+HC2L5cvWVtI85A6l1qOA4lfDW28spk32BYCW+TdDyR6L1HWSVPDHpOpSfp3aR1g14b0xckxSAzfu2KM2oS1XyX/UjzTO7IYPgfJa4HN+AS8T0ECyR1x4luwwHm3GxE8cls/YSRSoPDJYjf2KG5ZqMYayyFQec2/k3DZhxJ82PvtolBMMWvikXsiEOyzf+3f4SFTByB3Vng28RQx7JDuOO4nUvikPU//e8B8bQ9caltd3KEU9H4ijg4gqnKW4xa/JCTdPf3L/XWSOR5Y5/s8Bl8YNZnkH0aB+97CQtHYjzkhiR2xez/m6Fetm5bOOdl0bxs8w2G/DCIXeuAklkWrBiKzpEpAPizxUbo/vmtY1PsNMwaZ9RJ/01xLDhtQzJ0Lin8wfq9RYlikQQgxvzCVGSW50qiBJDk2ypvWq01rDevUmilPpT2tLm03MBahusbF0+yd5f9O7IOchVU1A3WG3HQKjEpP9LDUd5mtdBpj3m2xUZKWec16Pj/wtfcF4TcUoKXNF6tomyz+ermPLUSAJfs3e8eaIBwlhBMLd8N57vn4penYv89RvWmpUJjMiTSTy7jbLnEb0VMd1x6/bIYiwMw3jq7+v0edQ0VnMCMT49OaQxUOjPoev59YaqqCs+GwJ/ZnML6kTSRLPRzoKA7i8qAUJa3ETwu4GbzenuUZsCs9rCY+EjTDAnZfJnUPsZzU0Tt//Dy+11y0fK/KRMoKgZLnC/jdHH9H9dr62GMY+mB7ZQJwbGG1f1ue9rqnvLwy6ubjQYtGnKScRuaSZougc9LTHH6/bCjY6YbJ1KSp532BYfmyajDFPQrSqfihm9qDeKfi+WpbVpktcNeEl8bPh+6mdPp1R96VQlfMtKYMx28qsCUsNWymfW0dPy4TGFZLsubcvQY7ltjt8xweoarFvUHaQ5D9wTLM8OetZbWyMpNUaV51vjSZ5BIUW8tODI9kJmCdXxAGeBn03bRW21uR/64swkrfrjwDR3Jj1Gb8bRlYleUl/m64gLI0NCBF0GCxWc5DzPsHQ/MbAuaa6TfajZy53KJKTJw13/ibiia8pNTP6h6rtOYRS7MncwPA3bMg7wlphykEN06WbfjFxAkRlhiBK6OdV80tNG8veWQyVENCGyJy11+Kf+2qHJjnpHmsYFP6yX/T2NTcuBW/ujtbhoskkF1wwSc7wE16e00072y6tbKIKPocEmGsSetsG4tbakH6cg4LFwrP/jZj8DezPhcdPPR4fkrNNQA+uuiYL4vyqH6tuWGXN1EfYDhdOnwjYvX2BEjjmhlQtSG67bzyqpqrZDgIo+tIgAhKrrPHU7WgxTc8MvxoZgpByu67LTiSK+nGN8ysKgXTcGGUUQQH9XHIih0G+RQix8Y1t7PcrFa52xog12+8vqeJ6/2Bzqgk3RlCo6sufnl9dEyp/bFvpjAPLt53ylu3p1e37NdHTQL6Z4nupUlhj5bFh3qfTg7gUryU95UsU1X6+M0P7u5MIJWE4zmgQ7WfzOzSRM5V9ZqtWHuyYgrhZQfXtiMTWRUh1eXfsAB4Vs/ecI5RsXinBUbQf8FXQwkgeEQWotM88m1VMjUYReYXUJGKQp7EVOeYXraDNWNg+Anv+sm8mfC3sReGpcX25fayeyX9CmM7VdB+YaSxSOlCrclFxUBCCRzl2LgjKA8+2uVgYNeclolBp1d/6VzQzE2mdgu11aHyF1+clRUanDKratFxjrdvxhtAbyMrkRKiecfKproJuXVE2US+rpmZZ93R03qhwDIjbvvJFlg9NmiApl6nUfGHuR6pHtDhBt7YolCAEw+f1F0sqpQfuza0V7jVnklIJMy9J0MoAuMoetZ+sflAydVJgs6vG/DSRe7+2musMVt6PL//GzcHWNl9sc989Qp8tyf+meiVhNdo0U6fFX7IRa2B81pIO4uDG6pdj/RBeyL6SRycZJC0ZiNJUfRJkWXatbNK9jBsRPBrs51ZIWBj2E8HK/TTrlEoY85+yORsRCqD8jx6u3aM/brOUJ3bpHHSKzEvp84byvYg0HXi+UJHc5ygeBOAULVe0JVad+NKPcXhxjZ51Cgihb3IHfC29LH5KQ+P1oijJ+bw2qTniX/nh2HSoJ+HbB2Xc9qZIIVHRj64669M4orxsu9uOsTCKLSJJFp680lFcaY43UdzJHUGu98+Ed8t/U6lQlGx+CesHDz76kfoRtbIi1FTMO07Fqv7mQdl3NT5mN0MwwoLpyiwwesNut2y2gwADU6NE7uddH+0PyvKbtyAlj4jjOFi/uJ5mLKnZnuSD15k608uZQxqyyu1IQUjV5K+rz1IXcXeRUp6a1PrNoOkIwjB5QyILLXHGzWFcbQXX85VV4duwAxfvh/xHmyS2gbAnC2UMNH4eoQZxC1oTGuddgzLI0PLkh3+bTCQkz9/l3On47LvCEU/4yRlbBPXs4WeE7qsSDxLiiqFZYu9PllXEvtP7hY/RLPOh9hJ13c2s7+cMW2V6gSdVRbzcPRNCMoOVVJG6xHKe151APc+nyYiENJ6m8eYwIA0+YC3wF0/hghp+f6UiBSdAZczi6c3jk+4S7NFSQHrL8oyhZ7JaSLbvDQGt/GAGT8UP+je+zEzMe7O+bRmzfereu75JorId/Ap9GXxSSNvhLvpxNTo7pcaORBUA86H1C8SzChInDXQVPV4F5IH9AV+4V3wajL3kN/qTup0M9xdkz1CeBdEAJDCobALM9iMsFvK2j5Pf4SdAsFzKLMB0kkr5bVtAqCGl06/o/QI6n54he/z2E745ScD3Lch+dZtPqC8bcbsGq9qbO7jcNzPYCNXF6Y/61egYdw/Di9NAS21hLPPF7F6rSD9esgzjdGUp77rf/E6t+UVFUqnZ7zash/ZFWIXSHXNQSF+EeMWa97B/QxKt5cAxCMV8Cb7t5X0pV8+DmsyAaMo2+4WfbmdT8NI7cPirNrBTlxTJpkIulasPJ5bG612ag2AJmPi6b/9aryra4pKlvsxY9h3fLS3ghpPujQdZMYLBQayYa5rOur8Zc7APGaRTxjfVvZy0oXZ4C5vL0tbqiSrXj92GzGHurwSy+aZOZRea2kTEy3VlSihsIJWvZqZAv/eCUHGgxvIfMExRpyHqJMGgnuheefgbBgbsfFu3f5NUc2WKJWbY9zTUIaETI1340NFPYT4IHdVEC/ciYm065JfIzJdiJ4TZ4igIrwREV46Nw2wM9RdikhajdfISXr5uj9+2dfjdHgfVI+vl1SEQt6EVUz76Eiqo7kV9K3vp67yDzqH8dX5C/M6oqLHfe163/T2pT2NI9Tz/AWP4myDjm/YBq/mW3gRlcbvH6zeAlMXbq+edWex7lM/VVzkET69DxqiEs5CY9HUzo1qPxSKi29cAs7bQhorWTwNnCzcXLdnwaahN/EXCuajGJG4vTtCyBNNah8/qVlRQJxjGl9D9TcRdFjX9I73oCTphcVCPAeMGlezW17Voc0SZNJpWiF6B0Ns+EFM0e4/F0YXum1QbTbFyyLGgOVh4Yi3bVOcNZjxB75zf7afrtIGIrwFVKX7mAZ5swWsNwcUa8gDJUWLiugahd0o4gFcmFUS/4q9hNplH0KDEMAy1+YektxudBtZp8eGwu16zcW5818nLtHAkWghmoUP6rfXh7S2Qb2qbHJEmnXINlt/6Z821xL52F8WfHJ7leOF52FuCk4degR0BuGxHs7j8gpiO1IAwb6ikxirMIis83XfV+Wkvfw61PnYqlVW5o1SOTN0j4h03L+QlhdW7hWS5LPgKSMeyKafbhgi9wNaLWy19lhfakzdBwBxxDRWUp2M2vr2CeM4XxM7GuflJM0g5MI3TNeUurlGVqt3UjPUAPwCQnR5/x0du4RVluiKrEoNguoHeTL6DmVTOkXk9drsPITeT9o5Yx4ll0GmhcCfODDon/wUv0s0wKy8z9ft3R8gK37OeminFpghhQ1owC5lNZPKSoC+SlxZI/7m8AEcyHJY0UXWtiiVkTartC9HIxYXchsAhdIrD0rX1r3jfhrljfVRfJQ06uteY5JR/BK7sDTfeBVHbZdtpAzKwRSBJKhpxJymgzB6wqTkwyi+D9ei/L+khv7xcYAfPPB7baM2PaqrVaYhX2v7q36qV9X3mjeEXGzrFD6za49CZ5e26eT3ZdWhjLVKkXNRsobaj6rFroerpe8TKdcucadLCaYd6kpuIgS2Cx4t/jTTPeoyE6WkLtCprafvrH4caBpio4BmHCWi6mfAo5ak1Jch+266xRMqpbMPe+JsU6yw6vf059Isous9psx3YvwIPb9xFO4NYuuVoXOnwmTJOE3Y94cYmcEMCGosOSdgt0BSwUOmCL2iekAoMxOtY+oUsoaqg/UDqpz5GBL4D54fAidOMXD6Z+Y9NwJHWJw+8/UqSA7799/mWjWO1MJ37yrWx6hVrRUPbHrFpkw53RtvOod40vyuavuSDAE4JJmPzzWXNFQY+i3NqRwicBj/34KqOSVd5yCm/TDFsfN7G2HmDW5rrpYyhTsY2Zqw9nzlMVKdQ9JzzD9yqaJIlcdg/8tcp9x1LdaWwFUS0e/nHABPFpb2RcWPfHaIARagmTXj0hHc2fSUUBngbT0I0mTefAJibWE9XWvRAhjDKxG+2EnvagCTh9kzfJbcvKhbi/voEGuXpEztLm2LSEZWPqtnFOEkiR9h4jRtjQRbBwZaRckQOwFAm6nJ9P2LGhpA2QzObnMl0zsUHdu2A24RIjUIcpWNtEKoJ1TQx2DR+ccUaH2aU8Yvx5XzibCy+0zcQjVCcV5d7nZXXiGGhq5SsX+ma19lm1BIJYqCLUx7ZxuYqkP9ZjAJ7KaFUVx9DgeK0SOthjIqT+DkYoWAkFR88WE7DdZKk2KPvUDJzUNF8YUK/NCss1iiFmRVuJmC94poyy/Mmo4TXUyjQDVKVPav6Suzwyprdrna6bioF7zqpbPOX7lfNk4FwdmbomUUNJ8NOB8zs/eKvmHfkTsCgyMwl6H3w1w2jff42EMg5kfKwlaVZG3G3tKQ4ZUnTZ1p2rtvrOmlZ2V5w1AjxYMw5G6GIFp30VMm97TJZLzRON7Ko6Oy4H9JD5J6XYzfFRfDe2k1o+qQaTOAtoLe7eK9LPDoR14P1DX0/uO+7mdF/WYRejrJXxtxt3vlukNejiSeWEEVV07KtheSp8KgQfvsqWXC45FWovueDYtlTDWbMGoNHbVY/DlTOIrc5T4p514dgqUaVFgrmF/G694fi6sLVwZQrV1+pb0Ro0UrmYlkmoPkX1NjCJRTm1vkUrIFgxCe7rvsmgsAcyfELGgli6o2+TXWX9AtpZMItU9vfNGwOfnS2dpCTqSrjG66HS/7CWeEsFRYCoSCAH2gsO3jIKzEaDeA+yvMfwRs0O0EBKaMibUHg7u6sNk4KLLJGXtJnHYWGiTT2yG69y3jb6oPHWm5uwXlFYCPmUdw3EEKqkt5CWOyiLFRadvuR2iEt351TkjNV9H/lLvIOMbS+xVe8ftEJRDx27pkMSKr6YzfcqMDW5NP508v6tb7h1afTgODv6vNUFC4eRiuqiIhvq1RLpX6JgbvMXya3CHmIXy/oJWin7c/GQHnVp7X9L9j9yNhLT21WnpAIku0xisrlLM2+xqShp0ErV+KvusMS6o6X82ay5/nxdco8dI+mI+GShnRj5flKVbQr1h0ZMGhrPi17qJDT3nSNqhqa0Wn6NqQlApm0Nt0W/v5O1Cd0u/HU8l6NS7ZbGjcaTY3OowL1AX8HEOGikcVqglhD0J5LUaSoGYve2lS3EyN0mRtEhiuqY+twgzpQkUPe6IZFqRBdY61pjzcZ0CU6flA2VTT3enHLzw76kVrU3+czqrXNbjdhWDOsy4xpXdHS9Qx8CRGSW5wkvbHKupkhOsEtr9lJXBHztkHmT7eQWNtXFX/yR33+q9eOZNFX428S46oTXX9seGO/BJWcCGjyY4PvZpBP0hDMCs0O7GkC8B/sJseVekGvw4owmyoOCxtKilSxAbOwRhu64HKWnVqwfNpd4pcdwP/gIAYTO0l3SniyQFUmsJtyo5NcSUhv0VhbzbpgCLbuTxyR/QB2BRmoAFIqCGLEny355cmTCXzS7CSHzsDx0q0fLc504/4S1dT37aGUkfp0TolH0nstklnMQum3mfFBUJfSeTuNRQSPnsB5QItZwJT4YT1ZJW0k3NZulh/gY3nNq4/LC4fkBGXXbqyYDPE21P/oTzmEbj+zMRjjKafnw//8m+LF5lPqGvHZgZjFKtnXcQoaRhgESSUMD56XO4q/X5b7R0u2oG4GV8SGgeZG11VQNl0gePrSwL806lEa6nUIbx+gZPQI0lkiuYgBCY1v008lZOr2i4KYX+tAlWfvvFfV9mx3hnWf+WvkeXSk9yohwBtwzRp9lxog8NEQk1mlSbfQZy4I5iDQMdeXp9rl+RejkwSKBijSNbZLlW9Ds29GhSC0uK11mmAxILuu5oIqtuL1yDS/4F9QeFpI5FNifmjLBNFBa+Hp9b5TGalH4wh/O5sg0hGJXudv8i2aV+2bbd9Il73NG5BYZNu9Dz43A+i4bUZWXR6660X+SKmwQEIvgZnJnsn3rFCzepsRt2rzBKnJzbiohf1uQ0pqLcxcKxJRXlt9t/1G8Bk2rJsxx6j3bN0jWdNiSIbRw2ZQCYJ6ewW25qN7iGoPIAhzhetXCCR7Nbvo4yFRHbx1ZudNKS0ISZFvtE0Nnv2afms3wOSK523gae9ku5eziMwOLSl0kiLaZ7teXtrSsyYa7Hb8XRcGlMQ8aQWJ2D89jSgaoU6XUaeuz3jgt5A1E0DY36IE3kzZrVLy3ojF1Oz2cnnR0cig+YQ4lII1CJP0v+Z35RHRTD3DdBA1CtIw/CQ56yUy/Gz87Wiz/hHO47ZgyCJkgegR//oSpdFPiiSz0mGkEF3exjDaplDNQSR6w/yLdt7f2yWezO3UX1WyrZ7D+QTkQxwcSnDq9hHRcpNbl31/Ni//198OMSsI1rjmiaG7gIgr4zqUon2dcfKWY1S2iM5vub3ef2LrFiVn6S9zyt/I9O5kzvOsFk+nJKjilDQra4lGUL8asIv5E6ilN6t7K1dytW8bDoC3ZwnZm2f0oriNLlWtaI3PeLZxJDgpkJGCM5+6AqPsIO7S3OvMLIa+VvDMx2IW1BIt398zlup3hc639wjFQ71N9gG8YWhSIPZ5RteP2Z4g2m1veGehp7GLOI/yBo9ER/Ll/b6kvAx1ijtgCKgocpjHv2YFjQcdWQL05/v6sv2cGqdKzUXBzUuhuYoU+E1Tq4vnPqTZbr5Mfug4P8dcPKeJB1id8DKg8IVbe+xLUj8x8Gp43Ibqzbm5iHuvnnQ0y+2HUjPK9OXu+DWety9nIMffdHGMUDWKNZfv6g/Cy3V6vKHsJSmNR2O9qH80+uPb7WGb8tVS6NnRDDC7bF/yfU5wKGeM2dcMlN/+QTVucVkM+3EpczAvhxu9E56ddn3UhijiGSyj1Gu/Vpc9htNpM2t+nbwyXJu4EO6o8a+QfR8uqo78fQebX8Y57zNoYHf7/V7G9qqkBjS9XZPyZvUyWlPkyPkbwU/4MyWht3iav472VGManwsb7AokhPsCe3bkK/SesDojmyajrZipVBHZD7NAOkopzmGCVAxKtGMJln2kOdPaSULuQUZfswcKDenZWX7dF8SnUEgfkbEn0+lGycerlElk0UuI/v6AORyIaNTMHAqJaDK+7Y9VBRjZ4sOHES/vLVbzMNF/U5nzyBviYSQMl2aGxBZDdPa2s4B1rOmGcSQtAzveYKSY8JdBHIg1mCpVh9F0oGPL08szbUWX0yrZr0j64Suh/Xi0ET2TR77YF+PjG4byizXnH1ClmNWvLUg09PElj/788imId6ieo5DeVzsx+1gni8SZM0p3Zmd8FEAmwZEViC5MpTjnT+OOu95ASNa8dy354Wo5rNURje9+Pk/aadqIcIYW7st+ui45GnhvCkCwdMnebeJov/oo3idXI+q42TQZrPDsbfoSZENDwfeJ3sc9FIdCj8xFWHqSZF6JZ1os5+XrgfYkJ+d0ZL6sG7XXOj3CmIPpxW+AXilDp6f09sdt5d090UhaUJJmYdeJWZ9aBoqVUfuIRcqO0M937VoHMahZTB4lQjKbuvCF5qOnlk4VzGrUwPlysPI1MEB0nnG0kGUo0RRihRBi/Rw1NwMeHNUfxeL+hjmPhqG5mxjw1+ZnXjuC2RY8RuObhbhPwyrYzaeNFynAz1XTILxUZcb5V3klXgjy6bKqUfiRDnnm5Zn6M1IxFpS0REEt/q4R2Zk46Q+haV5WDtH5DfGZNFGHWA0VB9+z6HGXIc9zDEtWqW9AF8oR29V8BrmQ18vZ2x8q2X2GC0j8eQNA8DzWgC0rH/pV+ByTn5hy6LRkzqS4u0tvHbLL27tTFvj4KKCv7PdhGRKe39AHakyOYiY82SD2mTfE/lP4K6a4lJ/hAZFcbRa4iajIerhyfHkoMlsKBPhUgt+Aubzg3ki7T9C7tDaW71wkbyxIBOrhWlw7jkWsQYodikmJckhm7BLl7GxmLoeqwrvoEEQIyvDBkyNfi31HWUryJdxBLFpOdWUGJCEJJCKpG1KDgYBGYiYMuWFZihZEoYD5CFGW5ZuIP5PV/p7/kQglbCpDQJD/BPG4/uVuTqqA75Q/3dDwRFTvv0ClFjbvMlkiElMH6PdiGXQJHP0npbeNXslEVVTnkNq3WjMgQpDiMXj/D+NDfWvU714ekXzQ/aNTQxi8pF/ERVjyysrKEmVwriUcuo5SF8VrqUgzz8D1EGbGqvZiyVAQIcMsqkzPOOMhl9Gpw6O/r0HtNyzSYVbZpb5bWcfB0a0Zfqcr8NlCPOPs63M8K0mH6dh1JRyPNFODkMhkBXRIuabwIDdvTil2y6wnTUJPr/gV/NE5bvvevC1SlBRkZEv2Z0i0MU8KWUa6l1+ltLDR/kUzwsfb2KvYa+sn79hY7J07J2t0+JMRzi+iAzo4rLAe4e2MwEuSNjCDL9TFtEt9GLl6Z42jYCI4+AXRTw1KpnWsLtD1AKe76SnYpK8Id3PCi4aCv7ducNgJ6zwLijdPRipwjXLSLRH+hkOYTs4+bcDegGfoXLzfVAg+oVqR6zO+DS3JR6N1XhscfzF5oMM3y2ZE6ZkaGpHNj2UvlFblgVhzu68OiJTyK/qfsCU4Nckh89cvd3rOKZ9+e6ffap5yejYdmoMcmustQvCnPALDNuxuqWkAfh3TGX+Da6VrS2+R4NK1v1Q0XKjoFjTnmjcEnh76MkGcjwamV7f018/MmTj0cMbWclnl3zTrtOUndJY4rbJl8+1JyyvwTjyV5oaqEH5mHGaBqAEFXSWg9010z0yRU7CZRxO2Xm5qz+TfmjckUpWrPY3aqCuBAS2qs/j7jnoNZH44HekVr3JSRqZGU6Rf5fD+9BZEw+5h36jjxnYu+DPx5yfSJOeN05ZeWrrct4E8fnPHxj9iiK+J5H8AgiFa69jLADMoLX9tqS9gei8fVjA02w0zKpsvzPW3LhsxpfgKyHP29HGq8fXj1yvq0AC2M1+vJr/8ZWiSfG4bsvYfo/NXbjE/IMEMnh664QIAbXxaGB2fu6wKubT677bYBp2zZ/+qQFq2FeSNeZoFcpt8sESlgb+LLDSpoOtMkYTo+TokZt+Q2wRk8vIXVqj0txHwl/g1SOWUZJRm72UHCRTRrIwUlcf8KSODrU7fwVxto+Ny8jhMyFi5zXuO6fnWE3tgZeosYAwEIw+ASeWTbe8lxxlHmg+I8j3CgMRVTkB1bvN13Ciw4fSH24vzw9/Te7bNz/FVe3DFP7N9oy3N29yhJrq6U3byZg9eSqQakjeUtoQhza5PX9u1I/Sm6Ayq+9IGyPjQpmkh+d/PDXpAGEn1Q6xFN+8GS4C2tnyPNh81MZt9Pr4v9WauiysOS7rUvTChU+rB8SUC80nw3900lqZ8xtzIpLy1pkjlGbqQzYtHKckA3371chpe666FhJuHk+Lvo4AKzeyQey+6QaH5JUGQVoqI6lBrYiK47kl2Rx+pl6iLkZFuyDvfVNRn0gJrtduBKlShpp7xTKg8O52/reVRC1nM3iz1g3YxXo4uo2/fCPo7B90yp5/utj99iyPRHMYkocAFemWmBOoZxnP6QGM8eELw4x5Mi0n9JNa/2EKG5S066ZbbiBwnw8wbw8hU6O2BP3iUeX0k0YL4+L6R+pBAFgfUn/8o9jKO7riQIIXfprgGrmm/WcagmdDSmIxkkI+ogbit+2Oy6y2jDI94iKG1pF4/0xUmS+XEbWbTbD5VcJqRoJe7Dln9iCYNd38Km8x0x4IXmaPiR0w9wuK2pbo/56MUV9IhyDmOZOK9CaZ70sUB3DNr0cHkfA0rKE3Av9Lby3jDddapzOB0SYJ8ZejqtlcBnJb4oDvdTn906bZ9705oZkPUCxjSzwgp7xV/TVT2fyOZD8QV9ar4q/1HfF3EtQz1KVMr6wea/M5ZVtPy2t7jqWnrME5KPBCTGsPOCxK3KV0b+te4682sEGuliWQLRHzkNgeSb3xAm16E6oi9hAEX6sTaJ0tq98ReQby8GNBrY9F61EFFhKi0mJzymXJ2MS1bUpiboIYAe0pQtIvM4BtNkvK9G+a7Wmgmohn3V9FrBeansNyQ/mROR41+zWBWpSdFcnzDXZjrUm94OinQAcFOEDX66oM9N1TDmMEnT9fmM9vX81ugIiywRjw9au2HWpAsfJuUWHFuyrdXmcMaQ5h3Z0Ks4+3+IgmVSEZ++njF0oDpZhSykDpQEcIRGuqM39ZeN0r8J/LvhGdisjVg7vzCyCOi0GMLfrphbWrGXO9PuaEvLKhu6C1KTG7nGOzzCbswWiYO7pSh8/aMfRMYw4G3yZrrU7q5mG69YWrR3Kc6wk9Yb+zEew9+8DguHXSb1i1ERcTJno6lgl42hfYFWMrleNrWrjrG+Nsxn+BDphDCOAqzD0S+WWy3+EwpPig5TOfcwJmK0js7j3r+IG9GHYlS/+iEPwp4vpf9evxdZMXIo9X2VI7rNA01jn7bxtd9WUHgJCIy5kXl1r2gOa59ayzKI1wTiAXNAzzOopn7C7H5CHZV9Gm+6XfKO3YPdBPE98FpnpHEc3Epku0qb2iTxjM36GLrUuK222HOw5GY9t+VrbZ+CdabpEVHusIVkk5SpD7RgBWclZwmyYGbjNn/EpC+Jpu3sSIwhSqsy0+SYtqlywbB7jq4IDUObu+gjsnQ0D2aRNGZGgRMMbuIZ7cHE5vpq1VmtL1vSz2N63oF8WJBn8SIRcb4vjMeY/6aLuvTEmwQmjWfmfaiopd0bpAmZpF+pLpSE4lEq6+TbWqBZG2s1xAxOVhzMXiMCt6nC5qyMp/JC446XuIREt/+YZExRLTYgDti7ITI0i8/TXXkDoDloRH2mdG9I2TFXhvbIJHs4s0JmUCYHdJZ0y77GGH7qyB2XxgxKyRZzy47yKUSbc+91wOiL8T8QDzpbv7RfWwYmuDwnTVn80z+EYtUMBz+GBFIlnmx57efzboLrdB4CuF5wLhjfjtDniW3XzFm1retY38S54++QQKyu58pp2ZQSG4PDE9AX9XCIPm28Dm5iK4pA8qfQdyWZGzbi3H+zCrytxLhNLjWILzYjmk4iQiMNTzp+Sv3BAwHeki6HBsw1/2BnOG/iZcHwMLkI84pOg4cq+u0RNAPGLtGRWhWXk4rxK20M8xnOIE0RhlAQp/6tgzkbg2hBUQpc5BbBufkQmPgAeiefeaMUrd5XHG6Ik/aQjhv3fqccix2eFqEr3zNOl5TE+cBFCCkUYMm7vw605G/6Egp4YowDuoiMCcXt6w16/LcsnRdrlF28gUDfeizzKL9EsH7lwn1yuW2HKA168Zop9D+fp2pEe9rhmvRiBZCzCJSR+2C9TKTR7+Tl7XpNmnVJBhxi+33e1ppmjah2h02Q8fb8wFC2wraFhvdQiOGbx9sH444p/3klFsrOM4TbGhdmTQbPKGZC355kxRMJF11TVrv0bUJXKZ1JcJsc2Un5eXKxkJ6K4ocVmPjlHK7vAdQecQL2ReyJW8gs2k7R3MaZRJa5zxduCiJ0N7T3yVtbixtSkqYcaW8BXKTnyGvfPfaoD4YXvoXZ+B5yubLA9jHeuuqU0HvFgVRWupNSspev1l0zYacn1AWT7KsGt+Rr/G+w3UWkHW5waJDkb9iWO4zxN9YBwKudoMquDnpw28dp1NBrj8VNjlgP8qbBue0kPaJMHotFSLc/HTSYEPC4qnIzeoJn226ua2WJq82EnqYkHFiLGPS2IcWQh2tsh7Z/QLXIZC5ZGslHbr1JBgDX5jIE0gqzr8JqxhEkY/fJP0YoDYzBaoMp57PUK/S6KOKIto3M6QzRFgCJNpB7YvouWZKpVvZ3LaUAGXSZEroFxbUEamuDh+nabTF7uENsoFz/G0ReGPicpjSUmAWEWmSY9F0KY3WIZ6Tx8bcZtBU9oPED4J91Dkx3i9oIo7trd7+qsNgJ6LfcrhZJky94+r8iel11gUJIcNbl7OfNxj1UnHhPG0g5flba37z8KVSgbyMPr9VRUxvMhznC6nB2cxs/pdO8Czh7GbpNvR1X3C/SWronSX4nPgF2dOxsa8yKM5j0e1ad59BBLpLYba2aC8LGdU6O9aw5DzXZP5RxK0KyuJjdCTmxdwdfgPFThXZFMsmvgyUXLCA/Hj4ijlvqkFy+FqoCERRuyU7HINwowfdjm+8AAElYH+ZkBa3gIDULBhpm30xUNrfkAWYDI7fuud4NJm+AjNlaoOO4nvyL8EUAwgcyvzuC9VrBD+8pdCEl9C5HRjAujWfPr2omvKmxMwDr1diu6/QvICuUPgJP6kn9N0e/fTz4CG1yTKD5idwY75tryV6X7z3BPOHSxCy27gQ22a5H/9FKYKw5SFmoOaXBUZp5L0q8jhMTXFDvWZf2xfeLYcpEAqJGG2Tz1Bi8Hry+4ow3iuQ7JOn1Ap0grAXkiHUQ8GQ4QyKEG3IVBNzJwuD+GYvB7UfLYCo1TNHvippxA3m9cQh5aYRsod4Zah7kRlSunfDOKG4cBpvnkFDn46Tp0KdyJn9PnOpOthUARzKzdvUMgwN3R42J8kopGWD6Llfd2Ojax1CtDeG6JsNe7Y4VsJkulYOkiX1mlaTaWX7BY0JNJPkyWXl6+zbtOSvG8hG5ho2duFtCH4r84pPFOoc3kAwpNxEeP3kOl2oEEm8kcYNRtbrtghEz63A69fFE4yb41ztddM5MXpJMx9PbfVWoXRhURSyTIkSUkPT4B9pU8ruUmNs0WKQgupHguC98fn7KEIp6ZYEc3hm1QG9hyYaVfzkEv3bq/C00KDnpha4tEtz4jZFrbrZthvmCRw51uC0KTgKBGUayGv3oGiCdzsneySRp4Ba71/DIybQA3CRY5kSZJOFBNAXdckbahw7Jt/YntafMUU4mcl88QStQgTmG88ZdhKiOpIuxllIIVnnR5kidXjFthWaX9mKorANj94b6szsHfgBcxvGNEd7215i9l44oHITewOtTohjrLirwdZiLlhEGKv18z6nCczW9dp9eiTpoQtjjpZf4IqqcmUmLKlVNvlImg7sTsN91DZs4zhf//OmxUmxSL4LXJiPboKmRPjKZkG42gEI+gNf3xlwm9NXWH/BVSNzk6PhcPfHYwUmfQQr0qsxF8tour0aSr3tbn4YJuMZMJPMNahZTbB2HePEYJW14dkRAIAnduorsOaE5fyurqbnU2677Xt+QZ2/ryd0xSrl/V6ZUVOcdzs61R3fWgdUVESjdW4mjKejaudT733dfCo43dgMaWw+hqgdxpdm0XuHAMYReMNfuExnhViXVBMQEh9LbyjfE9IhFK7DgnWQJ+VDWxfdwtyxYNqplRcTNKSGTdH3ZhIYO+N/iPptbS6Ra9Q6yFBlSjvVxy6NJNWLmQ7YxNq5L7+ymcWeP1mD+fH6ieGTMXWZuttntvt2cKL1XA9Wt+pX5k3s+3yjqt/Zss4kSFmLGD3ZNrznQfhZzhIASRWsfLcBZ7yay1gSbDahGDaI4Qi6OhHR5gEjXaiYsIG+fnbBDn1+0SqeZ+fw91z5lYWCguVmQo+IZ7qovOA1Rn3eHErMFt8/oytmOTXQnaoJdQGIXSg2wbDa/p1kdgMn0iMIYO8OffUc+xzH+3U2+QC5LdcnMtVS8uZnpiwLiivIvxXL/DVzot5Bo63QUZrm6TYyzYCX5zPpupnYOoEh+K0vbpRJZ0C8mr1souAC3TRvvxxL5NcJm0CvzGmWBp+wtKtK2RcbHSCnTBJS7dGMCiF2S0lpRxVgX95InLMSl3zZz5l6Xw7RccTz5k++kQaz9XpMgy8s5RYNziG4rPoPMMiF9yH45ZZj+coWrl2XpfKOjRpdDfSktUvupzez4LOyQ0gNUacDZLtA5mnbjDkjZBW/bnMMsugqDmpIrnT9SmSCoNw2oUCnuLqJL6qhPcbHGSepPrDOQgwqWdkJUrjMktnNr+6dPpmgkOsQ6s/G1YKh0eHAnOIQrgWKn2BXNwpqRNHjku49rxz8MO6zEcBs+CqXsUnXs4ne7XfCGcLFzS/JecNJEQhsjq/8XIR8bD8kklcQ+UP7SKJahVV7HTnHF2e+nALSmRqJIANbyfnpRbhyuutRweMYhLikqkE3W+M/gWpGq7qQxW9akkz3UyqqHSpz1yRXKP52r6DsQ3pGPxgbEcozfD24D5Z0k3LgtFN7TTxeK1E4Yxz3CTriVJgx9ybDBVHfpzQms19Uu3TY3UDGJPoPn4IQATv/+lc23qzHqdfPnKJ8fQoyOPjNss+D2REKlT037Bf0L/UdC30Hcb9ovzBjpgnaxIn1V4+Ac+tYWkv6IwKLv1fzoqsnOcrq3aPJI7z+9ehWz9AtcPynNNs0ZzMMN3yucI5mO2knma8ZkkyyNAJFMxJ9NOlbk/XLpbmrwVOclaeK2GI+O3Ugfs3mAnszeRAUyjk2G9/l2xHhj89hbQMR+3Si2m92b1PIJLtDKIpIZ13vEmW5sylKqZN2sNFF+IfmSavGTAQLLc69yyqYrangkmPauFY7CS+vkpQlYQK931iaMVnvU2Nwu3WCA5mUTiIC3xlTjK1ldfN0lKJRfiblD37zOLmFQozZhHuX7g9tMCMnI+5F0DDl0kcHLEHv0kRnkCinFKF0TT8HnJR6p7IrcAP+I24RbfJfu08TwT8/8E0eOZSqknK0teFmvsnadaJhF3uuguyULvMCaajq7BvQl8YFe3oL3rs/cbE30hKNt8yh+cPuF59INTi/LfXFkQU6Wd9tp79xhvnebUxu5AtC/fqjMIVzXpbN38AwNgFDu+lKvItA/MyfdUEmucgckPu/5anl23uzIFPf3CAVnrEWGnUv1VYH5vAT25/C0cLvTYgt/PpOZoMMjEeF+QV/GcDEsDeG7zf0iS3ifVtd/kdAfIw9tRABPJbsZsv9K91FQp1rQluM91rQJk2ub7PZX1TutLyRA0QKLQTHwuOqTvJtIq5tiXc93Ra7YVEQ4/VXTE/BtsUOXcsmfRjQe/3iCp8bMtNy6Mqe2BrzzA3atfgn0Mf1cyaAToFpcb7LyNn2oz3jC9v3XaEQvmb5hpDNaahfwPUUG+BZycFx4tvO24qPqoiB8e2i1tpxKnJHkuP+OMVamgATbwQBTjL/lPPBXci8aaMM3QvWI6EphMm2GRXRmjBS5QMsfLOLm28B9ev7Ccgb3lVeE665DLEyCh8ZlotEiuoOwOs7nuj6ypZZ7zmsbSbuWvAjBDTsbSpbd4FPgeAiR80+oxLVljiJsPb1thAFMyHJ1+G8sDWCdjgtGuu6EmCfxic1MDsG47YbVmb+lxKylGWuXZPzFTISNqNwjBpeKLmKP64fT6yepVh1Tgr1E5glYdLURC7HoTP6873HJ7y/4Vd+RI/+ThzNRHprQ18u4nMLI5Q9dZV3AAQAw/xGauqswjCBAliSZUlxM+mU7f6FjxlHz+bl/Fxhae1c5oIPlQv7km8DsZWH8egwOjf0j0hhrT/D+ehYe1QuC5u5IurKezfB9cq0ZiO0JF+3r9N9/b45M43G8ly84cva8iq9TehIRg5jj1o3X7Lsi5h8zBHuosCVMTniItqsxlBZGjxak6iVlM88D2Oxf6RPYOLGdrixhHkxu76BMbGOCs943N0gTCzWMa08ekos3xkK0LBI0ghiyBWIheEHwTQMO86V2JWTCaJqW7jdzstN1u/sxVXSkjQPlOTOLk11J/Bkw3kFpS8phj+KTG1jlQgL7dDyzvKeOrJ1CoHcSMvCo/Kqlu1Itm1TiAWhfRWSkjYmz1TsaU7MbLwc502FmVpDwqmsdFEX8MyL+6d/MG17wp93ogup5iOnXeKBe30TvcRwRoLxPp2McCMDgbweRP9kafu2/iuzdvLSdrf/xmMBcKU4J6zEyHnS6As8v9ARWSq3hN8n96wgehrDXLbkoV+HoObxR0xH5NPrlEEwsUEqes7vWPxxh54e6Qx6UsaooK0DhjOOwJrXoRYtJmhoel3MNizKowUIPrnfKE0kn/nu/0TkRB7/xpswcpnAriz8/mL2a43Lqb4G5GmllltfQ2MEn8+0TB3PU1RZ7iize6aNC1G0oUpOby8p2nIIRzKLeFItf3fdmuYk5LyxnF4xAybThTeIe7OsB9teJMgED8dGnI2oC6KNqTZOy0bnxTcUIXokMjWtKR+FnM93JhPDNqs+JGQdWpjudbu+ACiecAhy21moeW/lG7sg1XuGq1vnaXrsDtzu6xHUireyrwAyz6QPnPou7ZgOKx+VKV849dFKGV2r8xnJTeWjLq+rtMPBi7+s2A+waa8ysY0+wQvpDzh3yBZi04H0YxzDogsHEQiKrnUQUWWFA5Xl6T2fWeNHAiIz9fGLC9WuWYh+WR8pkxzuCD9sdv/di7vYzo4/EqeDvh52LRyMXOqO0l0gvhjRm+fPOLBjzHaOn6tUD5rZviDfaZFmeJtGqIREUgQ69UBvxVHYFBT63sdwdvcOSboIeQnporRxP8CCfbQNonfzk37EGtp7yiZBFOPgvle9xV4y+IaXN5CR6p0uJeaHtEIuRTRb/fZheNhfOoxaHUyKFNtghHfwoqkFggd2+NRynYqoGSGmNwgs3BAKBDhLvrevqa+Oa84npCla7hfcnLXGl5QwGwKJWkvOgEEEg1HEcgX2Nz0uzUCVZZpITBn99lsyWFYF5gsKcuT97ewXavRBpbiCbncXToiIrbc+FUGnU2C7c85rWhObEY0lXWKUd/uWKE50qktAzaJFH0yHYCAAN44WLQhq2izVamU9aRGwjoxUrpIvIj0TLFj0FeMpkBORUhu+XTMDQ690NSyXrUwLupkTOXnwzUuH8bDltQ/G+EvxKHRqRK0yt0++GPN25iSPPvHDdQZM+5EPtNiu+UzA6kFwKxgbEqoYfXywL09hLvxxxnlIejWxmHQ2EBXMtxLpSCIybyntFq7rD2qg991+FOBJCY/XztSx8iUrZzCLoiISr88OgukvgckmfEaS+4p+B6V5hH7cPnymNAaFsHpqLFRPsbWhPtpOHL/coFRd0WD9dhCkcrdr6OQj8P1I2ct66hVXKokbtt9QXAg8a8eJKcjSL9S7o5Sx1jVEkrP0TXrzbtZbUEJdNck2X+ivuC8b7+UL+bWm15SDEoN1a0IhFsyisSL6N6wvBUZoMeHIdGmBHhcbpN902PMFc/Ir1mEvvymZx04KIJKW/6MYkhiH5dAyluI9bMwGElr8hP7Mcswbcf2hhQGpAGQxq0CaHIoArU+KRF8WpR35FNX348uF0auvwGqHeNAz801InmTbHAyNxYU/Y1uJIPsWayhx+YueKk2K9gCKiA8zmXzSgltUMVU3fee2QDHuPronh1PV1yOPXl9V7nsqRZwflnC+v02xd56BxITz2TM6gOItGfbFA/JT0HJvzyoxK5CzYegQBMYZGhhtGvFOoeqSD7rQ2kCxgzDcXOgyNOl9nde7XFQRsp2foSELDxq9xBi5LVzsh6enYakitaL/CtLWfWZi5MhvnEseTbcqgVTYXiq6IJ6eyVohQpTvYQA6pPSHn204V59fVLi1TzTTEwHlopYqRY3233FYSseP20ZuEFPXff3Epvn8JrWkvjf+eZmesxWvvCODyl1RaDzrowLh9x4OomOFyGGFVHvEJGK9Dc86BbvQcTQIYTrrO800DgWGPFR5eQqInolapvFsgu+qpKoOlNKDZfdvhu6B82ypsXmMkKzL5/zXeBHeAB8ym0eqpcpKpTZV5MyAIpb5y892EDBr6iBk7y4HHnOevt6N/ZGc8r1Gn04Jp2k6P97TrsAaFZ+QLCqSaNq1KAfbRm5R3bc5wlY/ZcNfS5IuGQmc1SoJ3gt05gYmq5T3yY6Qp5lrfdl2Ns3vtE8KBKYuSF42aQzmre676LDUCGnXhPJKyzvJ2Rfj1ELZlVR+zffXjJJrOnhaTIqa3wBYEZrXYdnYGyTuNdMT+5ws6S+JZBhAANDbzZmRcFfh6fbbhEqmX/mjJZGcN5YGy2+slEpzpP8X8YLeQnQzwYDqJpO9tNXmiD+Iib4+9Bvux5Lqat1VoA8ysCqMqOXJd60BdUAzWUzSj5fqenOQ/DnnrlId5+s0RL5mc5ofPu2XE5b3l7B/h3IYPsoYN0/EAcKNrZTLKtX6BS+RWN2nReV9pMtX2UB2kJqXliSEtCWXkkFzer49bdF3+Gt1A3PdugShZg/PjwxS3+7R3pzJhefRMix/+ikVeHzzmUGxTMmb3eL8EdbaDIR+C+LMRqtsfrkGnpK/Gof9N8sXwnaIM/4UcsOLbRhhLfhxn9JrDrcoJDb9vUq+0/ZPoKc1hzgNCWkt3OCHfNHuoTEgXG5o17lXyO2fIbZhNXWgPC7vCLF5T1y3VpeT06CGRt5tOlcAh3OwVxr+stvkz423UJXWvvmeBylO0W+zwp+j6M165RggY3B/S1KsKDjBaNLtZm8Sf+VXqH5qP6rGCwaXgDuUr2IL4+eIbUGX7/MelN+mDwPWaIf6BFIf4zs3bt8UaDt0G2fqw9AAFaqTels5E6zRS/0GSLnvMVvNZFoREQYGX4gzPxBAqqh1mE0RMni+RuhUnqLD3lwzaLs9BG7jDCpJIKZFYnydkgchJ9Ra1raIoa3Z0BSeT+BUTvc930YL8+yJKDvtIC1TenOd/m3w9QV60RC1uel6cFMGsDsSSv3EhPk7lZu5aC2JMc56O3Rr9YIjWL5GgKRdGVJDn6e89+YS1IOQ7QQH9GurbAdpi0IPPlFdJV1LTvcvMwQ+z+VUKEtGrdWaSnwGkbS8VMVdczsU+bAa0oeRgJGRxq1ux//mQcEmO7CgcqjbNpWkJ0K1/4K97O7F2aqdrw8Ya1oWGQQGwbC6qJTmJh9G0Q+fSPZl1bohom43oZOX9fBObai+hEH/CtcAkVJirdu+rjcz4RP98sv2OGijfypsxYM2U3wVb6/GZYpDG4gX/5eo69hyk+m2T/PPyWFIDkJkEDATOYmcn/5StL91B1522241VJ2w94kxxDwLt1qNCSDRsnG/8tjgM+6FjrUpzd1uCkNjFYkXOQrekfdRxMl6whCUvB5fwk2/S8gF1wDXFHOhxNifTJAiJOWLWVKUH1Dvli0WEnNGnedQAuqqXLBXFwEtUqL8bp45xr2V3zQeRqckWBaCZDU328QaMclpuvT6Qi9WB/ZJ9APK/N38SIvbAlWAcZbzyBHYDQdJq63fhps8Sya9vHQ+9Xrsw6BEr2Gxi4NuaBGt9UQG1UmiBSo7xIgksWjcffptmNIim60QSxoKsxo5NuDscYcL6iV16qV81ekEPiIGEWMGz/OpMHgah2Un7MrfYxgDWjzU+mrsIrVWzrREFWK5sD24N64V2EDlouJGFbNwlpRbg6NWdqFUEOccsQEqr1EUVYjb80PL+uN/kTCFELocFwqY1mW6dFs35fSsa89Zju1WL6Wlj9SrSSmznZR8ggbmW3ZCAxiNkMUsUuTH3JeQ87q7tqx23TflEJnsnvJXGDSq9y+U1EkDJQnK32wQY6hFESfF8PEElbas2+FPPih+5M5xXXcp0NqfMnRfbwlqJniexBRAkCh2ToIQ3vO2+cVMmHmaW3mWdVAKrHCVE59krVEPuxnISra+ckPjp48F/JiezfAb9Bhv9ukfKjsDmCI9K+kBjr/s7fGddql+Pqk2Ul4Ajz7LWQ8SbjhzkTIQ7GF0vP128ZfEXcPvVo3VbiloaEFMtihB/jffa8NEb0v2TZ8G+okqUsONHKUIb7cPtNZkrFu7RMGswMQhv7Y6+225pC0cL6cJT81i3PCn38af9H345K4LPCwLz0jer+/NnwWC2S56ry1Qxs13PSByxyKX+22yjmUu9homX/D90SLKBa8lFwn0Ey8vCL7Kg4x/kyx7Jx64Pj8I9/vVprLuwMJ/rBxTe1oHNSiwNO6XO6vGprJMIK52gdLEbeuA5Gco6B9fQmBrtSszwN+tEOimVn74NH9cOxf3+4ziMFUpPIq08Iahxq+Rg/XDrlh6RMq2jPBiQZrWFvLyXT8hfAvkrhPxikA0fdxGO233yYJpmdTTyOeWmkw2/5YEMLNFRDP+SVwzVELdOoeiJKlaJYEdsVhen+I6Buq+af2Kw/KvvgIxLfCwOciwpQf1udSKeYPKHrYa+DI6BSTi7OroaYk2iwM3zrp5O1aNlUIsF8LuYp/Rfv8UDpAQfpJs7L6try4v1OSDMUAUhwYoNH9K7CKUWaP7znJdEVhumXffu0zR+pujtUgisn4S1Ty/ZGZTA85v4mM7q76UmY64DQr55RzmpfFgP2aAS3AWyKfr7FhA8D85iDf7HPhOkgc2r2PanOJqPIH27N9tCmae52lC+8FRXlKzQpnm73pz3sLab2fAmQ2iiBDaCjNqseF+8pfTqj9uQqKuqPNi+glr0amOV7wc7MshsbnLt32c/fu9cKnsBfksLfUmjj4E8BC6z6jv0DwpUop686Mvxgr8bKym/eMDGf0U7e67ZvY6FKOkFw50+76YyIN1zxOy4rp9T58lL+/2jyJrTgnNoOGate5mbgRGllhoD5yNnyqVmIZtOGEYFqEZ7ZDQ/2zha/UqyzchpPKCndiFY59Uqd9nKKRmSdh99lYe4wLafBSRpAyZjBGZhEFGt48VOc35Yeh2hrZuyHbs2AmiD4srEnKtK56anEwM231kZbT03eEj0l8xi9Z2BN2cDiTULqUj2Y9fuRI/JUgbLk7RZeats1MjfwjL39fJfo3t7dHflk6rvUFVkJwcBL/MxFCyt5cjS2SZyx+Z9ZZEBxm0QVDv2B4l+G+cGr/IYkt+y3nji8KluMHE5XPF1QzeB/zaWhuVJ5f3Qafx6QVcH7x/cGKplKUlZy7bqbI7MPxW6V8j0O8GWCCiVR+XzfGFhg9itatpTWh5GhyeweHRXPJT11Efg0wX69fa8gYbHMzqJLzczjwN4t0mpiGEY4BwCh6AsOQWrPiFa+OFqAWfW+srvzGv5hTmyXWO1HTO+jOS9izSzimeXLq4uWp0LqjNPsAoQ1o7N649HwPT9UHHLMPDwb5EH3wgnIldFm1Ck9rwwtyTkbS0m7jRpAv4hxuCZRt2sx6xEtZILZg8rRVqrwnrYJCwrCsLMhUsTF7HjbR3yhRMdKF8tqw40y0xKCwjY1duMRUHv0YhAOb3LNXN801+HYKPKvKkzI+W9OyruyAu+nHbJFXKOv9Ir9sT1Dh0f0a8KJj0vWZD0Fx524THBnOmt0YKsb2bzkfpBIWHr3Xeqo0D7mKf03imhUH3/i/W1jXW/Kod/WjMjWxvbBwJ3+n2sWt2AvY31rhFjORZT8yL9jl0XwjTK2UlokZ6KFzTiXpHD4blaz28k0obnL6eAoJ9JNInCMCnwDaVT48CuDgvv8FaMmkT7TEyCaaVhk1dsK/g/Ni3cDvVCbaissWsheEnufrfAVlVGz5VSLcF9JCi/AnfvYMIpsPfyK1v/U+ozWrv09fxlREEj2rnf//1yqvFp3XPmxV+i3l8hVcVvzwQQSklimR68Cf/XD4nyuhgkBsLR5V/CYtOdzYGtgfVk92vgnlC1vJ6qybw+xno+D8C/RO5N1kfVx4Ne+OUDJNAK8WS8T4ncit0SSQrMXPUP4ezlJLzzIb/kYIMiIonIYdOfmGZom6+xnSILnFi2Iev9+dwSen2TY7Oa0GdE/rty994xD4QGhfshtxm1QxIQl2Rv/MUmtbu9+6M9s26xSq5TZCtHMytq8ftSRLlCL+GDR8hxyrVjjOWHBLYKbIn/Xnbkht+2pOOqzXLcrv/Ywt5kUJbvihLvVkO/oSrbwtbDevWnOLGxhD8vV/9WYJnKG+LliMASYOQ27y3uCVvjmCRW7LFzFqIVQdG91rcUIH0BIG/3DkVir9kn37kcDH0hTVdr6QAnULgwo5q2/LekacJ1UAYQqSqITEkCoka/KUmRaeogXGo95sMgiePeOJDUm6rrFmFMPeagXzfl0KnjEbzb2J1mo7D3zY226xQhrs9fc9tzYdzM4Pfi6pfA4CZC9Qdh1oCjCQmHBsUWvbbSThlquIHNWbWoTeS4CGzeTY1yLg1Jaif8oPWizmJdMw1QyxjllzhQwrKmv2tPm4ebosJst8vERhrrGGhzIizHdBFtqqP/uAOo7TLke0MjXH6uSsPzK6JLyg0PG2QPuBhH6dLHc5f0bo7zxTUDpUhp0TwJ46RU9PO0UHCZ2zQd6QYgB3d28KK08IIf4G+b0l75AohH/gs/GcZPFu8lu+/QbJR3VB/Nx4yH5RLxd9q++0JuRKBuFzOqlAkKjgP+UalaxyzwSAKZlOdcILC4kCQbnuHeXHd74UPFHZs5TkwA7Ee3ZdgwZ0vCA/r2OuFiA3+4t9m9iv2CwODHETrYTZ8iQcIC0mjBIMYlkUALXcBkIPaOXoNgdEO/S/SqRrV7aP2g+kJUUSzDcmfaH2mvNlChDzbfQAVpym5X37DT+UODsw5FbVGkS/PSwLnKze/ot63ehaQ0OAiQTCc+pajUDrbaqW6IxVO5SiUW0RvEMg1p4FWVvYGKv9e+EuKDmu8tn6J2S0GNZYI100D3kDlhUOVneSKUVsQTLygcXajtmIm9YDzm/5FXRUoNzREouXcv9Xno/lNM/88h8s1G6OSKitPnMrlWmCTU+7bMvQqQ9lql0QVrotQFWJQPhfVhOfC7pCEsUTovom4AqeSW5JQbtVlPnlL1C+osT5YjzidpVZMvD78TpFiFCYB5vSDk8VuvlvulAym2rJhSpAURqdQ/KslP5aqC3t2TrQ3K/mgE/PMwiIhtqTvJ4qkQ7DyXorN6Zf7x0VYn/BXOurJi/z5bkzVSkKneUagv4WiKK2hnpUIqimqwPF6+TZuOHBfkUuI4EvQ9Af0VrMUHisNkTcx5mZBS3oRuLBj74i5pu6DXHxIz/reyHc3fJOEPnuj0ZYTml+fsnxZzKQkgEdj6ujnppY42vqWIsYlilFNYr3GGBgnKLdLsk0fA9mExbhGiNUPk+TT7ovQNdBqyvz6FVfKDlf5l4g7ddMFUFVg2d/VeOOikFYEl9vkVcBq0btI2rjUK7Eovv2YF4A09ujGZb8n5SQ2TBkbHebLMtnkn9s/DR9PHJmnL6mmfOK2HXXhTOEM/7kmcd6wMn8d/su/rca4gPIXSi9NiTc1IlGAaAta0rhZpAvPWMOfeNBJHn1EKV32GFuAQwXcAYHjcq/boWKouP5WB+ga+eXdcpDZqw4XQ6eysfFutFCrjigtt79Vma/vvm0dbALSaRpj7e2T4EAoymeFcgANybM/dbGOrGiJdR+IlYbEbMyuGNXZ61stheXQco+/JrwnmJSV4lJMJtTxcPn+SEKL1s88oR1J8t/bwVjIJ4jtcHlF4ZzvJypf/Ks9iZSXfoPjqLO4hScrKDLRMWb32DoMlyG8+2aaNMhltsIC1EAGRb5DLTULKRe3j8rKkIF7Z1E6bHUJ1Vvu+vXoqehZWXlx70fErhIh9fONDQrli574xL07NStwgvii0N4SEbZU7IbaoTS2xrMz08CELPl1sJ58gKH1RN8OMWazLy/+gt7XnLtPiDg4NLl8ACAi/f3cTymJ5vPs0WITm5knyjQtFZcqjrIWUH49nVol00Dnj75RORhJKQ1/Tnx2bLM6351cbcd0jbThQJ3QKs2wyqSvB2WLhhuG3cBpDnJTL8QbxkMeZG404cm5V0BkhfD568dvXN4j3DPDrIjmReS6Rn5ZBphy90Zb/PNV5cvJ8rznZHk6Al8Tjd912CKPLSt6y++0DewqjyJ1JloZ919ZOzFnmhXarmGttitmjwqkBjCZlxTekVCZGlZzd24PDDViPlGbJvIXZSoURUu+WWCBtpxGigM9/QQ2cxNPg8/C1DX/uoxgRRU/owUSdklz8+gQgHSiZ2RoX1JtpyqKy92cxuhb6r8SV2JI36sZD9orZi0LaHbCMvpvSkjiDCh7dUTslG8Uu6gt2o7LSzdswWMfkQ2c6SD+ohPDXLyuEmKbIIydJ0R3lbpKx9CbXhcfX3eavT7Pr2YjrjdNx7f9K3eirhYhCU1UkATdP0VAde0zhNqQ4+EE03X5zd5m2YPXkNdPCp6eYTjmKWta+QXFV7BvvRqZi8vhZ5PgEy+mBdvLxOJ330fxmvybEI9tV/fojzcFDZjrOfJfqKy3UVojX0V7y9upiiOkHKLo1njybAmsD+zp8tUru5K4W1Cp70kIab36VyYliVDURM7s6ds66+ui5BD7psBPRk0MZgDCdnedULwppwcHM0JwPUsrkLguNQ8VxQf7MTSvYWC2rihT4V+LEPJR+ZEdgOTnNWJo28hHKavZFBXPKc6Qf8bt1qYgJI+YAfvL3t+fsF9phGsXGlduGFMBIoOKKxnwSTEpv8E1lFpjpMvvb+qpzLUHauoS4yIy843O9YY9mR55yaa5UKscL7dRwV7QBwHPfz8SQ569Y+mnQ7S2FsjXlXk68gToz/Q+1/AMZjYrNfYgIWYLYR9I7F/dPAzWZ7DoM6LuNrFvEtZuwlRJAxvDEIV6FP0yRl92bFxDrAXG4/JathW+bbz3+6GwgBkZtRedX8Wss243XpvAXAlW+uJJWgprx8+xh78d20cEZqvtmzB8MBsjsrrk7B2WJeGnYhjlSX5yhFBStyOTu0l+7BQW9AwV6eFlSO2tD2Bev7ZsG8TaXkiG9QupHtyk0RLhb9YbCN0ApiwUC/ljcweBjhoKwm+BwzU9f3S5GBmUhC98JqpXG4IDDHSYwnP3ZT3t5Rq+ovbIbHha4mSFNyR8mvNwpKcOfo4C+h+QIFk/oTiMqQA43xm3amm5N3baSyczhs+3Mn5DwOKmUgIZiX1lfLLmX/vF5eorsoJg07lOg669YeaXaV76yZqMSjdh7ULo/IHk+UPaUYWJmUeKhlx+VwvHXgPU2SBjhKgLh+h5ghg66FvIPx8qZMlnH7Qh0hxkrfzrozxZFle/cme78ZpTHvuAaQNZfv1epAdH0X6kTNDCRLPjeZOLzIrONPd8XOAQEF5I6vukP8tJQY/wK4xyoZz5WyrlJq0EofFHPwYsVv+u2dCcyHsFGvx7l6CeAlHn+l1RWIiGoyy+Vu4rMDz9I+Sm0p8B9DdBF5p3aJo2VQ4aX1pUsMyeaRxhCbbsmUFwsbfhJciuIXq6AjF7RZlnu40/8Lya1dNBtZHgcM2mJRS0iDv7B1bShy8mR7TfuYDq8WJBgTMK+kh386PKGyO0r1mYPWftYlHYLBZrV3abapsW12cMNkB/G/FzivBNG2DW0+2/9ZGB1jN96RXKghpGgF1KwGEzc880kSJaiISPU0DaG53kjMOabcTkRcgHDSjasKOW0QNvvAUuUZLwHXT54hQy8cxHw626JmrlWvYFNM3+vJtkAAdrSUjwzZj7IcDfjmepEb9zEKwPJunjn64zwAcBM1qrzzbfVtI4D71QeFwFjy0u7GcKbhJM0c7ceBOrlYCQUuNA7NUuk8wGti9+iYIrJL9ChXJTiVobxxG9ybKk9KXxGA5Sn79ZihGYuV7v98VJIeAl4rVqa6DN0lP1dBnWdM6QZeQWzG6jVDrdAR56vmZ8665s34LHnomGwG/J5q69kbyQzBTmirdddwnkxo+/u8EOMAtN1RF4Z4ODhWsnk3xoxk5ve4dnZFZULzZpp3csZdeIwogM7B6BMdb6U0+9OfRWqQuY/fwU79G1pFB/bjN34rAX6LXrKn7j7MrabnH1kqRfKSlZi78ASTxdpAiiT9C3GRCaj2ciB5dsg0IpC8HniS1cSGbjkge9KmfTHQ25rKp70ZgIUcCFcewn0KL3oVM4D8bPyH1TuE/gs7mgYermvflg5NxPyQ1CQBnWa4zsvMSK7fcsdPupThUT7e4KLnii5QYTpF4BkdjgTRLCb5LG+TvX5vclOfX4VmnONE1vafDv2cxYiv7JRPN9d4W71MzN0V0CmfqXzn8JVAN4OGbfD79v2NzNppIgLl3T8y7UBZiNBXR1M4IKU5pLDdBBc/EAXIvdCeDiJk+cx4juzQEdHjFuC6UheeWqyy84EoGOR1phcnhlgp+UW5/OIm7gkcWbSUmxdt1m76TzSbOWGuzS1Ir7JRFVuEnFL/q+iE9zM23H9VPeVGjehMCQIPZ95Ld/SPNIJ2dTup/v5kOwt1ntVd54Z88mkS3i82MG7XuPosh5ObI5666E1+3sUeQVML81Q6N5d+k8CFMyJmdRPJFQPYdcSsfqJYzLEyakRTmGRjzKtXannwU1mjY/jYSx1btQ49ZUJpfkwJiwxZrugpbTsYMur/CTU+LXNPE4DPeL3ZDfQ+dXjka0qwQp5IGOiuFx8SLubjlg/DKx/K48rhiE28BgxwI9afYZlugoWWGmZt/+Pijf8/RJ/1fz7H5CC6EJIyAhQRxvTWmBh3OK7fJVFnQiskK8K3/rQBj0V7lL43DmsK7AB8IcueL66021t2YffL4iT5/0ZnZzXNPExQ5vxyqFWO/VwoRjgRizTv29fo4hajuxDx5+Ft2VTipYLCaS7diB4u7cqsPaTjDhs/lpdnXRSdeLGdJMYMAwPR4mFDnkjRFu4dZfqFLH30IOtB+c8/pyMDUjkXmu3/TgZUaoHNPfZd/DY/ixRfDaxzxsTEk5McjmreWHS9+iv3WWMl8OCIax5zyvQnKDaGCuqb7yqhTkQZ5NoC/0I2tDePt4buGu7/OkV3SDvlKs9D8NYf+WARYqeREvqv1bOvfsfyGo8oVCQVXUZ2kFkfK7XPvRvyubuEiNFmG3aUzg8+RQGUBUuUKbghPHTIyM82JnZfckZZ6lWW4gJT96Yk26N7/RlOM3kGYVXZRk0OnAnEKkHTsEDy6Gig0gl7P472e50k5L5K11V45hb7QjNDCNQvG1+vaQFvVyQk9+mUmi2RfeIK0DIDL4pXdXIlWZe/pfRv6gmvUlYHAi1ueSyGXEJb+Dsg3kKJmFQ8cXD3rdfsAVixAYB9bW6hIJfVsiMCbgEa/GHRAfkh8O5Inzc28TwNSp9REeGZRfFUFwZWulA/I8ZdMI+QTcWd+11/zRoiPRVFDz5WwbMuKVnuY3Gyvb+YwtbEHmqiQwjPBCLEs1RIP6vdvDB2T4FJc++xIrXj3FN5GXVL5t+yciyEMj5BeY3q9OkXVzDtG1JLLFY68YOXNiWXTCN8WQ1wUZw7KDgEekMk0Nz83eaVhY9lFQxVcO1aKUOdCAil77TZYygNNA3D9nGWaBk4Jm7Ru++guzDUViPNU2L2kmqeWNhtT8xDON9jkaeZ6963wHYACFyOg4bV9wcVPQQrzVDBM/2rBzUZRnZbeu2WKAeOtIqEXVyGYNcFhdSh1FgUsikomQZpXqvBFMRUIut5QOmeNsvl8+Qszd8GWZm05/5mHN9vxcWucWaJ7cHOe2V67HWe3rOp5lzzUj0vK7GxA5uvUPs7sA7ICh1Q9BRL2HJfOZFQldduzP9SAvuEl2XfY15DgSZyrpZhirVN3W7cJPI0PwqHjuJWMT8ZdvfQTD3LP7tKLibpSIQajVZ+gj5lDmMv/um3CZ3EqAh6OPoS0yA8VCwJl28icOQ1a358xkOq2keTAo9bFmURETW8NQDfHeTppQ5ginmPzzRHYelg/v588v8frbPCpvSCSJMwJFLWw4ac+gbykyq8be4yJsXKworO9fB+0Vrp2WWOJJZ1W7rBvTmmYuYGZlhRN4ieFz3ehoWBQQAreQ48YVLp2EZvhQiC+pENmwvNbCv8GMbPr5bYqErvhm4saS0FQoQ7etX8WNWCBrHSXQB36T8/l3JeY3lg5HIRRBQF/Y/DVVDOadzvKiMdXFF9vBoPFCYoB9CS43ByGXZdkEVAZ4j63fBBnGU/nWdkWLICjIlRUvd7iBe6rzn4nIF2/IjUco1WxenB3UVDdtwMkH26bIZqe31gffN4u6rIFK2/HEg50P7ytif53PRKyJlqz2PIOS3JxVnCyWnt2MbJK+pJ3ch/CzdYEigmIN0auORp604+lMZVkZxncf40wOZpB4AT+otd702jVSviCUS/9QUmx/ZE4pKEi8Qy5PIzTbb53LiYF8YlIJ0bqTuAnh6wcWnfgq1/YtCzuNw5W8NsEz6FFwQW2KuCvkIpEsSiLfQ3Lm+zOaUr3RwQmtXiN+W67rM1NUxZ5NHD9+vwhpe4k6H7Sy/nB1P5yap3W03dn7vUQeTcr+Nb9Uo/KZTBW/osiitGopix1A8ja5vx8kJLPolWd+UbAK7O+UyXk9Qk+wId0CeJVBSucP37l1ectou8/Xa81VmCE7UjrYZxaNAD35Qy4Dw9xECdqBJlVqlmfWZAIBFMJnEysQgvvtD3icg07wb8NBOqgz42/4cw1+p1N0pKNH8pa9Ux6DnMBvk4htUBwtdqsabLMdwAMumyEgCehbYBs8lXT0JRpbrR+UYDpZb9CfIiFleUCIG2mho7qun+2TqDp/NTd2anrfPSBKADde0UGB5YACihJejd4NSeqfps+c+GqH/L5vrdSKCPYU0OfUeKLtzaB9pNCAa/2GI2KgKLZyx0e9SajcNaRs4qu4NTBYVEQy26mXr1mnZmzz48cyvDsSRbkBJygGTwByapxLRZxSs9QmqqK2rzURGD3+1/oBlnlBN2skSRJ/E6bvJ2bFGQW4hqXXK6zeKDQlk4GONDTRCCg2yneQ1xzxWrSgDjH8ufZ1zRy3hwKByBaNGsY4TQAigGgyj25b9vNCSDsmFA1mjuFsyGFGSWQF9YROTsd1EhVKwxFuqKwyNsetDvh3Iaz0aB7PlfACNwN4Zdz8BeEACSWmODCRT27U0rdpHFRrpiug0DN/o/rPLjE/p3AUbnFy8kKVKjHQXrGdVB14b0IkYlaO4dimMu7ZFWfsPdiRy37i402GYcPktLodeo1tBTN8f45SpqZfGvCbwloVOTb1KNZWEHRF0BjLf0XeM0SzTE5h/j79oYMMEQPQ9emLPUf9BToo2TTnQ5D/rACc4FmWca6tyIjr3KH0pjBdiTRmJwp5vmkeJ0x8YvhW/ziNd77vm2kWf+MD2Te8YWbWAzFBq+9ts+YkL35PqbQgETRd8PNebOK5/YI5nvAhSjNemgMNUWmCpUX4T1W6FsabRkt7ghLKFW2/8uureTzfhHmHc/yEf1XrE+ZyVU6Z+wadvA1WiAqU32ZilwnJKeU2mk7CuYziglNIy5vL7OngBhIE/yuy4Nd41XfYemSPkRvdAIzEAXI4XGsyuDfnk+JvR9G5f+YDgdlZE48WTUv7aVZmLLDhM+JhYeVe4kPOj2IGL+xQjKCBjUjdrt8HxVQFhjtSFHE9nz6z6W4fY8xtE87dx7V83nQ80Ec0nbBcoiSWBnUN32wRvgDV7PTg8agoe1FvVJ76ON/qZ8g97wngMGX/OVMmfbYQeLSVbIWuVxw1jaGnm55DvH7Dz7VIvdCJF+HvGntznjQa1TroTT9SbybWs5vFhQPTGa5lNW8wF3dcYQoWwAYqkVBTTj5uFFsrepZusfpjbGJx5kXcXNypZpzgWtl9ZqoajfY0Fa5bMaKTYLo9Jmb1feuG+Tk/ASPGQo7J9HpKKwI4hmwDpd7zvEwf5MGj9B8PAvZoF2krD9Ddzm9nAvRAIIHOFsSH4OivC/6n06640EapXtAfDS/MjP5uxbWu2/4XKhXJz7YPdJax5FiXkFhh+OsZnDNrfz8nUMCY2Yo7JH4DZoPtKiYH9690knuckGlu+aWO3WzcDDTslzPsxBtyKWvA5c1NcrFbxlflw6Iw6pIzk7uSYfbAZSMfyPgbaib2Yv7C5MyrhRJ/JWBA0458+W4aCB5t2fhsb1rYBIyGop22Xxi47WkBzyeY10WJwHOLmG5eeA2OiM3+7ZaSvNHclJ+VH1SZH1YZ7OS3rBWR1qzic7n99E0AgG0Yg2B0lw+e8uAYbD5ml1P86GRcNqyZZiugTtWIgLpXn6zRPY3HKAO5pLUF/3bTABC0EIfUWUNd4BBNRXT/vOIrBc+zRTFmPc63DCmadk1My4G7s54LpdYOcb5TfJGUIi1QuiHASSIMWCgYbsWBYHNQRT1QXP0gMBnHaapogaulQRKh+H4rWTx+DFnNatGdcg2INP9y0+mBM6xc//Dfmy21M79pennTOTxjZOJn0cRrhBqEm3l7d3sVI9nexpWhMQtqqJmiZ06FLOal7HfdUZPL90QFRNgc9RJvA7RJsG8zXdM8/QGXNcIIPW09j68X/N6c4RqwxLwRkN5m/mbOwcvcCs0tM7oiPV/GGD72214IrGe6BayrNDI/M4s3JqMjaHffu0LDX3iSkCksx0+Xo4pCbt17im+gVvqmRPihR2oiR7fSS52ObDNgn9J5GsWyrTdBn5ImbrkNAQeajQEW3ji5Z2J+PTqG4gb4OuChPvfINRNgouclMeq4pl4TYSgT2s2yZn5gjA9j6pNu7LPovaqp248S38TTPfJn1GW3z09TspzDOxoQJ9nRa1GD0eBZI5gpRTsk052iYXQg8ikmjTq3ZY+6HYQlY3WN2K+Nj2mRaqZChP2TmhJCFE2R4/sAgLzcQbjDdlNLSLl2Qt40SMgQW1oLp4YtlRpkPDHtB65zEJzV82unb0Luk5eOBu3juq2Y+ta4BzTXGSCK9H3VZ816wo1ke0vZJ53jHs8KDdsJWSevw+zH+HSItdDXeuyHkoQeTLLk7MbmAZ9rhUtzbc0jxeHmaDca1QS3/8pHclfncgAQk2xBfZdPKkzqeImCQkSLENG+wtn2103q89wMMhA5liL5ggzAY9Ah+haD4ags+nPvQ0OIjL+p+Q/u1ATE6dioTKzy15pbB3W/IFRhPlrzjurFDOVOojGsjRiGBrznfHFxNFOFYiNHhN2uZm2rjofRiFXYRC7fNW9J0OkL63UNn8Vr1AR6Z7Xu7Qcx0pfagBv9FY7903/j3r1bZQqvyWkkvn+i4U8odARbCG/jrGX4t1rN97sO/Cg5n53O9g1N2IN+I8zmuE6K9LKLtsSrM/nID3+L7IP/1E997qYg9v/XrgmFW3dtXcDD0wgp9zfRm8Dg2gCwwjt5Za+O++xZ5DuI7J5VMINBqS9E3trN3yE6ILGXSJpPIyBAnVS+v4EK5AUBYs8mBI/88mXmaEQaNigRMmM4Ichb4CF4yKUIwxlyVUW2QHs6xAGzBt/fC0yMMThzU+4r7pFrcz5f5PWNTe+M9Ap7V8I7GM7KRPeiusmH/mHkVVp1DIcJIkxOEQC9n3T1OJ1HTH0/rvcJChcKShJZl8KBcANvhfyaxgKr8/fAfgDKejtpahURt4US8RTDpyIxxtiR1onl6KNP0z0Umj7CcNK66s849T/527EbXTEBUOfboFBGRy+CjoifI18xhe0+rIlMdcUtpbILefikXBHhQ5BkwVA1m8nyE8D38vpGTeBiwv/9VzII8haTVmOvge1A58WwS51bzHgf4eyb1U6rZsJChJLfhMqAdkJcXltus3UAKALcax6Q1e2/YiKG7KPqQJCqS2/AIBzxQ/SLqHkQm7q5ZQDXin2ljOAWZZfZWTHZoJmtC9MoypWeD7n2lCTXy+eX2/3fFiK4YW4M8QVxyGtW9pA1cB1c5F9sv87cuF1aVJxcyprLOkh8sI0pZOwp8broQ9uhtAUHJjJATm6msmES+NJkSOoFySRmyCTZ8De86OJb+0k358SLRl/otRTxVv6AmSJEkqQpRr8tyJYXZZblpZZlhteOtzPSgv1ZGEtaW7rA0saFtc2eSMWvyWUyIDGh9fj6LuVdp03h8PVQOki4MyAnvZ42yfubox34K5TgQUVubDpboO6OZnVd67w7oxLbJQxXHvpA7G8UTNvPPNl89ve6z9xW3wIBqmkz+MBp8MyDc8PWcvhX9EDOl7eQfwgt7AK4TvWVbbNabvcf79cWHC0TlaVJYBF+CaRFSv/0i+CmCymPvMhhGhM3ckd1cyf6zdzTJ/VUyCCYDhLTnA++Lv3RoSneQj/Rwm7fF99iyw7SWnxxnXIRY/M7Z8Ufy8tV1oSn/Kndj+Gs9vA9uECHpEGFjAG6GI7W3iYtmHxfoweuXrR9GjJbhKQSYcrMwF5UWCloVmYZbfAdf3rX/jeytKMA4HDp7p+WuJuPo7l82i+cbtxbFyeqOk4Zna7PZGPj+EmVne2aNV0qsXMxMove1aqIKsKJ6zjvkpkY6ek6MigNTcj3tJQJdPtstW3FWC1ejqjcQOpFaZZJzPL7Tege/oWVUUh6brPHr8l9nN8x2AVHkUC5xYCviYANqN8NP+gbxbx56wrraBjfuluUeYRxqXMDhvgLlJxm87yxITGo1JMSjAv+WXEd03EwpzamBQV/FLPw+RzyqYQ2eRgZNz6DZZJNLdcS3d/v4onY1yHlQr8ECtlXMwpVNbYaD7yQOYAwsSg2AANWilTTPJ2zGTMZQmO4ev2NDY8x4eF4t26BVrArvAtCYaXvgfBG+L516jd7dU8Std2S5iE0UlbAEDKfIbgA89UCZy1iKPziu5e9cpuIu5wXpYOlEt+MZnR/tcBcD/HW5phAygbg047bE+tqDjADTFlvS8Bl3IfqBEI4SGD9TlSTwaShyQH1eYZ5v6i1sDVY1iWmpf4EZ6fjI4cGctI7w//e6W31G70ExrYWuq80naYJp7zsljqd1QmV5fb4NgPMSb65jFogvcySyI6VN2xgb9tv2WSpGUGTH2/Dac5cGagKF2/E9qp8xiSQQrvs0inQsx8jC7f2rE/VFzOhChTRvziAL2c/Kfm+atmSUozDFr/9ArO528ToTS2i7FLuyKFH9D8AdONOWYuYgtiMD8bgnCGXMOEoHnBPMwotjdUmthKFXmzrkprbQBsCSib2xjnCsiepUZocSkEro79slKfof8OlLIwlBXe3Sx3FzWBs56aOWNurvSJSPkEWjNLwdes9DLF3xm8MT1+MQoPAZDcUKv56Uf5vdN/z6u3tbVkuSa1clWQnCSNfEtaPvsls+/LJQ5rvChJtcC5QwEw14HCJCS/dnoLMTB/joLYniLAva4Awl2blkT5J3mxcGqVlnz14b3jxGtcRqGgp69hl6GvNo/B86n1ftsk4AmdQXVdwoOui9mrmzJjMbgJvhsmLVm2T03mQC9TZF5618TfSjFqMxuaqdXIVb0siXoXtFDbsBtBQXHBeGgHTQbXL5yP1ivYEkZLCRbDssaiyxVIqYg0M2scGTIlCL+Xpi7hPX/EL7b62TkP4l+denw51muSXG2E0gEAp+6pXgTnDIBfOvpcTnQXZFwVGMs6qJBoEJsSWCpz8cjK3rzCGevVw/j0VP7lkZTm4GERoNvU2lsMbZYVYDYkdvejKIXuir86nDQ947f5LCGMFrG7I4dlOkoQV3R+/HJf38cpAYxxCe2Jcn6gt4Is17Vr5UDn49DEEZxh00A6ezZ+6kggBoATDOcIoCZM8dMh8p3uXNeHz22Qfqq2M1si1/LOFJVfCJD4ljKPie0Qs4+fYlGehmpEyQdFBx01zA8g3RfcZii/SAFUogjy9sUeuslHGEvHzlSCj0LMlopkfxJo7l8cN1a92Y0fXcMhQCM9IzaF4Kx5U6kUXZ9pOVoX5LWHWQehG5JaY1xKK6yRcCHHBuRhaXl8WToF36U61DPpB5cgvJYv6d335lzeNsnzB9VXKxXwyuXwzKDhG6zWapBd3MOYp9yHOvuwz9d52wo8ZfIRp3Xkwab3w9Tfo6ktv21dhkm/sMbj8zMogmB9zp8ho+iulMTkapbhQadWVXnaM4LsGCZR6a/TPyyyCNwsdNzCDYrYphJ/07Sb0CZsfWF3epICVvfyGmA6PKU2vQoNsvxnjE9SlPLpf/eMZgy/sc//DCWzkv9nLEYbfLdUd9rs58TVTGIASk2vBPQ0sEdznKPerNzzfyWCHAn4BtIX6lk/Fk1jcSoWJwUlPuDfiGbF9e7/8uVbgNZ2zWRH1sFaMygQEer0Rm88bgjEHi829/Zk5X3uN5RNFt6+E+fv1yY/Lp0P8jJ9Bkk3CCuI3Ix7PSpPrcDBa7J+oTfaDZlVpadJlSK9AqY8hkj0Fp3OnlDlJsFsZsMisscasM92+ke/doxeXwjJvZPJ5quB3yxIGPhc178P4Nn0+bQUcBGxD0trI/MkG/mI+cemcvaDMDaOT5Q0uaA1uBmG311vMQZBqqmYqkfLXHpHMJgnjfCmKAE5mflV6sn5hv3hRkxBym7PHbhRxhL6onOw4OzzEulHTAXud77W6GZzxcfH2jKRYTZZC3uQeCGF/zPqLaW7Ql0FCxstmCEmg1Gn/ssjJZGor+bWNlmTD4ZHQrl0VaYP9zIyUBAYaf1bfWqf+6s6z7xzDF6Mkb7Bjk7WaFDxXdmfbcYZxiNTXSuvrADuyr8/v1sZqdTDAiZjsWlaYe8TQZdV6lbqcIuLhFKtfQvv1cKM+O834WJZMWe0VEGrd1kFkRvNrRZvzbaGJKfWcF/umAzQ70N1pa3+ZPvjmFDmXSovSawi8MVrXqQtDmbVgWnxnKhbK/evdHt/+p70jAq5xBj45WORZ8FifIBVS3tuYnFjnt3IReqFHLngU5+kdLF+UpDpm8Yxmqr0DpCdCNifNKzr9oMPf589PUHWx5cL/vljCcb4StbXeE6QJdP4afWVUDxr6lt6hn5TJtxlvrrVWqITOju7p+F3Uy7lizcyle0pyi7oCMPr+pvufwuCKkjkRLrg3qOQ8m379mHe1fH5lEne8ZgHP6rMy/doBiTnqrdMhl6tuvmXMjN+Mcmt9m69/tmKYVjjl6K6UrNlmlsGnPCjKowV0QBTnm5h7XjmcCUmE3+Z5bmEFqh8Gw2VHCSoroGeTWb7lTwBMM4fsd9wugkiesHs3ej8wHEK6stDXHS4UM0150wyK44PzvebqB3WQnBSE4AFT5f/uSwH6nDLHwaqCHvqUZqwApwUd5fGijYxOKyqpFUO6OIE345cdf0GD+/7QkiE1Ks1DRnrR0mQ5JJdLpn2YbCpDXPoTjDrSX0llB2gl5iKyT+rpQPxFBLerjN/AKLWhT5jmrdtNGZQ1pFgRga9YV5pnVPjYUxyo3toObpBDbTTdJ6ujoFDKbteFh+FNPnXOCOr+JX520xMo4pYbVNkxWAQ87ri944K3EJ+OlPMqtIR69v9UlraXILycOjdTvZTu3P4icfIgEZQNFoLRWQEyKjDuXRfGEGDKw82kDBALGG69cZ2dFhDxWXHyZczVnFWIzFXRtLnIfx1nBmqrPjaL0qbLJjdjAQUq7PSOrPzIoOW0rLSdLHjwWTP3SZuuYtrwCyvP1hGF8uWmqa8v21WkIj4crvCL4fSp7gALDlj/R4yn4oIILPZKeFp38HmoRUR+g/Pqb5sPNJaN1TQrmZ7NJ+UKsuRLKLNTTFCEwqvm/IAQLZetptv7JPhuVlOZdkTBcm82H17WhzYvzuOB75Cyv70JoEs3yNAfFkq21LafDFXWvEkMZBBQyOLIjf2O2O3doQEWk5xtYZ4LTGTtw5owRrNQWsewbOLbv35nEMPfucpf9H2JhiIS77f7HYf7C0ITCWZjNxs4JD6/qgPX3lDnO8bPa8XR7lm8hL3lsH1nlQbc8hlUfI0mUFKsEz4G2+V733cv6v4Mq1na3zjt6S0kwzpUn16oMq7QpK9gfuHhc/blDtbdkC0BC/pgTU3yRDuMkdns+cOYZb6vEdP1AkUSXN7bF+VaKh0vbf0uQ2aMtlcbhoOtrY5WZEPCdvCXCfxSSM6YGr6espRXjlIndp+ukZXPcBpYFCBBxFZDJXHRYlC6Qt65NMivF+MC+oLSnc8Wbz53GcLoVMWTC+Ks8GdVi0Qq+IfNU9hmu53eY6TkZQeq8PCZCvtmggBdgydoINPcM1vNpiimkjdGJWsY47YsT4oa4yvm8Kpep79CX2gQm8tG7bIWt5Xdfr48KSVdqkA4swciXGRC1alnkjjCWtVvS8Uz8RD7SlRpfceCyrKoTRREACmNQbBGv3RndTeJacWRpWQmp1o7Kf+msfUTmiKAkGKA6K/3JlvHhmDWZZaeuB+X/3iyRVE52MAp7yDIkwJbtkP3U83TfQdImSoQAJPZjzW3zAWFCuD5yPh0QpU2Re+YYRlrBIncazZnT/GrpZduGtSXP7mZy5XjcNuLznJzrcgoZcATNzha57AFViXj6CcSUtv3RNo9b6o+usjrmU/9Cm+nY5aQSjDuj7rN3E+BPcM3hmOcMFkGBXc2ShtgewP47zaoFRwjDNLnkFAfr/UCu9dYz/V+NyZafqDeAzp/FnyLVDR+jJxTqmH6NjcEdPGM9ZDjhxsvNPeIzPMbN8fh44OEr8JGl+9r7J6K/OHm4SoM1QNsh1UfkimmElarhDGW1ozvWJY/67TEYIwiWcEhpyB8r49CbvkIl1aueaMGs3V0ZArF3aaNZ4TdsBtS2dgk9mvMm8paPaXTkC59Lb2MBdNuPVFXoyjxR/nVPyyeST1bxZB6dMpa4eJC+D6Ue2oU8Ft+khGRrcQaJdocSmjcU42aMiSaBM9uReE+UTZX3KbREUqAlUOHdQctf3H1elu3txU6ssWY+vDDpoLhSKJIyzlBfNdyC5xc/AqpNF6LNRDtAUmk2VEhw/V9siAuhNmfNiQBJM1r6Bg1N/4xA+cdX1Fbc1upDfa9mxH7tIizIweMja0Nt2f9MvT+oTBTwvfMP97Tj9a6OH8mofX9mlusx+i5+jo9buOftiw2uCC6JKEvrVluO9sbffK9/elaI+xNG3vSUOj2hdxG2qVhtG76YTXm8k7DsQiNzIKP78JDI2+JQ8NHKYhTPmMSWrPO1PV5vmBF++sI+gNa6UsA2QHUqvFsvXkENH4s5DYU6CBiRe3KSnnUveNLRL1PorWXuIlWnNzxeMBqYMLD7axxZDWOIqUnxu4UyBrNlCu+rlyderR9QwDKF+BxpKxwj0RhJpxoguj1DCiOXx5wA9pqNgTLQ+n0PdBV/fQ7Bi036jOpaSSZbgWEkeV0CTmVUvbgT5My+ZiUfgnDHmIb+VA9Tb+vDH/6zr2d3eI+yG8ShtdTr1KT6u4xdH6sJCeTw85FrL19x2t1TjHOjB1YgdsynOyX5agnOwtMBbgwVp7lOg9Rh7jt9v2Oac3CUiFuaSN8xjdLdP531PWxF2OXYb7az0VNMnkW20zXnHrYttfYDRZPOlADPoghInX1CBJm3iYHgc8hPMD3VPqSy/e3SopJVJoXLsW0clZ8a26Nsh9/nM3v1OD0xxIJLkhn+6drN04fVdal0Pfn3f/mo9YUn5oJZXFXoybS34fwQ1n3ajNCQKR2ONa4VfcFyzehZQ+6xnrOPBz1DUWH6ANPoKDaHKCMYAp7Rl0fRLY7t2dv0wknryKfzp/UTC+Qx+DS/c9z8ygNAriA5ZPgH37Lu4QWrX+Nq1hcmKn1BcWsvGuBtHrgFVUTMQApwUcw7eCh3l8uYHscqo6JkGIBM25KNHmoLrxfZhIi3jE2SxmP406duECy+NhHPEiXuj33gLi5gqyqMG5D/XkZecd8LJ/+PAFo79mmIlDlBUkJnjEqpd/Erp6LFWTauS9fXz2XMRIN672WfXubKPZwJIg+OnSaAi2a4n4OdF76/5+u0CiSTU3w7u8nC6SAePS/gXSlRP/9Ad12wnyqvrFnpm3lUsQthjuQdPDX/JxMbi1pt8dKvpzG8i1I0C4T2/B2XUhcrsFAfD8pY/Kmo0DzGAm9STM0nyG9s8+TlBnaxyepdTfPCT5wqYxp6wW9ltt9+3i3C6xJ/n4RQBoDuituwXNr7RIf5oNzz4KqvgVzsqqXOw5OFH9/8ZiOC6hgoruWnPEpqnP7VGzZ0vFkcRpPLL+f2zV1jZkRgcGeH4KVflAqc81WxH+nQ93QhEr9ADOeHLz6ehIMIHHxlFq9Jz4xc5qmxI7c9gSVLzIOePpyc5CdyXbZ7cwgA1OPxMt8CqRErdhhOvCLOZ0tmsMRxmqeWdMlSMTTP4rJ4vE6eKjADFr5QVeDqP0M9N8Pgj4xighhapjtWgU3hWQTf+ZV4DiLNtRpBYUTh6PGBLAL9TRXvb7ce3VNea3iqjrUy3Q4npRL1D8pckJCZMtw1hwo0NjIoD2Mqz/Xpjh3Jr4jWJ8nMkD02duI1kyt3PiQSfNs2oGIbPEHiAc/tSjGu9cFq/LVPTkPniVJStAPnLzgHUOQ+6LkiZ+1jIFzlqw2dP8/7t5r23EkyRb8mn68vaDFIzRAEloQwBu0JLT++oHzRJbozK7qNbeye6YjM1acAyrQTe1tbm5G/Oyk8TJaI3uapvr7BVRRjq58LjrE9yGG3LZvbTbnDPjXNwIVpFkU14y0TpwiJHKYix53nLzUavVb2DGOzoQoztojwEtu/xmKs8r79t457OqsD+PmBoKQcSMMa4FFK9QojHdA4tNnL2Um2IQTIbrZU8Numjg0IxBzHY0zPh/JdIi983f1utqkDBkfqdn1qk2LZmD3AvnmZnivXFKZNKGT9FbRgZAoErF/xud5e7s8y47l337rv/7aMI038uL4Fng4U6JSPE1xS0rvEgvqUChNPPDLlIP5naCx9sHlOKoWsLkass6Gkm85Wrq5m7T1/rbB5u/9qz1P6XJWZHfg79acAgpF2K3rdSuQwnL22mjBKM3gTSESiYYzwHK7hoWa/I48Lk+55hkUBizELO5vr/4ecQjqtnsjbXlSYU+kxg2i4ZLXXsinNPyHmhSLqJfKK8Dvb6PgUGmAGkqr5qrQfGWDpy7yZ7SLiH5/JuUkODTsjcw3QW97MY8p0CP+QmORmB6Mg98cJLtFyrmovLdBAvFGYNNG+37u7QkmcTumfaztg/Nqzhixz9m86GejEo/FtVs9RlZTsBsviD5BJXorrZYxgtmfqb/oGA8H7Uw1H67s+aWxcgIxufTOnc864tljsRVyT83QXG7OZc7Di9rtb2y8w1aGHkXsOwyV9VFmINp35z1kDa3+cYZucGPvX0dMpA+CEMxIkOmNXBASU+gMjbl6QONAX5EpZlvijIOtgyZSfXyna+RbmcM+1ukryug/5iA+ktXfGdf39/oS55NH89tWXtmP2pjf9iZT6puR4Rep1rJfzMjeEqVKErFTA6j98zGrA+CpURZpV14Jo3MWAybUaIpUZYdJLQzpMBpXL6rbbuNBevM1jjVdqEgGvmCnUMpaTzw0py9YmhdHgE1i3gJHKUkOjpDSewX79hJvJxZyxIV5ZfYOdq8azw+2ey4XwB/biSLe3l7OppWe/1IS5Jku7SCSc1iZIJyyvgmTGzK6wYPDs8AmEYJ3wZa3tra29D3J9Gxnm+A8sTgupI6ulAln61Zxo+CSFjtx5eEcahRGBGcXFaFnb67+mRh0vm+dtiL1GWKv0hggOSpFihTtzwp5pZXmsmW7HzqAo6FNss1Eu93VHINYlZtv7w+KB0sqGCfLyRUV+AyWSxyyPrmPVfzax83mmHrp38qsPcsy01qNNQPrLRepl7PTAseBmul8zF4HFAez3/CkNiKSH9SYnK6IaZLua0ViTKJXNGbyzkGyW8yFjgI38lAmcX5R50mIHFgQ4vE8ksW81lXXAMzU3cvAciIDheoiNkUsUMUXlNeZYO41wSmIOvCNCGsNdIHDDmJyGFojQGP0QcosFodhi5DHWjIA5rnyVsllkYrmeqhXdq81wN03w+h7TADHDz49Eojn69USr0BLJ+OOOkARXa085FVYD43QL+1dmIRvcX0YPD8Tx/ccBeDEBA7Y57eFcu+hxIQuuFlzcqAQEq7V3vRkgTLVIfTxlggMU2PKq0uYSQyMW3E0Vxzsm+V/jxW7GH1jn93U8owp1zVz36sej09E9q8Z2bNcHZFXWUrvK1zZBxKDGSQHv2ZkUpF8upUPpL9xP7LdnvF2R8vL2t778BApRGbDMGdujaDkR7C+TfNbx2ENmfGSa8hoKeexIxxa0E59mw/5rdyzGBSLCnFfjxl58J4NEJBoaOSk100NiQv9lvoJXfMiJfqeIHwZqnW5p4TMutF7T2am1GTa7I3JxOUVwXzT5gpH6wa6PdrXF9hd1OGnauQJoLtXpnCwunHf6pzzjWYwe/IZ0T/JN8e9ZdAGkvMMEpN+uSMU5NWEF31RwrccEBjaFK5oMcZC1scaQXBptr73aYQ9ipeWZCkILIBnaXPYIsT1FWfIdCSqb28cHI+0WfZrva3QqG5mv2YMsSJuVgEehZIHnhhvNs/5O4Tvfj0EGduu9dPcoKj+QXgsmk4h7+N0UD2gdmbpRnmJoTRyK17o/ej3vvTph9TW2K5xVnQ08Wczc0aCtLdKtaK5kasZE0mIUN1jzZ8Lg+L2pXdT+CH0Vx8zNt0+k42RP0KIHcjqhhTG0OTNi86Cy4swYtG1Ows47MrzIdaUPgKbLXCA4LLvUTfAEzejGFHUOELkFbYP4ggXM35PIsZGt4ZHdLIWsXdbpEHA7lJgeO/NEppKS3UEIdRsbGFiTAcGiogyMnTvKcj986ZBXyeylEIAEiZFQ9O8HuZpLc9orPLbZiwxpcgWjYkrhSRt3OPCjWuUrAZYmfI4ktvHn+YjNz1a50c19jGJMKiDkJBGX28JeaqzH6odO5/CZ1H0t9amw3n4Zr3nJLX7UGYDOMlAouEj+adwMCqCwN6Mf3Ii/7xgDa6uvGC+BxFxRvKPXf1UO6K3rc+BfggixdtgL+7FX+eU5MX3jBUp73iW7Dqwy+xGbZsbvV9wJb37YxLHg3u5JuNj+CR+9Ksj22SpzrD0Zj+eo6WUZw2hC2Qayte9tBqovqWq5r0nGinODDioKRKg+lCsl+SGNRXy0kh91+jTvH1jqpVhxBhsvZu7SwU0Tw5GqDeiaFOZdusZGKajl5Huz2PyZiEfoTcOsjj+U0GwokiBh/vJbkbEXHs2xndhWBKG+My6atjgJ2+UDvQ9pfg9at4/TR6iWoLTL3EzndpCkhkcwZlkRc9MHBdW0KNhsMc3CdzlGKuNZn0ujY85KhkAhNKMH3sskCzTFdCaRQO5JIMZc7DFDILsqkugFT4rM62ZlkBdwnSWOt4C1lb4XO6Aov3A9KojZbjVf/X2/WPOIaPn78bU2ojA+8W9nF73YICoo+qV+i9y5qa2xCTvIDA7L6FmXoMnCLi5JraJiv6wPfZLNcAN0k9+IUrd7+EIJEw6ohsmm7Iv5dYjglxxXWJ723jjH8+/MMxnlxROHHNuxOUGDl7/rkPfh4footxZjzq3aW9bjBrt7drR2xeo73jp75Quh8cz3m/ciaxC7rZk7ZTnAXo5qIhhnVl4HS+QuJV5yV4SZN97GmCoCDiw8hIZ5uWdJ78VTUTy7+nbxprdJhJ5NAYVGkbVTtRjWdBdn6YNeUz1Z1xvVqXlgDzUKBlkGULGX6zkjd/Wbo+gdIls98kH01ZHxN/wRt7LW4epSuq0ufLVI1QVqlkGIY9tsG/GgdMLIhX7yrkDGVY3731GcLKVNbjJjKsBOSGaTz/V46fgMZd+PV9Q+GG2MSNtDKyENsc98T2RLEsLB/IDtABp0cV5HqzZ7pyCVDZML2ZWuGY80tXn2cCDvFR5R/DGTe7ASz+XCZpXoAiXJc+bGiYtA1/UKeSl8MgoUTayV+LEDBZHxv0VgSIqQl7lIYqJPAhw+LfAVyIQWpyBjmrWVz/w+aZ4EqhmYtJbA69k6tITisv3bb2u4FVwzKrr9mG+ArlxKW5u3U6/cAqv3rfJ6znVtY6wmSfI5GK48MRIXXlhoK+USIMFYx9mib/7ql1UsM2SGy4om1CNm7vY9DSQLWGArLC3y2ZNoUa9b0RXYYFcxtolhW3H1sPNmGdZPlYOryHYY2PPfMKwZ61VwCCeIj5S/Pw1+XGMlH3qE9BiybA+O2Xf5Ph7wpfgfadgiTQdP6p+X1QzDh0anxZQ8ZYZrd8+csKt8/HdcM7RrVQaKT8o6ILAmSZRmhI+5oNJUmFpfI5rCVK6FO342K8jaBSwKj686P3xcydBUuhwPOYkbdclRkd5iRTGDe5vGl/45E8JNMt13orubAjR782CIzqYi+qt3Gr4iiuVyYlndiMVPEwTVpm3FTPBGxcjxaiHvH8/dQRkjd9Ar6+bn3zv6evCqZPAmUdwQ54dRTsG1IiBI/PfFv18lm0qHL3M6BNpN3mOz7kZMqUZiwfJTYpHKfQLouGXZ/OMnd8s4ESV1KwU2es/kjM6Foy/mdN7PSCngxfOW3c4fVWxoD/64oJmWMUP+1LHVc4iFTPSy4fggD6wh5bA64Pt6I1QdMd+Jr2c9QoFWCuXeVjP5cwT5wwb43xFpyWwjHQbNcOxPlcPgeCD/h7QnQcXBUnsnBW79Hiy8XeewntXMm8t1NGf1jvS4+4U1amh+ww3zhkfLzdukkdanqfnucoiOAzFciXwNARoE0RGaXkRJD1LRhxPhV2Amgd+cXLGtDoILHq8lDlEptRTv6ylBJmyqZ2lacBjdoZ8MI+HFX64G0hBFY1vRINDsVTJ30xTe1LcRT1EFK2+x8IqByXUPcRtjdgOpZPzzc9Zm6TpbvSWiQ14v6vns3rOaxdlbh0IWUb2H/plq1a+pq/16vc3obdruUH03A4TUKZ8cBTs25P+6i2XEYRpx1l/bgsUZlGPEWkThh5vwqT9lJsCIGNpLDgwk/NBvSCg9H57UmCS4MnKoNnC8L4dfs2FjsxToIAQaFAfU7rtGJhLkmTxQnMQBfE1Gs5PjNY1vF85MWHZRHuEtIZPPl8QVY5BEIAYFySUitXPPZg4XFmGqvOb7+I7wgrT7PH0Jk7/HjRk5m/GDrAsszfpyAIjGEVG88nAzQ0jSDPd2HLs/W2YNrxNiB4+tCoaDjX2OuV/CP9jGQ6aZkJuHswcFgjXpTv1SrAsDNltfPgSD90UTPGKbkfBe78Yv2ezokNI04Gttt8DWoQkd0WbvM5vEipINZRw93fev/0ogJv5Vi1p8c3Q+Ra/5G+CXkJuJsK8kXjZnysZL+ZU5myaZqnJrTrKwPJrfxYxjQJkeKWzCd+c5TLOqvMnuH6KH+VBFw5x85KUeaTp1zt8cJBVpjFW288IlG9cH9aIBwLKsxkkNo3Jl/tvviZ/kPgaLGF9x4RvqmDWJ4BIvMukELWE5BRdEpkptGLW3GRM3BilfRvFwH7AyhE3WcSi1/d4yDPUOF9kfCLophJXNwOnHt9oDpiu5Mp5U5Dtk390yWZfws3Yx5gvsU8Tc/lDZ5+zQ8pBDGvOt7ZJ/HGGYophzbdpbrdtW0EjJL3zEh0upYpOGqUipYGssXPHbuP2vAJYofKzrmU43yzKjCcSehsdWjDioRnvE4k/IUzBVmQHwO0zJng+1NAUz+HszBo3CYjcHti4wg80cqTPzxgDrUqvjcK3tnunM28vHwxs6BxG1qabHiJbO0PPlb0g2Xi8ETfq3xnZRcWyZlzT6a2w5oJg4Cc45ckZByN+3APmtv7wMMuZCGULbdFXg/UC+9p7cCMdLuXy57ee8yTCmpgG/tWHWWMlM722BxRNXoB5HQYqU2KDYlF5gzJUfjlxcokTuHvN6SC+6EgnXCo8tZZk9WfDl7e2Na99oWlMoQ+cQOAdBnnWDL39DyX/ZJPQcEbnFLRLRyiHeADMTYMa0D1xlQx9Xe1rKJsHiBXP6IjSwksWP/Ft+kNRGIXuUm3ON0Mn1xjA1+z99owHmHbKdctBxRAl8wAvP6bBu/gtXmK72zPuZlxeVJhXx2mtpYmbLQYPOi49VSX1xCU0He+Z29c86BqSVUXsH5SSsg7Sx8mmLS1DZLXg7pKCHvvK2lmexT71cLd8R9Ytn5yZEUowCfPdORD8Y25lOhf+7ZXnB8sa0AJcBgahsk+SOV8Yec6BTEmeAq6d55TzweiMvTkvcOfajbZj5gbJ2QGOTD1A03820f3xJt8tMc58OCPqlBvfufTgw4DViudz9T+XnaSgW71oZ4QMfwoUp7SvycWpXQykqa05ME20wQ5B3tdjY80Xsj7DOJ96QXT4zhP12wuBIiLx6SFE+CGz/CTYzUw5VOu9S1QRmzFQqCDx4OTmG8W+Id5xtR4O+LScYY52WIPGCRElkYbIS4DiUprL42UrHzctm8U75myFAk/wjbXhH+u6cUZ0tCqaglVqVEOut3uBtPIguBhF8cAvlAKchAkJkGtiNm9FZnYgxqkvIV7zaxJ8CqUDLHR8fRBOoP5VdtNWEOGPnUsKAZZlp9/azaLa0Eb6YDbNEHDkHPUeuF8V1w2Pi5BMjCea18HIYrK6OQOUTCWUkAIfsIeMvBd2PHtwulJ07f0FW/ELYjaTp5z7r4XL2q00jT22Gap5A+N+SYH2LcSXcBKDQJVXSaF5dlL98J1E9UG28o7WsvbunUu/9QfIh49+ErHXsqwFAawGMwUpY1/ptubIRbHwj+uKeXx5T+/I1Vov1q09NfoXpSju/Q1js26X3kXRzZdzfn7hBLf/lulneTNMGWgLIS55JZtIQaFva9KkfKF+Zap0+a1hBgMNCt40/SH0rktF6zZcjMyiIqIPe5hRP+6OTkFCMw6CvLhcgbKBZSZc+riOrETU6PWwMGmu7jzap2cjiOFFnK/JnbkSp42+1CfNfilI2/yU85o4wQMa4X+4cbcI9boV6+R7FLtxSEfZBgCJ4XrII4Lwj35eAFa3vJdgWBOkiU5APrSXBF/kgeTuCSwr9B04peHzeVzJulPIBPfaeQRzIPu/Yrwtv+BkgSg8iwaQz/Z5n9zzOxC0oGJM3nWgcewZlbdTAolQL+VJLFi3lJMrjuTrNe8SWADigIzkCan0QDCUYf6MJmL7sUsnS083i2R9L6XZB/QiA4w+elaXbRJO3TTUEa3enLMfFJFALIpXqbEyI36CVHmqe120CqrCVOTkDPPdnPYkbfbHnjjnEv3C5JsFdi+c4am2F3JmPGUjvWHGUsV6/N7fIEB7DOBWQ9M0rNGAOSQPDpSInFxK8UZL9k/vRpOvao3xhQrHd0VJwy73+8plUumdVNy1LWNhtIsHfDc9K3zRstri+Jxf3z9KyDgoCT34CdERnjxmZI/W9nwrbz2fkVOM2fVwB4RcOe+reR+CIGQdnAdnRQcnoRPeMfIODjmWrghfj/V7T1WRe8vO44h5bO6XEnLOcZoaU2xhRLBPMijkGZmwx70+26ur10+UFbhakYHGoKeybk63b3JRSF/oXWT2HoWF8RT2D5fhz2EN7nB5x4fItMl3Aykp3Tdw8BitpEJV2UMWQcxjMutXvsmDj4VVT4SysIe9QOu4j02LaJk3DxiWDTZrirT/6IUsjAb55DPzWdb95A0QyZREtJP9ZU/mG7ZXvxDoqjfu52HSQrgfgAkcQzTscnsyYAokW956V/GhGUOvsoPkppa2G/7Oew2twbquIWeUMvQk5G4sP+yLIwTCcRB3MwDuMozt8imeTmlIu2HeXIzuC0rvsFK8Z2tlHJLP7juYSe1z6/ftO/eMWBBE6HgLD1cco7ePwypteRNSbyfMN/TMptzNKV9sL+LpgcgclqD3KLtMNPV4y1sB/G2mTzJlRHEOdu9gf0ZPF3UuGDFHgSnQw2XztlF7IidFRaXEXcjMDnK8jw2qT9ixEngjW3iUTvi9kUrjhojMBo4ORG9EMbmF6fdm7O8vEnjna46Qj6nzE1l2ynfv9+pVkvs5cK1vlWIQ3HreXsvRedWjdY31QbnXVzdN+pUEdiJ9nKa8OQcsRlz189BtjBR2LnmZovEyG+CqeetGRWc8t75fiuB58M6eUIvldNdWiPwwOwf0eWFjNrTSnDfUdWOZO/4zN0U03AOvapQ8yod/Icu6lSxNk6xMohjo6VhQ8rKpSR1LPTpDmON26XNjeCyrz9F0CNd+h1x+W7iQku8a//aJV+xhvQYKU1NT7N7wQcnzl0hLcFF7TERUpTcHXqCxriqn28gtXTCxG/YEr330UiaNHsDPc2ju1pjhgUpfdG74GuOX9QX3x80pyLW4KACWGHTI/KbDk2jA1KyBXTGFv8lQYLLItuMKlZX0sq6F/J7anfXOI9lfVgOZTyw38JbQlM30IJU6aXYVaYgJVFLOgCvv5+2zxy+RQ2Sg9K23k+GbxJ7ChhbwN+cN6rqwGMzS2JhLPpFuDg8II3kTP0cRGiqzu3Zhs4MHpQ8QFdCMQRvZsxq265lxdeOq3Xf417eyhUak22cftGy1pwFmHIo8okbgBEzuQeH3hOYsodW3hV8BCr6K4W0DD2+35kZ+zIvY+/UYCy9k8um6P9U1KtGPkfctz0hvLYL1UABXhe5CG3DLDG/eaCaAp5tVvrbjfPsTYfI5YCO5gVFa8TS/bRk487Hm2oinvLMicf/kv9GbLb7ojwfpGboAUIQ/wY6rKDejsTGQtiSAxooQxiOa/Mjow/Uz3VKA3pM+crsEjZcfhUfkA8V340pWRwj0GGP8ECuwGnlAq5LBvexHvMSbXiUXNSFdL8wgoqrtLvykeXkY3DhILm2iviVw3wl4O5O7ssLduO1B8GiISRmJ7S1I09K9pRU3faxbuyq+3TG/uOo1+5i8GnmprdsqFCRoZMpKcbj5BR1rBC5+z5sL/HvxdyWAn4jg6F1KkK9homc97chGlPOTprQS3fZmM3L6lRkbDLj6WuzRZU3gU5BQ+CT8svAMKu84rp6Qjg3CfBqGe70t9oIh2oNodKBqoyPzb6dS3foeQaRjs/gm0/Gyx7RhVG1jhLJy2RS+lAl8Edj4QWkZ6w8n7VsNnZsiaPYivl6fpCKYWfuepXla7M7RehIS8ifz1wEOoER5U+Kq3ch5Sg3XFD3xmV/b89vPML9IJPbr/Xu+jQFenqC/g4JueBpjlwShN7xAwcBlFkW7Pc2NCAGfAzQmuyj5diffUTzc9TjoLssL1N+WXJdJ6OYNb6/hattU1/WQqFc1C7mLKT2u+zdTH97PQLq5Atl9E/x+UIDuLZT9ZHLJihaeIuOegb08/eZWsALYIcnCEyNEut9zm/kiy+Lq9WzHCQUSA/5evgdlUMULws+8X6O1s7xmKN+6cDRB+n7Ckfroxj5+nqxGAphEfDuW/SrOklocw6wWI6dPh+mfroN56OLB8n43ryl8yHcC7CyJP/aQ7fo4QhPbPxtpJISsEwM6exyf8rWLzP021m3jp1PB2pNHxZaBX+waL5WsLCdHPfaFeBU3tftO73srBQ2yWtotZcjXXP7SU56FeSPAsVcGcbwH+4YpQc1JyFppwAt7ncL2rctHzZDe+tZeRzQrezQPnIzdJfWW9cUHHwrSAp53zcbgk6jkKjG97UWsj524OOjmxlbnulnvyLQxRXR5xU5A64YMy9tOQN+35xOfEpi1rqg8FnznooIqL0IMyTagIVp9eArU6ZetU8jBv5tdoqUtuA3y6epyWzF8b9HFDRGwk5AKh1K98LTN9WJ7SEgbnYd5nEVh5vkoUc6Hc6llNnJiT9oNFS4bnoPdS/S7xF/5wvjfSpGerRF+Y25r3iT2bavCjBoAAFthM2NM3pxC3lwhOIgdD86zZug3adR6ESPI83n2b1yFlBVrvK4VR7dH0YaMW/EgbxA965RsFh29yY+B1m/P3K3byHTwScvpsT6pnnsNWciENN/t7Dq/i+DSW6UvZnb1aaJ+4N82aiI2ybUVqSBW2M7MG66UiQxqQUkisZqccIpCfwvYnvyAC/0ze0onoFr1zm52lXi7nhFp+1hpE82fgjdIdN8/rLCy3AKmG53muXItsWa5lgf0bOBlDG3CvH11E1CVpo5md+OwOgmomaOYbCVPOOKN0v92R1Dy9MF0EGY+rmBO+O12xTdbDk8ucThjFNL9ZZYQFdMqMoBeXp9UKuRvW9iIMAuCeysWhT2Il1Z2u0irOvt5Wmd+YcRZWGnppMyH4Nf0UQV6vnlLDnbtMtCZ49uAHUGxxbowUMGVVt/NAQllLqjlQk3RLZxo4tS/7i/e7lRJwnYSaLt3LTdlnDdcj4bt8Rxj16E35VthkX/Lm7tIeA98S2AI8ayjsJodW6NBhLU6FVJhm2L0SxsXDL1ZL0fzakgr3kknQqFva8HtCvvYX/Ee8Rud9uAcmIKcEJ4KNP2uAAuuqXSLCOX1nYG1YrTTcV1A2a/CSFmhhanqvlcCpwDT83d7k8TwPU8PgT5xzlAWda5lAYYEXeeGeCAS4ybF4kcSP0dm8fniAF9fyzdbT0pqXS2syNkdhlfi23EIHoeP1W2h1Cmuc8fg3enZrOxeen2t6OBtA5bkZVXK56toaL7tzw3IKQS1Fp+A4KPUxdZ77alH6UOmmSVZf+3U7qBVcHWEx59MDhkuySHcOdqbKOYGdJlKHOF3XKVh+jpocyeybJlMvCrG4TDjQbBVwIMOUh+2nadNnm9n3tz2gEDLR2cjbdMMJ4m8CwvONu9qyTQfJMlm1nvlGQPS2G5fSC3n+ZRfOKoWe5viUWW+0rmu3S1+NjgtTkr7nYsmGVj67soWViDWKPoS3U0xDJmOumlJgWM3FMRJWfUDtMm6aUGZ+gIQJXX6kxNZ1RJFfZtZQh+eplP2BRQIM4OVE9FsTIgARE64Cz/Zc8T4BUyCnDXgC9+d6+4cZAaUrHJMSjPP25NITE7fPpjdH1la7JKQYaVx3cBkn+WbxAr0wXJGZaauL1NIdXjN7hOCotHv7X2d5kU6n5Dt1ryX8sOrSLlBP5+yjYYhUpNpeCcCJnjqs+F1HEPUVBBj+3AoTiCuOXyy2wiiKycVEV8bw3hjKl5eaa1KaQVaf922BhqhsR4uKo0qxdU1PJNS3tfs2xmSvJLYecQBJN+gI1HpZ58YPtg7hCUt26xq8vuqpeYeWX1KA+GNc7tSxtND6mQLZHKe/IevLywqSoP3zWpW5MIauJBn30VsFNyCF4UDTssBkPquJgaIGlZZHykV2wlvlSs3VatFhnDMagII3yxv4vA83qzpBdgggeKJPckj2JVFmKpfGz4HOEhtbJ0wN7xxC+F5DbeAZyLdBbxtBjvr7R4Izgr3gyDXn0lp7KduIOHbF/QLD9aZ0zHNn+paRp25f2VdlyjsnE1NbkrXs0hPvufy5/WdcaVzLpPLDACUTN7jrDEGMDcGwRNGiLQr2hOThNVul/l1ZMr5+HY1YeWbST+wd1ElUtqBVqisIdVMCj/pyL09ClHrJ61yr+/p3e4I36Wv+kkeg6kncB7DwA2y1HBKo1AHYTQ+87WdhlPrHyZ8MmwH9ZvjF6yqLwr+5q220euteABOJXRMOO4MS70y21FS9kg5FEPXbm5tI3oXFw7Nnl9Sga4Hwyd+km2Jz60JsjRoz/IQZzSuWROaU2MLuR/eeLVav+s1pCmuezYjifSpf7yUC3bEumhU8YKyhFdIsDdyC7ZAcZWGvM8102NbaWm2sF6ysnNCtzWtHvInZobDUktNwecOHDzrwP6Lrze4XdlgY9tCxzxT9vqSjDmiXzlbKJSUAPjbnRXpQP1nVCgN5FaRKNT0ElmGqI/1miFHciW4bTruKLqnhac7qeUeqCtAAIxZAnoj5XIaMQ6ziRsa9+R7/3b8K5Ud86FrH7AbAWAY16MYl3DS/MrqHb15JVNSTbGU5BX6dt2/ejHlu0Kj+/pzEGWgnHEBAgqpVuTPqarT5oy1FZWsdFhjoijpsS7mh0Wwq4h7bF8cS6w+Q6qK72jsPvvhn2nKSDs483yA8dNsKkj5eEmFh0L2qTCZ5cM9VtTIW+TGvhXcS1So4lvIjS9+hUJvW7wdRtWHI4Z8spdvLLYPds+4uLWkjDocgkjPKor7EEK0WsLoU06sTD2ELMGsJpVp8o0ukMGQSF7D6zANkVxpfJ3YjCER0LS/1VEqD6Nw/DJmYjgD/aJAxniXDBMSHSo+PjKv9ELqA478LAAiDClUxUHVxv3987B8FDL5KRzSx7L0DsC8mWDe2fKt0ShUfRvUY2a+U11a0n6OHkbifeNeg5ZI3/IWIGwXTl1xixEaAhuCOU8Z/E66tUI96QovStUxocPAzchTHxoIkLVRFx/f9GM9WqfnHXUW8pXkjHfRcHDjs4AK6ezmld8adnT+tjW4o7+UkKmvRZCYsZ3Lre3Wg5iIJiZOcfmUbE4GGOyVpLKFmhCt8syu8rdvbrrC8iz1MBGG5jwkmVZ9l2a2GgXjYc+XzkMLctavlrjjR/pgt8z79j0A6Z/QYzYHoKvBnSTASZztKGNbbanRGrzbIWc1lcv7sPDdosCepG7DGzrx6znIeoc/84GMBOxYZQN1xiZk/MSaieTEaUfpvUj4qFnZ0DtV3Phi80DuQDZMIQ+d1FPRxFBU2lzwj3mzYGpqiV8hY23E3CZnOPyuPB4lAXyvS+03UZLMJQq715peK5+hj6e0bGZDrHBvkS3KrcEaoL5YjexiqyaFTYavIt6qwbdDsRf+3QZKFjraW8nM62fXob3kYLyZLkNiwNXGNpeD6TCsc6/FgJITdi6nt02Ws9eEwSYSHgvJHayUEUCuUGMgnN7t+05SA3gI00hV4/4d7DAZXEdcSvWdRSptLqWDsJbCWiM4QYbvUsQ7XiGKsZK/5/YABGvw2UBqMp+J0TRj9uTBarfeYmsBYxxO7dxmTX3mUN75fNqnVT3s6hymFssoPK1kO3Ig7RWxOrrcjiNB8PubHddY4qIFZJKcv/YrOr6BeNrgvxMq43MTlIrYP5/eolbvW9ij1ZfWOleLcXnYcFnhI0OnSNkuEkw+DewEEU6oV1KXvaW+H58hjL24x/ZRh7mtXgoEBZ+o8RgJ74Bv64YikgrGms3Vs8RL2uxukJ87D1G62aWy9AOz4UpdIt63RRfjDSuKgmxmbXFrU69/CobZXoaJYHCLSWbbfm6chon0V1Y3bZD5ZP+499K4Jkqt3xmSIe/p4u7Dnw+4g4b3cvsF4tLA+HBQrgdWfW5zimWwoUxd16O5XpSs3Sh5oRIvoIfH9lSurliJQlMZsP2YvNg8lgI7sbD1ql5zRq6RYh17sbTm7VALTf/o4DAB9LzDF54Rk/Q031NvWfMwKSohtRZcH0j7AVskayw7bD5gIpCFMULy9mWCrtEJhlPaTofAY9T3i0FL02dz8bRwKrR/wHiPB+tHNhwqhG+65YAtrQyjxm+dkEE6WXtDMsMREjl+x6On9Sb3ql46yBPx2aonkj6K9M2ZQFeAGywS2o3Yi17O7kjQOAn5dN3Egx56Elat8bMHR1uWC62gd0yIcDmbHdSaZ0kXS5Ths5e7v6L3YpjoEghyhmqQlsdDZLWsdoiVWj0gcMyfjaRVL9KlZHhIE7nUn76tmD9OJbqvLD6P7g6CkbCZHhtfzQ8OJyRMAdUpjg8G7rKy7l4vN8JxvmtxueAyjEZt1ERpMK7dcEHWEM3rErZnNi2V8ghIbmsoVE55axTypxcIfCERHXF0pXrbVUP0VEV8z47aGJvd1mX3HO36JwVaX65lVdi/WlY26GslkdJhumP3KqKvLNYEAPTacZa3nyrboUWqf8y0yC26dMDekF4HfOQWllvGdOQXmmfu5QnqbkBv2+KFhDX8KEXPaXyHRLM3vNjXC0VpP+YwgTOwBRMx4a3oIhrUO8kE316LvjOFqPhxbmxV+jdv//Yom8d3erv5GpJJxq2bOuU0Lucy3qtBPX86D/JJovIHnT/4Df+NmtkZMus/M7Ni1cEcbC5t+Y7fy5HYwZuSLURd9glWk838fGrcq7aekRpYPt7PmTHQeyX2J84fnYMRqVs/m3YNQIUHS1Gac2vACbG3275Xvxpq7Afsat5FXrB+x8rGKm6bZhX0Y09MgbObtXuLCqrK2omB6o/6NAHqjpSFl/sueNDMB5dvSEFwd/gGcspS4g7PSANamojDRb86PLsRGYuuJKkdZHb1Aco1sIoO3CB5QsVXZG/QN0jmGeJFlr2JCd+yGa2L3/UMYjzk9UJYvGlOQ6ijDQTN/J7vI9xtW5aoB7tQjGES7AvKlIDWu0bOngpk0XqqtqBNR2EQH/4InyVhmS69Gn1U1Fdj0bxV2mVPNM30WJGXE7gffIdym32gvaQxaLcbpkZrF9gVfpnCFR/P8Zk0Z8iXdugm15g8fBBUOnM/B7cYtOwmqlP7xLXjw1x98wibT9mda4YkFUtTDRMTS53Ey+KyqEa6JaFwlhBOT42zpRQrTDWDhk6mtN3iuW10W57HIeQMoXtNIhMpKLYNX6JjR/WoTwaG7xPyOLEP4g/Wg6LbXtH1jYlOo4cxjDW+m0NYLbKwtHy4ea5ZQWVvIMt7fVGgsibihKqkxysdEHUOPsbweLfyxOo3FC0xVFkZKpZuhWkbUxGoIrz47oMbgx4NRbffXBdkojzsbOSYrJ84pIf9J29RLMtHN7W4QWtwT4Ff0HGylsGyjpVnn8PVwu+xmAtCGoA2082DhvYC+GjFlsnuevNVo4pWyCU6lYdeFJ0xmK2gPwVZ1oFKWO7NvdA7ICdoLPODqfOjOXjcO4SoAP6U/MyhtBZcrl0MSNilj6W4MHvNt4Eh8ZB1IJZXRCkqln0GjkHl6JeCTcw8GfTBk4xSPqMXY/hZX9KOYZjSEr/b/nYpn84WHmR3G7557cqZSJaSKoL9+HhsL1sFkepaw/sONFTPR51OExw8BfHd29ThVvrWguOZy4bssP3enSdspU80PBZIzeu8t2jzO8yZ0QvnDPgKK1WxV+kvjFowvHNLrQ+2043XIwQgVR1bt+je8qAS5vTKVfc7Uupc3BMDUNrhWOHSe/fy5a0K+YzP7asMJ6aD2C3UnsOJr+aQZhr3PSUM2dGDyt9YdyINmyc3gTXyR89QJ/RcyheNZP4NIf1Pqd/49EULJ+hw+vzEvpwa1SqJ2gNT5sXUhrcWvYcxyORcQRf8hnYhs3CMqbyf7xWk7MTcsYVr3H19WhxBuSOw0pswsr0Q/wiJ3uOf1hFVshc+Fc85wOgcA8+yC8VkpiSa9sbMYfI2u6rsBT+otEQRQuphgu33SL29ENez2fR+AHeT7ELus9yc9VWbl/gbbB8oT840jjA8Kd7s38cYyQHb17rV4fvN8FeNTQcsaykSUEvkcwOBJeamgdTLOsjeqQLlg3/HqVASLXonlp0ziprQz/g9vwrLTlfVe/NvP1OvsLpJ14K+32vYMRY5zpZVpER34y/ZzGgRMhblqBr5lsinoVV0j88dVDXO5+ircNQ/FYTWhbobnPerfz0Q5dvJ6FJ5zbRpUDdnjWD90xbi8swk0xjBH6aQdvP1tKK3JaRK4Crv1/vAEiV7PO1ja/v1FaHb4dmEzQiCEerRcUcqzwMs68k5rXcD2VMnnRgdSNPCeU/9ZnQTi+YAXfMULetAZaMIE8wmLw+nfz8YYLnGJOvsaCe3Y+8OJ4GPdzF16DVib0LftlKXLKMs6Gd4khwrXnoTGvRsMCa/QlrvFtiUcQMpsLESjixPtHHWm9TkfnffMJLxiCkSL5A7JRKJ1qQ+268ejrnu22SNJkSwj2kUGhp5ksd+LPljFwtEP6NQ4jfiQ4hojY2gNOZkBULlE+Ppjo/AUrIXdaagB7MmP/qRpctuPxhI8rhTS5mexCKZC59oatcfimbQ4dtFbWTl4btDXL++ZSQBZHY3NLrhMlgp1miS46CZlJvSFHSNc3NalsPFNxSBvh6rZSRn/EGXKCtXItN2H20sUJbD+e+jEarveCUVzb8pAFnIg4F9rpdrLm/zhL7n82GJejVq9ppZkg0B4VAgJe9mPhPvf8n03QAzrs13UxavO2b7qDSns7vLN6QD+4Widqv3FKlGOHrjYzJ2PURec2iDMX6hWmalpt7SQkxf/jDk2+9ebD08J3Ns/GiAPjjtVxfVmY6/zjbjTGjW6V35PEkb1gjximFjRJUUpBNnT3qUQmVJN0yUiYSEAl9iIEzIwpu9jr6TrDr/2ejyyRiZJpf1vnzTvh/GqM3J/Nba+Y9aGlrMfWCEibe8UfDnuNz/BFzaFg4UBUJCWAS9Re7nlKMx9SN4Vg51GQtMo8+G9FJvukGsULE8a5WSzm/hzarnJ1YJaKbvn0QsoNtypft+bFaeNP3J+xzNd2PeGVcsdNFDdOVRlJ1EVHIjGrOhkIEI1rVb/AgVrCUnfL0xYBp1GMpQmTFsQqlENrEf+zsWKJ9aofXa2gk1ZXg5gR6pEQjZqXJde9JWG/DZsz6P0eU3eO2YCUbgb83uRwrbI/UVEZf4Ft5I6lsYzMq9nu4dpDrR8B0I+pFt5UEuZpgUxXY+X8u0F5bSYN/BZL6ePKtNoHvT1KSCIw+QGgOJ0aQgYxMthsILlwOn5MKkmYWQCyOrmQ5LzQ5Hhg8Ruce9XJ/maSY0STzX1FASqrymiec+BkJo+Lg4SAvBtTDBraXcOMXyj4sW2f71ueLb+DkmSzi5oJEnpGTTLKECtkRoroIhyaKjGh3NGT1T1Nj+hoS8a2PzG0ggdo34ue6CM+6cl+idJKF27NK6j03yn+5TqLiPBnjn7rIbeywnlqeBkIfRLUOjwk+K8SDqVqWuc/TCg+j1HGdqySBn9/CUGztQuiaq+Pjp5YvKlyRL9YTLUb8qaIVWEKW5hfZQsDIByrgQcwj1DcO+9nfCdyYULQwJ5T+d1Oi8RDj/m3r8Zmqzmzh4sJOPaeE9YQhqcZrkUH5exmrAgUnKiRXc65RCh76csiqN7Fuz+brFZFDd5E90lm6ukIujoNmvwvFVm9YbLg5fVxUDw/Vrwzhc0dDy5+20Rz5oRK9kCks9tdsETy7uH/TFrGzDQpRcqhjqDDtIWfoFZb+g3A0+MumxDSfkvJOMKyjPu/o37bfMQvLb4O6tVuylzS3np1l0okXgw26pfG4nohnGaDfE0UxW3rqeZCjztRNQ6Lw9HXVq7eyNJ4XzhkT7dWmmMmgh1UNivwi5/PJP7sa4sxSVqAvdSHvT911NwUAyVl2Vze5vLOmoZ9mHZB9BNOdIwkSlHRMvDogqU5jt9ZmXulOTg/8cOdQxXxBdXuaKagwJp8TCJhzYYVRuj/s+jQalbmQEsjWugdHZYwfSWo65IU/2AZIFTWVKkHJTDZ6Qktt/PU06TKwPfjsrljkSGKLNz9CvTMK2PVsgimRq1FhYFFOjMvTtt1J6UbiG7DZwjZ4VF3HLtWt81/u8ghvw8Yby0DKzJvkdT48RtxCQMgLkZCYO+/BujChcKokJT9kzaIa1A3swkIJf6FwwdVrcWWNmiOp+/yk5Pjm45cVo1q2e+UGgrgO3w3E7lXSgunEkWFPWXOu95NBbEXhpKmDFBHCYM1amBZsU6CdsAuJ2Hn3AwrLGxwfVWfohQ1DzzafwHTHzD9g2H9Rbi4PIvWzgbYrj+dHVebNfyuLujWyOhh5QYJdhtBpxZg/MUI8otxPTX2FJl7AnljUVWrya20Z50CGFRcme/MA2GC8nwu/7E73S7x9R5SiVEK8QLXO5qVvfMylByhk++nYQXMFQImpTZUAL7NQIM34cziJTTVhHm9xpV9JJ2ulV7q6kuPQWbJE7HqcuEKCX10ecBUpUWOuYW1u/1xYrI9anCRBM1Nuvg2zLZyqnk1BPJ/1uG0OutuRwfc6c05Ojmqor/nwLMU0DKXV8yu7nSWRwX6CWJSGv5cNmtQzQz00rOWBDYvP+yWX4dP7Yd42eeSVhv5lDvukZjuZKpb5UolhvZFtX6Vv/SUxACGc08XVcUJLSIUtCEbU4RAsfJMDVgJdjABV4kI0K6WDimnLdbFDJFIrfXyXzGjKpXWRXIUTfYh7IIoffHLRFV5KgvyZa4kZuoVRQeuwIC9YdOYMYdmKltjEbIadmoZ8OQhM1blrtemzWTfX6AmN8bWA8ew5XTOHWo6ZykO/qozMF7W6givT2O4SVRm++YYZ+WKEHvJryfsw1pyQ/320lewu+fZrSyQWEQ2kXf7jHfSdIXL0JmUFDRPW4l9wsguF+zdO2gZb7FcNn9f0Ks3kcuGdt7A0slypL8jUMCadwFrj8HIvtiuT7UAkajvAJXQ2Ybe1CRISb5VSPHnMeWFRMBMUjw1C/DI9zbzUTaNAhX2QsSF8euL49ruz2pC/TrpigvFHA2FnEx3uBu4ClNn0Qa5bdtj1Qxczn+De9z1tQOlmcj1D+uqWZxDaZySRb95oB6xMcjQz7a1tJ5CPWSxAw3zNvyMPojSL7Ru/Rx7a+zd4uKsO3w6BXsnPpwQUbi6lN1MQ6aGQLKxdp1lhcFpnUs05/vnJgUTdi7mTeavIXt4khTJd8C3Uj8WBBk5Sd6G+/utNntRqlDIeRN4kP/uXOtOkBgtz2OLl2FrS8OJjPbrFHStKXh1mava2Mfo7sF9iFaAQnafZiufihtQ4rUNa0x4VrQPB0f5BgC5MdMoGzWiV4iHBQ7a1y4dqOo6oLfZGeUgXDVnegFQ/7zRrHfSysp79SAnUjoSkoi+mI0vM7GUHTb8gmOE/oMALYXEdcOwY3dMn0El9ecMcE+/Y/Dkkkr+od8NSJMN7XzKBwKJgL7ysmw9NAIRgPdMhiO0LGttuFzZf3OB+4eynQrOiJjhnkvUo7eQIUyB7xt+fj/e1PulF5P+Vj9Ka+soua6HATdQtBEHaCzfOqTIonFYVAXawxtWdWQ9qYBBLXSVuedQ0mfcdFlMYQbiLungA3CLzI3953YqV+jK2rJ7AAoAshKRTicsmF+FQeTqTInrDMC+ZwfCz6wvqRAgKyZ3V/6vKqWoaJmV+duuMROFH3P/4ztlygZG2n9SSTVrrmostk7j/sw3JxYWoeRVH8G8p//2fTasqSpeq7+9c9m5f70tQv0a8rNHT//m+gCwO0ZdOSHeBFCIiQ4NIQTVm3/M0lVPg3lPscUtZ/smW6PRH06wUYTf685Pz5nUB/ft2rdCl/PQX5uVRmVVH+elPs19Oi+ef34i9v/B0p9v04ECQOLmvb3z79+zMC3Zj7+xpQpv+9/6hds59L/4YQLfiieX/fPQLNy9n+PEKMa//bA/9nrq776m1HEEwNx18fvH8qwL/wb28DkiPfd/q5/vNxf31TZOrXLs3A7YDV3MtqyewhSsCj+xQN97Vy+dy3z8P3j/My9U3G9W0/fV+NiiJNo+hfHnn/WjEE3GbVtn/zzDzPiCT51wjsP8iLJMjfCQyFfy8wFPoXCIz8vxcY/kcCQ/D/AzrRQHE0Z2D2IDSfn7hv5//NcoQR6p8KEgZn2v8USdK/k6QxVVsEZttDDRhACk1g0AiEgmfF55LN/+JFT4mYwInfLTr8R4ueI/+qRcdo4u8WHUbp3y86Dv05i47if5L5HBT032MpNEGi0e+F9geWksEpnpH/Ikv5TSC/hIZQ0O9dHvknyew/j1HzEHX/72X27//+738js5/3+t8kM4r85zL7k5zbb3jl/8bO0D+SWVJmSTOvn/sJ2F/d4v9ew/sLQvsHQoThP8lb4vCf5S0F8b9HaMT3z38pxOHgv3+N0KjfoPk/EBr2Z8nsP7e8/594y/8hmVH/XGZ/lrfE0f913vJ/Roj0b9r/P+ItsT/J8g4I/t9seTTyz4WG/lky+7P4wFv5S4SLp98u5v30iZbfX/+vmuQCmnn/AxF2fZf9B1n9uhS1VQFSVsktk+y+zgKJVUnUMr8e+FRpCj7mD3Xm77XqXyBy9O/ZBEpR/47/TubUH8gc/1fI/I/4xH9Y6axLmWnqd7BkbTTPVfJPTAf6/vlDdJgd1eKDtft3/Ndvwa93uVdrOv/mIfBr8GuV/2jNs7TI/vGK31+iX6fk17N+SzEs0VRkv1kN8ceS+ZuF/yPy/du1KWujpdr+/jb+SBq/PsHoq68Z/Ub+KfzvJI8TyN+/xc/t/3rVX2X6uzfCSfjvnQb+H97o5zv/7o1uqUbn3zxtAE+Y//Mb/t3n/Ioe/9l9IRD5j54P9m2+d/BXTf2LDP5rykv99ykv/P8B5f2fUlSc/HsX9f+0d2XtiSpN+Necy28emp1LRVDcAcHljkUBUUHB9dd/kImZ2KBhHJDEZM55zskYl7arurrqrbeqAAVZnqyKiqOXGv9m1kpW1MS68lbUJLz5jawswOkytRdlLrUXh32lrNr7Mi7lE2ovSRRrZknke5nZS+39fZeWprwQ1ozdbXqhN8KRz6G8DILdev4/Ky/1QB/htum9T0FLUzwItsMx/D7Fw9BLxSPQYhQvsWDqtuLB64Ke/8+KR19HQDJH01RaNK0bz5yGJvBLjJ8539bvARAiqfYYFPLcEwzTRQEgMVb6QiZ4SV9/AzIBwdAfSjE9r52HGNO87TxO3lPzeAgafCyytKx2DhJj0jB/aE8DO+5Zi9WibxQ62kKaGqG2sq7CdO82WPfC0Fueb+HXlcc/h57/KqKLp6RAhpFAQ2dlsS+IYXy9/+/3/f43nkEOMoIiGZJOUnRS2XEAyUFGnwYpzOo6Xfr2v3WsNHfq0jkBCELc506h4PKYUmcQ7AN36g4Phkmj1/2cyiS3BLvEBTAk5VgiKaYzl2P5aeKbW8H5nUf2dc8uwCSAl3mOSSiYuTcch6MVjIHCq/yOMUDSIpFnOscgn3NMY5c4Wuo5PofBeZ9jgKQFHwUd5Nso232H9VXNSkumXR5MBoa3sh5M5sxceMDBBNepLplJEmRaoEJcpUgks+25hi4YxjA8nyV0MbUpPcuNun4F23x/cOmk6p3rB/7p3IKPmC6XW585AsVTBYv8l1qVoC1jyaz0wH/3UYko9VvpBE5/qBOASbFHuSjFeb2PUQrw9ZTiCrsqDePIk9dIkWUqBVqQuTe+mRQzHO3CzD2aAz019RQfYv/pEfCiThNxMjCL0Ghjmlt5GX0ZJBNnP+sDYiNK5CG0HHIxqUJ7X472vLKLbOKHsgMIWpTwcsjKfGPhYSgoU3g51FSnsvmVleEt/c00CCJ5RPux1RdRNPxaLPrNGMSR4fwFUUnRJIUYkCll2HAy/j4h/wDF2e5AiEBGUEkpvdW/5A4woV8CKc6DxvWmkBfAMVYqPgUlxCOLey9yTF4e9Tf2X858Ggy5jJVI7DafBlA3n//PfBqAJZ04WwtscIbkv3hxK8Av7+k4sIKNA1WUg3yjFcC/haYHBLkanD6D0JCPhZZW3JqP0JK+VXqN4xNsNJz2Ttvo1GLGfHY6h0Yz0PFAjLeN+vNgdJ2S5MuJgZlHRHDiqtPmnGmGTn3VOvZxvb7vtA+nk0odacVufy2nN17iO03Ba/E/+WgKhV4oCp0GDpEpipJHBSU4n/XcGYTQu1xVnrhtEfzajuasVtPwqoZ8+wpMFEAc9BTqW1EFmADPAVBMVZnBNAjfif0by5cBSInyLapJ2ZN3WSLPmNStSniyKDueFit/qcYhJQkNo35dKfF8QOsQgOfA/P5kvUPKkSOFkBnkWFj3kLfSgK/bPqSk80dlkVtRDURAao8saFt/gOC4PObybnss0zC1KxYkpYcDwTi4gIIjuSAEfn6kP9040feMXclbsPAFBkxcx4ovYOHfXW9KqwuAwtW7eYsUApHQC+Qt5tHcKRUtbP/3Mn/5O/HUIlMAWew0OgtWFJ3lRs+nH6JaeVpBJjK6j6WqPbIt1G0y+teqmsdJuGr+zjKvR1XNJxZcctU8IDJwCUotg7hwMsjPpoD/g7FMBoHeI3PDEFgzMjYMuUvo1+GWn966t7hdJNwQGSQuiaJ664LUplZfCiMrR2g48rHQCkPIUns5fW2ErCQp4jDOkpRicfgY+exAS04lnRgBRcWPLM0G536eP6Vhn6p+BKMvMRccSTm6hYVWZFFFn8w3kyJUqJsmxcKqgMgcCkp+kva3L1ioGv+hSXsqCYsVwzUtyXkBlxbwoVxTKocRRulcU5K/agKfQGgY9bHQCuOaUklY5gFc05JOB/3xRhfHNc3SsPTHtY+xD4gR/MhmaG+VPF8Dpjzr1KeBKVHm0nm7vx8afFgL7IcG6DTwpEChX2NJZ82W5N+RK72yiio1hY5BU+EYAHn4mVUJv/Q4SbKYnMvfVlYl1pV3ZRWdhiZ9/Tm6ZfnWlxmyh87RBWdrmPsM61X80c8sN4z6WG6F5VLonyKAwvEE4jKfSZ47uTwCT0jpLL4CRK1Jreo8OsPslmPUQENnu5akKuo2xHCTZD+pLAqs3YLzmXQapldY8RadBCaW22BGHyidsLHODl3aEhfIIb/XdlU9HLc7tCj9CIlGk8BcgULKoZzmU3SDoVEdy4aam8SUNvF8hEcTl30ICOKNfviQfjB0YUyPeMn8IZ4m87zSo+gs0isMuU0drPBM0FRO9H6KgqugCApLO2ZMyjHLBZ5i0pCKPGge7E/TpbOQmUt/kjgfhoe0XGJuJKh+h9s5G7xy6ploGj5JJJOyzUhKHWguFi9lBMK7tAf2stlO+BRbzUD6nLrRhWU9UsYY7J0ocg2C398rcLzVU2wzxcAVemkbzaTZjRz2GUVyuBh+GlQ8+q4BcEYSTfP7ikIv0HM0UHbe42vVgsCTBHAM/3VnkouGhncSsJOYU2YiseQPqkHgdeVdDYIiabhoQZqHPo3mUQgNV49Fuoczf/5AOdLPpodwMWv5ephhhM4j9LCIzpkXqVym1FQuDeVgyHtHddMU5MzCc5ryMph4+oLzU7xkAFJsnFdO8o0BsFf8xuN4RJyHItdhSX8zhf3O/Mn7BwR7+Rc5APwFybyHph89fLHYJ9ALkiay6EVRtEcUSSKeqfE/XGXxBFsPkPMdd2vniwIE3mDQBwIC5ewzjWZR8cIAgXNf1fItH4Leyt6UZ/lK6uREZMGJirN8N2bT/TBS8rrc4NYvFCAeievcGF33AwZ+XrUhcdgy4EmqWnFK8+A5pWWFwq+hV2no4ZXI8u8HmiKwlaHPF0nOwTCA53B+ODICfgGF334BQzK3nv/v4TZI+vt/bRGpNIsY6s/MnaWhfoYMmfRgz52QLhhhkCLeZZDQZKSQzy0WN+F4wVheqGHfgLrO4PiHYgRpNi8fOeZQhZB69sBTywylPpZZSoOLfESGXhXZP0WKmWdlpDmQugHWpBkcQm2/2wdHDFtbewrfzH1/y5xIc2Wt1nQ4tazwOmcpWxHx5/AoC2T6EgjchZA54+jvub7nbFLeXF/0xtjOD7CJUAfrPYHQJrmezg+haeFDYoOdtM1O2xwRgzjsKffgz0/B4d+QhadXARrqwgAQJGlfCtSADMHGl2ecXhOf6Wyi7xLjnFgt8vbj5+cSP+KXTjR5rmW+yLQkBUrciGGyC/SBjUVvJlJzbjh6WSb7qrdlxY4kROMAAEPvpZ68xZ3nG6CgRqTw51CvKffcQrss4y+/tCnJqa8CSV1afIpKGnz83P8ob+J6pF+Psw95lNjfax/oMu0DgcKXOn0nuAQQBDIPBdXMMxAjiP4AKUosjM4bKsKuh6uZ2xilZsSqTmhEXyZ+A2Pj+PGXgsvSCuxtZJI6SWSLYmczNK8h5Tg8HvdtIulFo8aCigrfguGr0MOdcWwqHCFpK9OL6QNo3GX9N38AiZR3akVxwE/W41osiieyHsn67VQNySXrgWUgop69B2epxddB9eX/lcCPvIjXfdDOf5k5h3hz3va0renTRd8LnFd3/+wrJDb9xZ34Ow84KVpro5nO9M/Fd1aCK3fh6/epmVqoRYr9+69RXLyy/kNZR632pD3SqlteJfrTlRWbU6zopx4X/adms5VO/HhTl5tC/MMUVDsqN4p3/uVfOnqMXfjacLYimI2GbtsOvuufInNQJbb6EoT6cOASPWpLbUW3yQqOMI9+x/dPlX2ntia3G+HYmdv4tO546/aR3rXCjYaZmAm6AwWMVDDbRXddlUHMhuRO6uKAO/RHgDE2reNuhjFMReQqRG/gGo3qgZyu/OlogS+asjKuV63ojQVbkHleUtTNotkWo6U2bHfBiaqEr3qoqSn9Y6dyanSRKmd01qETrST6sFmkcDwu90WWtHX3NPGZadw9YzM8+SeSaCw3Ysj6leU+eozf7sL1sNnw9P3eG4zWPb0mohqy6Co7GwfYgsToma3VGjY1kPuHmm52rLpCzDv8qG3O8d1uxNZOtm5YrSExFnW6R3Hx3mwdIAEV1wASCgs1WlF7NtKWp2NtQvqnqsMRYk/ltJ2G7mqrrsaZLlU1uKpHLk68EHJudyVVZPQkALWmrxhKHg6sVbu/RoA/Chfu6Lg1lMnYnY9whVwQ9R2qDKu19cSNhXmSDkAgMUDWkeZ+OVPb/pgTmRYBarMWMsX5sWpiWHSweERaxD0RqijBD7uHltRojsiFO56uDdRsVpbtKu7i9vAwGC4FHxgntqE0pOjpYeuo6mNBHzqTarOnCmaLdL2u3eQbstPVmkvuoHjWXPS7O+nQoUS7txxYTncryWbrpAz4zZxG1D7rOUazT1uBs+R9EdWtQX3Krf2GuFXbp8ix5XeT5m61shtrRw7V3qEXrqRW9OHxsiuqHUw0odtnFj1VE3fd41Kmm+vWobFrVQ7o/OVp1alCnfS1u2PxBQ/WVXkw364OYHRqs9KE7Q5ptz6R9FMV7S7Uyo5GsdoWNB17jOzqdXHhN+QFsp7XvNBuHnq1AQ5EIZQDwNb3+7rRdJoSV2uTQ1ckbXNtbF+OUVW2TDHoqexmQy/siu3KW5Vb142ZJwF/IjjtVrSfywC3UFdSNrbsSPxaPW7GbTYA+60/ELzJ0VeFebfTtKzJ6UhUnGhNbZ+T9JG7q4QOu1WFOm+p+No0eg1xTs45X6q2IztRPXJ7ux7MacWLVW1Tx44VamxufbLCm63RhEXGNDLoBOx20Q5sttkLlhg+1B2Pr4U2oc7346bboQTpSISLdfQGPjj6g0l8ZndWs0pSi5o/aO452pugoy41DZvCyltoO25wXDqjPepsR61VfUD5dU60F4O2REQmWpaNYLoU9xLbitbEE+2qzBkt1XEj8+Z4xow/hfK6PsJQQZxb7EJdUwo7D4KDU1UWU0tegOGWr2lCHVfF08A3d2x3ph69ljchd1vhgBjRey7mI7Yx53qbKlYfRqvFt2ZLkttK9KNkzk4m2jXXyn4pHiVWQKXTml+OQmnHqXV/KIjH03QkyqdJTxkBYz10uOayTYD+gFiL0Q1DseZUGNRnPVWnqJmJbn2JHRFWtAJnPKpHn/3yKchs40f7xWuyv/SkWnTAxzY3AiorcIPKui8vLGUm7p0N1+sOeFvZYp4WK/C6M1AtZU7NQL85Zaez04HVY+MUzEaHwz5yS/jucM2ARZ+ZBi2G8qMHYsyX1y1yaXQbK5wY6/36jCD3K3ERHj2p2ZK62kJcDhRHQ1p2Z+krB0+VJx3ZX4mt+Kyz8ozuhdbBxGYjCTf3Y1uYgo7r0ES7Js8HYNyqtGyHq1OAbAvRN1OEaWio/ZbQD6iV4qzoih3YvXW70saOLSU6ifxaELfiSrXE6NkVKbrtVGHZJE7CgLRU4tgi+rzSZ83alLbbXn1scNbOELobRB3ul4HrCa6ge1vDbtiVBiLVRZup1JD4rcQ5U+mz0S9l2qr79TZSpUWHtjmniiwHnqJ1G1a8PoSrDJQB5sVKyne4fZfyIltYcwWRkqqtkRV27Op6X2UbPW1jMiQJZI4e8zbbkzl8XLfZjswh44bNtmTuIFSGltNbiVgoiAznVsftiSAznlsRdVWI7lLVwrYEOEb3kILoi0ZrKw18dqXRkQpW187BizZjcFT72LEnYfaqqsdfY2IPe27Tj+6cKskN+kos3j6iNrSGtlH8aXRF8fH9K558dmbsx+ZgG/SRejWIvaDolopeRh1XrrlqCPSOnXBAqEgHpN8aWhLX2cyX/pCTsOFWRHRDcESnJc0ahL3ne9GrbV6OK2arLl5lZMC2Xe4IcICuWMC2gqq/GqGuYIlWfQKQHcMZ9QpW3013nqUhtcVxL6EYzfUVS1hFGt5WhbVQH9Ninx7P992NPbKr1p63uUadHfbmSJerBHrzYFSsscXNCbNf4cx6JRi1HE+w8X3dJvRBlQO1is2zCMbNWvudj5yitZkHbtQg/b6vL18MZ7wVlkHsfSegJnh/3JGM2czo8tXObM/OqbaIj7pKAx0eTuywa81psh8sNVecoroYOfdVfTlTmOHEaLmLyvLD87B2j+NFrWWrE3ffGqrs+tS0lWDNqcsR6zfF5sZYc7LsDoa+0nSBsIz8sUFzrXY0XlkOuPUEafmdZVM8emps11aAdcP+eoZ1FNsYeGOKHx9dDQtNhKMWdHR3UTX3ZK4OnhhdL0r05sd9QAnUNl53t2axPQJHXKNqkYy3CGh1RFuS5Mldwtha4+gpTe04qOkKu3JPTntd6dKDyn7UIoSjbSpDhBitO7R4AMfRSV6QO5aiwLB73DrtI7Hi607f4HfVOhFdiPxp1HFjpdPr/aPbiLSsatUmtl6jnMM4tmC9Deo0aUdeNabNyXCGicZ4ohqbQaMrT4gAa7dWYzCrD9X2oOs0FMvoC7GZshUpoDpmMO2Zslwdy4QdG7gqUd1Zo0G9AbpU7Iu5nQZ5kqUNMpd5lfSQ1QIXeQy4q8U6Oso843n0ZtmN/KL2KQ5AeHeyi+NrfdtvD2lSRKnDqUdP3dBst+y+ofEHbWrVw0WzEp28qrEJECu+73fL3/e+Thy3hI1Ksf+3O2gLkhzj1JHoH2tcjzbBeLmmmSgw5GPhqZo+VqXJ3GcsWtsF03owtFSwDf2uunOB2aJqFCYybAddtOqAONaiu3uMaQq7RXGZiT5rOBhjARhFsY4X58mqjZEWtJnmIDaJ411THuiD7lZ8cb4r3IIfRC6BuGTZvDKDl7EYQFISg2ncVDyXYOwj3mKe4XoSjvkJ0a8oBQHDimRKzxM8hcmeT4h+o1QqV4isHEI4SNQJgOg0PbD9z9sQyvwbt8fW5HmHMidqmK4IrjAuP5ZMqjygeXtJx4TJuNvFlS6d5fikwyMwmsyyv4WZITyHxEu6GWLxx5ihkuSGZ5JbYVbo3Iv/W4yQIDLtdYE2KJmvCGztNeP0PO3BSJDR2BdWOY4nY5Gn7RBGUpn2ujilTrIBn7RJGAUTb6/sdWFlwfj1IU0/ZcElakZyMPy1U1jcPZ6Mswu9WsrqSJLYaAx56MXy05LkUyoGSTGZFKO48/ede5IAMsPWF+aAEMnI/kmbkoBMSl6Y+0GkxfjQvv6QtWNjBCApoSkRfWFsbSIZ0v/15ZM6behBXfx5nmEwLIsPN5tNybzIrgwURuEpaRIs5WTlQnUliurrUu6sr3IkCVD6Y1EWNuwLJT7Kg35NWZY1/yt55RHJpHaB0kyrdczDmF733Z9BbFDr11ShYSkOYT4y+/TljEW0ybkoZTrfVBe9c7BSe+dApYSAhp2dzG1koTeiCqpuIuDyl3Mhw9XyJhK5+YJ/L28i0uZslaHZRbd5+p0pKa0Uj7kiyE+rq8y5a1xxqpehUvfx4wbyGaZ8qXpImaqHoyBdkA9TvbuU45MUCBevHOW2nwN52SUcA78ijcAphKDpyF3D4Mw4gfx6+QXK4CB6IlmI1QLg2he63pwu8Qr6o+50sGWkc7aM53P1tLAYmk9QAHX/B6m1omc+Su6oGJkBvMzTdbru/F8xPRf++1mnPs30Esg+EDT0Dpl7EzDQccQLvJZINEXm2ZrgxnboXa+zO8lrGDvSVBzTWLQybJNYY2P0BycwX5p+vdY9Kvu5/xfEdUhZPwdDvcAuV7DhxplkQ130rE65gwjnT39aq55TsgPD4Pv1sWb9wY2PM2E6OIK+9zcjwQCEPj/Sn26c6HvGB++WJ3p5HeBXxAK5p7+x57LuCBSmot19S+AEDPqetayIW+JuVhXa2dJHfLnEPZ6ij75f05VKhdsfq1x/etocKLZt/3QyvG09UHgoGsDOYxUfMbn+TWVz72+rG8+cYyNQDJZbasK0qPbS5HUe1r8l2Yjy2kuXJEkqUZqTmi8trMM0mYYdfaEO0yWJjUgYzlSxFdVkmkoDPe6ZL3JvaBU3lN74GGYha8IgwkPgM9rmGGwOuEueTHcW4Ctjih/miGUahjGd7fxjcJhha8OYLXcfUZe/c9hFwFksIoVjVlxzYSoDTvOl465bebWimgsnkgoolVqPk5RpLv2FqTQcpkDsraD+oRchGZVdCg9C6FDoPqCRNx/tr/sLQ306AQ43A8irwTACa+YrFS43dJ7KgVr3DYfHUCjc2TEKzFI4PEU5+FRRLLoSHfySJEnBMwtTJVmcg0/lQKH7fiNkKCLJfEwTW2EO/l+hYhkmf9zjrCPBgnCpv8TQfpC1F/2BprIBHDzUjX8gUy3jQEI0QQIpuJ/82Xe+gOipUiF6mIRJ5kXCJAprMQ+ll85M4qsLg5lw0Av+3aM8f/X3mhyphvz6V28T2p7lrbQF9+dRSKHm26Uvv9xuL9r2TufPKgneKeQ7+tLbr97U+OV382kYHl/fUNuGXvTQn2W0vZfYNq8TdedhOHsBl4fhykSWzFqe2R6dkwo/U3UfdrnlcImR5KUL9Ga/8p+pG/1148XS+WMWoi9ldzxzGj/j/w== \ No newline at end of file diff --git a/docs/img/pybtc.png b/docs/img/pybtc.png new file mode 100644 index 0000000..21a2da2 Binary files /dev/null and b/docs/img/pybtc.png differ diff --git a/docs/source/.DS_Store b/docs/source/.DS_Store new file mode 100644 index 0000000..74ba4d1 Binary files /dev/null and b/docs/source/.DS_Store differ diff --git a/docs/source/_static/pybtc.png b/docs/source/_static/pybtc.png new file mode 100644 index 0000000..21a2da2 Binary files /dev/null and b/docs/source/_static/pybtc.png differ diff --git a/docs/source/address.rst b/docs/source/address.rst new file mode 100644 index 0000000..fc02023 --- /dev/null +++ b/docs/source/address.rst @@ -0,0 +1,30 @@ +========= +Addresses +========= + +Collection of base classes that implement the work with Bitcoin addresses and address keys. +Supports addresses types PUBKEY, P2PKH, P2SH, P2SH-PWPKH, P2WPKH, P2WSH. + +| +| + +.. autoclass:: pybtc.PrivateKey + :members: + :inherited-members: + +| +| + +.. autoclass:: pybtc.PublicKey + :members: + :inherited-members: + +| +| + +.. autoclass:: pybtc.Address + :members: + :inherited-members: + + + diff --git a/docs/source/block.rst b/docs/source/block.rst new file mode 100644 index 0000000..027e75c --- /dev/null +++ b/docs/source/block.rst @@ -0,0 +1,10 @@ +====== +Blocks +====== + +The class for creating transaction. + + + +.. autoclass:: pybtc.Block + \ No newline at end of file diff --git a/docs/source/classes.rst b/docs/source/classes.rst new file mode 100644 index 0000000..6fb35aa --- /dev/null +++ b/docs/source/classes.rst @@ -0,0 +1,13 @@ +========= +Reference +========= + +.. toctree:: + :name: mastertoc + :maxdepth: 2 + + address.rst + transaction.rst + block.rst + wallet.rst + diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..c68f7fc --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +from sphinx.ext.autodoc import ( + ClassLevelDocumenter, InstanceAttributeDocumenter) + + +sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath('../_static/')) +sys.path.insert(0, os.path.abspath('../../_static/')) +sys.path.insert(0, os.path.abspath('../../pybtc/')) +sys.path.insert(0, os.path.abspath('../../pybtc')) +sys.path.insert(0, os.path.abspath('./_static/')) + +sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath('../..')) +# -- Project information ----------------------------------------------------- + +project = 'pybtc' +copyright = '2015-2018, bitaps.com' +author = 'Aleksey Karpov' + + +def iad_add_directive_header(self, sig): + ClassLevelDocumenter.add_directive_header(self, sig) + +InstanceAttributeDocumenter.add_directive_header = iad_add_directive_header + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.mathjax', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', + 'sphinx.ext.githubpages', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +html_theme_options = { + 'logo': 'pybtc.png', + 'description': ' ', + 'github_banner': True, + 'github_button': True, + 'github_user': 'bitaps-com', + 'github_repo': 'pybtc', + 'page_width': '1100px', + 'caption_font_family': "sans-serif", + 'font_family': "sans-serif", + 'font_size': '16px' +} + +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', + 'searchbox.html', + 'donate.html', + ] +} +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'pybtcdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'pybtc.tex', 'pybtc Documentation', + 'Aleksey Karpov', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'pybtc', 'pybtc Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'pybtc', 'pybtc Documentation', + author, 'pybtc', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True \ No newline at end of file diff --git a/docs/source/conf.py.old b/docs/source/conf.py.old new file mode 100644 index 0000000..c68f7fc --- /dev/null +++ b/docs/source/conf.py.old @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +from sphinx.ext.autodoc import ( + ClassLevelDocumenter, InstanceAttributeDocumenter) + + +sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath('../_static/')) +sys.path.insert(0, os.path.abspath('../../_static/')) +sys.path.insert(0, os.path.abspath('../../pybtc/')) +sys.path.insert(0, os.path.abspath('../../pybtc')) +sys.path.insert(0, os.path.abspath('./_static/')) + +sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath('../..')) +# -- Project information ----------------------------------------------------- + +project = 'pybtc' +copyright = '2015-2018, bitaps.com' +author = 'Aleksey Karpov' + + +def iad_add_directive_header(self, sig): + ClassLevelDocumenter.add_directive_header(self, sig) + +InstanceAttributeDocumenter.add_directive_header = iad_add_directive_header + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.mathjax', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', + 'sphinx.ext.githubpages', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +html_theme_options = { + 'logo': 'pybtc.png', + 'description': ' ', + 'github_banner': True, + 'github_button': True, + 'github_user': 'bitaps-com', + 'github_repo': 'pybtc', + 'page_width': '1100px', + 'caption_font_family': "sans-serif", + 'font_family': "sans-serif", + 'font_size': '16px' +} + +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', + 'searchbox.html', + 'donate.html', + ] +} +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'pybtcdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'pybtc.tex', 'pybtc Documentation', + 'Aleksey Karpov', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'pybtc', 'pybtc Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'pybtc', 'pybtc Documentation', + author, 'pybtc', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True \ No newline at end of file diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst new file mode 100644 index 0000000..a7b801b --- /dev/null +++ b/docs/source/contributing.rst @@ -0,0 +1,36 @@ +.. _pybtc-contributing: + +============ +Contributing +============ + +Instructions for contributors +----------------------------- + + +In order to make a clone of the GitHub repo: open the link and press the +"Fork" button on the upper-right menu of the web page. + + +Workflow is pretty straightforward: + + 1. Clone the GitHub + + 2. Make a change + + 3. Make sure all tests passed + + 4. Add a record intp file into ``change.log``. + + 5. Commit changes to own aiohttp clone + + 6. Make pull request from github page for your clone against master branch + + +Tests coverage +-------------- + +We are trying hard to have good test coverage; please don't make it worse. +All tests located in ``tests/`` folder. + + diff --git a/docs/source/examples.rst b/docs/source/examples.rst new file mode 100644 index 0000000..3dc5ae3 --- /dev/null +++ b/docs/source/examples.rst @@ -0,0 +1,118 @@ +======== +Examples +======== + + +Create address +-------------- + +This is example of usage Address class. The address class implements the work with addresses controlled by a private key. +Supports the ability to create P2WPKH, P2PKH, PUBKEY address types and P2SH_P2WPKH as exception for SEGWIT adoption. +It is recommended to use native SEGWIT address type - P2WPKH, which reduces costs of miner fee and expand block capacity. +To create an address, you need to create a class object. Buy default, +will be created P2WPKH address for mainnet. + + + +.. code-block:: bash + + >>> import pybtc + >>> a = pybtc.Address() + >>> a.address + 'bc1q6cxx5t8xkruz3s5khx7923xvsx5ry4c6p74m5s' + >>> a.private_key.wif + 'L5XKGA2xEHcinWEpmyiABS1bqQux8Av5dGVqcpRtVJC3ZCR5sXUe' + >>> + >>> # create P2PKH legacy format + >>> pybtc.Address(address_type="P2PKH").address + '1ChpKurzFhdCULKaNHCc3Ra9KfxM2LRguw' + >>> + >>> # create testnet address + >>> pybtc.Address(address_type="P2PKH", testnet=True).address + 'mpR4hDfu269yxgZtPVYSD21gtpvdxpTmH6' + >>> + >>> # create P2SH_P2WPKH SEGWIT adoption address + >>> pybtc.Address(address_type="P2SH_P2WPKH").address + '3Bqeq3XqL6azMK3BxNyr8vXgXUtoG63J4T' + >>> + + +Get address from key +-------------------- + +In case you already have private or public key you can object from your key. + +.. code-block:: bash + + >>> a = pybtc.Address('L5XKGA2xEHcinWEpmyiABS1bqQux8Av5dGVqcpRtVJC3ZCR5sXUe') + >>> a.address + 'bc1q6cxx5t8xkruz3s5khx7923xvsx5ry4c6p74m5s' + >>> a.public_key.hex + '03b8b44876e1f45be7e42953ea47026c39cc45341344d3ab32701b93de696107af' + >>> + >>> # get address from public key + >>> pub = pybtc.PublicKey('03b8b44876e1f45be7e42953ea47026c39cc45341344d3ab32701b93de696107af') + >>> + >>> pybtc.Address(pub).address + 'bc1q6cxx5t8xkruz3s5khx7923xvsx5ry4c6p74m5s' + >>> + +Pure functions for address +-------------------------- + +Create private key + +.. code-block:: bash + + >>> import pybtc + >>> pybtc.create_private_key() + 'KyvZYvdzWD4JSPFt4wXwjG53as227zT2qiWbMTicZEUSjiwvbEqi' + >>> + >>> pybtc.create_private_key(compressed=False) + '5Jw8DY1uBrd35xup6eD6KLEFa4AJFbX381HWuHvPGirJto9ZTnr' + >>> + >>> pybtc.is_wif_valid('5Jw8DY1uBrd35xup6eD6KLEFa4AJFbX381HWuHvPGirJto9ZTnr') + True + >>> pybtc.is_wif_valid('5Jw8DY1uBrd35xup6eD6KLEFa4AJFbX381**********Jto9ZTnr') + False + >>> + +Get public key from private key + +.. code-block:: bash + + >>> import pybtc + >>> pybtc.private_to_public_key('5Jw8DY1uBrd35xup6eD6KLEFa4AJFbX381HWuHvPGirJto9ZTnr') + '0479f17a94410afd4f27588a192bacada53add0741765092dc0f8e2a29ea1bcd276dbc1ef74c3e0172d9db8047f2a0a5dc2e8e51a13f7f0cc072de906b765e0f7f' + >>> + >>> pybtc.public_key_to_address('0479f17a94410afd4f27588a192bacada53add0741765092dc0f8e2a29ea1bcd276dbc1ef74c3e0172d9db8047f2a0a5dc2e8e51a13f7f0cc072de906b765e0f7f') + >>> + >>> # this is uncompressed public key, so we can't create witness address + >>> # we have to set witness_version to None to get non segwit address + >>> pub = pybtc.private_to_public_key('5Jw8DY1uBrd35xup6eD6KLEFa4AJFbX381HWuHvPGirJto9ZTnr') + >>> pybtc.public_key_to_address(pub, witness_version=None) + '17mXwxxZRmj1nJJzDszZbW9URSAradEuAt' + >>> + +Tools + +.. code-block:: bash + + >>> pybtc.is_address_valid('17mXwxxZRmj1nJJzDszZbW9URSAradEuAt') + True + >>> pybtc.address_type('17mXwxxZRmj1nJJzDszZbW9URSAradEuAt') + 'P2PKH' + >>> pybtc.address_net_type('17mXwxxZRmj1nJJzDszZbW9URSAradEuAt') + 'mainnet' + >>> + + +Create script address +--------------------- + + + + + + + diff --git a/docs/source/functional.rst b/docs/source/functional.rst new file mode 100644 index 0000000..19529f1 --- /dev/null +++ b/docs/source/functional.rst @@ -0,0 +1,131 @@ + +======================== +Pure functions reference +======================== + +Base function primitives implemented in functional programming paradigm. + + + +Mnemonic(BIP39) +=============== + +.. autofunction:: pybtc.generate_entropy +.. autofunction:: pybtc.load_word_list +.. autofunction:: pybtc.entropy_to_mnemonic +.. autofunction:: pybtc.mnemonic_to_entropy +.. autofunction:: pybtc.mnemonic_to_seed + + +Private keys +============ + +.. autofunction:: pybtc.create_private_key +.. autofunction:: pybtc.private_key_to_wif +.. autofunction:: pybtc.wif_to_private_key +.. autofunction:: pybtc.is_wif_valid + + +Public keys +=========== + +.. WARNING:: + Using uncompressed public keys is + `deprecated `_ + in a new SEGWIT address format. + To avoid potential future funds loss, users MUST NOT use uncompressed keys + in version 0 witness programs. Use uncompressed keys only for backward + compatibilitylegacy in legacy address format (PUBKEY, P2PKH). + + +.. autofunction:: pybtc.private_to_public_key +.. autofunction:: pybtc.is_public_key_valid + + + +Extended keys(BIP32) +==================== + +.. autofunction:: pybtc.create_master_xprivate_key +.. autofunction:: pybtc.xprivate_to_xpublic_key +.. autofunction:: pybtc.derive_xkey +.. autofunction:: pybtc.public_from_xpublic_key +.. autofunction:: pybtc.private_from_xprivate_key + + + +Addresses +========= + +.. autofunction:: pybtc.hash_to_address +.. autofunction:: pybtc.address_to_hash +.. autofunction:: pybtc.public_key_to_address +.. autofunction:: pybtc.address_type +.. autofunction:: pybtc.address_to_script +.. autofunction:: pybtc.is_address_valid + + + +Script +====== + +.. autofunction:: pybtc.decode_script +.. autofunction:: pybtc.parse_script +.. autofunction:: pybtc.delete_from_script +.. autofunction:: pybtc.script_to_hash + + +Signatures +========== + +.. autofunction:: pybtc.verify_signature +.. autofunction:: pybtc.sign_message +.. autofunction:: pybtc.is_valid_signature_encoding + + +Hash encoding +============= + +.. autofunction:: pybtc.rh2s +.. autofunction:: pybtc.s2rh +.. autofunction:: pybtc.reverse_hash + + +Merkle root +=========== + +.. autofunction:: pybtc.merkle_root +.. autofunction:: pybtc.merkle_branches +.. autofunction:: pybtc.merkleroot_from_branches + + +Difficulty +========== + +.. autofunction:: pybtc.bits_to_target +.. autofunction:: pybtc.target_to_difficulty +.. autofunction:: pybtc.bits_to_difficulty +.. autofunction:: pybtc.difficulty_to_target + + +Tools +===== + +.. autofunction:: pybtc.bytes_needed +.. autofunction:: pybtc.int_to_bytes +.. autofunction:: pybtc.bytes_to_int +.. autofunction:: pybtc.int_to_var_int +.. autofunction:: pybtc.var_int_to_int +.. autofunction:: pybtc.var_int_len +.. autofunction:: pybtc.get_var_int_len +.. autofunction:: pybtc.read_var_int +.. autofunction:: pybtc.read_var_list +.. autofunction:: pybtc.int_to_c_int +.. autofunction:: pybtc.c_int_to_int +.. autofunction:: pybtc.c_int_len + + + + + + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..687f68f --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,113 @@ +.. aiohttp documentation master file, created by + sphinx-quickstart on Wed Mar 5 12:35:35 2014. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +================== +Welcome to PYBTC +================== + +Python library for Bitcoin. + +Current version is 2.0. + + +.. _GitHub: https://github.com/bitaps-com/pybtc + + +Key Features +============ + + +- Supports addresses types PUBKEY, P2PKH, P2SH, P2SH-PWPKH, P2WPKH, P2WSH. +- Supports BIP32(Hierarchical Deterministic Wallets), BIP39(Mnemonic code generation) +- Supports BIP141(Segregated Witness) +- Transaction constructor +- Mining pool basic primitives + + +.. _aiohttp-installation: + +Quick library Installation +========================== + +.. code-block:: bash + + $ pip install pybtc + + +Getting Started +=============== + +Usage example:: + + import pybtc + a = pybtc.Address() + print(a.address) + print(a.private_key.wif) + + + + + + +What's new in pybtc 2.0 ? +========================= + +- Mnemonic code generation (BIP39) +- Hierarchical Deterministic Wallets (BIP32) +- Wallet class implemented acording BIP44 +- Imporved transaction deserialization perfomance +- Multisig transacton signing regardless of sequence + + + +Source code +=========== + +The project is hosted on GitHub_ + +Please feel free to file an issue on the `bug tracker +`_ if you have found a bug +or have some suggestion in order to improve the library. + + +Dependencies +============ + +- Python 3.3.3+ +- *secp256k1* + + + +Authors and License +=================== + +The ``pybtc`` package was initially written by `Aleksey Karpov `_ and development continues with contributors. + +Recent contributors: + +- `Aleksey Karpov `_ + +It's *GPL-3.0* licensed and freely available. + +Feel free to improve this package and send a pull request to GitHub_. + + + + +Table Of Contents +================= + +.. toctree:: + :name: mastertoc + :maxdepth: 2 + + installation.rst + examples.rst + classes.rst + functional.rst + contributing.rst + + + diff --git a/docs/source/installation.rst b/docs/source/installation.rst new file mode 100644 index 0000000..d5c3d9d --- /dev/null +++ b/docs/source/installation.rst @@ -0,0 +1,39 @@ +============ +Installation +============ + +This part of the documentation covers the installation of pybtc library. The first step to using any software package is getting it properly installed. + +Get from pip package +-------------------- + +To install pybtc, simply run this simple command in your terminal of choice: + +.. code-block:: bash + + $ pip install pybtc + + +If you don’t have pip installed, this Python pip `installation guide `_ can guide you through the process. + + +Get the Source Code +------------------- + +You can clone the public repository: + +.. code-block:: bash + + $ git clone git://github.com/bitaps-com/pybtc + +Once you have a copy of the source, you can embed it in your own Python package, or install it into your site-packages easily: + +.. code-block:: bash + + $ cd pybtc + $ python3 setup.py install + + + + + diff --git a/docs/source/pybtc.png b/docs/source/pybtc.png new file mode 100644 index 0000000..21a2da2 Binary files /dev/null and b/docs/source/pybtc.png differ diff --git a/docs/source/transaction.rst b/docs/source/transaction.rst new file mode 100644 index 0000000..1da13cb --- /dev/null +++ b/docs/source/transaction.rst @@ -0,0 +1,12 @@ +============ +Transactions +============ + +The class for creating transaction. + + +.. autoclass:: pybtc.Transaction + :members: + + + diff --git a/docs/source/wallet.rst b/docs/source/wallet.rst new file mode 100644 index 0000000..8b68cdd --- /dev/null +++ b/docs/source/wallet.rst @@ -0,0 +1,9 @@ +====== +Wallet +====== + +The class for creating transaction. + + + +.. autoclass:: pybtc.Wallet diff --git a/finalPyflo/pyflo b/finalPyflo/pyflo deleted file mode 160000 index c8db052..0000000 --- a/finalPyflo/pyflo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c8db052b4283a61ebcda48d016a9b82a7442ba82 diff --git a/freshPyflo/pyflo b/freshPyflo/pyflo deleted file mode 160000 index b50066a..0000000 --- a/freshPyflo/pyflo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b50066a1faec3701cf841c45315bb27e1beac632 diff --git a/keyshare/base64.js b/keyshare/base64.js deleted file mode 100644 index ad53bb8..0000000 --- a/keyshare/base64.js +++ /dev/null @@ -1,71 +0,0 @@ -var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -var b64padchar="="; - -function hex2b64(h) { - var i; - var c; - var ret = ""; - for(i = 0; i+3 <= h.length; i+=3) { - c = parseInt(h.substring(i,i+3),16); - ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); - } - if(i+1 == h.length) { - c = parseInt(h.substring(i,i+1),16); - ret += b64map.charAt(c << 2); - } - else if(i+2 == h.length) { - c = parseInt(h.substring(i,i+2),16); - ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); - } - while((ret.length & 3) > 0) ret += b64padchar; - return ret; -} - -// convert a base64 string to hex -function b64tohex(s) { - var ret = "" - var i; - var k = 0; // b64 state, 0-3 - var slop; - for(i = 0; i < s.length; ++i) { - if(s.charAt(i) == b64padchar) break; - v = b64map.indexOf(s.charAt(i)); - if(v < 0) continue; - if(k == 0) { - ret += int2char(v >> 2); - slop = v & 3; - k = 1; - } - else if(k == 1) { - ret += int2char((slop << 2) | (v >> 4)); - slop = v & 0xf; - k = 2; - } - else if(k == 2) { - ret += int2char(slop); - ret += int2char(v >> 2); - slop = v & 3; - k = 3; - } - else { - ret += int2char((slop << 2) | (v >> 4)); - ret += int2char(v & 0xf); - k = 0; - } - } - if(k == 1) - ret += int2char(slop << 2); - return ret; -} - -// convert a base64 string to a byte/number array -function b64toBA(s) { - //piggyback on b64tohex for now, optimize later - var h = b64tohex(s); - var i; - var a = new Array(); - for(i = 0; 2*i < h.length; ++i) { - a[i] = parseInt(h.substring(2*i,2*i+2),16); - } - return a; -} diff --git a/keyshare/ec.js b/keyshare/ec.js deleted file mode 100644 index 0482d4e..0000000 --- a/keyshare/ec.js +++ /dev/null @@ -1,343 +0,0 @@ -// Basic Javascript Elliptic Curve implementation -// Ported loosely from BouncyCastle's Java EC code -// Only Fp curves implemented for now - -// Requires jsbn.js and jsbn2.js - -// ---------------- -// ECFieldElementFp - -// constructor -function ECFieldElementFp(q,x) { - this.x = x; - // TODO if(x.compareTo(q) >= 0) error - this.q = q; -} - -function feFpEquals(other) { - if(other == this) return true; - return (this.q.equals(other.q) && this.x.equals(other.x)); -} - -function feFpToBigInteger() { - return this.x; -} - -function feFpNegate() { - return new ECFieldElementFp(this.q, this.x.negate().mod(this.q)); -} - -function feFpAdd(b) { - return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); -} - -function feFpSubtract(b) { - return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); -} - -function feFpMultiply(b) { - return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); -} - -function feFpSquare() { - return new ECFieldElementFp(this.q, this.x.square().mod(this.q)); -} - -function feFpDivide(b) { - return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); -} - -ECFieldElementFp.prototype.equals = feFpEquals; -ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger; -ECFieldElementFp.prototype.negate = feFpNegate; -ECFieldElementFp.prototype.add = feFpAdd; -ECFieldElementFp.prototype.subtract = feFpSubtract; -ECFieldElementFp.prototype.multiply = feFpMultiply; -ECFieldElementFp.prototype.square = feFpSquare; -ECFieldElementFp.prototype.divide = feFpDivide; - -// ---------------- -// ECPointFp - -// constructor -function ECPointFp(curve,x,y,z) { - this.curve = curve; - this.x = x; - this.y = y; - // Projective coordinates: either zinv == null or z * zinv == 1 - // z and zinv are just BigIntegers, not fieldElements - if(z == null) { - this.z = BigInteger.ONE; - } - else { - this.z = z; - } - this.zinv = null; - //TODO: compression flag -} - -function pointFpGetX() { - if(this.zinv == null) { - this.zinv = this.z.modInverse(this.curve.q); - } - var r = this.x.toBigInteger().multiply(this.zinv); - this.curve.reduce(r); - return this.curve.fromBigInteger(r); -} - -function pointFpGetY() { - if(this.zinv == null) { - this.zinv = this.z.modInverse(this.curve.q); - } - var r = this.y.toBigInteger().multiply(this.zinv); - this.curve.reduce(r); - return this.curve.fromBigInteger(r); -} - -function pointFpEquals(other) { - if(other == this) return true; - if(this.isInfinity()) return other.isInfinity(); - if(other.isInfinity()) return this.isInfinity(); - var u, v; - // u = Y2 * Z1 - Y1 * Z2 - u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); - if(!u.equals(BigInteger.ZERO)) return false; - // v = X2 * Z1 - X1 * Z2 - v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); - return v.equals(BigInteger.ZERO); -} - -function pointFpIsInfinity() { - if((this.x == null) && (this.y == null)) return true; - return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); -} - -function pointFpNegate() { - return new ECPointFp(this.curve, this.x, this.y.negate(), this.z); -} - -function pointFpAdd(b) { - if(this.isInfinity()) return b; - if(b.isInfinity()) return this; - - // u = Y2 * Z1 - Y1 * Z2 - var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); - // v = X2 * Z1 - X1 * Z2 - var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); - - if(BigInteger.ZERO.equals(v)) { - if(BigInteger.ZERO.equals(u)) { - return this.twice(); // this == b, so double - } - return this.curve.getInfinity(); // this = -b, so infinity - } - - var THREE = new BigInteger("3"); - var x1 = this.x.toBigInteger(); - var y1 = this.y.toBigInteger(); - var x2 = b.x.toBigInteger(); - var y2 = b.y.toBigInteger(); - - var v2 = v.square(); - var v3 = v2.multiply(v); - var x1v2 = x1.multiply(v2); - var zu2 = u.square().multiply(this.z); - - // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) - var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); - // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 - var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); - // z3 = v^3 * z1 * z2 - var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); - - return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); -} - -function pointFpTwice() { - if(this.isInfinity()) return this; - if(this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); - - // TODO: optimized handling of constants - var THREE = new BigInteger("3"); - var x1 = this.x.toBigInteger(); - var y1 = this.y.toBigInteger(); - - var y1z1 = y1.multiply(this.z); - var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); - var a = this.curve.a.toBigInteger(); - - // w = 3 * x1^2 + a * z1^2 - var w = x1.square().multiply(THREE); - if(!BigInteger.ZERO.equals(a)) { - w = w.add(this.z.square().multiply(a)); - } - w = w.mod(this.curve.q); - //this.curve.reduce(w); - // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) - var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); - // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 - var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); - // z3 = 8 * (y1 * z1)^3 - var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); - - return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); -} - -// Simple NAF (Non-Adjacent Form) multiplication algorithm -// TODO: modularize the multiplication algorithm -function pointFpMultiply(k) { - if(this.isInfinity()) return this; - if(k.signum() == 0) return this.curve.getInfinity(); - - var e = k; - var h = e.multiply(new BigInteger("3")); - - var neg = this.negate(); - var R = this; - - var i; - for(i = h.bitLength() - 2; i > 0; --i) { - R = R.twice(); - - var hBit = h.testBit(i); - var eBit = e.testBit(i); - - if (hBit != eBit) { - R = R.add(hBit ? this : neg); - } - } - - return R; -} - -// Compute this*j + x*k (simultaneous multiplication) -function pointFpMultiplyTwo(j,x,k) { - var i; - if(j.bitLength() > k.bitLength()) - i = j.bitLength() - 1; - else - i = k.bitLength() - 1; - - var R = this.curve.getInfinity(); - var both = this.add(x); - while(i >= 0) { - R = R.twice(); - if(j.testBit(i)) { - if(k.testBit(i)) { - R = R.add(both); - } - else { - R = R.add(this); - } - } - else { - if(k.testBit(i)) { - R = R.add(x); - } - } - --i; - } - - return R; -} - -ECPointFp.prototype.getX = pointFpGetX; -ECPointFp.prototype.getY = pointFpGetY; -ECPointFp.prototype.equals = pointFpEquals; -ECPointFp.prototype.isInfinity = pointFpIsInfinity; -ECPointFp.prototype.negate = pointFpNegate; -ECPointFp.prototype.add = pointFpAdd; -ECPointFp.prototype.twice = pointFpTwice; -ECPointFp.prototype.multiply = pointFpMultiply; -ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo; - -// ---------------- -// ECCurveFp - -// constructor -function ECCurveFp(q,a,b) { - this.q = q; - this.a = this.fromBigInteger(a); - this.b = this.fromBigInteger(b); - this.infinity = new ECPointFp(this, null, null); - this.reducer = new Barrett(this.q); -} - -function curveFpGetQ() { - return this.q; -} - -function curveFpGetA() { - return this.a; -} - -function curveFpGetB() { - return this.b; -} - -function curveFpEquals(other) { - if(other == this) return true; - return(this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); -} - -function curveFpGetInfinity() { - return this.infinity; -} - -function curveFpFromBigInteger(x) { - return new ECFieldElementFp(this.q, x); -} - -function curveReduce(x) { - this.reducer.reduce(x); -} - -// for now, work with hex strings because they're easier in JS -function curveFpDecodePointHex(s) { - switch(parseInt(s.substr(0,2), 16)) { // first byte - case 0: - return this.infinity; - case 2: - case 3: - // point compression not supported yet - return null; - case 4: - case 6: - case 7: - var len = (s.length - 2) / 2; - var xHex = s.substr(2, len); - var yHex = s.substr(len+2, len); - - return new ECPointFp(this, - this.fromBigInteger(new BigInteger(xHex, 16)), - this.fromBigInteger(new BigInteger(yHex, 16))); - - default: // unsupported - return null; - } -} - -function curveFpEncodePointHex(p) { - if (p.isInfinity()) return "00"; - var xHex = p.getX().toBigInteger().toString(16); - var yHex = p.getY().toBigInteger().toString(16); - var oLen = this.getQ().toString(16).length; - if ((oLen % 2) != 0) oLen++; - while (xHex.length < oLen) { - xHex = "0" + xHex; - } - while (yHex.length < oLen) { - yHex = "0" + yHex; - } - return "04" + xHex + yHex; -} - -ECCurveFp.prototype.getQ = curveFpGetQ; -ECCurveFp.prototype.getA = curveFpGetA; -ECCurveFp.prototype.getB = curveFpGetB; -ECCurveFp.prototype.equals = curveFpEquals; -ECCurveFp.prototype.getInfinity = curveFpGetInfinity; -ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger; -ECCurveFp.prototype.reduce = curveReduce; -ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex; -ECCurveFp.prototype.encodePointHex = curveFpEncodePointHex; diff --git a/keyshare/jsbn.js b/keyshare/jsbn.js deleted file mode 100644 index 4ed7c83..0000000 --- a/keyshare/jsbn.js +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright (c) 2005 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Basic JavaScript BN library - subset useful for RSA encryption. - -// Bits per digit -var dbits; - -// JavaScript engine analysis -var canary = 0xdeadbeefcafe; -var j_lm = ((canary&0xffffff)==0xefcafe); - -// (public) Constructor -function BigInteger(a,b,c) { - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); -} - -// return new, unset BigInteger -function nbi() { return new BigInteger(null); } - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) -function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this[i++]+w[j]+c; - c = Math.floor(v/0x4000000); - w[j++] = v&0x3ffffff; - } - return c; -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) -function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this[i]&0x7fff; - var h = this[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w[j++] = l&0x3fffffff; - } - return c; -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. -function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this[i]&0x3fff; - var h = this[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w[j++] = l&0xfffffff; - } - return c; -} -if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; -} -else if(j_lm && (navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; -} -else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; -} - -BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; -} - -// (protected) set from integer value x, -DV <= x < DV -function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this[0] = x; - else if(x < -1) this[0] = x+this.DV; - else this.t = 0; -} - -// return bigint initialized to value -function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - -// (protected) set from string and radix -function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); - } - else - this[this.t-1] |= x<= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; -} - -// (public) return string representation in given radix -function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1< 0) { - if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } - while(i >= 0) { - if(p < k) { - d = (this[i]&((1<>(p+=this.DB-k); - } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); - } - } - return m?r:"0"; -} - -// (public) -this -function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - -// (public) |this| -function bnAbs() { return (this.s<0)?this.negate():this; } - -// (public) return + if this > a, - if this < a, 0 if equal -function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - r = i-a.t; - if(r != 0) return (this.s<0)?-r:r; - while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; - return 0; -} - -// returns bit length of the integer x -function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; -} - -// (public) return the number of bits in "this" -function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); -} - -// (protected) r = this << n*DB -function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; - for(i = n-1; i >= 0; --i) r[i] = 0; - r.t = this.t+n; - r.s = this.s; -} - -// (protected) r = this >> n*DB -function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r[i-n] = this[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; -} - -// (protected) r = this << n -function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); -} - -// (protected) r = this >> n -function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<>bs; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<>bs; - } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c -= a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r[i++] = this.DV+c; - else if(c > 0) r[i++] = c; - r.t = i; - r.clamp(); -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. -function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); -} - -// (protected) r = this^2, r != this (HAC 14.16) -function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x[i],r,2*i,0,1); - if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r[i+x.t] -= x.DV; - r[i+x.t+1] = 1; - } - } - if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); - r.s = 0; - r.clamp(); -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. -function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } - else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<= 0) { - r[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); - if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); -} - -// (public) this mod a -function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; -} - -// Modular reduction using "classic" algorithm -function Classic(m) { this.m = m; } -function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; -} -function cRevert(x) { return x; } -function cReduce(x) { x.divRemTo(this.m,null,x); } -function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } -function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -Classic.prototype.convert = cConvert; -Classic.prototype.revert = cRevert; -Classic.prototype.reduce = cReduce; -Classic.prototype.mulTo = cMulTo; -Classic.prototype.sqrTo = cSqrTo; - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. -function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; -} - -// Montgomery reduction -function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; -} - -// xR mod m -function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; -} - -// x/R mod m -function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; -} - -// x = x/R mod m (HAC 14.32) -function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = "x^2/R mod m"; x != r -function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = "xy/R mod m"; x,y != r -function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Montgomery.prototype.convert = montConvert; -Montgomery.prototype.revert = montRevert; -Montgomery.prototype.reduce = montReduce; -Montgomery.prototype.mulTo = montMulTo; -Montgomery.prototype.sqrTo = montSqrTo; - -// (protected) true iff this is even -function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) -function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1< 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); -} - -// (public) this^e % m, 0 <= e < 2^32 -function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); -} - -// protected -BigInteger.prototype.copyTo = bnpCopyTo; -BigInteger.prototype.fromInt = bnpFromInt; -BigInteger.prototype.fromString = bnpFromString; -BigInteger.prototype.clamp = bnpClamp; -BigInteger.prototype.dlShiftTo = bnpDLShiftTo; -BigInteger.prototype.drShiftTo = bnpDRShiftTo; -BigInteger.prototype.lShiftTo = bnpLShiftTo; -BigInteger.prototype.rShiftTo = bnpRShiftTo; -BigInteger.prototype.subTo = bnpSubTo; -BigInteger.prototype.multiplyTo = bnpMultiplyTo; -BigInteger.prototype.squareTo = bnpSquareTo; -BigInteger.prototype.divRemTo = bnpDivRemTo; -BigInteger.prototype.invDigit = bnpInvDigit; -BigInteger.prototype.isEven = bnpIsEven; -BigInteger.prototype.exp = bnpExp; - -// public -BigInteger.prototype.toString = bnToString; -BigInteger.prototype.negate = bnNegate; -BigInteger.prototype.abs = bnAbs; -BigInteger.prototype.compareTo = bnCompareTo; -BigInteger.prototype.bitLength = bnBitLength; -BigInteger.prototype.mod = bnMod; -BigInteger.prototype.modPowInt = bnModPowInt; - -// "constants" -BigInteger.ZERO = nbv(0); -BigInteger.ONE = nbv(1); diff --git a/keyshare/jsbn2.js b/keyshare/jsbn2.js deleted file mode 100644 index 5b2b725..0000000 --- a/keyshare/jsbn2.js +++ /dev/null @@ -1,656 +0,0 @@ -// Copyright (c) 2005-2009 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Extended JavaScript BN functions, required for RSA private ops. - -// Version 1.1: new BigInteger("0", 10) returns "proper" zero -// Version 1.2: square() API, isProbablePrime fix - -// (public) -function bnClone() { var r = nbi(); this.copyTo(r); return r; } - -// (public) return value as integer -function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<>24; } - -// (public) return value as short (assumes DB>=16) -function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - -// (protected) return x s.t. r^x < DV -function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - -// (public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; -} - -// (protected) convert to radix string -function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; -} - -// (protected) convert from radix string -function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) alternate constructor -function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1< 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - if((d&0x80) != 0) d |= -256; - if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; -} - -function bnEquals(a) { return(this.compareTo(a)==0); } -function bnMin(a) { return(this.compareTo(a)<0)?this:a; } -function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - -// (protected) r = this op a (bitwise) -function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); -} - -// (public) this & a -function op_and(x,y) { return x&y; } -function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - -// (public) this | a -function op_or(x,y) { return x|y; } -function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - -// (public) this ^ a -function op_xor(x,y) { return x^y; } -function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - -// (public) this & ~a -function op_andnot(x,y) { return x&~y; } -function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - -// (public) ~this -function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; -} - -// (public) this << n -function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; -} - -// (public) this >> n -function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; -} - -// return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; -} - -// (public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; -} - -// return number of 1 bits in x -function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; -} - -// (public) return number of set bits -function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; -} - -// (public) true iff nth bit is set -function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); -} - -// (protected) this op (1<>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); -} - -// (public) this + a -function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - -// (public) this - a -function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - -// (public) this * a -function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - -// (public) this^2 -function bnSquare() { var r = nbi(); this.squareTo(r); return r; } - -// (public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - -// (public) this % a -function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - -// (public) [this/a,this%a] -function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return new Array(q,r); -} - -// (protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); -} - -// (protected) this += n << w words, this >= 0 -function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } -} - -// A "null" reducer -function NullExp() {} -function nNop(x) { return x; } -function nMulTo(x,y,r) { x.multiplyTo(y,r); } -function nSqrTo(x,r) { x.squareTo(r); } - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -// (public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); -} - -// Barrett modular reduction -function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; -} - -function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } -} - -function barrettRevert(x) { return x; } - -// x = x mod m (HAC 14.42) -function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = x^2 mod m; x != r -function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = x*y mod m; x,y != r -function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -// (public) this^e % m (HAC 14.85) -function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1< 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; -} - -// (protected) this % n, n < 2^26 -function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; -} - -// (public) 1/this % m (HAC 14.61) -function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; -} - -var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - -// (public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); -} - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for(var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; -} - -// protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -// public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - -// JSBN-specific extension -BigInteger.prototype.square = bnSquare; - -// BigInteger interfaces not implemented in jsbn: - -// BigInteger(int signum, byte[] magnitude) -// double doubleValue() -// float floatValue() -// int hashCode() -// long longValue() -// static BigInteger valueOf(long val) diff --git a/keyshare/keysharing.html b/keyshare/keysharing.html deleted file mode 100644 index 720a93d..0000000 --- a/keyshare/keysharing.html +++ /dev/null @@ -1,283 +0,0 @@ - - - - JavaScript ECDH Key Exchange Demo - - - - - - - - - - - - -

JavaScript ECDH Key Exchange Demo

- -
- - - - - - -
AliceBob
-[Step 1] Alice's private value (a):
-
-

-[Step 3] Alice's public point (A = aG) (X,Y):
-
-
-

-[Step 5] Alice's secret key (S = aB = abG) (X,Y):
-
-
- -

-[Step 2] Bob's private value (b):
-
-

-[Step 4] Bob's public point (B = bG) (X,Y):
-
-
-

-[Step 6] Bob's secret key (S = bA = baG) (X,Y):
-
-
- -

-

Status:
-

-


-

Elliptic Curve parameters

- - - - - - - - -

-Curve Q:
-
-Curve A:
-
-Curve B:
-

-G (X,Y):
-
-

-N:
-

-

-
-

Notes

-
    -
  • Performance data moved to the speed tables -
  • Implementation based on BouncyCastle's Java EC code -
  • Point compression not supported -
  • Only curves over F(p) supported, no F(2m) support yet -
  • Additional performance optimizations (e.g. windowed multiplier) not yet exploited -
  • More error checking needed -
  • Need a switch to display hex values in demo -
-
-
Tom Wu
- - diff --git a/keyshare/prng4.js b/keyshare/prng4.js deleted file mode 100644 index 3034f3f..0000000 --- a/keyshare/prng4.js +++ /dev/null @@ -1,45 +0,0 @@ -// prng4.js - uses Arcfour as a PRNG - -function Arcfour() { - this.i = 0; - this.j = 0; - this.S = new Array(); -} - -// Initialize arcfour context from key, an array of ints, each from [0..255] -function ARC4init(key) { - var i, j, t; - for(i = 0; i < 256; ++i) - this.S[i] = i; - j = 0; - for(i = 0; i < 256; ++i) { - j = (j + this.S[i] + key[i % key.length]) & 255; - t = this.S[i]; - this.S[i] = this.S[j]; - this.S[j] = t; - } - this.i = 0; - this.j = 0; -} - -function ARC4next() { - var t; - this.i = (this.i + 1) & 255; - this.j = (this.j + this.S[this.i]) & 255; - t = this.S[this.i]; - this.S[this.i] = this.S[this.j]; - this.S[this.j] = t; - return this.S[(t + this.S[this.i]) & 255]; -} - -Arcfour.prototype.init = ARC4init; -Arcfour.prototype.next = ARC4next; - -// Plug in your RNG constructor here -function prng_newstate() { - return new Arcfour(); -} - -// Pool size must be a multiple of 4 and greater than 32. -// An array of bytes the size of the pool will be passed to init() -var rng_psize = 256; diff --git a/keyshare/rng.js b/keyshare/rng.js deleted file mode 100644 index 9db1382..0000000 --- a/keyshare/rng.js +++ /dev/null @@ -1,75 +0,0 @@ -// Random number generator - requires a PRNG backend, e.g. prng4.js - -// For best results, put code like -// -// in your main HTML document. - -var rng_state; -var rng_pool; -var rng_pptr; - -// Mix in a 32-bit integer into the pool -function rng_seed_int(x) { - rng_pool[rng_pptr++] ^= x & 255; - rng_pool[rng_pptr++] ^= (x >> 8) & 255; - rng_pool[rng_pptr++] ^= (x >> 16) & 255; - rng_pool[rng_pptr++] ^= (x >> 24) & 255; - if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; -} - -// Mix in the current time (w/milliseconds) into the pool -function rng_seed_time() { - rng_seed_int(new Date().getTime()); -} - -// Initialize the pool with junk if needed. -if(rng_pool == null) { - rng_pool = new Array(); - rng_pptr = 0; - var t; - if(window.crypto && window.crypto.getRandomValues) { - // Use webcrypto if available - var ua = new Uint8Array(32); - window.crypto.getRandomValues(ua); - for(t = 0; t < 32; ++t) - rng_pool[rng_pptr++] = ua[t]; - } - if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { - // Extract entropy (256 bits) from NS4 RNG if available - var z = window.crypto.random(32); - for(t = 0; t < z.length; ++t) - rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; - } - while(rng_pptr < rng_psize) { // extract some randomness from Math.random() - t = Math.floor(65536 * Math.random()); - rng_pool[rng_pptr++] = t >>> 8; - rng_pool[rng_pptr++] = t & 255; - } - rng_pptr = 0; - rng_seed_time(); - //rng_seed_int(window.screenX); - //rng_seed_int(window.screenY); -} - -function rng_get_byte() { - if(rng_state == null) { - rng_seed_time(); - rng_state = prng_newstate(); - rng_state.init(rng_pool); - for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) - rng_pool[rng_pptr] = 0; - rng_pptr = 0; - //rng_pool = null; - } - // TODO: allow reseeding after first request - return rng_state.next(); -} - -function rng_get_bytes(ba) { - var i; - for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); -} - -function SecureRandom() {} - -SecureRandom.prototype.nextBytes = rng_get_bytes; diff --git a/keyshare/rsa.js b/keyshare/rsa.js deleted file mode 100644 index 9f86640..0000000 --- a/keyshare/rsa.js +++ /dev/null @@ -1,112 +0,0 @@ -// Depends on jsbn.js and rng.js - -// Version 1.1: support utf-8 encoding in pkcs1pad2 - -// convert a (hex) string to a bignum object -function parseBigInt(str,r) { - return new BigInteger(str,r); -} - -function linebrk(s,n) { - var ret = ""; - var i = 0; - while(i + n < s.length) { - ret += s.substring(i,i+n) + "\n"; - i += n; - } - return ret + s.substring(i,s.length); -} - -function byte2Hex(b) { - if(b < 0x10) - return "0" + b.toString(16); - else - return b.toString(16); -} - -// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint -function pkcs1pad2(s,n) { - if(n < s.length + 11) { // TODO: fix for utf-8 - alert("Message too long for RSA"); - return null; - } - var ba = new Array(); - var i = s.length - 1; - while(i >= 0 && n > 0) { - var c = s.charCodeAt(i--); - if(c < 128) { // encode using utf-8 - ba[--n] = c; - } - else if((c > 127) && (c < 2048)) { - ba[--n] = (c & 63) | 128; - ba[--n] = (c >> 6) | 192; - } - else { - ba[--n] = (c & 63) | 128; - ba[--n] = ((c >> 6) & 63) | 128; - ba[--n] = (c >> 12) | 224; - } - } - ba[--n] = 0; - var rng = new SecureRandom(); - var x = new Array(); - while(n > 2) { // random non-zero pad - x[0] = 0; - while(x[0] == 0) rng.nextBytes(x); - ba[--n] = x[0]; - } - ba[--n] = 2; - ba[--n] = 0; - return new BigInteger(ba); -} - -// "empty" RSA key constructor -function RSAKey() { - this.n = null; - this.e = 0; - this.d = null; - this.p = null; - this.q = null; - this.dmp1 = null; - this.dmq1 = null; - this.coeff = null; -} - -// Set the public key fields N and e from hex strings -function RSASetPublic(N,E) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - } - else - alert("Invalid RSA public key"); -} - -// Perform raw public operation on "x": return x^e (mod n) -function RSADoPublic(x) { - return x.modPowInt(this.e, this.n); -} - -// Return the PKCS#1 RSA encryption of "text" as an even-length hex string -function RSAEncrypt(text) { - var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); - if(m == null) return null; - var c = this.doPublic(m); - if(c == null) return null; - var h = c.toString(16); - if((h.length & 1) == 0) return h; else return "0" + h; -} - -// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string -//function RSAEncryptB64(text) { -// var h = this.encrypt(text); -// if(h) return hex2b64(h); else return null; -//} - -// protected -RSAKey.prototype.doPublic = RSADoPublic; - -// public -RSAKey.prototype.setPublic = RSASetPublic; -RSAKey.prototype.encrypt = RSAEncrypt; -//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; diff --git a/keyshare/rsa2.js b/keyshare/rsa2.js deleted file mode 100644 index 1dfdb70..0000000 --- a/keyshare/rsa2.js +++ /dev/null @@ -1,132 +0,0 @@ -// Depends on rsa.js and jsbn2.js - -// Version 1.1: support utf-8 decoding in pkcs1unpad2 - -// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext -function pkcs1unpad2(d,n) { - var b = d.toByteArray(); - var i = 0; - while(i < b.length && b[i] == 0) ++i; - if(b.length-i != n-1 || b[i] != 2) - return null; - ++i; - while(b[i] != 0) - if(++i >= b.length) return null; - var ret = ""; - while(++i < b.length) { - var c = b[i] & 255; - if(c < 128) { // utf-8 decode - ret += String.fromCharCode(c); - } - else if((c > 191) && (c < 224)) { - ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63)); - ++i; - } - else { - ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63)); - i += 2; - } - } - return ret; -} - -// Set the private key fields N, e, and d from hex strings -function RSASetPrivate(N,E,D) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - } - else - alert("Invalid RSA private key"); -} - -// Set the private key fields N, e, d and CRT params from hex strings -function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - this.p = parseBigInt(P,16); - this.q = parseBigInt(Q,16); - this.dmp1 = parseBigInt(DP,16); - this.dmq1 = parseBigInt(DQ,16); - this.coeff = parseBigInt(C,16); - } - else - alert("Invalid RSA private key"); -} - -// Generate a new random private key B bits long, using public expt E -function RSAGenerate(B,E) { - var rng = new SecureRandom(); - var qs = B>>1; - this.e = parseInt(E,16); - var ee = new BigInteger(E,16); - for(;;) { - for(;;) { - this.p = new BigInteger(B-qs,1,rng); - if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break; - } - for(;;) { - this.q = new BigInteger(qs,1,rng); - if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break; - } - if(this.p.compareTo(this.q) <= 0) { - var t = this.p; - this.p = this.q; - this.q = t; - } - var p1 = this.p.subtract(BigInteger.ONE); - var q1 = this.q.subtract(BigInteger.ONE); - var phi = p1.multiply(q1); - if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { - this.n = this.p.multiply(this.q); - this.d = ee.modInverse(phi); - this.dmp1 = this.d.mod(p1); - this.dmq1 = this.d.mod(q1); - this.coeff = this.q.modInverse(this.p); - break; - } - } -} - -// Perform raw private operation on "x": return x^d (mod n) -function RSADoPrivate(x) { - if(this.p == null || this.q == null) - return x.modPow(this.d, this.n); - - // TODO: re-calculate any missing CRT params - var xp = x.mod(this.p).modPow(this.dmp1, this.p); - var xq = x.mod(this.q).modPow(this.dmq1, this.q); - - while(xp.compareTo(xq) < 0) - xp = xp.add(this.p); - return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); -} - -// Return the PKCS#1 RSA decryption of "ctext". -// "ctext" is an even-length hex string and the output is a plain string. -function RSADecrypt(ctext) { - var c = parseBigInt(ctext, 16); - var m = this.doPrivate(c); - if(m == null) return null; - return pkcs1unpad2(m, (this.n.bitLength()+7)>>3); -} - -// Return the PKCS#1 RSA decryption of "ctext". -// "ctext" is a Base64-encoded string and the output is a plain string. -//function RSAB64Decrypt(ctext) { -// var h = b64tohex(ctext); -// if(h) return this.decrypt(h); else return null; -//} - -// protected -RSAKey.prototype.doPrivate = RSADoPrivate; - -// public -RSAKey.prototype.setPrivate = RSASetPrivate; -RSAKey.prototype.setPrivateEx = RSASetPrivateEx; -RSAKey.prototype.generate = RSAGenerate; -RSAKey.prototype.decrypt = RSADecrypt; -//RSAKey.prototype.b64_decrypt = RSAB64Decrypt; diff --git a/keyshare/sec.js b/keyshare/sec.js deleted file mode 100644 index 7e0814e..0000000 --- a/keyshare/sec.js +++ /dev/null @@ -1,227 +0,0 @@ -// Named EC curves - -// Requires ec.js, jsbn.js, and jsbn2.js - -// ---------------- -// X9ECParameters - -// constructor -function X9ECParameters(curve,g,n,h) { - this.curve = curve; - this.g = g; - this.n = n; - this.h = h; -} - -function x9getCurve() { - return this.curve; -} - -function x9getG() { - return this.g; -} - -function x9getN() { - return this.n; -} - -function x9getH() { - return this.h; -} - -X9ECParameters.prototype.getCurve = x9getCurve; -X9ECParameters.prototype.getG = x9getG; -X9ECParameters.prototype.getN = x9getN; -X9ECParameters.prototype.getH = x9getH; - -// ---------------- -// SECNamedCurves - -function fromHex(s) { return new BigInteger(s, 16); } - -function secp128r1() { - // p = 2^128 - 2^97 - 1 - var p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); - var a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"); - var b = fromHex("E87579C11079F43DD824993C2CEE5ED3"); - //byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679"); - var n = fromHex("FFFFFFFE0000000075A30D1B9038A115"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "161FF7528B899B2D0C28607CA52C5B86" - + "CF5AC8395BAFEB13C02DA292DDED7A83"); - return new X9ECParameters(curve, G, n, h); -} - -function secp160k1() { - // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); - var a = BigInteger.ZERO; - var b = fromHex("7"); - //byte[] S = null; - var n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" - + "938CF935318FDCED6BC28286531733C3F03C4FEE"); - return new X9ECParameters(curve, G, n, h); -} - -function secp160r1() { - // p = 2^160 - 2^31 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"); - var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"); - var b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"); - //byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345"); - var n = fromHex("0100000000000000000001F4C8F927AED3CA752257"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "4A96B5688EF573284664698968C38BB913CBFC82" - + "23A628553168947D59DCC912042351377AC5FB32"); - return new X9ECParameters(curve, G, n, h); -} - -function secp192k1() { - // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"); - var a = BigInteger.ZERO; - var b = fromHex("3"); - //byte[] S = null; - var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" - + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); - return new X9ECParameters(curve, G, n, h); -} - -function secp192r1() { - // p = 2^192 - 2^64 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); - var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"); - var b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"); - //byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); - var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" - + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); - return new X9ECParameters(curve, G, n, h); -} - -function secp224r1() { - // p = 2^224 - 2^96 + 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); - var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"); - var b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"); - //byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); - var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" - + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); - return new X9ECParameters(curve, G, n, h); -} - -function secp256r1() { - // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1 - var p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); - var a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"); - var b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); - //byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90"); - var n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" - + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); - return new X9ECParameters(curve, G, n, h); -} - - -function secp256k1() { - // 2256 - 232 - 29 - 28 - 27 - 26 - 24 - 1 - var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); - var a = fromHex("0000000000000000000000000000000000000000000000000000000000000000"); - var b = fromHex("0000000000000000000000000000000000000000000000000000000000000007"); - - var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); - var h = BigInteger.ONE; - var curve = new ECCurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" - + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); - return new X9ECParameters(curve, G, n, h); -} - - -// TODO: make this into a proper hashtable -function getSECCurveByName(name) { - if(name == "secp128r1") return secp128r1(); - if(name == "secp160k1") return secp160k1(); - if(name == "secp160r1") return secp160r1(); - if(name == "secp192k1") return secp192k1(); - if(name == "secp192r1") return secp192r1(); - if(name == "secp224r1") return secp224r1(); - if(name == "secp256r1") return secp256r1(); - if(name == "secp256k1") return secp256k1(); - return null; -} - - -/* Create the signature function -Method will be create the base root. -Then add the overlay integration - -GeneratePrivateKeyPublicKey("Name of curve" CurveName){ - Force some randomness - Randomness is Private Key - Extract Curve Parameters - Multiply Randomness into Curve Base Point - Result is the Public Key - Pack the output in some object with private key, and 2 points in public key - This should have been done -} - - -EllipticCurveSignature("Name of curve" CurveName, "Message to be signed" MessageToBeSigned, "Private Key" PrivateKey) { - From CurveName Extract Parameters find base point and n - Truncate the message till bit length of n (Message cannot be bigger than n ). Call it z - Select another Cryptographic Random k which is greater than 1 and less than n-1 - Multiply k with base point to get x1, y1 - r value = x1 mod n - If r is zero, select another random - - s = Random K mod inverse (Truncated Message + r value multiply PrivateKey ) mod n - If s = 0, select another random number - - Get help from Bitcoin Code on this - -} - -EllipticCurveSignatureVerify("Name of curve" CurveName, "Message" Message, R value, S Value, "Public Key" Public Key) { - From CurveName Extract Parameters find base point and n - Truncate the message till bit length of n (Message cannot be bigger than n ). Call it z - - Calculate w = s inverse mod n - Multiply w with Truncated Message mod n. Call this integer u1 - Muiltiply w with r value. Call this integer u2 - - Multiply the base point with u1 - Multiply the public key with u2 - - Add the above two to get another point on the curve - If the x value mod n of that point is equal to r, the signature is valid - -} - - - - -*/ \ No newline at end of file diff --git a/keyshare/sha1.js b/keyshare/sha1.js deleted file mode 100644 index eb380c9..0000000 --- a/keyshare/sha1.js +++ /dev/null @@ -1,330 +0,0 @@ -/* - * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined - * in FIPS 180-1 - * Version 2.2 Copyright Paul Johnston 2000 - 2009. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for details. - */ - -/* - * Configurable variables. You may need to tweak these to be compatible with - * the server-side, but the defaults work in most cases. - */ -var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ -var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ - -/* - * These are the functions you'll usually want to call - * They take string arguments and return either hex or base-64 encoded strings - */ -function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); } -function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); } -function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); } -function hex_hmac_sha1(k, d) - { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); } -function b64_hmac_sha1(k, d) - { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); } -function any_hmac_sha1(k, d, e) - { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); } - -/* - * Perform a simple self-test to see if the VM is working - */ -function sha1_vm_test() -{ - return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d"; -} - -/* - * Calculate the SHA1 of a raw string - */ -function rstr_sha1(s) -{ - return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8)); -} - -/* - * Calculate the HMAC-SHA1 of a key and some data (raw strings) - */ -function rstr_hmac_sha1(key, data) -{ - var bkey = rstr2binb(key); - if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8); - - var ipad = Array(16), opad = Array(16); - for(var i = 0; i < 16; i++) - { - ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5C5C5C5C; - } - - var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8); - return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160)); -} - -/* - * Convert a raw string to a hex string - */ -function rstr2hex(input) -{ - try { hexcase } catch(e) { hexcase=0; } - var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; - var output = ""; - var x; - for(var i = 0; i < input.length; i++) - { - x = input.charCodeAt(i); - output += hex_tab.charAt((x >>> 4) & 0x0F) - + hex_tab.charAt( x & 0x0F); - } - return output; -} - -/* - * Convert a raw string to a base-64 string - */ -function rstr2b64(input) -{ - try { b64pad } catch(e) { b64pad=''; } - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - var output = ""; - var len = input.length; - for(var i = 0; i < len; i += 3) - { - var triplet = (input.charCodeAt(i) << 16) - | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) - | (i + 2 < len ? input.charCodeAt(i+2) : 0); - for(var j = 0; j < 4; j++) - { - if(i * 8 + j * 6 > input.length * 8) output += b64pad; - else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); - } - } - return output; -} - -/* - * Convert a raw string to an arbitrary string encoding - */ -function rstr2any(input, encoding) -{ - var divisor = encoding.length; - var remainders = Array(); - var i, q, x, quotient; - - /* Convert to an array of 16-bit big-endian values, forming the dividend */ - var dividend = Array(Math.ceil(input.length / 2)); - for(i = 0; i < dividend.length; i++) - { - dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); - } - - /* - * Repeatedly perform a long division. The binary array forms the dividend, - * the length of the encoding is the divisor. Once computed, the quotient - * forms the dividend for the next step. We stop when the dividend is zero. - * All remainders are stored for later use. - */ - while(dividend.length > 0) - { - quotient = Array(); - x = 0; - for(i = 0; i < dividend.length; i++) - { - x = (x << 16) + dividend[i]; - q = Math.floor(x / divisor); - x -= q * divisor; - if(quotient.length > 0 || q > 0) - quotient[quotient.length] = q; - } - remainders[remainders.length] = x; - dividend = quotient; - } - - /* Convert the remainders to the output string */ - var output = ""; - for(i = remainders.length - 1; i >= 0; i--) - output += encoding.charAt(remainders[i]); - - /* Append leading zero equivalents */ - var full_length = Math.ceil(input.length * 8 / - (Math.log(encoding.length) / Math.log(2))) - for(i = output.length; i < full_length; i++) - output = encoding[0] + output; - - return output; -} - -/* - * Encode a string as utf-8. - * For efficiency, this assumes the input is valid utf-16. - */ -function str2rstr_utf8(input) -{ - var output = ""; - var i = -1; - var x, y; - - while(++i < input.length) - { - /* Decode utf-16 surrogate pairs */ - x = input.charCodeAt(i); - y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; - if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) - { - x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); - i++; - } - - /* Encode output as utf-8 */ - if(x <= 0x7F) - output += String.fromCharCode(x); - else if(x <= 0x7FF) - output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), - 0x80 | ( x & 0x3F)); - else if(x <= 0xFFFF) - output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), - 0x80 | ((x >>> 6 ) & 0x3F), - 0x80 | ( x & 0x3F)); - else if(x <= 0x1FFFFF) - output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), - 0x80 | ((x >>> 12) & 0x3F), - 0x80 | ((x >>> 6 ) & 0x3F), - 0x80 | ( x & 0x3F)); - } - return output; -} - -/* - * Encode a string as utf-16 - */ -function str2rstr_utf16le(input) -{ - var output = ""; - for(var i = 0; i < input.length; i++) - output += String.fromCharCode( input.charCodeAt(i) & 0xFF, - (input.charCodeAt(i) >>> 8) & 0xFF); - return output; -} - -function str2rstr_utf16be(input) -{ - var output = ""; - for(var i = 0; i < input.length; i++) - output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, - input.charCodeAt(i) & 0xFF); - return output; -} - -/* - * Convert a raw string to an array of big-endian words - * Characters >255 have their high-byte silently ignored. - */ -function rstr2binb(input) -{ - var output = Array(input.length >> 2); - for(var i = 0; i < output.length; i++) - output[i] = 0; - for(var i = 0; i < input.length * 8; i += 8) - output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); - return output; -} - -/* - * Convert an array of big-endian words to a string - */ -function binb2rstr(input) -{ - var output = ""; - for(var i = 0; i < input.length * 32; i += 8) - output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF); - return output; -} - -/* - * Calculate the SHA-1 of an array of big-endian words, and a bit length - */ -function binb_sha1(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << (24 - len % 32); - x[((len + 64 >> 9) << 4) + 15] = len; - - var w = Array(80); - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - var e = -1009589776; - - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - var olde = e; - - for(var j = 0; j < 80; j++) - { - if(j < 16) w[j] = x[i + j]; - else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); - var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), - safe_add(safe_add(e, w[j]), sha1_kt(j))); - e = d; - d = c; - c = bit_rol(b, 30); - b = a; - a = t; - } - - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - e = safe_add(e, olde); - } - return Array(a, b, c, d, e); - -} - -/* - * Perform the appropriate triplet combination function for the current - * iteration - */ -function sha1_ft(t, b, c, d) -{ - if(t < 20) return (b & c) | ((~b) & d); - if(t < 40) return b ^ c ^ d; - if(t < 60) return (b & c) | (b & d) | (c & d); - return b ^ c ^ d; -} - -/* - * Determine the appropriate additive constant for the current iteration - */ -function sha1_kt(t) -{ - return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : - (t < 60) ? -1894007588 : -899497514; -} - -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); -} - -/* - * Bitwise rotate a 32-bit number to the left. - */ -function bit_rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} diff --git a/pybtc b/pybtc deleted file mode 160000 index 90542e1..0000000 --- a/pybtc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 90542e111d8be652082e8e998975920289e12978 diff --git a/pybtc/__init__.py b/pybtc/__init__.py new file mode 100644 index 0000000..a8e288c --- /dev/null +++ b/pybtc/__init__.py @@ -0,0 +1,10 @@ +from pybtc.constants import * +from pybtc.opcodes import * +from pybtc.consensus import * +from pybtc.functions import * + + +from .transaction import * +from .block import * +from .address import * +from .wallet import * diff --git a/pybtc/__pycache__/__init__.cpython-310.pyc b/pybtc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..e577748 Binary files /dev/null and b/pybtc/__pycache__/__init__.cpython-310.pyc differ diff --git a/pybtc/__pycache__/__init__.cpython-36.pyc b/pybtc/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..02ca500 Binary files /dev/null and b/pybtc/__pycache__/__init__.cpython-36.pyc differ diff --git a/pybtc/__pycache__/__init__.cpython-38.pyc b/pybtc/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..c17a9aa Binary files /dev/null and b/pybtc/__pycache__/__init__.cpython-38.pyc differ diff --git a/pybtc/__pycache__/address.cpython-36.pyc b/pybtc/__pycache__/address.cpython-36.pyc new file mode 100644 index 0000000..bfdd591 Binary files /dev/null and b/pybtc/__pycache__/address.cpython-36.pyc differ diff --git a/pybtc/__pycache__/address.cpython-38.pyc b/pybtc/__pycache__/address.cpython-38.pyc new file mode 100644 index 0000000..c6c1c4c Binary files /dev/null and b/pybtc/__pycache__/address.cpython-38.pyc differ diff --git a/pybtc/__pycache__/block.cpython-36.pyc b/pybtc/__pycache__/block.cpython-36.pyc new file mode 100644 index 0000000..6d41026 Binary files /dev/null and b/pybtc/__pycache__/block.cpython-36.pyc differ diff --git a/pybtc/__pycache__/block.cpython-38.pyc b/pybtc/__pycache__/block.cpython-38.pyc new file mode 100644 index 0000000..eb45dc0 Binary files /dev/null and b/pybtc/__pycache__/block.cpython-38.pyc differ diff --git a/pybtc/__pycache__/consensus.cpython-36.pyc b/pybtc/__pycache__/consensus.cpython-36.pyc new file mode 100644 index 0000000..118ee80 Binary files /dev/null and b/pybtc/__pycache__/consensus.cpython-36.pyc differ diff --git a/pybtc/__pycache__/consensus.cpython-38.pyc b/pybtc/__pycache__/consensus.cpython-38.pyc new file mode 100644 index 0000000..9714d06 Binary files /dev/null and b/pybtc/__pycache__/consensus.cpython-38.pyc differ diff --git a/pybtc/__pycache__/constants.cpython-310.pyc b/pybtc/__pycache__/constants.cpython-310.pyc new file mode 100644 index 0000000..1feef21 Binary files /dev/null and b/pybtc/__pycache__/constants.cpython-310.pyc differ diff --git a/pybtc/__pycache__/constants.cpython-36.pyc b/pybtc/__pycache__/constants.cpython-36.pyc new file mode 100644 index 0000000..c25b82e Binary files /dev/null and b/pybtc/__pycache__/constants.cpython-36.pyc differ diff --git a/pybtc/__pycache__/constants.cpython-38.pyc b/pybtc/__pycache__/constants.cpython-38.pyc new file mode 100644 index 0000000..cfad311 Binary files /dev/null and b/pybtc/__pycache__/constants.cpython-38.pyc differ diff --git a/pybtc/__pycache__/opcodes.cpython-36.pyc b/pybtc/__pycache__/opcodes.cpython-36.pyc new file mode 100644 index 0000000..ee34c64 Binary files /dev/null and b/pybtc/__pycache__/opcodes.cpython-36.pyc differ diff --git a/pybtc/__pycache__/opcodes.cpython-38.pyc b/pybtc/__pycache__/opcodes.cpython-38.pyc new file mode 100644 index 0000000..23b2900 Binary files /dev/null and b/pybtc/__pycache__/opcodes.cpython-38.pyc differ diff --git a/pybtc/__pycache__/transaction.cpython-36.pyc b/pybtc/__pycache__/transaction.cpython-36.pyc new file mode 100644 index 0000000..8b007a5 Binary files /dev/null and b/pybtc/__pycache__/transaction.cpython-36.pyc differ diff --git a/pybtc/__pycache__/transaction.cpython-38.pyc b/pybtc/__pycache__/transaction.cpython-38.pyc new file mode 100644 index 0000000..9cef2c2 Binary files /dev/null and b/pybtc/__pycache__/transaction.cpython-38.pyc differ diff --git a/pybtc/__pycache__/wallet.cpython-36.pyc b/pybtc/__pycache__/wallet.cpython-36.pyc new file mode 100644 index 0000000..9808341 Binary files /dev/null and b/pybtc/__pycache__/wallet.cpython-36.pyc differ diff --git a/pybtc/__pycache__/wallet.cpython-38.pyc b/pybtc/__pycache__/wallet.cpython-38.pyc new file mode 100644 index 0000000..82e13ff Binary files /dev/null and b/pybtc/__pycache__/wallet.cpython-38.pyc differ diff --git a/pybtc/__to_remove_blockchain__.py b/pybtc/__to_remove_blockchain__.py new file mode 100644 index 0000000..fb7f8ed --- /dev/null +++ b/pybtc/__to_remove_blockchain__.py @@ -0,0 +1,685 @@ +""" +Old code will be removed +""" + + +import io +import json +import math +from .opcodes import * +from .tools import * +from .consensus import * +from binascii import hexlify, unhexlify + +k = 0 + + + + + +class OLDTransaction(): + def __init__(self, version = 1, tx_in = [], tx_out = [] , lock_time = 0, + hash=None, size = 0, timestamp = None, + marker = None, flag = None, witness = [], + whash = None, vsize = None): + self.hash = hash + self.whash = whash + self.vsize = vsize + self.witness = witness + self.marker = marker + self.flag = flag + self.valid = True + self.lock = False + self.in_sum = None + self.tx_fee = None + self.version = version + self.tx_in_count = len(tx_in) + self.tx_in = list(tx_in) + self.tx_out_count = len(tx_out) + self.tx_out = list(tx_out) + self.lock_time = lock_time + if self.tx_in: + self.coinbase = self.tx_in[0].coinbase + else: + self.coinbase = None + if self.coinbase: + self.whash = b"\x00" * 32 + self.double_spend = 0 + self.data = None + self.ip = None + self.size = size + if timestamp is not None : self.timestamp = timestamp + else: self.timestamp = int(time.time()) + self.op_sig_count = 0 + self.sum_value_age = 0 + self.total_outs_value = 0 + for i in self.tx_out: + self.op_sig_count += i.pk_script.op_sig_count + if i.pk_script.type=="NULL_DATA": + self.data = i.pk_script.data + for out in self.tx_out: + self.total_outs_value += out.value + if not self.tx_in: + self.witness = list() + if witness is None: + self.witness = (Witness.deserialize(b"\x00") for i in range(len(tx_in))) + if hash is None : + self.recalculate_txid() + + def recalculate_txid(self): + self.tx_in_count = len(self.tx_in) + self.tx_out_count = len(self.tx_out) + t = self.serialize(segwit=False) + t2 = self.serialize(segwit=True) + self.hash = double_sha256(t) + if self.coinbase: + self.whash = b"\x00" * 32 + else: + self.whash = double_sha256(t2) + self.size = len(t) + self.vsize = math.ceil((self.size * 3 + self.size) / 4) + + def txid(self): + return rh2s(self.hash) + + def add_input(self, tx_hash, output_number, + sequence = 0xffffffff, + sig_script = b"", + amount = None, + private_key = None): + self.tx_in.append(Input((tx_hash, output_number), sig_script, sequence, amount, private_key)) + self.witness.append(Witness.deserialize(b"\x00")) + self.tx_in_count += 1 + self.recalculate_txid() + + def add_output_script(self, amount, script): + if type(script)==str: + script = unhexlify(script) + self.tx_out.append(Output(amount,script)) + self.tx_out_count += 1 + self.recalculate_txid() + + def add_output_address(self, amount, address, testnet = False): + assert is_address_valid(address, testnet) + output_type = address_type(address, True) + if output_type == 0: + self.add_P2PKH_output(amount, address) + elif output_type == 1: + self.add_P2SH_output(amount, address) + elif output_type == 5: + self.add_P2WPKH_output(amount, address) + elif output_type == 6: + self.add_P2WSH_output(amount, address) + + + def add_output_hash(self, amount, output_hash, output_type, witness_version = 0): + if type(output_type)==str: + output_type = SCRIPT_TYPES[output_type] + if output_hash == str: + output_hash = unhexlify(output_hash) + assert output_type in (0, 1, 5, 6) + if output_type == 0: + self.add_P2PKH_output(amount, output_hash) + elif output_type == 1: + self.add_P2SH_output(amount, output_hash) + elif output_type == 5: + self.add_P2WPKH_output(amount, output_hash, witness_version) + elif output_type == 6: + self.add_P2WSH_output(amount, output_hash, witness_version) + + + def add_P2WPKH_output(self, amount, p2wpkh_address, witness_version = 0): + if type(p2wpkh_address)==str: + assert address_type(p2wpkh_address) == 'P2WPKH' + witness_version = get_witness_version(p2wpkh_address) + p2wpkh_address = address_to_hash(p2wpkh_address) + assert len(p2wpkh_address) == 20 + self.tx_out.append(Output(amount, + bytes([witness_version]) + b'\x14' + p2wpkh_address)) + self.tx_out_count += 1 + self.recalculate_txid() + + def add_P2WSH_output(self, amount, p2wsh_address, witness_version = 0): + if type(p2wsh_address)==str: + assert address_type(p2wsh_address) == 'P2WSH' + witness_version = get_witness_version(p2wsh_address) + p2wsh_address = address_to_hash(p2wsh_address) + assert len(p2wsh_address) == 32 + self.tx_out.append(Output(amount, + bytes([witness_version]) + b'\x20' + p2wsh_address)) + self.tx_out_count += 1 + self.recalculate_txid() + + def add_P2SH_output(self, amount, p2sh_address): + if type(p2sh_address)==str: + assert address_type(p2sh_address) == 'P2SH' + p2sh_address = decode_base58(p2sh_address)[1:-4] + if len(p2sh_address) != 20: + raise Exception("Invalid output hash160") + self.tx_out.append(Output(amount, + OPCODE["OP_HASH160"] + b'\x14' + p2sh_address + OPCODE["OP_EQUAL"])) + self.tx_out_count += 1 + self.recalculate_txid() + + + def add_P2PKH_output(self, amount, p2pkh_address): + if type(p2pkh_address)==str: + assert address_type(p2pkh_address) == 'P2PKH' + p2pkh_address = decode_base58(p2pkh_address)[1:-4] + if len(p2pkh_address) != 20: + raise p2pkh_address("Invalid output hash160") + self.tx_out.append(Output(amount, + OPCODE["OP_DUP"] + OPCODE["OP_HASH160"] + b'\x14' + \ + p2pkh_address + OPCODE["OP_EQUALVERIFY"] + OPCODE["OP_CHECKSIG"])) + self.tx_out_count += 1 + self.recalculate_txid() + + + + + def __str__(self): + return 'Transaction object [%s] [%s]'% (hexlify(self.hash[::-1]),id(self)) + + + def serialize(self, segwit = True, hex = False): + version = self.version.to_bytes(4,'little') + ninputs = int_to_var_int(self.tx_in_count) + inputs = [i.serialize() for i in self.tx_in] + nouts = int_to_var_int(len(self.tx_out)) + outputs = [o.serialize() for o in self.tx_out] + marke_flag = b"\x00\x01" if segwit else b"" + witness = b"" + if segwit: + for w in self.witness: + witness += w.serialize() + result = version + marke_flag + ninputs + b''.join(inputs) +\ + nouts + b''.join(outputs) + witness + self.lock_time.to_bytes(4,'little') + if hex: + return hexlify(result).decode() + else: + return result + + def sign_P2SHP2WPKH_input(self, sighash_type, input_index, private_key = None, amount = None): + if type(private_key) == str: + private_key = wif_to_private_key(private_key) + if amount is not None: + self.tx_in[input_index].amount = amount + else: + amount = self.tx_in[input_index].amount + if private_key is not None: + self.tx_in[input_index].private_key = private_key + else: + private_key = self.tx_in[input_index].private_key + pubkey = private_to_public_key(private_key, True) + pubkey_hash160 = hash160(pubkey) + scriptCode = b"\x19" + OPCODE["OP_DUP"] + OPCODE["OP_HASH160"] + scriptCode += b'\x14' + pubkey_hash160 + OPCODE["OP_EQUALVERIFY"] + OPCODE["OP_CHECKSIG"] + self.tx_in[input_index].sig_script = Script(b'\x16\x00\x14' + pubkey_hash160) # P2WPKHredeemScript + sighash = self.sighash_segwit(sighash_type, input_index, scriptCode, amount) + signature = sign_message(sighash, private_key) + sighash_type.to_bytes(1,'little') + self.witness[input_index] = Witness([signature, pubkey]) + self.recalculate_txid() + + def sign_P2PKH_input(self, sighash_type, input_index, compressed = True, private_key = None): + if private_key is not None: + self.tx_in[input_index].private_key = private_key + else: + private_key = self.tx_in[input_index].private_key + pubkey = private_to_public_key(private_key, compressed) + pubkey_hash160 = hash160(pubkey) + scriptCode = OPCODE["OP_DUP"] + OPCODE["OP_HASH160"] + b'\x14' + \ + pubkey_hash160 + OPCODE["OP_EQUALVERIFY"] + OPCODE["OP_CHECKSIG"] + sighash = self.sighash(sighash_type, input_index, scriptCode) + signature = sign_message(sighash, private_key) + sighash_type.to_bytes(1, 'little') + sig_script = len(signature).to_bytes(1, 'little') + signature + \ + len(pubkey).to_bytes(1, 'little') + pubkey + self.tx_in[input_index].sig_script = Script(sig_script) + self.recalculate_txid() + + def sighash(self, sighash_type, input_index, scriptCode, hex = False): + if type(scriptCode) == str: + scriptCode = unhexlify(scriptCode) + if len(self.tx_in) - 1 < input_index: + raise Exception('Input not exist') + preimage = bytearray() + if ((sighash_type&31) == SIGHASH_SINGLE) and (input_index>(len(self.tx_out)-1)): + return double_sha256(b'\x01'+b'\x00'*31 + sighash_type.to_bytes(4, 'little')) + preimage += self.version.to_bytes(4,'little') + preimage += b'\x01' if sighash_type & SIGHASH_ANYONECANPAY else int_to_var_int(self.tx_in_count) + for number, i in enumerate(self.tx_in): + if (sighash_type & SIGHASH_ANYONECANPAY) and (input_index != number): continue + input = i.outpoint[0]+i.outpoint[1].to_bytes(4,'little') + if sighash_type == 0 or input_index == number: + input += ((int_to_var_int(len(scriptCode)) + scriptCode) if sighash_type else \ + (int_to_var_int(len(i.sig_script.raw)) + i.sig_script.raw)) + i.sequence.to_bytes(4, 'little') + else: + input += b'\x00' + (i.sequence.to_bytes(4,'little') if \ + ((sighash_type&31) == SIGHASH_ALL) else b'\x00\x00\x00\x00') + preimage += input + preimage += b'\x00' if (sighash_type&31) == SIGHASH_NONE else (int_to_var_int(input_index + 1) if \ + (sighash_type&31) == SIGHASH_SINGLE else int_to_var_int(self.tx_out_count)) + if (sighash_type&31) != SIGHASH_NONE: + for number, i in enumerate(self.tx_out): + if number > input_index and (sighash_type&31) == SIGHASH_SINGLE: continue + preimage +=(b'\xff'*8+b'\x00' if (sighash_type&31) == SIGHASH_SINGLE and (input_index != number)\ + else i.value.to_bytes(8,'little') + int_to_var_int(len(i.pk_script.raw)) + i.pk_script.raw) + preimage += self.lock_time.to_bytes(4,'little') + preimage += sighash_type.to_bytes(4, 'little') + return double_sha256(preimage) if not hex else hexlify(double_sha256(preimage)).decode() + + + def sighash_segwit(self, sighash_type, input_index, scriptCode, amount, hex = False): + if type(scriptCode) == str: + scriptCode = unhexlify(scriptCode) + if len(self.tx_in)-1 < input_index: + raise Exception('Input not exist') + preimage = bytearray() + # 1. nVersion of the transaction (4-byte little endian) + preimage += self.version.to_bytes(4,'little') + # 2. hashPrevouts (32-byte hash) + # 3. hashSequence (32-byte hash) + # 4. outpoint (32-byte hash + 4-byte little endian) + # 5. scriptCode of the input (serialized as scripts inside CTxOuts) + # 6. value of the output spent by this input (8-byte little endian) + # 7. nSequence of the input (4-byte little endian) + hp = bytearray() + hs = bytearray() + for n, i in enumerate(self.tx_in): + if not (sighash_type & SIGHASH_ANYONECANPAY): + hp += i.outpoint[0] + i.outpoint[1].to_bytes(4,'little') + if (sighash_type&31) != SIGHASH_SINGLE and (sighash_type&31) != SIGHASH_NONE: + hs += i.sequence.to_bytes(4,'little') + if n == input_index: + outpoint = i.outpoint[0]+i.outpoint[1].to_bytes(4,'little') + nSequence = i.sequence.to_bytes(4,'little') + hashPrevouts = double_sha256(hp) if hp else b'\x00'*32 + hashSequence = double_sha256(hs) if hs else b'\x00'*32 + value = amount.to_bytes(8,'little') + # 8. hashOutputs (32-byte hash) + ho = bytearray() + for n, o in enumerate(self.tx_out): + if (sighash_type&31) != SIGHASH_SINGLE and (sighash_type&31) != SIGHASH_NONE: + ho += o.value.to_bytes(8,'little') + int_to_var_int(len(o.pk_script.raw)) + o.pk_script.raw + elif (sighash_type&31) == SIGHASH_SINGLE and input_index < len(self.tx_out): + if input_index == n: + ho += o.value.to_bytes(8, 'little') + int_to_var_int(len(o.pk_script.raw)) + o.pk_script.raw + hashOutputs = double_sha256(ho) if ho else b'\x00'*32 + preimage += hashPrevouts + hashSequence + outpoint + scriptCode + value + nSequence + hashOutputs + preimage += self.lock_time.to_bytes(4, 'little') + preimage += sighash_type.to_bytes(4, 'little') + return double_sha256(preimage) if not hex else hexlify(double_sha256(preimage)).decode() + + + def json(self, testnet = False): + r = dict() + r["txid"] = rh2s(self.hash) + r["wtxid"] = r["txid"] if self.whash is None else rh2s(self.whash) + r["size"] = self.size + r["vsize"] = self.vsize + r["version"] = self.version + r["locktime"] = self.lock_time + r["vin"] = list() + r["vout"] = list() + for i in self.tx_in: + input = {"txid": rh2s(i.outpoint[0]), + "vout": i.outpoint[1], + "scriptSig": {"hex": hexlify(i.sig_script.raw).decode(), + "asm": i.sig_script.asm}, + "sequence": i.sequence} + if i.coinbase: + input["coinbase"] = hexlify(i.sig_script.raw).decode() + r["vin"].append(input) + if self.witness is not None: + for index, w in enumerate(self.witness): + r["vin"][index]["witness"] = w.hex() + for index, o in enumerate(self.tx_out): + out = {"value": o.value, + "n": index, + "scriptPubKey": {"hex": hexlify(o.pk_script.raw).decode()}, + "asm": o.pk_script.asm, + "type": o.pk_script.type} + if self.witness is not None: + out["witnessVersion"] = o.pk_script.witness_version + out["address"] = [] + sh = False + if o.pk_script.ntype in (1,6): + sh =True + for a in o.pk_script.address: + out["address"].append(hash_to_address(a, + testnet=testnet, + script_hash= sh, + witness_version=o.pk_script.witness_version)) + + r["vout"].append(out) + + return json.dumps(r) + + + @classmethod + def deserialize(cls, stream): + stream = get_stream(stream) + raw_tx = bytearray() + raw_wtx = bytearray() + start = stream.tell() + version = int.from_bytes(stream.read(4), 'little') + marker = stream.read(1) + flag = stream.read(1) + if marker == b"\x00" and flag == b"\x01": + # segwit format + point1 = stream.tell() + tx_in = read_var_list(stream, Input) + tx_out = read_var_list(stream, Output) + point2 = stream.tell() + inputs_count = len(tx_in) + witness = [Witness.deserialize(stream) for i in range(inputs_count)] + point3 = stream.tell() + lock_time = int.from_bytes(stream.read(4), 'little') + # calculate tx_id hash + size = stream.tell() - start + stream.seek(start) + raw_tx += stream.read(4) + stream.seek(2,1) + raw_tx += stream.read(point2 - point1) + stream.seek(point3-point2, 1) + raw_tx += stream.read(4) + tx_id = double_sha256(raw_tx) + for w in witness: + if not w.empty: + # caluculate wtx_id + stream.seek(start) + data = stream.read(size) + wtx_id = double_sha256(data) + break + else: + wtx_id = tx_id + vsize = math.ceil((size * 3 + size) / 4) + else: + stream.seek(start) + marker = b"\x00" + flag = b"\x01" + version = int.from_bytes(stream.read(4), 'little') + tx_in = read_var_list(stream, Input) + tx_out = read_var_list(stream, Output) + witness = [Witness.deserialize(b"\x00") for i in range(len(tx_in))] + lock_time = int.from_bytes(stream.read(4), 'little') + size = stream.tell() - start + stream.seek(start) + data = stream.read(size) + tx_id = double_sha256(data) + wtx_id = tx_id + vsize = size + + return cls(version, tx_in, tx_out, lock_time, + hash = tx_id, size = size, + marker = marker, flag = flag, + witness = witness, whash = wtx_id, vsize = vsize) + + +class OLDBlock(): + def __init__(self, version, prev_block, merkle_root, + timestamp, bits, nonce, txs, block_size, hash = None, header = None): + qt = time.time() + self.hash = hash + self.header = header + self.version = version + self.nversion = int.from_bytes(version,'little') + self.prev_block = prev_block + self.merkle_root = merkle_root + self.timestamp = timestamp + self.bits = bits + self.nonce = nonce + + self.transactions = txs + self.tx_hash_list = list() + self.size = block_size + self.weight = block_size + self.height = None + self.amount = 0 + self.fee = 0 + self.sigop = 0 + + + self.target = None + self.fee = 0 + self.witness_root_hash = None + + if txs: + if txs[0].coinbase: + if self.nversion > 1: + self.height = int.from_bytes(txs[0].tx_in[0].sig_script.raw[1:5], "little") + self.coinbase = txs[0].tx_in[0].sig_script.raw[5:] + else: + self.coinbase = txs[0].tx_in[0].sig_script.raw + try: + for out in txs[0].tx_out: + if out.pk_script.ntype == 3: + if b'\xaa!\xa9\xed' == out.pk_script.data[:4]: + self.witness_root_hash = out.pk_script.data[4:36] + except: + pass + print("t ", time.time() - qt) + + def calculate_commitment(self, witness = None): + wtxid_list = [b"\x00" * 32,] + print(len(self.transactions)) + if self.transactions and not (len(self.transactions) == 1 and self.transactions[0].coinbase): + for tx in self.transactions[0 if not self.transactions[0].coinbase else 1:]: + wtxid_list.append(tx.whash) + if witness is None: + return double_sha256(merkleroot(wtxid_list) + self.transactions[0].witness[0].witness[0]) + else: + return double_sha256(merkleroot(wtxid_list) + witness) + + def create_coinbase_transaction(self, block_height, outputs, coinbase_message = b"", insert = True): + tx = Transaction(version = 1,tx_in = [], tx_out = [], witness= [] ) + coinbase = b'\x03' + block_height.to_bytes(4,'little') + coinbase_message + if len(coinbase) > 100: + raise Exception("coinbase is to long") + coinbase_input = Input((b'\x00'*32 ,0xffffffff), coinbase, 0xffffffff) + tx.tx_in = [coinbase_input] + tx.witness = [Witness([b'\x00'*32])] + commitment = self.calculate_commitment(tx.witness[0].witness[0]) + for o in outputs: + if type(o[1]) == str: + tx.tx_out.append(Output(o[0], address_to_script(o[1]))) + else: + tx.tx_out.append(Output(o[0], o[1])) + tx.tx_out.append(Output(0, b'j$\xaa!\xa9\xed' + commitment)) + tx.coinbase = True + tx.recalculate_txid() + if insert: + if self.transactions: + if self.transactions[0].coinbase: + self.transactions[0] = tx + self.tx_hash_list[0] = tx.hash + else: + self.transactions.insert(0,tx) + self.tx_hash_list.insert(0, tx.hash) + else: + self.transactions.insert(0, tx) + self.tx_hash_list.insert(0, tx.hash) + return tx + + def split_coinbase(self, extranonce_size = 8, extranonce_start = -8): + tx = self.transactions[0].serialize() + len_coinbase = len(self.transactions[0].tx_in[0].sig_script.raw) + if extranonce_start < 0: + extranonce_start = len_coinbase + extranonce_start + return tx[:44 + extranonce_start], tx[44 + extranonce_start + extranonce_size:] + + @classmethod + def deserialize(cls, stream): + stream = get_stream(stream) + header = stream.read(80) + stream.seek(-80, 1) + kwargs = { + 'hash': double_sha256(header), + 'version': stream.read(4), + 'prev_block': stream.read(32), + 'merkle_root': stream.read(32), + 'timestamp': int.from_bytes(stream.read(4), 'little'), + 'bits': stream.read(4), + 'nonce': stream.read(4)} + t = time.time() + kwargs['txs'] = read_var_list(stream, Transaction) + print("tx ",time.time() - t) + kwargs['block_size'] = stream.tell() + kwargs['header'] = header + global k + print(">.>.>.",k) + return cls(**kwargs) + + def serialize(self, hex = False): + block = self.version + \ + self.prev_block + \ + self.merkle_root + \ + self.timestamp.to_bytes(4,'little') + \ + self.bits + \ + self.nonce + \ + int_to_var_int(len (self.transactions)) + for t in self.transactions: + if t.hash == t.whash: + block += t.serialize(segwit = 0) + else: + block += t.serialize(segwit = 1) + if hex: + return hexlify(block).decode() + else: + return block + + +class BlockTemplate(): + def __init__(self, data, coinbase_output_address, testnet = False, coinbase_message = "", + extranonce1 = "00000000", + extranonce1_size = 4, + extranonce2_size = 4): + self.testnet = testnet + self.version = hexlify(data["version"].to_bytes(4, "big")).decode() + self.previous_block_hash = hexlify(reverse_hash(s2rh(data["previousblockhash"]))).decode() + self.time = hexlify(data["curtime"].to_bytes(4, "big")).decode() + self.bits = data["bits"] + self.height = data["height"] + self.block_reward = 50 * 100000000 >> data["height"] // 210000 + self.coinbasevalue = self.block_reward + self.extranonce1 = extranonce1 + self.extranonce1_size = extranonce1_size + self.extranonce2 = "00000000" + self.extranonce2_size = extranonce2_size + self.coinbase_output_address = coinbase_output_address + self.sigoplimit = data["sigoplimit"] + self.weightlimit = data["weightlimit"] + self.sigop= 0 + self.weight = 0 + if type(coinbase_message) == bytes: + coinbase_message = hexlify(coinbase_message).decode() + self.coinbase_message = coinbase_message + + self.transactions = list(data["transactions"]) + self.txid_list = list() + self.scan_tx_list() + self.coinbase_tx = self.create_coinbase_transaction() + self.coinb1, self.coinb2 = self.split_coinbase() + self.target = bits_to_target(self.bits) + self.difficulty = target_to_difficulty(self.target) + self.merkle_branches = [hexlify(i).decode() for i in merkle_branches([self.coinbase_tx.hash,] + self.txid_list)] + + + def scan_tx_list(self): + self.coinbasevalue = self.block_reward + self.sigop = 0 + self.weight = 0 + self.txid_list = list() + for tx in self.transactions: + txid = s2rh(tx["txid"]) + self.coinbasevalue += tx["fee"] + self.weight += tx["weight"] + self.sigop += tx["sigops"] + self.txid_list.append(txid) + + def calculate_commitment(self, witness): + wtxid_list = [b"\x00" * 32,] + if self.transactions: + for tx in self.transactions: + wtxid_list.append(s2rh(tx["hash"])) + return double_sha256(merkleroot(wtxid_list) + witness) + + def split_coinbase(self): + tx = self.coinbase_tx.serialize(segwit=0) + len_coinbase = len(self.coinbase_tx.tx_in[0].sig_script.raw) + extranonce_len = self.extranonce1_size + self.extranonce2_size + return hexlify(tx[:42 + len_coinbase - extranonce_len]).decode(),\ + hexlify(tx[42 + len_coinbase:]).decode() + + + def create_coinbase_transaction(self): + tx = Transaction(version = 1,tx_in = [], tx_out = [], witness= []) + coinbase = b'\x03' + self.height.to_bytes(4,'little') + unhexlify(self.coinbase_message) + coinbase += b"\x00" * (self.extranonce1_size + self.extranonce2_size) + assert len(coinbase) <= 100 + tx.tx_in = [Input((b'\x00'*32 ,0xffffffff), coinbase, 0xffffffff)] + tx.witness = [Witness([b'\x00'*32])] + commitment = self.calculate_commitment(tx.witness[0].witness[0]) + tx.add_output_address(self.coinbasevalue, self.coinbase_output_address, self.testnet) + tx.add_output_script(0, b'j$\xaa!\xa9\xed' + commitment) + tx.coinbase = True + tx.recalculate_txid() + return tx + + def get_job(self, job_id, clean_jobs = True): + """ + job_id - ID of the job. Use this ID while submitting share generated from this job. + prevhash - Hash of previous block. + coinb1 - Initial part of coinbase transaction. + coinb2 - Final part of coinbase transaction. + merkle_branch - List of hashes, will be used for calculation of merkle root. This is not a list of all + transactions, it only contains prepared hashes of steps of merkle tree algorithm. Please read some + materials for understanding how merkle trees calculation works. + version - Bitcoin block version. + nbits - Encoded current network difficulty + ntime - Current ntime/ + clean_jobs - When true, server indicates that submitting shares from previous jobs don't have a + sense and such shares will be rejected. When this flag is set, miner should also drop all previous + jobs, so job_ids can be eventually rotated. + + """ + return [job_id, + self.previous_block_hash, + self.coinb1, + self.coinb2, + self.merkle_branches, + self.version, + self.bits, + self.time, + clean_jobs] + + def submit_job(self, extra_nonce_1, extra_nonce_2, nonce, time): + version = s2rh(self.version) + prev_hash = s2rh_step4(self.previous_block_hash) + cb = self.coinb1 + extra_nonce_1 + extra_nonce_2 + self.coinb2 + time = s2rh(time) + bits = s2rh(self.bits) + nonce = s2rh(nonce) + cbh = double_sha256(unhexlify(cb)) + merkle_root = merkleroot_from_branches(self.merkle_branches, cbh) + print("merkle_root ", hexlify(merkle_root)) + print("branches ", self.merkle_branches) + header = version + prev_hash + merkle_root + time + bits + nonce + block = hexlify(header).decode() + block += hexlify(int_to_var_int(len (self.transactions) + 1)).decode() + block += cb + for t in self.transactions: + block += t["data"] + return double_sha256(header,1), block + + def build_orphan(self, hash, ntime): + self.previous_block_hash = hexlify(reverse_hash(s2rh(hash))).decode() + self.time = hexlify(ntime.to_bytes(4, "big")).decode() + self.height += 1 + self.transactions = list() + self.txid_list = list() + self.scan_tx_list() + self.coinbase_tx = self.create_coinbase_transaction() + self.coinb1, self.coinb2 = self.split_coinbase() + self.target = bits2target(self.bits) + self.difficulty = target2difficulty(self.target) + self.merkle_branches = [hexlify(i).decode() for i in merkle_branches([self.coinbase_tx.hash, ] + self.txid_list)] \ No newline at end of file diff --git a/pybtc/address.py b/pybtc/address.py new file mode 100644 index 0000000..3267e81 --- /dev/null +++ b/pybtc/address.py @@ -0,0 +1,281 @@ +from pybtc.constants import * +from pybtc.opcodes import * +from pybtc.functions.tools import bytes_from_hex, int_to_var_int +from pybtc.functions.script import op_push_data, decode_script +from pybtc.functions.hash import hash160, sha256 +from pybtc.functions.address import hash_to_address, public_key_to_p2sh_p2wpkh_script +from pybtc.functions.key import (create_private_key, + private_key_to_wif, + is_wif_valid, + wif_to_private_key, + is_public_key_valid, + private_to_public_key) + +class PrivateKey(): + """ + The class for creating private key object. + + :param key: (optional) private key in HEX, bytes string or WIF format. In case no key specified + new random private key will be created. + :param compressed: (optional) if set to True private key corresponding compressed public key, + by default set to True. Recommended use only compressed public key. + :param testnet: (optional) if set to True mean that this private key for testnet Bitcoin network. + + """ + def __init__(self, key=None, compressed=True, testnet=False): + + if key is None: + + #: flag for compressed type of corresponding public key (boolean) + self.compressed = compressed + #: flag for testnet network private key (boolean) + self.testnet = testnet + + #: private key in bytes (bytes) + self.key = create_private_key(wif=False) + #: private key in HEX (string) + self.hex = self.key.hex() + #: private key in WIF format (string) + self.wif = private_key_to_wif(self.key, compressed, testnet) + + else: + if isinstance(key, str): + try: + key = bytes_from_hex(key) + except: + pass + if isinstance(key, bytes): + if len(key) != 32: + raise TypeError("private key invalid length") + self.key = key + self.compressed = compressed + self.testnet = testnet + self.hex = self.key.hex() + self.wif = private_key_to_wif(self.key, compressed, testnet) + return + if not isinstance(key, str) or not is_wif_valid(key): + raise TypeError("private key invalid") + + self.key = wif_to_private_key(key, hex=False) + self.hex = self.key.hex() + if key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, + TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX): + self.compressed = False + else: + self.compressed = True + if key[0] in (TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, + TESTNET_PRIVATE_KEY_COMPRESSED_PREFIX): + self.testnet = True + else: + self.testnet = False + self.wif = private_key_to_wif(self.key, self.compressed, self.testnet) + + def __str__(self): + return self.wif + + +class PublicKey(): + """ + The class for public key object. + + :param key: one of this types allowed: + + - private key is instance of ``PrivateKey`` class + - private key HEX encoded string + - private key 32 bytes string + - private key in WIF format + - public key in HEX encoded string + - public key [33/65] bytes string + + In case no key specified with HEX or bytes string you have to provide flag for testnet + and compressed key. WIF format and ``PrivateKey`` instance already contain this flags. + For HEX or bytes public key only testnet flag has the meaning, comressed flag is determined + according to the length of key. + + :param compressed: (optional) if set to True private key corresponding compressed public key, + by default set to True. Recommended use only compressed public key. + :param testnet: (optional) if set to True mean that this private key for testnet Bitcoin network. + + """ + def __init__(self, key, compressed=True, testnet=False): + if isinstance(key, str): + try: + key = bytes_from_hex(key) + except: + if is_wif_valid(key): + key = PrivateKey(key) + + if isinstance(key, bytes): + if len(key) == 32: + key = PrivateKey(key, compressed=compressed, testnet=testnet) + elif is_public_key_valid(key): + public_key = key + self.testnet = testnet + self.compressed = True if len(key) == 33 else False + else: + raise TypeError("key invalid") + + if isinstance(key, PrivateKey): + #: flag for testnet network private key (boolean) + self.testnet = key.testnet + #: flag for compressed type of corresponding public key (boolean) + self.compressed = key.compressed + public_key = private_to_public_key(key.key, + compressed=key.compressed, + hex=False) + + #: public key in bytes (bytes) + self.key = public_key + #: public key in HEX (string) + self.hex = self.key.hex() + + def __str__(self): + return self.hex + + +class Address(): + """ + The class for Address object. + + :param key: (optional) one of this types allowed: + + - private key WIF format + - instance of ``PrivateKey`` + - private key HEX encoded string + - instance of ``PublicKey`` + + In case no key specified new Address will be created with random keys. + :param address_type: (optional) P2PKH, PUBKEY, P2WPKH, P2SH_P2WPKH, by default P2WPKH. + :param compressed: (optional) if set to True private key corresponding compressed public key, + by default set to True. Recommended use only compressed public key. + :param testnet: (optional) if set to True mean that this private key for testnet Bitcoin network. + + In case instance is created from WIF private key, ``PrivateKey`` or ``PublicKey`` compressed and testnet flags + already contain in initial key parameter and will be ignored. + """ + def __init__(self, key=None, + address_type="P2WPKH", testnet=False, compressed=True): + if key is None: + #: instance of ``PrivateKey`` class + self.private_key = PrivateKey(testnet=testnet, + compressed=compressed) + #: instance of ``PublicKey`` class + self.public_key = PublicKey(self.private_key) + #: flag for testnet network address (boolean) + self.testnet = testnet + if isinstance(key, str) or isinstance(key, bytes): + key = PrivateKey(key, testnet=testnet, compressed=compressed) + if isinstance(key, PrivateKey): + self.private_key = key + self.testnet = key.testnet + compressed = key.compressed + self.public_key = PublicKey(self.private_key) + elif isinstance(key, PublicKey): + self.public_key = key + self.testnet = testnet + compressed = key.compressed + if address_type not in ("P2PKH", "PUBKEY", "P2WPKH", "P2SH_P2WPKH"): + raise TypeError("address type invalid") + if not compressed: + if address_type not in ("P2PKH", "PUBKEY", "P2SH"): + raise TypeError("compressed public key invalid") + #: flag for testnet network address (boolean) + self.type = address_type + + if address_type == "PUBKEY": + self.pubkey_script = b"%s%s" % (op_push_data(self.public_key.key), OP_CHECKSIG) + self.pubkey_script_hex = self.pubkey_script.hex() + #: version of witness program for SEGWIT address (string) + self.witness_version = 0 if address_type == "P2WPKH" else None + self.compressed = compressed + if address_type == "P2SH_P2WPKH": + #: flag for script hash address (boolean) + self.script_hash = True + #: redeeem script, only for P2SH_P2WPKH (bytes) + self.redeem_script = public_key_to_p2sh_p2wpkh_script(self.public_key.key) + #: redeeem script HEX, only for P2SH_P2WPKH (string) + self.redeem_script_hex = self.redeem_script.hex() + #: address hash + self.hash = hash160(self.redeem_script) + self.witness_version = None + else: + self.script_hash = False + self.hash = hash160(self.public_key.key) + #: address hash HEX (string) + self.hash_hex = self.hash.hex() + #: address in base58 or bech32 encoding (string) + self.address = hash_to_address(self.hash, + script_hash=self.script_hash, + witness_version=self.witness_version, + testnet=self.testnet) + + def __str__(self): + return self.address + + +class ScriptAddress(): + def __init__(self, script, + testnet=False, witness_version=0): + self.witness_version = witness_version + self.testnet = testnet + if isinstance(script, str): + script = bytes.fromhex(script) + self.script = script + self.script_hex = self.script.hex() + if witness_version is None: + self.hash = hash160(self.script) + else: + self.hash = sha256(self.script) + self.script_opcodes = decode_script(self.script) + self.script_opcodes_asm = decode_script(self.script, 1) + self.address = hash_to_address(self.hash, + script_hash=True, + witness_version=self.witness_version, + testnet=self.testnet) + + @classmethod + def multisig(cls, n, m, public_key_list, + testnet=False, witness_version=0): + """ + The class method for creating a multisig address. + + :param n: count of required signatures (max 15). + :param m: count of total addresses of participants (max 15). + :param list address_list: addresses list, allowed types: + + - bytes or HEX encoded private key + - private key in WIF format + - PrivateKey instance, + - bytes or HEX encoded public key + - PublicKey instance + + + """ + if n > 15 or m > 15 or n > m or n < 1 or m < 1: + raise TypeError("invalid n of m maximum 15 of 15 multisig allowed") + if len(public_key_list) != m: + raise TypeError("invalid address list count") + script = bytes([0x50 + n]) + for a in list(public_key_list): + if isinstance(a, str): + try: + a = bytes.fromhex(a) + except: + if is_wif_valid(a): + a = private_to_public_key(a, hex=False) + pass + if isinstance(a, Address): + a = a.public_key.key + elif isinstance(a, PublicKey): + a = a.key + elif isinstance(a, PrivateKey): + a = private_to_public_key(a.key) + if not isinstance(a, bytes): + raise TypeError("invalid public key list element") + if len(a) == 32: + a = private_to_public_key(a) + if len(a) != 33: + raise TypeError("invalid public key list element size") + script += b"%s%s" % (int_to_var_int(len(a)), a) + script += b"%s%s" % (bytes([0x50 + m]),OP_CHECKMULTISIG) + return cls(script, testnet=testnet, witness_version=witness_version) diff --git a/pybtc/bip39_word_list/chinese_simplified.txt b/pybtc/bip39_word_list/chinese_simplified.txt new file mode 100644 index 0000000..b90f1ed --- /dev/null +++ b/pybtc/bip39_word_list/chinese_simplified.txt @@ -0,0 +1,2048 @@ +的 +一 +是 +在 +不 +了 +有 +和 +人 +这 +中 +大 +为 +上 +个 +国 +我 +以 +要 +他 +时 +来 +用 +们 +生 +到 +作 +地 +于 +出 +就 +分 +对 +成 +会 +可 +主 +发 +年 +动 +同 +工 +也 +能 +下 +过 +子 +说 +产 +种 +面 +而 +方 +后 +多 +定 +行 +学 +法 +所 +民 +得 +经 +十 +三 +之 +进 +着 +等 +部 +度 +家 +电 +力 +里 +如 +水 +化 +高 +自 +二 +理 +起 +小 +物 +现 +实 +加 +量 +都 +两 +体 +制 +机 +当 +使 +点 +从 +业 +本 +去 +把 +性 +好 +应 +开 +它 +合 +还 +因 +由 +其 +些 +然 +前 +外 +天 +政 +四 +日 +那 +社 +义 +事 +平 +形 +相 +全 +表 +间 +样 +与 +关 +各 +重 +新 +线 +内 +数 +正 +心 +反 +你 +明 +看 +原 +又 +么 +利 +比 +或 +但 +质 +气 +第 +向 +道 +命 +此 +变 +条 +只 +没 +结 +解 +问 +意 +建 +月 +公 +无 +系 +军 +很 +情 +者 +最 +立 +代 +想 +已 +通 +并 +提 +直 +题 +党 +程 +展 +五 +果 +料 +象 +员 +革 +位 +入 +常 +文 +总 +次 +品 +式 +活 +设 +及 +管 +特 +件 +长 +求 +老 +头 +基 +资 +边 +流 +路 +级 +少 +图 +山 +统 +接 +知 +较 +将 +组 +见 +计 +别 +她 +手 +角 +期 +根 +论 +运 +农 +指 +几 +九 +区 +强 +放 +决 +西 +被 +干 +做 +必 +战 +先 +回 +则 +任 +取 +据 +处 +队 +南 +给 +色 +光 +门 +即 +保 +治 +北 +造 +百 +规 +热 +领 +七 +海 +口 +东 +导 +器 +压 +志 +世 +金 +增 +争 +济 +阶 +油 +思 +术 +极 +交 +受 +联 +什 +认 +六 +共 +权 +收 +证 +改 +清 +美 +再 +采 +转 +更 +单 +风 +切 +打 +白 +教 +速 +花 +带 +安 +场 +身 +车 +例 +真 +务 +具 +万 +每 +目 +至 +达 +走 +积 +示 +议 +声 +报 +斗 +完 +类 +八 +离 +华 +名 +确 +才 +科 +张 +信 +马 +节 +话 +米 +整 +空 +元 +况 +今 +集 +温 +传 +土 +许 +步 +群 +广 +石 +记 +需 +段 +研 +界 +拉 +林 +律 +叫 +且 +究 +观 +越 +织 +装 +影 +算 +低 +持 +音 +众 +书 +布 +复 +容 +儿 +须 +际 +商 +非 +验 +连 +断 +深 +难 +近 +矿 +千 +周 +委 +素 +技 +备 +半 +办 +青 +省 +列 +习 +响 +约 +支 +般 +史 +感 +劳 +便 +团 +往 +酸 +历 +市 +克 +何 +除 +消 +构 +府 +称 +太 +准 +精 +值 +号 +率 +族 +维 +划 +选 +标 +写 +存 +候 +毛 +亲 +快 +效 +斯 +院 +查 +江 +型 +眼 +王 +按 +格 +养 +易 +置 +派 +层 +片 +始 +却 +专 +状 +育 +厂 +京 +识 +适 +属 +圆 +包 +火 +住 +调 +满 +县 +局 +照 +参 +红 +细 +引 +听 +该 +铁 +价 +严 +首 +底 +液 +官 +德 +随 +病 +苏 +失 +尔 +死 +讲 +配 +女 +黄 +推 +显 +谈 +罪 +神 +艺 +呢 +席 +含 +企 +望 +密 +批 +营 +项 +防 +举 +球 +英 +氧 +势 +告 +李 +台 +落 +木 +帮 +轮 +破 +亚 +师 +围 +注 +远 +字 +材 +排 +供 +河 +态 +封 +另 +施 +减 +树 +溶 +怎 +止 +案 +言 +士 +均 +武 +固 +叶 +鱼 +波 +视 +仅 +费 +紧 +爱 +左 +章 +早 +朝 +害 +续 +轻 +服 +试 +食 +充 +兵 +源 +判 +护 +司 +足 +某 +练 +差 +致 +板 +田 +降 +黑 +犯 +负 +击 +范 +继 +兴 +似 +余 +坚 +曲 +输 +修 +故 +城 +夫 +够 +送 +笔 +船 +占 +右 +财 +吃 +富 +春 +职 +觉 +汉 +画 +功 +巴 +跟 +虽 +杂 +飞 +检 +吸 +助 +升 +阳 +互 +初 +创 +抗 +考 +投 +坏 +策 +古 +径 +换 +未 +跑 +留 +钢 +曾 +端 +责 +站 +简 +述 +钱 +副 +尽 +帝 +射 +草 +冲 +承 +独 +令 +限 +阿 +宣 +环 +双 +请 +超 +微 +让 +控 +州 +良 +轴 +找 +否 +纪 +益 +依 +优 +顶 +础 +载 +倒 +房 +突 +坐 +粉 +敌 +略 +客 +袁 +冷 +胜 +绝 +析 +块 +剂 +测 +丝 +协 +诉 +念 +陈 +仍 +罗 +盐 +友 +洋 +错 +苦 +夜 +刑 +移 +频 +逐 +靠 +混 +母 +短 +皮 +终 +聚 +汽 +村 +云 +哪 +既 +距 +卫 +停 +烈 +央 +察 +烧 +迅 +境 +若 +印 +洲 +刻 +括 +激 +孔 +搞 +甚 +室 +待 +核 +校 +散 +侵 +吧 +甲 +游 +久 +菜 +味 +旧 +模 +湖 +货 +损 +预 +阻 +毫 +普 +稳 +乙 +妈 +植 +息 +扩 +银 +语 +挥 +酒 +守 +拿 +序 +纸 +医 +缺 +雨 +吗 +针 +刘 +啊 +急 +唱 +误 +训 +愿 +审 +附 +获 +茶 +鲜 +粮 +斤 +孩 +脱 +硫 +肥 +善 +龙 +演 +父 +渐 +血 +欢 +械 +掌 +歌 +沙 +刚 +攻 +谓 +盾 +讨 +晚 +粒 +乱 +燃 +矛 +乎 +杀 +药 +宁 +鲁 +贵 +钟 +煤 +读 +班 +伯 +香 +介 +迫 +句 +丰 +培 +握 +兰 +担 +弦 +蛋 +沉 +假 +穿 +执 +答 +乐 +谁 +顺 +烟 +缩 +征 +脸 +喜 +松 +脚 +困 +异 +免 +背 +星 +福 +买 +染 +井 +概 +慢 +怕 +磁 +倍 +祖 +皇 +促 +静 +补 +评 +翻 +肉 +践 +尼 +衣 +宽 +扬 +棉 +希 +伤 +操 +垂 +秋 +宜 +氢 +套 +督 +振 +架 +亮 +末 +宪 +庆 +编 +牛 +触 +映 +雷 +销 +诗 +座 +居 +抓 +裂 +胞 +呼 +娘 +景 +威 +绿 +晶 +厚 +盟 +衡 +鸡 +孙 +延 +危 +胶 +屋 +乡 +临 +陆 +顾 +掉 +呀 +灯 +岁 +措 +束 +耐 +剧 +玉 +赵 +跳 +哥 +季 +课 +凯 +胡 +额 +款 +绍 +卷 +齐 +伟 +蒸 +殖 +永 +宗 +苗 +川 +炉 +岩 +弱 +零 +杨 +奏 +沿 +露 +杆 +探 +滑 +镇 +饭 +浓 +航 +怀 +赶 +库 +夺 +伊 +灵 +税 +途 +灭 +赛 +归 +召 +鼓 +播 +盘 +裁 +险 +康 +唯 +录 +菌 +纯 +借 +糖 +盖 +横 +符 +私 +努 +堂 +域 +枪 +润 +幅 +哈 +竟 +熟 +虫 +泽 +脑 +壤 +碳 +欧 +遍 +侧 +寨 +敢 +彻 +虑 +斜 +薄 +庭 +纳 +弹 +饲 +伸 +折 +麦 +湿 +暗 +荷 +瓦 +塞 +床 +筑 +恶 +户 +访 +塔 +奇 +透 +梁 +刀 +旋 +迹 +卡 +氯 +遇 +份 +毒 +泥 +退 +洗 +摆 +灰 +彩 +卖 +耗 +夏 +择 +忙 +铜 +献 +硬 +予 +繁 +圈 +雪 +函 +亦 +抽 +篇 +阵 +阴 +丁 +尺 +追 +堆 +雄 +迎 +泛 +爸 +楼 +避 +谋 +吨 +野 +猪 +旗 +累 +偏 +典 +馆 +索 +秦 +脂 +潮 +爷 +豆 +忽 +托 +惊 +塑 +遗 +愈 +朱 +替 +纤 +粗 +倾 +尚 +痛 +楚 +谢 +奋 +购 +磨 +君 +池 +旁 +碎 +骨 +监 +捕 +弟 +暴 +割 +贯 +殊 +释 +词 +亡 +壁 +顿 +宝 +午 +尘 +闻 +揭 +炮 +残 +冬 +桥 +妇 +警 +综 +招 +吴 +付 +浮 +遭 +徐 +您 +摇 +谷 +赞 +箱 +隔 +订 +男 +吹 +园 +纷 +唐 +败 +宋 +玻 +巨 +耕 +坦 +荣 +闭 +湾 +键 +凡 +驻 +锅 +救 +恩 +剥 +凝 +碱 +齿 +截 +炼 +麻 +纺 +禁 +废 +盛 +版 +缓 +净 +睛 +昌 +婚 +涉 +筒 +嘴 +插 +岸 +朗 +庄 +街 +藏 +姑 +贸 +腐 +奴 +啦 +惯 +乘 +伙 +恢 +匀 +纱 +扎 +辩 +耳 +彪 +臣 +亿 +璃 +抵 +脉 +秀 +萨 +俄 +网 +舞 +店 +喷 +纵 +寸 +汗 +挂 +洪 +贺 +闪 +柬 +爆 +烯 +津 +稻 +墙 +软 +勇 +像 +滚 +厘 +蒙 +芳 +肯 +坡 +柱 +荡 +腿 +仪 +旅 +尾 +轧 +冰 +贡 +登 +黎 +削 +钻 +勒 +逃 +障 +氨 +郭 +峰 +币 +港 +伏 +轨 +亩 +毕 +擦 +莫 +刺 +浪 +秘 +援 +株 +健 +售 +股 +岛 +甘 +泡 +睡 +童 +铸 +汤 +阀 +休 +汇 +舍 +牧 +绕 +炸 +哲 +磷 +绩 +朋 +淡 +尖 +启 +陷 +柴 +呈 +徒 +颜 +泪 +稍 +忘 +泵 +蓝 +拖 +洞 +授 +镜 +辛 +壮 +锋 +贫 +虚 +弯 +摩 +泰 +幼 +廷 +尊 +窗 +纲 +弄 +隶 +疑 +氏 +宫 +姐 +震 +瑞 +怪 +尤 +琴 +循 +描 +膜 +违 +夹 +腰 +缘 +珠 +穷 +森 +枝 +竹 +沟 +催 +绳 +忆 +邦 +剩 +幸 +浆 +栏 +拥 +牙 +贮 +礼 +滤 +钠 +纹 +罢 +拍 +咱 +喊 +袖 +埃 +勤 +罚 +焦 +潜 +伍 +墨 +欲 +缝 +姓 +刊 +饱 +仿 +奖 +铝 +鬼 +丽 +跨 +默 +挖 +链 +扫 +喝 +袋 +炭 +污 +幕 +诸 +弧 +励 +梅 +奶 +洁 +灾 +舟 +鉴 +苯 +讼 +抱 +毁 +懂 +寒 +智 +埔 +寄 +届 +跃 +渡 +挑 +丹 +艰 +贝 +碰 +拔 +爹 +戴 +码 +梦 +芽 +熔 +赤 +渔 +哭 +敬 +颗 +奔 +铅 +仲 +虎 +稀 +妹 +乏 +珍 +申 +桌 +遵 +允 +隆 +螺 +仓 +魏 +锐 +晓 +氮 +兼 +隐 +碍 +赫 +拨 +忠 +肃 +缸 +牵 +抢 +博 +巧 +壳 +兄 +杜 +讯 +诚 +碧 +祥 +柯 +页 +巡 +矩 +悲 +灌 +龄 +伦 +票 +寻 +桂 +铺 +圣 +恐 +恰 +郑 +趣 +抬 +荒 +腾 +贴 +柔 +滴 +猛 +阔 +辆 +妻 +填 +撤 +储 +签 +闹 +扰 +紫 +砂 +递 +戏 +吊 +陶 +伐 +喂 +疗 +瓶 +婆 +抚 +臂 +摸 +忍 +虾 +蜡 +邻 +胸 +巩 +挤 +偶 +弃 +槽 +劲 +乳 +邓 +吉 +仁 +烂 +砖 +租 +乌 +舰 +伴 +瓜 +浅 +丙 +暂 +燥 +橡 +柳 +迷 +暖 +牌 +秧 +胆 +详 +簧 +踏 +瓷 +谱 +呆 +宾 +糊 +洛 +辉 +愤 +竞 +隙 +怒 +粘 +乃 +绪 +肩 +籍 +敏 +涂 +熙 +皆 +侦 +悬 +掘 +享 +纠 +醒 +狂 +锁 +淀 +恨 +牲 +霸 +爬 +赏 +逆 +玩 +陵 +祝 +秒 +浙 +貌 +役 +彼 +悉 +鸭 +趋 +凤 +晨 +畜 +辈 +秩 +卵 +署 +梯 +炎 +滩 +棋 +驱 +筛 +峡 +冒 +啥 +寿 +译 +浸 +泉 +帽 +迟 +硅 +疆 +贷 +漏 +稿 +冠 +嫩 +胁 +芯 +牢 +叛 +蚀 +奥 +鸣 +岭 +羊 +凭 +串 +塘 +绘 +酵 +融 +盆 +锡 +庙 +筹 +冻 +辅 +摄 +袭 +筋 +拒 +僚 +旱 +钾 +鸟 +漆 +沈 +眉 +疏 +添 +棒 +穗 +硝 +韩 +逼 +扭 +侨 +凉 +挺 +碗 +栽 +炒 +杯 +患 +馏 +劝 +豪 +辽 +勃 +鸿 +旦 +吏 +拜 +狗 +埋 +辊 +掩 +饮 +搬 +骂 +辞 +勾 +扣 +估 +蒋 +绒 +雾 +丈 +朵 +姆 +拟 +宇 +辑 +陕 +雕 +偿 +蓄 +崇 +剪 +倡 +厅 +咬 +驶 +薯 +刷 +斥 +番 +赋 +奉 +佛 +浇 +漫 +曼 +扇 +钙 +桃 +扶 +仔 +返 +俗 +亏 +腔 +鞋 +棱 +覆 +框 +悄 +叔 +撞 +骗 +勘 +旺 +沸 +孤 +吐 +孟 +渠 +屈 +疾 +妙 +惜 +仰 +狠 +胀 +谐 +抛 +霉 +桑 +岗 +嘛 +衰 +盗 +渗 +脏 +赖 +涌 +甜 +曹 +阅 +肌 +哩 +厉 +烃 +纬 +毅 +昨 +伪 +症 +煮 +叹 +钉 +搭 +茎 +笼 +酷 +偷 +弓 +锥 +恒 +杰 +坑 +鼻 +翼 +纶 +叙 +狱 +逮 +罐 +络 +棚 +抑 +膨 +蔬 +寺 +骤 +穆 +冶 +枯 +册 +尸 +凸 +绅 +坯 +牺 +焰 +轰 +欣 +晋 +瘦 +御 +锭 +锦 +丧 +旬 +锻 +垄 +搜 +扑 +邀 +亭 +酯 +迈 +舒 +脆 +酶 +闲 +忧 +酚 +顽 +羽 +涨 +卸 +仗 +陪 +辟 +惩 +杭 +姚 +肚 +捉 +飘 +漂 +昆 +欺 +吾 +郎 +烷 +汁 +呵 +饰 +萧 +雅 +邮 +迁 +燕 +撒 +姻 +赴 +宴 +烦 +债 +帐 +斑 +铃 +旨 +醇 +董 +饼 +雏 +姿 +拌 +傅 +腹 +妥 +揉 +贤 +拆 +歪 +葡 +胺 +丢 +浩 +徽 +昂 +垫 +挡 +览 +贪 +慰 +缴 +汪 +慌 +冯 +诺 +姜 +谊 +凶 +劣 +诬 +耀 +昏 +躺 +盈 +骑 +乔 +溪 +丛 +卢 +抹 +闷 +咨 +刮 +驾 +缆 +悟 +摘 +铒 +掷 +颇 +幻 +柄 +惠 +惨 +佳 +仇 +腊 +窝 +涤 +剑 +瞧 +堡 +泼 +葱 +罩 +霍 +捞 +胎 +苍 +滨 +俩 +捅 +湘 +砍 +霞 +邵 +萄 +疯 +淮 +遂 +熊 +粪 +烘 +宿 +档 +戈 +驳 +嫂 +裕 +徙 +箭 +捐 +肠 +撑 +晒 +辨 +殿 +莲 +摊 +搅 +酱 +屏 +疫 +哀 +蔡 +堵 +沫 +皱 +畅 +叠 +阁 +莱 +敲 +辖 +钩 +痕 +坝 +巷 +饿 +祸 +丘 +玄 +溜 +曰 +逻 +彭 +尝 +卿 +妨 +艇 +吞 +韦 +怨 +矮 +歇 diff --git a/pybtc/bip39_word_list/chinese_traditional.txt b/pybtc/bip39_word_list/chinese_traditional.txt new file mode 100644 index 0000000..9b02047 --- /dev/null +++ b/pybtc/bip39_word_list/chinese_traditional.txt @@ -0,0 +1,2048 @@ +的 +一 +是 +在 +不 +了 +有 +和 +人 +這 +中 +大 +為 +上 +個 +國 +我 +以 +要 +他 +時 +來 +用 +們 +生 +到 +作 +地 +於 +出 +就 +分 +對 +成 +會 +可 +主 +發 +年 +動 +同 +工 +也 +能 +下 +過 +子 +說 +產 +種 +面 +而 +方 +後 +多 +定 +行 +學 +法 +所 +民 +得 +經 +十 +三 +之 +進 +著 +等 +部 +度 +家 +電 +力 +裡 +如 +水 +化 +高 +自 +二 +理 +起 +小 +物 +現 +實 +加 +量 +都 +兩 +體 +制 +機 +當 +使 +點 +從 +業 +本 +去 +把 +性 +好 +應 +開 +它 +合 +還 +因 +由 +其 +些 +然 +前 +外 +天 +政 +四 +日 +那 +社 +義 +事 +平 +形 +相 +全 +表 +間 +樣 +與 +關 +各 +重 +新 +線 +內 +數 +正 +心 +反 +你 +明 +看 +原 +又 +麼 +利 +比 +或 +但 +質 +氣 +第 +向 +道 +命 +此 +變 +條 +只 +沒 +結 +解 +問 +意 +建 +月 +公 +無 +系 +軍 +很 +情 +者 +最 +立 +代 +想 +已 +通 +並 +提 +直 +題 +黨 +程 +展 +五 +果 +料 +象 +員 +革 +位 +入 +常 +文 +總 +次 +品 +式 +活 +設 +及 +管 +特 +件 +長 +求 +老 +頭 +基 +資 +邊 +流 +路 +級 +少 +圖 +山 +統 +接 +知 +較 +將 +組 +見 +計 +別 +她 +手 +角 +期 +根 +論 +運 +農 +指 +幾 +九 +區 +強 +放 +決 +西 +被 +幹 +做 +必 +戰 +先 +回 +則 +任 +取 +據 +處 +隊 +南 +給 +色 +光 +門 +即 +保 +治 +北 +造 +百 +規 +熱 +領 +七 +海 +口 +東 +導 +器 +壓 +志 +世 +金 +增 +爭 +濟 +階 +油 +思 +術 +極 +交 +受 +聯 +什 +認 +六 +共 +權 +收 +證 +改 +清 +美 +再 +採 +轉 +更 +單 +風 +切 +打 +白 +教 +速 +花 +帶 +安 +場 +身 +車 +例 +真 +務 +具 +萬 +每 +目 +至 +達 +走 +積 +示 +議 +聲 +報 +鬥 +完 +類 +八 +離 +華 +名 +確 +才 +科 +張 +信 +馬 +節 +話 +米 +整 +空 +元 +況 +今 +集 +溫 +傳 +土 +許 +步 +群 +廣 +石 +記 +需 +段 +研 +界 +拉 +林 +律 +叫 +且 +究 +觀 +越 +織 +裝 +影 +算 +低 +持 +音 +眾 +書 +布 +复 +容 +兒 +須 +際 +商 +非 +驗 +連 +斷 +深 +難 +近 +礦 +千 +週 +委 +素 +技 +備 +半 +辦 +青 +省 +列 +習 +響 +約 +支 +般 +史 +感 +勞 +便 +團 +往 +酸 +歷 +市 +克 +何 +除 +消 +構 +府 +稱 +太 +準 +精 +值 +號 +率 +族 +維 +劃 +選 +標 +寫 +存 +候 +毛 +親 +快 +效 +斯 +院 +查 +江 +型 +眼 +王 +按 +格 +養 +易 +置 +派 +層 +片 +始 +卻 +專 +狀 +育 +廠 +京 +識 +適 +屬 +圓 +包 +火 +住 +調 +滿 +縣 +局 +照 +參 +紅 +細 +引 +聽 +該 +鐵 +價 +嚴 +首 +底 +液 +官 +德 +隨 +病 +蘇 +失 +爾 +死 +講 +配 +女 +黃 +推 +顯 +談 +罪 +神 +藝 +呢 +席 +含 +企 +望 +密 +批 +營 +項 +防 +舉 +球 +英 +氧 +勢 +告 +李 +台 +落 +木 +幫 +輪 +破 +亞 +師 +圍 +注 +遠 +字 +材 +排 +供 +河 +態 +封 +另 +施 +減 +樹 +溶 +怎 +止 +案 +言 +士 +均 +武 +固 +葉 +魚 +波 +視 +僅 +費 +緊 +愛 +左 +章 +早 +朝 +害 +續 +輕 +服 +試 +食 +充 +兵 +源 +判 +護 +司 +足 +某 +練 +差 +致 +板 +田 +降 +黑 +犯 +負 +擊 +范 +繼 +興 +似 +餘 +堅 +曲 +輸 +修 +故 +城 +夫 +夠 +送 +筆 +船 +佔 +右 +財 +吃 +富 +春 +職 +覺 +漢 +畫 +功 +巴 +跟 +雖 +雜 +飛 +檢 +吸 +助 +昇 +陽 +互 +初 +創 +抗 +考 +投 +壞 +策 +古 +徑 +換 +未 +跑 +留 +鋼 +曾 +端 +責 +站 +簡 +述 +錢 +副 +盡 +帝 +射 +草 +衝 +承 +獨 +令 +限 +阿 +宣 +環 +雙 +請 +超 +微 +讓 +控 +州 +良 +軸 +找 +否 +紀 +益 +依 +優 +頂 +礎 +載 +倒 +房 +突 +坐 +粉 +敵 +略 +客 +袁 +冷 +勝 +絕 +析 +塊 +劑 +測 +絲 +協 +訴 +念 +陳 +仍 +羅 +鹽 +友 +洋 +錯 +苦 +夜 +刑 +移 +頻 +逐 +靠 +混 +母 +短 +皮 +終 +聚 +汽 +村 +雲 +哪 +既 +距 +衛 +停 +烈 +央 +察 +燒 +迅 +境 +若 +印 +洲 +刻 +括 +激 +孔 +搞 +甚 +室 +待 +核 +校 +散 +侵 +吧 +甲 +遊 +久 +菜 +味 +舊 +模 +湖 +貨 +損 +預 +阻 +毫 +普 +穩 +乙 +媽 +植 +息 +擴 +銀 +語 +揮 +酒 +守 +拿 +序 +紙 +醫 +缺 +雨 +嗎 +針 +劉 +啊 +急 +唱 +誤 +訓 +願 +審 +附 +獲 +茶 +鮮 +糧 +斤 +孩 +脫 +硫 +肥 +善 +龍 +演 +父 +漸 +血 +歡 +械 +掌 +歌 +沙 +剛 +攻 +謂 +盾 +討 +晚 +粒 +亂 +燃 +矛 +乎 +殺 +藥 +寧 +魯 +貴 +鐘 +煤 +讀 +班 +伯 +香 +介 +迫 +句 +豐 +培 +握 +蘭 +擔 +弦 +蛋 +沉 +假 +穿 +執 +答 +樂 +誰 +順 +煙 +縮 +徵 +臉 +喜 +松 +腳 +困 +異 +免 +背 +星 +福 +買 +染 +井 +概 +慢 +怕 +磁 +倍 +祖 +皇 +促 +靜 +補 +評 +翻 +肉 +踐 +尼 +衣 +寬 +揚 +棉 +希 +傷 +操 +垂 +秋 +宜 +氫 +套 +督 +振 +架 +亮 +末 +憲 +慶 +編 +牛 +觸 +映 +雷 +銷 +詩 +座 +居 +抓 +裂 +胞 +呼 +娘 +景 +威 +綠 +晶 +厚 +盟 +衡 +雞 +孫 +延 +危 +膠 +屋 +鄉 +臨 +陸 +顧 +掉 +呀 +燈 +歲 +措 +束 +耐 +劇 +玉 +趙 +跳 +哥 +季 +課 +凱 +胡 +額 +款 +紹 +卷 +齊 +偉 +蒸 +殖 +永 +宗 +苗 +川 +爐 +岩 +弱 +零 +楊 +奏 +沿 +露 +桿 +探 +滑 +鎮 +飯 +濃 +航 +懷 +趕 +庫 +奪 +伊 +靈 +稅 +途 +滅 +賽 +歸 +召 +鼓 +播 +盤 +裁 +險 +康 +唯 +錄 +菌 +純 +借 +糖 +蓋 +橫 +符 +私 +努 +堂 +域 +槍 +潤 +幅 +哈 +竟 +熟 +蟲 +澤 +腦 +壤 +碳 +歐 +遍 +側 +寨 +敢 +徹 +慮 +斜 +薄 +庭 +納 +彈 +飼 +伸 +折 +麥 +濕 +暗 +荷 +瓦 +塞 +床 +築 +惡 +戶 +訪 +塔 +奇 +透 +梁 +刀 +旋 +跡 +卡 +氯 +遇 +份 +毒 +泥 +退 +洗 +擺 +灰 +彩 +賣 +耗 +夏 +擇 +忙 +銅 +獻 +硬 +予 +繁 +圈 +雪 +函 +亦 +抽 +篇 +陣 +陰 +丁 +尺 +追 +堆 +雄 +迎 +泛 +爸 +樓 +避 +謀 +噸 +野 +豬 +旗 +累 +偏 +典 +館 +索 +秦 +脂 +潮 +爺 +豆 +忽 +托 +驚 +塑 +遺 +愈 +朱 +替 +纖 +粗 +傾 +尚 +痛 +楚 +謝 +奮 +購 +磨 +君 +池 +旁 +碎 +骨 +監 +捕 +弟 +暴 +割 +貫 +殊 +釋 +詞 +亡 +壁 +頓 +寶 +午 +塵 +聞 +揭 +炮 +殘 +冬 +橋 +婦 +警 +綜 +招 +吳 +付 +浮 +遭 +徐 +您 +搖 +谷 +贊 +箱 +隔 +訂 +男 +吹 +園 +紛 +唐 +敗 +宋 +玻 +巨 +耕 +坦 +榮 +閉 +灣 +鍵 +凡 +駐 +鍋 +救 +恩 +剝 +凝 +鹼 +齒 +截 +煉 +麻 +紡 +禁 +廢 +盛 +版 +緩 +淨 +睛 +昌 +婚 +涉 +筒 +嘴 +插 +岸 +朗 +莊 +街 +藏 +姑 +貿 +腐 +奴 +啦 +慣 +乘 +夥 +恢 +勻 +紗 +扎 +辯 +耳 +彪 +臣 +億 +璃 +抵 +脈 +秀 +薩 +俄 +網 +舞 +店 +噴 +縱 +寸 +汗 +掛 +洪 +賀 +閃 +柬 +爆 +烯 +津 +稻 +牆 +軟 +勇 +像 +滾 +厘 +蒙 +芳 +肯 +坡 +柱 +盪 +腿 +儀 +旅 +尾 +軋 +冰 +貢 +登 +黎 +削 +鑽 +勒 +逃 +障 +氨 +郭 +峰 +幣 +港 +伏 +軌 +畝 +畢 +擦 +莫 +刺 +浪 +秘 +援 +株 +健 +售 +股 +島 +甘 +泡 +睡 +童 +鑄 +湯 +閥 +休 +匯 +舍 +牧 +繞 +炸 +哲 +磷 +績 +朋 +淡 +尖 +啟 +陷 +柴 +呈 +徒 +顏 +淚 +稍 +忘 +泵 +藍 +拖 +洞 +授 +鏡 +辛 +壯 +鋒 +貧 +虛 +彎 +摩 +泰 +幼 +廷 +尊 +窗 +綱 +弄 +隸 +疑 +氏 +宮 +姐 +震 +瑞 +怪 +尤 +琴 +循 +描 +膜 +違 +夾 +腰 +緣 +珠 +窮 +森 +枝 +竹 +溝 +催 +繩 +憶 +邦 +剩 +幸 +漿 +欄 +擁 +牙 +貯 +禮 +濾 +鈉 +紋 +罷 +拍 +咱 +喊 +袖 +埃 +勤 +罰 +焦 +潛 +伍 +墨 +欲 +縫 +姓 +刊 +飽 +仿 +獎 +鋁 +鬼 +麗 +跨 +默 +挖 +鏈 +掃 +喝 +袋 +炭 +污 +幕 +諸 +弧 +勵 +梅 +奶 +潔 +災 +舟 +鑑 +苯 +訟 +抱 +毀 +懂 +寒 +智 +埔 +寄 +屆 +躍 +渡 +挑 +丹 +艱 +貝 +碰 +拔 +爹 +戴 +碼 +夢 +芽 +熔 +赤 +漁 +哭 +敬 +顆 +奔 +鉛 +仲 +虎 +稀 +妹 +乏 +珍 +申 +桌 +遵 +允 +隆 +螺 +倉 +魏 +銳 +曉 +氮 +兼 +隱 +礙 +赫 +撥 +忠 +肅 +缸 +牽 +搶 +博 +巧 +殼 +兄 +杜 +訊 +誠 +碧 +祥 +柯 +頁 +巡 +矩 +悲 +灌 +齡 +倫 +票 +尋 +桂 +鋪 +聖 +恐 +恰 +鄭 +趣 +抬 +荒 +騰 +貼 +柔 +滴 +猛 +闊 +輛 +妻 +填 +撤 +儲 +簽 +鬧 +擾 +紫 +砂 +遞 +戲 +吊 +陶 +伐 +餵 +療 +瓶 +婆 +撫 +臂 +摸 +忍 +蝦 +蠟 +鄰 +胸 +鞏 +擠 +偶 +棄 +槽 +勁 +乳 +鄧 +吉 +仁 +爛 +磚 +租 +烏 +艦 +伴 +瓜 +淺 +丙 +暫 +燥 +橡 +柳 +迷 +暖 +牌 +秧 +膽 +詳 +簧 +踏 +瓷 +譜 +呆 +賓 +糊 +洛 +輝 +憤 +競 +隙 +怒 +粘 +乃 +緒 +肩 +籍 +敏 +塗 +熙 +皆 +偵 +懸 +掘 +享 +糾 +醒 +狂 +鎖 +淀 +恨 +牲 +霸 +爬 +賞 +逆 +玩 +陵 +祝 +秒 +浙 +貌 +役 +彼 +悉 +鴨 +趨 +鳳 +晨 +畜 +輩 +秩 +卵 +署 +梯 +炎 +灘 +棋 +驅 +篩 +峽 +冒 +啥 +壽 +譯 +浸 +泉 +帽 +遲 +矽 +疆 +貸 +漏 +稿 +冠 +嫩 +脅 +芯 +牢 +叛 +蝕 +奧 +鳴 +嶺 +羊 +憑 +串 +塘 +繪 +酵 +融 +盆 +錫 +廟 +籌 +凍 +輔 +攝 +襲 +筋 +拒 +僚 +旱 +鉀 +鳥 +漆 +沈 +眉 +疏 +添 +棒 +穗 +硝 +韓 +逼 +扭 +僑 +涼 +挺 +碗 +栽 +炒 +杯 +患 +餾 +勸 +豪 +遼 +勃 +鴻 +旦 +吏 +拜 +狗 +埋 +輥 +掩 +飲 +搬 +罵 +辭 +勾 +扣 +估 +蔣 +絨 +霧 +丈 +朵 +姆 +擬 +宇 +輯 +陝 +雕 +償 +蓄 +崇 +剪 +倡 +廳 +咬 +駛 +薯 +刷 +斥 +番 +賦 +奉 +佛 +澆 +漫 +曼 +扇 +鈣 +桃 +扶 +仔 +返 +俗 +虧 +腔 +鞋 +棱 +覆 +框 +悄 +叔 +撞 +騙 +勘 +旺 +沸 +孤 +吐 +孟 +渠 +屈 +疾 +妙 +惜 +仰 +狠 +脹 +諧 +拋 +黴 +桑 +崗 +嘛 +衰 +盜 +滲 +臟 +賴 +湧 +甜 +曹 +閱 +肌 +哩 +厲 +烴 +緯 +毅 +昨 +偽 +症 +煮 +嘆 +釘 +搭 +莖 +籠 +酷 +偷 +弓 +錐 +恆 +傑 +坑 +鼻 +翼 +綸 +敘 +獄 +逮 +罐 +絡 +棚 +抑 +膨 +蔬 +寺 +驟 +穆 +冶 +枯 +冊 +屍 +凸 +紳 +坯 +犧 +焰 +轟 +欣 +晉 +瘦 +禦 +錠 +錦 +喪 +旬 +鍛 +壟 +搜 +撲 +邀 +亭 +酯 +邁 +舒 +脆 +酶 +閒 +憂 +酚 +頑 +羽 +漲 +卸 +仗 +陪 +闢 +懲 +杭 +姚 +肚 +捉 +飄 +漂 +昆 +欺 +吾 +郎 +烷 +汁 +呵 +飾 +蕭 +雅 +郵 +遷 +燕 +撒 +姻 +赴 +宴 +煩 +債 +帳 +斑 +鈴 +旨 +醇 +董 +餅 +雛 +姿 +拌 +傅 +腹 +妥 +揉 +賢 +拆 +歪 +葡 +胺 +丟 +浩 +徽 +昂 +墊 +擋 +覽 +貪 +慰 +繳 +汪 +慌 +馮 +諾 +姜 +誼 +兇 +劣 +誣 +耀 +昏 +躺 +盈 +騎 +喬 +溪 +叢 +盧 +抹 +悶 +諮 +刮 +駕 +纜 +悟 +摘 +鉺 +擲 +頗 +幻 +柄 +惠 +慘 +佳 +仇 +臘 +窩 +滌 +劍 +瞧 +堡 +潑 +蔥 +罩 +霍 +撈 +胎 +蒼 +濱 +倆 +捅 +湘 +砍 +霞 +邵 +萄 +瘋 +淮 +遂 +熊 +糞 +烘 +宿 +檔 +戈 +駁 +嫂 +裕 +徙 +箭 +捐 +腸 +撐 +曬 +辨 +殿 +蓮 +攤 +攪 +醬 +屏 +疫 +哀 +蔡 +堵 +沫 +皺 +暢 +疊 +閣 +萊 +敲 +轄 +鉤 +痕 +壩 +巷 +餓 +禍 +丘 +玄 +溜 +曰 +邏 +彭 +嘗 +卿 +妨 +艇 +吞 +韋 +怨 +矮 +歇 diff --git a/pybtc/bip39_word_list/english.txt b/pybtc/bip39_word_list/english.txt new file mode 100644 index 0000000..942040e --- /dev/null +++ b/pybtc/bip39_word_list/english.txt @@ -0,0 +1,2048 @@ +abandon +ability +able +about +above +absent +absorb +abstract +absurd +abuse +access +accident +account +accuse +achieve +acid +acoustic +acquire +across +act +action +actor +actress +actual +adapt +add +addict +address +adjust +admit +adult +advance +advice +aerobic +affair +afford +afraid +again +age +agent +agree +ahead +aim +air +airport +aisle +alarm +album +alcohol +alert +alien +all +alley +allow +almost +alone +alpha +already +also +alter +always +amateur +amazing +among +amount +amused +analyst +anchor +ancient +anger +angle +angry +animal +ankle +announce +annual +another +answer +antenna +antique +anxiety +any +apart +apology +appear +apple +approve +april +arch +arctic +area +arena +argue +arm +armed +armor +army +around +arrange +arrest +arrive +arrow +art +artefact +artist +artwork +ask +aspect +assault +asset +assist +assume +asthma +athlete +atom +attack +attend +attitude +attract +auction +audit +august +aunt +author +auto +autumn +average +avocado +avoid +awake +aware +away +awesome +awful +awkward +axis +baby +bachelor +bacon +badge +bag +balance +balcony +ball +bamboo +banana +banner +bar +barely +bargain +barrel +base +basic +basket +battle +beach +bean +beauty +because +become +beef +before +begin +behave +behind +believe +below +belt +bench +benefit +best +betray +better +between +beyond +bicycle +bid +bike +bind +biology +bird +birth +bitter +black +blade +blame +blanket +blast +bleak +bless +blind +blood +blossom +blouse +blue +blur +blush +board +boat +body +boil +bomb +bone +bonus +book +boost +border +boring +borrow +boss +bottom +bounce +box +boy +bracket +brain +brand +brass +brave +bread +breeze +brick +bridge +brief +bright +bring +brisk +broccoli +broken +bronze +broom +brother +brown +brush +bubble +buddy +budget +buffalo +build +bulb +bulk +bullet +bundle +bunker +burden +burger +burst +bus +business +busy +butter +buyer +buzz +cabbage +cabin +cable +cactus +cage +cake +call +calm +camera +camp +can +canal +cancel +candy +cannon +canoe +canvas +canyon +capable +capital +captain +car +carbon +card +cargo +carpet +carry +cart +case +cash +casino +castle +casual +cat +catalog +catch +category +cattle +caught +cause +caution +cave +ceiling +celery +cement +census +century +cereal +certain +chair +chalk +champion +change +chaos +chapter +charge +chase +chat +cheap +check +cheese +chef +cherry +chest +chicken +chief +child +chimney +choice +choose +chronic +chuckle +chunk +churn +cigar +cinnamon +circle +citizen +city +civil +claim +clap +clarify +claw +clay +clean +clerk +clever +click +client +cliff +climb +clinic +clip +clock +clog +close +cloth +cloud +clown +club +clump +cluster +clutch +coach +coast +coconut +code +coffee +coil +coin +collect +color +column +combine +come +comfort +comic +common +company +concert +conduct +confirm +congress +connect +consider +control +convince +cook +cool +copper +copy +coral +core +corn +correct +cost +cotton +couch +country +couple +course +cousin +cover +coyote +crack +cradle +craft +cram +crane +crash +crater +crawl +crazy +cream +credit +creek +crew +cricket +crime +crisp +critic +crop +cross +crouch +crowd +crucial +cruel +cruise +crumble +crunch +crush +cry +crystal +cube +culture +cup +cupboard +curious +current +curtain +curve +cushion +custom +cute +cycle +dad +damage +damp +dance +danger +daring +dash +daughter +dawn +day +deal +debate +debris +decade +december +decide +decline +decorate +decrease +deer +defense +define +defy +degree +delay +deliver +demand +demise +denial +dentist +deny +depart +depend +deposit +depth +deputy +derive +describe +desert +design +desk +despair +destroy +detail +detect +develop +device +devote +diagram +dial +diamond +diary +dice +diesel +diet +differ +digital +dignity +dilemma +dinner +dinosaur +direct +dirt +disagree +discover +disease +dish +dismiss +disorder +display +distance +divert +divide +divorce +dizzy +doctor +document +dog +doll +dolphin +domain +donate +donkey +donor +door +dose +double +dove +draft +dragon +drama +drastic +draw +dream +dress +drift +drill +drink +drip +drive +drop +drum +dry +duck +dumb +dune +during +dust +dutch +duty +dwarf +dynamic +eager +eagle +early +earn +earth +easily +east +easy +echo +ecology +economy +edge +edit +educate +effort +egg +eight +either +elbow +elder +electric +elegant +element +elephant +elevator +elite +else +embark +embody +embrace +emerge +emotion +employ +empower +empty +enable +enact +end +endless +endorse +enemy +energy +enforce +engage +engine +enhance +enjoy +enlist +enough +enrich +enroll +ensure +enter +entire +entry +envelope +episode +equal +equip +era +erase +erode +erosion +error +erupt +escape +essay +essence +estate +eternal +ethics +evidence +evil +evoke +evolve +exact +example +excess +exchange +excite +exclude +excuse +execute +exercise +exhaust +exhibit +exile +exist +exit +exotic +expand +expect +expire +explain +expose +express +extend +extra +eye +eyebrow +fabric +face +faculty +fade +faint +faith +fall +false +fame +family +famous +fan +fancy +fantasy +farm +fashion +fat +fatal +father +fatigue +fault +favorite +feature +february +federal +fee +feed +feel +female +fence +festival +fetch +fever +few +fiber +fiction +field +figure +file +film +filter +final +find +fine +finger +finish +fire +firm +first +fiscal +fish +fit +fitness +fix +flag +flame +flash +flat +flavor +flee +flight +flip +float +flock +floor +flower +fluid +flush +fly +foam +focus +fog +foil +fold +follow +food +foot +force +forest +forget +fork +fortune +forum +forward +fossil +foster +found +fox +fragile +frame +frequent +fresh +friend +fringe +frog +front +frost +frown +frozen +fruit +fuel +fun +funny +furnace +fury +future +gadget +gain +galaxy +gallery +game +gap +garage +garbage +garden +garlic +garment +gas +gasp +gate +gather +gauge +gaze +general +genius +genre +gentle +genuine +gesture +ghost +giant +gift +giggle +ginger +giraffe +girl +give +glad +glance +glare +glass +glide +glimpse +globe +gloom +glory +glove +glow +glue +goat +goddess +gold +good +goose +gorilla +gospel +gossip +govern +gown +grab +grace +grain +grant +grape +grass +gravity +great +green +grid +grief +grit +grocery +group +grow +grunt +guard +guess +guide +guilt +guitar +gun +gym +habit +hair +half +hammer +hamster +hand +happy +harbor +hard +harsh +harvest +hat +have +hawk +hazard +head +health +heart +heavy +hedgehog +height +hello +helmet +help +hen +hero +hidden +high +hill +hint +hip +hire +history +hobby +hockey +hold +hole +holiday +hollow +home +honey +hood +hope +horn +horror +horse +hospital +host +hotel +hour +hover +hub +huge +human +humble +humor +hundred +hungry +hunt +hurdle +hurry +hurt +husband +hybrid +ice +icon +idea +identify +idle +ignore +ill +illegal +illness +image +imitate +immense +immune +impact +impose +improve +impulse +inch +include +income +increase +index +indicate +indoor +industry +infant +inflict +inform +inhale +inherit +initial +inject +injury +inmate +inner +innocent +input +inquiry +insane +insect +inside +inspire +install +intact +interest +into +invest +invite +involve +iron +island +isolate +issue +item +ivory +jacket +jaguar +jar +jazz +jealous +jeans +jelly +jewel +job +join +joke +journey +joy +judge +juice +jump +jungle +junior +junk +just +kangaroo +keen +keep +ketchup +key +kick +kid +kidney +kind +kingdom +kiss +kit +kitchen +kite +kitten +kiwi +knee +knife +knock +know +lab +label +labor +ladder +lady +lake +lamp +language +laptop +large +later +latin +laugh +laundry +lava +law +lawn +lawsuit +layer +lazy +leader +leaf +learn +leave +lecture +left +leg +legal +legend +leisure +lemon +lend +length +lens +leopard +lesson +letter +level +liar +liberty +library +license +life +lift +light +like +limb +limit +link +lion +liquid +list +little +live +lizard +load +loan +lobster +local +lock +logic +lonely +long +loop +lottery +loud +lounge +love +loyal +lucky +luggage +lumber +lunar +lunch +luxury +lyrics +machine +mad +magic +magnet +maid +mail +main +major +make +mammal +man +manage +mandate +mango +mansion +manual +maple +marble +march +margin +marine +market +marriage +mask +mass +master +match +material +math +matrix +matter +maximum +maze +meadow +mean +measure +meat +mechanic +medal +media +melody +melt +member +memory +mention +menu +mercy +merge +merit +merry +mesh +message +metal +method +middle +midnight +milk +million +mimic +mind +minimum +minor +minute +miracle +mirror +misery +miss +mistake +mix +mixed +mixture +mobile +model +modify +mom +moment +monitor +monkey +monster +month +moon +moral +more +morning +mosquito +mother +motion +motor +mountain +mouse +move +movie +much +muffin +mule +multiply +muscle +museum +mushroom +music +must +mutual +myself +mystery +myth +naive +name +napkin +narrow +nasty +nation +nature +near +neck +need +negative +neglect +neither +nephew +nerve +nest +net +network +neutral +never +news +next +nice +night +noble +noise +nominee +noodle +normal +north +nose +notable +note +nothing +notice +novel +now +nuclear +number +nurse +nut +oak +obey +object +oblige +obscure +observe +obtain +obvious +occur +ocean +october +odor +off +offer +office +often +oil +okay +old +olive +olympic +omit +once +one +onion +online +only +open +opera +opinion +oppose +option +orange +orbit +orchard +order +ordinary +organ +orient +original +orphan +ostrich +other +outdoor +outer +output +outside +oval +oven +over +own +owner +oxygen +oyster +ozone +pact +paddle +page +pair +palace +palm +panda +panel +panic +panther +paper +parade +parent +park +parrot +party +pass +patch +path +patient +patrol +pattern +pause +pave +payment +peace +peanut +pear +peasant +pelican +pen +penalty +pencil +people +pepper +perfect +permit +person +pet +phone +photo +phrase +physical +piano +picnic +picture +piece +pig +pigeon +pill +pilot +pink +pioneer +pipe +pistol +pitch +pizza +place +planet +plastic +plate +play +please +pledge +pluck +plug +plunge +poem +poet +point +polar +pole +police +pond +pony +pool +popular +portion +position +possible +post +potato +pottery +poverty +powder +power +practice +praise +predict +prefer +prepare +present +pretty +prevent +price +pride +primary +print +priority +prison +private +prize +problem +process +produce +profit +program +project +promote +proof +property +prosper +protect +proud +provide +public +pudding +pull +pulp +pulse +pumpkin +punch +pupil +puppy +purchase +purity +purpose +purse +push +put +puzzle +pyramid +quality +quantum +quarter +question +quick +quit +quiz +quote +rabbit +raccoon +race +rack +radar +radio +rail +rain +raise +rally +ramp +ranch +random +range +rapid +rare +rate +rather +raven +raw +razor +ready +real +reason +rebel +rebuild +recall +receive +recipe +record +recycle +reduce +reflect +reform +refuse +region +regret +regular +reject +relax +release +relief +rely +remain +remember +remind +remove +render +renew +rent +reopen +repair +repeat +replace +report +require +rescue +resemble +resist +resource +response +result +retire +retreat +return +reunion +reveal +review +reward +rhythm +rib +ribbon +rice +rich +ride +ridge +rifle +right +rigid +ring +riot +ripple +risk +ritual +rival +river +road +roast +robot +robust +rocket +romance +roof +rookie +room +rose +rotate +rough +round +route +royal +rubber +rude +rug +rule +run +runway +rural +sad +saddle +sadness +safe +sail +salad +salmon +salon +salt +salute +same +sample +sand +satisfy +satoshi +sauce +sausage +save +say +scale +scan +scare +scatter +scene +scheme +school +science +scissors +scorpion +scout +scrap +screen +script +scrub +sea +search +season +seat +second +secret +section +security +seed +seek +segment +select +sell +seminar +senior +sense +sentence +series +service +session +settle +setup +seven +shadow +shaft +shallow +share +shed +shell +sheriff +shield +shift +shine +ship +shiver +shock +shoe +shoot +shop +short +shoulder +shove +shrimp +shrug +shuffle +shy +sibling +sick +side +siege +sight +sign +silent +silk +silly +silver +similar +simple +since +sing +siren +sister +situate +six +size +skate +sketch +ski +skill +skin +skirt +skull +slab +slam +sleep +slender +slice +slide +slight +slim +slogan +slot +slow +slush +small +smart +smile +smoke +smooth +snack +snake +snap +sniff +snow +soap +soccer +social +sock +soda +soft +solar +soldier +solid +solution +solve +someone +song +soon +sorry +sort +soul +sound +soup +source +south +space +spare +spatial +spawn +speak +special +speed +spell +spend +sphere +spice +spider +spike +spin +spirit +split +spoil +sponsor +spoon +sport +spot +spray +spread +spring +spy +square +squeeze +squirrel +stable +stadium +staff +stage +stairs +stamp +stand +start +state +stay +steak +steel +stem +step +stereo +stick +still +sting +stock +stomach +stone +stool +story +stove +strategy +street +strike +strong +struggle +student +stuff +stumble +style +subject +submit +subway +success +such +sudden +suffer +sugar +suggest +suit +summer +sun +sunny +sunset +super +supply +supreme +sure +surface +surge +surprise +surround +survey +suspect +sustain +swallow +swamp +swap +swarm +swear +sweet +swift +swim +swing +switch +sword +symbol +symptom +syrup +system +table +tackle +tag +tail +talent +talk +tank +tape +target +task +taste +tattoo +taxi +teach +team +tell +ten +tenant +tennis +tent +term +test +text +thank +that +theme +then +theory +there +they +thing +this +thought +three +thrive +throw +thumb +thunder +ticket +tide +tiger +tilt +timber +time +tiny +tip +tired +tissue +title +toast +tobacco +today +toddler +toe +together +toilet +token +tomato +tomorrow +tone +tongue +tonight +tool +tooth +top +topic +topple +torch +tornado +tortoise +toss +total +tourist +toward +tower +town +toy +track +trade +traffic +tragic +train +transfer +trap +trash +travel +tray +treat +tree +trend +trial +tribe +trick +trigger +trim +trip +trophy +trouble +truck +true +truly +trumpet +trust +truth +try +tube +tuition +tumble +tuna +tunnel +turkey +turn +turtle +twelve +twenty +twice +twin +twist +two +type +typical +ugly +umbrella +unable +unaware +uncle +uncover +under +undo +unfair +unfold +unhappy +uniform +unique +unit +universe +unknown +unlock +until +unusual +unveil +update +upgrade +uphold +upon +upper +upset +urban +urge +usage +use +used +useful +useless +usual +utility +vacant +vacuum +vague +valid +valley +valve +van +vanish +vapor +various +vast +vault +vehicle +velvet +vendor +venture +venue +verb +verify +version +very +vessel +veteran +viable +vibrant +vicious +victory +video +view +village +vintage +violin +virtual +virus +visa +visit +visual +vital +vivid +vocal +voice +void +volcano +volume +vote +voyage +wage +wagon +wait +walk +wall +walnut +want +warfare +warm +warrior +wash +wasp +waste +water +wave +way +wealth +weapon +wear +weasel +weather +web +wedding +weekend +weird +welcome +west +wet +whale +what +wheat +wheel +when +where +whip +whisper +wide +width +wife +wild +will +win +window +wine +wing +wink +winner +winter +wire +wisdom +wise +wish +witness +wolf +woman +wonder +wood +wool +word +work +world +worry +worth +wrap +wreck +wrestle +wrist +write +wrong +yard +year +yellow +you +young +youth +zebra +zero +zone +zoo diff --git a/pybtc/bip39_word_list/french.txt b/pybtc/bip39_word_list/french.txt new file mode 100644 index 0000000..1d74990 --- /dev/null +++ b/pybtc/bip39_word_list/french.txt @@ -0,0 +1,2048 @@ +abaisser +abandon +abdiquer +abeille +abolir +aborder +aboutir +aboyer +abrasif +abreuver +abriter +abroger +abrupt +absence +absolu +absurde +abusif +abyssal +académie +acajou +acarien +accabler +accepter +acclamer +accolade +accroche +accuser +acerbe +achat +acheter +aciduler +acier +acompte +acquérir +acronyme +acteur +actif +actuel +adepte +adéquat +adhésif +adjectif +adjuger +admettre +admirer +adopter +adorer +adoucir +adresse +adroit +adulte +adverbe +aérer +aéronef +affaire +affecter +affiche +affreux +affubler +agacer +agencer +agile +agiter +agrafer +agréable +agrume +aider +aiguille +ailier +aimable +aisance +ajouter +ajuster +alarmer +alchimie +alerte +algèbre +algue +aliéner +aliment +alléger +alliage +allouer +allumer +alourdir +alpaga +altesse +alvéole +amateur +ambigu +ambre +aménager +amertume +amidon +amiral +amorcer +amour +amovible +amphibie +ampleur +amusant +analyse +anaphore +anarchie +anatomie +ancien +anéantir +angle +angoisse +anguleux +animal +annexer +annonce +annuel +anodin +anomalie +anonyme +anormal +antenne +antidote +anxieux +apaiser +apéritif +aplanir +apologie +appareil +appeler +apporter +appuyer +aquarium +aqueduc +arbitre +arbuste +ardeur +ardoise +argent +arlequin +armature +armement +armoire +armure +arpenter +arracher +arriver +arroser +arsenic +artériel +article +aspect +asphalte +aspirer +assaut +asservir +assiette +associer +assurer +asticot +astre +astuce +atelier +atome +atrium +atroce +attaque +attentif +attirer +attraper +aubaine +auberge +audace +audible +augurer +aurore +automne +autruche +avaler +avancer +avarice +avenir +averse +aveugle +aviateur +avide +avion +aviser +avoine +avouer +avril +axial +axiome +badge +bafouer +bagage +baguette +baignade +balancer +balcon +baleine +balisage +bambin +bancaire +bandage +banlieue +bannière +banquier +barbier +baril +baron +barque +barrage +bassin +bastion +bataille +bateau +batterie +baudrier +bavarder +belette +bélier +belote +bénéfice +berceau +berger +berline +bermuda +besace +besogne +bétail +beurre +biberon +bicycle +bidule +bijou +bilan +bilingue +billard +binaire +biologie +biopsie +biotype +biscuit +bison +bistouri +bitume +bizarre +blafard +blague +blanchir +blessant +blinder +blond +bloquer +blouson +bobard +bobine +boire +boiser +bolide +bonbon +bondir +bonheur +bonifier +bonus +bordure +borne +botte +boucle +boueux +bougie +boulon +bouquin +bourse +boussole +boutique +boxeur +branche +brasier +brave +brebis +brèche +breuvage +bricoler +brigade +brillant +brioche +brique +brochure +broder +bronzer +brousse +broyeur +brume +brusque +brutal +bruyant +buffle +buisson +bulletin +bureau +burin +bustier +butiner +butoir +buvable +buvette +cabanon +cabine +cachette +cadeau +cadre +caféine +caillou +caisson +calculer +calepin +calibre +calmer +calomnie +calvaire +camarade +caméra +camion +campagne +canal +caneton +canon +cantine +canular +capable +caporal +caprice +capsule +capter +capuche +carabine +carbone +caresser +caribou +carnage +carotte +carreau +carton +cascade +casier +casque +cassure +causer +caution +cavalier +caverne +caviar +cédille +ceinture +céleste +cellule +cendrier +censurer +central +cercle +cérébral +cerise +cerner +cerveau +cesser +chagrin +chaise +chaleur +chambre +chance +chapitre +charbon +chasseur +chaton +chausson +chavirer +chemise +chenille +chéquier +chercher +cheval +chien +chiffre +chignon +chimère +chiot +chlorure +chocolat +choisir +chose +chouette +chrome +chute +cigare +cigogne +cimenter +cinéma +cintrer +circuler +cirer +cirque +citerne +citoyen +citron +civil +clairon +clameur +claquer +classe +clavier +client +cligner +climat +clivage +cloche +clonage +cloporte +cobalt +cobra +cocasse +cocotier +coder +codifier +coffre +cogner +cohésion +coiffer +coincer +colère +colibri +colline +colmater +colonel +combat +comédie +commande +compact +concert +conduire +confier +congeler +connoter +consonne +contact +convexe +copain +copie +corail +corbeau +cordage +corniche +corpus +correct +cortège +cosmique +costume +coton +coude +coupure +courage +couteau +couvrir +coyote +crabe +crainte +cravate +crayon +créature +créditer +crémeux +creuser +crevette +cribler +crier +cristal +critère +croire +croquer +crotale +crucial +cruel +crypter +cubique +cueillir +cuillère +cuisine +cuivre +culminer +cultiver +cumuler +cupide +curatif +curseur +cyanure +cycle +cylindre +cynique +daigner +damier +danger +danseur +dauphin +débattre +débiter +déborder +débrider +débutant +décaler +décembre +déchirer +décider +déclarer +décorer +décrire +décupler +dédale +déductif +déesse +défensif +défiler +défrayer +dégager +dégivrer +déglutir +dégrafer +déjeuner +délice +déloger +demander +demeurer +démolir +dénicher +dénouer +dentelle +dénuder +départ +dépenser +déphaser +déplacer +déposer +déranger +dérober +désastre +descente +désert +désigner +désobéir +dessiner +destrier +détacher +détester +détourer +détresse +devancer +devenir +deviner +devoir +diable +dialogue +diamant +dicter +différer +digérer +digital +digne +diluer +dimanche +diminuer +dioxyde +directif +diriger +discuter +disposer +dissiper +distance +divertir +diviser +docile +docteur +dogme +doigt +domaine +domicile +dompter +donateur +donjon +donner +dopamine +dortoir +dorure +dosage +doseur +dossier +dotation +douanier +double +douceur +douter +doyen +dragon +draper +dresser +dribbler +droiture +duperie +duplexe +durable +durcir +dynastie +éblouir +écarter +écharpe +échelle +éclairer +éclipse +éclore +écluse +école +économie +écorce +écouter +écraser +écrémer +écrivain +écrou +écume +écureuil +édifier +éduquer +effacer +effectif +effigie +effort +effrayer +effusion +égaliser +égarer +éjecter +élaborer +élargir +électron +élégant +éléphant +élève +éligible +élitisme +éloge +élucider +éluder +emballer +embellir +embryon +émeraude +émission +emmener +émotion +émouvoir +empereur +employer +emporter +emprise +émulsion +encadrer +enchère +enclave +encoche +endiguer +endosser +endroit +enduire +énergie +enfance +enfermer +enfouir +engager +engin +englober +énigme +enjamber +enjeu +enlever +ennemi +ennuyeux +enrichir +enrobage +enseigne +entasser +entendre +entier +entourer +entraver +énumérer +envahir +enviable +envoyer +enzyme +éolien +épaissir +épargne +épatant +épaule +épicerie +épidémie +épier +épilogue +épine +épisode +épitaphe +époque +épreuve +éprouver +épuisant +équerre +équipe +ériger +érosion +erreur +éruption +escalier +espadon +espèce +espiègle +espoir +esprit +esquiver +essayer +essence +essieu +essorer +estime +estomac +estrade +étagère +étaler +étanche +étatique +éteindre +étendoir +éternel +éthanol +éthique +ethnie +étirer +étoffer +étoile +étonnant +étourdir +étrange +étroit +étude +euphorie +évaluer +évasion +éventail +évidence +éviter +évolutif +évoquer +exact +exagérer +exaucer +exceller +excitant +exclusif +excuse +exécuter +exemple +exercer +exhaler +exhorter +exigence +exiler +exister +exotique +expédier +explorer +exposer +exprimer +exquis +extensif +extraire +exulter +fable +fabuleux +facette +facile +facture +faiblir +falaise +fameux +famille +farceur +farfelu +farine +farouche +fasciner +fatal +fatigue +faucon +fautif +faveur +favori +fébrile +féconder +fédérer +félin +femme +fémur +fendoir +féodal +fermer +féroce +ferveur +festival +feuille +feutre +février +fiasco +ficeler +fictif +fidèle +figure +filature +filetage +filière +filleul +filmer +filou +filtrer +financer +finir +fiole +firme +fissure +fixer +flairer +flamme +flasque +flatteur +fléau +flèche +fleur +flexion +flocon +flore +fluctuer +fluide +fluvial +folie +fonderie +fongible +fontaine +forcer +forgeron +formuler +fortune +fossile +foudre +fougère +fouiller +foulure +fourmi +fragile +fraise +franchir +frapper +frayeur +frégate +freiner +frelon +frémir +frénésie +frère +friable +friction +frisson +frivole +froid +fromage +frontal +frotter +fruit +fugitif +fuite +fureur +furieux +furtif +fusion +futur +gagner +galaxie +galerie +gambader +garantir +gardien +garnir +garrigue +gazelle +gazon +géant +gélatine +gélule +gendarme +général +génie +genou +gentil +géologie +géomètre +géranium +germe +gestuel +geyser +gibier +gicler +girafe +givre +glace +glaive +glisser +globe +gloire +glorieux +golfeur +gomme +gonfler +gorge +gorille +goudron +gouffre +goulot +goupille +gourmand +goutte +graduel +graffiti +graine +grand +grappin +gratuit +gravir +grenat +griffure +griller +grimper +grogner +gronder +grotte +groupe +gruger +grutier +gruyère +guépard +guerrier +guide +guimauve +guitare +gustatif +gymnaste +gyrostat +habitude +hachoir +halte +hameau +hangar +hanneton +haricot +harmonie +harpon +hasard +hélium +hématome +herbe +hérisson +hermine +héron +hésiter +heureux +hiberner +hibou +hilarant +histoire +hiver +homard +hommage +homogène +honneur +honorer +honteux +horde +horizon +horloge +hormone +horrible +houleux +housse +hublot +huileux +humain +humble +humide +humour +hurler +hydromel +hygiène +hymne +hypnose +idylle +ignorer +iguane +illicite +illusion +image +imbiber +imiter +immense +immobile +immuable +impact +impérial +implorer +imposer +imprimer +imputer +incarner +incendie +incident +incliner +incolore +indexer +indice +inductif +inédit +ineptie +inexact +infini +infliger +informer +infusion +ingérer +inhaler +inhiber +injecter +injure +innocent +inoculer +inonder +inscrire +insecte +insigne +insolite +inspirer +instinct +insulter +intact +intense +intime +intrigue +intuitif +inutile +invasion +inventer +inviter +invoquer +ironique +irradier +irréel +irriter +isoler +ivoire +ivresse +jaguar +jaillir +jambe +janvier +jardin +jauger +jaune +javelot +jetable +jeton +jeudi +jeunesse +joindre +joncher +jongler +joueur +jouissif +journal +jovial +joyau +joyeux +jubiler +jugement +junior +jupon +juriste +justice +juteux +juvénile +kayak +kimono +kiosque +label +labial +labourer +lacérer +lactose +lagune +laine +laisser +laitier +lambeau +lamelle +lampe +lanceur +langage +lanterne +lapin +largeur +larme +laurier +lavabo +lavoir +lecture +légal +léger +légume +lessive +lettre +levier +lexique +lézard +liasse +libérer +libre +licence +licorne +liège +lièvre +ligature +ligoter +ligue +limer +limite +limonade +limpide +linéaire +lingot +lionceau +liquide +lisière +lister +lithium +litige +littoral +livreur +logique +lointain +loisir +lombric +loterie +louer +lourd +loutre +louve +loyal +lubie +lucide +lucratif +lueur +lugubre +luisant +lumière +lunaire +lundi +luron +lutter +luxueux +machine +magasin +magenta +magique +maigre +maillon +maintien +mairie +maison +majorer +malaxer +maléfice +malheur +malice +mallette +mammouth +mandater +maniable +manquant +manteau +manuel +marathon +marbre +marchand +mardi +maritime +marqueur +marron +marteler +mascotte +massif +matériel +matière +matraque +maudire +maussade +mauve +maximal +méchant +méconnu +médaille +médecin +méditer +méduse +meilleur +mélange +mélodie +membre +mémoire +menacer +mener +menhir +mensonge +mentor +mercredi +mérite +merle +messager +mesure +métal +météore +méthode +métier +meuble +miauler +microbe +miette +mignon +migrer +milieu +million +mimique +mince +minéral +minimal +minorer +minute +miracle +miroiter +missile +mixte +mobile +moderne +moelleux +mondial +moniteur +monnaie +monotone +monstre +montagne +monument +moqueur +morceau +morsure +mortier +moteur +motif +mouche +moufle +moulin +mousson +mouton +mouvant +multiple +munition +muraille +murène +murmure +muscle +muséum +musicien +mutation +muter +mutuel +myriade +myrtille +mystère +mythique +nageur +nappe +narquois +narrer +natation +nation +nature +naufrage +nautique +navire +nébuleux +nectar +néfaste +négation +négliger +négocier +neige +nerveux +nettoyer +neurone +neutron +neveu +niche +nickel +nitrate +niveau +noble +nocif +nocturne +noirceur +noisette +nomade +nombreux +nommer +normatif +notable +notifier +notoire +nourrir +nouveau +novateur +novembre +novice +nuage +nuancer +nuire +nuisible +numéro +nuptial +nuque +nutritif +obéir +objectif +obliger +obscur +observer +obstacle +obtenir +obturer +occasion +occuper +océan +octobre +octroyer +octupler +oculaire +odeur +odorant +offenser +officier +offrir +ogive +oiseau +oisillon +olfactif +olivier +ombrage +omettre +onctueux +onduler +onéreux +onirique +opale +opaque +opérer +opinion +opportun +opprimer +opter +optique +orageux +orange +orbite +ordonner +oreille +organe +orgueil +orifice +ornement +orque +ortie +osciller +osmose +ossature +otarie +ouragan +ourson +outil +outrager +ouvrage +ovation +oxyde +oxygène +ozone +paisible +palace +palmarès +palourde +palper +panache +panda +pangolin +paniquer +panneau +panorama +pantalon +papaye +papier +papoter +papyrus +paradoxe +parcelle +paresse +parfumer +parler +parole +parrain +parsemer +partager +parure +parvenir +passion +pastèque +paternel +patience +patron +pavillon +pavoiser +payer +paysage +peigne +peintre +pelage +pélican +pelle +pelouse +peluche +pendule +pénétrer +pénible +pensif +pénurie +pépite +péplum +perdrix +perforer +période +permuter +perplexe +persil +perte +peser +pétale +petit +pétrir +peuple +pharaon +phobie +phoque +photon +phrase +physique +piano +pictural +pièce +pierre +pieuvre +pilote +pinceau +pipette +piquer +pirogue +piscine +piston +pivoter +pixel +pizza +placard +plafond +plaisir +planer +plaque +plastron +plateau +pleurer +plexus +pliage +plomb +plonger +pluie +plumage +pochette +poésie +poète +pointe +poirier +poisson +poivre +polaire +policier +pollen +polygone +pommade +pompier +ponctuel +pondérer +poney +portique +position +posséder +posture +potager +poteau +potion +pouce +poulain +poumon +pourpre +poussin +pouvoir +prairie +pratique +précieux +prédire +préfixe +prélude +prénom +présence +prétexte +prévoir +primitif +prince +prison +priver +problème +procéder +prodige +profond +progrès +proie +projeter +prologue +promener +propre +prospère +protéger +prouesse +proverbe +prudence +pruneau +psychose +public +puceron +puiser +pulpe +pulsar +punaise +punitif +pupitre +purifier +puzzle +pyramide +quasar +querelle +question +quiétude +quitter +quotient +racine +raconter +radieux +ragondin +raideur +raisin +ralentir +rallonge +ramasser +rapide +rasage +ratisser +ravager +ravin +rayonner +réactif +réagir +réaliser +réanimer +recevoir +réciter +réclamer +récolter +recruter +reculer +recycler +rédiger +redouter +refaire +réflexe +réformer +refrain +refuge +régalien +région +réglage +régulier +réitérer +rejeter +rejouer +relatif +relever +relief +remarque +remède +remise +remonter +remplir +remuer +renard +renfort +renifler +renoncer +rentrer +renvoi +replier +reporter +reprise +reptile +requin +réserve +résineux +résoudre +respect +rester +résultat +rétablir +retenir +réticule +retomber +retracer +réunion +réussir +revanche +revivre +révolte +révulsif +richesse +rideau +rieur +rigide +rigoler +rincer +riposter +risible +risque +rituel +rival +rivière +rocheux +romance +rompre +ronce +rondin +roseau +rosier +rotatif +rotor +rotule +rouge +rouille +rouleau +routine +royaume +ruban +rubis +ruche +ruelle +rugueux +ruiner +ruisseau +ruser +rustique +rythme +sabler +saboter +sabre +sacoche +safari +sagesse +saisir +salade +salive +salon +saluer +samedi +sanction +sanglier +sarcasme +sardine +saturer +saugrenu +saumon +sauter +sauvage +savant +savonner +scalpel +scandale +scélérat +scénario +sceptre +schéma +science +scinder +score +scrutin +sculpter +séance +sécable +sécher +secouer +sécréter +sédatif +séduire +seigneur +séjour +sélectif +semaine +sembler +semence +séminal +sénateur +sensible +sentence +séparer +séquence +serein +sergent +sérieux +serrure +sérum +service +sésame +sévir +sevrage +sextuple +sidéral +siècle +siéger +siffler +sigle +signal +silence +silicium +simple +sincère +sinistre +siphon +sirop +sismique +situer +skier +social +socle +sodium +soigneux +soldat +soleil +solitude +soluble +sombre +sommeil +somnoler +sonde +songeur +sonnette +sonore +sorcier +sortir +sosie +sottise +soucieux +soudure +souffle +soulever +soupape +source +soutirer +souvenir +spacieux +spatial +spécial +sphère +spiral +stable +station +sternum +stimulus +stipuler +strict +studieux +stupeur +styliste +sublime +substrat +subtil +subvenir +succès +sucre +suffixe +suggérer +suiveur +sulfate +superbe +supplier +surface +suricate +surmener +surprise +sursaut +survie +suspect +syllabe +symbole +symétrie +synapse +syntaxe +système +tabac +tablier +tactile +tailler +talent +talisman +talonner +tambour +tamiser +tangible +tapis +taquiner +tarder +tarif +tartine +tasse +tatami +tatouage +taupe +taureau +taxer +témoin +temporel +tenaille +tendre +teneur +tenir +tension +terminer +terne +terrible +tétine +texte +thème +théorie +thérapie +thorax +tibia +tiède +timide +tirelire +tiroir +tissu +titane +titre +tituber +toboggan +tolérant +tomate +tonique +tonneau +toponyme +torche +tordre +tornade +torpille +torrent +torse +tortue +totem +toucher +tournage +tousser +toxine +traction +trafic +tragique +trahir +train +trancher +travail +trèfle +tremper +trésor +treuil +triage +tribunal +tricoter +trilogie +triomphe +tripler +triturer +trivial +trombone +tronc +tropical +troupeau +tuile +tulipe +tumulte +tunnel +turbine +tuteur +tutoyer +tuyau +tympan +typhon +typique +tyran +ubuesque +ultime +ultrason +unanime +unifier +union +unique +unitaire +univers +uranium +urbain +urticant +usage +usine +usuel +usure +utile +utopie +vacarme +vaccin +vagabond +vague +vaillant +vaincre +vaisseau +valable +valise +vallon +valve +vampire +vanille +vapeur +varier +vaseux +vassal +vaste +vecteur +vedette +végétal +véhicule +veinard +véloce +vendredi +vénérer +venger +venimeux +ventouse +verdure +vérin +vernir +verrou +verser +vertu +veston +vétéran +vétuste +vexant +vexer +viaduc +viande +victoire +vidange +vidéo +vignette +vigueur +vilain +village +vinaigre +violon +vipère +virement +virtuose +virus +visage +viseur +vision +visqueux +visuel +vital +vitesse +viticole +vitrine +vivace +vivipare +vocation +voguer +voile +voisin +voiture +volaille +volcan +voltiger +volume +vorace +vortex +voter +vouloir +voyage +voyelle +wagon +xénon +yacht +zèbre +zénith +zeste +zoologie diff --git a/pybtc/bip39_word_list/italian.txt b/pybtc/bip39_word_list/italian.txt new file mode 100644 index 0000000..c47370f --- /dev/null +++ b/pybtc/bip39_word_list/italian.txt @@ -0,0 +1,2048 @@ +abaco +abbaglio +abbinato +abete +abisso +abolire +abrasivo +abrogato +accadere +accenno +accusato +acetone +achille +acido +acqua +acre +acrilico +acrobata +acuto +adagio +addebito +addome +adeguato +aderire +adipe +adottare +adulare +affabile +affetto +affisso +affranto +aforisma +afoso +africano +agave +agente +agevole +aggancio +agire +agitare +agonismo +agricolo +agrumeto +aguzzo +alabarda +alato +albatro +alberato +albo +albume +alce +alcolico +alettone +alfa +algebra +aliante +alibi +alimento +allagato +allegro +allievo +allodola +allusivo +almeno +alogeno +alpaca +alpestre +altalena +alterno +alticcio +altrove +alunno +alveolo +alzare +amalgama +amanita +amarena +ambito +ambrato +ameba +america +ametista +amico +ammasso +ammenda +ammirare +ammonito +amore +ampio +ampliare +amuleto +anacardo +anagrafe +analista +anarchia +anatra +anca +ancella +ancora +andare +andrea +anello +angelo +angolare +angusto +anima +annegare +annidato +anno +annuncio +anonimo +anticipo +anzi +apatico +apertura +apode +apparire +appetito +appoggio +approdo +appunto +aprile +arabica +arachide +aragosta +araldica +arancio +aratura +arazzo +arbitro +archivio +ardito +arenile +argento +argine +arguto +aria +armonia +arnese +arredato +arringa +arrosto +arsenico +arso +artefice +arzillo +asciutto +ascolto +asepsi +asettico +asfalto +asino +asola +aspirato +aspro +assaggio +asse +assoluto +assurdo +asta +astenuto +astice +astratto +atavico +ateismo +atomico +atono +attesa +attivare +attorno +attrito +attuale +ausilio +austria +autista +autonomo +autunno +avanzato +avere +avvenire +avviso +avvolgere +azione +azoto +azzimo +azzurro +babele +baccano +bacino +baco +badessa +badilata +bagnato +baita +balcone +baldo +balena +ballata +balzano +bambino +bandire +baraonda +barbaro +barca +baritono +barlume +barocco +basilico +basso +batosta +battuto +baule +bava +bavosa +becco +beffa +belgio +belva +benda +benevole +benigno +benzina +bere +berlina +beta +bibita +bici +bidone +bifido +biga +bilancia +bimbo +binocolo +biologo +bipede +bipolare +birbante +birra +biscotto +bisesto +bisnonno +bisonte +bisturi +bizzarro +blando +blatta +bollito +bonifico +bordo +bosco +botanico +bottino +bozzolo +braccio +bradipo +brama +branca +bravura +bretella +brevetto +brezza +briglia +brillante +brindare +broccolo +brodo +bronzina +brullo +bruno +bubbone +buca +budino +buffone +buio +bulbo +buono +burlone +burrasca +bussola +busta +cadetto +caduco +calamaro +calcolo +calesse +calibro +calmo +caloria +cambusa +camerata +camicia +cammino +camola +campale +canapa +candela +cane +canino +canotto +cantina +capace +capello +capitolo +capogiro +cappero +capra +capsula +carapace +carcassa +cardo +carisma +carovana +carretto +cartolina +casaccio +cascata +caserma +caso +cassone +castello +casuale +catasta +catena +catrame +cauto +cavillo +cedibile +cedrata +cefalo +celebre +cellulare +cena +cenone +centesimo +ceramica +cercare +certo +cerume +cervello +cesoia +cespo +ceto +chela +chiaro +chicca +chiedere +chimera +china +chirurgo +chitarra +ciao +ciclismo +cifrare +cigno +cilindro +ciottolo +circa +cirrosi +citrico +cittadino +ciuffo +civetta +civile +classico +clinica +cloro +cocco +codardo +codice +coerente +cognome +collare +colmato +colore +colposo +coltivato +colza +coma +cometa +commando +comodo +computer +comune +conciso +condurre +conferma +congelare +coniuge +connesso +conoscere +consumo +continuo +convegno +coperto +copione +coppia +copricapo +corazza +cordata +coricato +cornice +corolla +corpo +corredo +corsia +cortese +cosmico +costante +cottura +covato +cratere +cravatta +creato +credere +cremoso +crescita +creta +criceto +crinale +crisi +critico +croce +cronaca +crostata +cruciale +crusca +cucire +cuculo +cugino +cullato +cupola +curatore +cursore +curvo +cuscino +custode +dado +daino +dalmata +damerino +daniela +dannoso +danzare +datato +davanti +davvero +debutto +decennio +deciso +declino +decollo +decreto +dedicato +definito +deforme +degno +delegare +delfino +delirio +delta +demenza +denotato +dentro +deposito +derapata +derivare +deroga +descritto +deserto +desiderio +desumere +detersivo +devoto +diametro +dicembre +diedro +difeso +diffuso +digerire +digitale +diluvio +dinamico +dinnanzi +dipinto +diploma +dipolo +diradare +dire +dirotto +dirupo +disagio +discreto +disfare +disgelo +disposto +distanza +disumano +dito +divano +divelto +dividere +divorato +doblone +docente +doganale +dogma +dolce +domato +domenica +dominare +dondolo +dono +dormire +dote +dottore +dovuto +dozzina +drago +druido +dubbio +dubitare +ducale +duna +duomo +duplice +duraturo +ebano +eccesso +ecco +eclissi +economia +edera +edicola +edile +editoria +educare +egemonia +egli +egoismo +egregio +elaborato +elargire +elegante +elencato +eletto +elevare +elfico +elica +elmo +elsa +eluso +emanato +emblema +emesso +emiro +emotivo +emozione +empirico +emulo +endemico +enduro +energia +enfasi +enoteca +entrare +enzima +epatite +epilogo +episodio +epocale +eppure +equatore +erario +erba +erboso +erede +eremita +erigere +ermetico +eroe +erosivo +errante +esagono +esame +esanime +esaudire +esca +esempio +esercito +esibito +esigente +esistere +esito +esofago +esortato +esoso +espanso +espresso +essenza +esso +esteso +estimare +estonia +estroso +esultare +etilico +etnico +etrusco +etto +euclideo +europa +evaso +evidenza +evitato +evoluto +evviva +fabbrica +faccenda +fachiro +falco +famiglia +fanale +fanfara +fango +fantasma +fare +farfalla +farinoso +farmaco +fascia +fastoso +fasullo +faticare +fato +favoloso +febbre +fecola +fede +fegato +felpa +feltro +femmina +fendere +fenomeno +fermento +ferro +fertile +fessura +festivo +fetta +feudo +fiaba +fiducia +fifa +figurato +filo +finanza +finestra +finire +fiore +fiscale +fisico +fiume +flacone +flamenco +flebo +flemma +florido +fluente +fluoro +fobico +focaccia +focoso +foderato +foglio +folata +folclore +folgore +fondente +fonetico +fonia +fontana +forbito +forchetta +foresta +formica +fornaio +foro +fortezza +forzare +fosfato +fosso +fracasso +frana +frassino +fratello +freccetta +frenata +fresco +frigo +frollino +fronde +frugale +frutta +fucilata +fucsia +fuggente +fulmine +fulvo +fumante +fumetto +fumoso +fune +funzione +fuoco +furbo +furgone +furore +fuso +futile +gabbiano +gaffe +galateo +gallina +galoppo +gambero +gamma +garanzia +garbo +garofano +garzone +gasdotto +gasolio +gastrico +gatto +gaudio +gazebo +gazzella +geco +gelatina +gelso +gemello +gemmato +gene +genitore +gennaio +genotipo +gergo +ghepardo +ghiaccio +ghisa +giallo +gilda +ginepro +giocare +gioiello +giorno +giove +girato +girone +gittata +giudizio +giurato +giusto +globulo +glutine +gnomo +gobba +golf +gomito +gommone +gonfio +gonna +governo +gracile +grado +grafico +grammo +grande +grattare +gravoso +grazia +greca +gregge +grifone +grigio +grinza +grotta +gruppo +guadagno +guaio +guanto +guardare +gufo +guidare +ibernato +icona +identico +idillio +idolo +idra +idrico +idrogeno +igiene +ignaro +ignorato +ilare +illeso +illogico +illudere +imballo +imbevuto +imbocco +imbuto +immane +immerso +immolato +impacco +impeto +impiego +importo +impronta +inalare +inarcare +inattivo +incanto +incendio +inchino +incisivo +incluso +incontro +incrocio +incubo +indagine +india +indole +inedito +infatti +infilare +inflitto +ingaggio +ingegno +inglese +ingordo +ingrosso +innesco +inodore +inoltrare +inondato +insano +insetto +insieme +insonnia +insulina +intasato +intero +intonaco +intuito +inumidire +invalido +invece +invito +iperbole +ipnotico +ipotesi +ippica +iride +irlanda +ironico +irrigato +irrorare +isolato +isotopo +isterico +istituto +istrice +italia +iterare +labbro +labirinto +lacca +lacerato +lacrima +lacuna +laddove +lago +lampo +lancetta +lanterna +lardoso +larga +laringe +lastra +latenza +latino +lattuga +lavagna +lavoro +legale +leggero +lembo +lentezza +lenza +leone +lepre +lesivo +lessato +lesto +letterale +leva +levigato +libero +lido +lievito +lilla +limatura +limitare +limpido +lineare +lingua +liquido +lira +lirica +lisca +lite +litigio +livrea +locanda +lode +logica +lombare +londra +longevo +loquace +lorenzo +loto +lotteria +luce +lucidato +lumaca +luminoso +lungo +lupo +luppolo +lusinga +lusso +lutto +macabro +macchina +macero +macinato +madama +magico +maglia +magnete +magro +maiolica +malafede +malgrado +malinteso +malsano +malto +malumore +mana +mancia +mandorla +mangiare +manifesto +mannaro +manovra +mansarda +mantide +manubrio +mappa +maratona +marcire +maretta +marmo +marsupio +maschera +massaia +mastino +materasso +matricola +mattone +maturo +mazurca +meandro +meccanico +mecenate +medesimo +meditare +mega +melassa +melis +melodia +meninge +meno +mensola +mercurio +merenda +merlo +meschino +mese +messere +mestolo +metallo +metodo +mettere +miagolare +mica +micelio +michele +microbo +midollo +miele +migliore +milano +milite +mimosa +minerale +mini +minore +mirino +mirtillo +miscela +missiva +misto +misurare +mitezza +mitigare +mitra +mittente +mnemonico +modello +modifica +modulo +mogano +mogio +mole +molosso +monastero +monco +mondina +monetario +monile +monotono +monsone +montato +monviso +mora +mordere +morsicato +mostro +motivato +motosega +motto +movenza +movimento +mozzo +mucca +mucosa +muffa +mughetto +mugnaio +mulatto +mulinello +multiplo +mummia +munto +muovere +murale +musa +muscolo +musica +mutevole +muto +nababbo +nafta +nanometro +narciso +narice +narrato +nascere +nastrare +naturale +nautica +naviglio +nebulosa +necrosi +negativo +negozio +nemmeno +neofita +neretto +nervo +nessuno +nettuno +neutrale +neve +nevrotico +nicchia +ninfa +nitido +nobile +nocivo +nodo +nome +nomina +nordico +normale +norvegese +nostrano +notare +notizia +notturno +novella +nucleo +nulla +numero +nuovo +nutrire +nuvola +nuziale +oasi +obbedire +obbligo +obelisco +oblio +obolo +obsoleto +occasione +occhio +occidente +occorrere +occultare +ocra +oculato +odierno +odorare +offerta +offrire +offuscato +oggetto +oggi +ognuno +olandese +olfatto +oliato +oliva +ologramma +oltre +omaggio +ombelico +ombra +omega +omissione +ondoso +onere +onice +onnivoro +onorevole +onta +operato +opinione +opposto +oracolo +orafo +ordine +orecchino +orefice +orfano +organico +origine +orizzonte +orma +ormeggio +ornativo +orologio +orrendo +orribile +ortensia +ortica +orzata +orzo +osare +oscurare +osmosi +ospedale +ospite +ossa +ossidare +ostacolo +oste +otite +otre +ottagono +ottimo +ottobre +ovale +ovest +ovino +oviparo +ovocito +ovunque +ovviare +ozio +pacchetto +pace +pacifico +padella +padrone +paese +paga +pagina +palazzina +palesare +pallido +palo +palude +pandoro +pannello +paolo +paonazzo +paprica +parabola +parcella +parere +pargolo +pari +parlato +parola +partire +parvenza +parziale +passivo +pasticca +patacca +patologia +pattume +pavone +peccato +pedalare +pedonale +peggio +peloso +penare +pendice +penisola +pennuto +penombra +pensare +pentola +pepe +pepita +perbene +percorso +perdonato +perforare +pergamena +periodo +permesso +perno +perplesso +persuaso +pertugio +pervaso +pesatore +pesista +peso +pestifero +petalo +pettine +petulante +pezzo +piacere +pianta +piattino +piccino +picozza +piega +pietra +piffero +pigiama +pigolio +pigro +pila +pilifero +pillola +pilota +pimpante +pineta +pinna +pinolo +pioggia +piombo +piramide +piretico +pirite +pirolisi +pitone +pizzico +placebo +planare +plasma +platano +plenario +pochezza +poderoso +podismo +poesia +poggiare +polenta +poligono +pollice +polmonite +polpetta +polso +poltrona +polvere +pomice +pomodoro +ponte +popoloso +porfido +poroso +porpora +porre +portata +posa +positivo +possesso +postulato +potassio +potere +pranzo +prassi +pratica +precluso +predica +prefisso +pregiato +prelievo +premere +prenotare +preparato +presenza +pretesto +prevalso +prima +principe +privato +problema +procura +produrre +profumo +progetto +prolunga +promessa +pronome +proposta +proroga +proteso +prova +prudente +prugna +prurito +psiche +pubblico +pudica +pugilato +pugno +pulce +pulito +pulsante +puntare +pupazzo +pupilla +puro +quadro +qualcosa +quasi +querela +quota +raccolto +raddoppio +radicale +radunato +raffica +ragazzo +ragione +ragno +ramarro +ramingo +ramo +randagio +rantolare +rapato +rapina +rappreso +rasatura +raschiato +rasente +rassegna +rastrello +rata +ravveduto +reale +recepire +recinto +recluta +recondito +recupero +reddito +redimere +regalato +registro +regola +regresso +relazione +remare +remoto +renna +replica +reprimere +reputare +resa +residente +responso +restauro +rete +retina +retorica +rettifica +revocato +riassunto +ribadire +ribelle +ribrezzo +ricarica +ricco +ricevere +riciclato +ricordo +ricreduto +ridicolo +ridurre +rifasare +riflesso +riforma +rifugio +rigare +rigettato +righello +rilassato +rilevato +rimanere +rimbalzo +rimedio +rimorchio +rinascita +rincaro +rinforzo +rinnovo +rinomato +rinsavito +rintocco +rinuncia +rinvenire +riparato +ripetuto +ripieno +riportare +ripresa +ripulire +risata +rischio +riserva +risibile +riso +rispetto +ristoro +risultato +risvolto +ritardo +ritegno +ritmico +ritrovo +riunione +riva +riverso +rivincita +rivolto +rizoma +roba +robotico +robusto +roccia +roco +rodaggio +rodere +roditore +rogito +rollio +romantico +rompere +ronzio +rosolare +rospo +rotante +rotondo +rotula +rovescio +rubizzo +rubrica +ruga +rullino +rumine +rumoroso +ruolo +rupe +russare +rustico +sabato +sabbiare +sabotato +sagoma +salasso +saldatura +salgemma +salivare +salmone +salone +saltare +saluto +salvo +sapere +sapido +saporito +saraceno +sarcasmo +sarto +sassoso +satellite +satira +satollo +saturno +savana +savio +saziato +sbadiglio +sbalzo +sbancato +sbarra +sbattere +sbavare +sbendare +sbirciare +sbloccato +sbocciato +sbrinare +sbruffone +sbuffare +scabroso +scadenza +scala +scambiare +scandalo +scapola +scarso +scatenare +scavato +scelto +scenico +scettro +scheda +schiena +sciarpa +scienza +scindere +scippo +sciroppo +scivolo +sclerare +scodella +scolpito +scomparto +sconforto +scoprire +scorta +scossone +scozzese +scriba +scrollare +scrutinio +scuderia +scultore +scuola +scuro +scusare +sdebitare +sdoganare +seccatura +secondo +sedano +seggiola +segnalato +segregato +seguito +selciato +selettivo +sella +selvaggio +semaforo +sembrare +seme +seminato +sempre +senso +sentire +sepolto +sequenza +serata +serbato +sereno +serio +serpente +serraglio +servire +sestina +setola +settimana +sfacelo +sfaldare +sfamato +sfarzoso +sfaticato +sfera +sfida +sfilato +sfinge +sfocato +sfoderare +sfogo +sfoltire +sforzato +sfratto +sfruttato +sfuggito +sfumare +sfuso +sgabello +sgarbato +sgonfiare +sgorbio +sgrassato +sguardo +sibilo +siccome +sierra +sigla +signore +silenzio +sillaba +simbolo +simpatico +simulato +sinfonia +singolo +sinistro +sino +sintesi +sinusoide +sipario +sisma +sistole +situato +slitta +slogatura +sloveno +smarrito +smemorato +smentito +smeraldo +smilzo +smontare +smottato +smussato +snellire +snervato +snodo +sobbalzo +sobrio +soccorso +sociale +sodale +soffitto +sogno +soldato +solenne +solido +sollazzo +solo +solubile +solvente +somatico +somma +sonda +sonetto +sonnifero +sopire +soppeso +sopra +sorgere +sorpasso +sorriso +sorso +sorteggio +sorvolato +sospiro +sosta +sottile +spada +spalla +spargere +spatola +spavento +spazzola +specie +spedire +spegnere +spelatura +speranza +spessore +spettrale +spezzato +spia +spigoloso +spillato +spinoso +spirale +splendido +sportivo +sposo +spranga +sprecare +spronato +spruzzo +spuntino +squillo +sradicare +srotolato +stabile +stacco +staffa +stagnare +stampato +stantio +starnuto +stasera +statuto +stelo +steppa +sterzo +stiletto +stima +stirpe +stivale +stizzoso +stonato +storico +strappo +stregato +stridulo +strozzare +strutto +stuccare +stufo +stupendo +subentro +succoso +sudore +suggerito +sugo +sultano +suonare +superbo +supporto +surgelato +surrogato +sussurro +sutura +svagare +svedese +sveglio +svelare +svenuto +svezia +sviluppo +svista +svizzera +svolta +svuotare +tabacco +tabulato +tacciare +taciturno +tale +talismano +tampone +tannino +tara +tardivo +targato +tariffa +tarpare +tartaruga +tasto +tattico +taverna +tavolata +tazza +teca +tecnico +telefono +temerario +tempo +temuto +tendone +tenero +tensione +tentacolo +teorema +terme +terrazzo +terzetto +tesi +tesserato +testato +tetro +tettoia +tifare +tigella +timbro +tinto +tipico +tipografo +tiraggio +tiro +titanio +titolo +titubante +tizio +tizzone +toccare +tollerare +tolto +tombola +tomo +tonfo +tonsilla +topazio +topologia +toppa +torba +tornare +torrone +tortora +toscano +tossire +tostatura +totano +trabocco +trachea +trafila +tragedia +tralcio +tramonto +transito +trapano +trarre +trasloco +trattato +trave +treccia +tremolio +trespolo +tributo +tricheco +trifoglio +trillo +trincea +trio +tristezza +triturato +trivella +tromba +trono +troppo +trottola +trovare +truccato +tubatura +tuffato +tulipano +tumulto +tunisia +turbare +turchino +tuta +tutela +ubicato +uccello +uccisore +udire +uditivo +uffa +ufficio +uguale +ulisse +ultimato +umano +umile +umorismo +uncinetto +ungere +ungherese +unicorno +unificato +unisono +unitario +unte +uovo +upupa +uragano +urgenza +urlo +usanza +usato +uscito +usignolo +usuraio +utensile +utilizzo +utopia +vacante +vaccinato +vagabondo +vagliato +valanga +valgo +valico +valletta +valoroso +valutare +valvola +vampata +vangare +vanitoso +vano +vantaggio +vanvera +vapore +varano +varcato +variante +vasca +vedetta +vedova +veduto +vegetale +veicolo +velcro +velina +velluto +veloce +venato +vendemmia +vento +verace +verbale +vergogna +verifica +vero +verruca +verticale +vescica +vessillo +vestale +veterano +vetrina +vetusto +viandante +vibrante +vicenda +vichingo +vicinanza +vidimare +vigilia +vigneto +vigore +vile +villano +vimini +vincitore +viola +vipera +virgola +virologo +virulento +viscoso +visione +vispo +vissuto +visura +vita +vitello +vittima +vivanda +vivido +viziare +voce +voga +volatile +volere +volpe +voragine +vulcano +zampogna +zanna +zappato +zattera +zavorra +zefiro +zelante +zelo +zenzero +zerbino +zibetto +zinco +zircone +zitto +zolla +zotico +zucchero +zufolo +zulu +zuppa diff --git a/pybtc/bip39_word_list/japanese.txt b/pybtc/bip39_word_list/japanese.txt new file mode 100644 index 0000000..fb8501a --- /dev/null +++ b/pybtc/bip39_word_list/japanese.txt @@ -0,0 +1,2048 @@ +あいこくしん +あいさつ +あいだ +あおぞら +あかちゃん +あきる +あけがた +あける +あこがれる +あさい +あさひ +あしあと +あじわう +あずかる +あずき +あそぶ +あたえる +あたためる +あたりまえ +あたる +あつい +あつかう +あっしゅく +あつまり +あつめる +あてな +あてはまる +あひる +あぶら +あぶる +あふれる +あまい +あまど +あまやかす +あまり +あみもの +あめりか +あやまる +あゆむ +あらいぐま +あらし +あらすじ +あらためる +あらゆる +あらわす +ありがとう +あわせる +あわてる +あんい +あんがい +あんこ +あんぜん +あんてい +あんない +あんまり +いいだす +いおん +いがい +いがく +いきおい +いきなり +いきもの +いきる +いくじ +いくぶん +いけばな +いけん +いこう +いこく +いこつ +いさましい +いさん +いしき +いじゅう +いじょう +いじわる +いずみ +いずれ +いせい +いせえび +いせかい +いせき +いぜん +いそうろう +いそがしい +いだい +いだく +いたずら +いたみ +いたりあ +いちおう +いちじ +いちど +いちば +いちぶ +いちりゅう +いつか +いっしゅん +いっせい +いっそう +いったん +いっち +いってい +いっぽう +いてざ +いてん +いどう +いとこ +いない +いなか +いねむり +いのち +いのる +いはつ +いばる +いはん +いびき +いひん +いふく +いへん +いほう +いみん +いもうと +いもたれ +いもり +いやがる +いやす +いよかん +いよく +いらい +いらすと +いりぐち +いりょう +いれい +いれもの +いれる +いろえんぴつ +いわい +いわう +いわかん +いわば +いわゆる +いんげんまめ +いんさつ +いんしょう +いんよう +うえき +うえる +うおざ +うがい +うかぶ +うかべる +うきわ +うくらいな +うくれれ +うけたまわる +うけつけ +うけとる +うけもつ +うける +うごかす +うごく +うこん +うさぎ +うしなう +うしろがみ +うすい +うすぎ +うすぐらい +うすめる +うせつ +うちあわせ +うちがわ +うちき +うちゅう +うっかり +うつくしい +うったえる +うつる +うどん +うなぎ +うなじ +うなずく +うなる +うねる +うのう +うぶげ +うぶごえ +うまれる +うめる +うもう +うやまう +うよく +うらがえす +うらぐち +うらない +うりあげ +うりきれ +うるさい +うれしい +うれゆき +うれる +うろこ +うわき +うわさ +うんこう +うんちん +うんてん +うんどう +えいえん +えいが +えいきょう +えいご +えいせい +えいぶん +えいよう +えいわ +えおり +えがお +えがく +えきたい +えくせる +えしゃく +えすて +えつらん +えのぐ +えほうまき +えほん +えまき +えもじ +えもの +えらい +えらぶ +えりあ +えんえん +えんかい +えんぎ +えんげき +えんしゅう +えんぜつ +えんそく +えんちょう +えんとつ +おいかける +おいこす +おいしい +おいつく +おうえん +おうさま +おうじ +おうせつ +おうたい +おうふく +おうべい +おうよう +おえる +おおい +おおう +おおどおり +おおや +おおよそ +おかえり +おかず +おがむ +おかわり +おぎなう +おきる +おくさま +おくじょう +おくりがな +おくる +おくれる +おこす +おこなう +おこる +おさえる +おさない +おさめる +おしいれ +おしえる +おじぎ +おじさん +おしゃれ +おそらく +おそわる +おたがい +おたく +おだやか +おちつく +おっと +おつり +おでかけ +おとしもの +おとなしい +おどり +おどろかす +おばさん +おまいり +おめでとう +おもいで +おもう +おもたい +おもちゃ +おやつ +おやゆび +およぼす +おらんだ +おろす +おんがく +おんけい +おんしゃ +おんせん +おんだん +おんちゅう +おんどけい +かあつ +かいが +がいき +がいけん +がいこう +かいさつ +かいしゃ +かいすいよく +かいぜん +かいぞうど +かいつう +かいてん +かいとう +かいふく +がいへき +かいほう +かいよう +がいらい +かいわ +かえる +かおり +かかえる +かがく +かがし +かがみ +かくご +かくとく +かざる +がぞう +かたい +かたち +がちょう +がっきゅう +がっこう +がっさん +がっしょう +かなざわし +かのう +がはく +かぶか +かほう +かほご +かまう +かまぼこ +かめれおん +かゆい +かようび +からい +かるい +かろう +かわく +かわら +がんか +かんけい +かんこう +かんしゃ +かんそう +かんたん +かんち +がんばる +きあい +きあつ +きいろ +ぎいん +きうい +きうん +きえる +きおう +きおく +きおち +きおん +きかい +きかく +きかんしゃ +ききて +きくばり +きくらげ +きけんせい +きこう +きこえる +きこく +きさい +きさく +きさま +きさらぎ +ぎじかがく +ぎしき +ぎじたいけん +ぎじにってい +ぎじゅつしゃ +きすう +きせい +きせき +きせつ +きそう +きぞく +きぞん +きたえる +きちょう +きつえん +ぎっちり +きつつき +きつね +きてい +きどう +きどく +きない +きなが +きなこ +きぬごし +きねん +きのう +きのした +きはく +きびしい +きひん +きふく +きぶん +きぼう +きほん +きまる +きみつ +きむずかしい +きめる +きもだめし +きもち +きもの +きゃく +きやく +ぎゅうにく +きよう +きょうりゅう +きらい +きらく +きりん +きれい +きれつ +きろく +ぎろん +きわめる +ぎんいろ +きんかくじ +きんじょ +きんようび +ぐあい +くいず +くうかん +くうき +くうぐん +くうこう +ぐうせい +くうそう +ぐうたら +くうふく +くうぼ +くかん +くきょう +くげん +ぐこう +くさい +くさき +くさばな +くさる +くしゃみ +くしょう +くすのき +くすりゆび +くせげ +くせん +ぐたいてき +くださる +くたびれる +くちこみ +くちさき +くつした +ぐっすり +くつろぐ +くとうてん +くどく +くなん +くねくね +くのう +くふう +くみあわせ +くみたてる +くめる +くやくしょ +くらす +くらべる +くるま +くれる +くろう +くわしい +ぐんかん +ぐんしょく +ぐんたい +ぐんて +けあな +けいかく +けいけん +けいこ +けいさつ +げいじゅつ +けいたい +げいのうじん +けいれき +けいろ +けおとす +けおりもの +げきか +げきげん +げきだん +げきちん +げきとつ +げきは +げきやく +げこう +げこくじょう +げざい +けさき +げざん +けしき +けしごむ +けしょう +げすと +けたば +けちゃっぷ +けちらす +けつあつ +けつい +けつえき +けっこん +けつじょ +けっせき +けってい +けつまつ +げつようび +げつれい +けつろん +げどく +けとばす +けとる +けなげ +けなす +けなみ +けぬき +げねつ +けねん +けはい +げひん +けぶかい +げぼく +けまり +けみかる +けむし +けむり +けもの +けらい +けろけろ +けわしい +けんい +けんえつ +けんお +けんか +げんき +けんげん +けんこう +けんさく +けんしゅう +けんすう +げんそう +けんちく +けんてい +けんとう +けんない +けんにん +げんぶつ +けんま +けんみん +けんめい +けんらん +けんり +こあくま +こいぬ +こいびと +ごうい +こうえん +こうおん +こうかん +ごうきゅう +ごうけい +こうこう +こうさい +こうじ +こうすい +ごうせい +こうそく +こうたい +こうちゃ +こうつう +こうてい +こうどう +こうない +こうはい +ごうほう +ごうまん +こうもく +こうりつ +こえる +こおり +ごかい +ごがつ +ごかん +こくご +こくさい +こくとう +こくない +こくはく +こぐま +こけい +こける +ここのか +こころ +こさめ +こしつ +こすう +こせい +こせき +こぜん +こそだて +こたい +こたえる +こたつ +こちょう +こっか +こつこつ +こつばん +こつぶ +こてい +こてん +ことがら +ことし +ことば +ことり +こなごな +こねこね +このまま +このみ +このよ +ごはん +こひつじ +こふう +こふん +こぼれる +ごまあぶら +こまかい +ごますり +こまつな +こまる +こむぎこ +こもじ +こもち +こもの +こもん +こやく +こやま +こゆう +こゆび +こよい +こよう +こりる +これくしょん +ころっけ +こわもて +こわれる +こんいん +こんかい +こんき +こんしゅう +こんすい +こんだて +こんとん +こんなん +こんびに +こんぽん +こんまけ +こんや +こんれい +こんわく +ざいえき +さいかい +さいきん +ざいげん +ざいこ +さいしょ +さいせい +ざいたく +ざいちゅう +さいてき +ざいりょう +さうな +さかいし +さがす +さかな +さかみち +さがる +さぎょう +さくし +さくひん +さくら +さこく +さこつ +さずかる +ざせき +さたん +さつえい +ざつおん +ざっか +ざつがく +さっきょく +ざっし +さつじん +ざっそう +さつたば +さつまいも +さてい +さといも +さとう +さとおや +さとし +さとる +さのう +さばく +さびしい +さべつ +さほう +さほど +さます +さみしい +さみだれ +さむけ +さめる +さやえんどう +さゆう +さよう +さよく +さらだ +ざるそば +さわやか +さわる +さんいん +さんか +さんきゃく +さんこう +さんさい +ざんしょ +さんすう +さんせい +さんそ +さんち +さんま +さんみ +さんらん +しあい +しあげ +しあさって +しあわせ +しいく +しいん +しうち +しえい +しおけ +しかい +しかく +じかん +しごと +しすう +じだい +したうけ +したぎ +したて +したみ +しちょう +しちりん +しっかり +しつじ +しつもん +してい +してき +してつ +じてん +じどう +しなぎれ +しなもの +しなん +しねま +しねん +しのぐ +しのぶ +しはい +しばかり +しはつ +しはらい +しはん +しひょう +しふく +じぶん +しへい +しほう +しほん +しまう +しまる +しみん +しむける +じむしょ +しめい +しめる +しもん +しゃいん +しゃうん +しゃおん +じゃがいも +しやくしょ +しゃくほう +しゃけん +しゃこ +しゃざい +しゃしん +しゃせん +しゃそう +しゃたい +しゃちょう +しゃっきん +じゃま +しゃりん +しゃれい +じゆう +じゅうしょ +しゅくはく +じゅしん +しゅっせき +しゅみ +しゅらば +じゅんばん +しょうかい +しょくたく +しょっけん +しょどう +しょもつ +しらせる +しらべる +しんか +しんこう +じんじゃ +しんせいじ +しんちく +しんりん +すあげ +すあし +すあな +ずあん +すいえい +すいか +すいとう +ずいぶん +すいようび +すうがく +すうじつ +すうせん +すおどり +すきま +すくう +すくない +すける +すごい +すこし +ずさん +すずしい +すすむ +すすめる +すっかり +ずっしり +ずっと +すてき +すてる +すねる +すのこ +すはだ +すばらしい +ずひょう +ずぶぬれ +すぶり +すふれ +すべて +すべる +ずほう +すぼん +すまい +すめし +すもう +すやき +すらすら +するめ +すれちがう +すろっと +すわる +すんぜん +すんぽう +せあぶら +せいかつ +せいげん +せいじ +せいよう +せおう +せかいかん +せきにん +せきむ +せきゆ +せきらんうん +せけん +せこう +せすじ +せたい +せたけ +せっかく +せっきゃく +ぜっく +せっけん +せっこつ +せっさたくま +せつぞく +せつだん +せつでん +せっぱん +せつび +せつぶん +せつめい +せつりつ +せなか +せのび +せはば +せびろ +せぼね +せまい +せまる +せめる +せもたれ +せりふ +ぜんあく +せんい +せんえい +せんか +せんきょ +せんく +せんげん +ぜんご +せんさい +せんしゅ +せんすい +せんせい +せんぞ +せんたく +せんちょう +せんてい +せんとう +せんぬき +せんねん +せんぱい +ぜんぶ +ぜんぽう +せんむ +せんめんじょ +せんもん +せんやく +せんゆう +せんよう +ぜんら +ぜんりゃく +せんれい +せんろ +そあく +そいとげる +そいね +そうがんきょう +そうき +そうご +そうしん +そうだん +そうなん +そうび +そうめん +そうり +そえもの +そえん +そがい +そげき +そこう +そこそこ +そざい +そしな +そせい +そせん +そそぐ +そだてる +そつう +そつえん +そっかん +そつぎょう +そっけつ +そっこう +そっせん +そっと +そとがわ +そとづら +そなえる +そなた +そふぼ +そぼく +そぼろ +そまつ +そまる +そむく +そむりえ +そめる +そもそも +そよかぜ +そらまめ +そろう +そんかい +そんけい +そんざい +そんしつ +そんぞく +そんちょう +ぞんび +ぞんぶん +そんみん +たあい +たいいん +たいうん +たいえき +たいおう +だいがく +たいき +たいぐう +たいけん +たいこ +たいざい +だいじょうぶ +だいすき +たいせつ +たいそう +だいたい +たいちょう +たいてい +だいどころ +たいない +たいねつ +たいのう +たいはん +だいひょう +たいふう +たいへん +たいほ +たいまつばな +たいみんぐ +たいむ +たいめん +たいやき +たいよう +たいら +たいりょく +たいる +たいわん +たうえ +たえる +たおす +たおる +たおれる +たかい +たかね +たきび +たくさん +たこく +たこやき +たさい +たしざん +だじゃれ +たすける +たずさわる +たそがれ +たたかう +たたく +ただしい +たたみ +たちばな +だっかい +だっきゃく +だっこ +だっしゅつ +だったい +たてる +たとえる +たなばた +たにん +たぬき +たのしみ +たはつ +たぶん +たべる +たぼう +たまご +たまる +だむる +ためいき +ためす +ためる +たもつ +たやすい +たよる +たらす +たりきほんがん +たりょう +たりる +たると +たれる +たれんと +たろっと +たわむれる +だんあつ +たんい +たんおん +たんか +たんき +たんけん +たんご +たんさん +たんじょうび +だんせい +たんそく +たんたい +だんち +たんてい +たんとう +だんな +たんにん +だんねつ +たんのう +たんぴん +だんぼう +たんまつ +たんめい +だんれつ +だんろ +だんわ +ちあい +ちあん +ちいき +ちいさい +ちえん +ちかい +ちから +ちきゅう +ちきん +ちけいず +ちけん +ちこく +ちさい +ちしき +ちしりょう +ちせい +ちそう +ちたい +ちたん +ちちおや +ちつじょ +ちてき +ちてん +ちぬき +ちぬり +ちのう +ちひょう +ちへいせん +ちほう +ちまた +ちみつ +ちみどろ +ちめいど +ちゃんこなべ +ちゅうい +ちゆりょく +ちょうし +ちょさくけん +ちらし +ちらみ +ちりがみ +ちりょう +ちるど +ちわわ +ちんたい +ちんもく +ついか +ついたち +つうか +つうじょう +つうはん +つうわ +つかう +つかれる +つくね +つくる +つけね +つける +つごう +つたえる +つづく +つつじ +つつむ +つとめる +つながる +つなみ +つねづね +つのる +つぶす +つまらない +つまる +つみき +つめたい +つもり +つもる +つよい +つるぼ +つるみく +つわもの +つわり +てあし +てあて +てあみ +ていおん +ていか +ていき +ていけい +ていこく +ていさつ +ていし +ていせい +ていたい +ていど +ていねい +ていひょう +ていへん +ていぼう +てうち +ておくれ +てきとう +てくび +でこぼこ +てさぎょう +てさげ +てすり +てそう +てちがい +てちょう +てつがく +てつづき +でっぱ +てつぼう +てつや +でぬかえ +てぬき +てぬぐい +てのひら +てはい +てぶくろ +てふだ +てほどき +てほん +てまえ +てまきずし +てみじか +てみやげ +てらす +てれび +てわけ +てわたし +でんあつ +てんいん +てんかい +てんき +てんぐ +てんけん +てんごく +てんさい +てんし +てんすう +でんち +てんてき +てんとう +てんない +てんぷら +てんぼうだい +てんめつ +てんらんかい +でんりょく +でんわ +どあい +といれ +どうかん +とうきゅう +どうぐ +とうし +とうむぎ +とおい +とおか +とおく +とおす +とおる +とかい +とかす +ときおり +ときどき +とくい +とくしゅう +とくてん +とくに +とくべつ +とけい +とける +とこや +とさか +としょかん +とそう +とたん +とちゅう +とっきゅう +とっくん +とつぜん +とつにゅう +とどける +ととのえる +とない +となえる +となり +とのさま +とばす +どぶがわ +とほう +とまる +とめる +ともだち +ともる +どようび +とらえる +とんかつ +どんぶり +ないかく +ないこう +ないしょ +ないす +ないせん +ないそう +なおす +ながい +なくす +なげる +なこうど +なさけ +なたでここ +なっとう +なつやすみ +ななおし +なにごと +なにもの +なにわ +なのか +なふだ +なまいき +なまえ +なまみ +なみだ +なめらか +なめる +なやむ +ならう +ならび +ならぶ +なれる +なわとび +なわばり +にあう +にいがた +にうけ +におい +にかい +にがて +にきび +にくしみ +にくまん +にげる +にさんかたんそ +にしき +にせもの +にちじょう +にちようび +にっか +にっき +にっけい +にっこう +にっさん +にっしょく +にっすう +にっせき +にってい +になう +にほん +にまめ +にもつ +にやり +にゅういん +にりんしゃ +にわとり +にんい +にんか +にんき +にんげん +にんしき +にんずう +にんそう +にんたい +にんち +にんてい +にんにく +にんぷ +にんまり +にんむ +にんめい +にんよう +ぬいくぎ +ぬかす +ぬぐいとる +ぬぐう +ぬくもり +ぬすむ +ぬまえび +ぬめり +ぬらす +ぬんちゃく +ねあげ +ねいき +ねいる +ねいろ +ねぐせ +ねくたい +ねくら +ねこぜ +ねこむ +ねさげ +ねすごす +ねそべる +ねだん +ねつい +ねっしん +ねつぞう +ねったいぎょ +ねぶそく +ねふだ +ねぼう +ねほりはほり +ねまき +ねまわし +ねみみ +ねむい +ねむたい +ねもと +ねらう +ねわざ +ねんいり +ねんおし +ねんかん +ねんきん +ねんぐ +ねんざ +ねんし +ねんちゃく +ねんど +ねんぴ +ねんぶつ +ねんまつ +ねんりょう +ねんれい +のいず +のおづま +のがす +のきなみ +のこぎり +のこす +のこる +のせる +のぞく +のぞむ +のたまう +のちほど +のっく +のばす +のはら +のべる +のぼる +のみもの +のやま +のらいぬ +のらねこ +のりもの +のりゆき +のれん +のんき +ばあい +はあく +ばあさん +ばいか +ばいく +はいけん +はいご +はいしん +はいすい +はいせん +はいそう +はいち +ばいばい +はいれつ +はえる +はおる +はかい +ばかり +はかる +はくしゅ +はけん +はこぶ +はさみ +はさん +はしご +ばしょ +はしる +はせる +ぱそこん +はそん +はたん +はちみつ +はつおん +はっかく +はづき +はっきり +はっくつ +はっけん +はっこう +はっさん +はっしん +はったつ +はっちゅう +はってん +はっぴょう +はっぽう +はなす +はなび +はにかむ +はぶらし +はみがき +はむかう +はめつ +はやい +はやし +はらう +はろうぃん +はわい +はんい +はんえい +はんおん +はんかく +はんきょう +ばんぐみ +はんこ +はんしゃ +はんすう +はんだん +ぱんち +ぱんつ +はんてい +はんとし +はんのう +はんぱ +はんぶん +はんぺん +はんぼうき +はんめい +はんらん +はんろん +ひいき +ひうん +ひえる +ひかく +ひかり +ひかる +ひかん +ひくい +ひけつ +ひこうき +ひこく +ひさい +ひさしぶり +ひさん +びじゅつかん +ひしょ +ひそか +ひそむ +ひたむき +ひだり +ひたる +ひつぎ +ひっこし +ひっし +ひつじゅひん +ひっす +ひつぜん +ぴったり +ぴっちり +ひつよう +ひてい +ひとごみ +ひなまつり +ひなん +ひねる +ひはん +ひびく +ひひょう +ひほう +ひまわり +ひまん +ひみつ +ひめい +ひめじし +ひやけ +ひやす +ひよう +びょうき +ひらがな +ひらく +ひりつ +ひりょう +ひるま +ひるやすみ +ひれい +ひろい +ひろう +ひろき +ひろゆき +ひんかく +ひんけつ +ひんこん +ひんしゅ +ひんそう +ぴんち +ひんぱん +びんぼう +ふあん +ふいうち +ふうけい +ふうせん +ぷうたろう +ふうとう +ふうふ +ふえる +ふおん +ふかい +ふきん +ふくざつ +ふくぶくろ +ふこう +ふさい +ふしぎ +ふじみ +ふすま +ふせい +ふせぐ +ふそく +ぶたにく +ふたん +ふちょう +ふつう +ふつか +ふっかつ +ふっき +ふっこく +ぶどう +ふとる +ふとん +ふのう +ふはい +ふひょう +ふへん +ふまん +ふみん +ふめつ +ふめん +ふよう +ふりこ +ふりる +ふるい +ふんいき +ぶんがく +ぶんぐ +ふんしつ +ぶんせき +ふんそう +ぶんぽう +へいあん +へいおん +へいがい +へいき +へいげん +へいこう +へいさ +へいしゃ +へいせつ +へいそ +へいたく +へいてん +へいねつ +へいわ +へきが +へこむ +べにいろ +べにしょうが +へらす +へんかん +べんきょう +べんごし +へんさい +へんたい +べんり +ほあん +ほいく +ぼうぎょ +ほうこく +ほうそう +ほうほう +ほうもん +ほうりつ +ほえる +ほおん +ほかん +ほきょう +ぼきん +ほくろ +ほけつ +ほけん +ほこう +ほこる +ほしい +ほしつ +ほしゅ +ほしょう +ほせい +ほそい +ほそく +ほたて +ほたる +ぽちぶくろ +ほっきょく +ほっさ +ほったん +ほとんど +ほめる +ほんい +ほんき +ほんけ +ほんしつ +ほんやく +まいにち +まかい +まかせる +まがる +まける +まこと +まさつ +まじめ +ますく +まぜる +まつり +まとめ +まなぶ +まぬけ +まねく +まほう +まもる +まゆげ +まよう +まろやか +まわす +まわり +まわる +まんが +まんきつ +まんぞく +まんなか +みいら +みうち +みえる +みがく +みかた +みかん +みけん +みこん +みじかい +みすい +みすえる +みせる +みっか +みつかる +みつける +みてい +みとめる +みなと +みなみかさい +みねらる +みのう +みのがす +みほん +みもと +みやげ +みらい +みりょく +みわく +みんか +みんぞく +むいか +むえき +むえん +むかい +むかう +むかえ +むかし +むぎちゃ +むける +むげん +むさぼる +むしあつい +むしば +むじゅん +むしろ +むすう +むすこ +むすぶ +むすめ +むせる +むせん +むちゅう +むなしい +むのう +むやみ +むよう +むらさき +むりょう +むろん +めいあん +めいうん +めいえん +めいかく +めいきょく +めいさい +めいし +めいそう +めいぶつ +めいれい +めいわく +めぐまれる +めざす +めした +めずらしい +めだつ +めまい +めやす +めんきょ +めんせき +めんどう +もうしあげる +もうどうけん +もえる +もくし +もくてき +もくようび +もちろん +もどる +もらう +もんく +もんだい +やおや +やける +やさい +やさしい +やすい +やすたろう +やすみ +やせる +やそう +やたい +やちん +やっと +やっぱり +やぶる +やめる +ややこしい +やよい +やわらかい +ゆうき +ゆうびんきょく +ゆうべ +ゆうめい +ゆけつ +ゆしゅつ +ゆせん +ゆそう +ゆたか +ゆちゃく +ゆでる +ゆにゅう +ゆびわ +ゆらい +ゆれる +ようい +ようか +ようきゅう +ようじ +ようす +ようちえん +よかぜ +よかん +よきん +よくせい +よくぼう +よけい +よごれる +よさん +よしゅう +よそう +よそく +よっか +よてい +よどがわく +よねつ +よやく +よゆう +よろこぶ +よろしい +らいう +らくがき +らくご +らくさつ +らくだ +らしんばん +らせん +らぞく +らたい +らっか +られつ +りえき +りかい +りきさく +りきせつ +りくぐん +りくつ +りけん +りこう +りせい +りそう +りそく +りてん +りねん +りゆう +りゅうがく +りよう +りょうり +りょかん +りょくちゃ +りょこう +りりく +りれき +りろん +りんご +るいけい +るいさい +るいじ +るいせき +るすばん +るりがわら +れいかん +れいぎ +れいせい +れいぞうこ +れいとう +れいぼう +れきし +れきだい +れんあい +れんけい +れんこん +れんさい +れんしゅう +れんぞく +れんらく +ろうか +ろうご +ろうじん +ろうそく +ろくが +ろこつ +ろじうら +ろしゅつ +ろせん +ろてん +ろめん +ろれつ +ろんぎ +ろんぱ +ろんぶん +ろんり +わかす +わかめ +わかやま +わかれる +わしつ +わじまし +わすれもの +わらう +われる diff --git a/pybtc/bip39_word_list/korean.txt b/pybtc/bip39_word_list/korean.txt new file mode 100644 index 0000000..1acebf7 --- /dev/null +++ b/pybtc/bip39_word_list/korean.txt @@ -0,0 +1,2048 @@ +가격 +가끔 +가난 +가능 +가득 +가르침 +가뭄 +가방 +가상 +가슴 +가운데 +가을 +가이드 +가입 +가장 +가정 +가족 +가죽 +각오 +각자 +간격 +간부 +간섭 +간장 +간접 +간판 +갈등 +갈비 +갈색 +갈증 +감각 +감기 +감소 +감수성 +감자 +감정 +갑자기 +강남 +강당 +강도 +강력히 +강변 +강북 +강사 +강수량 +강아지 +강원도 +강의 +강제 +강조 +같이 +개구리 +개나리 +개방 +개별 +개선 +개성 +개인 +객관적 +거실 +거액 +거울 +거짓 +거품 +걱정 +건강 +건물 +건설 +건조 +건축 +걸음 +검사 +검토 +게시판 +게임 +겨울 +견해 +결과 +결국 +결론 +결석 +결승 +결심 +결정 +결혼 +경계 +경고 +경기 +경력 +경복궁 +경비 +경상도 +경영 +경우 +경쟁 +경제 +경주 +경찰 +경치 +경향 +경험 +계곡 +계단 +계란 +계산 +계속 +계약 +계절 +계층 +계획 +고객 +고구려 +고궁 +고급 +고등학생 +고무신 +고민 +고양이 +고장 +고전 +고집 +고춧가루 +고통 +고향 +곡식 +골목 +골짜기 +골프 +공간 +공개 +공격 +공군 +공급 +공기 +공동 +공무원 +공부 +공사 +공식 +공업 +공연 +공원 +공장 +공짜 +공책 +공통 +공포 +공항 +공휴일 +과목 +과일 +과장 +과정 +과학 +관객 +관계 +관광 +관념 +관람 +관련 +관리 +관습 +관심 +관점 +관찰 +광경 +광고 +광장 +광주 +괴로움 +굉장히 +교과서 +교문 +교복 +교실 +교양 +교육 +교장 +교직 +교통 +교환 +교훈 +구경 +구름 +구멍 +구별 +구분 +구석 +구성 +구속 +구역 +구입 +구청 +구체적 +국가 +국기 +국내 +국립 +국물 +국민 +국수 +국어 +국왕 +국적 +국제 +국회 +군대 +군사 +군인 +궁극적 +권리 +권위 +권투 +귀국 +귀신 +규정 +규칙 +균형 +그날 +그냥 +그늘 +그러나 +그룹 +그릇 +그림 +그제서야 +그토록 +극복 +극히 +근거 +근교 +근래 +근로 +근무 +근본 +근원 +근육 +근처 +글씨 +글자 +금강산 +금고 +금년 +금메달 +금액 +금연 +금요일 +금지 +긍정적 +기간 +기관 +기념 +기능 +기독교 +기둥 +기록 +기름 +기법 +기본 +기분 +기쁨 +기숙사 +기술 +기억 +기업 +기온 +기운 +기원 +기적 +기준 +기침 +기혼 +기획 +긴급 +긴장 +길이 +김밥 +김치 +김포공항 +깍두기 +깜빡 +깨달음 +깨소금 +껍질 +꼭대기 +꽃잎 +나들이 +나란히 +나머지 +나물 +나침반 +나흘 +낙엽 +난방 +날개 +날씨 +날짜 +남녀 +남대문 +남매 +남산 +남자 +남편 +남학생 +낭비 +낱말 +내년 +내용 +내일 +냄비 +냄새 +냇물 +냉동 +냉면 +냉방 +냉장고 +넥타이 +넷째 +노동 +노란색 +노력 +노인 +녹음 +녹차 +녹화 +논리 +논문 +논쟁 +놀이 +농구 +농담 +농민 +농부 +농업 +농장 +농촌 +높이 +눈동자 +눈물 +눈썹 +뉴욕 +느낌 +늑대 +능동적 +능력 +다방 +다양성 +다음 +다이어트 +다행 +단계 +단골 +단독 +단맛 +단순 +단어 +단위 +단점 +단체 +단추 +단편 +단풍 +달걀 +달러 +달력 +달리 +닭고기 +담당 +담배 +담요 +담임 +답변 +답장 +당근 +당분간 +당연히 +당장 +대규모 +대낮 +대단히 +대답 +대도시 +대략 +대량 +대륙 +대문 +대부분 +대신 +대응 +대장 +대전 +대접 +대중 +대책 +대출 +대충 +대통령 +대학 +대한민국 +대합실 +대형 +덩어리 +데이트 +도대체 +도덕 +도둑 +도망 +도서관 +도심 +도움 +도입 +도자기 +도저히 +도전 +도중 +도착 +독감 +독립 +독서 +독일 +독창적 +동화책 +뒷모습 +뒷산 +딸아이 +마누라 +마늘 +마당 +마라톤 +마련 +마무리 +마사지 +마약 +마요네즈 +마을 +마음 +마이크 +마중 +마지막 +마찬가지 +마찰 +마흔 +막걸리 +막내 +막상 +만남 +만두 +만세 +만약 +만일 +만점 +만족 +만화 +많이 +말기 +말씀 +말투 +맘대로 +망원경 +매년 +매달 +매력 +매번 +매스컴 +매일 +매장 +맥주 +먹이 +먼저 +먼지 +멀리 +메일 +며느리 +며칠 +면담 +멸치 +명단 +명령 +명예 +명의 +명절 +명칭 +명함 +모금 +모니터 +모델 +모든 +모범 +모습 +모양 +모임 +모조리 +모집 +모퉁이 +목걸이 +목록 +목사 +목소리 +목숨 +목적 +목표 +몰래 +몸매 +몸무게 +몸살 +몸속 +몸짓 +몸통 +몹시 +무관심 +무궁화 +무더위 +무덤 +무릎 +무슨 +무엇 +무역 +무용 +무조건 +무지개 +무척 +문구 +문득 +문법 +문서 +문제 +문학 +문화 +물가 +물건 +물결 +물고기 +물론 +물리학 +물음 +물질 +물체 +미국 +미디어 +미사일 +미술 +미역 +미용실 +미움 +미인 +미팅 +미혼 +민간 +민족 +민주 +믿음 +밀가루 +밀리미터 +밑바닥 +바가지 +바구니 +바나나 +바늘 +바닥 +바닷가 +바람 +바이러스 +바탕 +박물관 +박사 +박수 +반대 +반드시 +반말 +반발 +반성 +반응 +반장 +반죽 +반지 +반찬 +받침 +발가락 +발걸음 +발견 +발달 +발레 +발목 +발바닥 +발생 +발음 +발자국 +발전 +발톱 +발표 +밤하늘 +밥그릇 +밥맛 +밥상 +밥솥 +방금 +방면 +방문 +방바닥 +방법 +방송 +방식 +방안 +방울 +방지 +방학 +방해 +방향 +배경 +배꼽 +배달 +배드민턴 +백두산 +백색 +백성 +백인 +백제 +백화점 +버릇 +버섯 +버튼 +번개 +번역 +번지 +번호 +벌금 +벌레 +벌써 +범위 +범인 +범죄 +법률 +법원 +법적 +법칙 +베이징 +벨트 +변경 +변동 +변명 +변신 +변호사 +변화 +별도 +별명 +별일 +병실 +병아리 +병원 +보관 +보너스 +보라색 +보람 +보름 +보상 +보안 +보자기 +보장 +보전 +보존 +보통 +보편적 +보험 +복도 +복사 +복숭아 +복습 +볶음 +본격적 +본래 +본부 +본사 +본성 +본인 +본질 +볼펜 +봉사 +봉지 +봉투 +부근 +부끄러움 +부담 +부동산 +부문 +부분 +부산 +부상 +부엌 +부인 +부작용 +부장 +부정 +부족 +부지런히 +부친 +부탁 +부품 +부회장 +북부 +북한 +분노 +분량 +분리 +분명 +분석 +분야 +분위기 +분필 +분홍색 +불고기 +불과 +불교 +불꽃 +불만 +불법 +불빛 +불안 +불이익 +불행 +브랜드 +비극 +비난 +비닐 +비둘기 +비디오 +비로소 +비만 +비명 +비밀 +비바람 +비빔밥 +비상 +비용 +비율 +비중 +비타민 +비판 +빌딩 +빗물 +빗방울 +빗줄기 +빛깔 +빨간색 +빨래 +빨리 +사건 +사계절 +사나이 +사냥 +사람 +사랑 +사립 +사모님 +사물 +사방 +사상 +사생활 +사설 +사슴 +사실 +사업 +사용 +사월 +사장 +사전 +사진 +사촌 +사춘기 +사탕 +사투리 +사흘 +산길 +산부인과 +산업 +산책 +살림 +살인 +살짝 +삼계탕 +삼국 +삼십 +삼월 +삼촌 +상관 +상금 +상대 +상류 +상반기 +상상 +상식 +상업 +상인 +상자 +상점 +상처 +상추 +상태 +상표 +상품 +상황 +새벽 +색깔 +색연필 +생각 +생명 +생물 +생방송 +생산 +생선 +생신 +생일 +생활 +서랍 +서른 +서명 +서민 +서비스 +서양 +서울 +서적 +서점 +서쪽 +서클 +석사 +석유 +선거 +선물 +선배 +선생 +선수 +선원 +선장 +선전 +선택 +선풍기 +설거지 +설날 +설렁탕 +설명 +설문 +설사 +설악산 +설치 +설탕 +섭씨 +성공 +성당 +성명 +성별 +성인 +성장 +성적 +성질 +성함 +세금 +세미나 +세상 +세월 +세종대왕 +세탁 +센터 +센티미터 +셋째 +소규모 +소극적 +소금 +소나기 +소년 +소득 +소망 +소문 +소설 +소속 +소아과 +소용 +소원 +소음 +소중히 +소지품 +소질 +소풍 +소형 +속담 +속도 +속옷 +손가락 +손길 +손녀 +손님 +손등 +손목 +손뼉 +손실 +손질 +손톱 +손해 +솔직히 +솜씨 +송아지 +송이 +송편 +쇠고기 +쇼핑 +수건 +수년 +수단 +수돗물 +수동적 +수면 +수명 +수박 +수상 +수석 +수술 +수시로 +수업 +수염 +수영 +수입 +수준 +수집 +수출 +수컷 +수필 +수학 +수험생 +수화기 +숙녀 +숙소 +숙제 +순간 +순서 +순수 +순식간 +순위 +숟가락 +술병 +술집 +숫자 +스님 +스물 +스스로 +스승 +스웨터 +스위치 +스케이트 +스튜디오 +스트레스 +스포츠 +슬쩍 +슬픔 +습관 +습기 +승객 +승리 +승부 +승용차 +승진 +시각 +시간 +시골 +시금치 +시나리오 +시댁 +시리즈 +시멘트 +시민 +시부모 +시선 +시설 +시스템 +시아버지 +시어머니 +시월 +시인 +시일 +시작 +시장 +시절 +시점 +시중 +시즌 +시집 +시청 +시합 +시험 +식구 +식기 +식당 +식량 +식료품 +식물 +식빵 +식사 +식생활 +식초 +식탁 +식품 +신고 +신규 +신념 +신문 +신발 +신비 +신사 +신세 +신용 +신제품 +신청 +신체 +신화 +실감 +실내 +실력 +실례 +실망 +실수 +실습 +실시 +실장 +실정 +실질적 +실천 +실체 +실컷 +실태 +실패 +실험 +실현 +심리 +심부름 +심사 +심장 +심정 +심판 +쌍둥이 +씨름 +씨앗 +아가씨 +아나운서 +아드님 +아들 +아쉬움 +아스팔트 +아시아 +아울러 +아저씨 +아줌마 +아직 +아침 +아파트 +아프리카 +아픔 +아홉 +아흔 +악기 +악몽 +악수 +안개 +안경 +안과 +안내 +안녕 +안동 +안방 +안부 +안주 +알루미늄 +알코올 +암시 +암컷 +압력 +앞날 +앞문 +애인 +애정 +액수 +앨범 +야간 +야단 +야옹 +약간 +약국 +약속 +약수 +약점 +약품 +약혼녀 +양념 +양력 +양말 +양배추 +양주 +양파 +어둠 +어려움 +어른 +어젯밤 +어쨌든 +어쩌다가 +어쩐지 +언니 +언덕 +언론 +언어 +얼굴 +얼른 +얼음 +얼핏 +엄마 +업무 +업종 +업체 +엉덩이 +엉망 +엉터리 +엊그제 +에너지 +에어컨 +엔진 +여건 +여고생 +여관 +여군 +여권 +여대생 +여덟 +여동생 +여든 +여론 +여름 +여섯 +여성 +여왕 +여인 +여전히 +여직원 +여학생 +여행 +역사 +역시 +역할 +연결 +연구 +연극 +연기 +연락 +연설 +연세 +연속 +연습 +연애 +연예인 +연인 +연장 +연주 +연출 +연필 +연합 +연휴 +열기 +열매 +열쇠 +열심히 +열정 +열차 +열흘 +염려 +엽서 +영국 +영남 +영상 +영양 +영역 +영웅 +영원히 +영하 +영향 +영혼 +영화 +옆구리 +옆방 +옆집 +예감 +예금 +예방 +예산 +예상 +예선 +예술 +예습 +예식장 +예약 +예전 +예절 +예정 +예컨대 +옛날 +오늘 +오락 +오랫동안 +오렌지 +오로지 +오른발 +오븐 +오십 +오염 +오월 +오전 +오직 +오징어 +오페라 +오피스텔 +오히려 +옥상 +옥수수 +온갖 +온라인 +온몸 +온종일 +온통 +올가을 +올림픽 +올해 +옷차림 +와이셔츠 +와인 +완성 +완전 +왕비 +왕자 +왜냐하면 +왠지 +외갓집 +외국 +외로움 +외삼촌 +외출 +외침 +외할머니 +왼발 +왼손 +왼쪽 +요금 +요일 +요즘 +요청 +용기 +용서 +용어 +우산 +우선 +우승 +우연히 +우정 +우체국 +우편 +운동 +운명 +운반 +운전 +운행 +울산 +울음 +움직임 +웃어른 +웃음 +워낙 +원고 +원래 +원서 +원숭이 +원인 +원장 +원피스 +월급 +월드컵 +월세 +월요일 +웨이터 +위반 +위법 +위성 +위원 +위험 +위협 +윗사람 +유난히 +유럽 +유명 +유물 +유산 +유적 +유치원 +유학 +유행 +유형 +육군 +육상 +육십 +육체 +은행 +음력 +음료 +음반 +음성 +음식 +음악 +음주 +의견 +의논 +의문 +의복 +의식 +의심 +의외로 +의욕 +의원 +의학 +이것 +이곳 +이념 +이놈 +이달 +이대로 +이동 +이렇게 +이력서 +이론적 +이름 +이민 +이발소 +이별 +이불 +이빨 +이상 +이성 +이슬 +이야기 +이용 +이웃 +이월 +이윽고 +이익 +이전 +이중 +이튿날 +이틀 +이혼 +인간 +인격 +인공 +인구 +인근 +인기 +인도 +인류 +인물 +인생 +인쇄 +인연 +인원 +인재 +인종 +인천 +인체 +인터넷 +인하 +인형 +일곱 +일기 +일단 +일대 +일등 +일반 +일본 +일부 +일상 +일생 +일손 +일요일 +일월 +일정 +일종 +일주일 +일찍 +일체 +일치 +일행 +일회용 +임금 +임무 +입대 +입력 +입맛 +입사 +입술 +입시 +입원 +입장 +입학 +자가용 +자격 +자극 +자동 +자랑 +자부심 +자식 +자신 +자연 +자원 +자율 +자전거 +자정 +자존심 +자판 +작가 +작년 +작성 +작업 +작용 +작은딸 +작품 +잔디 +잔뜩 +잔치 +잘못 +잠깐 +잠수함 +잠시 +잠옷 +잠자리 +잡지 +장관 +장군 +장기간 +장래 +장례 +장르 +장마 +장면 +장모 +장미 +장비 +장사 +장소 +장식 +장애인 +장인 +장점 +장차 +장학금 +재능 +재빨리 +재산 +재생 +재작년 +재정 +재채기 +재판 +재학 +재활용 +저것 +저고리 +저곳 +저녁 +저런 +저렇게 +저번 +저울 +저절로 +저축 +적극 +적당히 +적성 +적용 +적응 +전개 +전공 +전기 +전달 +전라도 +전망 +전문 +전반 +전부 +전세 +전시 +전용 +전자 +전쟁 +전주 +전철 +전체 +전통 +전혀 +전후 +절대 +절망 +절반 +절약 +절차 +점검 +점수 +점심 +점원 +점점 +점차 +접근 +접시 +접촉 +젓가락 +정거장 +정도 +정류장 +정리 +정말 +정면 +정문 +정반대 +정보 +정부 +정비 +정상 +정성 +정오 +정원 +정장 +정지 +정치 +정확히 +제공 +제과점 +제대로 +제목 +제발 +제법 +제삿날 +제안 +제일 +제작 +제주도 +제출 +제품 +제한 +조각 +조건 +조금 +조깅 +조명 +조미료 +조상 +조선 +조용히 +조절 +조정 +조직 +존댓말 +존재 +졸업 +졸음 +종교 +종로 +종류 +종소리 +종업원 +종종 +종합 +좌석 +죄인 +주관적 +주름 +주말 +주머니 +주먹 +주문 +주민 +주방 +주변 +주식 +주인 +주일 +주장 +주전자 +주택 +준비 +줄거리 +줄기 +줄무늬 +중간 +중계방송 +중국 +중년 +중단 +중독 +중반 +중부 +중세 +중소기업 +중순 +중앙 +중요 +중학교 +즉석 +즉시 +즐거움 +증가 +증거 +증권 +증상 +증세 +지각 +지갑 +지경 +지극히 +지금 +지급 +지능 +지름길 +지리산 +지방 +지붕 +지식 +지역 +지우개 +지원 +지적 +지점 +지진 +지출 +직선 +직업 +직원 +직장 +진급 +진동 +진로 +진료 +진리 +진짜 +진찰 +진출 +진통 +진행 +질문 +질병 +질서 +짐작 +집단 +집안 +집중 +짜증 +찌꺼기 +차남 +차라리 +차량 +차림 +차별 +차선 +차츰 +착각 +찬물 +찬성 +참가 +참기름 +참새 +참석 +참여 +참외 +참조 +찻잔 +창가 +창고 +창구 +창문 +창밖 +창작 +창조 +채널 +채점 +책가방 +책방 +책상 +책임 +챔피언 +처벌 +처음 +천국 +천둥 +천장 +천재 +천천히 +철도 +철저히 +철학 +첫날 +첫째 +청년 +청바지 +청소 +청춘 +체계 +체력 +체온 +체육 +체중 +체험 +초등학생 +초반 +초밥 +초상화 +초순 +초여름 +초원 +초저녁 +초점 +초청 +초콜릿 +촛불 +총각 +총리 +총장 +촬영 +최근 +최상 +최선 +최신 +최악 +최종 +추석 +추억 +추진 +추천 +추측 +축구 +축소 +축제 +축하 +출근 +출발 +출산 +출신 +출연 +출입 +출장 +출판 +충격 +충고 +충돌 +충분히 +충청도 +취업 +취직 +취향 +치약 +친구 +친척 +칠십 +칠월 +칠판 +침대 +침묵 +침실 +칫솔 +칭찬 +카메라 +카운터 +칼국수 +캐릭터 +캠퍼스 +캠페인 +커튼 +컨디션 +컬러 +컴퓨터 +코끼리 +코미디 +콘서트 +콜라 +콤플렉스 +콩나물 +쾌감 +쿠데타 +크림 +큰길 +큰딸 +큰소리 +큰아들 +큰어머니 +큰일 +큰절 +클래식 +클럽 +킬로 +타입 +타자기 +탁구 +탁자 +탄생 +태권도 +태양 +태풍 +택시 +탤런트 +터널 +터미널 +테니스 +테스트 +테이블 +텔레비전 +토론 +토마토 +토요일 +통계 +통과 +통로 +통신 +통역 +통일 +통장 +통제 +통증 +통합 +통화 +퇴근 +퇴원 +퇴직금 +튀김 +트럭 +특급 +특별 +특성 +특수 +특징 +특히 +튼튼히 +티셔츠 +파란색 +파일 +파출소 +판결 +판단 +판매 +판사 +팔십 +팔월 +팝송 +패션 +팩스 +팩시밀리 +팬티 +퍼센트 +페인트 +편견 +편의 +편지 +편히 +평가 +평균 +평생 +평소 +평양 +평일 +평화 +포스터 +포인트 +포장 +포함 +표면 +표정 +표준 +표현 +품목 +품질 +풍경 +풍속 +풍습 +프랑스 +프린터 +플라스틱 +피곤 +피망 +피아노 +필름 +필수 +필요 +필자 +필통 +핑계 +하느님 +하늘 +하드웨어 +하룻밤 +하반기 +하숙집 +하순 +하여튼 +하지만 +하천 +하품 +하필 +학과 +학교 +학급 +학기 +학년 +학력 +학번 +학부모 +학비 +학생 +학술 +학습 +학용품 +학원 +학위 +학자 +학점 +한계 +한글 +한꺼번에 +한낮 +한눈 +한동안 +한때 +한라산 +한마디 +한문 +한번 +한복 +한식 +한여름 +한쪽 +할머니 +할아버지 +할인 +함께 +함부로 +합격 +합리적 +항공 +항구 +항상 +항의 +해결 +해군 +해답 +해당 +해물 +해석 +해설 +해수욕장 +해안 +핵심 +핸드백 +햄버거 +햇볕 +햇살 +행동 +행복 +행사 +행운 +행위 +향기 +향상 +향수 +허락 +허용 +헬기 +현관 +현금 +현대 +현상 +현실 +현장 +현재 +현지 +혈액 +협력 +형부 +형사 +형수 +형식 +형제 +형태 +형편 +혜택 +호기심 +호남 +호랑이 +호박 +호텔 +호흡 +혹시 +홀로 +홈페이지 +홍보 +홍수 +홍차 +화면 +화분 +화살 +화요일 +화장 +화학 +확보 +확인 +확장 +확정 +환갑 +환경 +환영 +환율 +환자 +활기 +활동 +활발히 +활용 +활짝 +회견 +회관 +회복 +회색 +회원 +회장 +회전 +횟수 +횡단보도 +효율적 +후반 +후춧가루 +훈련 +훨씬 +휴식 +휴일 +흉내 +흐름 +흑백 +흑인 +흔적 +흔히 +흥미 +흥분 +희곡 +희망 +희생 +흰색 +힘껏 diff --git a/pybtc/bip39_word_list/spanish.txt b/pybtc/bip39_word_list/spanish.txt new file mode 100644 index 0000000..fdbc23c --- /dev/null +++ b/pybtc/bip39_word_list/spanish.txt @@ -0,0 +1,2048 @@ +ábaco +abdomen +abeja +abierto +abogado +abono +aborto +abrazo +abrir +abuelo +abuso +acabar +academia +acceso +acción +aceite +acelga +acento +aceptar +ácido +aclarar +acné +acoger +acoso +activo +acto +actriz +actuar +acudir +acuerdo +acusar +adicto +admitir +adoptar +adorno +aduana +adulto +aéreo +afectar +afición +afinar +afirmar +ágil +agitar +agonía +agosto +agotar +agregar +agrio +agua +agudo +águila +aguja +ahogo +ahorro +aire +aislar +ajedrez +ajeno +ajuste +alacrán +alambre +alarma +alba +álbum +alcalde +aldea +alegre +alejar +alerta +aleta +alfiler +alga +algodón +aliado +aliento +alivio +alma +almeja +almíbar +altar +alteza +altivo +alto +altura +alumno +alzar +amable +amante +amapola +amargo +amasar +ámbar +ámbito +ameno +amigo +amistad +amor +amparo +amplio +ancho +anciano +ancla +andar +andén +anemia +ángulo +anillo +ánimo +anís +anotar +antena +antiguo +antojo +anual +anular +anuncio +añadir +añejo +año +apagar +aparato +apetito +apio +aplicar +apodo +aporte +apoyo +aprender +aprobar +apuesta +apuro +arado +araña +arar +árbitro +árbol +arbusto +archivo +arco +arder +ardilla +arduo +área +árido +aries +armonía +arnés +aroma +arpa +arpón +arreglo +arroz +arruga +arte +artista +asa +asado +asalto +ascenso +asegurar +aseo +asesor +asiento +asilo +asistir +asno +asombro +áspero +astilla +astro +astuto +asumir +asunto +atajo +ataque +atar +atento +ateo +ático +atleta +átomo +atraer +atroz +atún +audaz +audio +auge +aula +aumento +ausente +autor +aval +avance +avaro +ave +avellana +avena +avestruz +avión +aviso +ayer +ayuda +ayuno +azafrán +azar +azote +azúcar +azufre +azul +baba +babor +bache +bahía +baile +bajar +balanza +balcón +balde +bambú +banco +banda +baño +barba +barco +barniz +barro +báscula +bastón +basura +batalla +batería +batir +batuta +baúl +bazar +bebé +bebida +bello +besar +beso +bestia +bicho +bien +bingo +blanco +bloque +blusa +boa +bobina +bobo +boca +bocina +boda +bodega +boina +bola +bolero +bolsa +bomba +bondad +bonito +bono +bonsái +borde +borrar +bosque +bote +botín +bóveda +bozal +bravo +brazo +brecha +breve +brillo +brinco +brisa +broca +broma +bronce +brote +bruja +brusco +bruto +buceo +bucle +bueno +buey +bufanda +bufón +búho +buitre +bulto +burbuja +burla +burro +buscar +butaca +buzón +caballo +cabeza +cabina +cabra +cacao +cadáver +cadena +caer +café +caída +caimán +caja +cajón +cal +calamar +calcio +caldo +calidad +calle +calma +calor +calvo +cama +cambio +camello +camino +campo +cáncer +candil +canela +canguro +canica +canto +caña +cañón +caoba +caos +capaz +capitán +capote +captar +capucha +cara +carbón +cárcel +careta +carga +cariño +carne +carpeta +carro +carta +casa +casco +casero +caspa +castor +catorce +catre +caudal +causa +cazo +cebolla +ceder +cedro +celda +célebre +celoso +célula +cemento +ceniza +centro +cerca +cerdo +cereza +cero +cerrar +certeza +césped +cetro +chacal +chaleco +champú +chancla +chapa +charla +chico +chiste +chivo +choque +choza +chuleta +chupar +ciclón +ciego +cielo +cien +cierto +cifra +cigarro +cima +cinco +cine +cinta +ciprés +circo +ciruela +cisne +cita +ciudad +clamor +clan +claro +clase +clave +cliente +clima +clínica +cobre +cocción +cochino +cocina +coco +código +codo +cofre +coger +cohete +cojín +cojo +cola +colcha +colegio +colgar +colina +collar +colmo +columna +combate +comer +comida +cómodo +compra +conde +conejo +conga +conocer +consejo +contar +copa +copia +corazón +corbata +corcho +cordón +corona +correr +coser +cosmos +costa +cráneo +cráter +crear +crecer +creído +crema +cría +crimen +cripta +crisis +cromo +crónica +croqueta +crudo +cruz +cuadro +cuarto +cuatro +cubo +cubrir +cuchara +cuello +cuento +cuerda +cuesta +cueva +cuidar +culebra +culpa +culto +cumbre +cumplir +cuna +cuneta +cuota +cupón +cúpula +curar +curioso +curso +curva +cutis +dama +danza +dar +dardo +dátil +deber +débil +década +decir +dedo +defensa +definir +dejar +delfín +delgado +delito +demora +denso +dental +deporte +derecho +derrota +desayuno +deseo +desfile +desnudo +destino +desvío +detalle +detener +deuda +día +diablo +diadema +diamante +diana +diario +dibujo +dictar +diente +dieta +diez +difícil +digno +dilema +diluir +dinero +directo +dirigir +disco +diseño +disfraz +diva +divino +doble +doce +dolor +domingo +don +donar +dorado +dormir +dorso +dos +dosis +dragón +droga +ducha +duda +duelo +dueño +dulce +dúo +duque +durar +dureza +duro +ébano +ebrio +echar +eco +ecuador +edad +edición +edificio +editor +educar +efecto +eficaz +eje +ejemplo +elefante +elegir +elemento +elevar +elipse +élite +elixir +elogio +eludir +embudo +emitir +emoción +empate +empeño +empleo +empresa +enano +encargo +enchufe +encía +enemigo +enero +enfado +enfermo +engaño +enigma +enlace +enorme +enredo +ensayo +enseñar +entero +entrar +envase +envío +época +equipo +erizo +escala +escena +escolar +escribir +escudo +esencia +esfera +esfuerzo +espada +espejo +espía +esposa +espuma +esquí +estar +este +estilo +estufa +etapa +eterno +ética +etnia +evadir +evaluar +evento +evitar +exacto +examen +exceso +excusa +exento +exigir +exilio +existir +éxito +experto +explicar +exponer +extremo +fábrica +fábula +fachada +fácil +factor +faena +faja +falda +fallo +falso +faltar +fama +familia +famoso +faraón +farmacia +farol +farsa +fase +fatiga +fauna +favor +fax +febrero +fecha +feliz +feo +feria +feroz +fértil +fervor +festín +fiable +fianza +fiar +fibra +ficción +ficha +fideo +fiebre +fiel +fiera +fiesta +figura +fijar +fijo +fila +filete +filial +filtro +fin +finca +fingir +finito +firma +flaco +flauta +flecha +flor +flota +fluir +flujo +flúor +fobia +foca +fogata +fogón +folio +folleto +fondo +forma +forro +fortuna +forzar +fosa +foto +fracaso +frágil +franja +frase +fraude +freír +freno +fresa +frío +frito +fruta +fuego +fuente +fuerza +fuga +fumar +función +funda +furgón +furia +fusil +fútbol +futuro +gacela +gafas +gaita +gajo +gala +galería +gallo +gamba +ganar +gancho +ganga +ganso +garaje +garza +gasolina +gastar +gato +gavilán +gemelo +gemir +gen +género +genio +gente +geranio +gerente +germen +gesto +gigante +gimnasio +girar +giro +glaciar +globo +gloria +gol +golfo +goloso +golpe +goma +gordo +gorila +gorra +gota +goteo +gozar +grada +gráfico +grano +grasa +gratis +grave +grieta +grillo +gripe +gris +grito +grosor +grúa +grueso +grumo +grupo +guante +guapo +guardia +guerra +guía +guiño +guion +guiso +guitarra +gusano +gustar +haber +hábil +hablar +hacer +hacha +hada +hallar +hamaca +harina +haz +hazaña +hebilla +hebra +hecho +helado +helio +hembra +herir +hermano +héroe +hervir +hielo +hierro +hígado +higiene +hijo +himno +historia +hocico +hogar +hoguera +hoja +hombre +hongo +honor +honra +hora +hormiga +horno +hostil +hoyo +hueco +huelga +huerta +hueso +huevo +huida +huir +humano +húmedo +humilde +humo +hundir +huracán +hurto +icono +ideal +idioma +ídolo +iglesia +iglú +igual +ilegal +ilusión +imagen +imán +imitar +impar +imperio +imponer +impulso +incapaz +índice +inerte +infiel +informe +ingenio +inicio +inmenso +inmune +innato +insecto +instante +interés +íntimo +intuir +inútil +invierno +ira +iris +ironía +isla +islote +jabalí +jabón +jamón +jarabe +jardín +jarra +jaula +jazmín +jefe +jeringa +jinete +jornada +joroba +joven +joya +juerga +jueves +juez +jugador +jugo +juguete +juicio +junco +jungla +junio +juntar +júpiter +jurar +justo +juvenil +juzgar +kilo +koala +labio +lacio +lacra +lado +ladrón +lagarto +lágrima +laguna +laico +lamer +lámina +lámpara +lana +lancha +langosta +lanza +lápiz +largo +larva +lástima +lata +látex +latir +laurel +lavar +lazo +leal +lección +leche +lector +leer +legión +legumbre +lejano +lengua +lento +leña +león +leopardo +lesión +letal +letra +leve +leyenda +libertad +libro +licor +líder +lidiar +lienzo +liga +ligero +lima +límite +limón +limpio +lince +lindo +línea +lingote +lino +linterna +líquido +liso +lista +litera +litio +litro +llaga +llama +llanto +llave +llegar +llenar +llevar +llorar +llover +lluvia +lobo +loción +loco +locura +lógica +logro +lombriz +lomo +lonja +lote +lucha +lucir +lugar +lujo +luna +lunes +lupa +lustro +luto +luz +maceta +macho +madera +madre +maduro +maestro +mafia +magia +mago +maíz +maldad +maleta +malla +malo +mamá +mambo +mamut +manco +mando +manejar +manga +maniquí +manjar +mano +manso +manta +mañana +mapa +máquina +mar +marco +marea +marfil +margen +marido +mármol +marrón +martes +marzo +masa +máscara +masivo +matar +materia +matiz +matriz +máximo +mayor +mazorca +mecha +medalla +medio +médula +mejilla +mejor +melena +melón +memoria +menor +mensaje +mente +menú +mercado +merengue +mérito +mes +mesón +meta +meter +método +metro +mezcla +miedo +miel +miembro +miga +mil +milagro +militar +millón +mimo +mina +minero +mínimo +minuto +miope +mirar +misa +miseria +misil +mismo +mitad +mito +mochila +moción +moda +modelo +moho +mojar +molde +moler +molino +momento +momia +monarca +moneda +monja +monto +moño +morada +morder +moreno +morir +morro +morsa +mortal +mosca +mostrar +motivo +mover +móvil +mozo +mucho +mudar +mueble +muela +muerte +muestra +mugre +mujer +mula +muleta +multa +mundo +muñeca +mural +muro +músculo +museo +musgo +música +muslo +nácar +nación +nadar +naipe +naranja +nariz +narrar +nasal +natal +nativo +natural +náusea +naval +nave +navidad +necio +néctar +negar +negocio +negro +neón +nervio +neto +neutro +nevar +nevera +nicho +nido +niebla +nieto +niñez +niño +nítido +nivel +nobleza +noche +nómina +noria +norma +norte +nota +noticia +novato +novela +novio +nube +nuca +núcleo +nudillo +nudo +nuera +nueve +nuez +nulo +número +nutria +oasis +obeso +obispo +objeto +obra +obrero +observar +obtener +obvio +oca +ocaso +océano +ochenta +ocho +ocio +ocre +octavo +octubre +oculto +ocupar +ocurrir +odiar +odio +odisea +oeste +ofensa +oferta +oficio +ofrecer +ogro +oído +oír +ojo +ola +oleada +olfato +olivo +olla +olmo +olor +olvido +ombligo +onda +onza +opaco +opción +ópera +opinar +oponer +optar +óptica +opuesto +oración +orador +oral +órbita +orca +orden +oreja +órgano +orgía +orgullo +oriente +origen +orilla +oro +orquesta +oruga +osadía +oscuro +osezno +oso +ostra +otoño +otro +oveja +óvulo +óxido +oxígeno +oyente +ozono +pacto +padre +paella +página +pago +país +pájaro +palabra +palco +paleta +pálido +palma +paloma +palpar +pan +panal +pánico +pantera +pañuelo +papá +papel +papilla +paquete +parar +parcela +pared +parir +paro +párpado +parque +párrafo +parte +pasar +paseo +pasión +paso +pasta +pata +patio +patria +pausa +pauta +pavo +payaso +peatón +pecado +pecera +pecho +pedal +pedir +pegar +peine +pelar +peldaño +pelea +peligro +pellejo +pelo +peluca +pena +pensar +peñón +peón +peor +pepino +pequeño +pera +percha +perder +pereza +perfil +perico +perla +permiso +perro +persona +pesa +pesca +pésimo +pestaña +pétalo +petróleo +pez +pezuña +picar +pichón +pie +piedra +pierna +pieza +pijama +pilar +piloto +pimienta +pino +pintor +pinza +piña +piojo +pipa +pirata +pisar +piscina +piso +pista +pitón +pizca +placa +plan +plata +playa +plaza +pleito +pleno +plomo +pluma +plural +pobre +poco +poder +podio +poema +poesía +poeta +polen +policía +pollo +polvo +pomada +pomelo +pomo +pompa +poner +porción +portal +posada +poseer +posible +poste +potencia +potro +pozo +prado +precoz +pregunta +premio +prensa +preso +previo +primo +príncipe +prisión +privar +proa +probar +proceso +producto +proeza +profesor +programa +prole +promesa +pronto +propio +próximo +prueba +público +puchero +pudor +pueblo +puerta +puesto +pulga +pulir +pulmón +pulpo +pulso +puma +punto +puñal +puño +pupa +pupila +puré +quedar +queja +quemar +querer +queso +quieto +química +quince +quitar +rábano +rabia +rabo +ración +radical +raíz +rama +rampa +rancho +rango +rapaz +rápido +rapto +rasgo +raspa +rato +rayo +raza +razón +reacción +realidad +rebaño +rebote +recaer +receta +rechazo +recoger +recreo +recto +recurso +red +redondo +reducir +reflejo +reforma +refrán +refugio +regalo +regir +regla +regreso +rehén +reino +reír +reja +relato +relevo +relieve +relleno +reloj +remar +remedio +remo +rencor +rendir +renta +reparto +repetir +reposo +reptil +res +rescate +resina +respeto +resto +resumen +retiro +retorno +retrato +reunir +revés +revista +rey +rezar +rico +riego +rienda +riesgo +rifa +rígido +rigor +rincón +riñón +río +riqueza +risa +ritmo +rito +rizo +roble +roce +rociar +rodar +rodeo +rodilla +roer +rojizo +rojo +romero +romper +ron +ronco +ronda +ropa +ropero +rosa +rosca +rostro +rotar +rubí +rubor +rudo +rueda +rugir +ruido +ruina +ruleta +rulo +rumbo +rumor +ruptura +ruta +rutina +sábado +saber +sabio +sable +sacar +sagaz +sagrado +sala +saldo +salero +salir +salmón +salón +salsa +salto +salud +salvar +samba +sanción +sandía +sanear +sangre +sanidad +sano +santo +sapo +saque +sardina +sartén +sastre +satán +sauna +saxofón +sección +seco +secreto +secta +sed +seguir +seis +sello +selva +semana +semilla +senda +sensor +señal +señor +separar +sepia +sequía +ser +serie +sermón +servir +sesenta +sesión +seta +setenta +severo +sexo +sexto +sidra +siesta +siete +siglo +signo +sílaba +silbar +silencio +silla +símbolo +simio +sirena +sistema +sitio +situar +sobre +socio +sodio +sol +solapa +soldado +soledad +sólido +soltar +solución +sombra +sondeo +sonido +sonoro +sonrisa +sopa +soplar +soporte +sordo +sorpresa +sorteo +sostén +sótano +suave +subir +suceso +sudor +suegra +suelo +sueño +suerte +sufrir +sujeto +sultán +sumar +superar +suplir +suponer +supremo +sur +surco +sureño +surgir +susto +sutil +tabaco +tabique +tabla +tabú +taco +tacto +tajo +talar +talco +talento +talla +talón +tamaño +tambor +tango +tanque +tapa +tapete +tapia +tapón +taquilla +tarde +tarea +tarifa +tarjeta +tarot +tarro +tarta +tatuaje +tauro +taza +tazón +teatro +techo +tecla +técnica +tejado +tejer +tejido +tela +teléfono +tema +temor +templo +tenaz +tender +tener +tenis +tenso +teoría +terapia +terco +término +ternura +terror +tesis +tesoro +testigo +tetera +texto +tez +tibio +tiburón +tiempo +tienda +tierra +tieso +tigre +tijera +tilde +timbre +tímido +timo +tinta +tío +típico +tipo +tira +tirón +titán +títere +título +tiza +toalla +tobillo +tocar +tocino +todo +toga +toldo +tomar +tono +tonto +topar +tope +toque +tórax +torero +tormenta +torneo +toro +torpedo +torre +torso +tortuga +tos +tosco +toser +tóxico +trabajo +tractor +traer +tráfico +trago +traje +tramo +trance +trato +trauma +trazar +trébol +tregua +treinta +tren +trepar +tres +tribu +trigo +tripa +triste +triunfo +trofeo +trompa +tronco +tropa +trote +trozo +truco +trueno +trufa +tubería +tubo +tuerto +tumba +tumor +túnel +túnica +turbina +turismo +turno +tutor +ubicar +úlcera +umbral +unidad +unir +universo +uno +untar +uña +urbano +urbe +urgente +urna +usar +usuario +útil +utopía +uva +vaca +vacío +vacuna +vagar +vago +vaina +vajilla +vale +válido +valle +valor +válvula +vampiro +vara +variar +varón +vaso +vecino +vector +vehículo +veinte +vejez +vela +velero +veloz +vena +vencer +venda +veneno +vengar +venir +venta +venus +ver +verano +verbo +verde +vereda +verja +verso +verter +vía +viaje +vibrar +vicio +víctima +vida +vídeo +vidrio +viejo +viernes +vigor +vil +villa +vinagre +vino +viñedo +violín +viral +virgo +virtud +visor +víspera +vista +vitamina +viudo +vivaz +vivero +vivir +vivo +volcán +volumen +volver +voraz +votar +voto +voz +vuelo +vulgar +yacer +yate +yegua +yema +yerno +yeso +yodo +yoga +yogur +zafiro +zanja +zapato +zarza +zona +zorro +zumo +zurdo diff --git a/pybtc/block.py b/pybtc/block.py new file mode 100644 index 0000000..1f1be47 --- /dev/null +++ b/pybtc/block.py @@ -0,0 +1,97 @@ +from struct import unpack, pack +from io import BytesIO +from pybtc.functions.block import bits_to_target, target_to_difficulty +from pybtc.functions.hash import double_sha256 +from pybtc.functions.tools import var_int_to_int, read_var_int, var_int_len, rh2s +from pybtc.transaction import Transaction + + +class Block(dict): + def __init__(self, raw_block=None, format="decoded", version=536870912, testnet=False): + if format not in ("decoded", "raw"): + raise ValueError("tx_format error, raw or decoded allowed") + self["format"] = format + self["testnet"] = testnet + self["header"] = None + self["hash"] = None + self["version"] = version + self["versionHex"] = pack(">L", version).hex() + self["previousBlockHash"] = None + self["merkleRoot"] = None + self["tx"] = dict() + self["time"] = None + self["bits"] = None + self["nonce"] = None + self["weight"] = 0 + self["size"] = 80 + self["strippedSize"] = 80 + self["amount"] = 0 + self["height"] = None + self["difficulty"] = None + self["targetDifficulty"] = None + self["target"] = None + if raw_block is None: + return + self["size"] = len(raw_block) if isinstance(raw_block, bytes) else int(len(raw_block)/2) + s = self.get_stream(raw_block) + self["format"] = "raw" + self["version"] = unpack("L", self["version"]).hex() + self["previousBlockHash"] = s.read(32) + self["merkleRoot"] = s.read(32) + self["time"] = unpack(" order/2 to a checksig operation +# causes script failure +# (softfork safe, BIP62 rule 5). +SCRIPT_VERIFY_NULLDUMMY = 0b0000000000100000 +# verify dummy stack item consumed by CHECKMULTISIG is of zero-length +# (softfork safe, BIP62 rule 7). +SCRIPT_VERIFY_SIGPUSHONLY = 0b0000000001000000 +# Using a non-push operator in the scriptSig causes script failure +# (softfork safe, BIP62 rule 2). +SCRIPT_VERIFY_MINIMALDATA = 0b0000000010000000 +# Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE +# where possible, direct pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, +# OP_PUSHDATA2 for anything larger). Evaluating any other push causes the script +# to fail (BIP62 rule 3). In addition, whenever a stack element is interpreted +# as a number, it must be of minimal length (BIP62 rule 4). +SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = 0b0000000100000000 +# Discourage use of NOPs reserved for upgrades (NOP1-10) +# Provided so that nodes can avoid accepting or mining transactions +# containing executed NOP's whose meaning may change after a soft-fork, +# thus rendering the script invalid; with this flag set executing +# discouraged NOPs fails the script. This verification flag will never be +# a mandatory flag applied to scripts in a block. NOPs that are not +# executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected. +SCRIPT_VERIFY_CLEANSTACK = 0b0000001000000000 +# Require that only a single stack element remains after evaluation. This changes the success criterion from +# "At least one stack element must remain, and when interpreted as a boolean, it must be true" to +# "Exactly one stack element must remain, and when interpreted as a boolean, it must be true". +# (softfork safe, BIP62 rule 6) +# Note: CLEANSTACK should never be used without P2SH. +SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = 0b0000010000000000 +# See BIP65 for details. +SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = 0b0000100000000000 +# See BIP112 for details + + +MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH +STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS |\ + SCRIPT_VERIFY_STRICTENC |\ + SCRIPT_VERIFY_MINIMALDATA |\ + SCRIPT_VERIFY_NULLDUMMY |\ + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |\ + SCRIPT_VERIFY_CLEANSTACK \ No newline at end of file diff --git a/pybtc/constants.py b/pybtc/constants.py new file mode 100644 index 0000000..da656be --- /dev/null +++ b/pybtc/constants.py @@ -0,0 +1,92 @@ +from secp256k1 import lib +import random +import os + +ROOT_DIR = os.path.abspath(os.path.dirname(__file__)) +BIP0039_DIR = os.path.normpath(os.path.join(ROOT_DIR, 'bip39_word_list')) + +MAX_AMOUNT = 16000000000000000 +SIGHASH_ALL = 0x00000001 +SIGHASH_NONE = 0x00000002 +SIGHASH_SINGLE = 0x00000003 +SIGHASH_ANYONECANPAY = 0x00000080 +ECDSA_SEC256K1_ORDER = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 + +MAINNET_ADDRESS_BYTE_PREFIX = b'\x23' +TESTNET_ADDRESS_BYTE_PREFIX = b'\x73' +MAINNET_SCRIPT_ADDRESS_BYTE_PREFIX = b'\x05' +TESTNET_SCRIPT_ADDRESS_BYTE_PREFIX = b'\xc4' +MAINNET_SEGWIT_ADDRESS_BYTE_PREFIX = b'\x03\x03\x00\x02\x03' +TESTNET_SEGWIT_ADDRESS_BYTE_PREFIX = b'\x03\x03\x00\x14\x02' + +MAINNET_ADDRESS_PREFIX = 'F' +TESTNET_ADDRESS_PREFIX = 'o' +TESTNET_ADDRESS_PREFIX_2 = 'o' +MAINNET_SCRIPT_ADDRESS_PREFIX = '3' +TESTNET_SCRIPT_ADDRESS_PREFIX = '2' + +MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX = '5' +MAINNET_PRIVATE_KEY_COMPRESSED_PREFIX = 'R' +MAINNET_PRIVATE_KEY_COMPRESSED_PREFIX_2 = 'R' +TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX = '9' +TESTNET_PRIVATE_KEY_COMPRESSED_PREFIX = 'c' + +ADDRESS_PREFIX_LIST = (MAINNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX_2, + MAINNET_SCRIPT_ADDRESS_PREFIX, + TESTNET_SCRIPT_ADDRESS_PREFIX) + +PRIVATE_KEY_PREFIX_LIST = (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, + MAINNET_PRIVATE_KEY_COMPRESSED_PREFIX, + MAINNET_PRIVATE_KEY_COMPRESSED_PREFIX_2, + TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, + TESTNET_PRIVATE_KEY_COMPRESSED_PREFIX) + +MAINNET_PRIVATE_KEY_BYTE_PREFIX = b'\xa3' +TESTNET_PRIVATE_KEY_BYTE_PREFIX = b'\xef' + +MAINNET_SEGWIT_ADDRESS_PREFIX = 'bc' +TESTNET_SEGWIT_ADDRESS_PREFIX = 'tb' + + +EC_COMPRESSED = lib.SECP256K1_EC_COMPRESSED +EC_UNCOMPRESSED = lib.SECP256K1_EC_UNCOMPRESSED + +FLAG_SIGN = lib.SECP256K1_CONTEXT_SIGN +FLAG_VERIFY = lib.SECP256K1_CONTEXT_VERIFY +ALL_FLAGS = FLAG_SIGN | FLAG_VERIFY +NO_FLAGS = lib.SECP256K1_CONTEXT_NONE + +HAS_RECOVERABLE = hasattr(lib, 'secp256k1_ecdsa_sign_recoverable') +HAS_SCHNORR = hasattr(lib, 'secp256k1_schnorr_sign') +HAS_ECDH = hasattr(lib, 'secp256k1_ecdh') + +ECDSA_CONTEXT_SIGN = lib.secp256k1_context_create(FLAG_SIGN) +ECDSA_CONTEXT_VERIFY = lib.secp256k1_context_create(FLAG_VERIFY) +ECDSA_CONTEXT_ALL = lib.secp256k1_context_create(ALL_FLAGS) +lib.secp256k1_context_randomize(ECDSA_CONTEXT_SIGN, + random.SystemRandom().randint(0, ECDSA_SEC256K1_ORDER).to_bytes(32, byteorder="big")) + +SCRIPT_TYPES = {"P2PKH": 0, + "P2SH": 1, + "PUBKEY": 2, + "NULL_DATA": 3, + "MULTISIG": 4, + "P2WPKH": 5, + "P2WSH": 6, + "NON_STANDARD": 7, + "NULL_DATA_NON_STANDARD": 8 + } + + +# CONSTANTS hierarchical deterministic wallets (HD Wallets) +MAINNET_XPRIVATE_KEY_PREFIX = b'\x04\x88\xAD\xE4' +MAINNET_XPUBLIC_KEY_PREFIX = b'\x04\x88\xB2\x1E' +TESTNET_XPRIVATE_KEY_PREFIX = b'\x04\x35\x83\x94' +TESTNET_XPUBLIC_KEY_PREFIX = b'\x04\x35\x87\xCF' +HARDENED_KEY = 0x80000000 +FIRST_HARDENED_CHILD = 0x80000000 +PATH_LEVEL_BIP0044 = [0x8000002C, 0x80000000, 0x80000000, 0, 0] +TESTNET_PATH_LEVEL_BIP0044 = [0x8000002C, 0x80000001, 0x80000000, 0, 0] + diff --git a/pybtc/functions/__init__.py b/pybtc/functions/__init__.py new file mode 100644 index 0000000..f6cab7b --- /dev/null +++ b/pybtc/functions/__init__.py @@ -0,0 +1,9 @@ +from .key import * +from .address import * +from .script import * +from .tools import * +from .hash import * +from .block import * +from .encode import * +from .bip39_mnemonic import * +from .bip32 import * \ No newline at end of file diff --git a/pybtc/functions/__pycache__/__init__.cpython-36.pyc b/pybtc/functions/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..d9a875e Binary files /dev/null and b/pybtc/functions/__pycache__/__init__.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/__init__.cpython-38.pyc b/pybtc/functions/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..ab4183e Binary files /dev/null and b/pybtc/functions/__pycache__/__init__.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/address.cpython-36.pyc b/pybtc/functions/__pycache__/address.cpython-36.pyc new file mode 100644 index 0000000..6ffd223 Binary files /dev/null and b/pybtc/functions/__pycache__/address.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/address.cpython-38.pyc b/pybtc/functions/__pycache__/address.cpython-38.pyc new file mode 100644 index 0000000..c5b38e1 Binary files /dev/null and b/pybtc/functions/__pycache__/address.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/bip32.cpython-36.pyc b/pybtc/functions/__pycache__/bip32.cpython-36.pyc new file mode 100644 index 0000000..95a53fa Binary files /dev/null and b/pybtc/functions/__pycache__/bip32.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/bip32.cpython-38.pyc b/pybtc/functions/__pycache__/bip32.cpython-38.pyc new file mode 100644 index 0000000..2b78eb2 Binary files /dev/null and b/pybtc/functions/__pycache__/bip32.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/bip39_mnemonic.cpython-36.pyc b/pybtc/functions/__pycache__/bip39_mnemonic.cpython-36.pyc new file mode 100644 index 0000000..46bfdae Binary files /dev/null and b/pybtc/functions/__pycache__/bip39_mnemonic.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/bip39_mnemonic.cpython-38.pyc b/pybtc/functions/__pycache__/bip39_mnemonic.cpython-38.pyc new file mode 100644 index 0000000..9f942fa Binary files /dev/null and b/pybtc/functions/__pycache__/bip39_mnemonic.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/block.cpython-36.pyc b/pybtc/functions/__pycache__/block.cpython-36.pyc new file mode 100644 index 0000000..de5d4a5 Binary files /dev/null and b/pybtc/functions/__pycache__/block.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/block.cpython-38.pyc b/pybtc/functions/__pycache__/block.cpython-38.pyc new file mode 100644 index 0000000..57000dd Binary files /dev/null and b/pybtc/functions/__pycache__/block.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/encode.cpython-36.pyc b/pybtc/functions/__pycache__/encode.cpython-36.pyc new file mode 100644 index 0000000..5023da7 Binary files /dev/null and b/pybtc/functions/__pycache__/encode.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/encode.cpython-38.pyc b/pybtc/functions/__pycache__/encode.cpython-38.pyc new file mode 100644 index 0000000..00760cb Binary files /dev/null and b/pybtc/functions/__pycache__/encode.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/hash.cpython-36.pyc b/pybtc/functions/__pycache__/hash.cpython-36.pyc new file mode 100644 index 0000000..11b6ea8 Binary files /dev/null and b/pybtc/functions/__pycache__/hash.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/hash.cpython-38.pyc b/pybtc/functions/__pycache__/hash.cpython-38.pyc new file mode 100644 index 0000000..1f565af Binary files /dev/null and b/pybtc/functions/__pycache__/hash.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/key.cpython-36.pyc b/pybtc/functions/__pycache__/key.cpython-36.pyc new file mode 100644 index 0000000..ae876e7 Binary files /dev/null and b/pybtc/functions/__pycache__/key.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/key.cpython-38.pyc b/pybtc/functions/__pycache__/key.cpython-38.pyc new file mode 100644 index 0000000..fd42042 Binary files /dev/null and b/pybtc/functions/__pycache__/key.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/script.cpython-36.pyc b/pybtc/functions/__pycache__/script.cpython-36.pyc new file mode 100644 index 0000000..57fe3eb Binary files /dev/null and b/pybtc/functions/__pycache__/script.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/script.cpython-38.pyc b/pybtc/functions/__pycache__/script.cpython-38.pyc new file mode 100644 index 0000000..0bc4ac0 Binary files /dev/null and b/pybtc/functions/__pycache__/script.cpython-38.pyc differ diff --git a/pybtc/functions/__pycache__/tools.cpython-36.pyc b/pybtc/functions/__pycache__/tools.cpython-36.pyc new file mode 100644 index 0000000..381a71c Binary files /dev/null and b/pybtc/functions/__pycache__/tools.cpython-36.pyc differ diff --git a/pybtc/functions/__pycache__/tools.cpython-38.pyc b/pybtc/functions/__pycache__/tools.cpython-38.pyc new file mode 100644 index 0000000..55b3b7f Binary files /dev/null and b/pybtc/functions/__pycache__/tools.cpython-38.pyc differ diff --git a/pybtc/functions/address.py b/pybtc/functions/address.py new file mode 100644 index 0000000..fb489ff --- /dev/null +++ b/pybtc/functions/address.py @@ -0,0 +1,285 @@ +from pybtc.opcodes import * +from pybtc.constants import * + +from pybtc.functions.tools import bytes_from_hex +from pybtc.functions.hash import double_sha256, hash160 +from pybtc.functions.encode import (encode_base58, + rebase_8_to_5, + bech32_polymod, + rebase_5_to_32, + decode_base58, + rebase_5_to_8, + rebase_32_to_5, + base32charset, + base32charset_upcase) + + +def hash_to_address(address_hash, testnet=False, script_hash=False, witness_version=0): + """ + Get address from public key/script hash. In case PUBKEY, P2PKH, P2PKH public key/script hash is SHA256+RIPEMD160, + P2WSH script hash is SHA256. + + + :param address_hash: public key hash or script hash in HEX or bytes string format. + :param testnet: (optional) flag for testnet network, by default is False. + :param script_hash: (optional) flag for script hash (P2SH address), by default is False. + :param witness_version: (optional) witness program version, by default is 0, for legacy + address format use None. + :return: address in base58 or bech32 format. + """ + if isinstance(address_hash, str): + address_hash = bytes_from_hex(address_hash) + if not isinstance(address_hash, bytes): + raise TypeError("address hash must be HEX encoded string or bytes") + + if not script_hash: + if witness_version is None: + if len(address_hash) != 20: + raise ValueError("address hash length incorrect") + if testnet: + prefix = TESTNET_ADDRESS_BYTE_PREFIX + else: + prefix = MAINNET_ADDRESS_BYTE_PREFIX + address_hash = b"%s%s" % (prefix, address_hash) + address_hash += double_sha256(address_hash)[:4] + return encode_base58(address_hash) + else: + if len(address_hash) not in (20, 32): + raise ValueError("address hash length incorrect") + + if witness_version is None: + if testnet: + prefix = TESTNET_SCRIPT_ADDRESS_BYTE_PREFIX + else: + prefix = MAINNET_SCRIPT_ADDRESS_BYTE_PREFIX + address_hash = b"%s%s" % (prefix, address_hash) + address_hash += double_sha256(address_hash)[:4] + return encode_base58(address_hash) + + if testnet: + prefix = TESTNET_SEGWIT_ADDRESS_BYTE_PREFIX + hrp = TESTNET_SEGWIT_ADDRESS_PREFIX + else: + prefix = MAINNET_SEGWIT_ADDRESS_BYTE_PREFIX + hrp = MAINNET_SEGWIT_ADDRESS_PREFIX + + address_hash = b"%s%s" % (witness_version.to_bytes(1, "big"), + rebase_8_to_5(address_hash)) + checksum = bech32_polymod(b"%s%s%s" % (prefix, address_hash, b"\x00" * 6)) + checksum = rebase_8_to_5(checksum.to_bytes(5, "big"))[2:] + return "%s1%s" % (hrp, rebase_5_to_32(address_hash + checksum).decode()) + + +def public_key_to_address(pubkey, testnet=False, p2sh_p2wpkh=False, witness_version=0): + """ + Get address from public key/script hash. In case PUBKEY, P2PKH, P2PKH public key/script hash is SHA256+RIPEMD160, + P2WSH script hash is SHA256. + + :param pubkey: public key HEX or bytes string format. + :param testnet: (optional) flag for testnet network, by default is False. + :param p2sh_p2wpkh: (optional) flag for P2WPKH inside P2SH address, by default is False. + :param witness_version: (optional) witness program version, by default is 0, for legacy + address format use None. + :return: address in base58 or bech32 format. + """ + if isinstance(pubkey, str): + pubkey = bytes.fromhex(pubkey) + if not isinstance(pubkey, bytes): + raise TypeError("public key invalid, expected bytes or str") + if p2sh_p2wpkh: + if len(pubkey) != 33: + raise ValueError("public key invalid") + h = hash160(b'\x00\x14%s' % hash160(pubkey)) + witness_version = None + else: + if witness_version is not None: + if len(pubkey) != 33: + raise ValueError("public key invalid") + h = hash160(pubkey) + return hash_to_address(h, testnet=testnet, + script_hash=p2sh_p2wpkh, + witness_version=witness_version) + + +def address_to_hash(address, hex=True): + """ + Get address hash from base58 or bech32 address format. + + :param address: address in base58 or bech32 format. + :param hex: (optional) If set to True return key in HEX format, by default is True. + :return: script in HEX or bytes string. + """ + if address[0] in ADDRESS_PREFIX_LIST: + h = decode_base58(address)[1:-4] + elif address.split("1")[0] in (MAINNET_SEGWIT_ADDRESS_PREFIX, + TESTNET_SEGWIT_ADDRESS_PREFIX): + address = address.split("1")[1] + h = rebase_5_to_8(rebase_32_to_5(address)[1:-6], False) + else: + return None + return h.hex() if hex else h + + +def address_type(address, num=False): + """ + Get address type. + + :param address: address in base58 or bech32 format. + :param num: (optional) If set to True return type in numeric format, by default is False. + :return: address type in string or numeric format. + """ + if address[0] in (TESTNET_SCRIPT_ADDRESS_PREFIX, + MAINNET_SCRIPT_ADDRESS_PREFIX): + t = 'P2SH' + elif address[0] in (MAINNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX_2): + t = 'P2PKH' + elif address[:2] in (MAINNET_SEGWIT_ADDRESS_PREFIX, + TESTNET_SEGWIT_ADDRESS_PREFIX): + if len(address) == 42: + t = 'P2WPKH' + elif len(address) == 62: + t = 'P2WSH' + else: + return SCRIPT_TYPES['NON_STANDARD'] if num else 'UNKNOWN' + else: + return SCRIPT_TYPES['NON_STANDARD'] if num else 'UNKNOWN' + return SCRIPT_TYPES[t] if num else t + + +def address_net_type(address): + """ + Get address network type. + + :param address: address in base58 or bech32 format. + :return: address network type in string format or None. + """ + if address[0] in (MAINNET_SCRIPT_ADDRESS_PREFIX, + MAINNET_ADDRESS_PREFIX): + return "mainnet" + elif address[:2] == MAINNET_SEGWIT_ADDRESS_PREFIX: + return "mainnet" + elif address[0] in (TESTNET_SCRIPT_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX_2): + return "testnet" + elif address[:2] == TESTNET_SEGWIT_ADDRESS_PREFIX: + return "testnet" + return None + + +def address_to_script(address, hex=False): + """ + Get public key script from address. + + :param address: address in base58 or bech32 format. + :param hex: (optional) If set to True return key in HEX format, by default is True. + :return: public key script in HEX or bytes string. + """ + if address[0] in (TESTNET_SCRIPT_ADDRESS_PREFIX, + MAINNET_SCRIPT_ADDRESS_PREFIX): + s = [OP_HASH160, + b'\x14', + address_to_hash(address, hex=False), + OP_EQUAL] + elif address[0] in (MAINNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX_2): + s = [OP_DUP, + OP_HASH160, + b'\x14', + address_to_hash(address, hex=False), + OP_EQUALVERIFY, + OP_CHECKSIG] + elif address[:2] in (TESTNET_SEGWIT_ADDRESS_PREFIX, + MAINNET_SEGWIT_ADDRESS_PREFIX): + h = address_to_hash(address, hex=False) + s = [OP_0, + bytes([len(h)]), + h] + else: + raise ValueError("address invalid") + s = b''.join(s) + return s.hex() if hex else s + + +def public_key_to_p2sh_p2wpkh_script(pubkey): + if len(pubkey) != 33: + raise ValueError("public key len invalid") + return b'\x00\x14%s' % hash160(pubkey) + + +def is_address_valid(address, testnet=False): + """ + Check is address valid. + + :param address: address in base58 or bech32 format. + :param testnet: (optional) flag for testnet network, by default is False. + :return: boolean. + """ + if not address or type(address) != str: + return False + if address[0] in (MAINNET_ADDRESS_PREFIX, + MAINNET_SCRIPT_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX_2, + TESTNET_SCRIPT_ADDRESS_PREFIX): + if testnet: + if address[0] not in (TESTNET_ADDRESS_PREFIX, + TESTNET_ADDRESS_PREFIX_2, + TESTNET_SCRIPT_ADDRESS_PREFIX): + return False + else: + if address[0] not in (MAINNET_ADDRESS_PREFIX, + MAINNET_SCRIPT_ADDRESS_PREFIX): + return False + h = decode_base58(address) + if len(h) != 25: + return False + checksum = h[-4:] + if double_sha256(h[:-4])[:4] != checksum: + return False + return True + elif address[:2].lower() in (TESTNET_SEGWIT_ADDRESS_PREFIX, + MAINNET_SEGWIT_ADDRESS_PREFIX): + if len(address) not in (42, 62): + return False + try: + prefix, payload = address.split('1') + except: + return False + upp = True if prefix[0].isupper() else False + for i in payload[1:]: + if upp: + if not i.isupper() or i not in base32charset_upcase: + return False + else: + if i.isupper() or i not in base32charset: + return False + payload = payload.lower() + prefix = prefix.lower() + if testnet: + if prefix != TESTNET_SEGWIT_ADDRESS_PREFIX: + return False + stripped_prefix = TESTNET_SEGWIT_ADDRESS_BYTE_PREFIX + else: + if prefix != MAINNET_SEGWIT_ADDRESS_PREFIX: + return False + stripped_prefix = MAINNET_SEGWIT_ADDRESS_BYTE_PREFIX + d = rebase_32_to_5(payload) + address_hash = d[:-6] + checksum = d[-6:] + checksum2 = bech32_polymod(b"%s%s%s" % (stripped_prefix, address_hash, b"\x00" * 6)) + checksum2 = rebase_8_to_5(checksum2.to_bytes(5, "big"))[2:] + if checksum != checksum2: + return False + return True + + +def get_witness_version(address): + address = address.split("1")[1] + h = rebase_32_to_5(address) + return h[0] + + diff --git a/pybtc/functions/bip32.py b/pybtc/functions/bip32.py new file mode 100644 index 0000000..624902a --- /dev/null +++ b/pybtc/functions/bip32.py @@ -0,0 +1,266 @@ +from struct import pack +from secp256k1 import ffi, lib +from pybtc.functions.key import private_to_public_key, private_key_to_wif +from pybtc.functions.hash import hmac_sha512, double_sha256, hash160 +from pybtc.functions.encode import (encode_base58, + decode_base58_with_checksum, + encode_base58_with_checksum) +from pybtc.constants import * + + +def create_master_xprivate_key(seed, testnet=False, base58=True, hex=False): + """ + Create extended private key from seed + + :param str,bytes key: seed HEX or bytes string. + :param boolean base58: (optional) return result as base58 encoded string, by default True. + :param boolean hex: (optional) return result as HEX encoded string, by default False. + In case True base58 flag value will be ignored. + :return: extended private key in base58, HEX or bytes string format. + """ + if isinstance(seed, str): + seed = bytes.fromhex(seed) + if not isinstance(seed, bytes): + raise TypeError("seed should be bytes or hex encoded string") + i = hmac_sha512(b"Bitcoin seed", seed) + m, c = i[:32], i[32:] + m_int = int.from_bytes(m, byteorder="big") + + if m_int <= 0 or m_int > ECDSA_SEC256K1_ORDER: + return None + prefix = TESTNET_XPRIVATE_KEY_PREFIX if testnet else MAINNET_XPRIVATE_KEY_PREFIX + key = b''.join([prefix, + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00', + c, b'\x00', m]) + if base58: + key = b"".join([key, double_sha256(key)[:4]]) + return encode_base58(key) + else: + return key + + +def xprivate_to_xpublic_key(xprivate_key, base58=True, hex=False): + """ + Get extended public key from extended private key using ECDSA secp256k1 + + :param str,bytes key: extended private key in base58, HEX or bytes string. + :param boolean base58: (optional) return result as base58 encoded string, by default True. + :param boolean hex: (optional) return result as HEX encoded string, by default False. + In case True base58 flag value will be ignored. + :return: extended public key in base58, HEX or bytes string format. + """ + if isinstance(xprivate_key, str): + try: + if len(xprivate_key) == 156: + xprivate_key = bytes.fromhex(xprivate_key) + else: + xprivate_key = decode_base58_with_checksum(xprivate_key) + except: + raise ValueError("invalid extended private key") + if not isinstance(xprivate_key, bytes): + raise TypeError("extended private key should be base58 string or bytes") + if xprivate_key[:4] == TESTNET_XPRIVATE_KEY_PREFIX: + prefix = TESTNET_XPUBLIC_KEY_PREFIX + elif xprivate_key[:4] == MAINNET_XPRIVATE_KEY_PREFIX: + prefix = MAINNET_XPUBLIC_KEY_PREFIX + else: + raise ValueError("invalid extended private key") + + key = b"".join([prefix, + xprivate_key[4:45], + private_to_public_key(xprivate_key[46:], hex=False)]) + if hex: + return key.hex() + elif base58: + key = b"".join([key, double_sha256(key)[:4]]) + return encode_base58(key) + else: + return key + + +def derive_xkey(xkey, *path_level, base58=True, hex=False): + """ + Child Key derivation for extended private/public keys + + :param bytes xkey: extended private/public in base58, HEX or bytes string format. + :param list path_level: list of derivation path levels. For hardened derivation use HARDENED_KEY flag. + :param boolean base58: (optional) return result as base58 encoded string, by default True. + :param boolean hex: (optional) return result as HEX encoded string, by default False. + In case True base58 flag value will be ignored. + :return: extended child private/public key in base58, HEX or bytes string format. + """ + + xkey = decode_base58_with_checksum(xkey) + if xkey[:4] in [MAINNET_XPRIVATE_KEY_PREFIX, TESTNET_XPRIVATE_KEY_PREFIX]: + for i in path_level: + xkey = derive_child_xprivate_key(xkey, i) + elif xkey[:4] in [MAINNET_XPUBLIC_KEY_PREFIX, TESTNET_XPUBLIC_KEY_PREFIX]: + for i in path_level: + xkey = derive_child_xpublic_key(xkey, i) + else: + raise ValueError("invalid extended key") + + if hex: + return xkey.hex() + elif base58: + return encode_base58_with_checksum(xkey) + else: + return xkey + + +def derive_child_xprivate_key(xprivate_key, i): + c = xprivate_key[13:45] + k = xprivate_key[45:] + depth = xprivate_key[4] + 1 + if depth > 255: + raise ValueError("path depth should be <= 255") + pub = private_to_public_key(k[1:], hex=False) + fingerprint = hash160(pub)[:4] + s = hmac_sha512(c, b"%s%s" % (k if i >= HARDENED_KEY else pub, pack(">L", i))) + p_int = int.from_bytes(s[:32],byteorder='big') + if p_int >= ECDSA_SEC256K1_ORDER: + return None + k_int = (int.from_bytes(k[1:], byteorder='big') + p_int) % ECDSA_SEC256K1_ORDER + if not k_int: + return None + key = int.to_bytes(k_int, byteorder = "big", length=32) + return b"".join([xprivate_key[:4], + bytes([depth]), + fingerprint, + pack(">L", i), + s[32:], + b'\x00', + key]) + + +def derive_child_xpublic_key(xpublic_key, i): + c = xpublic_key[13:45] + k = xpublic_key[45:] + fingerprint = hash160(k)[:4] + depth = xpublic_key[4] + 1 + if depth > 255: + raise ValueError("path depth should be <= 255") + if i >= HARDENED_KEY: + raise ValueError("derivation from extended public key impossible") + s = hmac_sha512(c, k + pack(">L", i)) + if int.from_bytes(s[:32], byteorder='big') >= ECDSA_SEC256K1_ORDER: + return None + pubkey_ptr = ffi.new('secp256k1_pubkey *') + if not lib.secp256k1_ec_pubkey_parse(ECDSA_CONTEXT_VERIFY, pubkey_ptr, k, len(k)): + raise RuntimeError("secp256k1 parse public key operation failed") + if not lib.secp256k1_ec_pubkey_tweak_add(ECDSA_CONTEXT_ALL, pubkey_ptr, s[:32]): + raise RuntimeError("secp256k1 parse tweak addition operation failed") + pubkey = ffi.new('char [%d]' % 33) + outlen = ffi.new('size_t *', 33) + if not lib.secp256k1_ec_pubkey_serialize(ECDSA_CONTEXT_VERIFY, pubkey, outlen, pubkey_ptr, EC_COMPRESSED): + raise RuntimeError("secp256k1 serialize public key operation failed") + pk = bytes(ffi.buffer(pubkey, 33)) + print(len(pk)) + return b"".join([xpublic_key[:4], + bytes([depth]), + fingerprint, + pack(">L", i), + s[32:], + pk]) + + +def public_from_xpublic_key(xpublic_key, hex=True): + """ + Get public key from extended public key + + :param bytes xpublic_key: extended public in base58, HEX or bytes string format. + :param boolean base58: (optional) return result as base58 encoded string, by default True. + :param boolean hex: (optional) return result as HEX encoded string, by default False. + In case True base58 flag value will be ignored. + :return: public key in HEX or bytes string format. + """ + if isinstance(xpublic_key, str): + if len(xpublic_key) == 156: + xpublic_key = bytes.fromhex(xpublic_key) + else: + xpublic_key = decode_base58_with_checksum(xpublic_key) + if not isinstance(xpublic_key, bytes): + raise TypeError("xpublic_key should be HEX, Base58 or bytes string") + if xpublic_key[:4] not in [MAINNET_XPUBLIC_KEY_PREFIX, + TESTNET_XPUBLIC_KEY_PREFIX]: + raise ValueError("invalid extended public key") + + return xpublic_key[45:].hex() if hex else xpublic_key[45:] + + +def private_from_xprivate_key(xprivate_key, wif=True, hex=False): + """ + Get private key from extended private key + + :param bytes xprivate_key: extended public in base58, HEX or bytes string format. + :param boolean wif: (optional) return result as WIF format, by default True. + :param boolean hex: (optional) return result as HEX encoded string, by default False. + In case True WIF flag value will be ignored. + :return: private key in HEX or bytes string format. + """ + if isinstance(xprivate_key, str): + if len(xprivate_key) == 156: + xprivate_key = bytes.fromhex(xprivate_key) + else: + xprivate_key = decode_base58_with_checksum(xprivate_key) + if not isinstance(xprivate_key, bytes): + raise TypeError("xprivate_key should be HEX, Base58 or bytes string") + if xprivate_key[:4] not in [MAINNET_XPRIVATE_KEY_PREFIX, + TESTNET_XPRIVATE_KEY_PREFIX]: + raise ValueError("invalid extended private key") + + if hex: + return xprivate_key[46:].hex() + elif wif: + if xprivate_key[:4] == MAINNET_XPRIVATE_KEY_PREFIX: + testnet = False + else: + testnet = True + return private_key_to_wif(xprivate_key[46:], testnet=testnet) + return xprivate_key[46:].hex() if hex else xprivate_key[46:] + + +def is_xprivate_key_valid(key): + """ + Check the extended private key is valid according to BIP-0032. + + :param key: extended private key in BASE58, HEX or bytes string format. + :return: boolean. + """ + if isinstance(key, str): + try: + key = decode_base58_with_checksum(key) + except: + try: + key = bytes.fromhex(key) + except: + pass + if not isinstance(key, bytes) or len(key)!=78: + return False + if key[:4] not in [MAINNET_XPRIVATE_KEY_PREFIX, + TESTNET_XPRIVATE_KEY_PREFIX]: + return False + return True + + +def is_xpublic_key_valid(key): + """ + Check the extended private key is valid according to BIP-0032. + + :param key: extended private key in BASE58, HEX or bytes string format. + :return: boolean. + """ + if isinstance(key, str): + try: + key = decode_base58_with_checksum(key) + except: + try: + key = bytes.fromhex(key) + except: + pass + if not isinstance(key, bytes) or len(key)!=78: + return False + if key[:4] not in [MAINNET_XPUBLIC_KEY_PREFIX, + TESTNET_XPUBLIC_KEY_PREFIX]: + return False + return True \ No newline at end of file diff --git a/pybtc/functions/bip39_mnemonic.py b/pybtc/functions/bip39_mnemonic.py new file mode 100644 index 0000000..43ad391 --- /dev/null +++ b/pybtc/functions/bip39_mnemonic.py @@ -0,0 +1,137 @@ +from pybtc.constants import * +import time +import hashlib +from pybtc.functions.hash import sha256 +from pybtc.functions.tools import int_from_bytes + +def generate_entropy(strength=256, hex=True): + """ + Generate 128-256 bits entropy bytes string + + :param int strength: entropy bits strength, by default is 256 bit. + :param boolean hex: return HEX encoded string result flag, by default True. + :return: HEX encoded or bytes entropy string. + """ + if strength not in [128, 160, 192, 224, 256]: + raise ValueError('strength should be one of the following [128, 160, 192, 224, 256]') + a = random.SystemRandom().randint(0, ECDSA_SEC256K1_ORDER) + i = int((time.time() % 0.01 ) * 100000) + h = a.to_bytes(32, byteorder="big") + # more entropy from system timer and sha256 derivation + while i: + h = hashlib.sha256(h).digest() + i -= 1 + if not i and int_from_bytes(h, byteorder="big") > ECDSA_SEC256K1_ORDER: + i += 1 + return h[:int(strength/8)] if not hex else h[:int(strength/8)].hex() + + +def load_word_list(language='english', word_list_dir=None): + """ + Load the word list from local file. + + :param str language: (optional) uses word list language (chinese_simplified, chinese_traditional, english, french, + italian, japanese, korean, spanish), by default is english. + :param str word_list_dir: (optional) path to a directory containing a list of words, + by default None (use BIP39 standard list) + :return: list of words. + """ + if not word_list_dir: + word_list_dir = BIP0039_DIR + path = os.path.join(word_list_dir, '.'.join((language, 'txt'))) + if not os.path.exists(path): + raise ValueError("word list not exist") + with open(path) as f: + word_list = f.read().rstrip('\n').split('\n') + if len(word_list) != 2048: + raise ValueError("word list invalid, should contain 2048 words") + return word_list + + +def entropy_to_mnemonic(entropy, language='english', word_list_dir=None, word_list=None): + """ + Convert entropy to mnemonic words string. + + :param str,bytes entropy: random entropy HEX encoded or bytes string. + :param str language: (optional) uses word list language (chinese_simplified, chinese_traditional, english, french, + italian, japanese, korean, spanish), by default is english. + :param str word_list_dir: (optional) path to a directory containing a list of words, + by default None (use BIP39 standard list) + :param list word_list: (optional) already loaded word list, by default None + :return: mnemonic words string. + """ + if isinstance(entropy, str): + entropy = bytes.fromhex(entropy) + if not isinstance(entropy, bytes): + raise TypeError("entropy should be bytes or hex encoded string") + if len(entropy) not in [16, 20, 24, 28, 32]: + raise ValueError( + 'entropy length should be one of the following: [16, 20, 24, 28, 32]') + if word_list is None: + word_list = load_word_list(language, word_list_dir) + elif not isinstance(word_list, list) or len(word_list) != 2048: + raise TypeError("invalid word list type") + + i = int.from_bytes(entropy, byteorder="big") + # append checksum + i = (i << len(entropy) * 8 // 32) | sha256(entropy)[0] + + return " ".join([word_list[i.__rshift__(((d - 1) * 11)) & 2047] + for d in range(int((len(entropy) * 8 + 8) // 11), 0, -1)]) + + +def mnemonic_to_entropy(mnemonic, language='english', word_list_dir=None, + word_list=None, hex=True): + """ + Converting mnemonic words to entropy. + + :param str mnemonic: mnemonic words string (space separated) + :param str language: (optional) uses word list language (chinese_simplified, chinese_traditional, english, french, + italian, japanese, korean, spanish), by default is english. + :param str word_list_dir: (optional) path to a directory containing a list of words, + by default None (use BIP39 standard list) + :param list word_list: (optional) already loaded word list, by default None + :param boolean hex: return HEX encoded string result flag, by default True. + :return: bytes string. + """ + if word_list is None: + word_list = load_word_list(language, word_list_dir) + elif not isinstance(word_list, list) or len(word_list) != 2048: + raise TypeError("invalid word list type") + + mnemonic = mnemonic.split() + word_count = len(mnemonic) + if word_count not in [12, 15, 18, 21, 24]: + raise ValueError('Number of words must be one of the following: [12, 15, 18, 21, 24]') + + codes = {w: c for c, w in enumerate(word_list)} + entropy_int = 0 + bit_size = word_count * 11 + chk_sum_bit_len = word_count * 11 % 32 + for w in mnemonic: + entropy_int = (entropy_int << 11) | codes[w] + chk_sum = entropy_int & (2 ** chk_sum_bit_len - 1) + entropy_int = entropy_int >> chk_sum_bit_len + entropy = entropy_int.to_bytes((bit_size - chk_sum_bit_len) // 8, byteorder="big") + if (sha256(entropy)[0] >> (8 - chk_sum_bit_len)) != chk_sum: + raise ValueError("invalid mnemonic checksum") + return entropy if not hex else entropy.hex() + + +def mnemonic_to_seed(mnemonic, passphrase="", hex=True): + """ + Converting mnemonic words string to seed for uses in key derivation (BIP-0032). + + :param str mnemonic: mnemonic words string (space separated) + :param str passphrase: (optional) passphrase to get ability use 2FA approach for + creating seed, by default empty string. + :param boolean hex: return HEX encoded string result flag, by default True. + :return: HEX encoded or bytes string. + """ + if not isinstance(mnemonic, str): + raise TypeError("mnemonic should be string") + if not isinstance(passphrase, str): + raise TypeError("mnemonic should be string") + + seed = hashlib.pbkdf2_hmac('sha512', mnemonic.encode(), ("mnemonic"+passphrase).encode(), 2048) + return seed if not hex else seed.hex() diff --git a/pybtc/functions/block.py b/pybtc/functions/block.py new file mode 100644 index 0000000..1cf84a2 --- /dev/null +++ b/pybtc/functions/block.py @@ -0,0 +1,130 @@ +from pybtc.functions.tools import s2rh, bytes_from_hex, int_from_bytes +from pybtc.functions.hash import double_sha256 + +def merkle_root(tx_hash_list, hex=True): + """ + Calculate merkle root from transaction hash list + + :param tx_hash_list: list of transaction hashes in bytes or HEX encoded string. + :param hex: (optional) If set to True return result in HEX format, by default is True. + :return: merkle root in bytes or HEX encoded string corresponding hex flag. + """ + tx_hash_list = [h if isinstance(h, bytes) else s2rh(h) for h in tx_hash_list] + if len(tx_hash_list) == 1: + return tx_hash_list[0] + while True: + new_hash_list = list() + append = new_hash_list.append + while tx_hash_list: + h1 = tx_hash_list.pop(0) + try: + h2 = tx_hash_list.pop(0) + except: + h2 = h1 + append(double_sha256(h1 + h2)) + if len(new_hash_list) > 1: + tx_hash_list = new_hash_list + else: + return new_hash_list[0] if not hex else new_hash_list[0].hex() + + +def merkle_branches(tx_hash_list, hex=True): + """ + Calculate merkle branches for coinbase transacton + + :param tx_hash_list: list of transaction hashes in bytes or HEX encoded string. + :param hex: (optional) If set to True return result in HEX format, by default is True. + :return: list of merkle branches in bytes or HEX encoded string corresponding hex flag. + """ + tx_hash_list = [h if isinstance(h, bytes) else s2rh(h) for h in tx_hash_list] + branches = [] + if len(tx_hash_list) == 1: + return [] + tx_hash_list.pop(0) + branches_append = branches.append + while True: + branches_append(tx_hash_list.pop(0)) + new_hash_list = list() + new_hash_list_append = new_hash_list.append + while tx_hash_list: + h1 = tx_hash_list.pop(0) + try: + h2 = tx_hash_list.pop(0) + except: + h2 = h1 + new_hash_list_append(double_sha256(h1 + h2)) + if len(new_hash_list) > 1: + tx_hash_list = new_hash_list + else: + if new_hash_list: + branches_append(new_hash_list.pop(0)) + return branches if not hex else [h.hex() for h in branches] + + +def merkleroot_from_branches(merkle_branches, coinbase_hash, hex=True): + """ + Calculate merkle root from merkle branches and coinbase transacton hash + + :param merkle_branches: list merkle branches in bytes or HEX encoded string. + :param coinbase_hash: list coinbase transaction hash in bytes or HEX encoded string. + :param hex: (optional) If set to True return result in HEX format, by default is True. + :return: merkle root in bytes or HEX encoded string corresponding hex flag. + """ + merkle_root = coinbase_hash if not isinstance(coinbase_hash, str) else bytes_from_hex(coinbase_hash) + for h in merkle_branches: + if type(h) == str: + h = bytes_from_hex(h) + merkle_root = double_sha256(merkle_root + h) + return merkle_root if not hex else merkle_root.hex() + + +# Difficulty + + +def bits_to_target(bits): + """ + Calculate target from bits + + :param bits: HEX string, bytes string or integer representation of bits. + :return: integer. + """ + if type(bits) == str: + bits = bytes_from_hex(bits) + if type(bits) == bytes: + return int_from_bytes(bits[1:], 'big') * (2 ** (8 * (bits[0] - 3))) + else: + shift = bits >> 24 + target = (bits & 0xffffff) * (1 << (8 * (shift - 3))) + return target + + +def target_to_difficulty(target): + """ + Calculate difficulty from target + + :param target: integer. + :return: float. + """ + return 0x00000000FFFF0000000000000000000000000000000000000000000000000000 / target + + +def bits_to_difficulty(bits): + """ + Calculate difficulty from bits + + :param bits: HEX string, bytes string or integer representation of bits. + :return: integer. + """ + return target_to_difficulty(bits_to_target(bits)) + + +def difficulty_to_target(difficulty): + """ + Calculate target from difficulty + + :param target: integer. + :return: float. + """ + return int(0x00000000FFFF0000000000000000000000000000000000000000000000000000 / difficulty) + + diff --git a/pybtc/functions/encode.py b/pybtc/functions/encode.py new file mode 100644 index 0000000..d26f3a5 --- /dev/null +++ b/pybtc/functions/encode.py @@ -0,0 +1,140 @@ +from pybtc.functions.hash import double_sha256 +from pybtc.functions.tools import bytes_from_hex + +b58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' +base32charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" +base32charset_upcase = "QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L" + +int_base32_map = dict() +base32_int_map = dict() + +for n, i in enumerate(base32charset): + int_base32_map[i] = n + base32_int_map[n] = ord(i) +for n, i in enumerate(base32charset_upcase): + int_base32_map[i] = n + + +def rebasebits(data, frombits, tobits, pad=True): + """General power-of-2 base conversion.""" + acc = 0 + bits = 0 + ret = bytearray() + append = ret.append + maxv = (1 << tobits) - 1 + max_acc = (1 << (frombits + tobits - 1)) - 1 + for value in data: + if value < 0 or (value >> frombits): + raise ValueError("invalid bytes") + acc = ((acc << frombits) | value) & max_acc + bits += frombits + while bits >= tobits: + bits -= tobits + append((acc >> bits) & maxv) + if pad: + if bits: + append((acc << (tobits - bits)) & maxv) + elif bits >= frombits or ((acc << (tobits - bits)) & maxv): + raise ValueError("invalid padding") + return ret + + +def rebase_5_to_8(data, pad = True): + return rebasebits(data, 5, 8, pad) + + +def rebase_8_to_5(data, pad = True): + return rebasebits(data, 8, 5, pad) + + +def rebase_32_to_5(data): + if isinstance(data, bytes): + data = data.decode() + b = bytearray() + append = b.append + try: + [append(int_base32_map[i]) for i in data] + except: + raise Exception("Non base32 characters") + return b + + +def rebase_5_to_32(data, bytes = True): + r = bytearray() + append = r.append + [append(base32_int_map[i]) for i in data] + return r.decode() if not bytes else r + + +def bech32_polymod(values): + """Internal function that computes the Bech32 checksum.""" + generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] + chk = 1 + for value in values: + top = chk >> 25 + chk = (chk & 0x1ffffff) << 5 ^ value + for i in range(5): + chk ^= generator[i] if ((top >> i) & 1) else 0 + return chk ^ 1 + + +def encode_base58(b): + """Encode bytes to a base58-encoded string""" + # Convert big-endian bytes to integer + + n= int('0x0%s' % b.hex(), 16) + + # Divide that integer into bas58 + res = [] + append = res.append + while n > 0: + n, r = divmod(n, 58) + append(b58_digits[r]) + res = ''.join(res[::-1]) + # Encode leading zeros as base58 zeros + czero = 0 + pad = 0 + for c in b: + if c == czero: + pad += 1 + else: + break + return b58_digits[0] * pad + res + + +def decode_base58(s): + """Decode a base58-encoding string, returning bytes""" + if not s: + return b'' + # Convert the string to an integer + n = 0 + for c in s: + n *= 58 + if c not in b58_digits: + raise Exception('Character %r is not a valid base58 character' % c) + digit = b58_digits.index(c) + n += digit + # Convert the integer to bytes + h = '%x' % n + if len(h) % 2: + h = '0%s' % h + res = bytes_from_hex(h) + # Add padding back. + pad = 0 + for c in s[:-1]: + if c == b58_digits[0]: + pad += 1 + else: + break + return b''.join((b'\x00' * pad, res)) + + +def encode_base58_with_checksum(b): + return encode_base58(b"%s%s" % (b, double_sha256(b)[:4])) + + +def decode_base58_with_checksum(s): + b = decode_base58(s) + if double_sha256(b[:-4])[:4] != b[-4:]: + raise Exception("invalid checksum") + return b[:-4] diff --git a/pybtc/functions/hash.py b/pybtc/functions/hash.py new file mode 100644 index 0000000..e95db1b --- /dev/null +++ b/pybtc/functions/hash.py @@ -0,0 +1,39 @@ +from hashlib import new as hashlib_new +from hashlib import sha256 as hashlib_sha256 +from hashlib import sha512 as hashlib_sha512 +import hmac + +bytes_from_hex = bytes.fromhex + +def sha256(h, hex=False): + if isinstance(h, str): + h = bytes_from_hex(h) + return hashlib_sha256(h).hexdigest() if hex else hashlib_sha256(h).digest() + + +def double_sha256(h, hex=False): + if isinstance(h,str): + h = bytes_from_hex(h) + return sha256(sha256(h), True) if hex else sha256(sha256(h)) + + +def hmac_sha512(key, data, hex=False): + if hex: + return hmac.new(key, data, hashlib_sha512).hexdigest() + return hmac.new(key, data, hashlib_sha512).digest() + + +def ripemd160(h, hex=False): + if isinstance(h, str): + h = bytes_from_hex(h) + a = hashlib_new('ripemd160') + a.update(h) + return a.hexdigest() if hex else a.digest() + + +def hash160(h, hex=False): + if isinstance(h, str): + bytes_from_hex(h) + return ripemd160(sha256(h), True) if hex else ripemd160(sha256(h)) + + diff --git a/pybtc/functions/key.py b/pybtc/functions/key.py new file mode 100644 index 0000000..b00e81f --- /dev/null +++ b/pybtc/functions/key.py @@ -0,0 +1,154 @@ +from secp256k1 import ffi, lib +secp256k1_ec_pubkey_create = lib.secp256k1_ec_pubkey_create +secp256k1_ec_pubkey_serialize = lib.secp256k1_ec_pubkey_serialize + +from pybtc.constants import * +from pybtc.functions.encode import encode_base58, decode_base58 +from pybtc.functions.hash import double_sha256 +from .bip39_mnemonic import generate_entropy + +bytes_from_hex = bytes.fromhex + + +def create_private_key(compressed=True, testnet=False, wif=True, hex=False): + """ + Create private key + + :param compressed: (optional) Type of public key, by default set to compressed. + Using uncompressed public keys is deprecated in new SEGWIT addresses, + use this option only for backward compatibility. + :param testnet: (optional) flag for testnet network, by default is False. + :param wif: (optional) If set to True return key in WIF format, by default is True. + :param hex: (optional) If set to True return key in HEX format, by default is False. + :return: Private key in wif format (default), hex encoded byte string in case of hex flag or + raw bytes string in case wif and hex flags set to False. + + """ + if wif: + return private_key_to_wif(generate_entropy(hex=False), compressed=compressed, testnet=testnet) + elif hex: + return generate_entropy() + return generate_entropy(hex=False) + + +def private_key_to_wif(h, compressed=True, testnet=False): + """ + Encode private key in HEX or RAW bytes format to WIF format. + + :param h: private key 32 byte string or HEX encoded string. + :param compressed: (optional) flag of public key compressed format, by default set to True. + :param testnet: (optional) flag for testnet network, by default is False. + :return: Private key in WIF format. + """ + # uncompressed: 0x80 + [32-byte secret] + [4 bytes of Hash() of previous 33 bytes], base58 encoded. + # compressed: 0x80 + [32-byte secret] + 0x01 + [4 bytes of Hash() previous 34 bytes], base58 encoded. + if isinstance(h, str): + h = bytes_from_hex(h) + if len(h) != 32 and isinstance(h, bytes): + raise TypeError("private key must be a 32 bytes or hex encoded string") + if testnet: + h = TESTNET_PRIVATE_KEY_BYTE_PREFIX + h + else: + h = MAINNET_PRIVATE_KEY_BYTE_PREFIX + h + if compressed: + h += b'\x01' + h += double_sha256(h)[:4] + return encode_base58(h) + + +def wif_to_private_key(h, hex=True): + """ + Decode WIF private key to bytes string or HEX encoded string + + :param hex: (optional) if set to True return key in HEX format, by default is True. + :return: Private key HEX encoded string or raw bytes string. + """ + if not is_wif_valid(h): + raise TypeError("invalid wif key") + h = decode_base58(h) + return h[1:33].hex() if hex else h[1:33] + + +def is_wif_valid(wif): + """ + Check is private key in WIF format string is valid. + + :param wif: private key in WIF format string. + :return: boolean. + """ + if not isinstance(wif, str): + raise TypeError("invalid wif key") + if wif[0] not in PRIVATE_KEY_PREFIX_LIST: + return False + try: + h = decode_base58(wif) + except: + return False + checksum = h[-4:] + if wif[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, + TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX): + if len(h) != 37: + return False + elif len(h) != 38: + return False + if double_sha256(h[:-4])[:4] != checksum: + return False + return True + + +def private_to_public_key(private_key, compressed=True, hex=True): + """ + Get public key from private key using ECDSA secp256k1 + + :param private_key: private key in WIF, HEX or bytes. + :param compressed: (optional) flag of public key compressed format, by default set to True. + In case private_key in WIF format, this flag is set in accordance with + the key format specified in WIF string. + :param hex: (optional) if set to True return key in HEX format, by default is True. + :return: 33/65 bytes public key in HEX or bytes string. + """ + if not isinstance(private_key, bytes): + if isinstance(private_key, bytearray): + private_key = bytes(private_key) + elif isinstance(private_key, str): + if not is_wif_valid(private_key): + private_key = bytes_from_hex(private_key) + else: + if private_key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, + TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX): + compressed = False + private_key = wif_to_private_key(private_key, hex=False) + else: + raise TypeError("private key must be a bytes or WIF or hex encoded string") + pubkey_ptr = ffi.new('secp256k1_pubkey *') + r = secp256k1_ec_pubkey_create(ECDSA_CONTEXT_ALL, pubkey_ptr, private_key) + if not r: + raise RuntimeError("secp256k1 error") + len_key = 33 if compressed else 65 + pubkey = ffi.new('char [%d]' % len_key) + outlen = ffi.new('size_t *', len_key) + compflag = EC_COMPRESSED if compressed else EC_UNCOMPRESSED + r = secp256k1_ec_pubkey_serialize(ECDSA_CONTEXT_VERIFY, pubkey, outlen, pubkey_ptr, compflag) + pub = bytes(ffi.buffer(pubkey, len_key)) + if not r: + raise RuntimeError("secp256k1 error") + return pub.hex() if hex else pub + + +def is_public_key_valid(key): + """ + Check public key is valid. + + :param key: public key in HEX or bytes string format. + :return: boolean. + """ + if isinstance(key, str): + key = bytes_from_hex(key) + if len(key) < 33: + return False + elif key[0] == 0x04 and len(key) != 65: + return False + elif key[0] == 0x02 or key[0] == 0x03: + if len(key) != 33: + return False + return True diff --git a/pybtc/functions/script.py b/pybtc/functions/script.py new file mode 100644 index 0000000..96e5b1e --- /dev/null +++ b/pybtc/functions/script.py @@ -0,0 +1,713 @@ +from struct import unpack +from secp256k1 import ffi, lib, PrivateKey +import hashlib + + +secp256k1_ecdsa_signature_parse_der = lib.secp256k1_ecdsa_signature_parse_der +secp256k1_ec_pubkey_parse = lib.secp256k1_ec_pubkey_parse +secp256k1_ecdsa_verify = lib.secp256k1_ecdsa_verify +secp256k1_ecdsa_sign = lib.secp256k1_ecdsa_sign +secp256k1_ecdsa_signature_serialize_der = lib.secp256k1_ecdsa_signature_serialize_der +secp256k1_ecdsa_signature_serialize_compact = ( + lib.secp256k1_ecdsa_signature_serialize_compact +) +secp256k1_ecdsa_recoverable_signature_parse_compact = ( + lib.secp256k1_ecdsa_recoverable_signature_parse_compact +) +secp256k1_ecdsa_recover = lib.secp256k1_ecdsa_recover +secp256k1_ec_pubkey_serialize = lib.secp256k1_ec_pubkey_serialize + +from pybtc.opcodes import * +from pybtc.constants import * + +from pybtc.functions.tools import bytes_from_hex, int_to_bytes, get_stream +from pybtc.functions.hash import hash160, sha256 +from pybtc.functions.address import hash_to_address +from pybtc.functions.key import is_wif_valid, wif_to_private_key, private_key_to_wif +from ellipticcurve.signature import Signature +from ellipticcurve.ecdsa import Ecdsa +from ellipticcurve.privateKey import PrivateKey +from ellipticcurve.publicKey import PublicKey + +from ellipticcurve.math import Math +from ellipticcurve.utils.integer import RandomInteger +from ellipticcurve.utils.binary import numberFromByteString +from ellipticcurve.utils.compatibility import * +import ellipticcurve.utils.der as der + + + +def public_key_to_pubkey_script(key, hex=True): + if isinstance(key, str): + key = bytes_from_hex(key) + s = b"%s%s%s" % (bytes([len(key)]), key, OP_CHECKSIG) + return s.hex() if hex else s + + +def parse_script(script, segwit=True): + """ + Parse script and return script type, script address and required signatures count. + + :param script: script in bytes string or HEX encoded string format. + :param segwit: (optional) If set to True recognize P2WPKH and P2WSH sripts, by default set to True. + + :return: dictionary: + + - nType - numeric script type + - type - script type + - addressHash - address hash in case address recognized + - script - script if no address recognized + - reqSigs - required signatures count + """ + if not script: + return {"nType": 7, "type": "NON_STANDARD", "reqSigs": 0, "script": b""} + if isinstance(script, str): + try: + script = bytes_from_hex(script) + except: + pass + assert isinstance(script, bytes) + l = len(script) + if segwit: + if l == 22 and script[0] == 0: + return { + "nType": 5, + "type": "P2WPKH", + "reqSigs": 1, + "addressHash": script[2:], + } + if l == 34 and script[0] == 0: + return { + "nType": 6, + "type": "P2WSH", + "reqSigs": None, + "addressHash": script[2:], + } + if l == 25 and script[:2] == b"\x76\xa9" and script[-2:] == b"\x88\xac": + return {"nType": 0, "type": "P2PKH", "reqSigs": 1, "addressHash": script[3:-2]} + if l == 23 and script[0] == 169 and script[-1] == 135: + return { + "nType": 1, + "type": "P2SH", + "reqSigs": None, + "addressHash": script[2:-1], + } + if l == 67 and script[-1] == 172: + return { + "nType": 2, + "type": "PUBKEY", + "reqSigs": 1, + "addressHash": hash160(script[1:-1]), + } + if l == 35 and script[-1] == 172: + return { + "nType": 2, + "type": "PUBKEY", + "reqSigs": 1, + "addressHash": hash160(script[1:-1]), + } + if script[0] == OPCODE["OP_RETURN"]: + if l == 1: + return {"nType": 3, "type": "NULL_DATA", "reqSigs": 0, "data": b""} + elif script[1] < OPCODE["OP_PUSHDATA1"]: + if script[1] == l - 2: + return { + "nType": 3, + "type": "NULL_DATA", + "reqSigs": 0, + "data": script[2:], + } + elif script[1] == OPCODE["OP_PUSHDATA1"]: + if l > 2: + if script[2] == l - 3 and script[2] <= 80: + return { + "nType": 3, + "type": "NULL_DATA", + "reqSigs": 0, + "data": script[3:], + } + return { + "nType": 8, + "type": "NULL_DATA_NON_STANDARD", + "reqSigs": 0, + "script": script, + } + if script[0] >= 81 and script[0] <= 96: + if script[-1] == 174: + if script[-2] >= 81 and script[-2] <= 96: + if script[-2] >= script[0]: + c, s = 0, 1 + while l - 2 - s > 0: + if script[s] < 0x4C: + s += script[s] + c += 1 + else: + c = 0 + break + s += 1 + if c == script[-2] - 80: + return { + "nType": 4, + "type": "MULTISIG", + "reqSigs": script[0] - 80, + "script": script, + } + + s, m, n, last, req_sigs = 0, 0, 0, 0, 0 + while l - s > 0: + if script[s] >= 81 and script[s] <= 96: + if not n: + n = script[s] - 80 + else: + if m == 0: + n, m = script[s] - 80, 0 + elif n > m: + n, m = script[s] - 80, 0 + elif m == script[s] - 80: + last = 0 if last else 2 + elif script[s] < 0x4C: + s += script[s] + m += 1 + if m > 16: + n, m = 0, 0 + elif script[s] == OPCODE["OP_PUSHDATA1"]: + try: + s += 1 + script[s + 1] + except: + break + elif script[s] == OPCODE["OP_PUSHDATA2"]: + try: + s += 2 + unpack(" 0: + if script[s] < 0x4C and script[s]: + if asm: + append(script[s + 1 : s + 1 + script[s]].hex()) + else: + append("[%s]" % script[s]) + s += script[s] + 1 + continue + + if script[s] == OPCODE["OP_PUSHDATA1"]: + if asm: + ld = script[s + 1] + append(script[s + 1 : s + 1 + ld].hex()) + else: + append(RAW_OPCODE[script[s]]) + ld = script[s + 1] + append("[%s]" % ld) + s += 1 + script[s + 1] + 1 + elif script[s] == OPCODE["OP_PUSHDATA2"]: + if asm: + ld = unpack(" 0: + if script[s] < 0x4C and script[s]: + stack_append(script[s] + 1) + s += script[s] + 1 + elif script[s] == OPCODE["OP_PUSHDATA1"]: + stack_append(1 + script[s + 1]) + s += 1 + script[s + 1] + elif script[s] == OPCODE["OP_PUSHDATA2"]: + stack_append(2 + unpack("= ls: + if script[k:s][:ls] == sub_script: + if s - k > ls: + result_append(script[k + ls : s]) + t = 0 + while t != s - k: + t += stack.pop(0) + k = s + else: + t = stack.pop(0) + result_append(script[k : k + t]) + k += t + if script[k:s][:ls] == sub_script: + if s - k > ls: + result_append(script[k + ls : s]) + else: + result_append(script[k : k + ls]) + + return b"".join(result) if not s_hex else b"".join(result).hex() + + +def script_to_hash(script, witness=False, hex=True): + """ + Encode script to hash HASH160 or SHA256 in dependency of the witness. + + :param script: script in bytes or HEX encoded string. + :param witness: (optional) If set to True return SHA256 hash for P2WSH, by default is False. + :param hex: (optional) If set to True return key in HEX format, by default is True. + :param sub_script: sub_script which is necessary to remove from target script in bytes or HEX encoded string. + :return: script in bytes or HEX encoded string corresponding to the format of target script. + """ + if isinstance(script, str): + s = bytes_from_hex(script) + if witness: + return sha256(script, hex) + else: + return hash160(script, hex) + + +def op_push_data(data): + if len(data) <= 0x4B: + return b"".join([bytes([len(data)]), data]) + elif len(data) <= 0xFF: + return b"".join([OP_PUSHDATA1, bytes([len(data)]), data]) + elif len(data) <= 0xFFFF: + return b"".join( + [OP_PUSHDATA2, int_to_bytes(len(data), byteorder="little"), data] + ) + + else: + return b"".join( + [OP_PUSHDATA4, int_to_bytes(len(data), byteorder="little"), data] + ) + + +def get_multisig_public_keys(script): + pub_keys = [] + s = get_stream(script) + o, d = read_opcode(s) + while o: + o, d = read_opcode(s) + if d: + pub_keys.append(d) + return pub_keys + + +def read_opcode(stream): + read = stream.read + b = read(1) + if not b: + return None, None + if b[0] <= 0x4B: + return b, read(b[0]) + elif b[0] == OP_PUSHDATA1: + return b, read(read(1)[0]) + elif b[0] == OP_PUSHDATA2: + return b, read(unpack(" curve.N: + recoveryId += 2 + + return Signature(r=r, s=s, recoveryId=recoveryId) + + +# {floID: 'FV7zHQ4xeATQPUPGSXbRsPyDKaRPT8z9ch', +# pubKey: '032DDE39DD45E4A0A652B3D4CEA6CBB7A56CC43EEDA00A8B32EDE749D957FF3A16', +# privKey: 'RFGCffC1fr4wqr1yV7u5KZ4ctLktEMf7fFPmN7LrZUJzsx52cvzm', +# numPriv: '104574576087683486847995456936233568908389625299457839251220264392921203285909'} + + +def sign_message_tanishk(msg, private_key, hex2=True): + + if(is_wif_valid(private_key)): + hex1 = wif_to_private_key(private_key) + else: + raise TypeError("Invalid Private_Key, must be in WIF format") + pk = PrivateKey.fromString(hex1) + signature = modSign(msg, pk) + + # print("HEX = " + hex1) + # print("SECRET = " + str(pk.secret)) + # msg = Ecdsasha256(msg) + # print("R = " + str(signature.r)) + # print("S = " + str(signature.s)) + print(signature._toString()) + a = int.from_bytes(signature.toDer(), 'big') + return hex(a)[2:] +def verify_message_tanishk(msg, signature, pub): + byteMessage = hashlib.sha256(msg.encode("utf-8")).hexdigest() + # byteMessage = '0x' + byteMessage + # sig = bytes.fromhex(signature) + sign = Signature._fromString(signature) + hold = der.parse(pub) + pub = PublicKey.fromDer(hold) + + print(Ecdsa.verify(msg, sign, pub)) + # byteMessage = script_to_hash("686579", True) + numberMessage = int(byteMessage, base=16) + numberMessage = to_base(numberMessage, 16) + +def sign_message(msg, private_key, hex=True): + """ + Sign message + + :param msg: message to sign bytes or HEX encoded string. + :param private_key: private key (bytes, hex encoded string or WIF format) + :param hex: (optional) If set to True return key in HEX format, by default is True. + :return: DER encoded signature in bytes or HEX encoded string. + """ + + if isinstance(msg, bytearray): + msg = bytes(msg) + if isinstance(msg, str): + try: + msg = bytes_from_hex(msg) + except: + pass + if not isinstance(msg, bytes): + raise TypeError("message must be a bytes or hex encoded string") + + if isinstance(private_key, bytearray): + private_key = bytes(private_key) + if isinstance(private_key, str): + try: + private_key = bytes_from_hex(private_key) + except: + if is_wif_valid(private_key): + private_key = wif_to_private_key(private_key, hex=False) + if not isinstance(private_key, bytes): + raise TypeError( + "private key must be a bytes, hex encoded string or in WIF format" + ) + + raw_sig = ffi.new("secp256k1_ecdsa_signature *") + signed = secp256k1_ecdsa_sign( + ECDSA_CONTEXT_SIGN, raw_sig, msg, private_key, ffi.NULL, ffi.NULL + ) + print(raw_sig.r) + if not signed: + raise RuntimeError("secp256k1 error") + len_sig = 74 + output = ffi.new("unsigned char[%d]" % len_sig) + outputlen = ffi.new("size_t *", len_sig) + res = secp256k1_ecdsa_signature_serialize_der( + ECDSA_CONTEXT_SIGN, output, outputlen, raw_sig + ) + if not res: + raise RuntimeError("secp256k1 error") + signature = bytes(ffi.buffer(output, outputlen[0])) + return signature.hex() if hex else signature + + +def public_key_recovery(signature, messsage, rec_id, compressed=True, hex=True): + if isinstance(signature, str): + signature = bytes_from_hex(signature) + if isinstance(messsage, str): + messsage = bytes_from_hex(messsage) + raw_sig = ffi.new("secp256k1_ecdsa_signature *") + r = secp256k1_ecdsa_signature_parse_der( + ECDSA_CONTEXT_SIGN, raw_sig, signature, len(signature) + ) + if not r: + raise RuntimeError("secp256k1 error") + compact_sig = ffi.new("unsigned char[%d]" % 64) + r = secp256k1_ecdsa_signature_serialize_compact( + ECDSA_CONTEXT_VERIFY, compact_sig, raw_sig + ) + if not r: + raise RuntimeError("secp256k1 error") + + recover_sig = ffi.new("secp256k1_ecdsa_recoverable_signature *") + t = secp256k1_ecdsa_recoverable_signature_parse_compact( + ECDSA_CONTEXT_ALL, recover_sig, compact_sig, rec_id + ) + if not r: + raise RuntimeError("secp256k1 error") + + pubkey_ptr = ffi.new("secp256k1_pubkey *") + t = secp256k1_ecdsa_recover(ECDSA_CONTEXT_ALL, pubkey_ptr, recover_sig, messsage) + len_key = 33 if compressed else 65 + pubkey = ffi.new("char [%d]" % len_key) + outlen = ffi.new("size_t *", len_key) + compflag = EC_COMPRESSED if compressed else EC_UNCOMPRESSED + if bytes(ffi.buffer(pubkey_ptr.data, 64)) == b"\x00" * 64: + return None + r = secp256k1_ec_pubkey_serialize( + ECDSA_CONTEXT_VERIFY, pubkey, outlen, pubkey_ptr, compflag + ) + if not r: + raise RuntimeError("secp256k1 error") + pub = bytes(ffi.buffer(pubkey, len_key)) + return pub.hex() if hex else pub + + +def is_valid_signature_encoding(sig): + """ + Check is valid signature encoded in DER format + + :param sig: signature in bytes or HEX encoded string. + :return: boolean. + """ + # Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] + # * total-length: 1-byte length descriptor of everything that follows, + # excluding the sighash byte. + # * R-length: 1-byte length descriptor of the R value that follows. + # * R: arbitrary-length big-endian encoded R value. It must use the shortest + # possible encoding for a positive integers (which means no null bytes at + # the start, except a single one when the next byte has its highest bit set). + # * S-length: 1-byte length descriptor of the S value that follows. + # * S: arbitrary-length big-endian encoded S value. The same rules apply. + # * sighash: 1-byte value indicating what data is hashed (not part of the DER + # signature) + length = len(sig) + # Minimum and maximum size constraints. + if (length < 9) or (length > 73): + return False + # A signature is of type 0x30 (compound). + if sig[0] != 0x30: + return False + # Make sure the length covers the entire signature. + if sig[1] != (length - 3): + return False + # Extract the length of the R element. + len_r = sig[3] + # Make sure the length of the S element is still inside the signature. + if (5 + len_r) >= length: + return False + # Extract the length of the S element. + len_s = sig[5 + len_r] + # Verify that the length of the signature matches the sum of the length + # of the elements. + if (len_r + len_s + 7) != length: + return False + # Check whether the R element is an integer. + if sig[2] != 0x02: + return False + # Zero-length integers are not allowed for R. + if len_r == 0: + return False + # Negative numbers are not allowed for R. + if sig[4] & 0x80: + return False + # Null bytes at the start of R are not allowed, unless R would + # otherwise be interpreted as a negative number. + if (len_r > 1) and (sig[4] == 0x00) and (not sig[5] & 0x80): + return False + # Check whether the S element is an integer. + if sig[len_r + 4] != 0x02: + return False + # Zero-length integers are not allowed for S. + if len_s == 0: + return False + # Negative numbers are not allowed for S. + if sig[len_r + 6] & 0x80: + return False + # Null bytes at the start of S are not allowed, unless S would otherwise be + # interpreted as a negative number. + if (len_s > 1) and (sig[len_r + 6] == 0x00) and (not sig[len_r + 7] & 0x80): + return False + return True diff --git a/pybtc/functions/tools.py b/pybtc/functions/tools.py new file mode 100644 index 0000000..c24d868 --- /dev/null +++ b/pybtc/functions/tools.py @@ -0,0 +1,360 @@ +from math import ceil, floor +from io import BytesIO +from struct import pack, unpack + + + +bytes_from_hex = bytes.fromhex +int_from_bytes = int.from_bytes + + +def rh2s(raw_hash): + """ + Encode raw transaction hash to HEX string with bytes order change + + :param raw_hash: transaction hash in bytes string. + :return: HEX encoded string. + """ + return raw_hash[::-1].hex() + + +def s2rh(hash_string): + """ + Decode HEX transaction hash to bytes with byte order change + + :param raw_hash: transaction hash in bytes string. + :return: bytes string. + """ + return bytes_from_hex(hash_string)[::-1] + + +def s2rh_step4(hash_string): + h = bytes_from_hex(hash_string) + return reverse_hash(h) + + +def reverse_hash(raw_hash): + """ + Reverse hash order + + :param raw_hash: bytes string. + :return: bytes string. + """ + return pack('>IIIIIIII', * unpack('>IIIIIIII', raw_hash)[::-1])[::-1] + + +def bytes_needed(n): + """ + Calculate bytes needed to convert integer to bytes. + + :param n: integer. + :return: integer. + """ + return ceil(n.bit_length()/8) if n != 0 else 1 + + +def int_to_bytes(i, byteorder='big'): + """ + Convert integer to bytes. + + :param n: integer. + :param byteorder: (optional) byte order 'big' or 'little', by default 'big'. + :return: bytes. + """ + return i.to_bytes(bytes_needed(i), byteorder=byteorder, signed=False) + + +def bytes_to_int(i, byteorder='big'): + """ + Convert bytes to integer. + + :param i: bytes. + :param byteorder: (optional) byte order 'big' or 'little', by default 'big'. + :return: integer. + """ + return int_from_bytes(i, byteorder=byteorder, signed=False) + + +# variable integer + +def int_to_var_int(i): + """ + Convert integer to variable integer + + :param i: integer. + :return: bytes. + """ + if i < 0xfd: + return pack('=1: + add_bytes+=floor((payload_bytes+add_bytes) / 8) - floor((payload_bytes) / 8) + payload_bytes+=add_bytes + if a==0: break + extra_bytes = int(ceil((l+payload_bytes)/8) - base_bytes) + for i in range(extra_bytes): + prefix += 2 ** i + if l < base_bytes * 8: + l = base_bytes * 8 + prefix = prefix << l + if prefix.bit_length() % 8: + prefix = prefix << 8 - prefix.bit_length() % 8 + n ^= prefix + return n.to_bytes(ceil(n.bit_length() / 8), byteorder="big") + + +def c_int_len(n, base_bytes=1): + """ + Get length of compressed integer from integer value + :param n: bytes. + :param base_bytes: len of bytes base from which start compression. + :return: integer. + """ + if n == 0: + return base_bytes + l = n.bit_length() + 1 + if l <= base_bytes * 8: + return base_bytes + payload_bytes = ceil((l) / 8) - base_bytes + a = payload_bytes + while True: + add_bytes = floor((a) / 8) + a = add_bytes + if add_bytes >= 1: + add_bytes += floor((payload_bytes + add_bytes) / 8) - floor((payload_bytes) / 8) + payload_bytes += add_bytes + if a == 0: break + return int(ceil((l+payload_bytes)/8)) + + +def c_int_to_int(b, base_bytes=1): + """ + Convert compressed integer bytes to integer + + :param b: compressed integer bytes. + :param base_bytes: len of bytes base from which start compression. + :return: integer. + """ + byte_length = 0 + f = 0 + while True: + v = b[f] + if v == 0xff: + byte_length += 8 + f += 1 + continue + while v & 0b10000000: + byte_length += 1 + v = v << 1 + break + n = int_from_bytes(b[:byte_length+base_bytes], byteorder="big") + if byte_length: + return n & ((1 << (byte_length+base_bytes) * 8 - byte_length) - 1) + return n + + +# generic big endian MPI format +def bn_bytes(v, have_ext=False): + ext = 0 + if have_ext: + ext = 1 + return ((v.bit_length() + 7) // 8) + ext + + +def bn2bin(v): + s = bytearray() + i = bn_bytes(v) + while i > 0: + s.append((v >> ((i - 1) * 8)) & 0xff) + i -= 1 + return s + + +def bin2bn(s): + l = 0 + for ch in s: + l = (l << 8) | ch + return l + + +def bn2mpi(v): + have_ext = False + if v.bit_length() > 0: + have_ext = (v.bit_length() & 0x07) == 0 + neg = False + if v < 0: + neg = True + v = -v + s = pack(b">I", bn_bytes(v, have_ext)) + ext = bytearray() + if have_ext: + ext.append(0) + v_bin = bn2bin(v) + if neg: + if have_ext: + ext[0] |= 0x80 + else: + v_bin[0] |= 0x80 + return s + ext + v_bin + + +def mpi2bn(s): + if len(s) < 4: + return None + s_size = bytes(s[:4]) + v_len = unpack(b">I", s_size)[0] + if len(s) != (v_len + 4): + return None + if v_len == 0: + return 0 + v_str = bytearray(s[4:]) + neg = False + i = v_str[0] + if i & 0x80: + neg = True + i &= ~0x80 + v_str[0] = i + v = bin2bn(v_str) + + if neg: + return -v + return v + +# bitcoin-specific little endian format, with implicit size + + +def mpi2vch(s): + r = s[4:] # strip size + r = r[::-1] # reverse string, converting BE->LE + return r + + +def bn2vch(v): + return bytes(mpi2vch(bn2mpi(v))) + + +def vch2mpi(s): + r = pack(b">I", len(s)) # size + r += s[::-1] # reverse string, converting LE->BE + return r + + +def vch2bn(s): + return mpi2bn(vch2mpi(s)) + + +def i2b(i): return bn2vch(i) + + +def b2i(b): return vch2bn(b) + + +def get_stream(stream): + if not isinstance(stream, BytesIO): + if isinstance(stream, str): + stream = bytes_from_hex(stream) + if isinstance(stream, bytes): + stream = BytesIO(stream) + else: + raise TypeError + return stream + diff --git a/pybtc/opcodes.py b/pybtc/opcodes.py new file mode 100644 index 0000000..dc826ef --- /dev/null +++ b/pybtc/opcodes.py @@ -0,0 +1,300 @@ +OPCODE = dict() + +# push opcodes + +OPCODE["OP_FALSE"] = 0x00 +OPCODE["OP_0"] = 0x00 +OPCODE["OP_PUSHDATA1"] = 0x4c +OPCODE["OP_PUSHDATA2"] = 0x4d +OPCODE["OP_PUSHDATA4"] = 0x4e +OPCODE["OP_1NEGATE"] = 0x4f +OPCODE["OP_RESERVED"] = 0x50 +OPCODE["OP_TRUE"] = 0x51 +OPCODE["OP_1"] = 0x51 +OPCODE["OP_2"] = 0x52 +OPCODE["OP_3"] = 0x53 +OPCODE["OP_4"] = 0x54 +OPCODE["OP_5"] = 0x55 +OPCODE["OP_6"] = 0x56 +OPCODE["OP_7"] = 0x57 +OPCODE["OP_8"] = 0x58 +OPCODE["OP_9"] = 0x59 +OPCODE["OP_10"] = 0x5a +OPCODE["OP_11"] = 0x5b +OPCODE["OP_12"] = 0x5c +OPCODE["OP_13"] = 0x5d +OPCODE["OP_14"] = 0x5e +OPCODE["OP_15"] = 0x5f +OPCODE["OP_16"] = 0x60 + +# control + +OPCODE["OP_NOP"] = 0x61 +OPCODE["OP_VER"] = 0x62 +OPCODE["OP_IF"] = 0x63 +OPCODE["OP_NOTIF"] = 0x64 +OPCODE["OP_VERIF"] = 0x65 +OPCODE["OP_ELSE"] = 0x67 +OPCODE["OP_ENDIF"] = 0x68 +OPCODE["OP_VERIFY"] = 0x69 +OPCODE["OP_RETURN"] = 0x6a + +# stack + +OPCODE["OP_TOALTSTACK"] = 0x6b +OPCODE["OP_FROMALTSTACK"] = 0x6c +OPCODE["OP_2DROP"] = 0x6d +OPCODE["OP_2DUP"] = 0x6e +OPCODE["OP_3DUP"] = 0x6f +OPCODE["OP_2OVER"] = 0x70 +OPCODE["OP_2ROT"] = 0x71 +OPCODE["OP_2SWAP"] = 0x72 +OPCODE["OP_IFDUP"] = 0x73 +OPCODE["OP_DEPTH"] = 0x74 +OPCODE["OP_DROP"] = 0x75 +OPCODE["OP_DUP"] = 0x76 +OPCODE["OP_NIP"] = 0x77 +OPCODE["OP_OVER"] = 0x78 +OPCODE["OP_PICK"] = 0x79 +OPCODE["OP_ROLL"] = 0x7a +OPCODE["OP_ROT"] = 0x7b +OPCODE["OP_SWAP"] = 0x7c +OPCODE["OP_TUCK"] = 0x7d + +# splice + +OPCODE["OP_CAT"] = 0x7e +OPCODE["OP_SUBSTR"] = 0x7f +OPCODE["OP_LEFT"] = 0x80 +OPCODE["OP_RIGHT"] = 0x81 +OPCODE["OP_SIZE"] = 0x82 + +# bit operations + +OPCODE["OP_INVERT"] = 0x83 +OPCODE["OP_AND"] = 0x84 +OPCODE["OP_OR"] = 0x85 +OPCODE["OP_XOR"] = 0x86 +OPCODE["OP_EQUAL"] = 0x87 +OPCODE["OP_EQUALVERIFY"] = 0x88 +OPCODE["OP_RESERVED1"] = 0x89 +OPCODE["OP_RESERVED2"] = 0x8a + +# math + +OPCODE["OP_1ADD"] = 0x8b +OPCODE["OP_1SUB"] = 0x8c +OPCODE["OP_2MUL"] = 0x8d +OPCODE["OP_2DIV"] = 0x8e +OPCODE["OP_NEGATE"] = 0x8f +OPCODE["OP_ABS"] = 0x90 +OPCODE["OP_NOT"] = 0x91 +OPCODE["OP_0NOTEQUAL"] = 0x92 + +OPCODE["OP_ADD"] = 0x93 +OPCODE["OP_SUB"] = 0x94 +OPCODE["OP_MUL"] = 0x95 +OPCODE["OP_DIV"] = 0x96 +OPCODE["OP_MOD"] = 0x97 +OPCODE["OP_LSHIFT"] = 0x98 +OPCODE["OP_RSHIFT"] = 0x99 + +OPCODE["OP_BOOLAND"] = 0x9a +OPCODE["OP_BOOLOR"] = 0x9b +OPCODE["OP_NUMEQUAL"] = 0x9c +OPCODE["OP_NUMEQUALVERIFY"] = 0x9d +OPCODE["OP_NUMNOTEQUAL"] = 0x9e +OPCODE["OP_LESSTHAN"] = 0x9f +OPCODE["OP_GREATERTHAN"] = 0xa0 +OPCODE["OP_LESSTHANOREQUAL"] = 0xa1 +OPCODE["OP_GREATERTHANOREQUAL"] = 0xa2 +OPCODE["OP_MIN"] = 0xa3 +OPCODE["OP_MAX"] = 0xa4 + +OPCODE["OP_WITHIN"] = 0xa5 + +# crypto + +OPCODE["OP_RIPEMD160"] = 0xa6 +OPCODE["OP_SHA1"] = 0xa7 +OPCODE["OP_SHA256"] = 0xa8 +OPCODE["OP_HASH160"] = 0xa9 +OPCODE["OP_HASH256"] = 0xaa +OPCODE["OP_CODESEPARATOR"] = 0xab +OPCODE["OP_CHECKSIG"] = 0xac +OPCODE["OP_CHECKSIGVERIFY"] = 0xad +OPCODE["OP_CHECKMULTISIG"] = 0xae +OPCODE["OP_CHECKMULTISIGVERIFY"] = 0xaf + +# expansion + +OPCODE["OP_NOP1"] = 0xb0 +OPCODE["OP_CHECKLOCKTIMEVERIFY"] = 0xb1 +OPCODE["OP_CHECKSEQUENCEVERIFY"] = 0xb2 +OPCODE["OP_NOP4"] = 0xb3 +OPCODE["OP_NOP5"] = 0xb4 +OPCODE["OP_NOP6"] = 0xb5 +OPCODE["OP_NOP7"] = 0xb6 +OPCODE["OP_NOP8"] = 0xb7 +OPCODE["OP_NOP9"] = 0xb8 +OPCODE["OP_NOP10"] = 0xb9 + +# template matching params + +OPCODE["OP_SMALLINTEGER"] = 0xfa +OPCODE["OP_PUBKEYS"] = 0xfb +OPCODE["OP_PUBKEYHASH"] = 0xfd +OPCODE["OP_PUBKEY"] = 0xfe +OPCODE["OP_INVALIDOPCODE"] = 0xff + + +RAW_OPCODE = dict((OPCODE[i], i) for i in OPCODE) +BYTE_OPCODE = dict((i, bytes([OPCODE[i]])) for i in OPCODE) +HEX_OPCODE = dict((i, bytes([OPCODE[i]]).hex()) for i in OPCODE) +for i in range(256): + if i not in RAW_OPCODE: + RAW_OPCODE[i]="OP_UNKNOWN" + +OP_FALSE = BYTE_OPCODE["OP_FALSE"] +OP_0 = BYTE_OPCODE["OP_0"] +OP_PUSHDATA1 = BYTE_OPCODE["OP_PUSHDATA1"] +OP_PUSHDATA2 = BYTE_OPCODE["OP_PUSHDATA2"] +OP_PUSHDATA4 = BYTE_OPCODE["OP_PUSHDATA4"] +OP_1NEGATE = BYTE_OPCODE["OP_1NEGATE"] +OP_RESERVED = BYTE_OPCODE["OP_RESERVED"] +OP_1 = BYTE_OPCODE["OP_1"] +OP_TRUE = BYTE_OPCODE["OP_TRUE"] +OP_2 = BYTE_OPCODE["OP_2"] +OP_3 = BYTE_OPCODE["OP_3"] +OP_4 = BYTE_OPCODE["OP_4"] +OP_5 = BYTE_OPCODE["OP_5"] +OP_6 = BYTE_OPCODE["OP_6"] +OP_7 = BYTE_OPCODE["OP_7"] +OP_8 = BYTE_OPCODE["OP_8"] +OP_9 = BYTE_OPCODE["OP_9"] +OP_10 = BYTE_OPCODE["OP_10"] +OP_11 = BYTE_OPCODE["OP_11"] +OP_12 = BYTE_OPCODE["OP_12"] +OP_13 = BYTE_OPCODE["OP_13"] +OP_14 = BYTE_OPCODE["OP_14"] +OP_15 = BYTE_OPCODE["OP_15"] +OP_16 = BYTE_OPCODE["OP_16"] + +# control + +OP_NOP = BYTE_OPCODE["OP_NOP"] +OP_VER = BYTE_OPCODE["OP_VER"] +OP_IF = BYTE_OPCODE["OP_IF"] +OP_NOTIF = BYTE_OPCODE["OP_NOTIF"] +OP_VERIF = BYTE_OPCODE["OP_VERIF"] +OP_ELSE = BYTE_OPCODE["OP_ELSE"] +OP_ENDIF = BYTE_OPCODE["OP_ENDIF"] +OP_VERIFY = BYTE_OPCODE["OP_VERIFY"] +OP_RETURN = BYTE_OPCODE["OP_RETURN"] + +# stack + +OP_TOALTSTACK = BYTE_OPCODE["OP_TOALTSTACK"] +OP_FROMALTSTACK = BYTE_OPCODE["OP_FROMALTSTACK"] +OP_2DROP = BYTE_OPCODE["OP_2DROP"] +OP_2DUP = BYTE_OPCODE["OP_2DUP"] +OP_3DUP = BYTE_OPCODE["OP_3DUP"] +OP_2OVER = BYTE_OPCODE["OP_2OVER"] +OP_2ROT = BYTE_OPCODE["OP_2ROT"] +OP_2SWAP = BYTE_OPCODE["OP_2SWAP"] +OP_IFDUP = BYTE_OPCODE["OP_IFDUP"] +OP_DEPTH = BYTE_OPCODE["OP_DEPTH"] +OP_DROP = BYTE_OPCODE["OP_DROP"] +OP_DUP = BYTE_OPCODE["OP_DUP"] +OP_NIP = BYTE_OPCODE["OP_NIP"] +OP_OVER = BYTE_OPCODE["OP_OVER"] +OP_PICK = BYTE_OPCODE["OP_PICK"] +OP_ROLL = BYTE_OPCODE["OP_ROLL"] +OP_ROT = BYTE_OPCODE["OP_ROT"] +OP_SWAP = BYTE_OPCODE["OP_SWAP"] +OP_TUCK = BYTE_OPCODE["OP_TUCK"] + +# splice + +OP_CAT = BYTE_OPCODE["OP_CAT"] +OP_SUBSTR = BYTE_OPCODE["OP_SUBSTR"] +OP_LEFT = BYTE_OPCODE["OP_LEFT"] +OP_RIGHT = BYTE_OPCODE["OP_RIGHT"] +OP_SIZE = BYTE_OPCODE["OP_SIZE"] + +# bit operations + +OP_INVERT = BYTE_OPCODE["OP_INVERT"] +OP_AND = BYTE_OPCODE["OP_AND"] +OP_OR = BYTE_OPCODE["OP_OR"] +OP_XOR = BYTE_OPCODE["OP_XOR"] +OP_EQUAL = BYTE_OPCODE["OP_EQUAL"] +OP_EQUALVERIFY = BYTE_OPCODE["OP_EQUALVERIFY"] +OP_RESERVED1 = BYTE_OPCODE["OP_RESERVED1"] +OP_RESERVED2 = BYTE_OPCODE["OP_RESERVED2"] + +# math + +OP_1ADD = BYTE_OPCODE["OP_1ADD"] +OP_1SUB = BYTE_OPCODE["OP_1SUB"] +OP_2MUL = BYTE_OPCODE["OP_2MUL"] +OP_2DIV = BYTE_OPCODE["OP_2DIV"] +OP_NEGATE = BYTE_OPCODE["OP_NEGATE"] +OP_ABS = BYTE_OPCODE["OP_ABS"] +OP_NOT = BYTE_OPCODE["OP_NOT"] +OP_0NOTEQUAL = BYTE_OPCODE["OP_0NOTEQUAL"] + +OP_ADD = BYTE_OPCODE["OP_ADD"] +OP_SUB = BYTE_OPCODE["OP_SUB"] +OP_MUL = BYTE_OPCODE["OP_MUL"] +OP_DIV = BYTE_OPCODE["OP_DIV"] +OP_MOD = BYTE_OPCODE["OP_MOD"] +OP_LSHIFT = BYTE_OPCODE["OP_LSHIFT"] +OP_RSHIFT = BYTE_OPCODE["OP_RSHIFT"] + +OP_BOOLAND = BYTE_OPCODE["OP_BOOLAND"] +OP_BOOLOR = BYTE_OPCODE["OP_BOOLOR"] +OP_NUMEQUAL = BYTE_OPCODE["OP_NUMEQUAL"] +OP_NUMEQUALVERIFY = BYTE_OPCODE["OP_NUMEQUALVERIFY"] +OP_NUMNOTEQUAL = BYTE_OPCODE["OP_NUMNOTEQUAL"] +OP_LESSTHAN = BYTE_OPCODE["OP_LESSTHAN"] +OP_GREATERTHAN = BYTE_OPCODE["OP_GREATERTHAN"] +OP_LESSTHANOREQUAL = BYTE_OPCODE["OP_LESSTHANOREQUAL"] +OP_GREATERTHANOREQUAL = BYTE_OPCODE["OP_GREATERTHANOREQUAL"] +OP_MIN = BYTE_OPCODE["OP_MIN"] +OP_MAX = BYTE_OPCODE["OP_MAX"] +OP_WITHIN = BYTE_OPCODE["OP_WITHIN"] + +# crypto + +OP_RIPEMD160 = BYTE_OPCODE["OP_RIPEMD160"] +OP_SHA1 = BYTE_OPCODE["OP_SHA1"] +OP_SHA256 = BYTE_OPCODE["OP_SHA256"] +OP_HASH160 = BYTE_OPCODE["OP_HASH160"] +OP_HASH256 = BYTE_OPCODE["OP_HASH256"] +OP_CODESEPARATOR = BYTE_OPCODE["OP_CODESEPARATOR"] +OP_CHECKSIG = BYTE_OPCODE["OP_CHECKSIG"] +OP_CHECKSIGVERIFY = BYTE_OPCODE["OP_CHECKSIGVERIFY"] +OP_CHECKMULTISIG = BYTE_OPCODE["OP_CHECKMULTISIG"] +OP_CHECKMULTISIGVERIFY = BYTE_OPCODE["OP_CHECKMULTISIGVERIFY"] + +# expansion + +OP_NOP1 = BYTE_OPCODE["OP_NOP1"] +OP_CHECKLOCKTIMEVERIFY = BYTE_OPCODE["OP_CHECKLOCKTIMEVERIFY"] +OP_CHECKSEQUENCEVERIFY = BYTE_OPCODE["OP_CHECKSEQUENCEVERIFY"] +OP_NOP4 = BYTE_OPCODE["OP_NOP4"] +OP_NOP5 = BYTE_OPCODE["OP_NOP5"] +OP_NOP6 = BYTE_OPCODE["OP_NOP6"] +OP_NOP7 = BYTE_OPCODE["OP_NOP7"] +OP_NOP8 = BYTE_OPCODE["OP_NOP8"] +OP_NOP9 = BYTE_OPCODE["OP_NOP9"] +OP_NOP10 = BYTE_OPCODE["OP_NOP10"] + +# template matching params + +OP_SMALLINTEGER = BYTE_OPCODE["OP_SMALLINTEGER"] +OP_PUBKEYS = BYTE_OPCODE["OP_PUBKEYS"] +OP_PUBKEYHASH = BYTE_OPCODE["OP_PUBKEYHASH"] +OP_PUBKEY = BYTE_OPCODE["OP_PUBKEY"] +OP_INVALIDOPCODE = BYTE_OPCODE["OP_INVALIDOPCODE"] \ No newline at end of file diff --git a/pybtc/test/__init__.py b/pybtc/test/__init__.py new file mode 100644 index 0000000..1269687 --- /dev/null +++ b/pybtc/test/__init__.py @@ -0,0 +1,14 @@ +from .hash_functions import * +from .integer import * +from .address_functions import * +from .script_functions import * +from .ecdsa import * +from .mnemonic import * +from .sighash import * +from .address_class import * +from .transaction_deserialize import * +from .transaction_constructor import * +from .block import * + +# from .script_deserialize import * +# from .create_transaction import * diff --git a/pybtc/test/address_class.py b/pybtc/test/address_class.py new file mode 100644 index 0000000..581fe7a --- /dev/null +++ b/pybtc/test/address_class.py @@ -0,0 +1,112 @@ +import unittest +import os +import sys + + +parentPath = os.path.abspath("..") +if parentPath not in sys.path: + sys.path.insert(0, parentPath) + +# from pybtc.transaction import * +from pybtc import OPCODE +from binascii import unhexlify +import pybtc + +class AddressClassTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("\nTesting address class:\n") + + def test_is_WIF_valid(self): + # mainnet + self.assertEqual(pybtc.PrivateKey("7B56E2B7BD189F4491D43A1D209E6268046DF1741F61B6397349D7AA54978E76", + compressed=True, testnet=False).wif, + 'L1MU1jUjUwZ6Fd1L2HDZ8qH4oSWxct5boCQ4C87YvoSZbTW41hg4') + self.assertEqual(pybtc.PrivateKey("7B56E2B7BD189F4491D43A1D209E6268046DF1741F61B6397349D7AA54978E76", + compressed=False, testnet=False).wif, + '5Jkc7xqsrqA5pGQdwDHSQXRV3pUBLTXVjBjqJUSVz3pUmyuAFwP') + # testnet + self.assertEqual(pybtc.PrivateKey("7B56E2B7BD189F4491D43A1D209E6268046DF1741F61B6397349D7AA54978E76", + compressed=True, testnet=True).wif, + 'cRiTUeUav1FMR4UbQh2gW9n8RfpNHLBHsEYXJYa4Rv6ZrCdTPGqv') + self.assertEqual(pybtc.PrivateKey("7B56E2B7BD189F4491D43A1D209E6268046DF1741F61B6397349D7AA54978E76", + compressed=False, testnet=True).wif, + '92XEhhfRT4EDnKuvZZBMH7yShUptVd4h58bnP6o1KnZXYzkVa55') + + self.assertEqual(pybtc.PrivateKey("L1MU1jUjUwZ6Fd1L2HDZ8qH4oSWxct5boCQ4C87YvoSZbTW41hg4", + compressed=False, testnet=True).wif, + 'L1MU1jUjUwZ6Fd1L2HDZ8qH4oSWxct5boCQ4C87YvoSZbTW41hg4') + + p = pybtc.PrivateKey("L1MU1jUjUwZ6Fd1L2HDZ8qH4oSWxct5boCQ4C87YvoSZbTW41hg4") + pub = pybtc.PublicKey(p) + a = pybtc.Address(p) + self.assertEqual(a.address, 'bc1qxsms4rt5axt9674du2az7vq3pvephu3k5jyky8') + a = pybtc.Address(p, address_type = "P2PKH") + self.assertEqual(a.address, '15m65JmFohJiioQbzMWhqFeCS3ZL1KVaNh') + a = pybtc.Address(p, address_type = "PUBKEY") + self.assertEqual(a.address, '15m65JmFohJiioQbzMWhqFeCS3ZL1KVaNh') + a = pybtc.Address(p, address_type = "P2SH_P2WPKH") + self.assertEqual(a.address, '37WJdFAoHDbxUQioDgtvPZuyJPyrrNQ7aL') + self.assertEqual(a.redeem_script_hex, '001434370a8d74e9965d7aade2ba2f30110b321bf236') + self.assertEqual(a.public_key.hex, '02a8fb85e98c99b79150df12fde488639d8445c57babef83d53c66c1e5c818eeb4') + + cpk = "02a8fb85e98c99b79150df12fde488639d8445c57babef83d53c66c1e5c818eeb4" + ucpk = "04a8fb85e98c99b79150df12fde488639d8445c57babef83d53c66c1e5c818eeb" \ + "43bbd96a641808e5f34eb568e804fe679de82de419e2512736ea09013a82324a6" + # public key uncompressed from HEX private + self.assertEqual(pybtc.PublicKey("7b56e2b7bd189f4491d43a1d209e6268046df1741f61b6397349d7aa54978e76", + compressed=False).hex, ucpk) + # public key compressed from HEX private + self.assertEqual(pybtc.PublicKey("7b56e2b7bd189f4491d43a1d209e6268046df1741f61b6397349d7aa54978e76", + compressed=True).hex, cpk) + # public key compressed from WIF private + self.assertEqual(pybtc.PublicKey("L1MU1jUjUwZ6Fd1L2HDZ8qH4oSWxct5boCQ4C87YvoSZbTW41hg4", + compressed=False).hex, cpk) + # public key compressed from PrivateKey instance (flags have no effect) + p = pybtc.PrivateKey("L1MU1jUjUwZ6Fd1L2HDZ8qH4oSWxct5boCQ4C87YvoSZbTW41hg4") + self.assertEqual(pybtc.PublicKey(p, compressed=False).hex, cpk) + + # public key compressed from public + self.assertEqual(pybtc.PublicKey(cpk, compressed=False).hex, cpk) + + # public key compressed from public + self.assertEqual(pybtc.PublicKey(unhexlify(cpk), compressed=False).hex, cpk) + + # compressed public key + # private key hex string to compressed pub key + p = pybtc.PrivateKey("7b56e2b7bd189f4491d43a1d209e6268046df1741f61b6397349d7aa54978e76", compressed=False) + pub = pybtc.PublicKey(p) + a = pybtc.Address(p, address_type="P2PKH") + self.assertEqual(a.address, '17suVjHXyWF9KiGkpRRQW4ysiEqdDkRqo1') + a = pybtc.Address(p, address_type="PUBKEY") + self.assertEqual(a.address, '17suVjHXyWF9KiGkpRRQW4ysiEqdDkRqo1') + + # from pubkey + p = pybtc.PublicKey('02a8fb85e98c99b79150df12fde488639d8445c57babef83d53c66c1e5c818eeb4') + a = pybtc.Address(p) + self.assertEqual(a.address, 'bc1qxsms4rt5axt9674du2az7vq3pvephu3k5jyky8') + a = pybtc.Address(p, address_type="P2PKH") + self.assertEqual(a.address, '15m65JmFohJiioQbzMWhqFeCS3ZL1KVaNh') + a = pybtc.Address(p, address_type="PUBKEY") + self.assertEqual(a.address, '15m65JmFohJiioQbzMWhqFeCS3ZL1KVaNh') + a = pybtc.Address(p, address_type="P2SH_P2WPKH") + self.assertEqual(a.address, '37WJdFAoHDbxUQioDgtvPZuyJPyrrNQ7aL') + self.assertEqual(a.redeem_script_hex, '001434370a8d74e9965d7aade2ba2f30110b321bf236') + self.assertEqual(a.public_key.hex, '02a8fb85e98c99b79150df12fde488639d8445c57babef83d53c66c1e5c818eeb4') + + # from uncompressed pubkey + p = pybtc.PublicKey('04a8fb85e98c99b79150df12fde488639d8445c57babef83d53c66c1e5c818eeb43bbd96a641808' + 'e5f34eb568e804fe679de82de419e2512736ea09013a82324a6') + a = pybtc.Address(p, address_type="P2PKH") + self.assertEqual(a.address, '17suVjHXyWF9KiGkpRRQW4ysiEqdDkRqo1') + a = pybtc.Address(p, address_type="PUBKEY") + self.assertEqual(a.address, '17suVjHXyWF9KiGkpRRQW4ysiEqdDkRqo1') + + redeem = "5221032bfc25cf7cccc278b26473e2967b8fd403b4b544b836e71abdfebb08d8c96d6921032bfc25cf7cccc278b2" \ + "6473e2967b8fd403b4b544b836e71abdfebb08d8c96d6921032bfc25cf7cccc278b26473e2967b8fd403b4b544b8" \ + "36e71abdfebb08d8c96d6953ae" + a = pybtc.ScriptAddress(redeem, witness_version=None) + self.assertEqual(a.address, '3KCqqS6eznp3ucVPxtNkiYcVg6kQKNX9sg') + + + diff --git a/pybtc/test/address_functions.py b/pybtc/test/address_functions.py new file mode 100644 index 0000000..b9ec15f --- /dev/null +++ b/pybtc/test/address_functions.py @@ -0,0 +1,542 @@ +import unittest +import os, sys +parentPath = os.path.abspath("..") +if parentPath not in sys.path: + sys.path.insert(0, parentPath) + +from pybtc.functions import script as tools +from pybtc import functions +from pybtc import BYTE_OPCODE, HEX_OPCODE +from binascii import unhexlify, hexlify + + +class AddressFunctionsTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("\nTesting address functions:\n") + + def test_private_key_to_WIF(self): + p = "ceda1ae4286015d45ec5147fe3f63e9377ccd6d4e98bcf0847df9937da1944a4" + pcm = "L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX" + pum = "5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf" + put = "93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L" + pct = "cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6" + self.assertEqual(functions.private_key_to_wif(p, compressed=1, testnet=0), pcm) + self.assertEqual(functions.private_key_to_wif(p, compressed=0, testnet=0), pum) + self.assertEqual(functions.private_key_to_wif(p, compressed=1, testnet=1), pct) + self.assertEqual(functions.private_key_to_wif(p, compressed=0, testnet=1), put) + + def test_is_WIF_valid(self): + self.assertEqual(functions.is_wif_valid("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX"), 1) + self.assertEqual(functions.is_wif_valid("5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf"), 1) + self.assertEqual(functions.is_wif_valid("5KPPLXhtga99qqMcWRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf"), 0) + self.assertEqual(functions.is_wif_valid("93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L"), 1) + self.assertEqual(functions.is_wif_valid("cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6"), 1) + self.assertEqual(functions.is_wif_valid("cUWo47XLYiyByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6"), 0) + + def test_WIF_to_private_key(self): + p = "ceda1ae4286015d45ec5147fe3f63e9377ccd6d4e98bcf0847df9937da1944a4" + self.assertEqual(functions.wif_to_private_key("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX", + hex=1),p) + self.assertEqual(functions.wif_to_private_key("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX", + hex=0),unhexlify(p)) + self.assertEqual(functions.wif_to_private_key("5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf", + hex=1),p) + self.assertEqual(functions.wif_to_private_key("93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L", + hex=1),p) + self.assertEqual(functions.wif_to_private_key("cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6", + hex=1),p) + + def test_create_private_key(self): + p = functions.create_private_key(wif=0) + pw = functions.private_key_to_wif(p) + self.assertEqual(functions.is_wif_valid(pw), True) + + + + def test_private_to_public_key(self): + p = "ceda1ae4286015d45ec5147fe3f63e9377ccd6d4e98bcf0847df9937da1944a4" + pu = "04b635dbdc16dbdf4bb9cf5b55e7d03e514fb04dcef34208155c7d3ec88e9045f4c8cbe28702911260f2a1da099a338bed4ee98f66bb8dba8031a76ab537ff6663" + pk = "03b635dbdc16dbdf4bb9cf5b55e7d03e514fb04dcef34208155c7d3ec88e9045f4" + self.assertEqual(functions.private_to_public_key(p, hex=1), pk) + self.assertEqual(functions.private_to_public_key(p, hex=0), unhexlify(pk)) + self.assertEqual(functions.private_to_public_key(p, compressed=0, hex=1), pu) + self.assertEqual(functions.private_to_public_key("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX", hex=1), pk) + self.assertEqual(functions.private_to_public_key("5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf", hex=1), pu) + self.assertEqual(functions.private_to_public_key("93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L", hex=1), pu) + self.assertEqual(functions.private_to_public_key("cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6", hex=1), pk) + + def test_hash_to_address(self): + pc = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" + h = tools.hash160(pc) + s = bytes([len(unhexlify(pc))])+unhexlify(pc) + BYTE_OPCODE["OP_CHECKSIG"] + self.assertEqual(functions.hash_to_address(h), "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4") + self.assertEqual(functions.hash_to_address(h, testnet=1), "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx") + h = tools.script_to_hash(s, 1, 1) + self.assertEqual(functions.hash_to_address(h), "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3") + self.assertEqual(functions.hash_to_address(h, testnet=1), "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7") + pk = "03b635dbdc16dbdf4bb9cf5b55e7d03e514fb04dcef34208155c7d3ec88e9045f4" + h = tools.hash160(pk) + self.assertEqual(functions.hash_to_address(h, witness_version=None), "1Fs2Xqrk4P2XADaJeZWykaGXJ4HEb6RyT1") + self.assertEqual(functions.hash_to_address(h, witness_version=None, testnet=1), + "mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c") + # p2wpkh inside p2sh + p = "L32a8Mo1LgvjrVDbzcc3NkuUfkpoLsf2Y2oEWkV4t1KpQdFzuyff" + pk = functions.private_to_public_key(p) + script = b'\x00\x14' + tools.hash160(pk) + script_hash = tools.hash160(script) + self.assertEqual(functions.hash_to_address(script_hash, + script_hash=1, + witness_version=None), "33am12q3Bncnn3BfvLYHczyv23Sq2Wbwjw") + self.assertEqual(functions.hash_to_address(script_hash, + script_hash=1, + witness_version=None, + testnet=1), "2Mu8y4mm4oF88yppDbUAAEwyBEPezrx7CLh") + + def test_address_to_hash(self): + h = "751e76e8199196d454941c45d1b3a323f1433bd6" + self.assertEqual(functions.address_to_hash("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", 1), h) + self.assertEqual(functions.address_to_hash("tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", 1), h) + h = "1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262" + self.assertEqual(functions.address_to_hash("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", 1), h) + h = "a307d67484911deee457779b17505cedd20e1fe9" + self.assertEqual(functions.address_to_hash("1Fs2Xqrk4P2XADaJeZWykaGXJ4HEb6RyT1", 1), h) + self.assertEqual(functions.address_to_hash("mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c", 1), h) + h = "14c14c8d26acbea970757b78e6429ad05a6ac6bb" + self.assertEqual(functions.address_to_hash("33am12q3Bncnn3BfvLYHczyv23Sq2Wbwjw", 1), h) + self.assertEqual(functions.address_to_hash("2Mu8y4mm4oF88yppDbUAAEwyBEPezrx7CLh", 1), h) + + def test_address_type(self): + self.assertEqual(functions.address_type("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"), 'P2WPKH') + self.assertEqual(functions.address_type("tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"), 'P2WPKH') + self.assertEqual(functions.address_type("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"), 'P2WSH') + self.assertEqual(functions.address_type("tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7"), 'P2WSH') + self.assertEqual(functions.address_type("1Fs2Xqrk4P2XADaJeZWykaGXJ4HEb6RyT1"), 'P2PKH') + self.assertEqual(functions.address_type("mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c"), 'P2PKH') + self.assertEqual(functions.address_type("33am12q3Bncnn3BfvLYHczyv23Sq2Wbwjw"), 'P2SH') + self.assertEqual(functions.address_type("2Mu8y4mm4oF88yppDbUAAEwyBEPezrx7CLh"), 'P2SH') + + def test_address_net_type(self): + self.assertEqual(functions.address_net_type("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"), 'mainnet') + self.assertEqual(functions.address_net_type("tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"), 'testnet') + self.assertEqual(functions.address_net_type("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"), + 'mainnet') + self.assertEqual(functions.address_net_type("tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7"), + 'testnet') + self.assertEqual(functions.address_net_type("1Fs2Xqrk4P2XADaJeZWykaGXJ4HEb6RyT1"), 'mainnet') + self.assertEqual(functions.address_net_type("mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c"), 'testnet') + self.assertEqual(functions.address_net_type("33am12q3Bncnn3BfvLYHczyv23Sq2Wbwjw"), 'mainnet') + self.assertEqual(functions.address_net_type("2Mu8y4mm4oF88yppDbUAAEwyBEPezrx7CLh"), 'testnet') + + def test_public_key_to_address(self): + pc = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" + self.assertEqual(functions.public_key_to_address(pc), "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4") + self.assertEqual(functions.public_key_to_address(pc, testnet=1), "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx") + pc = "03b635dbdc16dbdf4bb9cf5b55e7d03e514fb04dcef34208155c7d3ec88e9045f4" + self.assertEqual(functions.public_key_to_address(pc, + witness_version=None, + testnet=0), "1Fs2Xqrk4P2XADaJeZWykaGXJ4HEb6RyT1") + self.assertEqual(functions.public_key_to_address(pc, witness_version=None, + testnet=1), "mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c") + p = "L32a8Mo1LgvjrVDbzcc3NkuUfkpoLsf2Y2oEWkV4t1KpQdFzuyff" + pk = functions.private_to_public_key(p) + self.assertEqual(functions.public_key_to_address(pk, p2sh_p2wpkh=1, + witness_version=None), "33am12q3Bncnn3BfvLYHczyv23Sq2Wbwjw") + + def test_is_address_valid(self): + self.assertEqual(functions.is_address_valid("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"), 1) + self.assertEqual(functions.is_address_valid("tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", 1), 1) + self.assertEqual(functions.is_address_valid("tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"), 0) + self.assertEqual(functions.is_address_valid("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"), 1) + self.assertEqual(functions.is_address_valid("tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", 1), 1) + self.assertEqual(functions.is_address_valid("1Fs2Xqrk4P2XADaJeZWykaGXJ4HEb6RyT1"), 1) + self.assertEqual(functions.is_address_valid("mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c", 1), 1) + self.assertEqual(functions.is_address_valid("33am12q3Bncnn3BfvLYHczyv23Sq2Wbwjw"), 1) + self.assertEqual(functions.is_address_valid("2Mu8y4mm4oF88yppDbUAAEwyBEPezrx7CLh",1), 1) + self.assertEqual(functions.is_address_valid("2Mu8y4mm4oF89yppDbUAAEwyBEPezrx7CLh",1), 0) + self.assertEqual(functions.is_address_valid("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", 1), 0) + self.assertEqual(functions.is_address_valid("tb1qw508d6qejxtdg4W5r3zarvary0c5xw7kxpjzsx",1), 0) + self.assertEqual(functions.is_address_valid("bc1qrp33g0q5c5txsp8arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"), 0) + self.assertEqual(functions.is_address_valid("tb1qrp23g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",1), 0) + self.assertEqual(functions.is_address_valid("1Fs2Xqrk4P2XADaJeZWykaGXJ2HEb6RyT1"), 0) + self.assertEqual(functions.is_address_valid("mvNyptwisQTkwL3vN8VMaVUrA3swVCX83c", 1), 0) + self.assertEqual(functions.is_address_valid("33am12q3Bncmn3BfvLYHczyv23Sq2Wbwjw"), 0) + self.assertEqual(functions.is_address_valid("2Mu8y4mm4oF78yppDbUAAEwyBEPezrx7CLh", 1), 0) + + def test_address_to_script(self): + self.assertEqual(functions.address_to_script("17rPqUf4Hqu6Lvpgfsavt1CzRy2GL19GD3", 1), + "76a9144b2832feeda5692c96c0594a6314136a998f515788ac") + self.assertEqual(functions.address_to_script("33RYUa9jT541UNPsKdV7V1DmwMiQHpVfD3", 1), + "a914130319921ecbcfa33fec2a8503c4ae1c86e4419387") + self.assertEqual(functions.address_to_script("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", 1), + "0014751e76e8199196d454941c45d1b3a323f1433bd6") + self.assertEqual(functions.address_to_script("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", 1), + "0014751e76e8199196d454941c45d1b3a323f1433bd6") + + def test_parse_script(self): + + k = tools.parse_script("76a9144b2832feeda5692c96c0594a6314136a998f515788ac") + address = functions.hash_to_address(k["addressHash"], witness_version = None) + self.assertEqual(address, "17rPqUf4Hqu6Lvpgfsavt1CzRy2GL19GD3") + self.assertEqual(k["type"],"P2PKH") + self.assertEqual(k["nType"],0) + self.assertEqual(k["reqSigs"],1) + self.assertEqual(functions.address_to_script(address, 1), + "76a9144b2832feeda5692c96c0594a6314136a998f515788ac") + + k = tools.parse_script("76a914a307d67484911deee457779b17505cedd20e1fe988ac") + address = functions.hash_to_address(k["addressHash"], testnet= True, witness_version=None) + self.assertEqual(address,"mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c") + self.assertEqual(k["type"],"P2PKH") + self.assertEqual(k["nType"],0) + self.assertEqual(k["reqSigs"],1) + self.assertEqual(functions.address_to_script(address, 1), + "76a914a307d67484911deee457779b17505cedd20e1fe988ac") + + k = tools.parse_script("a914b316ac9bdd0816ecdec6773d1192c0eaf52ae66487") + address = functions.hash_to_address(k["addressHash"], script_hash=True, witness_version=None) + self.assertEqual(address, "3J1x3KHjgjoTjqHjrwKax2zeT8LSDkZJae") + self.assertEqual(k["type"],"P2SH") + self.assertEqual(k["nType"],1) + self.assertEqual(k["reqSigs"], None) + self.assertEqual(functions.address_to_script(address, 1), + "a914b316ac9bdd0816ecdec6773d1192c0eaf52ae66487") + + k = tools.parse_script("0014751e76e8199196d454941c45d1b3a323f1433bd6") + address = functions.hash_to_address(k["addressHash"], script_hash=False, + witness_version=0, testnet=False) + self.assertEqual(address, "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4") + self.assertEqual(k["type"],"P2WPKH") + self.assertEqual(k["nType"],5) + self.assertEqual(k["reqSigs"],1) + self.assertEqual(functions.address_to_script(address, 1), + "0014751e76e8199196d454941c45d1b3a323f1433bd6") + + s = [HEX_OPCODE['OP_HASH160'], + '14', + '92c2f2da37093971ca335824edae06468e60ea20', + HEX_OPCODE['OP_EQUAL']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + address = functions.hash_to_address(k["addressHash"], script_hash=True, + witness_version=None, testnet=False) + self.assertEqual(address, "3F527pX8o2pgr6FuNdNvngA2Do2wVvDoZi") + self.assertEqual(k["type"],"P2SH") + self.assertEqual(k["nType"],1) + self.assertEqual(k["reqSigs"], None) + self.assertEqual(functions.address_to_script(address, 1), h) + + s = [HEX_OPCODE['OP_3'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + sh = tools.script_to_hash(h, 0, 0) + address = functions.hash_to_address(sh,script_hash=True, + witness_version=None, testnet=False) + self.assertEqual(address, "3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r") + self.assertEqual(k["type"],"MULTISIG") + self.assertEqual(k["nType"],4) + self.assertEqual(k["reqSigs"],3) + + s = [HEX_OPCODE['OP_0'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + sh = tools.script_to_hash(h, 0,0) + self.assertEqual(k["type"],"NON_STANDARD") + self.assertEqual(k["nType"],7) + self.assertEqual(k["reqSigs"],20) + + s = [HEX_OPCODE['OP_1'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"MULTISIG") + self.assertEqual(k["nType"],4) + self.assertEqual(k["reqSigs"],1) + + + + s = [HEX_OPCODE['OP_1'], + HEX_OPCODE['OP_1'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + sh = tools.script_to_hash(h, 0, 0) + self.assertEqual(k["type"],"NON_STANDARD") + self.assertEqual(k["nType"],7) + self.assertEqual(k["reqSigs"],1) + + s = [HEX_OPCODE['OP_1'], + HEX_OPCODE['OP_6'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"], "NON_STANDARD") + self.assertEqual(k["nType"], 7) + self.assertEqual(k["reqSigs"], 6) + + s = [HEX_OPCODE['OP_1'], + HEX_OPCODE['OP_6'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"NON_STANDARD") + self.assertEqual(k["nType"],7) + self.assertEqual(k["reqSigs"],20) + + s = [HEX_OPCODE['OP_1'], + HEX_OPCODE['OP_6'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKSIG'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"NON_STANDARD") + self.assertEqual(k["nType"],7) + self.assertEqual(k["reqSigs"],21) + + + s = [HEX_OPCODE['OP_1'], + HEX_OPCODE['OP_6'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"NON_STANDARD") + self.assertEqual(k["nType"],7) + self.assertEqual(k["reqSigs"],20) + + s = [ + HEX_OPCODE['OP_6'], + '21', + '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953', + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"NON_STANDARD") + self.assertEqual(k["nType"],7) + self.assertEqual(k["reqSigs"],20) + + + s = [ + HEX_OPCODE['OP_6'], + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"MULTISIG") + self.assertEqual(k["nType"],4) + self.assertEqual(k["reqSigs"],6) + + + s = [ + HEX_OPCODE['OP_1'], + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"MULTISIG") + self.assertEqual(k["nType"],4) + self.assertEqual(k["reqSigs"],1) + + + + s = [ + HEX_OPCODE['OP_1'], + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + '21', + '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"NON_STANDARD") + self.assertEqual(k["nType"],7) + self.assertEqual(k["reqSigs"],20) + + + s = [ + HEX_OPCODE['OP_1'], + '21', + '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b', + '21', + '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d', + HEX_OPCODE['OP_DUP'], + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + '21', + '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f', + '21', + '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e', + HEX_OPCODE['OP_6'], + HEX_OPCODE['OP_CHECKMULTISIG']] + h = ''.join(s) + s = unhexlify(h) + k = tools.parse_script(s) + self.assertEqual(k["type"],"NON_STANDARD") + self.assertEqual(k["nType"],7) + self.assertEqual(k["reqSigs"],20) + diff --git a/pybtc/test/block.py b/pybtc/test/block.py new file mode 100644 index 0000000..864568a --- /dev/null +++ b/pybtc/test/block.py @@ -0,0 +1,637 @@ +import unittest +import os, sys +parentPath = os.path.abspath("..") +if parentPath not in sys.path: + sys.path.insert(0, parentPath) + +from pybtc import * +from binascii import unhexlify +from pybtc import rh2s +from pybtc import * + +block_a = """00000020358d4156e298db6a1158e7796d511e7c3076ab64fd10bed03c1600000000000063b17c526b14f986fc73334d0879fb052daffdd33c1e280baa52d13b67aa98ab9c6d7d5a402b371a9465559c05010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff3103cf891300049c6d7d5a04545d002b0caff5545a289c0100000000000a636b706f6f6c0d2f6d696e656420627920636b2fffffffff02d82cab04000000001976a9147c16d7bcff670c37bab219e9407d75ceafaa34d488ac0000000000000000266a24aa21a9edf97be29b2cda15085a4bac02d8f9bcc6273744287c41e353ba394a6394f68799012000000000000000000000000000000000000000000000000000000000000000000000000001000000000101989da20569b2aca132eb0f8e0090c370d41edf59cf6e1520a8aabb2d1371378d0100000017160014a9389bcb70e54d474465d7ce90bcd8793cf3a9e2ffffffff0280778e060000000017a914a640d6d68fa719d2755bda2552c3e6958fc78bc087fdf684f61500000017a914ce175699405d5329596d3885e6aff61dc22b657d87024830450221009656689a849fe0cbc588442d56418270d21537e6c64d80aad394b57a182c246002200c94e5b11331709dd6b5a13b6643baee1e65537cf601ae5ccc70309185c5f423012102108261b4b61e9cb9bc54049a230e1509513d5a51881db0763cc9ffc50ca50b97000000000100000000010192ef9685c684dc644de8d4763ebf7072c656a1b6595fef9070a959ce42db970e0100000017160014a5b77a54a03531774805d7e97691b0828b5bf7e3ffffffff0280a4bf07000000001976a914efa24b963bc2f47ee35e1d43842668cc12eb3b0288ac42e8adf11500000017a9143c29761703c645d0e2c68dc22a5f56b3c60db37a870247304402205c4952fabdfd3ee859e7fc486762689456580f0ba158179ebfbba630acfa1b0e02205929178f15509b400fcd426d3e17c3e75ee72fd19bf80447ce04cc9297fbe0fb0121032455df65ea00ef726cc39a21f022ab459bb459ba19be604073c33fed2b16836b0000000001000000018cceaf4a6cc6745bc7387e12a69194c3f0f84ca677ea84fd90a27994a0023e5200000000fd660100473044022010a7b12a6c46b59ab25aa65750c51a14a997c83141f9ae5d7e788d473eeb6d3b02204b9087fcdda3317c35a53868db9bf3773e35c0a1b1a3e4c195b18455d915b7e70147304402202d8a8becc14d18e00305d8af81207fd15b53b2d5b0a26ed8e9fbf4dceaee78220220255302d8b6ed246e698887fb1b0550d6e8127ee1d1d5014eea5c779c2b84dd9401473044022032a19463e29fbbf72c198031c4a89eb48ca1556a1fe75c1e96b5a3ed4109023c02202f8db619c12256bbd5122c486a1843f60adba1a400ad7e5e082306e068659024014c8b5321039f37268e558566e5a816bdd32e2fdb46ed0106ead3bbeedd2e56d4ef24803dc02102718a52e82f51fcf0cda12ee34699bee4575430d6c7bb7503a7f243f0d0c3a85521035f62cccfb1108526ce32db4ffecb1d1d1be118899529b6a0697b81b2109994b8210206e93b92d95a053ad1c1bd43a52368c7edeb446caad63506621618fddd75a0a454aeffffffff02e0d40e000000000017a914a1726229f16d5ddf5bb6712b68003d7fed79f0be870000000000000000326a3045584f4e554d0100580f0200000000003080cc90dc9e59cd41664653b6df7419dc50dcbede2ec85c948890fc310a858e000000000100000001f62bf88577e7596b32246788b31119632da7db7df143ac0dd7716f66e1f7b5f300000000fd67010047304402201b0df8489f2ff8258d6d7f81e6a4bae875206d3d9634abf4bdcb26d93b4919af02206b8a05945d029afa84eb13b09667596657edacdc0994aac7d4579c932517661e0147304402206b18469f261a2b9ba044527a99ce5284575031af2b272f68ac284b5e1fc61e7302200269c2240c264a466c2dac545aee38b4b58fd9556a61d2b742dee032670d42d301483045022100e6a9ab3f91e6391ce20194084911e28ac1004f7970d7fc3b2d2b05325a048fb20220433616d1053d61780812cf7638ce66d4fbff85aab2d2761cea583b81bd8ee004014c8b532102949dcb6f05bc5b1fb8855aa0cbbd883edc70b1785a492bf1fa0c0287a8befc3321023193f287b227fb572f63d11aaa03a05fafc47f29caa5f8bb350359bc24191cee2103cd4aa05c4952acf1c29185df960e68787ac59aa30d6e748ff833522e4d11c8e3210221b476c94496bef7c4ace3af3e9c7bc805587f67870c425cafc6dc4a7bafe74754aeffffffff02f8530e000000000017a914b68c3488d295902dd465b486cc51be2d29af2408870000000000000000326a3045584f4e554d0100e0930400000000004892a52323d0775a566e44467b4f7aa1b0723cc98ec9e9e3f3ba266d658c8cb000000000""" +# # 00000020358d4156e298db6a1158e7796d511e7c3076ab64fd10bed03c1600000000000063b17c526b14f986fc73334d0879fb052daffdd33c1e280baa52d13b67aa98ab9c6d7d5a402b371a9465559c05010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff3103cf891300049c6d7d5a04545d002b0caff5545a289c0100000000000a636b706f6f6c0d2f6d696e656420627920636b2fffffffff02d82cab04000000001976a9147c16d7bcff670c37bab219e9407d75ceafaa34d488ac0000000000000000266a24aa21a9edf97be29b2cda15085a4bac02d8f9bcc6273744287c41e353ba394a6394f68799012000000000000000000000000000000000000000000000000000000000000000000000000001000000000101989da20569b2aca132eb0f8e0090c370d41edf59cf6e1520a8aabb2d1371378d0100000017160014a9389bcb70e54d474465d7ce90bcd8793cf3a9e2ffffffff0280778e060000000017a914a640d6d68fa719d2755bda2552c3e6958fc78bc087fdf684f61500000017a914ce175699405d5329596d3885e6aff61dc22b657d87024830450221009656689a849fe0cbc588442d56418270d21537e6c64d80aad394b57a182c246002200c94e5b11331709dd6b5a13b6643baee1e65537cf601ae5ccc70309185c5f423012102108261b4b61e9cb9bc54049a230e1509513d5a51881db0763cc9ffc50ca50b97000000000100000000010192ef9685c684dc644de8d4763ebf7072c656a1b6595fef9070a959ce42db970e0100000017160014a5b77a54a03531774805d7e97691b0828b5bf7e3ffffffff0280a4bf07000000001976a914efa24b963bc2f47ee35e1d43842668cc12eb3b0288ac42e8adf11500000017a9143c29761703c645d0e2c68dc22a5f56b3c60db37a870247304402205c4952fabdfd3ee859e7fc486762689456580f0ba158179ebfbba630acfa1b0e02205929178f15509b400fcd426d3e17c3e75ee72fd19bf80447ce04cc9297fbe0fb0121032455df65ea00ef726cc39a21f022ab459bb459ba19be604073c33fed2b16836b0000000001000000018cceaf4a6cc6745bc7387e12a69194c3f0f84ca677ea84fd90a27994a0023e5200000000fd660100473044022010a7b12a6c46b59ab25aa65750c51a14a997c83141f9ae5d7e788d473eeb6d3b02204b9087fcdda3317c35a53868db9bf3773e35c0a1b1a3e4c195b18455d915b7e70147304402202d8a8becc14d18e00305d8af81207fd15b53b2d5b0a26ed8e9fbf4dceaee78220220255302d8b6ed246e698887fb1b0550d6e8127ee1d1d5014eea5c779c2b84dd9401473044022032a19463e29fbbf72c198031c4a89eb48ca1556a1fe75c1e96b5a3ed4109023c02202f8db619c12256bbd5122c486a1843f60adba1a400ad7e5e082306e068659024014c8b5321039f37268e558566e5a816bdd32e2fdb46ed0106ead3bbeedd2e56d4ef24803dc02102718a52e82f51fcf0cda12ee34699bee4575430d6c7bb7503a7f243f0d0c3a85521035f62cccfb1108526ce32db4ffecb1d1d1be118899529b6a0697b81b2109994b8210206e93b92d95a053ad1c1bd43a52368c7edeb446caad63506621618fddd75a0a454aeffffffff02e0d40e000000000017a914a1726229f16d5ddf5bb6712b68003d7fed79f0be870000000000000000326a3045584f4e554d0100580f0200000000003080cc90dc9e59cd41664653b6df7419dc50dcbede2ec85c948890fc310a858e000000000100000001f62bf88577e7596b32246788b31119632da7db7df143ac0dd7716f66e1f7b5f300000000fd67010047304402201b0df8489f2ff8258d6d7f81e6a4bae875206d3d9634abf4bdcb26d93b4919af02206b8a05945d029afa84eb13b09667596657edacdc0994aac7d4579c932517661e0147304402206b18469f261a2b9ba044527a99ce5284575031af2b272f68ac284b5e1fc61e7302200269c2240c264a466c2dac545aee38b4b58fd9556a61d2b742dee032670d42d301483045022100e6a9ab3f91e6391ce20194084911e28ac1004f7970d7fc3b2d2b05325a048fb20220433616d1053d61780812cf7638ce66d4fbff85aab2d2761cea583b81bd8ee004014c8b532102949dcb6f05bc5b1fb8855aa0cbbd883edc70b1785a492bf1fa0c0287a8befc3321023193f287b227fb572f63d11aaa03a05fafc47f29caa5f8bb350359bc24191cee2103cd4aa05c4952acf1c29185df960e68787ac59aa30d6e748ff833522e4d11c8e3210221b476c94496bef7c4ace3af3e9c7bc805587f67870c425cafc6dc4a7bafe74754aeffffffff02f8530e000000000017a914b68c3488d295902dd465b486cc51be2d29af2408870000000000000000326a3045584f4e554d0100e0930400000000004892a52323d0775a566e44467b4f7aa1b0723cc98ec9e9e3f3ba266d658c8cb000000000 +# block_b = "00000020770aa9d59da8a8d897ed2aa023755d774c859bd7740e3fa6ef11000000000000a1bdc212eaae007129353da83ba81c3361681fcd526a9543f6b0210b4e595d1a5d8a7d5a402b371ae4be5a2202010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2b03df891300045d8a7d5a0456360e330c64887d5a73887d5a410f00000a636b706f6f6c07746573746e6574ffffffff02699ea904000000001976a91422ba040f820174c8ad8d3b568c2801390a81fa8c88ac0000000000000000266a24aa21a9ed15e05d39fb8de40813e91f4029eb0c0bdfd27df73bca3253b4c738c1cd8b374e012000000000000000000000000000000000000000000000000000000000000000000000000001000000000101875e650b1096e216784b141f98318ec9c6f4093cade620ffad8c753304b6028101000000171600142392b05ad19a4706f1a5c3feb1f37690b964cab5ffffffff0263190000000000001976a914eb2d08a5e7839661eaf02a39289f991ad8b44d2688ac3d9683d71500000017a914a10bf0bf639376e87a6b94559a67a328e88484f28702483045022100bd9b6f580242576d069b6e0cda91260166b969fbe8748a7238364324c669031a022051e602d7b0de61442d064baaef85a355667ffcb89b45aa7fa0f3eacf68a1aa8401210351286a6b3f8f603f35e8bdcda042973fcfe31385ef436e04c2c733fe8dead8d700000000" +# block_c ="00000020000000000000103cd40624d96d263493b88f71a148233b93451c4550c7e1c50a3cf28d16f386fc108a349edd9b5cde0935a0b7433aa4bd63145c83ade7dc93e75a80b5e71a372b4005bfac060a010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2303278d130068747470733a5c6170692e6269746170732e636f6d20d4ce1ac82a6b0000ffffffff02cafcab04000000001976a914d4e49947b9f545218cd20389244c249d3520545d88ac0000000000000000266a24aa21a9ed9c8ebeb53b3138337dcaacf0fb4d8fc1ce22a703312490bc6052cf1612ca6f57012000000000000000000000000000000000000000000000000000000000000000000000000002000000014733f43bb0952e3923ca689c4654da57222ef6b206cddd98985e80cec70ae581000000006b483045022100c309ebef9f2ea1d90336744e5a16a3d9cffafac9703ad88d2238859bebb440ff02203237047ab7ceacb5b94c35d5ea328775ecc898d2ba31272d06547e62f4665a0f0121037d094a55f3e12250aae026d3c04200d4dac282119601582678e2132b3bb2b078feffffff02ff547e04000000001976a9147863159848199efe02a51173e0cb5450d34d6f0c88acee0673c9120000001976a9146507aba717d88d7a48c75e59e3029e4b8ba3d15a88acce8c130002000000013b4973fa693a5ed999b488c494875bf5dee3f0201bd624d5f69a45499d263306010000006a473044022027f0a45246e972dfeb4a472ea46e3ac0ea55d8afbed2dd3af4ab04a3fc2e48e302203fc530e0f1206ab001eb8f663f0b8d64d4947d56900d3deccb073839285feccb012102d385d34c77c3125b7960a7b50fc9217c5e9916d49741f5ac56c35ae8da4dfe30ffffffff020000000000000000256a235357019c81d330a82cc58dafdab97093d841f5fa8f92d77eac54d0f1a23b22c2d187a35eaa0200000000001976a914278474a2dcb178ad4bd4f0f78064e0f5b0edf6e588ac0000000002000000017c98882bf8edf7f85f20fbb04eddd51839327773b75779611a231d0f92636b05010000006a473044022018e5f483b4bbdd94862d9f9b01eaf46c191ce8538dee5bdcf23d96e095305c840220557c2efc5a807bfa1d1d8ba0ce31d0b80edb76a35b3ada544fad03cb1439b5b0012102d385d34c77c3125b7960a7b50fc9217c5e9916d49741f5ac56c35ae8da4dfe30ffffffff020000000000000000256a235357019c81d330a82cc58dafdab97093d841f5fa8f92d77eac54d0f1a23b22c2d187a3bba70c00000000001976a914278474a2dcb178ad4bd4f0f78064e0f5b0edf6e588ac0000000002000000012bf1cba437312f6e8a9ef9a3a645fdd4369e26fefff607b0a6f971f06b8c75d3010000006a47304402206f472cf510fedcd44986ffbdd4df45c76bcfe149747794259f4db3e2a2490108022012e7f5a2737646bc2ceebae7f81166529ded77cc7b008f78ad481ca6fc46dbfe012102d385d34c77c3125b7960a7b50fc9217c5e9916d49741f5ac56c35ae8da4dfe30ffffffff020000000000000000256a235357019c81d330a82cc58dafdab97093d841f5fa8f92d77eac54d0f1a23b22c2d187a3f7691f00000000001976a914278474a2dcb178ad4bd4f0f78064e0f5b0edf6e588ac000000000200000001260ff9bd233cf6c1597dcdabcbf78b11184419fc1bd3966d289a25ebe5cfde1e010000006a473044022069cf55fe3c50600f9f876d24a73d1e5fc9897e2a360e77d2719faa36eeb59251022066a0d7b851e87febc80c704fc09cddc9f96379027c7a1247f69c9818c185aad9012102d385d34c77c3125b7960a7b50fc9217c5e9916d49741f5ac56c35ae8da4dfe30ffffffff020000000000000000256a235357019c81d330a82cc58dafdab97093d841f5fa8f92d77eac54d0f1a23b22c2d187a3bc180f00000000001976a914278474a2dcb178ad4bd4f0f78064e0f5b0edf6e588ac0000000002000000016aac147c604bb883e676e1c3fe2b1e60ba6fcc3573b334e70e287354843414c6010000006a473044022036f18ce444229d2bb0a4e5ef10278ac82670ef197471353f8b67b3694abc351a02207c6d58e9aa84234c2244c33eadc5401ba9019b853a9d258d6e8b498932b74cb6012102d385d34c77c3125b7960a7b50fc9217c5e9916d49741f5ac56c35ae8da4dfe30ffffffff020000000000000000256a235357019c81d330a82cc58dafdab97093d841f5fa8f92d77eac54d0f1a23b22c2d187a3bcbf0800000000001976a914278474a2dcb178ad4bd4f0f78064e0f5b0edf6e588ac0000000001000000028e59bf8afd391881a33e4e277373852d384096693654f9ee57eb571813f3814f01000000fdfe0000483045022100c65c19e9c36003111e994dea2555267c71d6d5a7ba70372146b460c46914842402201f850408d6fd0531b4bc97a7ea10fc5eaa886437d3174b19d87e22c59d232ab301483045022100c35ba17f5c2c62ef46499f4c15dcbc0130193853a2a75835ac4782c3f3f1c08b02207181bc732de489496f293678bc529e6c8092e1fdc7b7f4e4d254966660be7460014c69522102be54e9a71908f8ca9d73fa39d0cdfa42c462d28c8bd78f892c5d7c66e6b8d3752103ee6e1f7e41ab7b5401b22bc1e065493ed82b789c298196125acb75b7c598f603210393abd91f1d414ac15e7934788b8f3d91175b1fc979b8b14fd67fb6b2091ae1fb53aeffffffff9a66238a971a939926a6ac653caabf7c2781afc850358ceea50ebfaaeb7c70d900000000fdfd000048304502210082bdce0d12ba7de95103e79a25ad2d70529ed1a3fb091f07bee56905dbd759ce02200390714c151d52ad7ab95300f4c9af22f13c65f57546f68092848fbc36f782950147304402202da2ccfb83e71b2a5fe16709d5aa14992a596d4c828bca9899cbb3783a1c5428022054086bb02db7ad1d5fff34760275ef068a6042cce244c6354f70e283a76aafec014c695221029462cfdefa0f1a790c2bcc6a8e0201ab663be0e65d92c71f5e04727fd0bb2ab42102177373a3da72987fe3e39fe800ba1d2dbeb7d6fcd404db051329cbba28ecbbf82102478a976eef94fba38c86da8dca474593a9149ee9d08b7550e751df8c1509b52e53aeffffffff02a08601000000000017a914b78eaa6e1b0d4510dfc78bece72f3a517e0a162687764a00000000000017a914dddd2d4eb5950c8ec394ea44081560a6b1c3ef73870000000002000000014a87b7e27bfdbae90103aed7267531ad61ddd73fda99a51dd7c987b74bd54086010000006b483045022100b509165fa40bd108e44dc2d31891f350511fc14c3aae782e5bb85f4f9c4e539d022061602033ff412b24d4b6bcfd294ebd0afee5d83b5a45eea93113d1e525b121b7012102d385d34c77c3125b7960a7b50fc9217c5e9916d49741f5ac56c35ae8da4dfe30ffffffff020000000000000000256a235357019c81d330a82cc58dafdab97093d841f5fa8f92d77eac54d0f1a23b22c2d187a38e960400000000001976a914278474a2dcb178ad4bd4f0f78064e0f5b0edf6e588ac000000000200000001b1ff0067cfb3663c3e9fa8704ea190f086a4be6898ff03251ec3d71a6a40b551b00000006b4830450221009a99303bcb8d86cbdc9acce6c512fc6e7bcc502b1877438473edf5e2caaf141c02206169d5a837a07b37ec7b94119329aa69268e85ab6fdf1da0a04fc2381a93fb1201210242cb74d74bc5d281d80dd2ab21a4e5f454c177a775d1bec3aac0af461fb7afdbffffffff0100050000000000001976a914ffa73d19c1d7b4a81f7eb42df1731b499734da9488ac00000000" +# block_template = { +# "capabilities": [ +# "proposal" +# ], +# "version": 536870912, +# "rules": [ +# "csv", +# "segwit" +# ], +# "vbavailable": { +# }, +# "vbrequired": 0, +# "previousblockhash": "000000000000289f2c0ddd382204f00a074f3dc45ee67dd24931c332769678a2", +# "transactions": [ +# { +# "data": "02000000018d391ad038d0ab892bfe778fbca922570006b5433c794150fc0b6cdc0d4d8c24010000006b483045022100d47d2e260d15014bc76e8bfabc5b24d3861b3f5546912ccf25448ec3a99713df02203d6400d31a67c95b080aec14287295518d936f235fc0ae9f1dcbd2b38bdf8f9a01210265e757b7789d4207a6c8b31f6f61fffb7e77f38466a09f854503e79ba9921042ffffffff01647648050000000017a9145f49aacdc4f9a50e71073e8ed3c449a2775951768700000000", +# "txid": "adedea018281f4634bbbb8a9ab59c22d898a2f9b0a7e99645fcde5881a2b9297", +# "hash": "adedea018281f4634bbbb8a9ab59c22d898a2f9b0a7e99645fcde5881a2b9297", +# "depends": [ +# ], +# "fee": 211890, +# "sigops": 0, +# "weight": 760 +# }, +# { +# "data": "0200000001778242b7e893a75eac2f23d4fdd1089dddb96f15a6180888a74e0afa1039bb89000000006a47304402202607e5e111fbea1be4c522492d8ec75261295ff67c7ae2e178b40e632acbd2df02201c793fcec0c40e136dd940df7086b9251bcb0400fab81fc6a11bbc9cd57a9346012103f20010e67b3b8c4570ecd5e41e2e5c76aca47a2875ed8baf81d03e0ee58362b3feffffff02c09c6a150000000017a914c69533f8dee891ab00b10a53ca5da3a0aeb1338d871520009f390000001976a91443f8560c317db0cc9cffe2493cdb666d8af8fb4888ac218a1300", +# "txid": "1102b32f8d3178906f6f7eedf55c1db8065410287d6f2bb63f845be3732ca423", +# "hash": "1102b32f8d3178906f6f7eedf55c1db8065410287d6f2bb63f845be3732ca423", +# "depends": [ +# ], +# "fee": 112000, +# "sigops": 4, +# "weight": 892 +# }, +# { +# "data": "0200000001ddaa8cb4301386aac07445316ea6e77c415c7c1b55b1c8fc157bf4dbad904f48000000006a47304402200cc11f209b4d711e3bea37d5cb590aa5e93bcac3139f70e283550aaecc6e41860220422655042d71f539aa8c58d83e4647986db544fad6529a4c4b4decb2bef64063012102f9077641d9bcc3f4b1cd88806bc3753db9163c7c3e30973733efe2eb158048e6feffffff02dc85ba0b0000000017a914c69537336abdf1fbff7c402961588bd6f7c0612487344f7431220000001976a914f0f058cf6a10e06eb566e807c0d46975eb528f5e88ac218a1300", +# "txid": "e0cdcdbde06d28370ceabca5858383063ca49f5401d0b1f1eef07d7590ac9730", +# "hash": "e0cdcdbde06d28370ceabca5858383063ca49f5401d0b1f1eef07d7590ac9730", +# "depends": [ +# ], +# "fee": 112000, +# "sigops": 4, +# "weight": 892 +# }, +# { +# "data": "020000000123a42c73e35b843fb62b6f7d28105406b81d5cf5ed7e6f6f9078318d2fb30211010000006a47304402206dec928bbfb1b528d12cbc0616d5216670662b79df6c2aa23ba49c89d8c4e52402206cb09aeee2673908276cfa3985daddc7cb8c76415e64fcf42b59323c7ff40593012102627faadf34ee604025f928eecaf4b82fdbbfdcaee3f6d73bedd1debdfe922973feffffff020069328e390000001976a914ff840cb02ec485aadf183587dac007012c0522bd88ac9501cc100000000017a914c69533f8dee891ab00b10a53ca5da3a0aeb1338d87218a1300", +# "txid": "534aad37f7ebac88e1230ebcbf03e39478fe67c85d7819f4d7cc18969951b349", +# "hash": "534aad37f7ebac88e1230ebcbf03e39478fe67c85d7819f4d7cc18969951b349", +# "depends": [ +# 2 +# ], +# "fee": 112000, +# "sigops": 4, +# "weight": 892 +# }, +# { +# "data": "02000000013097ac90757df0eef1b1d001549fa43c06838385a5bcea0c37286de0bdcdcde0010000006b483045022100b26745d16059f2696cbe302fdbaea61ee1d9c5a853e3b058f279a59c5b057854022064e6ef71ac851225d6b9fc8ecf97b904cc228d02b83555903850b890e3d65da00121021fe6ff371efd74e52f04f890a4399de7e54e948356146cb8716ec1be2306afc6feffffff0253383d060000000017a914c6953588f38d06d640a838e7cf6e6fe4f4d17b92876161352b220000001976a914c3e56e70feb2af70d7bf587643016cc1aa1edcc088ac218a1300", +# "txid": "0ee0cf5f7cd415e1ceeb57919ee99c71cb495163aa44bc3dee2c25e198f81147", +# "hash": "0ee0cf5f7cd415e1ceeb57919ee99c71cb495163aa44bc3dee2c25e198f81147", +# "depends": [ +# 3 +# ], +# "fee": 112000, +# "sigops": 4, +# "weight": 896 +# }, +# { +# "data": "02000000014711f898e1252cee3dbc44aa635149cb719ce99e9157ebcee115d47c5fcfe00e010000006a47304402200875e97f19b8d2d282aef47b2b2ede0f780ec585f6fa741d900d05db168d09740220622ef6777fa4f109ab42af6976caa7864b29df05f66fc75f805040b29cfe1e1a012102e732d6c1283a35c3cf0565d4c2c09da3647b9913651ff0a7115bfee409aaa7e5feffffff02d973ed1f220000001976a914679d6a545c45516f4cb00320558a5665a8ea33a488ac0838460b0000000017a914c69536e5aaa50fcf53f6e433454797dce14f62ba87e9891300", +# "txid": "d1084adf211f17f828dd5e976b1cb96ef2ca9654314cb3d535361b7a2fc7834b", +# "hash": "d1084adf211f17f828dd5e976b1cb96ef2ca9654314cb3d535361b7a2fc7834b", +# "depends": [ +# 5 +# ], +# "fee": 112000, +# "sigops": 4, +# "weight": 892 +# }, +# { +# "data": "02000000014b83c72f7a1b3635d5b34c315496caf26eb91c6b975edd28f8171f21df4a08d1000000006a47304402204a33e70bd1ef6db33c4efe26f76c6a6cf998cce2e43bdd95f500f734c9b5a1b4022045fd6d337cc37f8f37704daedbc6a7174837910ec432dedb4b976f1e38bf4808012103abf4c59ba16be83fe0f89beb343e0fe85a3ecbeae21cfa456de76e7c12d9b483feffffff02771c19030000000017a9143207c5cfc389ec7fa6d18b55557b1c419ceb548e87e2a1d21c220000001976a9143af2d13f3344b16051efe30fa2e1de68930e76ba88ac218a1300", +# "txid": "161464d9ea88b48876520d7187ae7a0770741c97cc5cbceb649b20ab5bfc893a", +# "hash": "161464d9ea88b48876520d7187ae7a0770741c97cc5cbceb649b20ab5bfc893a", +# "depends": [ +# 6 +# ], +# "fee": 112000, +# "sigops": 4, +# "weight": 892 +# }, +# { +# "data": "010000000142b3b77c33c6cd2faef69ce87b7c5340e6ba1508580dd5dae671adaebd48d623010000006b4830450221008ffcc0bda2eac358ad6f1f95f0e8affe87e72c6e9d1358fda83eeb2aa6ac9ebb0220078e0a5280f49fe9847cade71896e5bab8f733a96d1a6e85544dda61a8ba15cb012103b403539e4175cde64cc99b71d0d9cfc701c193bed1d6df17ae37b92e8506f141ffffffff0200000000000000001e6a1c504f45540000000206b49b2877a2c3617c2baa3715a5f1d281f0dd42c30638510a0000001976a9140fcc88829c46f85443edcce2150a8edbf57b48be88ac00000000", +# "txid": "07e290439427132272fc4659e73ba8ea3dd8acc9c5a1e1af237b0c543ed1009f", +# "hash": "07e290439427132272fc4659e73ba8ea3dd8acc9c5a1e1af237b0c543ed1009f", +# "depends": [ +# ], +# "fee": 100000, +# "sigops": 4, +# "weight": 924 +# }, +# { +# "data": "01000000019f00d13e540c7b23afe1a1c5c9acd83deaa83be75946fc72221327944390e207010000006a473044022039c5760f1360a116d97ead676b03ce411eac1e0a3c4034b41d451c460e06c8ca0220772dcff5e02f9072c3e415bde162028f1e4a153dda75be5c019532e5004fb54c012103b403539e4175cde64cc99b71d0d9cfc701c193bed1d6df17ae37b92e8506f141ffffffff0200000000000000001e6a1c504f45540000000220429bbb2843aa1c5a07be2f656c4e9def1f2ddc238036510a0000001976a9140fcc88829c46f85443edcce2150a8edbf57b48be88ac00000000", +# "txid": "d70b312bebc09451c727518c94c3e917899f3717fb54ce266f609640f23a320e", +# "hash": "d70b312bebc09451c727518c94c3e917899f3717fb54ce266f609640f23a320e", +# "depends": [ +# 8 +# ], +# "fee": 100000, +# "sigops": 4, +# "weight": 920 +# }, +# { +# "data": "01000000010e323af24096606f26ce54fb17379f8917e9c3948c5127c75194c0eb2b310bd7010000006a473044022076d55c94f6e0a7857aceefc14f07d8ef97bbe4a85021955a771df7d20386261802207ee1cbf67783fd5fcc30d6ff5c38cc40c9668893095f9cdda0657cb4b357bf76012103b403539e4175cde64cc99b71d0d9cfc701c193bed1d6df17ae37b92e8506f141ffffffff0200000000000000001e6a1c504f4554000000025dedcff71eee29a04aea8109e73df3e96e9fa62a83f934510a0000001976a9140fcc88829c46f85443edcce2150a8edbf57b48be88ac00000000", +# "txid": "d22fa8f3177db58eb88f8d19bc10743efbe0ea64735ab39d91149ba140150666", +# "hash": "d22fa8f3177db58eb88f8d19bc10743efbe0ea64735ab39d91149ba140150666", +# "depends": [ +# 9 +# ], +# "fee": 100000, +# "sigops": 4, +# "weight": 920 +# }, +# { +# "data": "010000000166061540a19b14919db35a7364eae0fb3e7410bc198d8fb88eb57d17f3a82fd2010000006b483045022100c219d21caad88f89d9b807d06e13369ffa0d787aa6e12ae74db7faeb8363c79e02206ea3949f8a2eaffe247ff3807cec8d9d334a8b1ae2002da72aa779175bdb7611012103b403539e4175cde64cc99b71d0d9cfc701c193bed1d6df17ae37b92e8506f141ffffffff0200000000000000001e6a1c504f4554000000022ee8eb5c24137b5ca1e6456f1a339120c3e94a4ee37233510a0000001976a9140fcc88829c46f85443edcce2150a8edbf57b48be88ac00000000", +# "txid": "ef0b785703cc62c142120f5fe11b846af79e90fce506054dcbf7aa647a7d22ad", +# "hash": "ef0b785703cc62c142120f5fe11b846af79e90fce506054dcbf7aa647a7d22ad", +# "depends": [ +# 10 +# ], +# "fee": 100000, +# "sigops": 4, +# "weight": 924 +# }, +# { +# "data": "0100000001ad227d7a64aaf7cb4d0506e5fc909ef76a841be15f0f1242c162cc0357780bef0100000069463043022029d58814ccf9e7db0e409e1f93aad3176f931e54f8ab0727bc198b39272932b1021f41814b2fb78284772078b0761a2b7f8c51ab76d035d0dd68bb391577f2468e012103b403539e4175cde64cc99b71d0d9cfc701c193bed1d6df17ae37b92e8506f141ffffffff0200000000000000001e6a1c504f4554000000024feec14d383bb9cd8e1ea0dacbe9025d1da1c40743ec31510a0000001976a9140fcc88829c46f85443edcce2150a8edbf57b48be88ac00000000", +# "txid": "965264b41005f4a6b92402ed4ba1be4891200ecb4a7b11576bb75b22211bc06e", +# "hash": "965264b41005f4a6b92402ed4ba1be4891200ecb4a7b11576bb75b22211bc06e", +# "depends": [ +# 11 +# ], +# "fee": 100000, +# "sigops": 4, +# "weight": 916 +# }, +# { +# "data": "01000000016ec01b21225bb76b57117b4acb0e209148bea14bed0224b9a6f40510b4645296010000006b483045022100eaa7dbcb42fdadf3353e7b9f911b85781f455fe9410a27e02ad12f4b78ea4a1302202e3593b28b4144fe6eff3071b0a7ef3b705098851f79a75206c2a5b0ca7a6c4b012103b403539e4175cde64cc99b71d0d9cfc701c193bed1d6df17ae37b92e8506f141ffffffff0200000000000000001e6a1c504f455400000002e918a50a8246ac707f6dcbbcc703883c897e3ad0a36530510a0000001976a9140fcc88829c46f85443edcce2150a8edbf57b48be88ac00000000", +# "txid": "86d114198075a64957f4fe3b6c4f715d077715bd173aaa219b75fd8456df0f34", +# "hash": "86d114198075a64957f4fe3b6c4f715d077715bd173aaa219b75fd8456df0f34", +# "depends": [ +# 12 +# ], +# "fee": 100000, +# "sigops": 4, +# "weight": 924 +# }, +# { +# "data": "0100000001340fdf5684fd759b21aa3a17bd1577075d714f6c3bfef45749a675801914d186010000006b483045022100fa604226490c53e881d7c92a91054d65a25c77fd6694d1cd57e1e4fe47792b4f022072d64b98fa015b8f2d033cf7e59192cd35128ae8074e788bdf47f49490ed48f4012103b403539e4175cde64cc99b71d0d9cfc701c193bed1d6df17ae37b92e8506f141ffffffff0200000000000000001e6a1c504f455400000002fe7f46991263a0c17b12c047aaa527e4a286b90403df2e510a0000001976a9140fcc88829c46f85443edcce2150a8edbf57b48be88ac00000000", +# "txid": "daffe22de98438784938c1ef4ba00bb69034a389f8d77bbd804e8a5a1df68371", +# "hash": "daffe22de98438784938c1ef4ba00bb69034a389f8d77bbd804e8a5a1df68371", +# "depends": [ +# 13 +# ], +# "fee": 100000, +# "sigops": 4, +# "weight": 924 +# }, +# { +# "data": "01000000017183f61d5a8a4e80bd7bd7f889a33490b60ba04befc13849783884e92de2ffda010000006b483045022100ba449372778edd289742645a87173eef982043fd5a77279b0257ed101fb54657022061dc724a036851cb48c45143e0013929ddb944425295c0b410ea89cb46b823cf012103b403539e4175cde64cc99b71d0d9cfc701c193bed1d6df17ae37b92e8506f141ffffffff0200000000000000001e6a1c504f45540000000244f768bda67a4c83cb61f92b31382437517704f063582d510a0000001976a9140fcc88829c46f85443edcce2150a8edbf57b48be88ac00000000", +# "txid": "59909e0a12cb923355a2fb1eba803a5590e754911e79c0970b90bec15f6f473a", +# "hash": "59909e0a12cb923355a2fb1eba803a5590e754911e79c0970b90bec15f6f473a", +# "depends": [ +# 14 +# ], +# "fee": 100000, +# "sigops": 4, +# "weight": 924 +# }, +# { +# "data": "01000000014648b8a94c92cd11476e44786f6cfe23f18a901311cb5b901ec51dcb4bd4b73e00000000fd660100473044022013776d60a557095260eb6426b99273fbf4055ee63c3088eacfaadc53398e6354022042652562df50eb28ff9305f7aa3349db05bedd93211073c54acde89e9bc2e8ee01473044022018206acb46c7649fdfcf3e731267e599af6e31977e3eddb75ab13aaf6da5f39f02207a0e5b4d431fdde697c785c14fb437c2fa8a58ea393af4cfca55b58f40b7974201473044022033e1c29d740319a1c5e84c8fb49cced35efac7a0cdb488ce1a11d454516ae404022043ae86f96103cb1decf778982e1eb7baf106353220ff1e1d43782fa11f8ddf08014c8b532103bd459027722b7bf77849734fa3518e45adb1fc807e34452ebf675e6c864ec04a21037f1dc7d470b1b9a9dc22e816cb4077b614c171cc7e6a4e7423546104b34197202102564afded0cd71cb3125d2b9a1a6c1877557a9b72b4a5fe51234f583f4836dcf6210272f3486792803285182bbc138a11092f0448dc30fa6f028cbc1ba69b59e3a64454aeffffffff02a01d1f320000000017a91481dd0b8e0572b6e4e2b6db741d210af7d754bcc0870000000000000000326a3045584f4e554d010058731b0000000000c26de7c90145db427d7bfc91dab1ae33a11083a3714c4afc3cb07357df95b55f00000000", +# "txid": "0f37a946a8ce7a5eb67f57809ffe2f99147bf13d538be618e386fbb0376d59ee", +# "hash": "0f37a946a8ce7a5eb67f57809ffe2f99147bf13d538be618e386fbb0376d59ee", +# "depends": [ +# ], +# "fee": 100000, +# "sigops": 16, +# "weight": 2008 +# }, +# { +# "data": "0100000001ee596d37b0fb86e318e68b533df17b14992ffe9f80577fb65e7acea846a9370f00000000fd690100483045022100d81e1a01ab9a019fdacc40602fe7a3fe5fdbb9de5169b7aa26f2632a44a6d4df0220026118a23cdd5828d97346babfc7c13073db0c93cca28d71ace0cb0dd0b462a0014830450221009e5f9824ab5af66aee0c045454a590c7d5f3d6ff20ca1cb2b6aa2fa4f187fdb30220607e34292e967b12733300d8f3c603dd0b0c9f59c770556af3a9cb2b50cd4d2d014830450221008c635780d98a52168a34f3e7ea974c33258b33a569a72f43c8e7bab5d7287cda02205ef909417385f34269db0d4ba89ea411d84b28e35247bbcaddd46997f26112b9014c8b532103bd459027722b7bf77849734fa3518e45adb1fc807e34452ebf675e6c864ec04a21037f1dc7d470b1b9a9dc22e816cb4077b614c171cc7e6a4e7423546104b34197202102564afded0cd71cb3125d2b9a1a6c1877557a9b72b4a5fe51234f583f4836dcf6210272f3486792803285182bbc138a11092f0448dc30fa6f028cbc1ba69b59e3a64454aeffffffff0200971d320000000017a91481dd0b8e0572b6e4e2b6db741d210af7d754bcc0870000000000000000326a3045584f4e554d01004c751b000000000087421894b1b27c9d501cffd85479e073a8d62bd285e71d3fe8fdff757c67085a00000000", +# "txid": "c56308d23a194a9cf49df67aa6998b8009b56f89213a29a2efc735300f50b51e", +# "hash": "c56308d23a194a9cf49df67aa6998b8009b56f89213a29a2efc735300f50b51e", +# "depends": [ +# 16 +# ], +# "fee": 100000, +# "sigops": 16, +# "weight": 2020 +# }, +# { +# "data": "01000000011eb5500f3035c7efa2293a21896fb509808b99a67af69df49c4a193ad20863c500000000fd670100483045022100e70fa760c5cb6427e9d900a4a44e7e13ab60d0e8c6ddfa7e8a3e488c5f099d2d02204ffaa6f4a60a10191314f1cd425526c95abc7fab5821453fa178013e81f57ae701473044022008a9fe9c5ea3a7bbc3b023708bf469b37139f5813bc13a7b25eecd2ddb44db8202203bf8d6cbb75011cf1fcb29b923763bb84e70a76a132ffa362afeea1adb32ac070147304402200486f7c49c92e5f18aabee8073d6a357ac9288dd0cb95a51c39e6ad935f5417c02200fe7f1aa094abebe0d711b32383655bd2b7b8a1fb36a3170f92274173b90dc99014c8b532103bd459027722b7bf77849734fa3518e45adb1fc807e34452ebf675e6c864ec04a21037f1dc7d470b1b9a9dc22e816cb4077b614c171cc7e6a4e7423546104b34197202102564afded0cd71cb3125d2b9a1a6c1877557a9b72b4a5fe51234f583f4836dcf6210272f3486792803285182bbc138a11092f0448dc30fa6f028cbc1ba69b59e3a64454aeffffffff0260101c320000000017a91481dd0b8e0572b6e4e2b6db741d210af7d754bcc0870000000000000000326a3045584f4e554d010040771b0000000000403563620e665717afce2d109ac6141360dca9b4d83eb2a65f4aaa992c69dfa300000000", +# "txid": "44cb042ca67dfc2147773a5aebf711be4607e6793338f5ec0cdabafeeb8364f8", +# "hash": "44cb042ca67dfc2147773a5aebf711be4607e6793338f5ec0cdabafeeb8364f8", +# "depends": [ +# 17 +# ], +# "fee": 100000, +# "sigops": 16, +# "weight": 2012 +# }, +# { +# "data": "0100000001f86483ebfebada0cecf5383379e60746be11f7eb5a3a774721fc7da62c04cb4400000000fd680100483045022100c89aafbed082f3b219d711ac7ba557fd7e577b2825329d8d37cbada266e9318c02206cdfd97f4b30d2ed9b1f5bdd72d28f4600a043c86a0d428fff9a309b426bc9ed01473044022036a307ca516340ae3b4b76bc2c09e2e5c593247a4ae1308a212bf1f1665cdc3c022042f84158faa45d1c256bae73746d8490632d6a1fa785e7a138a17bb3145e651e01483045022100a99217f70fd1175b09f81a052d9ec5bec10c1e482f7aaadb777f03063100b0c20220324fe8e2d6de21296ca007c6ad8a7b609bcfe81c76e36040c82393f611c9f42a014c8b532103bd459027722b7bf77849734fa3518e45adb1fc807e34452ebf675e6c864ec04a21037f1dc7d470b1b9a9dc22e816cb4077b614c171cc7e6a4e7423546104b34197202102564afded0cd71cb3125d2b9a1a6c1877557a9b72b4a5fe51234f583f4836dcf6210272f3486792803285182bbc138a11092f0448dc30fa6f028cbc1ba69b59e3a64454aeffffffff02c0891a320000000017a91481dd0b8e0572b6e4e2b6db741d210af7d754bcc0870000000000000000326a3045584f4e554d010034791b0000000000b37029c8da51a2ecc3adabfbc6e9a16b424c43f184ea2c4c2e7664bc2f309c3f00000000", +# "txid": "6b4e2e8ba7479507c39e4e1707ef2b9a04be0e0370876611be419ab9e45e084d", +# "hash": "6b4e2e8ba7479507c39e4e1707ef2b9a04be0e0370876611be419ab9e45e084d", +# "depends": [ +# 18 +# ], +# "fee": 100000, +# "sigops": 16, +# "weight": 2016 +# }, +# { +# "data": "0100000001f6f9a7022660908e28c264b1525befe7ce015ae9f275510c4d228eab7bb7e8dd000000006b483045022100ba26217a6fa085604c3677d6c09a3095eead45de896b810279a11211cab79cad02204cdfec263563e312b26da66350d897a80851b160a2080abad2320f93a0b26cd901210256e3af2b1e059fc6643eeedd0efc7c9157dac3dbce7f29b515af72af03b54fdbffffffff02e8030000000000001976a914df59d5dc48fd0e5d3e6479c7ad70f020eabcfdca88ac2c717b00000000001976a914362f017f2f13f33aa9ad23d2888591f19982b3d988ac00000000", +# "txid": "13357efa88c12aa54ad31cb1ab0407032da420f198a63e5f1f18abd5b901c1f2", +# "hash": "13357efa88c12aa54ad31cb1ab0407032da420f198a63e5f1f18abd5b901c1f2", +# "depends": [ +# ], +# "fee": 34100, +# "sigops": 8, +# "weight": 904 +# }, +# { +# "data": "010000000140765a90de9a68e10349f3b24d181c56b954adf42eebfd990baa20badf95ac9b010000006a47304402202e256cac98f12c5f8c31819875df25494aa752cd1c7fd811ae325cafc93a31070220123a82c4479590a6b3ac1f2b6aa8990751402261a10995643e61eeda6619b5ec012103fe1d271eccc2c31fe8796287cfc9514b12463326224b2f1c69e2e1ccd7c671feffffffff020100000000000000296a27334d6b317a37786b4347446d5955427853794a7844726d71517a5943456a72633573635475704b78240900000000001976a914604169e04cc48bc3b667a62daf284c8d58bc19a188ac00000000", +# "txid": "f6b183e9b4694eabc0258f1a0fb4e9d0a7fac0ab53246295b67ca81ae9af2032", +# "hash": "f6b183e9b4694eabc0258f1a0fb4e9d0a7fac0ab53246295b67ca81ae9af2032", +# "depends": [ +# ], +# "fee": 30000, +# "sigops": 4, +# "weight": 964 +# }, +# { +# "data": "0100000001ef4323258df915d04a5a37e8509acda9913bdbd9ec1f6e5ae9a5ce2901545257000000006a47304402201a153b3cfa3d79ffef91c23db2da28e62a6dbc6b01853284ea3ab5097d8816c6022011129be21297395be97e727e2132acb893be0ac9d28af8d257958e48447df43f012102da594c0921a4735ef9fd6ed1336cf2388c56d8267bcc28e058248f1c6ddd3025ffffffff0263cd850e000000001976a9146f6fdda6575a09ebad60dd07624ebe5b918eb20d88acaa0a000000000000446a4222646364316135633936643937616263666133376533613332396566653733326362333162616530323032393734386162623766373033343335663866353934322200000000", +# "txid": "53a6682b9af4460dc478ecd0f1bd87c3bda64a9da4bef74512154bb36e57c5e0", +# "hash": "53a6682b9af4460dc478ecd0f1bd87c3bda64a9da4bef74512154bb36e57c5e0", +# "depends": [ +# ], +# "fee": 25000, +# "sigops": 4, +# "weight": 1072 +# }, +# { +# "data": "0200000001e6ea865621229b159b120b85499a7ac21692a7027c06fe1e8a52a0bdbe7af6f9010000006a473044022075117a78c2057474dbe41e084faa9d3e4d824b1880236428eb233082a5df8d7702207af57cd221910f7240cc14f7912fa2809a95631f6d10123211c7e0d9aabae4990121027841ffb9dedd74e7e867467b343a804e1b3c05f31c808100480bddf3b18466baffffffff0201000000000000001976a914b4f9e3aed8382696b31330b9cc6bbf0bc140569e88acc35a935a000000001976a9142b616be2d203180500099fc0c57a54012617ccd588ac00000000", +# "txid": "8ae11a1ce273f26c53789d495ea3ebd94b6b7d884cb17459c37798cf7c95c3c2", +# "hash": "8ae11a1ce273f26c53789d495ea3ebd94b6b7d884cb17459c37798cf7c95c3c2", +# "depends": [ +# ], +# "fee": 20518, +# "sigops": 8, +# "weight": 900 +# }, +# { +# "data": "0200000001c2c3957ccf9877c35974b14c887d6b4bd9eba35e499d78536cf273e21c1ae18a010000006b483045022100cb22ad51cd399f2eae08ad8b4ae7a9eb6887b5c7ff6f214a9a70da617502933e02203592f34cf57458c45255d8ed1c41fef418525acbe4411ffba05b59ff7761d8fc0121027841ffb9dedd74e7e867467b343a804e1b3c05f31c808100480bddf3b18466baffffffff02a0860100000000001976a914b4f9e3aed8382696b31330b9cc6bbf0bc140569e88ac9283915a000000001976a9142b616be2d203180500099fc0c57a54012617ccd588ac00000000", +# "txid": "995c2c60270b185165307992fc11be89d161dbfe16f8ecbc5883447b6ca9c661", +# "hash": "995c2c60270b185165307992fc11be89d161dbfe16f8ecbc5883447b6ca9c661", +# "depends": [ +# 23 +# ], +# "fee": 20625, +# "sigops": 8, +# "weight": 904 +# }, +# { +# "data": "020000000161c6a96c7b448358bcecf816fedb61d189be11fc9279306551180b27602c5c99010000006a4730440220197c304ab9324a06dc342f9dde5784faa106107a4ee99a2ce6807ce818a1fd8f022039b74e0a5ee0ba896b98b50fc5ba4c32a9125e7d55a4ba3719311b960d8178870121027841ffb9dedd74e7e867467b343a804e1b3c05f31c808100480bddf3b18466baffffffff02a0860100000000001976a914b4f9e3aed8382696b31330b9cc6bbf0bc140569e88ac61ac8f5a000000001976a9142b616be2d203180500099fc0c57a54012617ccd588ac00000000", +# "txid": "b81fc0b5c5ccce3ac2ec7ffef3b1894be0d904596b36d19fce8fbb95c48aca86", +# "hash": "b81fc0b5c5ccce3ac2ec7ffef3b1894be0d904596b36d19fce8fbb95c48aca86", +# "depends": [ +# 24 +# ], +# "fee": 20625, +# "sigops": 8, +# "weight": 900 +# }, +# { +# "data": "01000000019e2c9b409c594b306cab3e249fbe24000fc192555e47e5f1e8a5b5462334fffa000000006b48304502210094ec2f34f709b793bfbbd74004e1498212d30af188857f2d9bdb779b423230ea022075aab04833dce8a6ca4f15a6648a5a233de6997837a56146a0f8d09551e15b47012102ce696461c14e328f8e82abf32e51251e05d45046f8e1874c9b90fb1afd187b3effffffff0240420f0000000000160014c823decbc9d30a10fb2600d65f5369b228a6040d3c8b6c00000000001600142a8da2900ddb1c18b3f7d403dae147e278a0fbad00000000", +# "txid": "1342b516d5e8801e9a6c045ed0b48d7026b8ecd7e37fb32fd7c9b91eb85d7e2a", +# "hash": "1342b516d5e8801e9a6c045ed0b48d7026b8ecd7e37fb32fd7c9b91eb85d7e2a", +# "depends": [ +# ], +# "fee": 11468, +# "sigops": 0, +# "weight": 880 +# }, +# { +# "data": "0100000001fbce4a04141699f9feb982dabc33a9f5702f3f1f3005a4e68340e7487cd2c34f010000006a47304402202410bfd95cf6f7535fa379e64b28e099a48e39b3e6b144542a0fa44bdba1c37102203b98fb33e1610fcf0e0cf4bc74aed7b632c2697437a8a5e0ec0d418fe6999e9d012102187fa162ef131370d02c74f116824d38a1e75aaa8ca65ae551f4f8298f8528a5ffffffff0300000000000000003d6a3b4343020156d362eeba9521daaa5b20766bd033bf107fece8d2cd054a8daba5070f546cf2d86472f193f7ba4061c7bf18defc6e9e8c0f1e69201640f0b9ee02000000001976a914900fb705e0d29eb70ee73d6b33b239945cb7101488ac58020000000000001976a914900fb705e0d29eb70ee73d6b33b239945cb7101488ac00000000", +# "txid": "81eb68d4b55e82c821f955ca4d56dbf943d1feb9d253d13ce7778b23b5eed1a3", +# "hash": "81eb68d4b55e82c821f955ca4d56dbf943d1feb9d253d13ce7778b23b5eed1a3", +# "depends": [ +# ], +# "fee": 5000, +# "sigops": 8, +# "weight": 1180 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e8210100006a47304402204f1a95be3a12ba6d1551a6bb28c761f13e726d2c4a0cf03781fca301ba0ff0600220342a8bee6f82ee5bdfe5dfe22206e3558774a2f76de33f83ceb6594ad745f26d01210240a07049fc5de766efff66be4ef4ed71424bafee24c1217313c8d7190ec5c126ffffffff01d7030000000000001976a91493a7ae5575446d36982d44a896a3f72162990a6088ac00000000", +# "txid": "d2a6d21ff93662a6ba901432be4afe1e3e948c59f5f41857839249b67c892250", +# "hash": "d2a6d21ff93662a6ba901432be4afe1e3e948c59f5f41857839249b67c892250", +# "depends": [ +# ], +# "fee": 1517, +# "sigops": 4, +# "weight": 764 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e8120100006a47304402201ac7a6e1b209082631cb16956bba69ce054bea70c92ae1408c2aa2e9320de45c02201d7240d2b096670781193b36cf26497096d48fb28666eeca0070a56568088cc30121025c4803138e05435693f1cc67b2b30e7c14f4a7bd3ea709c53d682cb3a54ef4eaffffffff01bb040000000000001976a914fefb15153442233172df7cdd21349c737204d48388ac00000000", +# "txid": "03c7a6b7b546a80d7940988b6d4fbd0ffc752a4f352297cd4bee31053cd26923", +# "hash": "03c7a6b7b546a80d7940988b6d4fbd0ffc752a4f352297cd4bee31053cd26923", +# "depends": [ +# ], +# "fee": 1289, +# "sigops": 4, +# "weight": 764 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e8220100006a473044022036d865f8c217d193a31e18e5c34e4888d91b087e6678eb353948efa54e31539902204cb8956223feee8bf09fb879120562325313acf49b7249ff21d614b6bda65cdb01210243a954f68dfe0acc49e54517a82f7632c221f60cefd2b7fa876cec5cf17c7231ffffffff01bc040000000000001976a914ffa73d19c1d7b4a81f7eb42df1731b499734da9488ac00000000", +# "txid": "d3b17f8356f214c7552649cbb08635fe5a187c283fe9ed23ce0e5e06420cf7a3", +# "hash": "d3b17f8356f214c7552649cbb08635fe5a187c283fe9ed23ce0e5e06420cf7a3", +# "depends": [ +# ], +# "fee": 1288, +# "sigops": 4, +# "weight": 764 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e8180100006a4730440220281f5e01b52472a418148c9639d158c8ef8764f8f983f0a30a0856aeb04e733b02206a41521df30b2ed4b45c2e33fe5713886f7708e7c928935d9f7bfcf1f2f8daed012102a0feffa63be4ac0d22f49c62e5d21780088068ad062426ddbfaedbdc1a5b0f24ffffffff01bd040000000000001976a914feab34ee0375b9ab712cd57d50694d288f93e72288ac00000000", +# "txid": "59afb58aa33e567959bfeb2dca4c0a2086c5c7f7d6250d5a2fd59b98184c5a03", +# "hash": "59afb58aa33e567959bfeb2dca4c0a2086c5c7f7d6250d5a2fd59b98184c5a03", +# "depends": [ +# ], +# "fee": 1287, +# "sigops": 4, +# "weight": 764 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e8240100006a473044022026db2d25e1e9a3d6d818622dd99a3ea5be4735b4ca761bd104bfbb3edcff7df50220036b416af07ea9ab21e25cd18592bad5bd3f03e681abc55383aa80145582ca790121035b2bfb889224341b12a240222e6df998ae77cb382d06793af4c1b318816f3282ffffffff01bd040000000000001976a914ffa73d19c1d7b4a81f7eb42df1731b499734da9488ac00000000", +# "txid": "e87c9d3e8a8890a5994acead3be4e2d946a8c8715d18a8553d4f5b9e43fbeb3f", +# "hash": "e87c9d3e8a8890a5994acead3be4e2d946a8c8715d18a8553d4f5b9e43fbeb3f", +# "depends": [ +# ], +# "fee": 1287, +# "sigops": 4, +# "weight": 764 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e8160100006a47304402206d4bb7b31d5dff4719136d321d7f98f5184db44a421bdee4f6f51bc5304eb05f02200b300c8f5b264aeb1532e0354784b9748af2e1641ea616f9729971e092429384012103261e0837961d28a6ccc8eb6b2e1de96cdf15b10063701ef8470d67129f3ca4c9ffffffff01bf040000000000001976a914feab34ee0375b9ab712cd57d50694d288f93e72288ac00000000", +# "txid": "c6b70556a3768a593e0ffd3a4c285ec54336f9a526a70a662fef44cee57c8e82", +# "hash": "c6b70556a3768a593e0ffd3a4c285ec54336f9a526a70a662fef44cee57c8e82", +# "depends": [ +# ], +# "fee": 1285, +# "sigops": 4, +# "weight": 764 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e81e0100006b483045022100cb629d7528de21423f311cdb5e746c43ba3a946042033792aa84de40e6509c0902203555595bb72650b8736bd3804370ad46d240d0022d75d105cea4b41dcba1543c01210242ad04f550d9e3a9ec5c574a7a43f1e1b2192e396b08f4d85f7732bf2f01d99bffffffff01bc040000000000001976a91493a7ae5575446d36982d44a896a3f72162990a6088ac00000000", +# "txid": "b8cb1ac6e12586ce44f00b26a1e435da90932a0b8522ec8796e2451cda48c64b", +# "hash": "b8cb1ac6e12586ce44f00b26a1e435da90932a0b8522ec8796e2451cda48c64b", +# "depends": [ +# ], +# "fee": 1288, +# "sigops": 4, +# "weight": 768 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e8200100006b483045022100ce298a47ace7d97b5845306ee35f5c1484fcf317cafc796dbe270bb3daa973e802205c06c0bd6e9e8473277896fb22527401a31edd69264369d73dbf8ebd81acb7bb01210310272de0afe4643768c2304cd214320b3a02dc37d783ed573af4e674f6c768bfffffffff01bc040000000000001976a91493a7ae5575446d36982d44a896a3f72162990a6088ac00000000", +# "txid": "57275e1562ea68136f49015fc556f775449e8a1c3e7790c62e1e6400ee73d674", +# "hash": "57275e1562ea68136f49015fc556f775449e8a1c3e7790c62e1e6400ee73d674", +# "depends": [ +# ], +# "fee": 1288, +# "sigops": 4, +# "weight": 768 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e81a0100006b483045022100e5f06ddafdf6ce3655feeb38581a4bf87334349715907220b9f0ec654a8dfda90220736af4ed2af359e753453ad10885800f1137cf3f4c8a08cdaa18441d9e660a73012102a6bd333798681cd37787a39bba3a4dd913358a49bdab6b5ccc5d5f778147d2d2ffffffff01bc040000000000001976a914ffa73d19c1d7b4a81f7eb42df1731b499734da9488ac00000000", +# "txid": "d66276de43202bd610037252358e56ff4b67c88073d267158d8ceb2cbaac2e79", +# "hash": "d66276de43202bd610037252358e56ff4b67c88073d267158d8ceb2cbaac2e79", +# "depends": [ +# ], +# "fee": 1288, +# "sigops": 4, +# "weight": 768 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e81c0100006b483045022100f884253db9ae698f81ad72b478e1174c86155c37c37805a752a1b79cb0bb168502200dd181423033d9b90054cb62fafece5bd967330e987e51acdf10a2e5f20b44fa012103eafd3542b7d2174e51fbeff7b63d71e5af3abffde86b3d3a266f900c2ddcd71fffffffff01bc040000000000001976a914ffa73d19c1d7b4a81f7eb42df1731b499734da9488ac00000000", +# "txid": "386d66caf586327093b4adcf6b236f16f2a684e2205187a3fd8ef30d21966d79", +# "hash": "386d66caf586327093b4adcf6b236f16f2a684e2205187a3fd8ef30d21966d79", +# "depends": [ +# ], +# "fee": 1288, +# "sigops": 4, +# "weight": 768 +# }, +# { +# "data": "02000000016ec20f21eeacbe3eb2c8fc3c6284b194ca13ffaf1abda395ead497b5235cf0e8140100006b483045022100a21f09e4543a9432fd4b52aeebeee829d6d88fb9c7c8a7bc920e10b886005274022049f16cda4db7366fa62fc5d0ddba3efe4e95f30d62ce2b371617e101c9056532012102d4bfff213b594336f27c4ea88b7bdaf064ef9a1be2ef477db5b9306dd1870e44ffffffff01bd040000000000001976a914fefb15153442233172df7cdd21349c737204d48388ac00000000", +# "txid": "0c594c6119de615f5314ed3f9deaa7066c8e4b67bb9250b6d44f1faf5ccb9ec7", +# "hash": "0c594c6119de615f5314ed3f9deaa7066c8e4b67bb9250b6d44f1faf5ccb9ec7", +# "depends": [ +# ], +# "fee": 1287, +# "sigops": 4, +# "weight": 768 +# }, +# { +# "data": "0100000001ef255c42de05c4cbdfb21ca7a811b973a12ff934c105a87d8733604439b78642000000006f0047304402203a634b47cdfd459e5334d093586ee6f35b7ab4211449c389afc9f2283d8d86c50220524a9d330abc89821386f4eae4a736fbaf2f4961f5b1742a60cd3588d61a105f0125512102473e862a0e90d86a1c97bc838b23b60ad39bf13706a6a88166331f194b87f04a51aeffffffff02405471040000000017a914d769dd9a7816a92829461ccf828a2626db246802870000000000000000326a3045584f4e554d0100d4c0fb0000000000bebe2813300b5a23bb73e25d7150a5267133c69137c7edd374b0ed7871b6f57100000000", +# "txid": "38d401ab8ef311b62b45e4fd9a5825b60aa4683f6a53b28cebdc923fdd05f381", +# "hash": "38d401ab8ef311b62b45e4fd9a5825b60aa4683f6a53b28cebdc923fdd05f381", +# "depends": [ +# ], +# "fee": 1000, +# "sigops": 4, +# "weight": 1012 +# }, +# { +# "data": "010000000181f305dd3f92dceb8cb2536a3f68a40ab625589afde4452bb611f38eab01d438000000006f0047304402205ba8351b70a4152c2e892c85d5afb7778d5929a366301c97c19bd39d62ca78590220413c8e2a9559b14ddab0d0b4e3e7c656f4cb1abc14a5856b9f21c535224d0b210125512102473e862a0e90d86a1c97bc838b23b60ad39bf13706a6a88166331f194b87f04a51aeffffffff02585071040000000017a914d769dd9a7816a92829461ccf828a2626db246802870000000000000000326a3045584f4e554d010020c5fb0000000000ba47b7fe4e9ecf98509611f074b2ebfe340b9e6372ab15d295b923664f56ff1c00000000", +# "txid": "ec124f6ee44393c74b9be5dfa26426818c60010aa964d4d0b3238fae1b229e6f", +# "hash": "ec124f6ee44393c74b9be5dfa26426818c60010aa964d4d0b3238fae1b229e6f", +# "depends": [ +# 39 +# ], +# "fee": 1000, +# "sigops": 4, +# "weight": 1012 +# }, +# { +# "data": "01000000025f9c4842cf2566c1318982f0629c8bd55e67ad96138df9c7d62be8b20ea2dd0a01000000fc0047304402206280789760de064f76974b8a1143e26bfa11e84459cb60507018f5eebdb319a802203efe872d9b869d2ef4a8e598a714d6681b6a839fcfe2f35b92abc8491f8f90e901473044022028d0b2f3b1d878ec67ee0480d38eb85eb3a9f6e0d43f3f4dd56a3cab3de01e9802206f7e03da0d94a104693f3359049d953f4b778ae1fec432d898e6a2b0b2b0da3b014c69522102ca37b73048d3ba3a0e67229efc7e6b236bd0706c3bb291d13a8d0f61cef044fd2103b572ee1331b5b66d68dca39ec5d8b65e50c271598bb8b8f098926b0437fe636c2103e45681e0f194688977189a780c40b366733a2990b83eedf27d8750ebbcc50d9253aeffffffff6703c4bdb92e4c60d28cc6fceedf6ec8c6bbf9a572f074824a5572ce70d8fc3500000000fdfd000047304402200fc00d2316afeb42cb5419bdb12c7aad2cb9e3960f5c7a476b5a55968e32cbd102204599d9ed36b6fa0cc40e03ebb97fa736df19f04414b8b948c83d8fc038645b7b0148304502210098879ceb526efb641356f2cdc49a736628909cfdc1a06c52eae05592515154c802200664eb6ca4b2f2533ef03bf84b6f392b562a49c1f6f9ac30b38b4de691d3c124014c695221029462cfdefa0f1a790c2bcc6a8e0201ab663be0e65d92c71f5e04727fd0bb2ab42102177373a3da72987fe3e39fe800ba1d2dbeb7d6fcd404db051329cbba28ecbbf82102478a976eef94fba38c86da8dca474593a9149ee9d08b7550e751df8c1509b52e53aeffffffff02a08601000000000017a914b78eaa6e1b0d4510dfc78bece72f3a517e0a162687e92f01000000000017a9148467ccafba030f5dc81501ba62ff9090069c4c2e8700000000", +# "txid": "ab48a745e7e597c0c7463b4d0867a99357d8788bcef90b37fd66d3a709ec0afd", +# "hash": "ab48a745e7e597c0c7463b4d0867a99357d8788bcef90b37fd66d3a709ec0afd", +# "depends": [ +# ], +# "fee": 2004, +# "sigops": 24, +# "weight": 2652 +# }, +# { +# "data": "010000000fbf461822c694155e15eb0b34850ac6d3d4afee3ca2c27241e98bedfb529e88d700000000fdfd000048304502210095b77581343bc2bb6a26d2b839ffba5de10969e7cd91375ef22e116f100bda6702201f06d3c5d7b243112978fa5355787559c53881f66468bfa5d9d8619298ef973b0147304402206dbcc05a9e4fe6cd15b050b22ee65d310d3c0535754d539d64a0b589d515a58b022053be658a680980976758a86868a7e7bcc8870d3ed39930da0e2cb38b5299e59d014c695221031c77da1de3f4b132e0df0c03863b9bc3cab4aa28b457485a899aa7dc62d22df92103719ebc1f0f5a09defc0172a0fe1dee077a8cce46520fbaed90445ee5a1400546210335129338d5fd8107d926c52b5e3ff26a6c2090112d350d188bf80fdda224744053aefffffffffb842f072cabe790474829ef214450239c4d57e779f560a46a0a99fe10ce506b00000000fdfe00004830450221008cdcece9945c8151fdcbd9175fbd33770b5f4adfa762f5892bfb53f50442b76102204550eef544a4b76470a020b1a6ae0adf5fd4761f14191683da220fab06b8cade01483045022100ac10077fae3c55c2f78cd7655530351f9ea6fcb3d9a6e0af30346248515c257402206bc699a139e3b6d3a3e533bd043f7fede68aecc6380a3504e0a2de94ec3e58ab014c695221031c77da1de3f4b132e0df0c03863b9bc3cab4aa28b457485a899aa7dc62d22df92103719ebc1f0f5a09defc0172a0fe1dee077a8cce46520fbaed90445ee5a1400546210335129338d5fd8107d926c52b5e3ff26a6c2090112d350d188bf80fdda224744053aeffffffffe8538ccefb8bcebfa2356ad71bdfd6aeb3beec0644c719b33a116beb7237387900000000fdfd00004730440220745d65eef8296482a16d0eabcf61c9f836fdaa619bccf8c4c38ba79263fc4eac02203625e929291f5a1a9bcc38afd07913ad6847491a834aefd2a8f14bf3c667536f01483045022100fe0de6ae3ea7974ff56a45b051ee2d1192b25f01454a1cef2d03973768e939ee02206623599365db6954759ca293ee66e56e6bd40fc0d8ba6cf1a3519c8a0e9d2147014c6952210392a20a34c09de12183fd362382ac00ac68674e52b3ad22ada2c628ccf828974a21021f939d9ff2062e824dc0399cbb934ee7e953f646a6744f3554c6e0b411fbc6fd21036d8536588ca168953652be21624b8961cf9c866f12f5f7d27e2b078476a9c50453aefffffffff0885359ddd67999c3acdb24d5c55369a3c1fbedefcf671e2a756a1a87a4645000000000fdfd0000483045022100d0112a4a3651c1c904f8c774f33d89cda81a5b77c538382f45a1d0d82cae8c36022021e120aa30eec758157a5da9d7ba4db1f70ce930962c1e35052cdf371c6671d1014730440220541ee6f854f17916c3936215391c824927ea4a58380d2ce983605cf6477cf84b02204da59477e06c546523afbf38803494e522d79bbeceba7a6a2c4904095dcbb750014c6952210392a20a34c09de12183fd362382ac00ac68674e52b3ad22ada2c628ccf828974a21021f939d9ff2062e824dc0399cbb934ee7e953f646a6744f3554c6e0b411fbc6fd21036d8536588ca168953652be21624b8961cf9c866f12f5f7d27e2b078476a9c50453aeffffffff454b2ea24fc2f5349c6e339b69dea48b636bb245eb1f21c8924b866d235faf2500000000fdfd0000483045022100e5ca6278ec0dbb81c586194455a728f0a828c521f1d6731cbf9ce8004b4ba1b8022055b6bea7203ef6b779654c9665e7ed9d8219b726aae0fb5e451c2e3a6976a1650147304402206558618b82356d5e67e06ea021070f9f17bb246c3638cf70d1b04fb3d1c0e703022019ea28dface31891e2f8460c62995ec1cb286902314562a4dbb933f15a17b03c014c6952210392a20a34c09de12183fd362382ac00ac68674e52b3ad22ada2c628ccf828974a21021f939d9ff2062e824dc0399cbb934ee7e953f646a6744f3554c6e0b411fbc6fd21036d8536588ca168953652be21624b8961cf9c866f12f5f7d27e2b078476a9c50453aeffffffff29e231abe5de183c7bb6411ece2e319e25521dfa2eab588b7de4d470df23228600000000fdfd000047304402200e5ac774e14a0afc43e439a872a1de8bb1ad8ca642d1f576e29904d0c82719cb022026e67abdd088a93357d6d9f66d3631faac348357b3e85f05c785ea9516ee5c9a01483045022100d286f57d3df09c1daf56e70e682432e7e4e760ac463db83655b8a34f84ce7d64022077516d35860de729aa5b30727993b62feb50f5b40aedb8dd729200f68df77e43014c695221031c77da1de3f4b132e0df0c03863b9bc3cab4aa28b457485a899aa7dc62d22df92103719ebc1f0f5a09defc0172a0fe1dee077a8cce46520fbaed90445ee5a1400546210335129338d5fd8107d926c52b5e3ff26a6c2090112d350d188bf80fdda224744053aeffffffff06b599e09533278ece0327d1f4648d2269cb2a2aa954f392c86c0aeeb1f294f600000000fc004730440220572963bcc5cd3c5caa78db6d74bf8f6133627cdbc5e69a0d001a0b76b54a999202201cb81ab2c4f44de18f89daeabdb6584a2e1e992aa908151fa59f6896b214ba3601473044022052f4dfb4826d55573c56a71a2aad9ab27b0a2aae7c7eedbb95bef2157c6e495202203b9e550e8e6d105cc0e8068a69285b804cbfa48230c4048570248b3d9ef9955f014c69522103b84f377cca926d3c89985d315cd18ea9eaf2a4c048683c451ae7dee602dfc9c421039a0ebbfee26f5d9000433decfe9c0782252cf040bf943df7425d0c78279626f12102d15fcd1c4ba666faddc3e8ff66c6d7488ebcfb7b78152b8e2d720c126a93fa8553aeffffffff52e94bf46c447ae90cfb1a6cd655da735b8188a061a9f268cd669f84bd70eed100000000fdfe0000483045022100cf8f1055a8569ed808275f54d939302c181058f5b09a82df1a5aa3bd12645c2302203a96ea55efc15ed88dd29d03305cc70c6b363c4b021153b8c30de26decb82a0e01483045022100af6dcf6ac30535e4813b030296863e90379c3c96c9b3ffafe777a63b8c072d79022016e1ce4c145997eaa6f562fbc8adf7d929860d60fb93341af94f9d822dbdbd18014c69522103265bed6916ce219ae538cfb856a748b82f08b0712c17b8b71b6c7d6007d6a1142103cf07caa252dc650c6fd3910b57ba76f59d5f416e983f7eae879b2dc2614d0f3d21037de000ddc0d11a95096c19463b39b5ad7bb6f2d596ed145557cd2855a07ce7d553aeffffffffd128a9376845d02d21e09869d3773aa0daa5b79c128b71fdd277318e4910851b00000000fc00473044022060548ec787cd70a6f0da6137e73c30d905643a76808c1ab6781c7e0befe52ebf02202d5ace3ceffb283adcb9d014031bd8343f2f4e8cc71145412088c9f4ff5538ba0147304402203fc1430e4021d6df39abe20b5436eee1dad65b6465989e216a7854712878289d022018e13c566be5bebda8f5b7c7529e3cbd3a512f1e18c672f2da5eedf2598ead16014c69522102621561b76b5b4f9c43db125f7690c1356b6c6efb0fb30a3f16ad86ad09b8f9132102100e11cd5dbcc03aa68e8ffcba48f9bffccd8e900875f6d18feb083a069bd04b2103110c07d3a19217bf269b1adad11a4378249b23ee98b41d0be5493981eb97cfe953aeffffffff070cc97726438b05950b00b3b1b92bfe9476547c2e0dc25c56724a7c9b26948800000000fdfe0000483045022100c919c56fff3dceb668cb993258334f2b9f9f409e396046c8b058cce726a66789022052c21d767b841b975fb96419954b4a6a7d68b929a5f1ae52eb219d587ba5d61d01483045022100dd16e0c008214aa932b310574ff4c6557512132ac937e500c96df8c527e95e4d02205213987c05839591c059c6677b5b759c8c04124d68446f5cd7e76cf34e794fdc014c69522102a710bf2071ea6305019b648ad3c1526ec9dc70d9eb4071fc8280cb4599e24eb5210251a803f5041d81d7fbaa0bcba26d50ab2d317869cf1db02d1014b7ce8a4784052103e697567f801247b9bb2d8134a1cfa75a0be947d284c219dad459f9c80b1ab15053aeffffffff59aac04cc3e1d0341179f8d44d7096012b47544edfc74be2da677badbc33878f00000000fdfd000047304402207641b3337dace48780bd4c5f93abe147387f52f1ed41c27d938d68610273ab120220731a9ab18370b9772a05b8b0e8decc29e014f9a6359a524fc8d25b1541f25ea7014830450221008a229b00458d4c6b58063e103a0ff23d836a18465d20f01dc1619679db86e83e02202367a877bb1f08db2caf73b326c2f2517affaaf994250c2159796bc425c80934014c69522103bca27e6c4a494e78d33c1e9b1d2b110343cf8c4382641783884f8aa044e1a88a2103aca4f1521ca97a31acff4e175cd4391437a97ec134f71e6619a1939bdbdf5c1f21020395d8352ac32071a72a938a716b5db3430acb31754fe1505ea743c167323fd953aeffffffff4691640af01f30047b85feeec19fc84979b1c5f964f4b9c6d7d088c5e8a271b500000000fdfd0000483045022100cba6a49a40c43dce9e925b3eefbf3dbb44136fa838d5df342b1f9d41dfb9a27b022058655dc169dc85b0bafea5757eaa46c96a788aa35dc80ba9dbe157a9923e57fe0147304402201d2c4ee33ed565642e40ba8d60b998aa42263d043b6dfd2b3dc57155600165dc02204512f8846e46226b202ef19c02787aaf606be129cbeb898b8061fb07c437cc11014c69522103bca27e6c4a494e78d33c1e9b1d2b110343cf8c4382641783884f8aa044e1a88a2103aca4f1521ca97a31acff4e175cd4391437a97ec134f71e6619a1939bdbdf5c1f21020395d8352ac32071a72a938a716b5db3430acb31754fe1505ea743c167323fd953aeffffffff66918fa1add8cce9c137437f4c288bf8231ff7fdb6b9ba5c405eddfac77f22d900000000fdfd00004830450221009202ecc40371c23bd5dd79408f1651195e0b0c0df7897476e35c31a0108bdabd02203354f99126d5c4e864b55976971aff102d44edfd192b95a16dcfe70c3c1fbca2014730440220100d824012bee769d2df3415dfe7075f273fbd393cce7ae38681ce93d3736aa70220132d6adcf50d3f6151a5e63b59939857532ee24c1879f82f52ebe63852ddccb5014c69522103bca27e6c4a494e78d33c1e9b1d2b110343cf8c4382641783884f8aa044e1a88a2103aca4f1521ca97a31acff4e175cd4391437a97ec134f71e6619a1939bdbdf5c1f21020395d8352ac32071a72a938a716b5db3430acb31754fe1505ea743c167323fd953aeffffffff7c9f7d1b1e820636d02737f260f7502b3b0fd88b6ddeba16e6454bc497818e8000000000fdfd0000483045022100c06309fa75a8e0abd09a040aa7b65be37b9b940dd7da74f044756489edadf19b02202597594434954566df6179b051043b85fc11f6c146aa994af66bfd31be8f96ec014730440220521e7ab156bc1aa168af1b82c70d0cc87b600803fc804cf3e3ecb20e371c300402207164d85965371f3fa9ccb8ab424f383d0bd40a48f046d58fb393b3b2872cdc06014c69522103bca27e6c4a494e78d33c1e9b1d2b110343cf8c4382641783884f8aa044e1a88a2103aca4f1521ca97a31acff4e175cd4391437a97ec134f71e6619a1939bdbdf5c1f21020395d8352ac32071a72a938a716b5db3430acb31754fe1505ea743c167323fd953aeffffffff4451b971b036c234cf6e0443c6e9f7692029b4505f12ba187488bc14a4557b6500000000fc0047304402207c38036acdfe696537207db298652b26a20ec0eeb99fa22b5617692e05d192e3022020c5de88edb695bb05dd4c3d82d8fb2e5029c4783081d8580e5b903b769ac7850147304402200611a80cac8e569c924557d483686365d4c30766072f30b5576fae17cc56f12202202e2e527ae10a948c749e7d19099757dbe8c48c2ab3e1e4a93c331a372f7f4f42014c695221028343c536f471a4fed69ab2947a73ca1550ef582f89cf189b6efa6e41d9c4e949210360a00ca3e2d1d6a7f31c7d028e21bb00410666680339443cf71acf326e5080152102524ae841722d1b7d4d3342b3bc31d23059a7f780ed20e87d6da5ff7d7331683853aeffffffff01fa9f1c0d0000000017a914a9974100aeee974a20cda9a2f545704a0ab54fdc8700000000", +# "txid": "5b7ede913eedfe8d365ddc50f5f5313a3b8bd45e5beb3cbd98237569e901056b", +# "hash": "5b7ede913eedfe8d365ddc50f5f5313a3b8bd45e5beb3cbd98237569e901056b", +# "depends": [ +# ], +# "fee": 13509, +# "sigops": 180, +# "weight": 17904 +# }, +# { +# "data": "0100000002f7b06000fd0336c892f6bfd949d621276fe5eae00521e6e940a2bf4148d8085800000000fc004730440220562dee7f14a7aa5f46745d41243cdbaa30d1cf29a8707efa279be3551505736602203481f9fdf38fc01cce922c1cf070caa2915a1966583db7059ca0b041fca633ea01473044022019022362bd96ca5f769419a2f0958649ede599fe1946bcfbdb1b193ceb9464f6022076fa7ce7a9679f3ff7dfe6b61b626717e0bd202e085e42a1411ec8aeffc58e00014c69522103e6652b1082ff638872453a90b19b673a0b8e33f6e87b589ae97743e7da20fa572102061fd01a8e0f411b02023441e1499d9712f9e92fd363f93eed29600e9b8a1ba42103f14c7b86ee3f7a130a28c16953b719a558c8f6c67e23ab96739ea384ecbe7bea53aeffffffff9876d47aa59178030ac4218f3acea3a543727375604ebd5e655b69f3a1097f9b00000000fdfe0000483045022100c9cbd3e86b48f38a90cf248dc35d84e57cf94ff222eb0116b9eb028139979fef02200aeb7d23c8b1c7c6a349bfe1a33bf661045c91b763aa9ddf0ebbcb9cc2100eda01483045022100823cb1b88b27fa406a4fc1a8b9a5f688fbcb0ba43f5818c73476dddeec7a318502206d4df7146923f303a89c1be3118603dfc8fdc3512b080f00624ec51bd365d9f8014c695221029462cfdefa0f1a790c2bcc6a8e0201ab663be0e65d92c71f5e04727fd0bb2ab42102177373a3da72987fe3e39fe800ba1d2dbeb7d6fcd404db051329cbba28ecbbf82102478a976eef94fba38c86da8dca474593a9149ee9d08b7550e751df8c1509b52e53aeffffffff02e92f01000000000017a914a3b3b77175dc3127777ac32f2f0b0081b7a6dda387a08601000000000017a914b78eaa6e1b0d4510dfc78bece72f3a517e0a16268700000000", +# "txid": "54dda7ffcf9b6a0f100b5a4911b66f47605d425552e22cc5fe354b7a559b7e62", +# "hash": "54dda7ffcf9b6a0f100b5a4911b66f47605d425552e22cc5fe354b7a559b7e62", +# "depends": [ +# ], +# "fee": 2004, +# "sigops": 24, +# "weight": 2656 +# }, +# { +# "data": "0100000002dcdc1ce34e62eedf01ddc0fcd0933a79c10488973f6dd99b2be3270ed171c03400000000fdfd00004730440220241d27f52ca3e83c7b28680fccfd2217b6d20dd2770dc78d33ac4ddb154f3f150220264024407a4c2079c25e58ef91f2a5d686a95bd6d1d66470637b45013ef7f17601483045022100f9949bcaefb3d1396b44f6e9ad92ab92e31b7ba1c3783ad989521f235907214002200d3467ee2d69963992ed2bed827476b7e18fc95668b158827721a702fc0f7a8e014c69522102cfadd42b716069884e333d344c0332184b84d3e7a836c9edd4f1e122dc7acd9e2103c8c939344dc786f81bfcce775df2297973f044521f0759be8c302dc051de171e210398cba8ace481e1aaaedeb525026f6ba234cc8a7af35d2694fdc34614099ed3d653aeffffffff0a233dc87198f7f93e27339320b0f86fb4e0aa863f7cd15426708f04f50e853900000000fdfd00004730440220496f062b953b72db71ee7f22e79a5ae5ebdf1cef0c433e30d6b78fe508000a06022071f3522fee5f7310258d2b13a8c1df5f431a1a10fd16e9d228fe7e41d9c7ce2d01483045022100b56930919fcd06fb74e503e02473a45ffccd1c148102892a2c61884ff97ebb8302205ef0a92497b3e4c7df26f222ff972a2458be58d4a6971933c1b49a6a918702b7014c695221029462cfdefa0f1a790c2bcc6a8e0201ab663be0e65d92c71f5e04727fd0bb2ab42102177373a3da72987fe3e39fe800ba1d2dbeb7d6fcd404db051329cbba28ecbbf82102478a976eef94fba38c86da8dca474593a9149ee9d08b7550e751df8c1509b52e53aeffffffff02e92f01000000000017a91446b939d49d6010e274d3d11f4d586d53bbf2eb8b87a08601000000000017a914b78eaa6e1b0d4510dfc78bece72f3a517e0a16268700000000", +# "txid": "3532f27421afe25db0ab9ae1ec7ebbc048ee5ebd81a7ed36da70bb44d7585fc4", +# "hash": "3532f27421afe25db0ab9ae1ec7ebbc048ee5ebd81a7ed36da70bb44d7585fc4", +# "depends": [ +# ], +# "fee": 2004, +# "sigops": 24, +# "weight": 2664 +# }, +# { +# "data": "01000000027bd49fe5ae5006930c7142ee822d62531e702d40628d3fb608d2acafe95e50c501000000fdfe00004830450221008bdc48e2c56e43a99e4e77a934629ccd518b3cf547aacd6f433e6795b2a062260220683ff581f348a42e3112abccc793b2b51a90d09f87af16d885af1f24c35f90820148304502210089534ad07704188722eb3005782a77d8628134be3575e02a5749f886ccf17d20022018ee18fec60b1dfc34fc7dccca88f550a74c79f48759cf761b2cb81daeaf9156014c695221020c389b2ca27811467764990cea19811f967cb7726ede896de86efb661b2cd44f210209ac1a9d8c56a46b25bd5023078ed77fb87845248a6359717c0eaf5059d26fea210291f50e312e02c02e55d0b9ddb8383cd09861df0ac4618dc0e3793e0b21cca13653aeffffffffaa8fab8147cfe9b943724ffb5b1a1869ec6f5bf355c1087410bf7d3cab642b5101000000fdfe0000483045022100be1ca6660bf70b5b04e1f32ae29c12e821567f110ece92bb85441daffbbbea8702207fe79cfe298d1a751724455ef9bf7e9fe006b79a7deb618888669fa676e08d1901483045022100881abfed3d66be0084b04c96fffa47ee6dcc1b2542e195742bd464c30653dbc8022003d13fd8e9376b0f1e4630663ce2bb2aa23cba61ba46b2a79614499a5c0b0978014c695221029462cfdefa0f1a790c2bcc6a8e0201ab663be0e65d92c71f5e04727fd0bb2ab42102177373a3da72987fe3e39fe800ba1d2dbeb7d6fcd404db051329cbba28ecbbf82102478a976eef94fba38c86da8dca474593a9149ee9d08b7550e751df8c1509b52e53aeffffffff02a08601000000000017a914b78eaa6e1b0d4510dfc78bece72f3a517e0a162687d55101000000000017a9142a05ceca707b2a7cc208005374271196885eace08700000000", +# "txid": "9f7db5106fabd89e59a9f896f5f5c6d1e3db5821d3ccd160937cb3ac71a3ddb2", +# "hash": "9f7db5106fabd89e59a9f896f5f5c6d1e3db5821d3ccd160937cb3ac71a3ddb2", +# "depends": [ +# ], +# "fee": 2004, +# "sigops": 24, +# "weight": 2672 +# }, +# { +# "data": "020000000135d8552c7d7fad924c6bd8b9b86fa98e0ab547c54f32be74f5a12ae264660629000000006b483045022100b46a60f57e917b619da2888bd49bbeef3f487972149887292a2fffda717a81380220319b7cad0d873ac59452959d17719cd3061263b1970e9cac374b113355d41edb012102c57b26b4b3ee0e9ff245d8b41f218001ab7fcb5d60e796ae68692f0386057791feffffff03e0723603000000001976a914d46a447e07f4711b85c15a7dd2be823588a6afa888ac9d850100000000001976a914a317bdecc0d3423c023d6af06f6d14e3a82cf87088acbdd30100000000001976a9143a883183c8bb41b67ba65fcfdb6def025c1f510288ac218a1300", +# "txid": "77c170a321bc551ed34e75c3e58fa03f12ef9dc754c9ecf5cf7a33623272322c", +# "hash": "77c170a321bc551ed34e75c3e58fa03f12ef9dc754c9ecf5cf7a33623272322c", +# "depends": [ +# ], +# "fee": 518, +# "sigops": 12, +# "weight": 1040 +# }, +# { +# "data": "0200000001154666678b3ff44110b472f4276599f3b90c4bbd71c070b05ca4516edbf3bdad000000006b483045022100dc17329b2b5f31c3f2a6adc4fccbf89e5a3340bfd824daca5ad61d4155314820022070568fee8dcf04b283ad2df1ba5ac1af9c2c39d20a41667e88143ebd49c18595012103667ae71dcc019583b88d307b4da7279860e7965955309a120844a0e78e7c1969feffffff03e076dc03000000001976a91471fe18427d3d850f0d542324047334eb1d5e60a288ac9d850100000000001976a914a9449e46dcca187f210e5933323d5ff5fe71a96b88acbdd30100000000001976a9146ad0fc92fdc6a599f4a4ad0dd27b36f6f98707f688ac218a1300", +# "txid": "dde6a0b677dd051ef4039d9ed26959dbcbd2fa7837e4f71d895f069fea887f65", +# "hash": "dde6a0b677dd051ef4039d9ed26959dbcbd2fa7837e4f71d895f069fea887f65", +# "depends": [ +# ], +# "fee": 518, +# "sigops": 12, +# "weight": 1040 +# }, +# { +# "data": "0200000001127cd7f81d56e3c1d33bc4c1e26a905a75f45ce3df0b37579f72e28da1f553c1020000006b4830450221009fd055980d2a963cb7b65fd8cb18eb964ea51c50372fc9f19e776e7de7d0b4d1022042a1027a2e534a1122a40a0037ed5e83b648731912929f52dd42064b7754366201210295eb27c319e1e8352818f10f59870f69c9f5ebd725c584cd2fa398a077fee110feffffff039d850100000000001976a914fb78d4cec69c038c2b498386fbaf3beee5a495ed88aca0500401000000001976a914ca722ee4eab5cdf295a62ba5b7a5d63fcdf3f9e088acbdd30100000000001976a914c21597182ff31f88bcd6c6165fa540d90048ffc188ac218a1300", +# "txid": "834b8f1af6f80733a8c5cc0b40815f369dcdbcb9f10b77c0ff14311f39b8edcd", +# "hash": "834b8f1af6f80733a8c5cc0b40815f369dcdbcb9f10b77c0ff14311f39b8edcd", +# "depends": [ +# ], +# "fee": 518, +# "sigops": 12, +# "weight": 1040 +# }, +# { +# "data": "0200000001ffe238f441a121162501b77485d4231930b94bf307c569473b6d1ce784ff124d010000006b483045022100f6d85bb5e215dba891f4570d7f10abdc9140918063641c7f4934f1b05225ac790220154ef58b860dcbfa01624065aa68cd51fdd4c71a0d3ae2b6275a455f1043bba901210241bc0cbaed50af10d8bdc80181f1affdc03a4a7a6b14e980227056b202c8136cfeffffff039d850100000000001976a914e52789ac907f9d4935eaf572f86db422864806f388acbdd30100000000001976a914215cf46ecd67abd925ce0989b26f7544beedfd2888ac82428404000000001976a914f80d74fee3c3d4a7fcbf9f4080fc90fc0bb8657a88ac218a1300", +# "txid": "dfe4dad848b41b7fa5fba396d68f3434ed49788ef85dbe36f195e9b804b2ecd6", +# "hash": "dfe4dad848b41b7fa5fba396d68f3434ed49788ef85dbe36f195e9b804b2ecd6", +# "depends": [ +# ], +# "fee": 518, +# "sigops": 12, +# "weight": 1040 +# }, +# { +# "data": "0100000001913e404e169428df65e1ac54fa001e60b3071a522d9eaf725b1bdfb957f5d12d00000000fd680100483045022100aed51a530084a7e3e29856fbd95540964eb08d4cc04a7273104ed9c77c8a39f702206e54b92d0f0d15e4190ecc2e6b357e04a6ea0b702f91cc9c76b17a68665195fb0147304402202a8dc1829e35aca47dbe1db1ffbc5e7a93812a016ab69ee80d34d4e269a360d4022033a83adef0c6ad8627cecca2cd09f4bda7e66c59770f965be4988e47a955c7f301483045022100c3082de7199e8b9c84c426a07cbfc6bd0534473aca718811de7c5f8572a8fdea02201d2bb9409f1734ffdd36d7a08ddec6cc212916f2c136e686d33b2cb486d6f141014c8b5321026623c05897d7992801d6c9e0dd8b606d4adddad50222dee6104c6de0c3d6413921033cd669b1958acf253f27c772773068dd42707aab9d1bbb30b1f970f222a989f8210310c8d0297e9b5d9ec2ec2d5cd78ae56b3292a8390673f23eb50e6ab6cbaf248021030d1609be5798176a46297d6202054b4bcd53bf07d5c30d295903ea91558ad6a354aeffffffff0288af0a770000000017a91415997c1f6fbd09b23ca2e79f4ed2e8b4458a1fe3870000000000000000326a3045584f4e554d01005876d60000000000da1f151dff11efba29d58df6642ea1a34c6f333ebec5ee417b90ea48c6ef541900000000", +# "txid": "992012004f12fa3cbf536d139b78a8e094a535d58d53650c641cc0bff1ed1c2a", +# "hash": "992012004f12fa3cbf536d139b78a8e094a535d58d53650c641cc0bff1ed1c2a", +# "depends": [ +# ], +# "fee": 1000, +# "sigops": 16, +# "weight": 2016 +# }, +# { +# "data": "01000000017b7633162cb73e9afd473b958234d6c06926d3c8456fe29d9e05e803b76c089700000000fd680100483045022100aaa6ed4219730ad83c835a5f7aded14cb67128895bbd10c913dff4e95a34fb8002202ad868ea4fb12bb2152b721e2efff453ffcba2e85abdf108f706c9f96b11040401483045022100948db14c57de90ab7f5831e9f31945ddb3b08986318e2238be4b37be4dd25cc00220127bb8680241b7a797db67db2c090a86d5aa6af135d6712c5287530a0092d0f8014730440220693c2d5a2a10cdc18216942d25ceebd1f8a005a9deaad6d584585ff7bf53a4190220728060b5abbc1d4ae1c84d5dbfac8030026687bd157298a0848176c3e1840792014c8b532102949dcb6f05bc5b1fb8855aa0cbbd883edc70b1785a492bf1fa0c0287a8befc3321023193f287b227fb572f63d11aaa03a05fafc47f29caa5f8bb350359bc24191cee2103cd4aa05c4952acf1c29185df960e68787ac59aa30d6e748ff833522e4d11c8e3210221b476c94496bef7c4ace3af3e9c7bc805587f67870c425cafc6dc4a7bafe74754aeffffffff0200290e000000000017a914b68c3488d295902dd465b486cc51be2d29af2408870000000000000000326a3045584f4e554d0100b86a05000000000066d7024aa1924f74d90c71421d428fe24da8e194b52da1ae2d6df582523711ff00000000", +# "txid": "0f5dd231f62ded09b135ae3acdc14341afa24d7acae5bec30a0a6995aaadbc44", +# "hash": "0f5dd231f62ded09b135ae3acdc14341afa24d7acae5bec30a0a6995aaadbc44", +# "depends": [ +# ], +# "fee": 1000, +# "sigops": 16, +# "weight": 2016 +# }, +# { +# "data": "01000000016e01155212f111e44c88c1dfa1043e5b49f483f4e2838d6b4c3e8aae5ee2615900000000fd680100483045022100c94d493ab5ab23b87beba84ed6eb8154e193793fa248ff5e69034204de977444022076c40a6635535986efb065a9b9d8ddc715a8c83bb5fcf3e989323f1c2dabf58501483045022100de9d93fcf5f03b68dd261552bc47fc26071a9eeaea9b5e3fdff7d801c7faa914022079649d4ab3cc58d2ae4249a3a446039e7fc31719ffd8484e0c759c7281c62c710147304402204b7be291918aa913cd7a7a02185b8a1d09b55872ad48cb60789c24a7644764f8022053c8848b99a5b7b34f1773df54fd90bd4a5f3608864e360c921f86ea8f818e5f014c8b5321028861613180bf9b975a92848a3481f69e0526773ec67a3fa74e050afabdd69f7621026423a45e3fafd2d558e9bc28cded5534b31fd10a890ba3314e1ac35efdf0360e21031e40f1faa6dc9e89747c9eb89ce83c15263bdaf705e2d67c162adedad8ca6a0321022f7437bfc3f0009d8802b9e57a34a2515032132dd479b9992a9de09570fb88f854aeffffffff0288b90e000000000017a9144113ab6d74a100be6ff45daf3877cc536a6c9b6e870000000000000000326a3045584f4e554d010098ab0200000000000e6c5fd922fbe68a8d1f5514103c1341f14f40f4efb03237dd9453072eec990500000000", +# "txid": "1d42486a96c75d7672a2345f9c0faeecbdda3f25432887626d480ac478c6df5f", +# "hash": "1d42486a96c75d7672a2345f9c0faeecbdda3f25432887626d480ac478c6df5f", +# "depends": [ +# ], +# "fee": 1000, +# "sigops": 16, +# "weight": 2016 +# } +# ], +# "coinbaseaux": { +# "flags": "" +# }, +# "coinbasevalue": 80419215, +# "longpollid": "000000000000289f2c0ddd382204f00a074f3dc45ee67dd24931c332769678a250446", +# "target": "000000000000372b400000000000000000000000000000000000000000000000", +# "mintime": 1518195745, +# "mutable": [ +# "time", +# "transactions", +# "prevblock" +# ], +# "noncerange": "00000000ffffffff", +# "sigoplimit": 80000, +# "sizelimit": 4000000, +# "weightlimit": 4000000, +# "curtime": 1518198947, +# "bits": "1a372b40", +# "height": 1280546 +# } +# + + +class BlockDeserializeTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("\nTesting Block class deserialization:\n") + + def test_block_class(self): + block_c = "2000000000000000000029a1a0390376afd72db120d698c2d8ebc41c545c7d4bc2b9033c303dd3d09d455da1c587406820a4dd77c5aa3fcc546dcceb1becc639829c4fe6535e815a1a372b405cc0829701010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2303f88e130068747470733a5c6170692e6269746170732e636f6d20f251bec0cb000000ffffffff02c817a804000000001976a914d4e49947b9f545218cd20389244c249d3520545d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000" + block_e = "2000000000000000000029a1a0390376afd72db120d698c2d8ebc41c545c7d4bc2b9033c303dd3d09d455da1c587406820a4dd77c5aa3fcc546dcceb1becc639829c4fe65a815e531a372b405cc0829701010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2303f88e130068747470733a5c6170692e6269746170732e636f6d20f251bec0cb000000ffffffff02c817a804000000001976a914d4e49947b9f545218cd20389244c249d3520545d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000" + l = Block(block_a, format="decoded") + f = open('./pybtc/test/raw_block.txt') + fc = f.readline() + qt = time.time() + bt = Block(fc[:-1], format="decoded") + print("decoded block", time.time() - qt ) + + import cProfile + + cProfile.run("import pybtc;" + "f = open('./pybtc/test/raw_block.txt');" + "fc = f.readline();" + "pybtc.Block(fc[:-1], format='decoded')") + cProfile.run("import pybtc;" + "f = open('./pybtc/test/raw_block.txt');" + "fc = f.readline();" + "pybtc.Block(fc[:-1], format='raw')") + # print(">>>",block.bits) + # print(">>>",block.hash) + # print(">>>",block.timestamp) + # target = int.from_bytes(block.bits[1:], 'big') * (2 ** (8 * (block.bits[0] - 3))) + # print(int.from_bytes(block.hash, 'big') OP_EQUALVERIFY OP_CHECKSIG") + self.assertEqual(s.op_sig_count, 1) + + def test_p2sh(self): + print("Deserialize P2SH") + s = blockchain.Script("a91469f37572ab1b69f304f987b119e2450e0b71bf5c87") + self.assertEqual(s.type, "P2SH") + self.assertEqual(s.ntype, 1) + self.assertEqual(s.asm, "OP_HASH160 69f37572ab1b69f304f987b119e2450e0b71bf5c OP_EQUAL") + self.assertEqual(s.address[0], address_to_hash("3BMEXVsYyfKB5h3m53XRSFHkqi1zPwsvcK")) + self.assertEqual(s.pattern, "OP_HASH160 <20> OP_EQUAL") + self.assertEqual(s.op_sig_count, 0) + + def test_null_data(self): + print("Deserialize NULL_DATA") + # 20 bytes valid + s = blockchain.Script("6a144279b52d6ee8393a9a755e8c6f633b5dd034bd67") + self.assertEqual(s.type, "NULL_DATA") + self.assertEqual(s.ntype, 3) + self.assertEqual(s.asm, "OP_RETURN 4279b52d6ee8393a9a755e8c6f633b5dd034bd67") + self.assertEqual(len(s.address), 0) + self.assertEqual(s.pattern, "OP_RETURN <20>") + self.assertEqual(s.op_sig_count, 0) + # 81 bytes invalid + s = blockchain.Script("6a4c51000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000") + self.assertEqual(s.asm, "OP_RETURN 000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000") + self.assertEqual(s.pattern, "OP_RETURN <81>") + self.assertEqual(len(s.address), 0) + self.assertEqual(s.op_sig_count, 0) + self.assertEqual(s.type, "NON_STANDARD") + self.assertEqual(s.ntype, 7) + + def test_multisig(self): + print("Deserialize MULTISIG") + # 15 from 15 + s = blockchain.Script("5f210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c" + "715fae") + self.assertEqual(s.pattern, "OP_15 <33> <33> <33> <33> <33> <33> <33> <33> <33> <33> <33> <33> " + "<33> <33> <33> OP_15 OP_CHECKMULTISIG") + self.assertEqual(s.type, "MULTISIG") + self.assertEqual(s.ntype, 4) + self.assertEqual(s.asm, "OP_15 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab" + "35c71 OP_15 OP_CHECKMULTISIG") + self.assertEqual(len(s.address), 15) + self.assertEqual(s.op_sig_count, 15) + + # 1 from 3 + s = blockchain.Script("512102953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213623" + "441048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf" + "410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b042060" + "466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcdffb6a97" + "40de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e3953ae") + self.assertEqual(s.pattern, "OP_1 <33> <65> <66> OP_3 OP_CHECKMULTISIG") + self.assertEqual(s.type, "MULTISIG") + self.assertEqual(s.ntype, 4) + self.assertEqual(s.asm, "OP_1 02953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213" + "6234 048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd79" + "5bbf410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b" + "0 060466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcd" + "ffb6a9740de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e39" + " OP_3 OP_CHECKMULTISIG") + self.assertEqual(len(s.address), 3) + self.assertEqual(s.op_sig_count, 3) + + def test_segwit_p2wpkh(self): + print("Deserialize segwit P2WPKH") + s = blockchain.Script("00144160bb1870159a08724557f75c7bb665a3a132e0") + self.assertEqual(s.type, "P2WPKH") + self.assertEqual(s.ntype, 5) + self.assertEqual(s.asm, "OP_0 4160bb1870159a08724557f75c7bb665a3a132e0") + self.assertEqual(s.address[0], unhexlify("4160bb1870159a08724557f75c7bb665a3a132e0")) + self.assertEqual(s.pattern, "OP_0 <20>") + self.assertEqual(s.op_sig_count, 1) + s = blockchain.Script("00144160bb1870159a08724557f75c7bb665a3a132e0", segwit=False) + self.assertEqual(s.type, "NON_STANDARD") + self.assertEqual(s.ntype, 7) + self.assertEqual(s.asm, "OP_0 4160bb1870159a08724557f75c7bb665a3a132e0") + self.assertEqual(len(s.address), 0) + self.assertEqual(s.pattern, "OP_0 <20>") + self.assertEqual(s.op_sig_count, 0) + + + def test_segwit_p2wsh(self): + print("Deserialize segwit P2WSH") + s = blockchain.Script("0020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70") + self.assertEqual(s.type, "P2WSH") + self.assertEqual(s.ntype, 6) + self.assertEqual(s.asm, "OP_0 cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70") + self.assertEqual(s.address[0], unhexlify("cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70")) + self.assertEqual(s.pattern, "OP_0 <32>") + self.assertEqual(s.op_sig_count, 0) + s = blockchain.Script("0020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70", segwit=False) + self.assertEqual(s.type, "NON_STANDARD") + self.assertEqual(s.ntype, 7) + self.assertEqual(s.asm, "OP_0 cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70") + self.assertEqual(len(s.address), 0) + self.assertEqual(s.pattern, "OP_0 <32>") + self.assertEqual(s.op_sig_count, 0) + +# class TransactionDeserializeTests(unittest.TestCase): +# @classmethod +# def setUpClass(cls): +# print("\nTesting Transaction class deserialization:\n") +# +# def test_p2pkh(self): +# print("Deserialize P2PKH") +# tx = blockchain.Transaction.deserialize("0200000001df2d507c1c765e526f8dbe6527fc34be1c30b27fdb88c521060b82" +# "45dd9f4e2e010000006b483045022100b00c4efde901f2efb92679681bef359c" +# "7639ba79979e0c436cb10a266d0b4c5d0220730d854aa51fbe715387256956f3" +# "71d2199297f7b4ea6bf9b4b87bf8bba8417e012102530c548d402670b13ad888" +# "7ff99c294e67fc18097d236d57880c69261b42def70000000001b88800000000" +# "00001600144160bb1870159a08724557f75c7bb665a3a132e000000000") +# "0200000001df2d507c1c765e526f8dbe6527fc34be1c30b27fdb88c521060b8245dd9f4e2e010000006b483045022100b00c4efde901f2efb92679681bef359c7639ba79979e0c436cb10a266d0b4c5d0220730d854aa51fbe715387256956f371d2199297f7b4ea6bf9b4b87bf8bba8417e012102530c548d402670b13ad8887ff99c294e67fc18097d236d57880c69261b42def70000000001b8880000000000001600144160bb1870159a08724557f75c7bb665a3a132e000000000" +# t = "0100000000010198f4f454fbb0aeae5bd167879ca65560b3b7073cd57aaee9cb5903d6f0f883860000000000ffffffff01204e0000000000001976a9143e2585f7b9e642ad9030c0812490ea5b83c511fa88ac02483045022100849b9929f619933224743d14dde08ad521540d9c2b1b85a20ec1ce5db77e4fa1022035222f713f5753119783e049e1c3ef8f819b2af4946cf150c98fe66fd1898409012102530c548d402670b13ad8887ff99c294e67fc18097d236d57880c69261b42def700000000" +# tx = blockchain.Transaction.deserialize(t) +# print(tx.json()) diff --git a/pybtc/test/script_functions.py b/pybtc/test/script_functions.py new file mode 100644 index 0000000..f9b0a98 --- /dev/null +++ b/pybtc/test/script_functions.py @@ -0,0 +1,55 @@ +import unittest +import os, sys +parentPath = os.path.abspath("..") +if parentPath not in sys.path: + sys.path.insert(0, parentPath) + +from pybtc.functions import * + + + +class ScriptFunctionsTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("\nTesting script functions:\n") + + def test_script_to_address(self): + self.assertEqual(script_to_address("76a914f18e5346e6efe17246306ce82f11ca53542fe00388ac"), + "1P2EMAeiSJEfCrtjC6ovdWaGWW1Mb6azpX") + self.assertEqual(script_to_address("a9143f4eecba122ad73039d481c8d37f99cb4f887cd887"), + "37Tm3Qz8Zw2VJrheUUhArDAoq58S6YrS3g") + self.assertEqual(script_to_address("76a914a307d67484911deee457779b17505cedd20e1fe988ac", testnet=1), + "mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c") + self.assertEqual(script_to_address("0014751e76e8199196d454941c45d1b3a323f1433bd6", testnet=0), + "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4") + self.assertEqual(script_to_address("0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d"), + "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej") + + + def test_op_return_parse(self): + self.assertEqual(parse_script(OP_RETURN + b"\x00")["type"], "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + b"\x00")["data"], b"") + self.assertEqual(parse_script(OP_RETURN + b"\x2012345678901234567890123456789012")["type"], "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + b"\x2012345678901234567890123456789012")["data"], + b"12345678901234567890123456789012") + + self.assertEqual(parse_script(OP_RETURN + b"\x201234567890123456789012345678901211")["type"], + "NULL_DATA_NON_STANDARD") + + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x00")["type"], "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x00")["data"], b"") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x2012345678901234567890123456789012")["type"], + "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x2012345678901234567890123456789012")["data"], + b"12345678901234567890123456789012") + + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x201234567890123456789012345678901211")["type"], + "NULL_DATA_NON_STANDARD") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x5012345678901234567890123456789012345678901234567890123456789012345678901234567890")["type"], + "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x5012345678901234567890123456789012345678901234567890123456789012345678901234567890")["data"], + b"12345678901234567890123456789012345678901234567890123456789012345678901234567890") + + self.assertEqual(parse_script( + OP_RETURN + OP_PUSHDATA1 + b"\x51123456789012345678901234567890123456789012345678901234567890123456789012345678901")["type"], + "NULL_DATA_NON_STANDARD") diff --git a/pybtc/test/sighash.py b/pybtc/test/sighash.py new file mode 100644 index 0000000..d1a8ee5 --- /dev/null +++ b/pybtc/test/sighash.py @@ -0,0 +1,585 @@ +import unittest +import os, sys +parentPath = os.path.abspath("..") +if parentPath not in sys.path: + sys.path.insert(0, parentPath) +from pybtc import * + + +class SighashTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("\nTesting sighash:\n") + + def test_sighash(self): + t = [ + ["907c2bc503ade11cc3b04eb2918b6f547b0630ab569273824748c87ea14b0696526c66ba740200000004ab65ababfd1f9bdd4ef073c7afc4ae00da8a66f429c917a0081ad1e1dabce28d373eab81d8628de802000000096aab5253ab52000052ad042b5f25efb33beec9f3364e8a9139e8439d9d7e26529c3c30b6c3fd89f8684cfd68ea0200000009ab53526500636a52ab599ac2fe02a526ed040000000008535300516352515164370e010000000003006300ab2ec229", "", 2, 1864164639, "31af167a6cf3f9d5f6875caa4d31704ceb0eba078d132b78dab52c3b8997317e"], + ["a0aa3126041621a6dea5b800141aa696daf28408959dfb2df96095db9fa425ad3f427f2f6103000000015360290e9c6063fa26912c2e7fb6a0ad80f1c5fea1771d42f12976092e7a85a4229fdb6e890000000001abc109f6e47688ac0e4682988785744602b8c87228fcef0695085edf19088af1a9db126e93000000000665516aac536affffffff8fe53e0806e12dfd05d67ac68f4768fdbe23fc48ace22a5aa8ba04c96d58e2750300000009ac51abac63ab5153650524aa680455ce7b000000000000499e50030000000008636a00ac526563ac5051ee030000000003abacabd2b6fe000000000003516563910fb6b5", "65", 0, -1391424484, "48d6a1bd2cd9eec54eb866fc71209418a950402b5d7e52363bfb75c98e141175"], + ["6e7e9d4b04ce17afa1e8546b627bb8d89a6a7fefd9d892ec8a192d79c2ceafc01694a6a7e7030000000953ac6a51006353636a33bced1544f797f08ceed02f108da22cd24c9e7809a446c61eb3895914508ac91f07053a01000000055163ab516affffffff11dc54eee8f9e4ff0bcf6b1a1a35b1cd10d63389571375501af7444073bcec3c02000000046aab53514a821f0ce3956e235f71e4c69d91abe1e93fb703bd33039ac567249ed339bf0ba0883ef300000000090063ab65000065ac654bec3cc504bcf499020000000005ab6a52abac64eb060100000000076a6a5351650053bbbc130100000000056a6aab53abd6e1380100000000026a51c4e509b8", "acab655151", 0, 479279909, "2a3d95b09237b72034b23f2d2bb29fa32a58ab5c6aa72f6aafdfa178ab1dd01c"], + ["73107cbd025c22ebc8c3e0a47b2a760739216a528de8d4dab5d45cbeb3051cebae73b01ca10200000007ab6353656a636affffffffe26816dffc670841e6a6c8c61c586da401df1261a330a6c6b3dd9f9a0789bc9e000000000800ac6552ac6aac51ffffffff0174a8f0010000000004ac52515100000000", "5163ac63635151ac", 1, 1190874345, "06e328de263a87b09beabe222a21627a6ea5c7f560030da31610c4611f4a46bc"], + ["e93bbf6902be872933cb987fc26ba0f914fcfc2f6ce555258554dd9939d12032a8536c8802030000000453ac5353eabb6451e074e6fef9de211347d6a45900ea5aaf2636ef7967f565dce66fa451805c5cd10000000003525253ffffffff047dc3e6020000000007516565ac656aabec9eea010000000001633e46e600000000000015080a030000000001ab00000000", "5300ac6a53ab6a", 1, -886562767, "f03aa4fc5f97e826323d0daa03343ebf8a34ed67a1ce18631f8b88e5c992e798"], + ["50818f4c01b464538b1e7e7f5ae4ed96ad23c68c830e78da9a845bc19b5c3b0b20bb82e5e9030000000763526a63655352ffffffff023b3f9c040000000008630051516a6a5163a83caf01000000000553ab65510000000000", "6aac", 0, 946795545, "746306f322de2b4b58ffe7faae83f6a72433c22f88062cdde881d4dd8a5a4e2d"], + ["a93e93440250f97012d466a6cc24839f572def241c814fe6ae94442cf58ea33eb0fdd9bcc1030000000600636a0065acffffffff5dee3a6e7e5ad6310dea3e5b3ddda1a56bf8de7d3b75889fc024b5e233ec10f80300000007ac53635253ab53ffffffff0160468b04000000000800526a5300ac526a00000000", "ac00636a53", 1, 1773442520, "5c9d3a2ce9365bb72cfabbaa4579c843bb8abf200944612cf8ae4b56a908bcbd"], + ["ce7d371f0476dda8b811d4bf3b64d5f86204725deeaa3937861869d5b2766ea7d17c57e40b0100000003535265ffffffff7e7e9188f76c34a46d0bbe856bde5cb32f089a07a70ea96e15e92abb37e479a10100000006ab6552ab655225bcab06d1c2896709f364b1e372814d842c9c671356a1aa5ca4e060462c65ae55acc02d0000000006abac0063ac5281b33e332f96beebdbc6a379ebe6aea36af115c067461eb99d22ba1afbf59462b59ae0bd0200000004ab635365be15c23801724a1704000000000965006a65ac00000052ca555572", "53ab530051ab", 1, 2030598449, "c336b2f7d3702fbbdeffc014d106c69e3413c7c71e436ba7562d8a7a2871f181"], + ["d3b7421e011f4de0f1cea9ba7458bf3486bee722519efab711a963fa8c100970cf7488b7bb0200000003525352dcd61b300148be5d05000000000000000000", "535251536aac536a", 0, -1960128125, "29aa6d2d752d3310eba20442770ad345b7f6a35f96161ede5f07b33e92053e2a"], + ["04bac8c5033460235919a9c63c42b2db884c7c8f2ed8fcd69ff683a0a2cccd9796346a04050200000003655351fcad3a2c5a7cbadeb4ec7acc9836c3f5c3e776e5c566220f7f965cf194f8ef98efb5e3530200000007526a006552526526a2f55ba5f69699ece76692552b399ba908301907c5763d28a15b08581b23179cb01eac03000000075363ab6a516351073942c2025aa98a05000000000765006aabac65abd7ffa6030000000004516a655200000000", "53ac6365ac526a", 1, 764174870, "bf5fdc314ded2372a0ad078568d76c5064bf2affbde0764c335009e56634481b"], + ["c363a70c01ab174230bbe4afe0c3efa2d7f2feaf179431359adedccf30d1f69efe0c86ed390200000002ab51558648fe0231318b04000000000151662170000000000008ac5300006a63acac00000000", "", 0, 2146479410, "191ab180b0d753763671717d051f138d4866b7cb0d1d4811472e64de595d2c70"], + ["8d437a7304d8772210a923fd81187c425fc28c17a5052571501db05c7e89b11448b36618cd02000000026a6340fec14ad2c9298fde1477f1e8325e5747b61b7e2ff2a549f3d132689560ab6c45dd43c3010000000963ac00ac000051516a447ed907a7efffebeb103988bf5f947fc688aab2c6a7914f48238cf92c337fad4a79348102000000085352ac526a5152517436edf2d80e3ef06725227c970a816b25d0b58d2cd3c187a7af2cea66d6b27ba69bf33a0300000007000063ab526553f3f0d6140386815d030000000003ab6300de138f00000000000900525153515265abac1f87040300000000036aac6500000000", "51", 3, -315779667, "b6632ac53578a741ae8c36d8b69e79f39b89913a2c781cdf1bf47a8c29d997a5"], + ["fd878840031e82fdbe1ad1d745d1185622b0060ac56638290ec4f66b1beef4450817114a2c0000000009516a63ab53650051abffffffff37b7a10322b5418bfd64fb09cd8a27ddf57731aeb1f1f920ffde7cb2dfb6cdb70300000008536a5365ac53515369ecc034f1594690dbe189094dc816d6d57ea75917de764cbf8eccce4632cbabe7e116cd0100000003515352ffffffff035777fc000000000003515200abe9140300000000050063005165bed6d10200000000076300536363ab65195e9110", "635265", 0, 1729787658, "6e3735d37a4b28c45919543aabcb732e7a3e1874db5315abb7cc6b143d62ff10"], + ["f40a750702af06efff3ea68e5d56e42bc41cdb8b6065c98f1221fe04a325a898cb61f3d7ee030000000363acacffffffffb5788174aef79788716f96af779d7959147a0c2e0e5bfb6c2dba2df5b4b97894030000000965510065535163ac6affffffff0445e6fd0200000000096aac536365526a526aa6546b000000000008acab656a6552535141a0fd010000000000c897ea030000000008526500ab526a6a631b39dba3", "00abab5163ac", 1, -1778064747, "d76d0fc0abfa72d646df888bce08db957e627f72962647016eeae5a8412354cf"], + ["a63bc673049c75211aa2c09ecc38e360eaa571435fedd2af1116b5c1fa3d0629c269ecccbf0000000008ac65ab516352ac52ffffffffbf1a76fdda7f451a5f0baff0f9ccd0fe9136444c094bb8c544b1af0fa2774b06010000000463535253ffffffff13d6b7c3ddceef255d680d87181e100864eeb11a5bb6a3528cb0d70d7ee2bbbc02000000056a0052abab951241809623313b198bb520645c15ec96bfcc74a2b0f3db7ad61d455cc32db04afc5cc702000000016309c9ae25014d9473020000000004abab6aac3bb1e803", "", 3, -232881718, "6e48f3da3a4ac07eb4043a232df9f84e110485d7c7669dd114f679c27d15b97e"], + ["4c565efe04e7d32bac03ae358d63140c1cfe95de15e30c5b84f31bb0b65bb542d637f49e0f010000000551abab536348ae32b31c7d3132030a510a1b1aacf7b7c3f19ce8dc49944ef93e5fa5fe2d356b4a73a00100000009abac635163ac00ab514c8bc57b6b844e04555c0a4f4fb426df139475cd2396ae418bc7015820e852f711519bc202000000086a00510000abac52488ff4aec72cbcfcc98759c58e20a8d2d9725aa4a80f83964e69bc4e793a4ff25cd75dc701000000086a52ac6aac5351532ec6b10802463e0200000000000553005265523e08680100000000002f39a6b0", "", 3, 70712784, "c6076b6a45e6fcfba14d3df47a34f6aadbacfba107e95621d8d7c9c0e40518ed"], + ["1233d5e703403b3b8b4dae84510ddfc126b4838dcb47d3b23df815c0b3a07b55bf3098110e010000000163c5c55528041f480f40cf68a8762d6ed3efe2bd402795d5233e5d94bf5ddee71665144898030000000965525165655151656affffffff6381667e78bb74d0880625993bec0ea3bd41396f2bcccc3cc097b240e5e92d6a01000000096363acac6a63536365ffffffff04610ad60200000000065251ab65ab52e90d680200000000046351516ae30e98010000000008abab52520063656a671856010000000004ac6aac514c84e383", "6aabab636300", 1, -114996813, "aeb8c5a62e8a0b572c28f2029db32854c0b614dbecef0eaa726abebb42eebb8d"], + ["0c69702103b25ceaed43122cc2672de84a3b9aa49872f2a5bb458e19a52f8cc75973abb9f102000000055365656aacffffffff3ffb1cf0f76d9e3397de0942038c856b0ebbea355dc9d8f2b06036e19044b0450100000000ffffffff4b7793f4169617c54b734f2cd905ed65f1ce3d396ecd15b6c426a677186ca0620200000008655263526551006a181a25b703240cce0100000000046352ab53dee22903000000000865526a6a516a51005e121602000000000852ab52ababac655200000000", "6a516aab63", 1, -2040012771, "a6e6cb69f409ec14e10dd476f39167c29e586e99bfac93a37ed2c230fcc1dbbe"], + ["fd22692802db8ae6ab095aeae3867305a954278f7c076c542f0344b2591789e7e33e4d29f4020000000151ffffffffb9409129cfed9d3226f3b6bab7a2c83f99f48d039100eeb5796f00903b0e5e5e0100000006656552ac63abd226abac0403e649000000000007abab51ac5100ac8035f10000000000095165006a63526a52510d42db030000000007635365ac6a63ab24ef5901000000000453ab6a0000000000", "536a52516aac6a", 1, 309309168, "7ca0f75e6530ec9f80d031fc3513ca4ecd67f20cb38b4dacc6a1d825c3cdbfdb"], + ["a43f85f701ffa54a3cc57177510f3ea28ecb6db0d4431fc79171cad708a6054f6e5b4f89170000000008ac6a006a536551652bebeaa2013e779c05000000000665ac5363635100000000", "ac", 0, 2028978692, "58294f0d7f2e68fe1fd30c01764fe1619bcc7961d68968944a0e263af6550437"], + ["c2b0b99001acfecf7da736de0ffaef8134a9676811602a6299ba5a2563a23bb09e8cbedf9300000000026300ffffffff042997c50300000000045252536a272437030000000007655353ab6363ac663752030000000002ab6a6d5c900000000000066a6a5265abab00000000", "52ac525163515251", 0, -894181723, "8b300032a1915a4ac05cea2f7d44c26f2a08d109a71602636f15866563eaafdc"], + ["82f9f10304c17a9d954cf3380db817814a8c738d2c811f0412284b2c791ec75515f38c4f8c020000000265ab5729ca7db1b79abee66c8a757221f29280d0681355cb522149525f36da760548dbd7080a0100000001510b477bd9ce9ad5bb81c0306273a3a7d051e053f04ecf3a1dbeda543e20601a5755c0cfae030000000451ac656affffffff71141a04134f6c292c2e0d415e6705dfd8dcee892b0d0807828d5aeb7d11f5ef0300000001520b6c6dc802a6f3dd0000000000056aab515163bfb6800300000000015300000000", "", 3, -635779440, "d55ed1e6c53510f2608716c12132a11fb5e662ec67421a513c074537eeccc34b"], + ["8edcf5a1014b604e53f0d12fe143cf4284f86dc79a634a9f17d7e9f8725f7beb95e8ffcd2403000000046aabac52ffffffff01c402b5040000000005ab6a63525100000000", "6351525251acabab6a", 0, 1520147826, "2765bbdcd3ebb8b1a316c04656b28d637f80bffbe9b040661481d3dc83eea6d6"], + ["2074bad5011847f14df5ea7b4afd80cd56b02b99634893c6e3d5aaad41ca7c8ee8e5098df003000000026a6affffffff018ad59700000000000900ac656a526551635300000000", "65635265", 0, -1804671183, "663c999a52288c9999bff36c9da2f8b78d5c61b8347538f76c164ccba9868d0a"], + ["7100b11302e554d4ef249ee416e7510a485e43b2ba4b8812d8fe5529fe33ea75f36d392c4403000000020000ffffffff3d01a37e075e9a7715a657ae1bdf1e44b46e236ad16fd2f4c74eb9bf370368810000000007636553ac536365ffffffff01db696a0400000000065200ac656aac00000000", "63005151", 0, -1210499507, "b9c3aee8515a4a3b439de1ffc9c156824bda12cb75bfe5bc863164e8fd31bd7a"], + ["02c1017802091d1cb08fec512db7b012fe4220d57a5f15f9e7676358b012786e1209bcff950100000004acab6352ffffffff799bc282724a970a6fea1828984d0aeb0f16b67776fa213cbdc4838a2f1961a3010000000951516a536552ab6aabffffffff016c7b4b03000000000865abac5253ac5352b70195ad", "65655200516a", 0, -241626954, "be567cb47170b34ff81c66c1142cb9d27f9b6898a384d6dfc4fce16b75b6cb14"], + ["cb3178520136cd294568b83bb2520f78fecc507898f4a2db2674560d72fd69b9858f75b3b502000000066aac00515100ffffffff03ab005a01000000000563526363006e3836030000000001abfbda3200000000000665ab0065006500000000", "ab516a0063006a5300", 0, 1182109299, "2149e79c3f4513da4e4378608e497dcfdfc7f27c21a826868f728abd2b8a637a"], + ["18a4b0c004702cf0e39686ac98aab78ad788308f1d484b1ddfe70dc1997148ba0e28515c310300000000ffffffff05275a52a23c59da91129093364e275da5616c4070d8a05b96df5a2080ef259500000000096aac51656a6aac53ab66e64966b3b36a07dd2bb40242dd4a3743d3026e7e1e0d9e9e18f11d068464b989661321030000000265ac383339c4fae63379cafb63b0bab2eca70e1f5fc7d857eb5c88ccd6c0465093924bba8b2a000000000300636ab5e0545402bc2c4c010000000000cd41c002000000000000000000", "abac635253656a00", 3, 2052372230, "32db877b6b1ca556c9e859442329406f0f8246706522369839979a9f7a235a32"], + ["1d9c5df20139904c582285e1ea63dec934251c0f9cf5c47e86abfb2b394ebc57417a81f67c010000000353515222ba722504800d3402000000000353656a3c0b4a0200000000000fb8d20500000000076300ab005200516462f30400000000015200000000", "ab65", 0, -210854112, "edf73e2396694e58f6b619f68595b0c1cdcb56a9b3147845b6d6afdb5a80b736"], + ["4504cb1904c7a4acf375ddae431a74de72d5436efc73312cf8e9921f431267ea6852f9714a01000000066a656a656553a2fbd587c098b3a1c5bd1d6480f730a0d6d9b537966e20efc0e352d971576d0f87df0d6d01000000016321aeec3c4dcc819f1290edb463a737118f39ab5765800547522708c425306ebfca3f396603000000055300ac656a1d09281d05bfac57b5eb17eb3fa81ffcedfbcd3a917f1be0985c944d473d2c34d245eb350300000007656a51525152ac263078d9032f470f0500000000066aac00000052e12da60200000000003488410200000000076365006300ab539981e432", "52536a52526a", 1, -31909119, "f0a2deee7fd8a3a9fad6927e763ded11c940ee47e9e6d410f94fda5001f82e0c"], + ["14bc7c3e03322ec0f1311f4327e93059c996275302554473104f3f7b46ca179bfac9ef753503000000016affffffff9d405eaeffa1ca54d9a05441a296e5cc3a3e32bb8307afaf167f7b57190b07e00300000008abab51ab5263abab45533aa242c61bca90dd15d46079a0ab0841d85df67b29ba87f2393cd764a6997c372b55030000000452005263ffffffff0250f40e02000000000651516a0063630e95ab0000000000046a5151ac00000000", "6a65005151", 0, -1460947095, "aa418d096929394c9147be8818d8c9dafe6d105945ab9cd7ec682df537b5dd79"], + ["2b3bd0dd04a1832f893bf49a776cd567ec4b43945934f4786b615d6cb850dfc0349b33301a000000000565ac000051cf80c670f6ddafab63411adb4d91a69c11d9ac588898cbfb4cb16061821cc104325c895103000000025163ffffffffa9e2d7506d2d7d53b882bd377bbcc941f7a0f23fd15d2edbef3cd9df8a4c39d10200000009ac63006a52526a5265ffffffff44c099cdf10b10ce87d4b38658d002fd6ea17ae4a970053c05401d86d6e75f99000000000963ab53526a5252ab63ffffffff035af69c01000000000100ba9b8b0400000000004cead10500000000026a520b77d667", "ab52abac526553", 3, -1955078165, "eb9ceecc3b401224cb79a44d23aa8f428e29f1405daf69b4e01910b848ef1523"], + ["35df11f004a48ba439aba878fe9df20cc935b4a761c262b1b707e6f2b33e2bb7565cd68b130000000000ffffffffb2a2f99abf64163bb57ca900500b863f40c02632dfd9ea2590854c5fb4811da90200000006ac006363636affffffffaf9d89b2a8d2670ca37c8f7c140600b81259f2e037cb4590578ec6e37af8bf200000000005abac6a655270a4751eb551f058a93301ffeda2e252b6614a1fdd0e283e1d9fe53c96c5bbaafaac57b8030000000153ffffffff020d9f3b02000000000100ed7008030000000004abac000000000000", "abac", 3, 593793071, "88fdee1c2d4aeead71d62396e28dc4d00e5a23498eea66844b9f5d26d1f21042"], + ["a08ff466049fb7619e25502ec22fedfb229eaa1fe275aa0b5a23154b318441bf547989d0510000000005ab5363636affffffff2b0e335cb5383886751cdbd993dc0720817745a6b1c9b8ab3d15547fc9aafd03000000000965656a536a52656a532b53d10584c290d3ac1ab74ab0a19201a4a039cb59dc58719821c024f6bf2eb26322b33f010000000965ac6aac0053ab6353ffffffff048decba6ebbd2db81e416e39dde1f821ba69329725e702bcdea20c5cc0ecc6402000000086363ab5351ac6551466e377b0468c0fa00000000000651ab53ac6a513461c6010000000008636a636365535100eeb3dc010000000006526a52ac516a43f362010000000005000063536500000000", "0063516a", 1, -1158911348, "f6a1ecb50bd7c2594ebecea5a1aa23c905087553e40486dade793c2f127fdfae"], + ["5ac2f17d03bc902e2bac2469907ec7d01a62b5729340bc58c343b7145b66e6b97d434b30fa000000000163ffffffff44028aa674192caa0d0b4ebfeb969c284cb16b80c312d096efd80c6c6b094cca000000000763acabac516a52ffffffff10c809106e04b10f9b43085855521270fb48ab579266e7474657c6c625062d2d030000000351636595a0a97004a1b69603000000000465ab005352ad68010000000008636a5263acac5100da7105010000000002acab90325200000000000000000000", "6a6aab516a63526353", 2, 1518400956, "f7efb74b1dcc49d316b49c632301bc46f98d333c427e55338be60c7ef0d953be"], + ["aeb2e11902dc3770c218b97f0b1960d6ee70459ecb6a95eff3f05295dc1ef4a0884f10ba460300000005516352526393e9b1b3e6ae834102d699ddd3845a1e159aa7cf7635edb5c02003f7830fee3788b795f20100000009ab006a526553ac006ad8809c570469290e0400000000050000abab00b10fd5040000000008ab655263abac53ab630b180300000000009d9993040000000002516300000000", "5351ababac6a65", 0, 1084852870, "f2286001af0b0170cbdad92693d0a5ebaa8262a4a9d66e002f6d79a8c94026d1"], + ["9860ca9a0294ff4812534def8c3a3e3db35b817e1a2ddb7f0bf673f70eab71bb79e90a2f3100000000086a636551acac5165ffffffffed4d6d3cd9ff9b2d490e0c089739121161a1445844c3e204296816ab06e0a83702000000035100ac88d0db5201c3b59a050000000005ac6a0051ab00000000", "535263ab006a526aab", 1, -962088116, "30df2473e1403e2b8e637e576825f785528d998af127d501556e5f7f5ed89a2a"], + ["4ddaa680026ec4d8060640304b86823f1ac760c260cef81d85bd847952863d629a3002b54b0200000008526365636a656aab65457861fc6c24bdc760c8b2e906b6656edaf9ed22b5f50e1fb29ec076ceadd9e8ebcb6b000000000152ffffffff033ff04f00000000000551526a00657a1d900300000000002153af040000000003006a6300000000", "ab526a53acabab", 0, 1055317633, "7f21b62267ed52462e371a917eb3542569a4049b9dfca2de3c75872b39510b26"], + ["01e76dcd02ad54cbc8c71d68eaf3fa7c883b65d74217b30ba81f1f5144ef80b706c0dc82ca000000000352ab6a078ec18bcd0514825feced2e8b8ea1ccb34429fae41c70cc0b73a2799e85603613c6870002000000086363ab6365536a53ffffffff043acea90000000000016ad20e1803000000000100fa00830200000000056352515351e864ee00000000000865535253ab6a6551d0c46672", "6a6365abacab", 0, -1420559003, "8af0b4cbdbc011be848edf4dbd2cde96f0578d662cfebc42252495387114224a"], + ["fa00b26402670b97906203434aa967ce1559d9bd097d56dbe760469e6032e7ab61accb54160100000006635163630052fffffffffe0d3f4f0f808fd9cfb162e9f0c004601acf725cd7ea5683bbdc9a9a433ef15a0200000005ab52536563d09c7bef049040f305000000000153a7c7b9020000000004ac63ab52847a2503000000000553ab00655390ed80010000000005006553ab52860671d4", "536565ab52", 0, 799022412, "40ed8e7bbbd893e15f3cce210ae02c97669818de5946ca37eefc7541116e2c78"], + ["cb5c06dc01b022ee6105ba410f0eb12b9ce5b5aa185b28532492d839a10cef33d06134b91b010000000153ffffffff02cec0530400000000005e1e4504000000000865656551acacac6a00000000", "ab53", 0, -1514251329, "136beb95459fe6b126cd6cefd54eb5d971524b0e883e41a292a78f78015cb8d5"], + ["f10a0356031cd569d652dbca8e7a4d36c8da33cdff428d003338602b7764fe2c96c505175b010000000465ac516affffffffbb54563c71136fa944ee20452d78dc87073ac2365ba07e638dce29a5d179da600000000003635152ffffffff9a411d8e2d421b1e6085540ee2809901e590940bbb41532fa38bd7a16b68cc350100000007535251635365636195df1603b61c45010000000002ab65bf6a310400000000026352fcbba10200000000016aa30b7ff0", "5351", 0, 1552495929, "9eb8adf2caecb4bf9ac59d7f46bd20e83258472db2f569ee91aba4cf5ee78e29"], + ["c3325c9b012f659466626ca8f3c61dfd36f34670abc054476b7516a1839ec43cd0870aa0c0000000000753525265005351e7e3f04b0112650500000000000363ac6300000000", "acac", 0, -68961433, "5ca70e727d91b1a42b78488af2ed551642c32d3de4712a51679f60f1456a8647"], + ["2333e54c044370a8af16b9750ac949b151522ea6029bacc9a34261599549581c7b4e5ece470000000007510052006563abffffffff80630fc0155c750ce20d0ca4a3d0c8e8d83b014a5b40f0b0be0dd4c63ac28126020000000465000000ffffffff1b5f1433d38cdc494093bb1d62d84b10abbdae57e3d04e82e600857ab3b1dc990300000003515100b76564be13e4890a908ea7508afdad92ec1b200a9a67939fadce6eb7a29eb4550a0a28cb0300000001acffffffff02926c930300000000016373800201000000000153d27ee740", "ab6365ab516a53", 3, 598653797, "2be27a686eb7940dd32c44ff3a97c1b28feb7ab9c5c0b1593b2d762361cfc2db"], + ["b500ca48011ec57c2e5252e5da6432089130603245ffbafb0e4c5ffe6090feb629207eeb0e010000000652ab6a636aab8302c9d2042b44f40500000000015278c05a050000000004ac5251524be080020000000007636aac63ac5252c93a9a04000000000965ab6553636aab5352d91f9ddb", "52005100", 0, -2024394677, "49c8a6940a461cc7225637f1e512cdd174c99f96ec05935a59637ededc77124c"], + ["f52ff64b02ee91adb01f3936cc42e41e1672778962b68cf013293d649536b519bc3271dd2c00000000020065afee11313784849a7c15f44a61cd5fd51ccfcdae707e5896d131b082dc9322a19e12858501000000036aac654e8ca882022deb7c020000000006006a515352abd3defc0000000000016300000000", "63520063", 0, 1130989496, "7f208df9a5507e98c62cebc5c1e2445eb632e95527594929b9577b53363e96f6"], + ["ab7d6f36027a7adc36a5cf7528fe4fb5d94b2c96803a4b38a83a675d7806dda62b380df86a0000000003000000ffffffff5bc00131e29e22057c04be854794b4877dda42e416a7a24706b802ff9da521b20000000007ac6a0065ac52ac957cf45501b9f06501000000000500ac6363ab25f1110b", "00526500536a635253", 0, 911316637, "5fa09d43c8aef6f6fa01c383a69a5a61a609cd06e37dce35a39dc9eae3ddfe6c"], + ["f940888f023dce6360263c850372eb145b864228fdbbb4c1186174fa83aab890ff38f8c9a90300000000ffffffff01e80ccdb081e7bbae1c776531adcbfb77f2e5a7d0e5d0d0e2e6c8758470e85f00000000020053ffffffff03b49088050000000004656a52ab428bd604000000000951630065ab63ac636a0cbacf0400000000070063ac5265ac53d6e16604", "ac63", 0, 39900215, "713ddeeefcfe04929e7b6593c792a4efbae88d2b5280d1f0835d2214eddcbad6"], + ["530ecd0b01ec302d97ef6f1b5a6420b9a239714013e20d39aa3789d191ef623fc215aa8b940200000005ac5351ab6a3823ab8202572eaa04000000000752ab6a51526563fd8a270100000000036a006581a798f0", "525153656a0063", 0, 1784562684, "fe42f73a8742676e640698222b1bd6b9c338ff1ccd766d3d88d7d3c6c6ac987e"], + ["5d781d9303acfcce964f50865ddfddab527ea971aee91234c88e184979985c00b4de15204b0100000003ab6352a009c8ab01f93c8ef2447386c434b4498538f061845862c3f9d5751ad0fce52af442b3a902000000045165ababb909c66b5a3e7c81b3c45396b944be13b8aacfc0204f3f3c105a66fa8fa6402f1b5efddb01000000096a65ac636aacab656ac3c677c402b79fa4050000000004006aab5133e35802000000000751ab635163ab0078c2e025", "6aac51636a6a005265", 0, -882306874, "551ce975d58647f10adefb3e529d9bf9cda34751627ec45e690f135ef0034b95"], + ["25ee54ef0187387564bb86e0af96baec54289ca8d15e81a507a2ed6668dc92683111dfb7a50100000004005263634cecf17d0429aa4d000000000007636a6aabab5263daa75601000000000251ab4df70a01000000000151980a890400000000065253ac6a006377fd24e3", "65ab", 0, 797877378, "069f38fd5d47abff46f04ee3ae27db03275e9aa4737fa0d2f5394779f9654845"], + ["a9c57b1a018551bcbc781b256642532bbc09967f1cbe30a227d352a19365d219d3f11649a3030000000451655352b140942203182894030000000006ab00ac6aab654add350400000000003d379505000000000553abacac00e1739d36", "5363", 0, -1069721025, "6da32416deb45a0d720a1dbe6d357886eabc44029dd5db74d50feaffbe763245"], + ["05c4fb94040f5119dc0b10aa9df054871ed23c98c890f1e931a98ffb0683dac45e98619fdc0200000007acab6a525263513e7495651c9794c4d60da835d303eb4ee6e871f8292f6ad0b32e85ef08c9dc7aa4e03c9c010000000500ab52acacfffffffffee953259cf14ced323fe8d567e4c57ba331021a1ef5ac2fa90f7789340d7c550100000007ac6aacac6a6a53ffffffff08d9dc820d00f18998af247319f9de5c0bbd52a475ea587f16101af3afab7c210100000003535363569bca7c0468e34f00000000000863536353ac51ac6584e319010000000006650052ab6a533debea030000000003ac0053ee7070020000000006ac52005253ac00000000", "6351005253", 2, 1386916157, "76c4013c40bfa1481badd9d342b6d4b8118de5ab497995fafbf73144469e5ff0"], + ["c95ab19104b63986d7303f4363ca8f5d2fa87c21e3c5d462b99f1ebcb7c402fc012f5034780000000009006aac63ac65655265ffffffffbe91afa68af40a8700fd579c86d4b706c24e47f7379dad6133de389f815ef7f501000000046aac00abffffffff1520db0d81be4c631878494668d258369f30b8f2b7a71e257764e9a27f24b48701000000076a515100535300b0a989e1164db9499845bac01d07a3a7d6d2c2a76e4c04abe68f808b6e2ef5068ce6540e0100000009ac53636a63ab65656affffffff0309aac6050000000005ab6563656a6067e8020000000003ac536aec91c8030000000009655251ab65ac6a53acc7a45bc5", "63526a65abac", 1, 512079270, "fb7eca81d816354b6aedec8cafc721d5b107336657acafd0d246049556f9e04b"], + ["ca66ae10049533c2b39f1449791bd6d3f039efe0a121ab7339d39ef05d6dcb200ec3fb2b3b020000000465006a53ffffffff534b8f97f15cc7fb4f4cea9bf798472dc93135cd5b809e4ca7fe4617a61895980100000000ddd83c1dc96f640929dd5e6f1151dab1aa669128591f153310d3993e562cc7725b6ae3d903000000046a52536582f8ccddb8086d8550f09128029e1782c3f2624419abdeaf74ecb24889cc45ac1a64492a0100000002516a4867b41502ee6ccf03000000000752acacab52ab6a4b7ba80000000000075151ab0052536300000000", "6553", 2, -62969257, "8085e904164ab9a8c20f58f0d387f6adb3df85532e11662c03b53c3df8c943cb"], + ["ba646d0b0453999f0c70cb0430d4cab0e2120457bb9128ed002b6e9500e9c7f8d7baa20abe0200000001652a4e42935b21db02b56bf6f08ef4be5adb13c38bc6a0c3187ed7f6197607ba6a2c47bc8a03000000040052516affffffffa55c3cbfc19b1667594ac8681ba5d159514b623d08ed4697f56ce8fcd9ca5b0b00000000096a6a5263ac655263ab66728c2720fdeabdfdf8d9fb2bfe88b295d3b87590e26a1e456bad5991964165f888c03a0200000006630051ac00acffffffff0176fafe0100000000070063acac65515200000000", "63", 1, 2002322280, "9db4e320208185ee70edb4764ee195deca00ba46412d5527d9700c1cf1c3d057"], + ["2ddb8f84039f983b45f64a7a79b74ff939e3b598b38f436def7edd57282d0803c7ef34968d02000000026a537eb00c4187de96e6e397c05f11915270bcc383959877868ba93bac417d9f6ed9f627a7930300000004516551abffffffffacc12f1bb67be3ae9f1d43e55fda8b885340a0df1175392a8bbd9f959ad3605003000000025163ffffffff02ff0f4700000000000070bd99040000000003ac53abf8440b42", "", 2, -393923011, "0133f1a161363b71dfb3a90065c7128c56bd0028b558b610142df79e055ab5c7"], + ["b21fc15403b4bdaa994204444b59323a7b8714dd471bd7f975a4e4b7b48787e720cbd1f5f00000000000ffffffff311533001cb85c98c1d58de0a5fbf27684a69af850d52e22197b0dc941bc6ca9030000000765ab6363ab5351a8ae2c2c7141ece9a4ff75c43b7ea9d94ec79b7e28f63e015ac584d984a526a73fe1e04e0100000007526352536a5365ffffffff02a0a9ea030000000002ab52cfc4f300000000000465525253e8e0f342", "000000", 1, 1305253970, "d1df1f4bba2484cff8a816012bb6ec91c693e8ca69fe85255e0031711081c46a"], + ["d1704d6601acf710b19fa753e307cfcee2735eada0d982b5df768573df690f460281aad12d0000000007656300005100acffffffff0232205505000000000351ab632ca1bc0300000000016300000000", "ac65ab65ab51", 0, 165179664, "40b4f03c68288bdc996011b0f0ddb4b48dc3be6762db7388bdc826113266cd6c"], + ["d2f6c096025cc909952c2400bd83ac3d532bfa8a1f8f3e73c69b1fd7b8913379793f3ce92202000000076a00ab6a53516ade5332d81d58b22ed47b2a249ab3a2cb3a6ce9a6b5a6810e18e3e1283c1a1b3bd73e3ab00300000002acabffffffff01a9b2d40500000000056352abab00dc4b7f69", "ab0065", 0, -78019184, "2ef025e907f0fa454a2b48a4f3b81346ba2b252769b5c35d742d0c8985e0bf5e"], + ["3e6db1a1019444dba461247224ad5933c997256d15c5d37ade3d700506a0ba0a57824930d7010000000852ab6500ab00ac00ffffffff03389242020000000001aba8465a0200000000086a6a636a5100ab52394e6003000000000953ac51526351000053d21d9800", "abababacab53ab65", 0, 1643661850, "1f8a3aca573a609f4aea0c69522a82fcb4e15835449da24a05886ddc601f4f6a"], + ["f821a042036ad43634d29913b77c0fc87b4af593ac86e9a816a9d83fd18dfcfc84e1e1d57102000000076a63ac52006351ffffffffbcdaf490fc75086109e2f832c8985716b3a624a422cf9412fe6227c10585d21203000000095252abab5352ac526affffffff2efed01a4b73ad46c7f7bc7fa3bc480f8e32d741252f389eaca889a2e9d2007e000000000353ac53ffffffff032ac8b3020000000009636300000063516300d3d9f2040000000006510065ac656aafa5de0000000000066352ab5300ac9042b57d", "525365", 1, 667065611, "0d17a92c8d5041ba09b506ddf9fd48993be389d000aad54f9cc2a44fcc70426b"], + ["58e3f0f704a186ef55d3919061459910df5406a9121f375e7502f3be872a449c3f2bb058380100000000f0e858da3ac57b6c973f889ad879ffb2bd645e91b774006dfa366c74e2794aafc8bbc871010000000751ac65516a515131a68f120fd88ca08687ceb4800e1e3fbfea7533d34c84fef70cc5a96b648d580369526d000000000600ac00515363f6191d5b3e460fa541a30a6e83345dedfa3ed31ad8574d46d7bbecd3c9074e6ba5287c24020000000151e3e19d6604162602010000000004005100ac71e17101000000000065b5e90300000000040053ab53f6b7d101000000000200ac00000000", "6563ab", 1, -669018604, "8221d5dfb75fc301a80e919e158e0b1d1e86ffb08870a326c89408d9bc17346b"], + ["efec1cce044a676c1a3d973f810edb5a9706eb4cf888a240f2b5fb08636bd2db482327cf500000000005ab51656a52ffffffff46ef019d7c03d9456e5134eb0a7b5408d274bd8e33e83df44fab94101f7c5b650200000009ac5100006353630051407aadf6f5aaffbd318fdbbc9cae4bd883e67d524df06bb006ce2f7c7e2725744afb76960100000005536aab53acec0d64eae09e2fa1a7c4960354230d51146cf6dc45ee8a51f489e20508a785cbe6ca86fc000000000651536a516300ffffffff014ef598020000000006636aac655265a6ae1b75", "53516a5363526563ab", 2, -1823982010, "13e8b5ab4e5b2ceeff0045c625e19898bda2d39fd7af682e2d1521303cfe1154"], + ["3c436c2501442a5b700cbc0622ee5143b34b1b8021ea7bbc29e4154ab1f5bdfb3dff9d640501000000086aab5251ac5252acffffffff0170b9a20300000000066aab6351525114b13791", "63acabab52ab51ac65", 0, -2140612788, "87ddf1f9acb6640448e955bd1968f738b4b3e073983af7b83394ab7557f5cd61"], + ["d62f183e037e0d52dcf73f9b31f70554bce4f693d36d17552d0e217041e01f15ad3840c838000000000963acac6a6a6a63ab63ffffffffabdfb395b6b4e63e02a763830f536fc09a35ff8a0cf604021c3c751fe4c88f4d0300000006ab63ab65ac53aa4d30de95a2327bccf9039fb1ad976f84e0b4a0936d82e67eafebc108993f1e57d8ae39000000000165ffffffff04364ad30500000000036a005179fd84010000000007ab636aac6363519b9023030000000008510065006563ac6acd2a4a02000000000000000000", "52", 1, 595020383, "da8405db28726dc4e0f82b61b2bfd82b1baa436b4e59300305cc3b090b157504"], + ["44c200a5021238de8de7d80e7cce905606001524e21c8d8627e279335554ca886454d692e6000000000500acac52abbb8d1dc876abb1f514e96b21c6e83f429c66accd961860dc3aed5071e153e556e6cf076d02000000056553526a51870a928d0360a580040000000004516a535290e1e302000000000851ab6a00510065acdd7fc5040000000007515363ab65636abb1ec182", "6363", 0, -785766894, "ed53cc766cf7cb8071cec9752460763b504b2183442328c5a9761eb005c69501"], + ["d682d52d034e9b062544e5f8c60f860c18f029df8b47716cabb6c1b4a4b310a0705e754556020000000400656a0016eeb88eef6924fed207fba7ddd321ff3d84f09902ff958c815a2bf2bb692eb52032c4d803000000076365ac516a520099788831f8c8eb2552389839cfb81a9dc55ecd25367acad4e03cfbb06530f8cccf82802701000000085253655300656a53ffffffff02d543200500000000056a510052ac03978b05000000000700ac51525363acfdc4f784", "", 2, -696035135, "e1a256854099907050cfee7778f2018082e735a1f1a3d91437584850a74c87bb"], + ["e8c0dec5026575ddf31343c20aeeca8770afb33d4e562aa8ee52eeda6b88806fdfd4fe0a97030000000953acabab65ab516552ffffffffdde122c2c3e9708874286465f8105f43019e837746686f442666629088a970e0010000000153ffffffff01f98eee0100000000025251fe87379a", "63", 1, 633826334, "abe441209165d25bc6d8368f2e7e7dc21019056719fef1ace45542aa2ef282e2"], + ["b288c331011c17569293c1e6448e33a64205fc9dc6e35bc756a1ac8b97d18e912ea88dc0770200000007635300ac6aacabfc3c890903a3ccf8040000000004656500ac9c65c9040000000009ab6a6aabab65abac63ac5f7702000000000365005200000000", "526a63", 0, 1574937329, "0dd1bd5c25533bf5f268aa316ce40f97452cca2061f0b126a59094ca5b65f7a0"], + ["fc0a092003cb275fa9a25a72cf85d69c19e4590bfde36c2b91cd2c9c56385f51cc545530210000000004ab530063ffffffff729b006eb6d14d6e5e32b1c376acf1c62830a5d9246da38dbdb4db9f51fd1c74020000000463636500ffffffff0ae695c6d12ab7dcb8d3d4b547b03f178c7268765d1de9af8523d244e3836b12030000000151ffffffff0115c1e20100000000066a6aabac6a6a1ff59aec", "ab0053ac", 0, 931831026, "73fe22099c826c34a74edf45591f5d7b3a888c8178cd08facdfd96a9a681261c"], + ["0fcae7e004a71a4a7c8f66e9450c0c1785268679f5f1a2ee0fb3e72413d70a9049ecff75de020000000452005251ffffffff99c8363c4b95e7ec13b8c017d7bb6e80f7c04b1187d6072961e1c2479b1dc0320200000000ffffffff7cf03b3d66ab53ed740a70c5c392b84f780fff5472aee82971ac3bfeeb09b2df0200000006ab5265636a0058e4fe9257d7c7c7e82ff187757c6eadc14cceb6664dba2de03a018095fd3006682a5b9600000000056353536a636de26b2303ff76de010000000001acdc0a2e020000000001ab0a53ed020000000007530063ab51510088417307", "ac6aacab5165535253", 2, -902160694, "eea96a48ee572aea33d75d0587ce954fcfb425531a7da39df26ef9a6635201be"], + ["612701500414271138e30a46b7a5d95c70c78cc45bf8e40491dac23a6a1b65a51af04e6b94020000000451655153ffffffffeb72dc0e49b2fad3075c19e1e6e4b387f1365dca43d510f6a02136318ddecb7f0200000003536352e115ffc4f9bae25ef5baf534a890d18106fb07055c4d7ec9553ba89ed1ac2101724e507303000000080063006563acabac2ff07f69a080cf61a9d19f868239e6a4817c0eeb6a4f33fe254045d8af2bca289a8695de0300000000430736c404d317840500000000086a00abac5351ab65306e0503000000000963ab0051536aabab6a6c8aca01000000000565516351ab5dcf960100000000016a00000000", "ab", 2, -604581431, "5ec805e74ee934aa815ca5f763425785ae390282d46b5f6ea076b6ad6255a842"], + ["6b68ba00023bb4f446365ea04d68d48539aae66f5b04e31e6b38b594d2723ab82d44512460000000000200acffffffff5dfc6febb484fff69c9eeb7c7eb972e91b6d949295571b8235b1da8955f3137b020000000851ac6352516a535325828c8a03365da801000000000800636aabac6551ab0f594d03000000000963ac536365ac63636a45329e010000000005abac53526a00000000", "005151", 0, 1317038910, "42f5ba6f5fe1e00e652a08c46715871dc4b40d89d9799fd7c0ea758f86eab6a7"], + ["aff5850c0168a67296cc790c1b04a9ed9ad1ba0469263a9432fcb53676d1bb4e0eea8ea1410100000005ac65526a537d5fcb1d01d9c26d0200000000065265ab5153acc0617ca1", "51ab650063", 0, 1712981774, "8449d5247071325e5f8edcc93cb9666c0fecabb130ce0e5bef050575488477eb"], + ["e6d6b9d8042c27aec99af8c12b6c1f7a80453e2252c02515e1f391da185df0874e133696b50300000006ac5165650065ffffffff6a4b60a5bfe7af72b198eaa3cde2e02aa5fa36bdf5f24ebce79f6ecb51f3b554000000000652656aababac2ec4c5a6cebf86866b1fcc4c5bd5f4b19785a8eea2cdfe58851febf87feacf6f355324a80100000001537100145149ac1e287cef62f6f5343579189fad849dd33f25c25bfca841cb696f10c5a34503000000046a636a63df9d7c4c018d96e20100000000015100000000", "53ab", 1, -1924777542, "f98f95d0c5ec3ac3e699d81f6c440d2e7843eab15393eb023bc5a62835d6dcea"], + ["046ac25e030a344116489cc48025659a363da60bc36b3a8784df137a93b9afeab91a04c1ed020000000951ab0000526a65ac51ffffffff6c094a03869fde55b9a8c4942a9906683f0a96e2d3e5a03c73614ea3223b2c29020000000500ab636a6affffffff3da7aa5ecef9071600866267674b54af1740c5aeb88a290c459caa257a2683cb0000000004ab6565ab7e2a1b900301b916030000000005abac63656308f4ed03000000000852ab53ac63ac51ac73d620020000000003ab00008deb1285", "6a", 2, 1299505108, "f79e6b776e2592bad45ca328c54abf14050c241d8f822d982c36ea890fd45757"], + ["bd515acd0130b0ac47c2d87f8d65953ec7d657af8d96af584fc13323d0c182a2e5f9a96573000000000652ac51acac65ffffffff0467aade000000000003655363dc577d050000000006515252ab5300137f60030000000007535163530065004cdc860500000000036a5265241bf53e", "acab", 0, 621090621, "771d4d87f1591a13d77e51858c16d78f1956712fe09a46ff1abcabbc1e7af711"], + ["ff1ae37103397245ac0fa1c115b079fa20930757f5b6623db3579cb7663313c2dc4a3ffdb300000000076353656a000053ffffffff83c59e38e5ad91216ee1a312d15b4267bae2dd2e57d1a3fd5c2f0f809eeb5d46010000000800abab6a6a53ab51ffffffff9d5e706c032c1e0ca75915f8c6686f64ec995ebcd2539508b7dd8abc3e4d7d2a01000000006b2bdcda02a8fe070500000000045253000019e31d04000000000700ab63acab526a00000000", "53656aab6a525251", 0, 881938872, "726bb88cdf3af2f7603a31f33d2612562306d08972a4412a55dbbc0e3363721c"], + ["ff5400dd02fec5beb9a396e1cbedc82bedae09ed44bae60ba9bef2ff375a6858212478844b03000000025253ffffffff01e46c203577a79d1172db715e9cc6316b9cfc59b5e5e4d9199fef201c6f9f0f000000000900ab6552656a5165acffffffff02e8ce62040000000002515312ce3e00000000000251513f119316", "", 0, 1541581667, "1e0da47eedbbb381b0e0debbb76e128d042e02e65b11125e17fd127305fc65cd"], + ["28e3daa603c03626ad91ffd0ff927a126e28d29db5012588b829a06a652ea4a8a5732407030200000004ab6552acffffffff8e643146d3d0568fc2ad854fd7864d43f6f16b84e395db82b739f6f5c84d97b40000000004515165526b01c2dc1469db0198bd884e95d8f29056c48d7e74ff9fd37a9dec53e44b8769a6c99c030200000009ab006a516a53630065eea8738901002398000000000007ac5363516a51abeaef12f5", "52ab52515253ab", 2, 1687390463, "55591346aec652980885a558cc5fc2e3f8d21cbd09f314a798e5a7ead5113ea6"], + ["b54bf5ac043b62e97817abb892892269231b9b220ba08bc8dbc570937cd1ea7cdc13d9676c010000000451ab5365a10adb7b35189e1e8c00b86250f769319668189b7993d6bdac012800f1749150415b2deb0200000003655300ffffffff60b9f4fb9a7e17069fd00416d421f804e2ef2f2c67de4ca04e0241b9f9c1cc5d0200000003ab6aacfffffffff048168461cce1d40601b42fbc5c4f904ace0d35654b7cc1937ccf53fe78505a0100000008526563525265abacffffffff01dbf4e6040000000007acac656553636500000000", "63", 2, 882302077, "f5b38b0f06e246e47ce622e5ee27d5512c509f8ac0e39651b3389815eff2ab93"], + ["ebf628b30360bab3fa4f47ce9e0dcbe9ceaf6675350e638baff0c2c197b2419f8e4fb17e16000000000452516365ac4d909a79be207c6e5fb44fbe348acc42fc7fe7ef1d0baa0e4771a3c4a6efdd7e2c118b0100000003acacacffffffffa6166e9101f03975721a3067f1636cc390d72617be72e5c3c4f73057004ee0ee010000000863636a6a516a5252c1b1e82102d8d54500000000000153324c900400000000015308384913", "0063516a51", 1, -1658428367, "eb2d8dea38e9175d4d33df41f4087c6fea038a71572e3bad1ea166353bf22184"], + ["d6a8500303f1507b1221a91adb6462fb62d741b3052e5e7684ea7cd061a5fc0b0e93549fa50100000004acab65acfffffffffdec79bf7e139c428c7cfd4b35435ae94336367c7b5e1f8e9826fcb0ebaaaea30300000000ffffffffd115fdc00713d52c35ea92805414bd57d1e59d0e6d3b79a77ee18a3228278ada020000000453005151ffffffff040231510300000000085100ac6a6a000063c6041c0400000000080000536a6563acac138a0b04000000000263abd25fbe03000000000900656a00656aac510000000000", "ac526aac6a00", 1, -2007972591, "13d12a51598b34851e7066cd93ab8c5212d60c6ed2dae09d91672c10ccd7f87c"], + ["658cb1c1049564e728291a56fa79987a4ed3146775fce078bd2e875d1a5ca83baf6166a82302000000056a656351ab2170e7d0826cbdb45fda0457ca7689745fd70541e2137bb4f52e7b432dcfe2112807bd720300000007006a0052536351ffffffff8715ca2977696abf86d433d5c920ef26974f50e9f4a20c584fecbb68e530af5101000000009e49d864155bf1d3c757186d29f3388fd89c7f55cc4d9158b4cf74ca27a35a1dd93f945502000000096a535353ac656351510d29fa870230b809040000000006ab6a6a526a633b41da050000000004ab6a6a65ed63bf62", "52acabac", 2, -1774073281, "53ab197fa7e27b8a3f99ff48305e67081eb90e95d89d7e92d80cee25a03a6689"], + ["e92492cc01aec4e62df67ea3bc645e2e3f603645b3c5b353e4ae967b562d23d6e043badecd0100000003acab65ffffffff02c7e5ea040000000002ab52e1e584010000000005536365515195d16047", "6551", 0, -424930556, "93c34627f526d73f4bea044392d1a99776b4409f7d3d835f23b03c358f5a61c2"], + ["02e242db04be2d8ced9179957e98cee395d4767966f71448dd084426844cbc6d15f2182e85030000000200650c8ffce3db9de9c3f9cdb9104c7cb26647a7531ad1ebf7591c259a9c9985503be50f8de30000000007ac6a51636a6353ffffffffa2e33e7ff06fd6469987ddf8a626853dbf30c01719efb259ae768f051f803cd30300000000fffffffffd69d8aead941683ca0b1ee235d09eade960e0b1df3cd99f850afc0af1b73e070300000001ab60bb602a011659670100000000076363526300acac00000000", "6353ab515251", 3, 1451100552, "bbc9069b8615f3a52ac8a77359098dcc6c1ba88c8372d5d5fe080b99eb781e55"], + ["b28d5f5e015a7f24d5f9e7b04a83cd07277d452e898f78b50aae45393dfb87f94a26ef57720200000008ababac630053ac52ffffffff046475ed040000000008ab5100526363ac65c9834a04000000000251abae26b30100000000040000ac65ceefb900000000000000000000", "ac6551ac6a536553", 0, -1756558188, "5848d93491044d7f21884eef7a244fe7d38886f8ae60df49ce0dfb2a342cd51a"], + ["efb8b09801f647553b91922a5874f8e4bb2ed8ddb3536ed2d2ed0698fac5e0e3a298012391030000000952ac005263ac52006affffffff04cdfa0f050000000007ac53ab51abac65b68d1b02000000000553ab65ac00d057d50000000000016a9e1fda010000000007ac63ac536552ac00000000", "6aac", 0, 1947322973, "603a9b61cd30fcea43ef0a5c18b88ca372690b971b379ee9e01909c336280511"], + ["68a59fb901c21946797e7d07a4a3ea86978ce43df0479860d7116ac514ba955460bae78fff0000000001abffffffff03979be80100000000036553639300bc040000000008006552006a656565cfa78d0000000000076552acab63ab5100000000", "ab65ab", 0, 995583673, "3b320dd47f2702452a49a1288bdc74a19a4b849b132b6cad9a1d945d87dfbb23"], + ["67761f2a014a16f3940dcb14a22ba5dc057fcffdcd2cf6150b01d516be00ef55ef7eb07a830100000004636a6a51ffffffff01af67bd050000000008526553526300510000000000", "6a00", 0, 1570943676, "079fa62e9d9d7654da8b74b065da3154f3e63c315f25751b4d896733a1d67807"], + ["e20fe96302496eb436eee98cd5a32e1c49f2a379ceb71ada8a48c5382df7c8cd88bdc47ced03000000016556aa0e180660925a841b457aed0aae47fca2a92fa1d7afeda647abf67198a3902a7c80dd00000000085152ac636a535265bd18335e01803c810100000000046500ac52f371025e", "6363ab", 1, -651254218, "2921a0e5e3ba83c57ba57c25569380c17986bf34c366ec216d4188d5ba8b0b47"], + ["4e1bd9fa011fe7aa14eee8e78f27c9fde5127f99f53d86bc67bdab23ca8901054ee8a8b6eb0300000009ac535153006a6a0063ffffffff044233670500000000000a667205000000000652ab636a51abe5bf35030000000003535351d579e505000000000700630065ab51ac3419ac30", "52abac52", 0, -1807563680, "4aae6648f856994bed252d319932d78db55da50d32b9008216d5366b44bfdf8a"], + ["ec02fbee03120d02fde12574649660c441b40d330439183430c6feb404064d4f507e704f3c0100000000ffffffffe108d99c7a4e5f75cc35c05debb615d52fac6e3240a6964a29c1704d98017fb60200000002ab63fffffffff726ec890038977adfc9dadbeaf5e486d5fcb65dc23acff0dd90b61b8e2773410000000002ac65e9dace55010f881b010000000005ac00ab650000000000", "51ac525152ac6552", 2, -1564046020, "3f988922d8cd11c7adff1a83ce9499019e5ab5f424752d8d361cf1762e04269b"], + ["23dbdcc1039c99bf11938d8e3ccec53b60c6c1d10c8eb6c31197d62c6c4e2af17f52115c3a0300000008636352000063ababffffffff17823880e1df93e63ad98c29bfac12e36efd60254346cac9d3f8ada020afc0620300000003ab63631c26f002ac66e86cd22a25e3ed3cb39d982f47c5118f03253054842daadc88a6c41a2e1500000000096a00ab636a53635163195314de015570fd0100000000096a5263acab5200005300000000", "ababac6a6553", 1, 11586329, "bd36a50e0e0a4ecbf2709e68daef41eddc1c0c9769efaee57910e99c0a1d1343"], + ["33b03bf00222c7ca35c2f8870bbdef2a543b70677e413ce50494ac9b22ea673287b6aa55c50000000005ab00006a52ee4d97b527eb0b427e4514ea4a76c81e68c34900a23838d3e57d0edb5410e62eeb8c92b6000000000553ac6aacac42e59e170326245c000000000009656553536aab516aabb1a10603000000000852ab52ab6a516500cc89c802000000000763ac6a63ac516300000000", "", 0, 557416556, "41bead1b073e1e9fee065dd612a617ca0689e8f9d3fed9d0acfa97398ebb404c"], + ["813eda1103ac8159850b4524ef65e4644e0fc30efe57a5db0c0365a30446d518d9b9aa8fdd0000000003656565c2f1e89448b374b8f12055557927d5b33339c52228f7108228149920e0b77ef0bcd69da60000000006abac00ab63ab82cdb7978d28630c5e1dc630f332c4245581f787936f0b1e84d38d33892141974c75b4750300000004ac53ab65ffffffff0137edfb02000000000000000000", "0063", 1, -1948560575, "71dfcd2eb7f2e6473aed47b16a6d5fcbd0af22813d892e9765023151e07771ec"], + ["9e45d9aa0248c16dbd7f435e8c54ae1ad086de50c7b25795a704f3d8e45e1886386c653fbf01000000025352fb4a1acefdd27747b60d1fb79b96d14fb88770c75e0da941b7803a513e6d4c908c6445c7010000000163ffffffff014069a8010000000001520a794fb3", "51ac005363", 1, -719113284, "0d31a221c69bd322ef7193dd7359ddfefec9e0a1521d4a8740326d46e44a5d6a"], + ["36e42018044652286b19a90e5dd4f8d9f361d0760d080c5c5add1970296ff0f1de630233c8010000000200ac39260c7606017d2246ee14ddb7611586178067e6a4be38e788e33f39a3a95a55a13a6775010000000352ac638bea784f7c2354ed02ea0b93f0240cdfb91796fa77649beee6f7027caa70778b091deee700000000066a65ac656363ffffffff4d9d77ab676d711267ef65363f2d192e1bd55d3cd37f2280a34c72e8b4c559d700000000056a006aab00001764e1020d30220100000000085252516aacab0053472097040000000009635353ab6a636a5100a56407a1", "006a536551ab53ab", 0, 827296034, "daec2af5622bbe220c762da77bab14dc75e7d28aa1ade9b7f100798f7f0fd97a"], + ["5e06159a02762b5f3a5edcdfc91fd88c3bff08b202e69eb5ba74743e9f4291c4059ab008200000000001ac348f5446bb069ef977f89dbe925795d59fb5d98562679bafd61f5f5f3150c3559582992d0000000008ab5165515353abac762fc67703847ec6010000000000e200cf040000000002abaca64b86010000000008520000515363acabb82b491b", "ab53525352ab6a", 0, -61819505, "75a7db0df41485a28bf6a77a37ca15fa8eccc95b5d6014a731fd8adb9ada0f12"], + ["a1948872013b543d6d902ccdeead231c585195214ccf5d39f136023855958436a43266911501000000086aac006a6a6a51514951c9b2038a538a04000000000452526563c0f345050000000007526a5252ac526af9be8e03000000000752acac51ab006306198db2", "ab6353", 0, -326384076, "ced7ef84aad4097e1eb96310e0d1c8e512cfcb392a01d9010713459b23bc0cf4"], + ["c3efabba03cb656f154d1e159aa4a1a4bf9423a50454ebcef07bc3c42a35fb8ad84014864d0000000000d1cc73d260980775650caa272e9103dc6408bdacaddada6b9c67c88ceba6abaa9caa2f7d020000000553536a5265ffffffff9f946e8176d9b11ff854b76efcca0a4c236d29b69fb645ba29d406480427438e01000000066a0065005300ffffffff040419c0010000000003ab6a63cdb5b6010000000009006300ab5352656a63f9fe5e050000000004acac5352611b980100000000086a00acac00006a512d7f0c40", "0053", 0, -59089911, "c503001c16fbff82a99a18d88fe18720af63656fccd8511bca1c3d0d69bd7fc0"], + ["efb55c2e04b21a0c25e0e29f6586be9ef09f2008389e5257ebf2f5251051cdc6a79fce2dac020000000351006affffffffaba73e5b6e6c62048ba5676d18c33ccbcb59866470bb7911ccafb2238cfd493802000000026563ffffffffe62d7cb8658a6eca8a8babeb0f1f4fa535b62f5fc0ec70eb0111174e72bbec5e0300000009abababac516365526affffffffbf568789e681032d3e3be761642f25e46c20322fa80346c1146cb47ac999cf1b0300000000b3dbd55902528828010000000001ab0aac7b0100000000015300000000", "acac52", 3, 1638140535, "e84444d91580da41c8a7dcf6d32229bb106f1be0c811b2292967ead5a96ce9d4"], + ["91d3b21903629209b877b3e1aef09cd59aca6a5a0db9b83e6b3472aceec3bc2109e64ab85a0200000003530065ffffffffca5f92de2f1b7d8478b8261eaf32e5656b9eabbc58dcb2345912e9079a33c4cd010000000700ab65ab00536ad530611da41bbd51a389788c46678a265fe85737b8d317a83a8ff7a839debd18892ae5c80300000007ab6aac65ab51008b86c501038b8a9a05000000000263525b3f7a040000000007ab535353ab00abd4e3ff04000000000665ac51ab65630b7b656f", "6551525151516a00", 2, 499657927, "ef4bd7622eb7b2bbbbdc48663c1bc90e01d5bde90ff4cb946596f781eb420a0c"], + ["5d5c41ad0317aa7e40a513f5141ad5fc6e17d3916eebee4ddb400ddab596175b41a111ead20100000005536a5265acffffffff900ecb5e355c5c9f278c2c6ea15ac1558b041738e4bffe5ae06a9346d66d5b2b00000000080000ab636a65ab6affffffff99f4e08305fa5bd8e38fb9ca18b73f7a33c61ff7b3c68e696b30a04fea87f3ca000000000163d3d1760d019fc13a00000000000000000000", "ab53acabab6aac6a52", 2, 1007461922, "4012f5ff2f1238a0eb84854074670b4703238ebc15bfcdcd47ffa8498105fcd9"], + ["ceecfa6c02b7e3345445b82226b15b7a097563fa7d15f3b0c979232b138124b62c0be007890200000009abac51536a63525253ffffffffbae481ccb4f15d94db5ec0d8854c24c1cc8642bd0c6300ede98a91ca13a4539a0200000001ac50b0813d023110f5020000000006acabac526563e2b0d0040000000009656aac0063516a536300000000", "0063526500", 0, -1862053821, "e1600e6df8a6160a79ac32aa40bb4644daa88b5f76c0d7d13bf003327223f70c"], + ["ae62d5fd0380c4083a26642159f51af24bf55dc69008e6b7769442b6a69a603edd980a33000000000005ab5100ab53ffffffff49d048324d899d4b8ed5e739d604f5806a1104fede4cb9f92cc825a7fa7b4bfe0200000005536a000053ffffffff42e5cea5673c650881d0b4005fa4550fd86de5f21509c4564a379a0b7252ac0e0000000007530000526a53525f26a68a03bfacc3010000000000e2496f000000000009ab5253acac52636563b11cc600000000000700510065526a6a00000000", "abab", 1, -1600104856, "05cf0ec9c61f1a15f651a0b3c5c221aa543553ce6c804593f43bb5c50bb91ffb"], + ["f06f64af04fdcb830464b5efdb3d5ee25869b0744005375481d7b9d7136a0eb8828ad1f0240200000003516563fffffffffd3ba192dabe9c4eb634a1e3079fca4f072ee5ceb4b57deb6ade5527053a92c5000000000165ffffffff39f43401a36ba13a5c6dd7f1190e793933ae32ee3bf3e7bfb967be51e681af760300000009650000536552636a528e34f50b21183952cad945a83d4d56294b55258183e1627d6e8fb3beb8457ec36cadb0630000000005abab530052334a7128014bbfd10100000000085352ab006a63656afc424a7c", "53650051635253ac00", 2, 313255000, "d309da5afd91b7afa257cfd62df3ca9df036b6a9f4b38f5697d1daa1f587312b"], + ["6dfd2f98046b08e7e2ef5fff153e00545faf7076699012993c7a30cb1a50ec528281a9022f030000000152ffffffff1f535e4851920b968e6c437d84d6ecf586984ebddb7d5db6ae035bd02ba222a8010000000651006a53ab51605072acb3e17939fa0737bc3ee43bc393b4acd58451fc4ffeeedc06df9fc649828822d5010000000253525a4955221715f27788d302382112cf60719be9ae159c51f394519bd5f7e70a4f9816c7020200000009526a6a51636aab656a36d3a5ff0445548e0100000000086a6a00516a52655167030b050000000004ac6a63525cfda8030000000000e158200000000000010000000000", "535263ac6a65515153", 3, 585774166, "72b7da10704c3ca7d1deb60c31b718ee12c70dc9dfb9ae3461edce50789fe2ba"], + ["187eafed01389a45e75e9dda526d3acbbd41e6414936b3356473d1f9793d161603efdb45670100000002ab00ffffffff04371c8202000000000563630063523b3bde02000000000753516563006300e9e765010000000005516aac656a373f9805000000000665525352acab08d46763", "ab", 0, 122457992, "393aa6c758e0eed15fa4af6d9e2d7c63f49057246dbb92b4268ec24fc87301ca"], + ["7d50b977035d50411d814d296da9f7965ddc56f3250961ca5ba805cadd0454e7c521e31b0300000000003d0416c2cf115a397bacf615339f0e54f6c35ffec95aa009284d38390bdde1595cc7aa7c0100000005ab52ac5365ffffffff4232c6e796544d5ac848c9dc8d25cfa74e32e847a5fc74c74d8f38ca51188562030000000653ac51006a51ffffffff016bd8bb00000000000465ab5253163526f3", "51ab526a00005353", 1, -1311316785, "60b7544319b42e4159976c35c32c2644f0adf42eff13be1dc2f726fc0b6bb492"], + ["2a45cd1001bf642a2315d4a427eddcc1e2b0209b1c6abd2db81a800c5f1af32812de42032702000000050051525200ffffffff032177db050000000005530051abac49186f000000000004ab6aab00645c0000000000000765655263acabac00000000", "6a65", 0, -1774715722, "6a9ac3f7da4c7735fbc91f728b52ecbd602233208f96ac5592656074a5db118a"], + ["479358c202427f3c8d19e2ea3def6d6d3ef2281b4a93cd76214f0c7d8f040aa042fe19f71f0300000001abffffffffa2709be556cf6ecaa5ef530df9e4d056d0ed57ce96de55a5b1f369fa40d4e74a020000000700006a51635365c426be3f02af578505000000000363ab63fd8f590500000000065153abac53632dfb14b3", "520063ab51", 1, -763226778, "cfe147982afacde044ce66008cbc5b1e9f0fd9b8ed52b59fc7c0fecf95a39b0e"], + ["76179a8e03bec40747ad65ab0f8a21bc0d125b5c3c17ad5565556d5cb03ade7c83b4f32d98030000000151ffffffff99b900504e0c02b97a65e24f3ad8435dfa54e3c368f4e654803b756d011d24150200000003ac5353617a04ac61bb6cf697cfa4726657ba35ed0031432da8c0ffb252a190278830f9bd54f0320100000006656551005153c8e8fc8803677c77020000000007ac6553535253ac70f442030000000001535be0f20200000000026300bf46cb3a", "6aab52", 1, -58495673, "35e94b3776a6729d20aa2f3ddeeb06d3aad1c14cc4cde52fd21a4efc212ea16c"], + ["75ae53c2042f7546223ce5d5f9e00a968ddc68d52e8932ef2013fa40ce4e8c6ed0b6195cde01000000056563ac630079da0452c20697382e3dba6f4fc300da5f52e95a9dca379bb792907db872ba751b8024ee0300000009655151536500005163ffffffffe091b6d43f51ff00eff0ccfbc99b72d3aff208e0f44b44dfa5e1c7322cfc0c5f01000000075200005363ab63ffffffff7e96c3b83443260ac5cfd18258574fbc4225c630d3950df812bf51dceaeb0f9103000000065365655165639a6bf70b01b3e14305000000000563530063ac00000000", "6300ab00ac", 2, 982422189, "ee4ea49d2aae0dbba05f0b9785172da54408eb1ec67d36759ff7ed25bfc28766"], + ["1cdfa01e01e1b8078e9c2b0ca5082249bd18fdb8b629ead659adedf9a0dd5a04031871ba120200000008525351536565ab6affffffff011e28430200000000076a5363636aac52b2febd4a", "abacac63656300", 0, 387396350, "299dcaac2bdaa627eba0dfd74767ee6c6f27c9200b49da8ff6270b1041669e7e"], + ["cc28c1810113dfa6f0fcd9c7d9c9a30fb6f1d774356abeb527a8651f24f4e6b25cf763c4e00300000003ab636affffffff02dfc6050000000000080053636351ab0052afd56903000000000453ab5265f6c90d99", "006551abacacac", 0, 1299280838, "a4c0773204ab418a939e23f493bd4b3e817375d133d307609e9782f2cc38dbcf"], + ["ca816e7802cd43d66b9374cd9bf99a8da09402d69c688d8dcc5283ace8f147e1672b757e020200000005516aabab5240fb06c95c922342279fcd88ba6cd915933e320d7becac03192e0941e0345b79223e89570300000004005151ac353ecb5d0264dfbd010000000005ac6aacababd5d70001000000000752ac53ac6a5151ec257f71", "63ac", 1, 774695685, "cc180c4f797c16a639962e7aec58ec4b209853d842010e4d090895b22e7a7863"], + ["b42b955303942fedd7dc77bbd9040aa0de858afa100f399d63c7f167b7986d6c2377f66a7403000000066aac00525100ffffffff0577d04b64880425a3174055f94191031ad6b4ca6f34f6da9be7c3411d8b51fc000000000300526a6391e1cf0f22e45ef1c44298523b516b3e1249df153590f592fcb5c5fc432dc66f3b57cb03000000046a6aac65ffffffff0393a6c9000000000004516a65aca674ac0400000000046a525352c82c370000000000030053538e577f89", "", 1, -1237094944, "566953eb806d40a9fb684d46c1bf8c69dea86273424d562bd407b9461c8509af"], + ["92c9fe210201e781b72554a0ed5e22507fb02434ddbaa69aff6e74ea8bad656071f1923f3f02000000056a63ac6a514470cef985ba83dcb8eee2044807bedbf0d983ae21286421506ae276142359c8c6a34d68020000000863ac63525265006aa796dd0102ca3f9d05000000000800abab52ab535353cd5c83010000000007ac00525252005322ac75ee", "5165", 0, 97879971, "6e6307cef4f3a9b386f751a6f40acebab12a0e7e17171d2989293cbec7fd45c2"], + ["ccca1d5b01e40fe2c6b3ee24c660252134601dab785b8f55bd6201ffaf2fddc7b3e2192325030000000365535100496d4703b4b66603000000000665535253ac633013240000000000015212d2a502000000000951abac636353636a5337b82426", "0052", 0, -1691630172, "577bf2b3520b40aef44899a20d37833f1cded6b167e4d648fc5abe203e43b649"], + ["bc1a7a3c01691e2d0c4266136f12e391422f93655c71831d90935fbda7e840e50770c61da20000000008635253abac516353ffffffff031f32aa020000000003636563786dbc0200000000003e950f00000000000563516a655184b8a1de", "51536a", 0, -1627072905, "730bc25699b46703d7718fd5f5c34c4b5f00f594a9968ddc247fa7d5175124ed"], + ["076d209e02d904a6c40713c7225d23e7c25d4133c3c3477828f98c7d6dbd68744023dbb66b030000000753ab00536565acffffffff10975f1b8db8861ca94c8cc7c7cff086ddcd83e10b5fffd4fc8f2bdb03f9463c0100000000ffffffff029dff76010000000006526365530051a3be6004000000000000000000", "515253ac65acacac", 1, -1207502445, "66c488603b2bc53f0d22994a1f0f66fb2958203102eba30fe1d37b27a55de7a5"], + ["690fd1f80476db1f9eebe91317f2f130a60cbc1f4feadd9d6474d438e9cb7f91e4994600af0300000004ab536a63a15ce9fa6622d0c4171d895b42bff884dc6e8a7452f827fdc68a29c3c88e6fdee364eaf50000000002ab52ffffffff022dc39d3c0956b24d7f410b1e387859e7a72955f45d6ffb1e884d77888d18fe0300000005ac6a63656afffffffff10b06bce1800f5c49153d24748fdefb0bf514c12863247d1042d56018c3e25c03000000086a63ac6365536a52ffffffff031f162f0500000000060000655265abffbcd40500000000045151ac001a9c8c05000000000652ac53656a6300000000", "ac51ab63acac", 0, -67986012, "051c0df7ac688c2c930808dabde1f50300aea115f2bb3334f4753d5169b51e46"], + ["49ac2af00216c0307a29e83aa5de19770e6b20845de329290bd69cf0e0db7aed61ae41b39002000000035163ac8b2558ef84635bfc59635150e90b61fc753d34acfd10d97531043053e229cd720133cd95000000000463516a51ffffffff02458471040000000008abab636a51ac0065545aa80000000000096a6553516a5263ac6a00000000", "51526300ab5363", 1, 1449668540, "ddfd902bba312a06197810da96a0ddccb595f96670b28ded7dba88d8cd0469b8"], + ["fa4d868b024b010bd5dce46576c2fb489aa60bb797dac3c72a4836f49812c5c564c258414f03000000007a9b3a585e05027bdd89edbadf3c85ac61f8c3a04c773fa746517ae600ff1a9d6b6c02fb0200000004515163abffffffff01b17d020500000000046a65520000000000", "536565ab65635363", 0, -1718953372, "96c2b32f0a00a5925db7ba72d0b5d39922f30ea0f7443b22bc1b734808513c47"], + ["cac6382d0462375e83b67c7a86c922b569a7473bfced67f17afd96c3cd2d896cf113febf9e0300000003006a53ffffffffaa4913b7eae6821487dd3ca43a514e94dcbbf350f8cc4cafff9c1a88720711b800000000096a6a525300acac6353ffffffff184fc4109c34ea27014cc2c1536ef7ed1821951797a7141ddacdd6e429fae6ff01000000055251655200ffffffff9e7b79b4e6836e290d7b489ead931cba65d1030ccc06f20bd4ca46a40195b33c030000000008f6bc8304a09a2704000000000563655353511dbc73050000000000cf34c500000000000091f76e0000000000085200ab00005100abd07208cb", "0063656a", 2, -1488731031, "bf078519fa87b79f40abc38f1831731422722c59f88d86775535f209cb41b9b1"], + ["1711146502c1a0b82eaa7893976fefe0fb758c3f0e560447cef6e1bde11e42de91a125f71c030000000015bd8c04703b4030496c7461482481f290c623be3e76ad23d57a955807c9e851aaaa20270300000000d04abaf20326dcb7030000000001632225350400000000075263ac00520063dddad9020000000000af23d148", "52520053510063", 0, 1852122830, "e33d5ee08c0f3c130a44d7ce29606450271b676f4a80c52ab9ffab00cecf67f8"], + ["8d5b124d0231fbfc640c706ddb1d57bb49a18ba8ca0e1101e32c7e6e65a0d4c7971d93ea360100000008acabac0000abac65ffffffff8fe0fd7696597b845c079c3e7b87d4a44110c445a330d70342a5501955e17dd70100000004ab525363ef22e8a90346629f030000000009516a00ac63acac51657bd57b05000000000200acfd4288050000000009acab5352ab00ab636300000000", "53ac526553ab65", 0, 1253152975, "8b57a7c3170c6c02dd14ae1d392ce3d828197b20e9145c89c1cfd5de050e1562"], + ["38146dc502c7430e92b6708e9e107b61cd38e5e773d9395e5c8ad8986e7e4c03ee1c1e1e760100000000c8962ce2ac1bb3b1285c0b9ba07f4d2e5ce87c738c42ac0548cd8cec1100e6928cd6b0b6010000000763ab636aab52527cccefbd04e5f6f8020000000006006aabacac65ab2c4a00000000000351635209a6f40100000000026aacce57dc040000000008ab5353ab516a516a00000000", "ab", 0, -1205978252, "3cb5b030e7da0b60ccce5b4a7f3793e6ca56f03e3799fe2d6c3cc22d6d841dcb"], + ["22d81c740469695a6a83a9a4824f77ecff8804d020df23713990afce2b72591ed7de98500502000000065352526a6a6affffffff90dc85e118379b1005d7bbc7d2b8b0bab104dad7eaa49ff5bead892f17d8c3ba010000000665656300ab51ffffffff965193879e1d5628b52005d8560a35a2ba57a7f19201a4045b7cbab85133311d0200000003ac005348af21a13f9b4e0ad90ed20bf84e4740c8a9d7129632590349afc03799414b76fd6e826200000000025353ffffffff04a0d40d04000000000060702700000000000652655151516ad31f1502000000000365ac0069a1ac0500000000095100655300ab53525100000000", "51636a52ac", 0, -1644680765, "add7f5da27262f13da6a1e2cc2feafdc809bd66a67fb8ae2a6f5e6be95373b6f"], + ["a27dcbc801e3475174a183586082e0914c314bc9d79d1570f29b54591e5e0dff07fbb45a7f0000000004ac53ab51ffffffff027347f5020000000005535351ab63d0e5c9030000000009ac65ab6a63515200ab7cd632ed", "ac63636553", 0, -686435306, "883a6ea3b2cc53fe8a803c229106366ca14d25ffbab9fef8367340f65b201da6"], + ["b123ed2204410d4e8aaaa8cdb95234ca86dad9ff77fb4ae0fd4c06ebed36794f0215ede0040100000002ac63ffffffff3b58b81b19b90d8f402701389b238c3a84ff9ba9aeea298bbf15b41a6766d27a01000000056a6553ab00151824d401786153b819831fb15926ff1944ea7b03d884935a8bde01ed069d5fd80220310200000000ffffffffa9c9d246f1eb8b7b382a9032b55567e9a93f86c77f4e32c092aa1738f7f756c30100000002ab65ffffffff011a2b48000000000000ed44d1fb", "630051ab63", 2, -1118263883, "b5dab912bcabedff5f63f6dd395fc2cf030d83eb4dd28214baba68a45b4bfff0"], + ["1339051503e196f730955c5a39acd6ed28dec89b4dadc3f7c79b203b344511270e5747fa9900000000045151636affffffff378c6090e08a3895cedf1d25453bbe955a274657172491fd2887ed5c9aceca7b0100000000ffffffffcf7cc3c36ddf9d4749edfa9cefed496d2f86e870deb814bfcd3b5637a5496461030000000451006300ffffffff04dcf3fa010000000008526a63005263acabb41d84040000000004abac5153800eff020000000005656a535365106c5e00000000000000000000", "abac5300", 2, 2013719928, "7fc74de39ce6ca46ca25d760d3cec7bb21fd14f7efe1c443b5aa294f2cb5f546"], + ["0728c606014c1fd6005ccf878196ba71a54e86cc8c53d6db500c3cc0ac369a26fac6fcbc210000000005ab53ac5365ba9668290182d7870100000000066a000053655100000000", "65", 0, 1789961588, "ab6baa6da3b2bc853868d166f8996ad31d63ef981179f9104f49968fd61c8427"], + ["a1134397034bf4067b6c81c581e2b73fb63835a08819ba24e4e92df73074bf773c94577df7000000000465525251ffffffff8b6608feaa3c1f35f49c6330a769716fa01c5c6f6e0cdc2eb10dfc99bbc21e77010000000952656aac005352655180a0bda4bc72002c2ea8262e26e03391536ec36867258cab968a6fd6ec7523b64fa1d8c001000000056a53ac6353ffffffff04dbeeed05000000000553650052abcd5d0e01000000000463abab51104b2e0500000000066aac53ac5165283ca7010000000004535252ab00000000", "ab515151516552ab", 1, -324598676, "91178482112f94d1c8e929de443e4b9c893e18682998d393ca9ca77950412586"], + ["bcdafbae04aa18eb75855aeb1f5124f30044741351b33794254a80070940cb10552fa4fa8e0300000001acd0423fe6e3f3f88ae606f2e8cfab7a5ef87caa2a8f0401765ff9a47d718afcfb40c0099b0000000008ac6565ab53ac6aac645308009d680202d600e492b31ee0ab77c7c5883ebad5065f1ce87e4dfe6453e54023a0010000000151ffffffffb9d818b14245899e1d440152827c95268a676f14c3389fc47f5a11a7b38b1bde03000000026300ffffffff03cda22102000000000751ac535263005100a4d20400000000045200536ac8bef405000000000700ab51ab6563ac00000000", "6553516a526aab", 1, -2111409753, "5e1849e7368cf4f042718586d9bd831d61479b775bab97aba9f450042bd9876a"], + ["ed3bb93802ddbd08cb030ef60a2247f715a0226de390c9c1a81d52e83f8674879065b5f87d0300000003ab6552ffffffff04d2c5e60a21fb6da8de20bf206db43b720e2a24ce26779bca25584c3f765d1e0200000008ab656a6aacab00ab6e946ded025a811d04000000000951abac6352ac00ab5143cfa3030000000005635200636a00000000", "5352ac650065535300", 1, -668727133, "e9995065e1fddef72a796eef5274de62012249660dc9d233a4f24e02a2979c87"], + ["59f4629d030fa5d115c33e8d55a79ea3cba8c209821f979ed0e285299a9c72a73c5bba00150200000002636affffffffd8aca2176df3f7a96d0dc4ee3d24e6cecde1582323eec2ebef9a11f8162f17ac0000000007ab6565acab6553ffffffffeebc10af4f99c7a21cbc1d1074bd9f0ee032482a71800f44f26ee67491208e0403000000065352ac656351ffffffff0434e955040000000004ab515152caf2b305000000000365ac007b1473030000000003ab530033da970500000000060051536a5253bb08ab51", "", 2, 396340944, "0e9c47973ef2c292b2252c623f465bbb92046fe0b893eebf4e1c9e02cb01c397"], + ["286e3eb7043902bae5173ac3b39b44c5950bc363f474386a50b98c7bdab26f98dc83449c4a020000000752ac6a00510051ffffffff4339cd6a07f5a5a2cb5815e5845da70300f5c7833788363bf7fe67595d3225520100000000fffffffff9c2dd8b06ad910365ffdee1a966f124378a2b8021065c8764f6138bb1e951380200000005ab5153ac6affffffff0370202aba7a68df85436ea7c945139513384ef391fa33d16020420b8ad40e9a000000000900ab5165526353abacffffffff020c1907000000000004abac526a1b490b040000000000df1528f7", "5353ab", 3, -1407529517, "32154c09174a9906183abf26538c39e78468344ca0848bbd0785e24a3565d932"], + ["2e245cf80179e2e95cd1b34995c2aff49fe4519cd7cee93ad7587f7f7e8105fc2dff206cd30200000009006a63516a6553ab52350435a201d5ed2d02000000000352ab6558552c89", "00ab53", 0, -233917810, "4605ae5fd3d50f9c45d37db7118a81a9ef6eb475d2333f59df5d3e216f150d49"], + ["33a98004029d262f951881b20a8d746c8c707ea802cd2c8b02a33b7e907c58699f97e42be80100000007ac53536552abacdee04cc01d205fd8a3687fdf265b064d42ab38046d76c736aad8865ca210824b7c622ecf02000000070065006a536a6affffffff01431c5d010000000000270d48ee", "", 1, 921554116, "ff9d7394002f3f196ea25472ea6c46f753bd879a7244795157bb7235c9322902"], + ["aac18f2b02b144ed481557c53f2146ae523f24fcde40f3445ab0193b6b276c315dc2894d2300000000075165650000636a233526947dbffc76aec7db1e1baa6868ad4799c76e14794dcbaaec9e713a83967f6a65170200000005abac6551ab27d518be01b652a30000000000015300000000", "52ac5353", 1, 1559377136, "59fc2959bb7bb24576cc8a237961ed95bbb900679d94da6567734c4390cb6ef5"], + ["5ab79881033555b65fe58c928883f70ce7057426fbdd5c67d7260da0fe8b1b9e6a2674cb850300000009ac516aac6aac006a6affffffffa5be9223b43c2b1a4d120b5c5b6ec0484f637952a3252181d0f8e813e76e11580200000000e4b5ceb8118cb77215bbeedc9a076a4d087bb9cd1473ea32368b71daeeeacc451ec209010000000005acac5153aced7dc34e02bc5d11030000000005ac5363006a54185803000000000552ab00636a00000000", "5100", 1, 1927062711, "e9f53d531c12cce1c50abed4ac521a372b4449b6a12f9327c80020df6bff66c0"], + ["6c2c8fac0124b0b7d4b610c3c5b91dee32b7c927ac71abdf2d008990ca1ac40de0dfd530660300000006ababac5253656bd7eada01d847ec000000000004ac52006af4232ec8", "6a6a6a0051", 0, -340809707, "fb51eb9d7e47d32ff2086205214f90c7c139e08c257a64829ae4d2b301071c6a"], + ["6e3880af031735a0059c0bb5180574a7dcc88e522c8b56746d130f8d45a52184045f96793e0100000008acabac6a526a6553fffffffffe05f14cdef7d12a9169ec0fd37524b5fcd3295f73f48ca35a36e671da4a2f560000000008006a526a6351ab63ffffffffdfbd869ac9e472640a84caf28bdd82e8c6797f42d03b99817a705a24fde2736600000000010090a090a503db956b04000000000952ac53ab6a536a63ab358390010000000009656a5200525153ac65353ee204000000000763530052526aaba6ad83fb", "535151ab6300", 2, 222014018, "57a34ddeb1bf36d28c7294dda0432e9228a9c9e5cc5c692db98b6ed2e218d825"], + ["8df1cd19027db4240718dcaf70cdee33b26ea3dece49ae6917331a028c85c5a1fb7ee3e475020000000865ab6a00510063636157988bc84d8d55a8ba93cdea001b9bf9d0fa65b5db42be6084b5b1e1556f3602f65d4d0100000005ac00ab0052206c852902b2fb54030000000008ac5252536aacac5378c4a5050000000007acabac535163532784439e", "acab6a", 0, 1105620132, "edb7c74223d1f10f9b3b9c1db8064bc487321ff7bb346f287c6bc2fad83682de"], + ["0e803682024f79337b25c98f276d412bc27e56a300aa422c42994004790cee213008ff1b8303000000080051ac65ac655165f421a331892b19a44c9f88413d057fea03c3c4a6c7de4911fe6fe79cf2e9b3b10184b1910200000005525163630096cb1c670398277204000000000253acf7d5d502000000000963536a6a636a5363ab381092020000000002ac6a911ccf32", "6565", 1, -1492094009, "f0672638a0e568a919e9d8a9cbd7c0189a3e132940beeb52f111a89dcc2daa2c"], + ["7d71669d03022f9dd90edac323cde9e56354c6804c6b8e687e9ae699f46805aafb8bcaa636000000000253abffffffff698a5fdd3d7f2b8b000c68333e4dd58fa8045b3e2f689b889beeb3156cecdb490300000009525353abab0051acabc53f0aa821cdd69b473ec6e6cf45cf9b38996e1c8f52c27878a01ec8bb02e8cb31ad24e500000000055353ab0052ffffffff0447a23401000000000565ab53ab5133aaa0030000000006515163656563057d110300000000056a6aacac52cf13b5000000000003526a5100000000", "6a6a51", 1, -1349253507, "722efdd69a7d51d3d77bed0ac5544502da67e475ea5857cd5af6bdf640a69945"], + ["9ff618e60136f8e6bb7eabaaac7d6e2535f5fba95854be6d2726f986eaa9537cb283c701ff02000000026a65ffffffff012d1c0905000000000865ab00ac6a516a652f9ad240", "51515253635351ac", 0, 1571304387, "659cd3203095d4a8672646add7d77831a1926fc5b66128801979939383695a79"], + ["9fbd43ac025e1462ecd10b1a9182a8e0c542f6d1089322a41822ab94361e214ed7e1dfdd8a020000000263519d0437581538e8e0b6aea765beff5b4f3a4a202fca6e5d19b34c141078c6688f71ba5b8e0100000003ac6552ffffffff02077774050000000009655153655263acab6a0ae4e10100000000035152524c97136b", "635152ab", 0, 1969622955, "d82d4ccd9b67810f26a378ad9592eb7a30935cbbd27e859b00981aefd0a72e08"], + ["0117c92004314b84ed228fc11e2999e657f953b6de3b233331b5f0d0cf40d5cc149b93c7b30300000005515263516a083e8af1bd540e54bf5b309d36ba80ed361d77bbf4a1805c7aa73667ad9df4f97e2da410020000000600ab6351ab524d04f2179455e794b2fcb3d214670001c885f0802e4b5e015ed13a917514a7618f5f332203000000086a536aab51000063ecf029e65a4a009a5d67796c9f1eb358b0d4bd2620c8ad7330fb98f5a802ab92d0038b1002000000036a6551a184a88804b04490000000000009ab6a5152535165526a33d1ab020000000001518e92320000000000002913df04000000000952abac6353525353ac8b19bfdf", "000051ab0000", 0, 489433059, "8eebac87e60da524bbccaf285a44043e2c9232868dda6c6271a53c153e7f3a55"], + ["e7f5482903f98f0299e0984b361efb2fddcd9979869102281e705d3001a9d283fe9f3f3a1e02000000025365ffffffffcc5c7fe82feebad32a22715fc30bc584efc9cd9cadd57e5bc4b6a265547e676e0000000001ab579d21235bc2281e08bf5e7f8f64d3afb552839b9aa5c77cf762ba2366fffd7ebb74e49400000000055263ab63633df82cf40100982e05000000000453ac535300000000", "acacab", 2, -1362931214, "046de666545330e50d53083eb78c9336416902f9b96c77cc8d8e543da6dfc7e4"], + ["09adb2e90175ca0e816326ae2dce7750c1b27941b16f6278023dbc294632ab97977852a09d030000000465ab006affffffff027739cf0100000000075151ab63ac65ab8a5bb601000000000653ac5151520011313cdc", "ac", 0, -76831756, "478ee06501b4965b40bdba6cbaad9b779b38555a970912bb791b86b7191c54bc"], + ["f973867602e30f857855cd0364b5bbb894c049f44abbfd661d7ae5dbfeaafca89fac8959c20100000005ab52536a51ffffffffbeceb68a4715f99ba50e131884d8d20f4a179313691150adf0ebf29d05f8770303000000066352ab00ac63ffffffff021fddb90000000000036a656322a177000000000008526500ac5100acac84839083", "52acab53ac", 0, 1407879325, "db0329439490efc64b7104d6d009b03fbc6fac597cf54fd786fbbb5fd73b92b4"], + ["fd22ebaa03bd588ad16795bea7d4aa7f7d48df163d75ea3afebe7017ce2f350f6a0c1cb0bb00000000086aabac5153526363ffffffff488e0bb22e26a565d77ba07178d17d8f85702630ee665ec35d152fa05af3bda10200000004515163abffffffffeb21035849e85ad84b2805e1069a91bb36c425dc9c212d9bae50a95b6bfde1200300000001ab5df262fd02b69848040000000008ab6363636a6363ace23bf2010000000007655263635253534348c1da", "006353526563516a00", 0, -1491036196, "92364ba3c7a85d4e88885b8cb9b520dd81fc29e9d2b750d0790690e9c1246673"], + ["130b462d01dd49fac019dc4442d0fb54eaa6b1c2d1ad0197590b7df26969a67abd7f3fbb4f0100000008ac65abac53ab6563ffffffff0345f825000000000004ac53acac9d5816020000000002ababeff8e90500000000086aab006552ac6a53a892dc55", "ab0065ac530052", 0, 944483412, "1f4209fd4ce7f13d175fdd522474ae9b34776fe11a5f17a27d0796c77a2a7a9d"], + ["f8e50c2604609be2a95f6d0f31553081f4e1a49a0a30777fe51eb1c596c1a9a92c053cf28c0300000009656a51ac5252630052fffffffff792ed0132ae2bd2f11d4a2aab9d0c4fbdf9a66d9ae2dc4108afccdc14d2b1700100000007ab6a6563ac636a7bfb2fa116122b539dd6a2ab089f88f3bc5923e5050c8262c112ff9ce0a3cd51c6e3e84f02000000066551ac5352650d5e687ddf4cc9a497087cabecf74d236aa4fc3081c3f67b6d323cba795e10e7a171b725000000000852635351ab635100ffffffff02df5409020000000008ac6a53acab5151004156990200000000045163655200000000", "ac53abac65005300", 0, -173065000, "b596f206d7eba22b7e2d1b7a4f4cf69c7c541b6c84dcc943f84e19a99a923310"], + ["18020dd1017f149eec65b2ec23300d8df0a7dd64fc8558b36907723c03cd1ba672bbb0f51d0300000005ab65ab6a63ffffffff037cd7ae000000000009ab516a65005352ac65f1e4360400000000056353530053f118f0040000000009536363ab006500abac00000000", "63ab51acab52ac", 0, -550412404, "e19b796c14a0373674968e342f2741d8b51092a5f8409e9bff7dcd52e56fcbcb"], + ["b04154610363fdade55ceb6942d5e5a723323863b48a0cb04fdcf56210717955763f56b08d0300000009ac526a525151635151ffffffff93a176e76151a9eabdd7af00ef2af72f9e7af5ecb0aa4d45d00618f394cdd03c030000000074d818b332ebe05dc24c44d776cf9d275c61f471cc01efce12fd5a16464157f1842c65cb00000000066a0000ac6352d3c4134f01d8a1c0030000000005520000005200000000", "5200656a656351", 2, -9757957, "6e3e5ba77f760b6b5b5557b13043f1262418f3dd2ce7f0298b012811fc8ad5bc"], + ["9794b3ce033df7b1e32db62d2f0906b589eacdacf5743963dc2255b6b9a6cba211fadd0d41020000000600ab00650065ffffffffaae00687a6a4131152bbcaafedfaed461c86754b0bde39e2bef720e6d1860a0302000000070065516aac6552ffffffff50e4ef784d6230df7486e972e8918d919f005025bc2d9aacba130f58bed7056703000000075265ab52656a52ffffffff02c6f1a9000000000006005251006363cf450c040000000008abab63510053abac00000000", "ac0063ababab515353", 1, 2063905082, "fad092fc98f17c2c20e10ba9a8eb44cc2bcc964b006f4da45cb9ceb249c69698"], + ["94533db7015e70e8df715066efa69dbb9c3a42ff733367c18c22ff070392f988f3b93920820000000006535363636300ce4dac3e03169af80300000000080065ac6a53ac65ac39c050020000000006abacab6aacac708a02050000000005ac5251520000000000", "6553", 0, -360458507, "5418cf059b5f15774836edd93571e0eed3855ba67b2b08c99dccab69dc87d3e9"], + ["c8597ada04f59836f06c224a2640b79f3a8a7b41ef3efa2602592ddda38e7597da6c639fee0300000009005251635351acabacffffffff4c518f347ee694884b9d4072c9e916b1a1f0a7fc74a1c90c63fdf8e5a185b6ae02000000007113af55afb41af7518ea6146786c7c726641c68c8829a52925e8d4afd07d8945f68e7230300000008ab00ab65ab650063ffffffffc28e46d7598312c420e11dfaae12add68b4d85adb182ae5b28f8340185394b63000000000165ffffffff04dbabb7010000000000ee2f6000000000000852ab6500ab6a51acb62a27000000000009ac53515300ac006a6345fb7505000000000752516a0051636a00000000", "", 3, 15199787, "0d66003aff5bf78cf492ecbc8fd40c92891acd58d0a271be9062e035897f317e"], + ["1a28c4f702c8efaad96d879b38ec65c5283b5c084b819ad7db1c086e85e32446c7818dc7a90300000008656351536a525165fa78cef86c982f1aac9c5eb8b707aee8366f74574c8f42ef240599c955ef4401cf578be30200000002ab518893292204c430eb0100000000016503138a0300000000040053abac60e0eb010000000005525200ab63567c2d030000000004abab52006cf81e85", "ab51525152", 1, 2118315905, "4e4c9a781f626b59b1d3ad8f2c488eb6dee8bb19b9bc138bf0dc33e7799210d4"], + ["c6c7a87003f772bcae9f3a0ac5e499000b68703e1804b9ddc3e73099663564d53ddc4e1c6e01000000076a536a6aac63636e3102122f4c30056ef8711a6bf11f641ddfa6984c25ac38c3b3e286e74e839198a80a34010000000165867195cd425821dfa2f279cb1390029834c06f018b1e6af73823c867bf3a0524d1d6923b0300000005acab53ab65ffffffff02fa4c49010000000008ab656a0052650053e001100400000000008836d972", "ac526351acab", 1, 978122815, "a869c18a0edf563d6e5eddd5d5ae8686f41d07f394f95c9feb8b7e52761531ca"], + ["0ea580ac04c9495ab6af3b8d59108bb4194fcb9af90b3511c83f7bb046d87aedbf8423218e02000000085152acac006363ab9063d7dc25704e0caa5edde1c6f2dd137ded379ff597e055b2977b9c559b07a7134fcef2000000000200aca89e50181f86e9854ae3b453f239e2847cf67300fff802707c8e3867ae421df69274449402000000056365abababffffffff47a4760c881a4d7e51c69b69977707bd2fb3bcdc300f0efc61f5840e1ac72cee0000000000ffffffff0460179a020000000004ab53ab52a5250c0500000000096565acac6365ab52ab6c281e02000000000952635100ac006563654e55070400000000046552526500000000", "ab526563acac53ab", 2, 1426964167, "b1c50d58b753e8f6c7513752158e9802cf0a729ebe432b99acc0fe5d9b4e9980"], + ["c33028b301d5093e1e8397270d75a0b009b2a6509a01861061ab022ca122a6ba935b8513320200000000ffffffff013bcf5a0500000000015200000000", "", 0, -513413204, "6b1459536f51482f5dbf42d7e561896557461e1e3b6bf67871e2b51faae2832c"], + ["43b2727901a7dd06dd2abf690a1ccedc0b0739cb551200796669d9a25f24f71d8d101379f50300000000ffffffff0418e031040000000000863d770000000000085352ac526563ac5174929e040000000004ac65ac00ec31ac0100000000066a51ababab5300000000", "65", 0, -492874289, "154ff7a9f0875edcfb9f8657a0b98dd9600fabee3c43eb88af37cf99286d516c"], + ["4763ed4401c3e6ab204bed280528e84d5288f9cac5fb8a2e7bd699c7b98d4df4ac0c40e55303000000066a6aacab5165ffffffff015b57f80400000000046a63535100000000", "ac51abab53", 0, -592611747, "849033a2321b5755e56ef4527ae6f51e30e3bca50149d5707368479723d744f8"], + ["d24f647b02f71708a880e6819a1dc929c1a50b16447e158f8ff62f9ccd644e0ca3c592593702000000050053536a00ffffffff67868cd5414b6ca792030b18d649de5450a456407242b296d936bcf3db79e07b02000000005af6319c016022f50100000000036a516300000000", "6aab526353516a6a", 0, 1350782301, "8556fe52d1d0782361dc28baaf8774b13f3ce5ed486ae0f124b665111e08e3e3"], + ["fe6ddf3a02657e42a7496ef170b4a8caf245b925b91c7840fd28e4a22c03cb459cb498b8d603000000065263656a650071ce6bf8d905106f9f1faf6488164f3decac65bf3c5afe1dcee20e6bc3cb6d052561985a030000000163295b117601343dbb0000000000026563dba521df", "", 1, -1696179931, "d9684685c99ce48f398fb467a91a1a59629a850c429046fb3071f1fa9a5fe816"], + ["c61523ef0129bb3952533cbf22ed797fa2088f307837dd0be1849f20decf709cf98c6f032f03000000026563c0f1d378044338310400000000066363516a5165a14fcb0400000000095163536a6a00ab53657271d60200000000001d953f0500000000010000000000", "53516353005153", 0, 1141615707, "7e975a72db5adaa3c48d525d9c28ac11cf116d0f8b16ce08f735ad75a80aec66"], + ["ba3dac6c0182562b0a26d475fe1e36315f0913b6869bdad0ecf21f1339a5fcbccd32056c840200000000ffffffff04300351050000000000220ed405000000000851abac636565ac53dbbd19020000000007636363ac6a52acbb005a0500000000016abd0c78a8", "63006a635151005352", 0, 1359658828, "47bc8ab070273e1f4a0789c37b45569a6e16f3f3092d1ce94dddc3c34a28f9f4"], + ["ac27e7f5025fc877d1d99f7fc18dd4cadbafa50e34e1676748cc89c202f93abf36ed46362101000000036300abffffffff958cd5381962b765e14d87fc9524d751e4752dd66471f973ed38b9d562e525620100000003006500ffffffff02b67120050000000004ac51516adc330c0300000000015200000000", "656352", 1, 15049991, "f3374253d64ac264055bdbcc32e27426416bd595b7c7915936c70f839e504010"], + ["edb30140029182b80c8c3255b888f7c7f061c4174d1db45879dca98c9aab8c8fed647a6ffc03000000086a53510052ab6300ffffffff82f65f261db62d517362c886c429c8fbbea250bcaad93356be6f86ba573e9d930100000000ffffffff04daaf150400000000016a86d1300100000000096a6353535252ac5165d4ddaf000000000002abab5f1c6201000000000000000000", "ab6a6a00ac", 0, -2058017816, "8d7794703dad18e2e40d83f3e65269834bb293e2d2b8525932d6921884b8f368"], + ["7e50207303146d1f7ad62843ae8017737a698498d4b9118c7a89bb02e8370307fa4fada41d000000000753006300005152b7afefc85674b1104ba33ef2bf37c6ed26316badbc0b4aa6cb8b00722da4f82ff3555a6c020000000900ac656363ac51ac52ffffffff93fab89973bd322c5d7ad7e2b929315453e5f7ada3072a36d8e33ca8bebee6e0020000000300acab930da52b04384b04000000000004650052ac435e380200000000076a6a515263ab6aa9494705000000000600ab6a525252af8ba90100000000096565acab526353536a279b17ad", "acac005263536aac63", 1, -34754133, "4e6357da0057fb7ff79da2cc0f20c5df27ff8b2f8af4c1709e6530459f7972b0"], + ["c05764f40244fb4ebe4c54f2c5298c7c798aa90e62c29709acca0b4c2c6ec08430b26167440100000008acab6a6565005253ffffffffc02c2418f398318e7f34a3cf669d034eef2111ea95b9f0978b01493293293a870100000000e563e2e00238ee8d040000000002acab03fb060200000000076500ac656a516aa37f5534", "52ab6a0065", 1, -2033176648, "83deef4a698b62a79d4877dd9afebc3011a5275dbe06e89567e9ef84e8a4ee19"], + ["5a59e0b9040654a3596d6dab8146462363cd6549898c26e2476b1f6ae42915f73fd9aedfda00000000036363abffffffff9ac9e9ca90be0187be2214251ff08ba118e6bf5e2fd1ba55229d24e50a510d53010000000165ffffffff41d42d799ac4104644969937522873c0834cc2fcdab7cdbecd84d213c0e96fd60000000000ffffffffd838db2c1a4f30e2eaa7876ef778470f8729fcf258ad228b388df2488709f8410300000000fdf2ace002ceb6d903000000000265654c1310040000000003ac00657e91c0ec", "536a63ac", 0, 82144555, "98ccde2dc14d14f5d8b1eeea5364bd18fc84560fec2fcea8de4d88b49c00695e"], + ["156ebc8202065d0b114984ee98c097600c75c859bfee13af75dc93f57c313a877efb09f230010000000463536a51ffffffff81114e8a697be3ead948b43b5005770dd87ffb1d5ccd4089fa6c8b33d3029e9c03000000066a5251656351ffffffff01a87f140000000000050000ac51ac00000000", "00", 0, -362221092, "a903c84d8c5e71134d1ab6dc1e21ac307c4c1a32c90c90f556f257b8a0ec1bf5"], + ["15e37793023c7cbf46e073428908fce0331e49550f2a42b92468827852693f0532a01c29f70200000007005353636351acffffffff38426d9cec036f00eb56ec1dcd193647e56a7577278417b8a86a78ac53199bc403000000056353006a53ffffffff04a25ce103000000000900ab5365656a526a63c8eff7030000000004526353537ab6db0200000000016a11a3fa02000000000651acacab526500000000", "53ac6aab6a6551", 0, 1117532791, "83c68b3c5a89260ce16ce8b4dbf02e1f573c532d9a72f5ea57ab419fa2630214"], + ["f7a09f10027250fc1b70398fb5c6bffd2be9718d3da727e841a73596fdd63810c9e4520a6a010000000963ac516a636a65acac1d2e2c57ab28d311edc4f858c1663972eebc3bbc93ed774801227fda65020a7ec1965f780200000005ac5252516a8299fddc01dcbf7200000000000463ac6551960fda03", "65acab51", 1, 2017321737, "9c5fa02abfd34d0f9dec32bf3edb1089fca70016debdb41f4f54affcb13a2a2a"], + ["6d97a9a5029220e04f4ccc342d8394c751282c328bf1c132167fc05551d4ca4da4795f6d4e02000000076a0052ab525165ffffffff9516a205e555fa2a16b73e6db6c223a9e759a7e09c9a149a8f376c0a7233fa1b0100000007acab51ab63ac6affffffff04868aed04000000000652ac65ac536a396edf01000000000044386c0000000000076aab5363655200894d48010000000001ab8ebefc23", "6351526aac51", 1, 1943666485, "f0bd4ca8e97203b9b4e86bc24bdc8a1a726db5e99b91000a14519dc83fc55c29"], + ["8e3fddfb028d9e566dfdda251cd874cd3ce72e9dde837f95343e90bd2a93fe21c5daeb5eed01000000045151525140517dc818181f1e7564b8b1013fd68a2f9a56bd89469686367a0e72c06be435cf99db750000000003635251ffffffff01c051780300000000096552ababac6a65acab099766eb", "5163ab6a52ababab51", 1, 1296295812, "5509eba029cc11d7dd2808b8c9eb47a19022b8d8b7778893459bbc19ab7ea820"], + ["a603f37b02a35e5f25aae73d0adc0b4b479e68a734cf722723fd4e0267a26644c36faefdab0200000000ffffffff43374ad26838bf733f8302585b0f9c22e5b8179888030de9bdda180160d770650200000001004c7309ce01379099040000000005526552536500000000", "abababab005153", 0, 1409936559, "4ca73da4fcd5f1b10da07998706ffe16408aa5dff7cec40b52081a6514e3827e"], + ["9eeedaa8034471a3a0e3165620d1743237986f060c4434f095c226114dcb4b4ec78274729f03000000086a5365510052ac6afb505af3736e347e3f299a58b1b968fce0d78f7457f4eab69240cbc40872fd61b5bf8b120200000002ac52df8247cf979b95a4c97ecb8edf26b3833f967020cd2fb25146a70e60f82c9ee4b14e88b103000000008459e2fa0125cbcd05000000000000000000", "52ab5352006353516a", 0, -1832576682, "fb018ae54206fdd20c83ae5873ec82b8e320a27ed0d0662db09cda8a071f9852"], + ["05921d7c048cf26f76c1219d0237c226454c2a713c18bf152acc83c8b0647a94b13477c07f0300000003ac526afffffffff2f494453afa0cabffd1ba0a626c56f90681087a5c1bd81d6adeb89184b27b7402000000036a6352ffffffff0ad10e2d3ce355481d1b215030820da411d3f571c3f15e8daf22fe15342fed04000000000095f29f7b93ff814a9836f54dc6852ec414e9c4e16a506636715f569151559100ccfec1d100000000055263656a53ffffffff04f4ffef010000000008ac6a6aabacabab6a0e6689040000000006ab536a5352abe364d005000000000965536363655251ab53807e00010000000004526aab63f18003e3", "6363ac51", 3, -375891099, "001b0b176f0451dfe2d9787b42097ceb62c70d324e925ead4c58b09eebdf7f67"], + ["b9b44d9f04b9f15e787d7704e6797d51bc46382190c36d8845ec68dfd63ee64cf7a467b21e00000000096aac00530052ab636aba1bcb110a80c5cbe073f12c739e3b20836aa217a4507648d133a8eedd3f02cb55c132b203000000076a000063526352b1c288e3a9ff1f2da603f230b32ef7c0d402bdcf652545e2322ac01d725d75f5024048ad0100000000ffffffffffd882d963be559569c94febc0ef241801d09dc69527c9490210f098ed8203c700000000056a006300ab9109298d01719d9a0300000000066a52ab006365d7894c5b", "ac6351650063636a", 3, -622355349, "ac87b1b93a6baab6b2c6624f10e8ebf6849b0378ef9660a3329073e8f5553c8d"], + ["ff60473b02574f46d3e49814c484081d1adb9b15367ba8487291fc6714fd6e3383d5b335f001000000026a6ae0b82da3dc77e5030db23d77b58c3c20fa0b70aa7d341a0f95f3f72912165d751afd57230300000008ac536563516a6363ffffffff04f86c0200000000000553acab636ab13111000000000003510065f0d3f305000000000951ab516a65516aabab730a3a010000000002515200000000", "ac6a", 1, 1895032314, "0767e09bba8cd66d55915677a1c781acd5054f530d5cf6de2d34320d6c467d80"], + ["f218026204f4f4fc3d3bd0eada07c57b88570d544a0436ae9f8b753792c0c239810bb30fbc0200000002536affffffff8a468928d6ec4cc10aa0f73047697970e99fa64ae8a3b4dca7551deb0b639149010000000851ab520052650051ffffffffa98dc5df357289c9f6873d0f5afcb5b030d629e8f23aa082cf06ec9a95f3b0cf0000000000ffffffffea2c2850c5107705fd380d6f29b03f533482fd036db88739122aac9eff04e0aa010000000365536a03bd37db034ac4c4020000000007515152655200ac33b27705000000000151efb71e0000000000007b65425b", "515151", 3, -1772252043, "de35c84a58f2458c33f564b9e58bc57c3e028d629f961ad1b3c10ee020166e5a"], + ["48e7d42103b260b27577b70530d1ac2fed2551e9dd607cbcf66dca34bb8c03862cf8f5fd5401000000075151526aacab00ffffffff1e3d3b841552f7c6a83ee379d9d66636836673ce0b0eda95af8f2d2523c91813030000000665acac006365ffffffff388b3c386cd8c9ef67c83f3eaddc79f1ff910342602c9152ffe8003bce51b28b0100000008636363006a636a52ffffffff04b8f67703000000000852005353ac6552520cef720200000000085151ab6352ab00ab5096d6030000000005516a005100662582020000000001ac6c137280", "6a65", 1, 1513618429, "e2fa3e1976aed82c0987ab30d4542da2cb1cffc2f73be13480132da8c8558d5c"], + ["91ebc4cf01bc1e068d958d72ee6e954b196f1d85b3faf75a521b88a78021c543a06e056279000000000265ab7c12df0503832121030000000000cc41a6010000000005ab5263516540a951050000000006ab63ab65acac00000000", "526a0065636a6a6aac", 0, -614046478, "7de4ba875b2e584a7b658818c112e51ee5e86226f5a80e5f6b15528c86400573"], + ["3cd4474201be7a6c25403bf00ca62e2aa8f8f4f700154e1bb4d18c66f7bb7f9b975649f0dc0100000006535151535153ffffffff01febbeb000000000006005151006aac00000000", "", 0, -1674687131, "6b77ca70cc452cc89acb83b69857cda98efbfc221688fe816ef4cb4faf152f86"], + ["92fc95f00307a6b3e2572e228011b9c9ed41e58ddbaefe3b139343dbfb3b34182e9fcdc3f50200000002acab847bf1935fde8bcfe41c7dd99683289292770e7f163ad09deff0e0665ed473cd2b56b0f40300000006516551ab6351294dab312dd87b9327ce2e95eb44b712cfae0e50fda15b07816c8282e8365b643390eaab01000000026aacffffffff016e0b6b040000000001ac00000000", "650065acac005300", 2, -1885164012, "bd7d26bb3a98fc8c90c972500618bf894cb1b4fe37bf5481ff60eef439d3b970"], + ["4db591ab018adcef5f4f3f2060e41f7829ce3a07ea41d681e8cb70a0e37685561e4767ac3b0000000005000052acabd280e63601ae6ef20000000000036a636326c908f7", "ac6a51526300630052", 0, 862877446, "355ccaf30697c9c5b966e619a554d3323d7494c3ea280a9b0dfb73f953f5c1cb"], + ["503fd5ef029e1beb7b242d10032ac2768f9a1aca0b0faffe51cec24770664ec707ef7ede4f01000000045253ac53375e350cc77741b8e96eb1ce2d3ca91858c052e5f5830a0193200ae2a45b413dda31541f0000000003516553ffffffff0175a5ba0500000000015200000000", "6aab65510053ab65", 1, 1603081205, "353ca9619ccb0210ae18b24d0e57efa7abf8e58fa6f7102738e51e8e72c9f0c4"], + ["c80abebd042cfec3f5c1958ee6970d2b4586e0abec8305e1d99eb9ee69ecc6c2cbd76374380000000007ac53006300ac510acee933b44817db79320df8094af039fd82111c7726da3b33269d3820123694d849ee5001000000056a65ab526562699bea8530dc916f5d61f0babea709dac578774e8a4dcd9c640ec3aceb6cb2443f24f302000000020063ea780e9e57d1e4245c1e5df19b4582f1bf704049c5654f426d783069bcc039f2d8fa659f030000000851ab53635200006a8d00de0b03654e8500000000000463ab635178ebbb0400000000055100636aab239f1d030000000006ab006300536500000000", "6565ac515100", 3, 1460851377, "b35bb1b72d02fab866ed6bbbea9726ab32d968d33a776686df3ac16aa445871e"], + ["0337b2d5043eb6949a76d6632b8bb393efc7fe26130d7409ef248576708e2d7f9d0ced9d3102000000075352636a5163007034384dfa200f52160690fea6ce6c82a475c0ef1caf5c9e5a39f8f9ddc1c8297a5aa0eb02000000026a51ffffffff38e536298799631550f793357795d432fb2d4231f4effa183c4e2f61a816bcf0030000000463ac5300706f1cd3454344e521fde05b59b96e875c8295294da5d81d6cc7efcfe8128f150aa54d6503000000008f4a98c704c1561600000000000072cfa6000000000000e43def01000000000100cf31cc0500000000066365526a6500cbaa8e2e", "", 3, 2029506437, "7615b4a7b3be865633a31e346bc3db0bcc410502c8358a65b8127089d81b01f8"], + ["59f6cffd034733f4616a20fe19ea6aaf6abddb30b408a3a6bd86cd343ab6fe90dc58300cc90200000000ffffffffc835430a04c3882066abe7deeb0fa1fdaef035d3233460c67d9eabdb05e95e5a02000000080065ac535353ab00ffffffff4b9a043e89ad1b4a129c8777b0e8d87a014a0ab6a3d03e131c27337bbdcb43b402000000066a5100abac6ad9e9bf62014bb118010000000001526cbe484f", "ab526352ab65", 0, 2103515652, "4f2ccf981598639bec57f885b4c3d8ea8db445ea6e61cfd45789c69374862e5e"], + ["cbc79b10020b15d605680a24ee11d8098ad94ae5203cb6b0589e432832e20c27b72a926af20300000006ab65516a53acbb854f3146e55c508ece25fa3d99dbfde641a58ed88c051a8a51f3dacdffb1afb827814b02000000026352c43e6ef30302410a020000000000ff4bd90100000000065100ab63000008aa8e0400000000095265526565ac5365abc52c8a77", "53526aac0051", 0, 202662340, "984efe0d8d12e43827b9e4b27e97b3777ece930fd1f589d616c6f9b71dab710e"], + ["7c07419202fa756d29288c57b5c2b83f3c847a807f4a9a651a3f6cd6c46034ae0aa3a7446b0200000004ab6a6365ffffffff9da83cf4219bb96c76f2d77d5df31c1411a421171d9b59ec02e5c1218f29935403000000008c13879002f8b1ac0400000000086a63536a636553653c584f02000000000000000000", "abac53ab656363", 1, -1038419525, "4a74f365a161bc6c9bddd249cbd70f5dadbe3de70ef4bd745dcb6ee1cd299fbd"], + ["351cbb57021346e076d2a2889d491e9bfa28c54388c91b46ee8695874ad9aa576f1241874d0200000008ab6563525300516affffffffe13e61b8880b8cd52be4a59e00f9723a4722ea58013ec579f5b3693b9e115b1100000000096363abac5252635351ffffffff027fee02040000000008ab6a5200ab006a65b85f130200000000086a52630053ab52ab00000000", "ab6aab65", 1, 586415826, "08bbb746a596991ab7f53a76e19acad087f19cf3e1db54054aab403c43682d09"], + ["a8252ea903f1e8ff953adb16c1d1455a5036222c6ea98207fc21818f0ece2e1fac310f9a0100000000095163ac635363ac0000be6619e9fffcde50a0413078821283ce3340b3993ad00b59950bae7a9f931a9b0a3a035f010000000463005300b8b0583fbd6049a1715e7adacf770162811989f2be20af33f5f60f26eba653dc26b024a00000000006525351636552ffffffff046d2acc030000000002636a9a2d430500000000080065005165ab53abecf63204000000000052b9ed050000000008acacac53ab65656500000000", "65ab53635253636a51", 2, 1442639059, "8ca11838775822f9a5beee57bdb352f4ee548f122de4a5ca61c21b01a1d50325"], + ["2f1a425c0471a5239068c4f38f9df135b1d24bf52d730d4461144b97ea637504495aec360801000000055300515365c71801dd1f49f376dd134a9f523e0b4ae611a4bb122d8b26de66d95203f181d09037974300000000025152ffffffff9bdcea7bc72b6e5262e242c94851e3a5bf8f314b3e5de0e389fc9e5b3eadac030000000009525265655151005153ffffffffdbb53ce99b5a2320a4e6e2d13b01e88ed885a0957d222e508e9ec8e4f83496cb0200000007635200abac63ac04c96237020cc5490100000000080000516a51ac6553074a360200000000025152225520ca", "6551ab65ac65516a", 1, -489869549, "9bc5bb772c553831fb40abe466074e59a469154679c7dee042b8ea3001c20393"], + ["ef3acfd4024defb48def411b8f8ba2dc408dc9ee97a4e8bde4d6cb8e10280f29c98a6e8e9103000000035100513d5389e3d67e075469dfd9f204a7d16175653a149bd7851619610d7ca6eece85a516b2df0300000005516aac6552ca678bdf02f477f003000000000057e45b0300000000055252525252af35c20a", "5165ac53ab", 1, -1900839569, "78eb6b24365ac1edc386aa4ffd15772f601059581c8776c34f92f8a7763c9ccf"], + ["ff4468dc0108475fc8d4959a9562879ce4ab4867a419664bf6e065f17ae25043e6016c70480100000000ffffffff02133c6f0400000000000bd0a8020000000004006a520035afa4f6", "51ac65ab", 0, -537664660, "f6da59b9deac63e83728850ac791de61f5dfcaeed384ebcbb20e44afcd8c8910"], + ["4e8594d803b1d0a26911a2bcdd46d7cbc987b7095a763885b1a97ca9cbb747d32c5ab9aa91030000000353ac53a0cc4b215e07f1d648b6eeb5cdbe9fa32b07400aa773b9696f582cebfd9930ade067b2b200000000060065abab6500fc99833216b8e27a02defd9be47fafae4e4a97f52a9d2a210d08148d2a4e5d02730bcd460100000004516351ac37ce3ae1033baa55040000000006006a636a63acc63c990400000000025265eb1919030000000005656a6a516a00000000", "", 1, -75217178, "04c5ee48514cd033b82a28e336c4d051074f477ef2675ce0ce4bafe565ee9049"], + ["a88830a7023f13ed19ab14fd757358eb6af10d6520f9a54923a6d613ac4f2c11e249cda8aa030000000851630065abababacffffffff8f5fe0bc04a33504c4b47e3991d25118947a0261a9fa520356731eeabd561dd3020000000363ababffffffff038404bd010000000008ab5153516aab6a63d33a5601000000000263004642dc020000000009655152acac636352004be6f3af", "5253536565006aab6a", 0, 1174417836, "2e42ead953c9f4f81b72c27557e6dc7d48c37ff2f5c46c1dbe9778fb0d79f5b2"], + ["44e1a2b4010762af23d2027864c784e34ef322b6e24c70308a28c8f2157d90d17b99cd94a401000000085163656565006300ffffffff0198233d020000000002000000000000", "52525153656365", 0, 1119696980, "d9096de94d70c6337da6202e6e588166f31bff5d51bb5adc9468594559d65695"], + ["44ca65b901259245abd50a745037b17eb51d9ce1f41aa7056b4888285f48c6f26cb97b7a25020000000552636363abffffffff047820350400000000040053acab14f3e603000000000652635100ab630ce66c03000000000001bdc704000000000765650065ac51ac3e886381", "51", 0, -263340864, "ed5622ac642d11f90e68c0feea6a2fe36d880ecae6b8c0d89c4ea4b3d162bd90"], + ["cfa147d2017fe84122122b4dda2f0d6318e59e60a7207a2d00737b5d89694d480a2c26324b0000000006006351526552ffffffff0456b5b804000000000800516aab525363ab166633000000000004655363ab254c0e02000000000952ab6a6a00ab525151097c1b020000000009656a52ac6300530065ad0d6e50", "6a535165ac6a536500", 0, -574683184, "f926d4036eac7f019a2b0b65356c4ee2fe50e089dd7a70f1843a9f7bc6997b35"], + ["91c5d5f6022fea6f230cc4ae446ce040d8313071c5ac1749c82982cc1988c94cb1738aa48503000000016a19e204f30cb45dd29e68ff4ae160da037e5fc93538e21a11b92d9dd51cf0b5efacba4dd70000000005656a6aac51ffffffff03db126905000000000953006a53ab6563636a36a273030000000006656a52656552b03ede00000000000352516500000000", "530052526a00", 1, 1437328441, "255c125b60ee85f4718b2972174c83588ee214958c3627f51f13b5fb56c8c317"], + ["03f20dc202c886907b607e278731ebc5d7373c348c8c66cac167560f19b341b782dfb634cb03000000076a51ac6aab63abea3e8de7adb9f599c9caba95aa3fa852e947fc88ed97ee50e0a0ec0d14d164f44c0115c10100000004ab5153516fdd679e0414edbd000000000005ac636a53512021f2040000000007006a0051536a52c73db2050000000005525265ac5369046e000000000003ab006a1ef7bd1e", "52656a", 0, 1360223035, "5a0a05e32ce4cd0558aabd5d79cd5fcbffa95c07137506e875a9afcba4bef5a2"], + ["d9611140036881b61e01627078512bc3378386e1d4761f959d480fdb9d9710bebddba2079d020000000763536aab5153ab819271b41e228f5b04daa1d4e72c8e1955230accd790640b81783cfc165116a9f535a74c000000000163ffffffffa2e7bb9a28e810624c251ff5ba6b0f07a356ac082048cf9f39ec036bba3d431a02000000076a000000ac65acffffffff01678a820000000000085363515153ac635100000000", "535353", 2, -82213851, "52b9e0778206af68998cbc4ebdaad5a9469e04d0a0a6cef251abfdbb74e2f031"], + ["98b3a0bf034233afdcf0df9d46ac65be84ef839e58ee9fa59f32daaa7d684b6bdac30081c60200000007636351acabababffffffffc71cf82ded4d1593e5825618dc1d5752ae30560ecfaa07f192731d68ea768d0f0100000006650052636563f3a2888deb5ddd161430177ce298242c1a86844619bc60ca2590d98243b5385bc52a5b8f00000000095365acacab520052ac50d4722801c3b8a60300000000035165517e563b65", "51", 1, -168940690, "b6b684e2d2ecec8a8dce4ed3fc1147f8b2e45732444222aa8f52d860c2a27a9d"], + ["97be4f7702dc20b087a1fdd533c7de762a3f2867a8f439bddf0dcec9a374dfd0276f9c55cc0300000000cdfb1dbe6582499569127bda6ca4aaff02c132dc73e15dcd91d73da77e92a32a13d1a0ba0200000002ab51ffffffff048cfbe202000000000900516351515363ac535128ce0100000000076aac5365ab6aabc84e8302000000000863536a53ab6a6552f051230500000000066aac535153510848d813", "ac51", 0, 229541474, "e5da9a416ea883be1f8b8b2d178463633f19de3fa82ae25d44ffb531e35bdbc8"], + ["085b6e04040b5bff81e29b646f0ed4a45e05890a8d32780c49d09643e69cdccb5bd81357670100000001abffffffffa5c981fe758307648e783217e3b4349e31a557602225e237f62b636ec26df1a80300000004650052ab4792e1da2930cc90822a8d2a0a91ea343317bce5356b6aa8aae6c3956076aa33a5351a9c0300000004abac5265e27ddbcd472a2f13325cc6be40049d53f3e266ac082172f17f6df817db1936d9ff48c02b000000000152ffffffff021aa7670500000000085353635163ab51ac14d584000000000001aca4d136cc", "6a525300536352536a", 0, -1398925877, "41ecca1e8152ec55074f4c39f8f2a7204dda48e9ec1e7f99d5e7e4044d159d43"], + ["eec32fff03c6a18b12cd7b60b7bdc2dd74a08977e53fdd756000af221228fe736bd9c42d870100000007005353ac515265ffffffff037929791a188e9980e8b9cc154ad1b0d05fb322932501698195ab5b219488fc02000000070063510065ab6a0bfc176aa7e84f771ea3d45a6b9c24887ceea715a0ff10ede63db8f089e97d927075b4f1000000000551abab63abffffffff02eb933c000000000000262c420000000000036563632549c2b6", "6352", 2, 1480445874, "ff8a4016dfdd918f53a45d3a1f62b12c407cd147d68ca5c92b7520e12c353ff5"], + ["98ea7eac0313d9fb03573fb2b8e718180c70ce647bebcf49b97a8403837a2556cb8c9377f30000000004ac53ac65ffffffff8caac77a5e52f0d8213ef6ce998bedbb50cfdf108954771031c0e0cd2a78423900000000010066e99a44937ebb37015be3693761078ad5c73aa73ec623ac7300b45375cc8eef36087eb80000000007515352acac5100ffffffff0114a51b02000000000000000000", "6aacab", 0, 243527074, "bad77967f98941af4dd52a8517d5ad1e32307c0d511e15461e86465e1b8b5273"], + ["3ab70f4604e8fc7f9de395ec3e4c3de0d560212e84a63f8d75333b604237aa52a10da17196000000000763526a6553ac63a25de6fd66563d71471716fe59087be0dde98e969e2b359282cf11f82f14b00f1c0ac70f02000000050052516aacdffed6bb6889a13e46956f4b8af20752f10185838fd4654e3191bf49579c961f5597c36c0100000005ac636363abc3a1785bae5b8a1b4be5d0cbfadc240b4f7acaa7dfed6a66e852835df5eb9ac3c553766801000000036a65630733b7530218569602000000000952006a6a6a51acab52777f06030000000007ac0063530052abc08267c9", "000000536aac0000", 1, 1919096509, "df1c87cf3ba70e754d19618a39fdbd2970def0c1bfc4576260cba5f025b87532"], + ["bdb6b4d704af0b7234ced671c04ba57421aba7ead0a117d925d7ebd6ca078ec6e7b93eea6600000000026565ffffffff3270f5ad8f46495d69b9d71d4ab0238cbf86cc4908927fbb70a71fa3043108e6010000000700516a65655152ffffffff6085a0fdc03ae8567d0562c584e8bfe13a1bd1094c518690ebcb2b7c6ce5f04502000000095251530052536a53aba576a37f2c516aad9911f687fe83d0ae7983686b6269b4dd54701cb5ce9ec91f0e6828390300000000ffffffff04cc76cc020000000002656a01ffb702000000000253ab534610040000000009acab006565516a00521f55f5040000000000389dfee9", "6a525165", 0, 1336204763, "71c294523c48fd7747eebefbf3ca06e25db7b36bff6d95b41c522fecb264a919"], + ["54258edd017d22b274fbf0317555aaf11318affef5a5f0ae45a43d9ca4aa652c6e85f8a040010000000953ac65ab5251656500ffffffff03321d450000000000085265526a51526a529ede8b030000000003635151ce6065020000000001534c56ec1b", "acac", 0, 2094130012, "110d90fea9470dfe6c5048f45c3af5e8cc0cb77dd58fd13d338268e1c24b1ccc"], + ["ce0d322e04f0ffc7774218b251530a7b64ebefca55c90db3d0624c0ff4b3f03f918e8cf6f60300000003656500ffffffff9cce943872da8d8af29022d0b6321af5fefc004a281d07b598b95f6dcc07b1830200000007abab515351acab8d926410e69d76b7e584aad1470a97b14b9c879c8b43f9a9238e52a2c2fefc2001c56af8010000000400ab5253cd2cd1fe192ce3a93b5478af82fa250c27064df82ba416dfb0debf4f0eb307a746b6928901000000096500abacac6a0063514214524502947efc0200000000035251652c40340100000000096a6aab52000052656a5231c54c", "51", 2, -2090320538, "0322ca570446869ec7ec6ad66d9838cff95405002d474c0d3c17708c7ee039c6"], + ["47ac54940313430712ebb32004679d3a512242c2b33d549bf5bbc8420ec1fd0850ed50eb6d0300000009536aac6a65acacab51ffffffffb843e44266ce2462f92e6bff54316661048c8c17ecb092cb493b39bfca9117850000000001519ab348c05e74ebc3f67423724a3371dd99e3bceb4f098f8860148f48ad70000313c4c223000000000653006565656512c2d8dc033f3c97010000000002636aa993aa010000000006526365ab526ab7cf560300000000076a0065ac6a526500000000", "005352535300ab6a", 2, 59531991, "8b5b3d00d9c658f062fe6c5298e54b1fe4ed3a3eab2a87af4f3119edc47b1691"], + ["233cd90b043916fc41eb870c64543f0111fb31f3c486dc72457689dea58f75c16ae59e9eb2000000000500536a6a6affffffff9ae30de76be7cd57fb81220fce78d74a13b2dbcad4d023f3cadb3c9a0e45a3ce000000000965ac6353ac5165515130834512dfb293f87cb1879d8d1b20ebad9d7d3d5c3e399a291ce86a3b4d30e4e32368a9020000000453005165ffffffff26d84ae93eb58c81158c9b3c3cbc24a84614d731094f38d0eea8686dec02824d0300000005636a65abacf02c784001a0bd5d03000000000900655351ab65ac516a416ef503", "", 1, -295106477, "b79f31c289e95d9dadec48ebf88e27c1d920661e50d090e422957f90ff94cb6e"], + ["9200e26b03ff36bc4bf908143de5f97d4d02358db642bd5a8541e6ff709c420d1482d471b70000000008abab65536a636553ffffffff61ba6d15f5453b5079fb494af4c48de713a0c3e7f6454d7450074a2a80cb6d880300000007ac6a00ab5165515dfb7574fbce822892c2acb5d978188b1d65f969e4fe874b08db4c791d176113272a5cc10100000000ffffffff0420958d000000000009ac63516a0063516353dd885505000000000465ac00007b79e901000000000066d8bf010000000005525252006a00000000", "ac5152", 0, 2089531339, "89ec7fab7cfe7d8d7d96956613c49dc48bf295269cfb4ea44f7333d88c170e62"], + ["45f335ba01ce2073a8b0273884eb5b48f56df474fc3dff310d9706a8ac7202cf5ac188272103000000025363ffffffff049d859502000000000365ab6a8e98b1030000000002ac51f3a80603000000000752535151ac00000306e30300000000020051b58b2b3a", "", 0, 1899564574, "78e01310a228f645c23a2ad0acbb8d91cedff4ecdf7ca997662c6031eb702b11"], + ["d8f652a6043b4faeada05e14b81756cd6920cfcf332e97f4086961d49232ad6ffb6bc6c097000000000453526563ffffffff1ea4d60e5e91193fbbc1a476c8785a79a4c11ec5e5d6c9950c668ceacfe07a15020000000352ab51fffffffffe029a374595c4edd382875a8dd3f20b9820abb3e93f877b622598d11d0b09e503000000095351000052ac515152ffffffff9d65fea491b979699ceb13caf2479cd42a354bd674ded3925e760758e85a756803000000046365acabffffffff0169001d00000000000651636a65656300000000", "ab0063630000ac", 3, 1050965951, "4cc85cbc2863ee7dbce15490d8ca2c5ded61998257b9eeaff968fe38e9f009ae"], + ["718662be026e1dcf672869ac658fd0c87d6835cfbb34bd854c44e577d5708a7faecda96e260300000004526a636a489493073353b678549adc7640281b9cbcb225037f84007c57e55b874366bb7b0fa03bdc00000000095165ababac65ac00008ab7f2a802eaa53d000000000007acac516aac526ae92f380100000000056aac00536500000000", "ab00", 1, 43296088, "2d642ceee910abff0af2116af75b2e117ffb7469b2f19ad8fef08f558416d8f7"], + ["94083c840288d40a6983faca876d452f7c52a07de9268ad892e70a81e150d602a773c175ad03000000007ec3637d7e1103e2e7e0c61896cbbf8d7e205b2ecc93dd0d6d7527d39cdbf6d335789f660300000000ffffffff019e1f7b03000000000800ac0051acac0053539cb363", "", 1, -183614058, "a17b66d6bb427f42653d08207a22b02353dd19ccf2c7de6a9a3a2bdb7c49c9e7"], + ["30e0d4d20493d0cd0e640b757c9c47a823120e012b3b64c9c1890f9a087ae4f2001ca22a61010000000152f8f05468303b8fcfaad1fb60534a08fe90daa79bff51675472528ebe1438b6f60e7f60c10100000009526aab6551ac510053ffffffffaaab73957ea2133e32329795221ed44548a0d3a54d1cf9c96827e7cffd1706df0200000009ab00526a005265526affffffffd19a6fe54352015bf170119742821696f64083b5f14fb5c7d1b5a721a3d7786801000000085265abababac53abffffffff020f39bd030000000004ab6aac52049f6c050000000004ab52516aba5b4c60", "6a6365516a6a655253", 0, -624256405, "8e221a6c4bf81ca0d8a0464562674dcd14a76a32a4b7baf99450dd9195d411e6"], + ["f9c69d940276ec00f65f9fe08120fc89385d7350388508fd80f4a6ba2b5d4597a9e21c884f010000000663ab63ababab15473ae6d82c744c07fc876ecd53bd0f3018b2dbedad77d757d5bdf3811b23d294e8c0170000000001abafababe00157ede2050000000006ac6a5263635300000000", "ab53", 1, 606547088, "714d8b14699835b26b2f94c58b6ea4c53da3f7adf0c62ea9966b1e1758272c47"], + ["5c0ac112032d6885b7a9071d3c5f493aa16c610a4a57228b2491258c38de8302014276e8be030000000300ab6a17468315215262ad5c7393bb5e0c5a6429fd1911f78f6f72dafbbbb78f3149a5073e24740300000003ac5100ffffffff33c7a14a062bdea1be3c9c8e973f54ade53fe4a69dcb5ab019df5f3345050be00100000008ac63655163526aab428defc0033ec36203000000000765516365536a00ae55b2000000000002ab53f4c0080400000000095265516a536563536a00000000", "6a005151006a", 2, 272749594, "91082410630337a5d89ff19145097090f25d4a20bdd657b4b953927b2f62c73b"], + ["e3683329026720010b08d4bec0faa244f159ae10aa582252dd0f3f80046a4e145207d54d31000000000852acac52656aacac3aaf2a5017438ad6adfa3f9d05f53ebed9ceb1b10d809d507bcf75e0604254a8259fc29c020000000653526552ab51f926e52c04b44918030000000000f7679c0100000000090000525152005365539e3f48050000000009516500ab635363ab008396c905000000000253650591024f", "6a6365", 0, 908746924, "458aec3b5089a585b6bad9f99fd37a2b443dc5a2eefac2b7e8c5b06705efc9db"], + ["48c4afb204204209e1df6805f0697edaa42c0450bbbd767941fe125b9bc40614d63d757e2203000000066a5363005152dc8b6a605a6d1088e631af3c94b8164e36e61445e2c60130292d81dabd30d15f54b355a802000000036a6353ffffffff1d05dcec4f3dedcfd02c042ce5d230587ee92cb22b52b1e59863f3717df2362f0300000005536552ac52ffffffffd4d71c4f0a7d53ba47bb0289ca79b1e33d4c569c1e951dd611fc9c9c1ca8bc6c030000000865536a65ab51abacffffffff042f9aa905000000000753655153656351ab93d8010000000002655337440e0300000000005d4c690000000000015278587acb", "ab006565526a51", 0, 1502064227, "bbed77ff0f808aa8abd946ba9e7ec1ddb003a969fa223dee0af779643cb841a9"], + ["00b20fd104dd59705b84d67441019fa26c4c3dec5fd3b50eca1aa549e750ef9ddb774dcabe000000000651ac656aac65ffffffff52d4246f2db568fc9eea143e4d260c698a319f0d0670f84c9c83341204fde48b0200000000ffffffffb8aeabb85d3bcbc67b132f1fd815b451ea12dcf7fc169c1bc2e2cf433eb6777a03000000086a51ac6aab6563acd510d209f413da2cf036a31b0def1e4dcd8115abf2e511afbcccb5ddf41d9702f28c52900100000006ac52ab6a0065ffffffff039c8276000000000008ab53655200656a52401561010000000003acab0082b7160100000000035100ab00000000", "535265", 1, -947367579, "3212c6d6dd8d9d3b2ac959dec11f4638ccde9be6ed5d36955769294e23343da0"], + ["455131860220abbaa72015519090a666faf137a0febce7edd49da1eada41feab1505a0028b02000000036365ab453ead4225724eb69beb590f2ec56a7693a608871e0ab0c34f5e96157f90e0a96148f3c502000000085251ab51535163acffffffff022d1249040000000009abac00acac6565630088b310040000000000e3920e59", "5152ab6a52ac5152", 0, 294375737, "c40fd7dfa72321ac79516502500478d09a35cc22cc264d652c7d18b14400b739"], + ["624d28cb02c8747915e9af2b13c79b417eb34d2fa2a73547897770ace08c6dd9de528848d3030000000651ab63abab533c69d3f9b75b6ef8ed2df50c2210fd0bf4e889c42477d58682f711cbaece1a626194bb85030000000765acab53ac5353ffffffff018cc280040000000009abacabac52636352ac6859409e", "ac51ac", 1, 1005144875, "919144aada50db8675b7f9a6849c9d263b86450570293a03c245bd1e3095e292"], + ["8f28471d02f7d41b2e70e9b4c804f2d90d23fb24d53426fa746bcdcfffea864925bdeabe3e0200000001acffffffff76d1d35d04db0e64d65810c808fe40168f8d1f2143902a1cc551034fd193be0e0000000001acffffffff048a5565000000000005005151516afafb610400000000045263ac53648bb30500000000086363516a6a5165513245de01000000000000000000", "6a0053510053", 1, -1525137460, "305fc8ff5dc04ebd9b6448b03c9a3d945a11567206c8d5214666b30ec6d0d6cc"], + ["10ec50d7046b8b40e4222a3c6449490ebe41513aad2eca7848284a08f3069f3352c2a9954f0000000009526aac656352acac53ffffffff0d979f236155aa972472d43ee6f8ce22a2d052c740f10b59211454ff22cb7fd00200000007acacacab63ab53ffffffffbbf97ebde8969b35725b2e240092a986a2cbfd58de48c4475fe077bdd493a20c010000000663ab5365ababffffffff4600722d33b8dba300d3ad037bcfc6038b1db8abfe8008a15a1de2da2264007302000000035351ac6dbdafaf020d0ccf04000000000663ab6a51ab6ae06e5e0200000000036aabab00000000", "", 0, -1658960232, "2420dd722e229eccafae8508e7b8d75c6920bfdb3b5bac7cb8e23419480637c2"], + ["fef98b7101bf99277b08a6eff17d08f3fcb862e20e13138a77d66fba55d54f26304143e5360100000006515365abab00ffffffff04265965030000000004655252ace2c775010000000001002b23b4040000000007516a5153ab53ac456a7a00000000000753ab525251acacba521291", "526aacacab00abab53", 0, -1614097109, "4370d05c07e231d6515c7e454a4e401000b99329d22ed7def323976fa1d2eeb5"], + ["34a2b8830253661b373b519546552a2c3bff7414ea0060df183b1052683d78d8f54e842442000000000152ffffffffd961a8e34cf374151058dfcddc86509b33832bc57267c63489f69ff01199697c0300000002abacba856cfb01b17c2f050000000008515365ac53ab000000000000", "5263ab656a", 1, -2104480987, "2f9993e0a84a6ca560d6d1cc2b63ffe7fd71236d9cfe7d809491cef62bbfad84"], + ["43559290038f32fda86580dd8a4bc4422db88dd22a626b8bd4f10f1c9dd325c8dc49bf479f01000000026351ffffffff401339530e1ed3ffe996578a17c3ec9d6fccb0723dd63e7b3f39e2c44b976b7b0300000006ab6a65656a51ffffffff6fb9ba041c96b886482009f56c09c22e7b0d33091f2ac5418d05708951816ce7000000000551ac525100ffffffff020921e40500000000035365533986f40500000000016a00000000", "52ac51", 0, 1769771809, "02040283ef2291d8e1f79bb71bdabe7c1546c40d7ed615c375643000a8b9600d"], + ["6878a6bd02e7e1c8082d5e3ee1b746cfebfac9e8b97e61caa9e0759d8a8ecb3743e36a30de0100000002ab532a911b0f12b73e0071f5d50b6bdaf783f4b9a6ce90ec0cad9eecca27d5abae188241ddec0200000001651c7758d803f7457b0500000000036551515f4e90000000000001007022080200000000035365acc86b6946", "6351ab", 0, -1929374995, "f24be499c58295f3a07f5f1c6e5084496ae160450bd61fdb2934e615289448f1"], + ["35b6fc06047ebad04783a5167ab5fc9878a00c4eb5e7d70ef297c33d5abd5137a2dea9912402000000036aacacffffffff21dc291763419a584bdb3ed4f6f8c60b218aaa5b99784e4ba8acfec04993e50c03000000046a00ac6affffffff69e04d77e4b662a82db71a68dd72ef0af48ca5bebdcb40f5edf0caf591bb41020200000000b5db78a16d93f5f24d7d932f93a29bb4b784febd0cbb1943f90216dc80bba15a0567684b000000000853ab52ab5100006a1be2208a02f6bdc103000000000265ab8550ea04000000000365636a00000000", "", 0, -1114114836, "1c8655969b241e717b841526f87e6bd68b2329905ba3fc9e9f72526c0b3ea20c"], + ["bebb90c302bf91fd4501d33555a5fc5f2e1be281d9b7743680979b65c3c919108cc2f517510100000003abab00ffffffff969c30053f1276550532d0aa33cfe80ca63758cd215b740448a9c08a84826f3303000000056565ab5153ffffffff04bf6f2a04000000000565ab5265ab903e760100000000026a6a7103fa020000000006526553525365b05b2c000000000006ab000000535300000000", "51510053ab63635153", 1, 1081291172, "94338cd47a4639be30a71e21a7103cee4c99ef7297e0edd56aaf57a068b004de"], + ["af48319f031b4eeb4319714a285f44244f283cbff30dcb9275b06f2348ccd0d7f015b54f8500000000066363ac65ac6affffffff2560a9817ebbc738ad01d0c9b9cf657b8f9179b1a7f073eb0b67517409d108180200000005ac6365ab52ffffffff0bdd67cd4ecae96249a2e2a96db1490ee645f042fd9d5579de945e22b799f4d003000000086552ab515153ab00cf187c8202e51abf0300000000066552006a00abadf37d000000000004ac6a535100000000", "63ab65", 1, -1855554446, "60caf46a7625f303c04706cec515a44b68ec319ee92273acb566cca4f66861c1"], + ["f35befbc03faf8c25cc4bc0b92f6239f477e663b44b83065c9cb7cf231243032cf367ce3130000000005ab65526a517c4c334149a9c9edc39e29276a4b3ffbbab337de7908ea6f88af331228bd90086a6900ba020000000151279d19950d2fe81979b72ce3a33c6d82ebb92f9a2e164b6471ac857f3bbd3c0ea213b542010000000953ab51635363520065052657c20300a9ba04000000000452636a6a0516ea020000000008535253656365ababcfdd3f01000000000865ac516aac00530000000000", "", 2, -99793521, "c834a5485e68dc13edb6c79948784712122440d7fa5bbaa5cd2fc3d4dac8185d"], + ["d3da18520216601acf885414538ce2fb4d910997eeb91582cac42eb6982c9381589587794f0300000000fffffffff1b1c9880356852e10cf41c02e928748dd8fae2e988be4e1c4cb32d0bfaea6f7000000000465ab6aabffffffff02fb0d69050000000002ababeda8580500000000085163526565ac52522b913c95", "ac", 1, -1247973017, "99b32b5679d91e0f9cdd6737afeb07459806e5acd7630c6a3b9ab5d550d0c003"], + ["8218eb740229c695c252e3630fc6257c42624f974bc856b7af8208df643a6c520ef681bfd00000000002510066f30f270a09b2b420e274c14d07430008e7886ec621ba45665057120afce58befca96010300000004525153ab84c380a9015d96100000000000076a5300acac526500000000", "ac005263", 0, -1855679695, "5071f8acf96aea41c7518bd1b5b6bbe16258b529df0c03f9e374b83c66b742c6"], + ["1123e7010240310013c74e5def60d8e14dd67aedff5a57d07a24abc84d933483431b8cf8ea0300000003530051fc6775ff1a23c627a2e605dd2560e84e27f4208300071e90f4589e762ad9c9fe8d0da95e020000000465655200ffffffff04251598030000000004ab65ab639d28d90400000000096563636aacac525153474df801000000000851525165ac51006a75e23b040000000000e5bd3a4a", "6363636565", 0, -467124448, "9cb0dd04e9fe287b112e94a1647590d27e8b164ca13c4fe70c610fd13f82c2fd"], + ["fd92fe1003083c5179f97e77bf7d71975788138147adbdb283306802e261c0aee080fa22630200000000860c643ba9a1816b9badf36077b4554d11720e284e395a1121bc45279e148b2064c65e49020000000651ab6a53636a2c713088d20f4bc4001264d972cce05b9fe004dc33376ad24d0d013e417b91a5f1b6734e000000000100ffffffff02e3064c0500000000066552006a5165b86e8705000000000665ab65ab53522052eadb", "00ab53525265", 0, 776203277, "47207b48777727532f62e09afcd4104ea6687e723c7657c30504fa2081331cc8"], + ["d1b6a703038f14d41fcc5cc45455faa135a5322be4bf0f5cbcd526578fc270a236cacb853f0200000001abffffffff135aeff902fa38f202ccf5bd34437ff89c9dc57a028b62447a0a38579383e8ef0000000000ffffffffadf398d2c818d0b90bc474f540c3618a4a643482eeab73d36101987e2ec0335900000000004bd3323504e69fc10000000000055151535251790ada02000000000563ab6aab521337a704000000000963ac63abacac52656a1e9862010000000007656500ac51ab6a8f4ee672", "ab5251656565ac63", 2, 82008394, "b8f3d255549909c07588ecba10a02e55a2d6f2206d831af9da1a7dae64cfbc8b"], + ["81dadaa7011556683db3fe95262f4fdb20391b7e75b7ffcee51b176af64d83c06f85545d620200000005ab5151ab52ffffffff044805ef0300000000065353516352639702c802000000000900516351515252ab5270db08040000000009ac516aab526553abac4aabc90500000000096365ab0052636a525100000000", "6565ab6a5152", 0, -2126294159, "ad01ec9d6dbae325ec3a8e1fd98e2d03b1188378210efef093dd8b0b0ef3f19d"], + ["3b937e05032b8895d2f4945cb7e3679be2fbd15311e2414f4184706dbfc0558cf7de7b4d000000000001638b91a12668a3c3ce349788c961c26aa893c862f1e630f18d80e7843686b6e1e6fc396310000000000852635353ab65ac51eeb09dd1c9605391258ee6f74b9ae17b5e8c2ef010dc721c5433dcdc6e93a1593e3b6d1700000000085365ac6553526351ffffffff0308b18e04000000000253acb6dd00040000000008536aac5153ac516ab0a88201000000000500ac006500804e3ff2", "", 0, 416167343, "595a3c02254564634e8085283ec4ea7c23808da97ce9c5da7aecd7b553e7fd7f"], + ["a48f27ca047997470da74c8ee086ddad82f36d9c22e790bd6f8603ee6e27ad4d3174ea875403000000095153ac636aab6aacabffffffffefc936294e468d2c9a99e09909ba599978a8c0891ad47dc00ba424761627cef202000000056a51630053ffffffff304cae7ed2d3dbb4f2fbd679da442aed06221ffda9aee460a28ceec5a9399f4e0200000000f5bddf82c9c25fc29c5729274c1ff0b43934303e5f595ce86316fc66ad263b96ca46ab8d0100000003536500d7cf226b0146b00c04000000000200ac5c2014ce", "515100636563", 0, 1991799059, "9c051a7092fe17fa62b1720bc2c4cb2ffc1527d9fb0b006d2e142bb8fe07bf3c"], + ["180cd53101c5074cf0b7f089d139e837fe49932791f73fa2342bd823c6df6a2f72fe6dba1303000000076a6a63ac53acabffffffff03853bc1020000000007ac526a6a6a6a003c4a8903000000000453515163a0fbbd030000000005ab656a5253253d64cf", "ac65", 0, -1548453970, "4d8efb3b99b9064d2f6be33b194a903ffabb9d0e7baa97a48fcec038072aac06"], + ["c21ec8b60376c47e057f2c71caa90269888d0ffd5c46a471649144a920d0b409e56f190b700000000008acac6a526a536365ffffffff5d315d9da8bf643a9ba11299450b1f87272e6030fdb0c8adc04e6c1bfc87de9a0000000000ea43a9a142e5830c96b0ce827663af36b23b0277244658f8f606e95384574b91750b8e940000000007516a63ac0063acffffffff023c61be0400000000055165ab5263313cc8020000000006006a53526551ed8c3d56", "6a", 1, 1160627414, "a638cc17fd91f4b1e77877e8d82448c84b2a4e100df1373f779de7ad32695112"], + ["128cd90f04b66a4cbc78bf48748f6eec0f08d5193ee8d0a6f2e8d3e5f138ed12c2c87d01a301000000085200ab6aac00ab00ffffffff09fc88bb1851e3dfb3d30179c38e15aeb1b39929c7c74f6acd071994ed4806490300000000e7fc5ea12ec56f56c0d758ecf4bb88aa95f3b08176b336db3b9bec2f6e27336dce28adbe030000000400530051fffffffffd6ff1adcf1fbe0d883451ee46904f1b7e8820243d395559b2d4ee8190a6e891000000000080fb1ae702f85b400000000000035200ab8d9651010000000006ab6a52536aab00000000", "ab", 1, 1667598199, "c10ccc9db8a92d7d4b133a2980782dab9d9d1d633d0dde9f9612ada57771fd89"], + ["da9695a403493d3511c10e1fe1286f954db0366b7667c91ef18ae4578056c1bf752114ac5901000000035351519788d91dd1f9c62dc005d80ea54eb13f7131ca5aace3d5d29f9b58ccc5fbc9a27e779950010000000453ac6a00ffffffffe2556ff29ebe83eb42a32c7a8d93bc598043578f491b5935805a33608538845a030000000252ab65d21b3b018f26c4030000000006acab51535352e1cbcb10", "006565ab52", 2, -1550927794, "0ca673a1ee66f9625ceb9ab278ebef772c113c188112b02824570c17fdf48194"], + ["b240517501334021240427adb0b413433641555424f6d24647211e3e6bfbb22a8045cbda2f000000000071bac8630112717802000000000000000000", "6a5165abac52656551", 0, 1790414254, "2c8be597620d95abd88f9c1cf4967c1ae3ca2309f3afec8928058c9598660e9e"], + ["96bac43903044a199b4b3efeeec5d196ee23fb05495541fa2cd6fb6405a9432d1723363660010000000151ffffffffe6ce2b66ce1488918a3e880bebb0e750123f007c7bcbac8fcd67ce75cb6fbae80300000000ffffffff9c0955aa07f506455834895c0c56be5a095398f47c62a3d431fe125b161d666a0200000005520000abac7ffdbc540216f2f004000000000165a26dce010000000001ab00000000", "5151ab656a656a6a63", 0, -707123065, "26b22e18d5d9081fde9631594a4f7c49069ed2e429f3d08caf9d834f685ccab2"], + ["b8fd394001ed255f49ad491fecc990b7f38688e9c837ccbc7714ddbbf5404f42524e68c18f0000000007ab6353535363ab081e15ee02706f7d050000000008515200535351526364c7ec040000000005636a53acac9206cbe1", "655352ac", 0, -1251578838, "8e0697d8cd8a9ccea837fd798cc6c5ed29f6fbd1892ee9bcb6c944772778af19"], + ["e42a76740264677829e30ed610864160c7f97232c16528fe5610fc08814b21c34eefcea69d010000000653006a6a0052ffffffff647046cf44f217d040e6a8ff3f295312ab4dd5a0df231c66968ad1c6d8f4428000000000025352ffffffff0199a7f900000000000000000000", "655263006a005163", 1, 1122505713, "7cda43f1ff9191c646c56a4e29b1a8c6cb3f7b331da6883ef2f0480a515d0861"], + ["0f034f32027a8e094119443aa9cfe11737c6d7dda9a52b839bc073dcc0235b847b28e0fab60200000006ac53ac536a63eee63447dfdad80476994b68706e916df1bd9d7cb4f3a4f6b14369de84564bea2e8688bd030000000565636a65acf8434663020b35fe01000000000800abab655163acabb3d6a103000000000353acab345eeda0", "526a51ac63ab51", 1, 66020215, "4435e62ff6531ac73529aac9cf878a7219e0b6e6cac79af8487c5355d1ad6d43"], + ["a2dfa4690214c1ab25331815a5128f143219de51a47abdc7ce2d367e683eeb93960a31af9f010000000363636affffffff8be0628abb1861b078fcc19c236bc4cc726fa49068b88ad170adb2a97862e7460200000004ac655363ffffffff0441f11103000000000153dbab0c000000000009ab53ac5365526aab63abbb95050000000004ab52516a29a029040000000003ac526a00000000", "6a52ac63", 1, -1302210567, "913060c7454e6c80f5ba3835454b54db2188e37dc4ce72a16b37d11a430b3d23"], + ["9dbc591f04521670af83fb3bb591c5d4da99206f5d38e020289f7db95414390dddbbeb56680100000004ac5100acffffffffb6a40b5e29d5e459f8e72d39f800089529f0889006cad3d734011991da8ef09d0100000009526a5100acab536a515fc427436df97cc51dc8497642ffc868857ee245314d28b356bd70adba671bd6071301fc0000000000ffffffff487efde2f620566a9b017b2e6e6d42525e4070f73a602f85c6dfd58304518db30000000005516353006a8d8090180244904a0200000000046a65656ab1e9c203000000000451ab63aba06a5449", "", 0, -1414953913, "bae189eb3d64aedbc28a6c28f6c0ccbd58472caaf0cf45a5aabae3e031dd1fea"], + ["1345fb2c04bb21a35ae33a3f9f295bece34650308a9d8984a989dfe4c977790b0c21ff9a7f0000000006ac52ac6a0053ffffffff7baee9e8717d81d375a43b691e91579be53875350dfe23ba0058ea950029fcb7020000000753ab53ab63ab52ffffffff684b6b3828dfb4c8a92043b49b8cb15dd3a7c98b978da1d314dce5b9570dadd202000000086353ab6a5200ac63d1a8647bf667ceb2eae7ec75569ca249fbfd5d1b582acfbd7e1fcf5886121fca699c011d0100000003ac006affffffff049b1eb00300000000001e46dc0100000000080065ab6a6a630065ca95b40300000000030051520c8499010000000006ab6aac526a6500000000", "53526aac636300", 2, 1809978100, "cfeaa36790bc398783d4ca45e6354e1ea52ee74e005df7f9ebd10a680e9607bf"], + ["7d75dc8f011e5f9f7313ba6aedef8dbe10d0a471aca88bbfc0c4a448ce424a2c5580cda1560300000003ab5152ffffffff01997f8e0200000000096552ac6a65656563530d93bbcc", "00656a6563", 0, 1414485913, "ec91eda1149f75bffb97612569a78855498c5d5386d473752a2c81454f297fa7"], + ["1459179504b69f01c066e8ade5e124c748ae5652566b34ed673eea38568c483a5a4c4836ca0100000008ac5352006563656affffffff5d4e037880ab1975ce95ea378d2874dcd49d5e01e1cdbfae3343a01f383fa35800000000095251ac52ac6aac6500ffffffff7de3ae7d97373b7f2aeb4c55137b5e947b2d5fb325e892530cb589bc4f92abd503000000086563ac53ab520052ffffffffb4db36a32d6e543ef49f4bafde46053cb85b2a6c4f0e19fa0860d9083901a1190300000003ab51531bbcfe5504a6dbda040000000008536a5365abac6500d660c80300000000096565abab6a53536a6a54e84e010000000003acac52df2ccf0500000000025351220c857e", "", 2, 1879181631, "3aad18a209fab8db44954eb55fd3cc7689b5ec9c77373a4d5f4dae8f7ae58d14"], + ["d98b777f04b1b3f4de16b07a05c31d79965579d0edda05600c118908d7cf642c9cd670093f020000000953005351ac65ab5363a268caad6733b7d1718008997f249e1375eb3ab9fe68ab0fe170d8e745ea24f54ce67f9b00000000066500516a5151ffffffff7ef8040dfcc86a0651f5907e8bfd1017c940f51cf8d57e3d3fe78d57e40b1e610200000003535263ffffffff39846cfed4babc098ff465256ba3820c30d710581316afcb67cd31c623b703360300000001acffffffff03d405120100000000056300006a5201a73d050000000004ab636a6a294c8c000000000006ac65536553ac00000000", "63525351abac", 1, 2018694761, "86970af23c89b72a4f9d6281e46b9ef5220816bed71ebf1ae20df53f38fe16ff"], + ["cabb1b06045a895e6dcfc0c1e971e94130c46feace286759f69a16d298c8b0f6fd0afef8f20300000004ac006352ffffffffa299f5edac903072bfb7d29b663c1dd1345c2a33546a508ba5cf17aab911234602000000056a65515365ffffffff89a20dc2ee0524b361231092a070ace03343b162e7162479c96b757739c8394a0300000002abab92ec524daf73fabee63f95c1b79fa8b84e92d0e8bac57295e1d0adc55dc7af5534ebea410200000001534d70e79b04674f6f00000000000600abacab53517d60cc0200000000035265ab96c51d040000000004ac6300ac62a787050000000008006a516563ab63639e2e7ff7", "6551ac6351ac", 3, 1942663262, "d0c4a780e4e0bc22e2f231e23f01c9d536b09f6e5be51c123d218e906ec518be"], + ["8b96d7a30132f6005b5bd33ea82aa325e2bcb441f46f63b5fca159ac7094499f380f6b7e2e00000000076aacabac6300acffffffff0158056700000000000465005100c319e6d0", "52006a", 0, -1100733473, "fb4bd26a91b5cf225dd3f170eb09bad0eac314bc1e74503cc2a3f376833f183e"], + ["112191b7013cfbe18a175eaf09af7a43cbac2c396f3695bbe050e1e5f4250603056d60910e02000000001c8a5bba03738a22010000000005525352656a77a149010000000002510003b52302000000000351ac52722be8e6", "65ac6565", 0, -1847972737, "8e795aeef18f510d117dfa2b9f4a2bd2e2847a343205276cedd2ba14548fd63f"], + ["ce6e1a9e04b4c746318424705ea69517e5e0343357d131ad55d071562d0b6ebfedafd6cb840100000003656553ffffffff67bd2fa78e2f52d9f8900c58b84c27ef9d7679f67a0a6f78645ce61b883fb8de000000000100d699a56b9861d99be2838e8504884af4d30b909b1911639dd0c5ad47c557a0773155d4d303000000046a5151abffffffff9fdb84b77c326921a8266854f7bbd5a71305b54385e747fe41af8a397e78b7fa010000000863acac6a51ab00ac0d2e9b9d049b8173010000000007ac53526a650063ba9b7e010000000008526a00525263acac0ab3fd030000000000ea8a0303000000000200aca61a97b9", "", 1, -1276952681, "b6ed4a3721be3c3c7305a5128c9d418efa58e419580cec0d83f133a93e3a22c5"], + ["a7721d94021652d90c79aaf5022d98219337d50f836382403ed313adb1116ba507ac28b0b0010000000551ac6300ab89e6d64a7aa81fb9595368f04d1b36d7020e7adf5807535c80d015f994cce29554fe869b01000000065353ab636500ffffffff024944c90100000000046300635369df9f01000000000000000000", "656a536551ab", 0, -1740151687, "935892c6f02948f3b08bcd463b6acb769b02c1912be4450126768b055e8f183a"], + ["2f7353dd02e395b0a4d16da0f7472db618857cd3de5b9e2789232952a9b154d249102245fd030000000151617fd88f103280b85b0a198198e438e7cab1a4c92ba58409709997cc7a65a619eb9eec3c0200000003636aabffffffff0397481c0200000000045300636a0dc97803000000000009d389030000000003ac6a53134007bb", "0000536552526a", 0, -1912746174, "30c4cd4bd6b291f7e9489cc4b4440a083f93a7664ea1f93e77a9597dab8ded9c"], + ["7d95473604fd5267d0e1bb8c9b8be06d7e83ff18ad597e7a568a0aa033fa5b4e1e2b6f1007020000000465006a6affffffffaee008503bfc5708bd557c7e78d2eab4878216a9f19daa87555f175490c40aaf000000000263abffffffffabd74f0cff6e7ceb9acc2ee25e65af1abcebb50c08306e6c78fa8171c37613dd010000000552acacababffffffff54a3069393f7930fa1b331cdff0cb945ec21c11d4605d8eedba1d3e094c6ae1f01000000026300ffffffff0182edeb050000000009526353ab5153530065a247e8cd", "51516aab00", 2, -426210430, "2707ca714af09494bb4cf0794abe33c6cba5f29891d619e76070269d1fa8e690"], + ["221d4718023d9ca9fe1af178dbfce02b2b369bf823ea3f43f00891b7fef98e215c06b94fdd000000000951005153ab000051acffffffffb1c7ad1c64b7441bf5e70cd0f6eb4ec96821d67fc4997d9e6dfdceadecd36dde01000000070051536a635153ffffffff04e883cd00000000000851ab536553ab0052bbb2f70400000000002f1b2e03000000000165259fcb00000000000010dbde99", "ab", 1, 665721280, "4abce77432a86dfe608e7c1646c18b5253a373392ff962e288e3ab96bba1ba1d"], + ["6f66c0b3013e6ae6aabae9382a4326df31c981eac169b6bc4f746edaa7fc1f8c796ef4e374000000000665ab6aabac6affffffff0191c8d6030000000002525300000000", "6a5352516a635352ab", 0, -1299629906, "48411efeb133c6b7fec4e7bdbe613f827093cb06ea0dbcc2ffcfde3a9ac4356c"], + ["89e7928c04363cb520eff4465251fd8e41550cbd0d2cdf18c456a0be3d634382abcfd4a2130200000006ac516a6a656355042a796061ed72db52ae47d1607b1ceef6ca6aea3b7eea48e7e02429f382b378c4e51901000000085351ab6352ab5252ffffffff53631cbda79b40183000d6ede011c778f70147dc6fa1aed3395d4ce9f7a8e69701000000096a6553ab52516a52abad0de418d80afe059aab5da73237e0beb60af4ac490c3394c12d66665d1bac13bdf29aa8000000000153f2b59ab6027a33eb040000000007005351ac5100ac88b941030000000003ab0052e1e8a143", "63656a", 0, 1258533326, "b575a04b0bb56e38bbf26e1a396a76b99fb09db01527651673a073a75f0a7a34"], + ["ca356e2004bea08ec2dd2df203dc275765dc3f6073f55c46513a588a7abcc4cbde2ff011c7020000000553525100003aefec4860ef5d6c1c6be93e13bd2d2a40c6fb7361694136a7620b020ecbaca9413bcd2a030000000965ac00536352535100ace4289e00e97caaea741f2b89c1143060011a1f93090dc230bee3f05e34fbd8d8b6c399010000000365526affffffff48fc444238bda7a757cb6a98cb89fb44338829d3e24e46a60a36d4e24ba05d9002000000026a53ffffffff03d70b440200000000056a6a526aac853c97010000000002515335552202000000000351635300000000", "0052", 3, -528192467, "fc93cc056c70d5e033933d730965f36ad81ef64f1762e57f0bc5506c5b507e24"], + ["82d4fa65017958d53e562fac073df233ab154bd0cf6e5a18f57f4badea8200b217975e31030200000004636aab51ac0891a204227cc9050000000006635200655365bfef8802000000000865650051635252acfc2d09050000000006ab65ac51516380195e030000000007ac52525352510063d50572", "53", 0, -713567171, "e095003ca82af89738c1863f0f5488ec56a96fb81ea7df334f9344fcb1d0cf40"], + ["75f6949503e0e47dd70426ef32002d6cdb564a45abedc1575425a18a8828bf385fa8e808e600000000036aabab82f9fd14e9647d7a1b5284e6c55169c8bd228a7ea335987cef0195841e83da45ec28aa2e0300000002516350dc6fe239d150efdb1b51aa288fe85f9b9f741c72956c11d9dcd176889963d699abd63f0000000001ab429a63f502777d20010000000007abac52ac516a53d081d9020000000003acac630c3cc3a8", "535152516551510000", 1, 973814968, "c6ec1b7cb5c16a1bfd8a3790db227d2acc836300534564252b57bd66acf95092"], + ["24f24cd90132b2162f938f1c22d3ca5e7daa83515883f31a61a5177aebf99d7db6bdfc398c010000000163ffffffff01d5562d0100000000016300000000", "5265ac5165ac5252ab", 0, 1055129103, "5eeb03e03806cd7bfd44bbba69c30f84c2c5120df9e68cd8facc605fcfbc9693"], + ["5ff2cac201423064a4d87a96b88f1669b33adddc6fa9acdc840c0d8a243671e0e6de49a5b00300000005ac6353655353b91db50180db5a03000000000663535151006a047a3aff", "52ab51ab5365005163", 0, -1336626596, "b8db8d57fe40ab3a99cf2f8ed57da7a65050fcc1d34d4280e25faf10108d3110"], + ["10011f150220ad76a50ccc7bb1a015eda0ff987e64cd447f84b0afb8dc3060bdae5b36a6900200000000ffffffff1e92dd814dfafa830187bc8e5b9258de2445ec07b02c420ee5181d0b203bb334000000000565ab536a65ffffffff0124e65401000000000800ab636553ab53ac00000000", "53abab0051", 0, 440222748, "c6675bf229737e005b5c8ffa6f81d9e2c4396840921b6151316f67c4315a4270"], + ["8b95ec900456648d820a9b8df1d8f816db647df8a8dc9f6e7151ebf6079d90ee3f6861352a02000000085200ab00ac535151ffffffff039b10b845f961225ac0bcaac4f5fe1991029a051aa3d06a3811b5762977a67403000000035252abffffffff8559d65f40d5e261f45aec8aad3d2c56c6114b22b26f7ee54a06f0881be3a7f5010000000765635252536363ffffffff38f8b003b50f6412feb2322b06b270197f81ad69c36af02ca5008b94eee5f650020000000165ffffffff01ae2b00010000000001638eb153a2", "0053ab5300ac53", 2, 1266056769, "205f3653f0142b35ce3ef39625442efebae98cde8cbf0516b97b51073bb0479f"], + ["babbb7ea01ab5d584727cb44393b17cf66521606dc81e25d85273be0d57bad43e8f6b6d43501000000036a656aba83a68803fb0f4a000000000005536353ab633fcfe4020000000009ac00acab6351006a65182a0c03000000000453ac5363bee74f44", "536a6a6a6365ac51ab", 0, -799187625, "3275e98dca37243b977525a07b5d8e369d6c3bdc08cb948029a635547d0d1a4e"], + ["e86a24bc03e4fae784cdf81b24d120348cb5e52d937cd9055402fdba7e43281e482e77a1c100000000046363006affffffffa5447e9bdcdab22bd20d88b19795d4c8fb263fbbf7ce8f4f9a85f865953a6325020000000663ac53535253ffffffff9f8b693bc84e0101fc73748e0513a8cecdc264270d8a4ee1a1b6717607ee1eaa00000000026a513417bf980158d82c020000000009005253005351acac5200000000", "6353516365536a6a", 2, -563792735, "508129278ef07b43112ac32faf00170ad38a500eed97615a860fd58baaad174b"], + ["53bd749603798ed78798ef0f1861b498fc61dcee2ee0f2b37cddb115b118e73bc6a5a47a0201000000096a63656a6aab6a000007ff674a0d74f8b4be9d2e8e654840e99d533263adbdd0cf083fa1d5dd38e44d2d163d900100000007abab5251ac6a51c8b6b63f744a9b9273ccfdd47ceb05d3be6400c1ed0f7283d32b34a7f4f0889cccf06be30000000009516a52636551ab516a9ac1fe63030c677e05000000000027bc610000000000086565636a635100526e2dc60200000000015300000000", "6552536a515351ab", 1, -1617066878, "fe516df92299e995b8e6489be824c6839543071ec5e9286060b2600935bf1f20"], + ["691bf9fc028ca3099020b79184e70039cf53b3c7b3fe695d661fd62d7b433e65feda2150610000000003ac63abffffffff2c814c15b142bc944192bddccb90a392cd05b968b599c1d8cd99a55a28a243fd0100000009ab5300526a5200abac98516a5803dfd3540500000000046552ac522838120100000000040053ab6a4409a903000000000665636a5300658759621b", "65ac5165ab", 0, -359941441, "d582c442e0ecc400c7ba33a56c93ad9c8cfd45af820350a13623594b793486f0"], + ["536bc5e60232eb60954587667d6bcdd19a49048d67a027383cc0c2a29a48b960dc38c5a0370300000005ac636300abffffffff8f1cfc102f39b1c9348a2195d496e602c77d9f57e0769dabde7eaaedf9c69e250100000006acabab6a6351ffffffff0432f56f0400000000046a5365517fd54b0400000000035265539484e4050000000003536a5376dc25020000000008ac536aab6aab536ab978e686", "ac0051006a006a006a", 0, -273074082, "f151f1ec305f698d9fdce18ea292b145a58d931f1518cf2a4c83484d9a429638"], + ["74606eba01c2f98b86c29ba5a32dc7a7807c2abe6ed8d89435b3da875d87c12ae05329e6070200000003510052ffffffff02a1e2c4020000000006516563526a63c68bae04000000000952ab6363ab00006363fe19ae4f", "63ababacac5365", 0, 112323400, "d1b1d79001b4a0324962607b739972d6f39c1493c4500ce814fd3bd72d32a5a0"], + ["2ed805e20399e52b5bcc9dc075dad5cf19049ff5d7f3de1a77aee9288e59c5f4986751483f020000000165ffffffff967531a5726e7a653a9db75bd3d5208fa3e2c5e6cd5970c4d3aba84eb644c72c0300000000ffffffffd79030d20c65e5f8d3c55b5692e5bdaa2ae78cfa1935a0282efb97515feac43f030000000400006365261ab88c02bdf66a000000000003ab6351d6ad8b000000000005525152abac00000000", "630053ab5265", 0, 2072814938, "1d25d16d84d5793be1ad5cda2de9c9cf70e04a66c3dae618f1a7ca4026198e7f"], + ["fab796ee03f737f07669160d1f1c8bf0800041157e3ac7961fea33a293f976d79ce49c02ab0200000003ac5252eb097ea1a6d1a7ae9dace338505ba559e579a1ee98a2e9ad96f30696d6337adcda5a85f403000000096500abab656a6a656396d5d41a9b11f571d91e4242ddc0cf2420eca796ad4882ef1251e84e42b930398ec69dd80100000005526551ac6a8e5d0de804f763bb0400000000015288271a010000000001acf2bf2905000000000300ab51c9641500000000000952655363636365ac5100000000", "00ac536552", 0, -1854521113, "f3bbab70b759fe6cfae1bf349ce10716dbc64f6e9b32916904be4386eb461f1f"], + ["f2b539a401e4e8402869d5e1502dbc3156dbce93583f516a4947b333260d5af1a34810c6a00200000003525363ffffffff01d305e2000000000005acab535200a265fe77", "", 0, -1435650456, "41617b27321a830c712638dbb156dae23d4ef181c7a06728ccbf3153ec53d7dd"], + ["9f10b1d8033aee81ac04d84ceee0c03416a784d1017a2af8f8a34d2f56b767aea28ff88c8f02000000025352ffffffff748cb29843bea8e9c44ed5ff258df1faf55fbb9146870b8d76454786c4549de100000000016a5ba089417305424d05112c0ca445bc7107339083e7da15e430050d578f034ec0c589223b0200000007abac53ac6565abffffffff025a4ecd010000000006636563ab65ab40d2700000000000056a6553526333fa296c", "", 0, -395044364, "20fd0eee5b5716d6cbc0ddf852614b686e7a1534693570809f6719b6fcb0a626"], + ["ab81755f02b325cbd2377acd416374806aa51482f9cc5c3b72991e64f459a25d0ddb52e66703000000036a00ab8727056d48c00cc6e6222be6608c721bc2b1e69d0ffbadd51d131f05ec54bcd83003aac5000000000003f2cdb60454630e020000000007526aac63000000e9e25c040000000003516a0088c97e0000000000076a535265655263771b5805000000000851ab00ac6565515100000000", "5151ab00ac", 0, -230931127, "ba0a2c987fcdd74b6915f6462f62c3f126a0750aa70048f7aa20f70726e6a20b"], + ["7a17e0ef0378dab4c601240639139335da3b7d684600fa682f59b7346ef39386fe9abd69350000000004ac5252ab807f26fb3249326813e18260a603b9ad66f41f05eaa8146f66bcca452162a502aac4aa8b02000000026a534ea460faa7e3d7854ec6c70d7e797025697b547ec500b2c09c873b4d5517767d3f3720660300000000ffffffff01b12e7a02000000000900ab006aab65656a63991c03e2", "6aab6a", 1, -1577994103, "62cd3413d9d819fb7355336365cf8a2a997f7436cc050a7143972044343b3281"], + ["ff2ecc09041b4cf5abb7b760e910b775268abee2792c7f21cc5301dd3fecc1b4233ee70a2c0200000009acac5300006a51526affffffffeb39c195a5426afff38379fc85369771e4933587218ef4968f3f05c51d6b7c92000000000165453a5f039b8dbef7c1ffdc70ac383b481f72f99f52b0b3a5903c825c45cfa5d2c0642cd50200000001654b5038e6c49daea8c0a9ac8611cfe904fc206dad03a41fb4e5b1d6d85b1ecad73ecd4c0102000000096a51000053ab656565bdb5548302cc719200000000000452655265214a3603000000000300ab6a00000000", "52516a006a63", 1, -2113289251, "37ed6fae36fcb3360c69cac8b359daa62230fc1419b2cf992a32d8f3e079dcff"], + ["70a8577804e553e462a859375957db68cfdf724d68caeacf08995e80d7fa93db7ebc04519d02000000045352ab53619f4f2a428109c5fcf9fee634a2ab92f4a09dc01a5015e8ecb3fc0d9279c4a77fb27e900000000006ab6a51006a6affffffff3ed1a0a0d03f25c5e8d279bb5d931b7eb7e99c8203306a6c310db113419a69ad010000000565516300abffffffff6bf668d4ff5005ef73a1b0c51f32e8235e67ab31fe019bf131e1382050b39a630000000004536a6563ffffffff02faf0bb00000000000163cf2b4b05000000000752ac635363acac15ab369f", "ac", 0, -1175809030, "1c9d6816c20865849078f9777544b5ddf37c8620fe7bd1618e4b72fb72dddca1"], + ["a3604e5304caa5a6ba3c257c20b45dcd468f2c732a8ca59016e77b6476ac741ce8b16ca8360200000004acac6553ffffffff695e7006495517e0b79bd4770f955040610e74d35f01e41c9932ab8ccfa3b55d0300000007ac5253515365acffffffff6153120efc5d73cd959d72566fc829a4eb00b3ef1a5bd3559677fb5aae116e38000000000400abab52c29e7abd06ff98372a3a06227386609adc7665a602e511cadcb06377cc6ac0b8f63d4fdb03000000055100acabacffffffff04209073050000000009ab5163ac525253ab6514462e05000000000952abacab636300656a20672c0400000000025153b276990000000000056565ab6a5300000000", "5351", 0, 1460890590, "249c4513a49076c6618aabf736dfd5ae2172be4311844a62cf313950b4ba94be"], + ["c6a72ed403313b7d027f6864e705ec6b5fa52eb99169f8ea7cd884f5cdb830a150cebade870100000009ac63ab516565ab6a51ffffffff398d5838735ff43c390ca418593dbe43f3445ba69394a6d665b5dc3b4769b5d700000000075265acab515365ffffffff7ee5616a1ee105fd18189806a477300e2a9cf836bf8035464e8192a0d785eea3030000000700ac6a51516a52ffffffff018075fd0000000000015100000000", "005251acac5252", 2, -656067295, "2cc1c7514fdc512fd45ca7ba4f7be8a9fe6d3318328bc1a61ae6e7675047e654"], + ["93c12cc30270fc4370c960665b8f774e07942a627c83e58e860e38bd6b0aa2cb7a2c1e060901000000036300abffffffff4d9b618035f9175f564837f733a2b108c0f462f28818093372eec070d9f0a5440300000001acffffffff039c2137020000000001525500990100000000055265ab636a07980e0300000000005ba0e9d1", "656a5100", 1, 18954182, "6beca0e0388f824ca33bf3589087a3c8ad0857f9fe7b7609ae3704bef0eb83e2"], + ["97bddc63015f1767619d56598ad0eb5c7e9f880b24a928fea1e040e95429c930c1dc653bdb0100000008ac53acac00005152aaa94eb90235ed10040000000000287bdd0400000000016a8077673a", "acac6a536352655252", 0, -813649781, "5990b139451847343c9bb89cdba0e6daee6850b60e5b7ea505b04efba15f5d92"], + ["cc3c9dd303637839fb727270261d8e9ddb8a21b7f6cbdcf07015ba1e5cf01dc3c3a327745d0300000000d2d7804fe20a9fca9659a0e49f258800304580499e8753046276062f69dbbde85d17cd2201000000096352536a520000acabffffffffbc75dfa9b5f81f3552e4143e08f485dfb97ae6187330e6cd6752de6c21bdfd21030000000600ab53650063ffffffff0313d0140400000000096565515253526aacac167f0a040000000008acab00535263536a9a52f8030000000006abab5151ab63f75b66f2", "6a635353636a65ac65", 1, 377286607, "dbc7935d718328d23d73f8a6dc4f53a267b8d4d9816d0091f33823bd1f0233e9"], + ["236f91b702b8ffea3b890700b6f91af713480769dda5a085ae219c8737ebae90ff25915a3203000000056300ac6300811a6a10230f12c9faa28dae5be2ebe93f37c06a79e76214feba49bb017fb25305ff84eb020000000100ffffffff041e351703000000000351ac004ff53e050000000003ab53636c1460010000000000cb55f701000000000651520051ab0000000000", "acac636a6aac5300", 0, 406448919, "793a3d3c37f6494fab79ff10c16702de002f63e34be25dd8561f424b0ea938c4"], + ["22e10d2003ab4ea9849a2801921113583b7c35c3710ff49a6003489395789a7cfb1e6051900100000006526a65535151ffffffff82f21e249ec60db33831d33b9ead0d56f6496db64337dcb7f1c3327c47729c4a020000000253abffffffff138f098f0e6a4cf51dc3e7a3b749f487d1ebde71b73b731d1d02ad1180ac7b8c02000000036563acda215011027a9484020000000007635165530000ac4bf6cb0400000000066aacabab65ab3ce3f32c", "ab0052ab", 2, 1136359457, "b5bd080bbcb8cd652f440484311d7a3cb6a973cd48f03c5c00fd6beb52dfc061"], + ["c47d5ad60485cb2f7a825587b95ea665a593769191382852f3514a486d7a7a11d220b62c54000000000663655253acab8c3cf32b0285b040e50dcf6987ddf7c385b3665048ad2f9317b9e0c5ba0405d8fde4129b00000000095251ab00ac65635300ffffffff549fe963ee410d6435bb2ed3042a7c294d0c7382a83edefba8582a2064af3265000000000152fffffffff7737a85e0e94c2d19cd1cde47328ece04b3e33cd60f24a8a345da7f2a96a6d0000000000865ab6a0051656aab28ff30d5049613ea020000000005ac51000063f06df1050000000008ac63516aabac5153afef5901000000000700656500655253688bc00000000000086aab5352526a53521ff1d5ff", "51ac52", 2, -1296011911, "0c1fd44476ff28bf603ad4f306e8b6c7f0135a441dc3194a6f227cb54598642a"], + ["0b43f122032f182366541e7ee18562eb5f39bc7a8e5e0d3c398f7e306e551cdef773941918030000000863006351ac51acabffffffffae586660c8ff43355b685dfa8676a370799865fbc4b641c5a962f0849a13d8250100000005abab63acabffffffff0b2b6b800d8e77807cf130de6286b237717957658443674df047a2ab18e413860100000008ab6aac655200ab63ffffffff04f1dbca03000000000800635253ab656a52a6eefd0300000000036365655d8ca90200000000005a0d530400000000015300000000", "65ac65acac", 0, 351448685, "86f26e23822afd1bdfc9fff92840fc1e60089f12f54439e3ab9e5167d0361dcf"], + ["4b0ecc0c03ba35700d2a30a71f28e432ff6ac7e357533b49f4e97cf28f1071119ad6b97f3e0300000008acab516363ac63acffffffffcd6a2019d99b5c2d639ddca0b1aa5ea7c1326a071255ea226960bd88f45ca57d00000000085253655363005353ffffffffba257635191c9f216de3277be548cb5a2313114cb1a4c563b03b4ef6c0f4f7040300000001abda542edf0495cdc40100000000026353c049e903000000000752516a53ab65512b0f9304000000000963ab516aac65516552fa9ece050000000009acab6500005152530000000000", "65ab51525352510052", 1, -1355414590, "3cd85f84aae6d702436f3f9b8980adcc1f8f202e957759540a27da0a32fc6c87"], + ["adaac0a803f66811346271c733036d6e0d45e15a9b602092e2e04ad93564f196e7f020b088000000000600526a636a00700ec3f9db07a3a6ce910bf318c7ec87a876e1f2a3366cc69f20cde09203b99c1cb9d15800000000050000ac636a4d0de554ebe95c6cc14faf5ff6361d1deba9474b8b0fd3b93c011cd96aec783abb3f36830200000005ab65005251ffffffff0464eb10050000000007520000ab6a65ab1beaa80300000000005a2f31050000000006526aab65ac52ba7db10000000000045251ab6a0cfb46e7", "ab0051ac52636a", 1, -184733716, "961ff413850336d3987c550404fc1d923266ca36cc9ffee7113edb3a9fea7f30"], + ["af1c4ab301ec462f76ee69ba419b1b2557b7ded639f3442a3522d4f9170b2d6859765c3df402000000016affffffff01a5ca6c000000000008ab52536aab00005300000000", "6a6351", 0, 110304602, "e88ed2eea9143f2517b15c03db00767eb01a5ce12193b99b964a35700607e5f4"], + ["0bfd34210451c92cdfa02125a62ba365448e11ff1db3fb8bc84f1c7e5615da40233a8cd368010000000252ac9a070cd88dec5cf9aed1eab10d19529720e12c52d3a21b92c6fdb589d056908e43ea910e0200000009ac516a52656a6a5165ffffffffc3edcca8d2f61f34a5296c405c5f6bc58276416c720c956ff277f1fb81541ddd00000000030063abffffffff811247905cdfc973d179c03014c01e37d44e78f087233444dfdce1d1389d97c302000000065163000063ab1724a26e02ca37c902000000000851ab53525352ac529012a90100000000085200525253535353fa32575b", "5352ac6351", 1, -1087700448, "b8f1e1f35e3e1368bd17008c756e59cced216b3c699bcd7bebdb5b6c8eec4697"], + ["2c84c0640487a4a695751d3e4be48019dbaea85a6e854f796881697383ea455347d2b2769001000000055265526500ffffffff6aac176d8aa00778d496a7231eeb7d3334f20c512d3db1683276402100d98de5030000000700536a5263526ac1ee9ceb171c0c984ebaf12c234fd1487fbf3b3d73aa0756907f26837efba78d1bed33200300000001ab4d9e8ec0bed837cb929bbed76ee848959cec59de44bd7667b7631a744f880d5c71a20cfd0100000007005363515300abffffffff023753fb0000000000036565532d3873050000000009005152ab6a63acab5200000000", "ab650053ab", 0, -877941183, "c49af297dffe2d80deddf10ceea84b99f8554bd2d55bbdc34e449728c31f0835"], + ["1f7e4b1b045d3efa6cd7a11d7873a8bab886c19bd11fcb6712f0948f2db3a7be76ff76c8f100000000095265ab6a0065ac5363ffffffffdaafcfa6029336c997680a541725190f09a6f6da21e54560eca4b5b8ae987da1000000000952ac52acac52515165ffffffff825a38d3b1e5bb4d10f33653ab3ab6882c7abdaec74460257d1528ce7be3f98e0100000007526a006a656a63c14adc8f04953a5d3d3f89237f38b857dd357713896d36215f7e8b77b11d98ea3cdc93df02000000015212484f6104bfafae0300000000025263a2b0120000000000056563ab00516c4d2605000000000653ac6500655301cc93030000000002acab14643b1f", "63acac53ab", 0, 333824258, "18da6ceb011cd36f15ad7dd6c55ef07e6f6ed48881ce3bb31416d3c290d9a0e9"], + ["467a3e7602e6d1a7a531106791845ec3908a29b833598e41f610ef83d02a7da3a1900bf2960000000005ab6a636353ffffffff031db6dac6f0bafafe723b9199420217ad2c94221b6880654f2b35114f44b1df010000000965ab52636a63ac6352ffffffff02b3b95c0100000000026300703216030000000001ab3261c0aa", "6a", 0, 2110869267, "3078b1d1a7713c6d101c64afe35adfae0977a5ab4c7e07a0b170b041258adbf2"], + ["8713bc4f01b411149d575ebae575f5dd7e456198d61d238695df459dd9b86c4e3b2734b62e0300000004abac6363ffffffff03b58049050000000002ac653c714c04000000000953656a005151526a527b5a9e03000000000652ac5100525300000000", "52", 0, -647281251, "0e0bed1bf2ff255aef6e5c587f879ae0be6222ab33bd75ee365ec6fbb8acbe38"], + ["f2ba8a8701b9c401efe3dd0695d655e20532b90ac0142768cee4a3bb0a89646758f544aa8102000000036a52527899f4e4040c6f0b030000000008636565ab530051ab52b60c000000000009515200ab630053ac53a49c5f040000000008ab53ab516300ab63fa27340300000000015100000000", "ac63abab5251", 0, -1328936437, "ab61497afd39e61fe06bc5677326919716f9b20083c9f3417dcea905090e0411"], + ["b5a7df6102107beded33ae7f1dec0531d4829dff7477260925aa2cba54119b7a07d92d5a1d02000000046a516a52803b625c334c1d2107a326538a3db92c6c6ae3f7c3516cd90a09b619ec6f58d10e77bd6703000000056563006a63ffffffff0117484b03000000000853acab52526a65abc1b548a1", "ac006a525100", 0, 2074359913, "680336db57347d8183b8898cd27a83f1ba5884155aeae5ce20b4840b75e12871"], + ["278cb16204b9dadf400266106392c4aa9df01ba03af988c8139dae4c1818ac009f13fc5f1a00000000065200ac656a52ffffffffd006bbebd8cbd7bdead24cddc9badfcc6bc0c2e63c037e5c29aa858f5d0f3e7d01000000046a0051acffffffffbc62a5f57e58da0b67956003ae81ac97cb4cbd1d694c914fc41515c008c4d8fd020000000165e329c844bcc16164be64b64a81cbf4ffd41ed2934e0daa0040ccb8365bab0b2a9e401c180300000003ab52abffffffff02588460030000000000a25a12030000000005535100005300000000", "6553ab6a5300acab51", 3, 989407546, "1c29f110576f4a3b257f67454d99dfc0dee62ef5517ca702848ce4bd2ea1a1d7"], + ["49eb2178020a04fca08612c34959fd41447319c190fb7ffed9f71c235aa77bec28703aa1820200000003ac6353abaff326071f07ec6b77fb651af06e8e8bd171068ec96b52ed584de1d71437fed186aecf0300000001acffffffff03da3dbe02000000000652ac63ac6aab8f3b680400000000096a536a65636a53516a5175470100000000016500000000", "6a536365", 0, 1283691249, "c670219a93234929f662ecb9aa148a85a2d281e83f4e53d10509461cdea47979"], + ["0f96cea9019b4b3233c0485d5b1bad770c246fe8d4a58fb24c3b7dfdb3b0fd90ea4e8e947f0300000006006a5163515303571e1e01906956030000000005ab635353abadc0fbbe", "acac", 0, -1491469027, "716a8180e417228f769dcb49e0491e3fda63badf3d5ea0ceeac7970d483dd7e2"], + ["9a7d858604577171f5fe3f3fd3e5e039c4b0a06717a5381e9977d80e9f53e025e0f16d2877020000000752636565536353ffffffff5862bd028e8276e63f044be1dddcbb8d0c3fa097678308abf2b0f45104a93dbd0100000001531200667ba8fdd3b28e98a35da73d3ddfe51e210303d8eb580f923de988ee632d77793892030000000752526363526563ffffffffe9744eb44db2658f120847c77f47786d268c302120d269e6004455aa3ea5f5e20200000009ab6300636aab656551ffffffff03c61a3c020000000009ab516a6aab6aab53ab737f1a05000000000853acabab655365ab92a4a00400000000016367edf6c8", "535352ab", 3, 659348595, "d36ee79fc80db2e63e05cdc50357d186181b40ae20e3720878284228a13ee8b3"], + ["148e68480196eb52529af8e83e14127cbfdbd4a174e60a86ac2d86eac9665f46f4447cf7aa01000000045200ac538f8f871401cf240c0300000000065252ab52656a5266cf61", "", 0, -344314825, "eacc47c5a53734d6ae3aedbc6a7c0a75a1565310851b29ef0342dc4745ceb607"], + ["e2bc29d4013660631ba14ecf75c60ec5e9bed7237524d8c10f66d0675daa66d1492cb834530200000004ac510065e42d0c9e04f2b26c01000000000951525152acac65ababa35b7504000000000953ac6aac00650053ab94688c0400000000056365526553a1bced0300000000016a00000000", "65ab0063655353", 0, -888431789, "59a34b3ed3a1cce0b104de8f7d733f2d386ffc7445efae67680cd90bc915f7e0"], + ["0c8a70d70494dca6ab05b2bc941b5b431c43a292bd8f2f02eab5e240a408ca73a676044a4103000000056a51ab006affffffff84496004e54836c035821f14439149f22e1db834f315b24588ba2f031511926c0100000000ffffffffbbc5e70ed1c3060ba1bfe99c1656a3158a7307c3ce8eb362ec32c668596d2bd30000000009636563635351abab00b039344c6fc4f9bec24322e45407af271b2d3dfec5f259ee2fc7227bc5285e22b3be85b40100000009ac00ab53abac6a5352e5ddfcff02d50231020000000005006a51536ab086d9020000000006ababac51ac6a00000000", "abab636565acac6a", 3, 241546088, "643a7b4c8d832e14d5c10762e74ec84f2c3f7ed96c03053157f1bed226614911"], + ["f98f79cf0274b745e1d6f36da7cbe205a79132a7ad462bdc434cfb1dcd62a6977c3d2a5dbc010000000553516a5365ffffffff4f89f485b53cdad7fb80cc1b7e314b9735b9383bc92c1248bb0e5c6173a55c0d010000000353655293f9b014045ad96d02000000000963ac526a53ac636365f4c27904000000000952536563635152526a2788f0030000000002516aff5add01000000000863530051655351abd04716ba", "ab6552536a53", 1, -2128899945, "56d29f5e300ddfed2cd8dcce5d79826e193981d0b70dc7487772c8a0b3b8d7b1"], + ["6c7913f902aa3f5f939dd1615114ce961beda7c1e0dd195be36a2f0d9d047c28ac62738c3a020000000453abac00ffffffff477bf2c5b5c6733881447ac1ecaff3a6f80d7016eee3513f382ad7f554015b970100000007ab6563acab5152ffffffff04e58fe1040000000009ab00526aabab526553e59790010000000002ab525a834b03000000000035fdaf0200000000086551ac65515200ab00000000", "63ac53", 1, 1285478169, "1536da582a0b6de017862445e91ba14181bd6bf953f4de2f46b040d351a747c9"], + ["4624aa9204584f06a8a325c84e3b108cafb97a387af62dc9eab9afd85ae5e2c71e593a3b690200000003636a005eb2b44eabbaeca6257c442fea00107c80e32e8715a1293cc164a42e62ce14fea146220c020000000090b9ee38106e3310037bfc519fd209bdbd21c588522a0e96df5fba4e979392bc993bfe9f01000000086363636a635353ab6f1907d218ef6f3c729d9200e23c1dbff2df58b8b1282c6717b26cf760ee4c880d23f4d100000000086a516a536a525163ffffffff01d6f162050000000000ebbab208", "525365ab0053", 1, -1515409325, "6cf9cd409b7185b1f118171f0a34217af5b612ea54195ea186505b667c19337f"], + ["16562fc503f1cf9113987040c408bfd4523f1512da699a2ca6ba122dc65677a4c9bf7763830000000003636552ffffffff1ec1fab5ff099d1c8e6b068156f4e39b5543286bab53c6d61e2582d1e07c96cf02000000045163656affffffffd0ef40003524d54c08cb4d13a5ee61c84fbb28cde9eca7a6d11ba3a9335d8c620100000007635153536a6300fbb84fc2012003a601000000000363ab6a00000000", "63636a006a6aab", 0, -1310262675, "1efbf3d37a92bc03d9eb950b792f307e95504f7c4998f668aa250707ebb752ac"], + ["531665d701f86bacbdb881c317ef60d9cd1baeffb2475e57d3b282cd9225e2a3bf9cbe0ded01000000086300ac515263acabffffffff0453a8500100000000086353acab516a6565e5e9200500000000026a52a44caa00000000000453ac000065e41b0500000000076500ac0065526ab4476f4d", "006563006aab00636a", 0, 1770013777, "0898b26dd3ca08632a5131fa48eb55b44386d0c5070c24d6e329673d5e3693b8"], + ["0f1227a20140655a3da36e413b9b5d108a866f6f147eb4940f032f5a89854eae6d7c3a91600100000009525363515153515253e37a79480161ab61020000000001ab00000000", "ab65005200", 0, -1996383599, "979782dc3f36d908d37d7e4046a38d306b4b08ddc60a5eba355fe3d6da1b29a9"], + ["063ff6eb01aff98d0d2a6db224475010edb634c2f3b46257084676adeb84165a4ff8558d7601000000066353006a5165deb3262c042d109c0000000000076363ab52ac005200b9c4050000000007516300ac510063cfffc800000000000200639e815501000000000700526a52ac6365ac7b07b8", "656552abac6500", 0, -1559847112, "674a4bcb04247f8dc98780f1792cac86b8aee41a800fc1e6f5032f6e1dccde65"], + ["3320f6730132f830c4681d0cae542188e4177cad5d526fae84565c60ceb5c0118e844f90bd030000000163ffffffff0257ec5a040000000005525251ac6538344d000000000002515200000000", "5352656a53ac516a65", 0, 788050308, "3afacaca0ef6be9d39e71d7b1b118994f99e4ea5973c9107ca687d28d8eba485"], + ["c13aa4b702eedd7cde09d0416e649a890d40e675aa9b5b6d6912686e20e9b9e10dbd40abb1000000000863ab6353515351ac11d24dc4cc22ded7cdbc13edd3f87bd4b226eda3e4408853a57bcd1becf2df2a1671fd1600000000045165516affffffff01baea300100000000076aab52ab53005300000000", "0065", 0, -1195908377, "241a23e7b1982d5f78917ed97a8678087acbbffe7f624b81df78a5fe5e41e754"], + ["d9a6f20e019dd1b5fae897fb472843903f9c3c2293a0ffb59cff2b413bae6eceab574aaf9d030000000663ab006a515102f54939032df5100100000000056a51ab65530ec28f010000000004ac5100007e874905000000000651005265ac6a00000000", "abacab63acacabab", 0, 271463254, "1326a46f4c21e7619f30a992719a905aa1632aaf481a57e1cbd7d7c22139b41e"], + ["157c81bf0490432b3fcb3f9a5b79e5f91f67f05efb89fa1c8740a3fe7e9bdc18d7cb6acd2203000000026351ffffffff912e48e72bbcf8a540b693cf8b028e532a950e6e63a28801f6eaad1afcc52ad00000000000b1a4b170a2b9e60e0cad88a0085137309f6807d25d5afb5c1e1d32aa10ba1cdf7df596dd0000000009525165656a51ab65ab3674fba32a76fe09b273618d5f14124465933f4190ba4e0fd09d838daafc6223b31642ac00000000086a53536551ac6565ffffffff01fe9fb6030000000008ab51656a5165636a00000000", "ab00ab6a6551", 3, -64357617, "1ddaab7f973551d71f16bd70c4c4edbf7225e64e784a6da0ee7f7a9fe4f12a0b"], + ["a2692fff03b2387f5bacd5640c86ba7df574a0ee9ed7f66f22c73cccaef3907eae791cbd230200000004536363abffffffff4d9fe7e5b375de88ba48925d9b2005447a69ea2e00495a96eafb2f144ad475b40000000008000053000052636537259bee3cedd3dcc07c8f423739690c590dc195274a7d398fa196af37f3e9b4a1413f810000000006ac63acac52abffffffff04c65fe60200000000075151536365ab657236fc020000000009005263ab00656a6a5195b8b6030000000007ac5165636aac6a7d7b66010000000002acab00000000", "51", 2, -826546582, "925037c7dc7625f3f12dc83904755a37016560de8e1cdd153c88270a7201cf15"], + ["2c5b003201b88654ac2d02ff6762446cb5a4af77586f05e65ee5d54680cea13291efcf930d0100000005ab536a006a37423d2504100367000000000004536a515335149800000000000152166aeb03000000000452510063226c8e03000000000000000000", "635251", 0, 1060344799, "7e058ca5dd07640e4aae7dea731cfb7d7fef1bfd0d6d7b6ce109d041f4ca2a31"], + ["f981b9e104acb93b9a7e2375080f3ea0e7a94ce54cd8fb25c57992fa8042bdf4378572859f0100000002630008604febba7e4837da77084d5d1b81965e0ea0deb6d61278b6be8627b0d9a2ecd7aeb06a0300000005ac5353536a42af3ef15ce7a2cd60482fc0d191c4236e66b4b48c9018d7dbe4db820f5925aad0e8b52a0300000008ab0063510052516301863715efc8608bf69c0343f18fb81a8b0c720898a3563eca8fe630736c0440a179129d03000000086aac6a52ac6a63ac44fec4c00408320a03000000000062c21c030000000007ac6a655263006553835f0100000000015303cd60000000000005535263536558b596e0", "00", 0, -2140385880, "49870a961263354c9baf108c6979b28261f99b374e97605baa532d9fa3848797"], + ["e7416df901269b7af14a13d9d0507709b3cd751f586ce9d5da8d16a121e1bd481f5a086e1103000000056aab005200ffffffff01aa269c040000000006acac6a6a5263ee718de6", "ab525363", 0, 1309186551, "eea7d2212bda2d408fff146f9ae5e85e6b640a93b9362622bb9d5e6e36798389"], + ["402a815902193073625ab13d876190d1bbb72aecb0ea733c3330f2a4c2fe6146f322d8843a0300000008656aab0000535363fffffffff9dccdec5d8509d9297d26dfcb1e789cf02236c77dc4b90ebccbf94d1b5821150300000001510bf1f96a03c5c145000000000002ac6ae11b1c0100000000055163516a5239c8a600000000000365636300000000", "63536aacab", 0, -1811424955, "0090803a20102a778ab967a74532faee13e03b702083b090b1497bc2267ee2fe"], + ["c4b702e502f1a54f235224f0e6de961d2e53b506ab45b9a40805d1dacd35148f0acf24ca5e00000000085200ac65ac53acabf34ba6099135658460de9d9b433b84a8562032723635baf21ca1db561dce1c13a06f4407000000000851ac006a63516aabffffffff02a853a603000000000163d17a67030000000005ab63006a5200000000", "ac5363515153", 1, 480734903, "5c46f7ac3d6460af0da28468fcc5b3c87f2b9093d0f837954b7c8174b4d7b6e7"], + ["9b83f78704f492b9b353a3faad8d93f688e885030c274856e4037818848b99e490afef27770200000000ffffffff36b60675a5888c0ef4d9e11744ecd90d9fe9e6d8abb4cff5666c898fdce98d9e00000000056aab656352596370fca7a7c139752971e169a1af3e67d7656fc4fc7fd3b98408e607c2f2c836c9f27c030000000653ac51ab6300a0761de7e158947f401b3595b7dc0fe7b75fa9c833d13f1af57b9206e4012de0c41b8124030000000953656a53ab53510052242e5f5601bf83b301000000000465516a6300000000", "63515200ac656365", 3, -150879312, "9cf05990421ea853782e4a2c67118e03434629e7d52ab3f1d55c37cf7d72cdc4"], + ["f492a9da04f80b679708c01224f68203d5ea2668b1f442ebba16b1aa4301d2fe5b4e2568f3010000000953005351525263ab65ffffffff93b34c3f37d4a66df255b514419105b56d7d60c24bf395415eda3d3d8aa5cd0101000000020065ffffffff9dba34dabdc4f1643b372b6b77fdf2b482b33ed425914bb4b1a61e4fad33cf390000000002ab52ffffffffbbf3dc82f397ef3ee902c5146c8a80d9a1344fa6e38b7abce0f157be7adaefae0000000009515351005365006a51ffffffff021359ba010000000000403fea0200000000095200ac6353abac635300000000", "00ac51acacac", 0, -2115078404, "fd44fc98639ca32c927929196fc3f3594578f4c4bd248156a25c04a65bf3a9f3"], + ["2f73e0b304f154d3a00fde2fdd40e791295e28d6cb76af9c0fd8547acf3771a02e3a92ba37030000000852ac6351ab6565639aa95467b065cec61b6e7dc4d6192b5536a7c569315fb43f470078b31ed22a55dab8265f02000000080065636a6aab6a53ffffffff9e3addbff52b2aaf9fe49c67017395198a9b71f0aa668c5cb354d06c295a691a0100000000ffffffff45c2b4019abaf05c5e484df982a4a07459204d1343a6ee5badade358141f8f990300000007ac516a6aacac6308655cd601f3bc2f0000000000015200000000", "", 0, -2082053939, "9a95e692e1f78efd3e46bb98f178a1e3a0ef60bd0301d9f064c0e5703dc879c2"], + ["5a60b9b503553f3c099f775db56af3456330f1e44e67355c4ab290d22764b9144a7b5f959003000000030052acbd63e0564decc8659aa53868be48c1bfcda0a8c9857b0db32a217bc8b46d9e7323fe9649020000000553ac6551abd0ecf806211db989bead96c09c7f3ec5f73c1411d3329d47d12f9e46678f09bac0dc383e0200000000ffffffff01494bb202000000000500516551ac00000000", "ac", 0, 1169947809, "62a36c6e8da037202fa8aeae03e533665376d5a4e0a854fc4624a75ec52e4eb1"], + ["7e98d353045569c52347ca0ff2fdba608829e744f61eb779ffdb5830aae0e6d6857ab2690e03000000075365acab656352ffffffffa890dd37818776d12da8dca53d02d243ef23b4535c67016f4c58103eed85360f030000000093dbacdc25ca65d2951e047d6102c4a7da5e37f3d5e3c8b87c29b489360725dcd117ee2003000000056a6300ac53c7e99fa1dc2b8b51733034e6555f6d6de47dbbf1026effac7db80cb2080678687380dc1e02000000075352005263516affffffff04423272040000000008ab6353ab65510051e0f53b0500000000086300516552635152f74a5f04000000000853acab0053ab52ab0e8e5f00000000000951ac5363516a6aabab00000000", "6a5163ab52", 3, 890006103, "476868cecd1763c91dade98f17defa42d31049547df45acffa1cc5ae5c3d75d6"], + ["e3649aa40405e6ffe377dbb1bbbb672a40d8424c430fa6512c6165273a2b9b6afa9949ec430200000007630052ab655153a365f62f2792fa90c784efe3f0981134d72aac0b1e1578097132c7f0406671457c332b84020000000353ab6ad780f40cf51be22bb4ff755434779c7f1def4999e4f289d2bd23d142f36b66fbe5cfbb4b01000000076a5252abac52ab1430ffdc67127c9c0fc97dcd4b578dab64f4fb9550d2b59d599773962077a563e8b6732c02000000016affffffff04cb2687000000000002ab636e320904000000000252acf70e9401000000000100dc3393050000000006ab0063536aacbc231765", "65520053", 3, -2016196547, "f64f805f0ff7f237359fa6b0e58085f3c766d1859003332223444fd29144112a"], + ["1d033569040700441686672832b531ab55db89b50dc1f9fc00fb72218b652da9dcfbc83be901000000066551ac526a632b390f9ad068e5fdee6563e88e2a8e4e09763c861072713dc069893dc6bbc9db3f00e26502000000096a5363526565525252ffffffff8a36bdd0aaf38f6707592d203e14476ca9f259021e487135c7e8324244057ed90300000000ed3fb2a3dfd4d46b5f3603fe0148653911988457bd0ed7f742b07c452f5476c228ff9f600200000007526aac00525152ffffffff04b88e48030000000000c753d602000000000853510000006553518fda2603000000000853ac52acac5263534839f1030000000006ac006aacac5300000000", "516553635300ab0052", 1, 2075958316, "c2cefaec2293134acbcf6d2a8bf2b3eb42e4ec04ee8f8bf30ff23e65680677c1"], + ["4c4be7540344050e3044f0f1d628039a334a7c1f7b4573469cfea46101d6888bb6161fe9710200000000ffffffffac85a4fdad641d8e28523f78cf5b0f4dc74e6c5d903c10b358dd13a5a1fd8a06000000000163e0ae75d05616b72467b691dc207fe2e65ea35e2eadb7e06ea442b2adb9715f212c0924f10200000000ffffffff0194ddfe02000000000265ac00000000", "00006500", 1, -479922562, "d66924d49f03a6960d3ca479f3415d638c45889ce9ab05e25b65ac260b51d634"], + ["202c18eb012bc0a987e69e205aea63f0f0c089f96dd8f0e9fcde199f2f37892b1d4e6da90302000000055352ac6565ffffffff0257e5450100000000025300ad257203000000000000000000", "520052ac6a005265", 0, 168054797, "502967a6f999f7ee25610a443caf8653dda288e6d644a77537bcc115a8a29894"], + ["32fa0b0804e6ea101e137665a041cc2350b794e59bf42d9b09088b01cde806ec1bbea077df0200000008515153650000006506a11c55904258fa418e57b88b12724b81153260d3f4c9f080439789a391ab147aabb0fa0000000007000052ac51ab510986f2a15c0d5e05d20dc876dd2dafa435276d53da7b47c393f20900e55f163b97ce0b800000000008ab526a520065636a8087df7d4d9c985fb42308fb09dce704650719140aa6050e8955fa5d2ea46b464a333f870000000009636300636a6565006affffffff01994a0d040000000002536500000000", "516563530065", 2, -163068286, "f58637277d2bc42e18358dc55f7e87e7043f5e33f4ce1fc974e715ef0d3d1c2a"], + ["ae23424d040cd884ebfb9a815d8f17176980ab8015285e03fdde899449f4ae71e04275e9a80100000007ab006553530053ffffffff018e06db6af519dadc5280c07791c0fd33251500955e43fe4ac747a4df5c54df020000000251ac330e977c0fec6149a1768e0d312fdb53ed9953a3737d7b5d06aad4d86e9970346a4feeb5030000000951ab51ac6563ab526a67cabc431ee3d8111224d5ecdbb7d717aa8fe82ce4a63842c9bd1aa848f111910e5ae1eb0100000004ac515300bfb7e0d7048acddc030000000009636a5253636a655363a3428e040000000001525b99c6050000000004655265ab717e6e020000000000d99011eb", "ac6a6a516565", 1, -716251549, "b098eb9aff1bbd375c70a0cbb9497882ab51f3abfebbf4e1f8d74c0739dc7717"], + ["030f44fc01b4a9267335a95677bd190c1c12655e64df74addc53b753641259af1a54146baa020000000152e004b56c04ba11780300000000026a53f125f001000000000251acd2cc7c03000000000763536563655363c9b9e50500000000015200000000", "ac", 0, -1351818298, "19dd32190ed2a37be22f0224a9b55b91e37290577c6c346d36d32774db0219a3"], + ["c05f448f02817740b30652c5681a3b128322f9dc97d166bd4402d39c37c0b14506d8adb5890300000003536353ffffffffa188b430357055ba291c648f951cd2f9b28a2e76353bef391b71a889ba68d5fc02000000056565526a6affffffff02745f73010000000001ab3ec34c0400000000036aac5200000000", "516551510053", 0, -267877178, "3a1c6742d4c374f061b1ebe330b1e169a113a19792a1fdde979b53e094cc4a3c"], + ["163ba45703dd8c2c5a1c1f8b806afdc710a2a8fc40c0138e2d83e329e0e02a9b6c837ff6b8000000000700655151ab6a522b48b8f134eb1a7e6f5a6fa319ce9d11b36327ba427b7d65ead3b4a6a69f85cda8bbcd22030000000563656552acffffffffdbcf4955232bd11eef0cc6954f3f6279675b2956b9bcc24f08c360894027a60201000000066500006500abffffffff04d0ce9d0200000000008380650000000000015233f360040000000003006aabedcf0801000000000000000000", "000065006500ac", 0, 216965323, "9afe3f4978df6a86e9a8ebd62ef6a9d48a2203f02629349f1864ef2b8b92fd55"], + ["07f7f5530453a12ad0c7eb8fbc3f140c7ab6818144d67d2d8752600ca5d9a9358e2dff87d4000000000663526aab526a9e599c379d455e2da36d0cde88d931a863a3e97e01e93b9edb65856f3d958dc08b92b720000000000165bbc8d66dae3b1b170a6e2457f5b161465cb8706e0e6ffc6af55deb918365f14c5f40d4890100000000a7bd77c069ee4b48638e2363fcf2a86b02bea022047bd9fcb16d2b94ad068308d19b31cb00000000066aab5300ab529672aa8f01dbd8a205000000000663536353006a02e99901", "ac006351006a63ab63", 1, 119789359, "6629a1e75c6ae8f4f9d5f734246b6a71682a5ea57246040ef0584f6b97916175"], + ["fe647f950311bf8f3a4d90afd7517df306e04a344d2b2a2fea368935faf11fa6882505890d0000000005ab5100516affffffff43c140947d9778718919c49c0535667fc6cc727f5876851cb8f7b6460710c7f60100000000ffffffffce4aa5d90d7ab93cbec2e9626a435afcf2a68dd693c15b0e1ece81a9fcbe025e0300000000ffffffff02f34806020000000002515262e54403000000000965635151ac655363636de5ce24", "6a005100ac516351", 2, 989643518, "818a7ceaf963f52b5c48a7f01681ac6653c26b63a9f491856f090d9d60f2ffe3"], + ["a1050f8604d0f9d2feefcdb5051ae0052f38e21bf39daf583fd0c3900faa3eab5d431c0bbe030000000653536a005151683d27e5c6e0da8f22125823f32d5d98477d8098ef36263b9694d61d4d85d3f2ac02b7570200000007000052005165abffffffff0cad981542bcb54a87d9400aa63e514c7c6fab7158c2b1fb37821ea755eb162a0200000000b94feb5100e5ef3bf8ed8d43356c8a8d5ac6c7e80d7ff6040f4f0aa19abbe783f4f461240200000007636500000052655686fd70042be3ad02000000000465ab636a15680b000000000004acac53511277c705000000000452635252d27a0102000000000000000000", "6a6aacab65655251", 1, -982144648, "dfcf484111801989eb6df8dc2bafb944d7365ffeb36a575a08f3270d3ef24c9f"], + ["cef7316804c3e77fe67fc6207a1ea6ae6eb06b3bf1b3a4010a45ae5c7ad677bb8a4ebd16d90200000009ac536a5152ac5263005301ab8a0da2b3e0654d31a30264f9356ba1851c820a403be2948d35cafc7f9fe67a06960300000006526a63636a53ffffffffbada0d85465199fa4232c6e4222df790470c5b7afd54704595a48eedd7a4916b030000000865ab63ac006a006ab28dba4ad55e58b5375053f78b8cdf4879f723ea4068aed3dd4138766cb4d80aab0aff3d0300000003ac6a00ffffffff010f5dd6010000000006ab006aab51ab00000000", "", 1, 889284257, "d0f32a6db43378af84b063a6706d614e2d647031cf066997c48c04de3b493a94"], + ["7b3ff28004ba3c7590ed6e36f45453ebb3f16636fe716acb2418bb2963df596a50ed954d2e03000000065251515265abffffffff706ee16e32e22179400c9841013971645dabf63a3a6d2d5feb42f83aa468983e030000000653ac51ac5152ffffffffa03a16e5e5de65dfa848b9a64ee8bf8656cc1f96b06a15d35bd5f3d32629876e020000000043c1a3965448b3b46f0f0689f1368f3b2981208a368ec5c30defb35595ef9cf95ffd10e902000000036aac65253a5bbe042e907204000000000800006565656352634203b4020000000002656336b3b7010000000001ab7a063f0100000000026500a233cb76", "006551636a53ac5251", 1, -1144216171, "68c7bd717b399b1ee33a6562a916825a2fed3019cdf4920418bb72ffd7403c8c"], + ["d5c1b16f0248c60a3ddccf7ebd1b3f260360bbdf2230577d1c236891a1993725e262e1b6cb000000000363636affffffff0a32362cfe68d25b243a015fc9aa172ea9c6b087c9e231474bb01824fd6bd8bc0300000005ab52ab516affffffff0420d9a70200000000045152656a45765d0000000000055252536a5277bad100000000000252ab3f3f3803000000000463acac5200000000", "52636a52ab65", 1, 1305123906, "978dc178ecd03d403b048213d904653979d11c51730381c96c4208e3ea24243a"], + ["1be8ee5604a9937ebecffc832155d9ba7860d0ca451eaced58ca3688945a31d93420c27c460100000006abac5300535288b65458af2f17cbbf7c5fbcdcfb334ffd84c1510d5500dc7d25a43c36679b702e850f7c0200000003005300ffffffff7c237281cb859653eb5bb0a66dbb7aeb2ac11d99ba9ed0f12c766a8ae2a2157203000000086aabac526365acabfffffffff09d3d6639849f442a6a52ad10a5d0e4cb1f4a6b22a98a8f442f60280c9e5be80200000007ab00ab6565ab52ffffffff0398fe83030000000005526aababacbdd6ec010000000005535252ab6a82c1e6040000000001652b71c40c", "6563526353656351", 2, -853634888, "0d936cceda2f56c7bb87d90a7b508f6208577014ff280910a710580357df25f3"], + ["9e0f99c504fbca858c209c6d9371ddd78985be1ab52845db0720af9ae5e2664d352f5037d4010000000552ac53636affffffff0e0ce866bc3f5b0a49748f597c18fa47a2483b8a94cef1d7295d9a5d36d31ae7030000000663515263ac635bb5d1698325164cdd3f7f3f7831635a3588f26d47cc30bf0fefd56cd87dc4e84f162ab702000000036a6365ffffffff85c2b1a61de4bcbd1d5332d5f59f338dd5e8accbc466fd860f96eef1f54c28ec030000000165ffffffff04f5cabd010000000007000052ac526563c18f1502000000000465510051dc9157050000000008655363ac525253ac506bb600000000000865656a53ab63006a00000000", "006a6a0052", 0, 1186324483, "2f9b7348600336512686e7271c53015d1cb096ab1a5e0bce49acd35bceb42bc8"], + ["11ce51f90164b4b54b9278f0337d95c50d16f6828fcb641df9c7a041a2b274aa70b1250f2b0000000008ab6a6a65006551524c9fe7f604af44be050000000005525365006521f79a0300000000015306bb4e04000000000265ac99611a05000000000765acab656500006dc866d0", "", 0, -1710478768, "cfa4b7573559b3b199478880c8013fa713ca81ca8754a3fd68a6d7ee6147dc5a"], + ["86bc233e02ba3c647e356558e7252481a7769491fb46e883dd547a4ce9898fc9a1ca1b77790000000006ab5351abab51f0c1d09c37696d5c7c257788f5dff5583f4700687bcb7d4acfb48521dc953659e325fa390300000003acac5280f29523027225af03000000000963abac0065ab65acab7e59d90400000000016549dac846", "53006aac52acac", 0, 711159875, "880330ccde00991503ea598a6dfd81135c6cda9d317820352781417f89134d85"], + ["beac155d03a853bf18cd5c490bb2a245b3b2a501a3ce5967945b0bf388fec2ba9f04c03d68030000000012fe96283aec4d3aafed8f888b0f1534bd903f9cd1af86a7e64006a2fa0d2d30711af770010000000163ffffffffd963a19d19a292104b9021c535d3e302925543fb3b5ed39fb2124ee23a9db00302000000056500ac63acffffffff01ad67f503000000000300ac5189f78db2", "53536a636500", 2, 748992863, "bde3dd0575164d7ece3b5783ce0783ffddb7df98f178fe6468683230314f285a"], + ["81dab34a039c9e225ba8ef421ec8e0e9d46b5172e892058a9ade579fe0eb239f7d9c97d45b0300000009ac65655351ab526363ffffffff10c0faaf7f597fc8b00bbc67c3fd4c6b70ca6b22718d15946bf6b032e62dae570000000005536a00ab6a02cddec3acf985bbe62c96fccf17012a87026ed63fc6756fa39e286eb4c2dd79b59d37400300000002516affffffff04f18b8d03000000000753abab5152636564411c02000000000400ab6300e965750300000000001bd2cf02000000000565ab526aab00000000", "006551ab", 0, -1488174485, "a3d65a8cd0c1eea8558d01396b929520a2221c29d9f25f29035b8abae874447f"], + ["489ebbf10478e260ba88c0168bd7509a651b36aaee983e400c7063da39c93bf28100011f280100000004abab63ab2fc856f05f59b257a4445253e0d91b6dffe32302d520ac8e7f6f2467f7f6b4b65f2f59e903000000096353abacab6351656affffffff0122d9480db6c45a2c6fd68b7bc57246edffbf6330c39ccd36aa3aa45ec108fc030000000265ab9a7e78a69aadd6b030b12602dff0739bbc346b466c7c0129b34f50ae1f61e634e11e9f3d0000000006516a53525100ffffffff011271070000000000086563ab6353536352c4dd0e2c", "", 0, -293358504, "4eba3055bc2b58765593ec6e11775cea4b6493d8f785e28d01e2d5470ea71575"], + ["6911195d04f449e8eade3bc49fd09b6fb4b7b7ec86529918b8593a9f6c34c2f2d301ec378b000000000263ab49162266af054643505b572c24ff6f8e4c920e601b23b3c42095881857d00caf56b28acd030000000565525200ac3ac4d24cb59ee8cfec0950312dcdcc14d1b360ab343e834004a5628d629642422f3c5acc02000000035100accf99b663e3c74787aba1272129a34130668a877cc6516bfb7574af9fa6d07f9b4197303400000000085351ab5152635252ffffffff042b3c95000000000000ff92330200000000046a5252ab884a2402000000000853530065520063000d78be03000000000953abab52ab53ac65aba72cb34b", "6a", 2, -637739405, "6b80d74eb0e7ee59d14f06f30ba7d72a48d3a8ff2d68d3b99e770dec23e9284f"], + ["746347cf03faa548f4c0b9d2bd96504d2e780292730f690bf0475b188493fb67ca58dcca4f0000000002005336e3521bfb94c254058e852a32fc4cf50d99f9cc7215f7c632b251922104f638aa0b9d080100000008656aac5351635251ffffffff4da22a678bb5bb3ad1a29f97f6f7e5b5de11bb80bcf2f7bb96b67b9f1ac44d09030000000365ababffffffff036f02b30000000000076353ab6aac63ac50b72a050000000002acaba8abf804000000000663006a6a6353797eb999", "acac5100", 1, -1484493812, "164c32a263f357e385bd744619b91c3f9e3ce6c256d6a827d6defcbdff38fa75"], + ["e17149010239dd33f847bf1f57896db60e955117d8cf013e7553fae6baa9acd3d0f1412ad90200000006516500516500cb7b32a8a67d58dddfb6ceb5897e75ef1c1ff812d8cd73875856487826dec4a4e2d2422a0100000004ac525365196dbb69039229270400000000070000535351636a8b7596020000000006ab51ac52655131e99d040000000003516551ee437f5c", "ac656a53", 1, 1102662601, "8858bb47a042243f369f27d9ab4a9cd6216adeac1c1ac413ed0890e46f23d3f3"], + ["144971940223597a2d1dec49c7d4ec557e4f4bd207428618bafa3c96c411752d494249e1fb0100000004526a5151ffffffff340a545b1080d4f7e2225ff1c9831f283a7d4ca4d3d0a29d12e07d86d6826f7f0200000003006553ffffffff03c36965000000000000dfa9af00000000000451636aac7f7d140300000000016300000000", "", 1, -108117779, "c84fcaf9d779df736a26cc3cabd04d0e61150d4d5472dd5358d6626e610be57f"], + ["b11b6752044e650b9c4744fb9c930819227d2ac4040d8c91a133080e090b042a142e93906e0000000003650053ffffffff6b9ce7e29550d3c1676b702e5e1537567354b002c8b7bb3d3535e63ad03b50ea01000000055100516300fffffffffcf7b252fea3ad5a108af3640a9bc2cd724a7a3ce22a760fba95496e88e2f2e801000000036a00ac7c58df5efba193d33d9549547f6ca839f93e14fa0e111f780c28c60cc938f785b363941b000000000863ab51516552ac5265e51fcd0308e9830400000000036a00abab72190300000000016a63d0710000000000050051ab6a6300000000", "53005165ac51ab65", 0, 229563932, "e562579d1a2b10d1c5e45c06513456002a6bec157d7eb42511d30b118103c052"], + ["2aee6b9a02172a8288e02fac654520c9dd9ab93cf514d73163701f4788b4caeeb9297d2e250300000004ab6363008fb36695528d7482710ea2926412f877a3b20acae31e9d3091406bfa6b62ebf9d9d2a6470100000009535165536a63520065ffffffff03f7b560050000000003acab6a9a8338050000000000206ce90000000000056552516a5100000000", "5252", 1, -1102319963, "fa4676c374ae3a417124b4c970d1ed3319dc3ac91fb36efca1aa9ed981a8aa1b"], + ["9554595203ad5d687f34474685425c1919e3d2cd05cf2dac89d5f33cd3963e5bb43f8706480100000000ffffffff9de2539c2fe3000d59afbd376cb46cefa8bd01dbc43938ff6089b63d68acdc2b02000000096553655251536a6500fffffffff9695e4016cd4dfeb5f7dadf00968e6a409ef048f81922cec231efed4ac78f5d010000000763abab6a5365006caaf0070162cc640200000000045163ab5100000000", "", 0, -1105256289, "e8e10ed162b1a43bfd23bd06b74a6c2f138b8dc1ab094ffb2fa11d5b22869bee"], + ["04f51f2a0484cba53d63de1cb0efdcb222999cdf2dd9d19b3542a896ca96e23a643dfc45f00200000007acac53510063002b091fd0bfc0cfb386edf7b9e694f1927d7a3cf4e1d2ce937c1e01610313729ef6419ae7030000000165a3372a913c59b8b3da458335dc1714805c0db98992fd0d93f16a7f28c55dc747fe66a5b503000000095351ab65ab52536351ffffffff5650b318b3e236802a4e41ed9bc0a19c32b7aa3f9b2cda1178f84499963a0cde000000000165ffffffff0383954f04000000000553ac536363a8fc90030000000000a2e315000000000005acab00ab5100000000", "0053", 2, -1424653648, "a5bc0356f56b2b41a2314ec05bee7b91ef57f1074bcd2efc4da442222269d1a3"], + ["5e4fab42024a27f0544fe11abc781f46596f75086730be9d16ce948b04cc36f86db7ad50fd01000000026a00613330f4916285b5305cc2d3de6f0293946aa6362fc087727e5203e558c676b314ef8dd401000000001af590d202ba496f040000000001009e3c9604000000000351ac51943d64d3", "51acabab5100ab52", 1, -129301207, "556c3f90aa81f9b4df5b92a23399fe6432cf8fecf7bba66fd8fdb0246440036c"], + ["a115284704b88b45a5f060af429a3a8eab10b26b7c15ed421258f5320fa22f4882817d6c2b0300000003005300ffffffff4162f4d738e973e5d26991452769b2e1be4b2b5b7e8cbeab79b9cf9df2882c040000000006636aac63ac5194abc8aa22f8ddc8a7ab102a58e39671683d1891799d19bd1308d24ea6d365e571172f1e030000000700515352515153ffffffff4da7ad75ce6d8541acbb0226e9818a1784e9c97c54b7d1ff82f791df1c6578f60000000000ffffffff01b1f265040000000009ab0051ac656a516a5300000000", "51abab6352535265", 0, -1269106800, "0ef7b6e87c782fa33fe109aab157a2d9cddc4472864f629510a1c92fa1fe7fc1"], + ["f3f771ae02939752bfe309d6c652c0d271b7cab14107e98032f269d92b2a8c8853ab057da8010000000563ab6a6365670c305c38f458e30a7c0ab45ee9abd9a8dc03bae1860f965ffced879cb2e5d0bb156821020000000153ffffffff025dc619050000000002ac51ec0d250100000000076a5200636a6363333aecd8", "650053ac515100ab", 1, 1812404608, "a7aa34bf8a5644f03c6dd8801f9b15ba2e07e07256dbf1e02dad59f0d3e17ea9"], + ["fd3e267203ae7d6d3975e738ca84f12540229bb237dd228d5f688e9d5ba53fce4302b0334d01000000026353ffffffff602a3ab75af7aa951d93093e345ef0037a2863f3f580a9b1a575fffe68e677450300000000239e476d1e8f81e8b6313880d8a49b27c1b00af467f29756e76f675f084a5676539636ab030000000765ab6351acac52d9217747044d773204000000000752ac51526353acc33e45050000000005516500005115d889040000000004ab5163510cbbbd0200000000016500000000", "65ac526aac6a53ab52", 2, -886179388, "bc46f3f83058ddf5bebd9e1f2c117a673847c4dc5e31cfb24bac91adf30877cf"], + ["f380ae23033646af5dfc186f6599098015139e961919aea28502ea2d69474413d94a555ea2000000000853635265abacac5314da394b99b07733341ddba9e86022637be3b76492992fb0f58f23c915098979250a96620300000003ab6300ffffffff4bb6d1c0a0d84eac7f770d3ad0fdc5369ae42a21bbe4c06e0b5060d5990776220300000000ffffffff0486fd70020000000007ac6500635252acf3fd72010000000005656a6a6551212de90500000000096365006a63635153000fa33100000000000600535151656300000000", "ab52", 2, -740890152, "f804fc4d81f039009ed1f2cccb5c91da797543f235ac71b214c20e763a6d86d7"], + ["5c45d09801bb4d8e7679d857b86b97697472d514f8b76d862460e7421e8617b15a2df217c6010000000863acacab6565006affffffff01156dbc03000000000952ac63516551ac6aac00000000", "6aabac", 0, 1310125891, "270445ab77258ced2e5e22a6d0d8c36ac7c30fff9beefa4b3e981867b03fa0ad"], + ["4ecc6bde030ca0f83c0ed3d4b777f94c0c88708c6c933fe1df6874f296d425cac95355c23d0000000006ac6a51536a52f286a0969d6170e20f2a8000193807f5bc556770e9d82341ef8e17b0035eace89c76edd50200000007ac65525100656affffffff5bade6e462fac1927f078d69d3a981f5b4c1e59311a38efcb9a910aa436afaa80000000007ac6a006352ab52ffffffff0331e58902000000000763ac53636352abb8b3ca000000000001637a1d26040000000009535263ac6a5352ab655ae34a39", "6a65ab", 2, 2142728517, "4a3415eb1677ae4e0c939644a4cfd5dc6299780b55cd0dc735967057b6b1526a"], + ["a59484b501eb50114be0fc79e72ab9bc9f4a5f7acdf274a56d6b68684eb68cf8b07ec5d1c2000000000765abab00ab00639e09aa940141e3530200000000046500ac6500000000", "00516565ab", 0, -1561622405, "d60bbadd2cc0674100baa08d0e0493ee4248f0304b3eb778da942041f503a896"], + ["53dc1a88046531c7b57a35f4d9adf101d068bf8d63fbbedaf4741dba8bc5e92c8725def571030000000453655251fcdf116a226b3ec240739c4c7493800e4edfe67275234e371a227721eac43d3d9ecaf1b50300000003ac0052ffffffff2c9279ffeea4718d167e9499bd067600715c14484e373ef93ae4a31d2f5671ab0000000009516553ac636a6a65001977752eeba95a8f16b88c571a459c2f2a204e23d48cc7090e4f4cc35846ca7fc0a455ce00000000055165ac0063188143f80205972902000000000765ac63ac516353c7b6a50000000000036a510000000000", "655351536a", 0, 103806788, "b276584d3514e5b4e058167c41dc02915b9d97f6795936a51f40e894ed8508bc"], + ["53f8959f01ddb36afdcd20167edcbb75a63d18654fdcf10bc0004c761ab450fe236d79cb2702000000065151650063653435003a033a5e34050000000009ac52516a630000516ab86db3030000000002006344ac090500000000046363ab00f3644537", "5263abab63ac656353", 0, -218513553, "f1f2a489682e42a6fc20025dfc89584d17f150b2d7ae3ddedd2bf43d5e24f37f"], + ["5a06cb4602dcfc85f49b8d14513f33c48f67146f2ee44959bbca092788e6823b2719f3160b0200000001ab3c013f2518035b9ea635f9a1c74ec1a3fb7496a160f46aae2e09bfc5cd5111a0f20969e003000000015158c89ab7049f20d6010000000008ac6a52abac53515349765e00000000000300ab638292630100000000045351ab0086da09010000000006656a6365525300000000", "526a63", 1, 1502936586, "bdfaff8a4e775379c5dc26e024968efa805f923de53fa8272dd53ec582afa0c5"], + ["ca9d84fa0129011e1bf27d7cb71819650b59fb292b053d625c6f02b0339249b498ff7fd4b601000000025352ffffffff032173a0040000000008525253abab5152639473bb030000000009005153526a53535151d085bd0000000000086a5365ab5165655300000000", "005152ac51", 0, 580353445, "c629d93b02037f40aa110e46d903edb34107f64806aa0c418d435926feef68b8"], + ["e3cdbfb4014d90ae6a4401e85f7ac717adc2c035858bf6ff48979dd399d155bce1f150daea0300000002ac51a67a0d39017f6c71040000000005535200535200000000", "", 0, -1899950911, "c1c7df8206e661d593f6455db1d61a364a249407f88e99ecad05346e495b38d7"], + ["b2b6b9ab0283d9d73eeae3d847f41439cd88279c166aa805e44f8243adeb3b09e584efb1df00000000026300ffffffff7dfe653bd67ca094f8dab51007c6adaced09de2af745e175b9714ca1f5c68d050000000003ac6500aa8e596903fd3f3204000000000553ac6a6a533a2e210500000000075253acabab526392d0ee020000000008520065635200ab5200000000", "65acacac65005365", 0, 28298553, "39c2aaa2496212b3ab120ab7d7f37c5e852bfe38d20f5226413a2268663eeae8"], + ["f30c5c3d01a6edb9e10fafaf7e85db14e7fec558b9dca4a80b05d7c3a2944d282c5018f4680200000003005263ffffffff04aac3530300000000026551bc2419010000000009005163acab6a5100658e7085050000000000c5e4ec050000000007656a6a635365ab2d8e8882", "abac53ab005251ac52", 0, -490287546, "877e347ec7487497769e2581142276d1a8d813b652e4483cf9cc993d16354417"], + ["4314339e01de40faabcb1b970245a7f19eedbc17c507dac86cf986c2973715035cf95736ae0200000007abababababab65bde67b900151510b04000000000853ac00655200535300000000", "52", 0, 399070095, "47585dc25469d04ff3a60939d0a03779e3e81a411bf0ca18b91bb925ebd30718"], + ["2d4cf4e9031b3e175b2ff18cd933151379d9cfac4713d8bd0e63b70bd4a92277aa7af901ab000000000565515353abffffffff557666c7f3be9cdecdad44c3df206eb63a2da4ed1f159d21193882a9f0340081020000000963ab53ab5252ac63abffffffff8a8c897bdb87e93886aad5ded9d82a13101d5476554386373646ca5e23612e450300000009006a526552abab6a635ac03fc00198bb02040000000009525100526a6563636a1d052834", "ab52ac00acac6a", 0, -1469882480, "09ed6563a454814ab7e3b4c28d56d8751162b77df1825b37ba66c6147750b2a3"], + ["f063171b03e1830fdc1d685a30a377537363ccafdc68b42bf2e3acb908dac61ee24b37595c020000000765ac5100ab6aacf447bc8e037b89d6cadd62d960cc442d5ced901d188867b5122b42a862929ce45e7b628d010000000253aba009a1ba42b00f1490b0b857052820976c675f335491cda838fb7934d5eea0257684a2a202000000001e83cf2401a7f777030000000008ab6553526a53526a00000000", "", 2, 1984790332, "c19caada8e71535e29a86fa29cfd9b74a0c7412003fc722a121005e461e01636"], + ["cf7bdc250249e22cbe23baf6b648328d31773ea0e771b3b76a48b4748d7fbd390e88a004d30000000003ac536a4ab8cce0e097136c90b2037f231b7fde2063017facd40ed4e5896da7ad00e9c71dd70ae600000000096a0063516352525365ffffffff01b71e3e00000000000300536a00000000", "", 1, 546970113, "6a815ba155270af102322c882f26d22da11c5330a751f520807936b320b9af5d"], + ["ac7a125a0269d35f5dbdab9948c48674616e7507413cd10e1acebeaf85b369cd8c88301b7c030000000963656aac6a530053abffffffffed94c39a582e1a46ce4c6bffda2ccdb16cda485f3a0d94b06206066da12aecfe010000000752abab63536363ef71dcfb02ee07fa0400000000016a6908c802000000000751656a6551abac688c2c2d", "6a6351526551", 0, 858400684, "552ff97d7924f51cda6d1b94be53483153ef725cc0a3a107adbef220c753f9a6"], + ["3a1f454a03a4591e46cf1f7605a3a130b631bf4dfd81bd2443dc4fac1e0a224e74112884fe0000000005516aac6a53a87e78b55548601ffc941f91d75eab263aa79cd498c88c37fdf275a64feff89fc1710efe03000000016a39d7ef6f2a52c00378b4f8f8301853b61c54792c0f1c4e2cd18a08cb97a7668caa008d970200000002656affffffff017642b20100000000096a63535253abac6a6528271998", "51", 2, 1459585400, "e9a7f21fc2d38be7be47095fbc8f1bf8923660aa4d71df6d797ae0ba5ca4d5b0"], + ["f59366cc0114c2a18e6bd1347ed9470f2522284e9e835dd5c5f7ef243639ebea95d9b232b6020000000153474b62eb045c00170500000000096352ab516352ab5200038a520400000000086aab5253656a63005b968904000000000963536353ac0053635387106002000000000000000000", "ab52526300ab51", 0, 1834116153, "cdf51f6e3a9dc2be5a59ea4c00f5aac1e1426a5202c325e6cf2567d07d8d8de4"], + ["6269e0fa0173e76e89657ca495913f1b86af5b8f1c1586bcd6c960aede9bc759718dfd5044000000000352ac530e2c7bd90219849b000000000007ab00ab6a53006319f281000000000007ab00515165ac5200000000", "6a", 0, -2039568300, "62094f98234a05bf1b9c7078c5275ed085656856fb5bdfd1b48090e86b53dd85"], + ["eb2bc00604815b9ced1c604960d54beea4a3a74b5c0035d4a8b6bfec5d0c9108f143c0e99a0000000000ffffffff22645b6e8da5f11d90e5130fd0a0df8cf79829b2647957471d881c2372c527d8010000000263acffffffff1179dbaf17404109f706ae27ad7ba61e860346f63f0c81cb235d2b05d14f2c1003000000025300264cb23aaffdc4d6fa8ec0bb94eff3a2e50a83418a8e9473a16aaa4ef8b855625ed77ef40100000003ac51acf8414ad404dd328901000000000652526500006ab6261c000000000002526a72a4c9020000000006ac526500656586d2e7000000000006656aac00ac5279cd8908", "51", 1, -399279379, "d37532e7b2b8e7db5c7c534197600397ebcc15a750e3af07a3e2d2e4f84b024f"], + ["dc9fe6a8038b84209bbdae5d848e8c040433237f415437592907aa798bf30d9dbbddf0ff85010000000153ffffffff23269a7ea29fcf788db483b8d4c4b35669e582608644259e950ce152b0fa6e050000000003acababffffffff65de94857897ae9ea3aa0b938ba6e5adf374d48469922d2b36dbb83d3b8c8261010000000452ac5200ffffffff02856e9b0300000000026a51980c8e02000000000365ab63d2648db4", "00ab0051ac526565", 2, 1562581941, "5cef9d8e18a2d5a70448f17b465d411a19dab78f0ddf1672ffd518b188f52433"], + ["eba8b0de04ac276293c272d0d3636e81400b1aaa60db5f11561480592f99e6f6fa13ad387002000000070053acab536563bebb23d66fd17d98271b182019864a90e60a54f5a615e40b643a54f8408fa8512cfac927030000000963ac6a6aabac65ababffffffff890a72192bc01255058314f376bab1dc72b5fea104c154a15d6faee75dfa5dba020000000100592b3559b0085387ac7575c05b29b1f35d9a2c26a0c27903cc0f43e7e6e37d5a60d8305a030000000252abffffffff0126518f05000000000000000000", "005300635252635351", 1, 664344756, "26dc2cba4bd5334e5c0b3a520b44cc1640c6b923d10e576062f1197171724097"], + ["91bd040802c92f6fe97411b159df2cd60fb9571764b001f31657f2d616964637605875c2a901000000055263006a65ffffffff3651df372645f50cf4e32fdf6e61c766e912e16335db2b40c5d52fe89eefe7cd00000000040065ab65ffffffff03ca8625030000000009ab51ac63530052ab52c6bf14020000000006ab00ab52005167d270000000000007ab53525351636a00000000", "5151ab63005252ac", 1, 1983087664, "3e5aa0200248d8d86ede3b315ca1b857018b89184a4bd023bd88ab12e499f6e1"], + ["185cda1a01ecf7a8a8c28466725b60431545fc7a3367ab68e34d486e8ea85ee3128e0d8384000000000465ac63abec88b7bb031c56eb04000000000965636a51005252006a7c78d5040000000007acac63abac51ac3024a40500000000086300526a51abac51464c0e8c", "0065535265515352", 0, 1594558917, "b5280b9610c0625a65b36a8c2402a95019a7bbb9dd3de77f7c3cb1d82c3263ba"], + ["a9531f07034091668b65fea8b1a79700d586ac9e2f42ca0455a26abe41f9e1805d009a0f5702000000096365516365ac5263ab3619bac643a9e28ee47855118cf80c3a74531cdf198835d206d0fe41804e325a4f9f105e03000000016a58e3ab0d46375d98994daf0fa7c600d2bb4669e726fca0e3a3f21ea0d9e777396740328f0100000008636a5363ab526a538d3ea7700304cb66030000000007515163ab52ab510184030500000000085353636565ac0051d9cff402000000000751ab52ab5352abf0e36254", "ab5353ac5365acab", 2, 1633101834, "04c9ef72f33668ca449c0415becf62cc0b8e0c75f9c8813852d42a58acf107c8"], + ["6b5ecc7903fe0ba37ea551df92a59e12bad0a3065846ba69179a8f4a741a2b4fcf679aac810200000004535263529a3d343293b99ab425e7ef8529549d84f480bcd92472bab972ea380a302128ae14dfcd0200000000025163ffffffff24636e4545cab9bf87009119b7fc3ec4d5ee9e206b90f35d1df8a563b6cd097a010000000852abac53005153abc64467860406e832020000000009526300006a53ac6352ac1395010000000002ac53b117f300000000000863655351acab00651edf02030000000008ab51ac6353535252628ef71d", "ab63ab6a52ac526563", 2, -1559697626, "8f07ece7d65e509f1e0780584ef8d271c1c61a13b10335d5faafc7afc8b5b8ec"], + ["92c9fb780138abc472e589d5b59489303f234acc838ca66ffcdf0164517a8679bb622a4267020000000153468e373d04de03fa020000000009ac006a5265ab5163006af649050000000007515153006a00658ceb59030000000001ac36afa0020000000009ab53006351ab51000000000000", "6a", 0, 2059357502, "e2358dfb51831ee81d7b0bc602a65287d6cd2dbfacf55106e2bf597e22a4b573"], + ["6f62138301436f33a00b84a26a0457ccbfc0f82403288b9cbae39986b34357cb2ff9b889b302000000045253655335a7ff6701bac9960400000000086552ab656352635200000000", "6aac51", 0, 1444414211, "502a2435fd02898d2ff3ab08a3c19078414b32ec9b73d64a944834efc9dae10c"], + ["9981143a040a88c2484ac3abe053849e72d04862120f424f373753161997dd40505dcb4783030000000700536365536565a2e10da3f4b1c1ad049d97b33f0ae0ea48c5d7c30cc8810e144ad93be97789706a5ead180100000003636a00ffffffffbdcbac84c4bcc87f03d0ad83fbe13b369d7e42ddb3aecf40870a37e814ad8bb5010000000963536a5100636a53abffffffff883609905a80e34202101544f69b58a0b4576fb7391e12a769f890eef90ffb72020000000651656352526affffffff04243660000000000004ab5352534a9ce001000000000863656363ab6a53652df19d030000000003ac65acedc51700000000000000000000", "ac6300acac", 2, 293672388, "7ba99b289c04718a7283f150d831175ed6303081e191a0608ea81f78926c5bdf"], + ["a2bb630b01989bc5d643f2da4fb9b55c0cdf846ba06d1dbe372893024dbbe5b9b8a1900af802000000055265ac63aca7a68d2f04916c74010000000003abac007077f0040000000001007d4127010000000005ac516aac000f31e8030000000000571079c9", "65ab0051ac", 0, -1103627693, "92d53b4390262e6b288e8a32e0cfc36cd5adfdfabfe96c7bfd4a19d65e233761"], + ["49f7d0b6037bba276e910ad3cd74966c7b3bc197ffbcfefd6108d6587006947e97789835ea0300000008526a52006a650053ffffffff8d7b6c07cd10f4c4010eac7946f61aff7fb5f3920bdf3467e939e58a1d4100ab03000000076aac63ac535351ffffffff8f48c3ba2d52ad67fbcdc90d8778f3c8a3894e3c35b9730562d7176b81af23c80100000003ab5265ffffffff0301e3ef0300000000046a525353e899ac0500000000075153ab6a65abac259bea0400000000007b739972", "53516aacac6aac", 1, 955403557, "5d366a7f4346ae18aeb7c9fc4dab5af71173184aa20ed22fcb4ea8511ad25449"], + ["58a4fed801fbd8d92db9dfcb2e26b6ff10b120204243fee954d7dcb3b4b9b53380e7bb8fb60100000003006351ffffffff02a0795b050000000006536351ac6aac2718d00200000000075151acabac515354d21ba1", "005363515351", 0, -1322430665, "bbee941bbad950424bf40e3623457db47f60ed29deaa43c99dec702317cb3326"], + ["32765a0b02e455793d9ce530e9f6a44bcbc612e893a875b5da61d822dc56d8245166c398b403000000085353abac6300006a6bdee2a78d0d0b6a5ea666eed70b9bfea99d1d612ba3878f615c4da10d4a521cba27155002000000035363abffffffff043cd42401000000000551656a53653685320100000000030000511881bc0500000000065165abab636a20169f010000000007acab656aac63acdb0706a8", "65ac53ab53", 0, 1936499176, "5c5a9c3a5de7dc7a82bc171c9d3505913b8bcc450bc8b2d11772c1a1d781210b"], + ["17fad0d303da0d764fedf9f2887a91ea625331b28704940f41e39adf3903d8e75683ef6d46020000000151ffffffffff376eea4e880bcf0f03d33999104aafed2b3daf4907950bb06496af6b51720a020000000900636a63525253525196521684f3b08497bad2c660b00b43a6a517edc58217876eb5e478aa3b5fda0f29ee1bea00000000046aacab6affffffff03dde8e2050000000007ac5365ac51516a14772e000000000005630000abacbbb360010000000006ab5251ab656a50f180f0", "0053", 0, -1043701251, "a3bdf8771c8990971bff9b4e7d59b7829b067ed0b8d3ac1ec203429811384668"], + ["236c32850300045e292c84ede2b9ab5733ba08315a2bb09ab234c4b4e8894808edbdac0d3b020000000653635363abacffffffffd3f696bb31fdd18a72f3fc2bb9ae54b416a253fc37c1a0f0180b52d35bad49440100000004650053abffffffffa85c75a2406d82a93b12e555b66641c1896a4e83ae41ef1038218311e38ace060200000006abab006a51ac104b5e6701e2842c04000000000800630051ac0000ab00000000", "ab63ac6a516a", 1, -1709887524, "8c29ea8ef60c5a927fccdba8ea385db6b6b84d98e891db45f5d4ee3148d3f5a7"], + ["b78d5fd601345f3100af494cdf447e7d4076179f940035b0ebe8962587d4d0c9c6c9fc34ee0300000003516a6affffffff03dc5c890100000000085353ac53ac6a52534ac941040000000007ac63656a51ab51d4266b0100000000036aacac70731f2d", "005351ab0053", 0, -1789071265, "d5f1c1cb35956a5711d67bfb4cedbc67e77c089b912d688ad440ff735adb390d"], + ["5a2257df03554550b774e677f348939b37f8e765a212e566ce6b60b4ea8fed4c9504b7f7d1000000000653655265ab5258b67bb931df15b041177cf9599b0604160b79e30f3d7a594e7826bae2c29700f6d8f8f40300000005515300ac6a159cf8808a41f504eb5c2e0e8a9279f3801a5b5d7bc6a70515fbf1c5edc875bb4c9ffac500000000050063510052ffffffff0422a90105000000000965006a650000516a006417d2020000000006526363ab00524d969d0100000000035153acc4f077040000000005ac5200636500000000", "6a52", 1, -1482463464, "37b794b05d0687c9b93d5917ab068f6b2f0e38406ff04e7154d104fc1fb14cdc"], + ["e0032ad601269154b3fa72d3888a3151da0aed32fb2e1a15b3ae7bee57c3ddcffff76a1321010000000100110d93ae03f5bd080100000000075263516a6551002871e60100000000046a005252eaa753040000000004ab6aab526e325c71", "630052", 0, -1857873018, "ea117348e94de86381bb8ad1c7f93b8c623f0272104341701bb54e6cb433596c"], + ["014b2a5304d46764817aca180dca50f5ab25f2e0d5749f21bb74a2f8bf6b8b7b3fa8189cb7030000000965ac5165ab6a51ac6360ecd91e8abc7e700a4c36c1a708a494c94bb20cbe695c408543146566ab22be43beae9103000000045163ab00ffffffffffa48066012829629a9ec06ccd4905a05df0e2b745b966f6a269c9c8e13451fc00000000026565ffffffffc40ccadc21e65fe8a4b1e072f4994738ccaf4881ae6fede2a2844d7da4d199ab02000000065152ab536aabffffffff01b6e054030000000004515352ab3e063432", "", 0, 1056459916, "a7aff48f3b8aeb7a4bfe2e6017c80a84168487a69b69e46681e0d0d8e63a84b6"], + ["c4ef04c103c5dde65410fced19bf6a569549ecf01ceb0db4867db11f2a3a3eef0320c9e8e001000000085100536a53516aabffffffff2a0354fa5bd96f1e28835ffe30f52e19bd7d5150c687d255021a6bec03cf4cfd03000000056a006300514900c5b01d3d4ae1b97370ff1155b9dd0510e198d266c356d6168109c54c11b4c283dca00300000002ababffffffff02e19e3003000000000451655351fa5c0003000000000163ef1fc64b", "51636a51ab630065", 1, -1754709177, "0a281172d306b6a32e166e6fb2a2cc52c505c5d60ea448e9ba7029aa0a2211e1"], + ["29083fe00398bd2bb76ceb178f22c51b49b5c029336a51357442ed1bac35b67e1ae6fdf13100000000066a6500acab51ffffffffe4ca45c9dc84fd2c9c47c7281575c2ba4bf33b0b45c7eca8a2a483f9e3ebe4b3010000000200abffffffffdf47ad2b8c263fafb1e3908158b18146357c3a6e0832f718cd464518a219d18303000000096352ac656351ac0052daddfb3b0231c36f00000000000400526a5275c7e0020000000001ab00000000", "acab536aac52", 2, 300802386, "82ebc07b16cff0077e9c1a279373185b3494e39d08fd3194aae6a4a019377509"], + ["1201ab5d04f89f07c0077abd009762e59db4bb0d86048383ba9e1dad2c9c2ad96ef660e6d00200000007ab6a65ac5200652466fa5143ab13d55886b6cdc3d0f226f47ec1c3020c1c6e32602cd3428aceab544ef43e00000000086a6a6a526a6a5263ffffffffd5be0b0be13ab75001243749c839d779716f46687e2e9978bd6c9e2fe457ee48020000000365abab1e1bac0f72005cf638f71a3df2e3bbc0fa35bf00f32d9c7dc9c39a5e8909f7d53170c8ae0200000008ab6a51516363516affffffff02f0a6210500000000036300ac867356010000000009acab65ac6353536a659356d367", "ac53535252", 0, 917543338, "418acc156c2bc76a5d7baa58db29f1b4cf6c266c9222ed167ef5b4d47f0e0f41"], + ["344fa11e01c19c4dd232c77742f0dd0aeb3695f18f76da627628741d0ee362b0ea1fb3a2180200000007635151005100529bab25af01937c1f0500000000055153ab53656e7630af", "6351005163ac51", 0, -629732125, "228ca52a0a376fe0527a61cfa8da6d7baf87486bba92d49dfd3899cac8a1034f"], + ["b2fda1950191358a2b855f5626a0ebc830ab625bea7480f09f9cd3b388102e35c0f303124c030000000565ac65ab53ffffffff03f9c5ec04000000000765ab51516551650e2b9f0500000000045365525284e8f6040000000001ac00000000", "ac51655253", 0, 1433027632, "d2fa7e13c34cecda5105156bd2424c9b84ee0a07162642b0706f83243ff811a8"], + ["a4a6bbd201aa5d882957ac94f2c74d4747ae32d69fdc765add4acc2b68abd1bdb8ee333d6e0300000008516a6552515152abffffffff02c353cb040000000007ac6351ab51536588bd320500000000066552525253ac00000000", "", 0, 1702060459, "499da7d74032388f820645191ac3c8d20f9dba8e8ded7fa3a5401ea2942392a1"], + ["584e8d6c035a6b2f9dac2791b980a485994bf38e876d9dda9b77ad156eee02fa39e19224a60300000003ab636529db326cc8686a339b79ab6b6e82794a18e0aabc19d9ad13f31dee9d7aad8eff38288588020000000452530052ffffffff09a41f07755c16cea1c7e193c765807d18cadddca6ec1c2ed7f5dcdca99e90e80000000001acffffffff01cba62305000000000451ac63acccdf1f67", "ab536a6363", 2, -27393461, "1125645b49202dca2df2d76dae51877387903a096a9d3f66b5ac80e042c95788"], + ["83a583d204d926f2ee587a83dd526cf1e25a44bb668e45370798f91a2907d184f7cddcbbc7030000000700ab6565536a539f71d3776300dffdfa0cdd1c3784c9a1f773e34041ca400193612341a9c42df64e3f550e01000000050052515251ffffffff52dab2034ab0648553a1bb8fc4e924b2c89ed97c18dfc8a63e248b454035564b01000000015139ab54708c7d4d2c2886290f08a5221cf69592a810fd1979d7b63d35c271961e710424fd0300000005ac65ac5251ffffffff01168f7c030000000000a85e5fb0", "6a536353656a00", 0, 179595345, "5350a31ac954a0b49931239d0ecafbf34d035a537fd0c545816b8fdc355e9961"], + ["ffd35d51042f290108fcb6ea49a560ba0a6560f9181da7453a55dfdbdfe672dc800b39e7320200000006630065516a65f2166db2e3827f44457e86dddfd27a8af3a19074e216348daa0204717d61825f198ec0030100000006ab51abab00abffffffffdf41807adb7dff7db9f14d95fd6dc4e65f8402c002d009a3f1ddedf6f4895fc8030000000500ab006a65a5a848345052f860620abd5fcd074195548ce3bd0839fa9ad8642ed80627bf43a0d47dbd010000000765ab006a656a53b38cdd6502a186da05000000000765ab00ab006a53527c0e0100000000085365ab51acacac52534bd1b1", "6a635253ac0000", 0, 1095082149, "3c05473a816621a3613f0e903faa1a1e44891dd40862b029e41fc520776350fa"], + ["6c9a4b98013c8f1cae1b1df9f0f2de518d0c50206a0ab871603ac682155504c0e0ce946f460100000000ffffffff04e9266305000000000753535100ac6aacded39e04000000000365ac6ab93ccd010000000002515397bf3d050000000003ab636300000000", "63520052ac656353", 0, -352633155, "936eff8cdfd771be24124da87c7b24feb48da7cbc2c25fb5ba13d1a23255d902"], + ["e01dc7f0021dc07928906b2946ca3e9ac95f14ad4026887101e2d722c26982c27dc2b59fdb0000000005ac5200516ab5a31ffadcbe74957a5a3f97d7f1475cc6423fc6dbc4f96471bd44c70cc736e7dec0d1ea020000000951636a526a52abac53ffffffff04bc2edd05000000000252ab528c7b02000000000952ac51526500525353324820040000000002005380c713000000000009630065ab00ac525252451bbb48", "53ab65ac", 0, -552384418, "69c0b30f4c630a6c878fde6ea6b74dae94f4eb3bcfbde2dc3649e1a9ada00757"], + ["009046a1023f266d0113556d604931374d7932b4d6a7952d08fbd9c9b87cbd83f4f4c178b4030000000452ac526346e73b438c4516c60edd5488023131f07acb5f9ea1540b3e84de92f4e3c432289781ea4900000000046500655357dfd6da02baef910100000000026a007d101703000000000800516500abacac5100000000", "6aab6553ac", 0, -802456605, "f8757fbb4448ca34e0cd41b997685b37238d331e70316659a9cc9087d116169d"], + ["df76ec0801a3fcf3d18862c5f686b878266dd5083f16cf655facab888b4cb3123b3ce5db7e01000000010010e7ac6a0233c83803000000000365ac51faf14a040000000004ac51655100000000", "6353acab", 0, 15705861, "e7d873aa079a19ec712b269a37d2670f60d8cb334c4f97e2e3fd10eeb8ee5f5e"], + ["828fd3e0031084051ccef9cfdd97fae4d9cc50c0dae36bd22a3ff332881f17e9756c3e288e0200000004ab535363961a2ccccaf0218ec6a16ba0c1d8b5e93cfd025c95b6e72bc629ec0a3f47da7a4c396dad01000000025353ffffffff19ad28747fb32b4caf7b5dbd9b2da5a264bedb6c86d3a4805cd294ae53a86ac40200000009ab53535351ab6551abffffffff04a41650030000000005656aab6aab8331a304000000000700516365ac516a0d2a47010000000007abac516353abacdebc19040000000006ab5300636a6300000000", "51ab52ab53ac52", 0, 1866105980, "311094b4d73e31aefc77e97859ef07ca2f07a7b7e4d7def80c69d3f5d58527e5"], + ["c4b80f850323022205b3e1582f1ed097911a81be593471a8dce93d5c3a7bded92ef6c7c1260100000002006affffffff70294d62f37c3da7c5eae5d67dce6e1b28fedd7316d03f4f48e1829f78a88ae801000000096a5200530000516351f6b7b544f7c39189d3a2106ca58ce4130605328ce7795204be592a90acd81bef517d6f170200000000ffffffff012ab8080000000000075100006365006335454c1e", "53ac6a536aacac", 0, -1124103895, "06277201504e6bf8b8c94136fad81b6e3dadacb9d4a2c21a8e10017bfa929e0e"], + ["8ab69ed50351b47b6e04ac05e12320984a63801716739ed7a940b3429c9c9fed44d3398ad40300000006536a516a52638171ef3a46a2adb8025a4884b453889bc457d63499971307a7e834b0e76eec69c943038a0300000000ffffffff566bb96f94904ed8d43d9d44a4a6301073cef2c011bf5a12a89bedbaa03e4724030000000265acb606affd01edea38050000000008515252516aacac6300000000", "65000000006365ac53", 0, -1338942849, "7912573937824058103cb921a59a7f910a854bf2682f4116a393a2045045a8c3"], + ["2484991e047f1cf3cfe38eab071f915fe86ebd45d111463b315217bf9481daf0e0d10902a402000000006e71a424eb1347ffa638363604c0d5eccbc90447ff371e000bf52fc743ec832851bb564a0100000001abffffffffef7d014fad3ae7927948edbbb3afe247c1bcbe7c4c8f5d6cf97c799696412612020000000851536a5353006a001dfee0d7a0dd46ada63b925709e141863f7338f34f7aebde85d39268ae21b77c3068c01d0000000008535151ab00636563ffffffff018478070200000000095200635365ac52ab5341b08cd3", "", 3, 265623923, "24cb420a53b4f8bb477f7cbb293caabfd2fc47cc400ce37dbbab07f92d3a9575"], + ["54839ef9026f65db30fc9cfcb71f5f84d7bb3c48731ab9d63351a1b3c7bc1e7da22bbd508e0300000000442ad138f170e446d427d1f64040016032f36d8325c3b2f7a4078766bdd8fb106e52e8d20000000003656500ffffffff02219aa101000000000851ababac52ab00659646bd02000000000552acacabac24c394a5", "ac", 0, 906807497, "69264faadcd1a581f7000570a239a0a26b82f2ad40374c5b9c1f58730514de96"], + ["5036d7080434eb4eef93efda86b9131b0b4c6a0c421e1e5feb099a28ff9dd8477728639f77030000000951516aab535152ab5391429be9cce85d9f3d358c5605cf8c3666f034af42740e94d495e28b9aaa1001ba0c87580300000008006552ab00ab006affffffffd838978e10c0c78f1cd0a0830d6815f38cdcc631408649c32a25170099669daa0000000002acab8984227e804ad268b5b367285edcdf102d382d027789250a2c0641892b480c21bf84e3fb0100000000b518041e023d8653010000000001004040fb0100000000080051ac5200636a6300000000", "52ac", 0, 366357656, "bd0e88829afa6bdc1e192bb8b2d9d14db69298a4d81d464cbd34df0302c634c6"], + ["9ad5ccf503fa4facf6a27b538bc910cce83c118d6dfd82f3fb1b8ae364a1aff4dcefabd38f03000000096365655263ac655300807c48130c5937190a996105a69a8eba585e0bd32fadfc57d24029cbed6446d30ebc1f100100000004000053650f0ccfca1356768df7f9210cbf078a53c72e0712736d9a7a238e0115faac0ca383f219d0010000000600ab536552002799982b0221b8280000000000000c41320000000000086552ac6365636a6595f233a3", "6a5152", 2, 553208588, "f99c29a79f1d73d2a69c59abbb5798e987639e36d4c44125d8dc78a94ddcfb13"], + ["669538a204047214ce058aed6a07ca5ad4866c821c41ac1642c7d63ed0054f84677077a84f030000000853abacab6a655353ffffffff70c2a071c115282924e3cb678b13800c1d29b6a028b3c989a598c491bc7c76c5030000000752ac52ac5163ac80420e8a6e43d39af0163271580df6b936237f15de998e9589ec39fe717553d415ac02a4030000000463635153184ad8a5a4e69a8969f71288c331aff3c2b7d1b677d2ebafad47234840454b624bf7ac1d03000000056a63abab63df38c24a02fbc63a040000000002ab535ec3dc050000000002536500000000", "635153", 3, -190399351, "9615541884dfb1feeb08073a6a6aa73ef694bc5076e52187fdf4138a369f94d9"], + ["a7f139e502af5894be88158853b7cbea49ba08417fbbca876ca6614b5a41432be34499987b000000000765635165abac63ffffffff8b8d70e96c7f54eb70da0229b548ced438e1ca2ba5ddd648a027f72277ee1efc0100000001abffffffff044f2c4204000000000165e93f550100000000050000526a6a94550304000000000365536aadc21c0300000000016300000000", "6aacac6363ab5265ac", 1, 2143189425, "6e3f97955490d93d6a107c18d7fe402f1cada79993bb0ff0d096357261b3a724"], + ["3b94438f0366f9f53579a9989b86a95d134256ce271da63ca7cd16f7dd5e4bffa17d35133f010000000100ffffffff1aaad0c721e06ec00d07e61a84fb6dc840b9a968002ce7e142f943f06fd143a10100000008535151ac51ab0053b68b8e9c672daf66041332163e04db3f6048534bd718e1940b3fc3811c4eef5b7a56888b01000000001d58e38c012e38e700000000000852ab53ac6365536a00000000", "ab655352", 1, -935223304, "b3b336de141d4f071313a2207b2a0c7cf54a070dd8d234a511b7f1d13e23b0c4"], + ["e5dca8a20456de0a67e185fa6ea94085ceae478d2c15c73cb931a500db3a1b6735dd1649ec0200000005ab536aabab32d11bbdcb81361202681df06a6b824b12b5cb40bb1a672cf9af8f2a836e4d95b7839327030000000951005365ab65abacabb345085932939eef0c724adef8a57f9e1bf5813852d957c039b6a12d9c2f201ea520fb030000000009ac5352005165acac6a5efc6072f1a421dc7dc714fc6368f6d763a5d76d0278b95fc0503b9268ccfadb48213a2500000000026a53ffffffff039ee1c4020000000009ac5353ab6353535163184018000000000005655265526a9a4a8a050000000001ac00000000", "65ab53ab6a00ab6553", 2, 1902561212, "7928ae8e86c0b0cad1b2c120ea313087437974382ee6d46443ca5ac3f5878b88"], + ["972128b904e7b673517e96e98d80c0c8ceceae76e2f5c126d63da77ffd7893fb53308bb2da0300000006ac6552ab52acffffffff4cac767c797d297c079a93d06dc8569f016b4bf7a7d79b605c526e1d36a40e2202000000095365ab636aac6a6a6a69928d2eddc836133a690cfb72ec2d3115bf50fb3b0d10708fa5d2ebb09b4810c426a1db01000000060052526300001e8e89585da7e77b2dd2e30625887f0660accdf29e53a614d23cf698e6fc8ab03310e87700000000076a520051acac6555231ddb0330ec2d03000000000200abfaf457040000000004ab6a6352bdc42400000000000153d6dd2f04", "", 0, 209234698, "4a92fec1eb03f5bd754ee9bfd70707dc4420cc13737374f4675f48529be518e4"], + ["1fb4085b022c6cfb848f8af7ba3ba8d21bd23ffa9f0bfd181cb68bcaaf2074e66d4974a31602000000090000006a6a6500acab6c12c07d9f3dbd2d93295c3a49e3757119767097e7fd5371f7d1ba9ba32f1a67a5a426f00000000000ffffffff018fd2fc04000000000363ac5100000000", "65ab006a6aab526a", 0, 1431502299, "8b7dd0ff12ca0d8f4dbf9abf0abba00e897c2f6fd3b92c79f5f6a534e0b33b32"], + ["5374f0c603d727f63006078bd6c3dce48bd5d0a4b6ea00a47e5832292d86af258ea0825c260000000009655353636352526a6af2221067297d42a9f8933dfe07f61a574048ff9d3a44a3535cd8eb7de79fb7c45b6f47320200000003ac006affffffff153d917c447d367e75693c5591e0abf4c94bbdd88a98ab8ad7f75bfe69a08c470200000005ac65516365ffffffff037b5b7b000000000001515dc4d904000000000004bb26010000000004536a6aac00000000", "516552516352ac", 2, 328538756, "8bb7a0129eaf4b8fc23e911c531b9b7637a21ab11a246352c6c053ff6e93fcb6"], + ["c441132102cc82101b6f31c1025066ab089f28108c95f18fa67db179610247086350c163bd010000000651525263ab00ffffffff9b8d56b1f16746f075249b215bdb3516cbbe190fef6292c75b1ad8a8988897c3000000000751ab6553abab00ffffffff02f9078b000000000009ab0053ac51ac00ab51c0422105000000000651006563525200000000", "ac51", 0, -197051790, "55acd8293ed0be6792150a3d7ced6c5ccd153ca7daf09cee035c1b0dac92bb96"], + ["ab82ad3b04545bd86b3bb937eb1af304d3ef1a6d1343ed809b4346cafb79b7297c09e1648202000000086351ac5200535353ffffffff95d32795bbaaf5977a81c2128a9ec0b3c7551b9b1c3d952876fcb423b2dfb9e80000000005515363acac47a7d050ec1a603627ce6cd606b3af314fa7964abcc579d92e19c7aba00cf6c3090d6d4601000000056a516551633e794768bfe39277ebc0db18b5afb5f0c8117dde9b4dfd5697e9027210eca76a9be20d63000000000700520063ab6aacffffffff01ec2ddc050000000008ac52ac65ac65ac5100000000", "536300abab", 1, -2070209841, "b362da5634f20be7267de78b545d81773d711b82fe9310f23cd0414a8280801d"], + ["8bff9d170419fa6d556c65fa227a185fe066efc1decf8a1c490bc5cbb9f742d68da2ab7f320100000007ab000053525365a7a43a80ab9593b9e8b6130a7849603b14b5c9397a190008d89d362250c3a2257504eb810200000007acabacac00ab51ee141be418f003e75b127fd3883dbf4e8c3f6cd05ca4afcaac52edd25dd3027ae70a62a00000000008ac52526a5200536affffffffb8058f4e1d7f220a1d1fa17e96d81dfb9a304a2de4e004250c9a576963a586ae0300000005abacac5363b9bc856c039c01d804000000000951656aac53005365acb0724e00000000000565abab63acea7c7a0000000000036a00ac00000000", "6565", 1, -1349282084, "2b822737c2affeefae13451d7c9db22ff98e06490005aba57013f6b9bbc97250"], + ["0e1633b4041c50f656e882a53fde964e7f0c853b0ada0964fc89ae124a2b7ffc5bc97ea6230100000006ac6aacacabacffffffff2e35f4dfcad2d53ea1c8ada8041d13ea6c65880860d96a14835b025f76b1fbd9000000000351515121270867ef6bf63a91adbaf790a43465c61a096acc5a776b8e5215d4e5cd1492e611f761000000000600ac6aab5265ffffffff63b5fc39bcac83ca80ac36124abafc5caee608f9f63a12479b68473bd4bae769000000000965ac52acac5263acabffffffff0163153e020000000008ab005165ab65515300000000", "6a6aac00", 0, -968477862, "20732d5073805419f275c53784e78db45e53332ee618a9fcf60a3417a6e2ca69"], + ["2b052c24022369e956a8d318e38780ef73b487ba6a8f674a56bdb80a9a63634c6110fb5154010000000251acffffffff48fe138fb7fdaa014d67044bc05940f4127e70c113c6744fbd13f8d51d45143e01000000005710db3804e01aa9030000000008acac6a516a5152abfd55aa01000000000751ab510000ac636d6026010000000000b97da9000000000000fddf3b53", "006552", 0, 595461670, "685d67d84755906d67a007a7d4fa311519467b9bdc6a351913246a41e082a29f"], + ["073bc856015245f03b2ea2da62ccedc44ecb99e4250c7042f596bcb23b294c9dc92cfceb6b02000000095163abab52abab636afe292fb303b7c3f001000000000352636af3c49502000000000400ac6a535851850100000000066aac6553ab6500000000", "ab6aab53006aab52", 0, 247114317, "123916c6485cf23bfea95654a8815fbf04ce4d21a3b7f862805c241472906658"], + ["7888b71403f6d522e414d4ca2e12786247acf3e78f1918f6d727d081a79813d129ee8befce0100000009ab516a6353ab6365abffffffff4a882791bf6400fda7a8209fb2c83c6eef51831bdf0f5dacde648859090797ec030000000153ffffffffbb08957d59fa15303b681bad19ccf670d7d913697a2f4f51584bf85fcf91f1f30200000008526565ac52ac63acffffffff0227c0e8050000000001ac361dc801000000000800515165ab00ab0000000000", "656a", 2, 1869281295, "f43378a0b7822ad672773944884e866d7a46579ee34f9afc17b20afc1f6cf197"], + ["cc4dda57047bd0ca6806243a6a4b108f7ced43d8042a1acaa28083c9160911cf47eab910c40200000007526a0000ab6a63e4154e581fcf52567836c9a455e8b41b162a78c85906ccc1c2b2b300b4c69caaaa2ba0230300000008ab5152ac5100ab65ffffffff69696b523ed4bd41ecd4d65b4af73c9cf77edf0e066138712a8e60a04614ea1c0300000004ab6a000016c9045c7df7836e05ac4b2e397e2dd72a5708f4a8bf6d2bc36adc5af3cacefcf074b8b403000000065352ac5252acffffffff01d7e380050000000000cf4e699a", "525163656351", 1, -776533694, "ff18c5bffd086e00917c2234f880034d24e7ea2d1e1933a28973d134ca9e35d2"], + ["b7877f82019c832707a60cf14fba44cfa254d787501fdd676bd58c744f6e951dbba0b3b77f0200000009ac515263ac53525300a5a36e500148f89c0500000000085265ac6a6a65acab00000000", "6563", 0, -1785108415, "cb6e4322955af12eb29613c70e1a00ddbb559c887ba844df0bcdebed736dffbd"], + ["aeb14046045a28cc59f244c2347134d3434faaf980961019a084f7547218785a2bd03916f3000000000165f852e6104304955bda5fa0b75826ee176211acc4a78209816bbb4419feff984377b2352200000000003a94a5032df1e0d60390715b4b188c330e4bb7b995f07cdef11ced9d17ee0f60bb7ffc8e0100000002516513e343a5c1dc1c80cd4561e9dddad22391a2dbf9c8d2b6048e519343ca1925a9c6f0800a020000000665516365ac513180144a0290db27000000000006ab655151ab5138b187010000000007ab5363abac516a9e5cd98a", "53ac", 0, 478591320, "e8d89a302ae626898d4775d103867a8d9e81f4fd387af07212adab99946311ef"], + ["c9270fe004c7911b791a00999d108ce42f9f1b19ec59143f7b7b04a67400888808487bd59103000000066a0052ac6565b905e76687be2dd7723b22c5e8269bc0f2000a332a289cfc40bc0d617cfe3214a61a85a30300000007ac63ac00635251560871209f21eb0268f175b8b4a06edd0b04162a974cf8b5dada43e499a1f22380d35ede0300000000792213fc58b6342cc8100079f9f5f046fb89f2d92cf0a2cb6d07304d32d9da858757037c0000000008abab51636565516affffffff02c72a8b03000000000452acac530dfb9f05000000000096f94307", "5253ab536351", 3, 543688436, "0278adbcc476d135493ae9bdcd7b3c2002df17f2d81c17d631c50c73e546c264"], + ["57a5a04c0278c8c8e243d2df4bb716f81d41ac41e2df153e7096f5682380c4f441888d9d260300000004ab63ab6afdbe4203525dff42a7b1e628fe22bccaa5edbb34d8ab02faff198e085580ea5fcdb0c61b0000000002ac6affffffff03375e6c05000000000663ab516a6a513cb6260400000000007ca328020000000006516a636a52ab94701cc7", "0053ac5152", 0, -550925626, "b7ca991ab2e20d0158168df2d3dd842a57ab4a3b67cca8f45b07c4b7d1d11126"], + ["072b75a504ad2550c2e9a02614bc9b2a2f50b5b553af7b87c0ef07c64ddc8d8934c96d216401000000036aabaca1387242a5bcd21099b016ad6045bed7dce603472757d9822cc5f602caa4ae20414d378b02000000026a63e4ac816734acdc969538d6f70b8ab43a2589f55e0177a4dc471bdd0eb61d59f0f46f6bb801000000065351526aab52d9f2977be76a492c3a7617b7a16dc29a3b0a7618f328c2f7d4fd9bafe760dc427a5066ef000000000465635165ffffffff02c5793600000000000165296820050000000002ac6300000000", "53006a6aac0052ab", 2, 66084636, "437e89bb6f70fd2ed2feef33350b6f6483b891305e574da03e580b3efd81ae13"], + ["7e27c42d0279c1a05eeb9b9faedcc9be0cab6303bde351a19e5cbb26dd0d594b9d74f40d2b020000000200518c8689a08a01e862d5c4dcb294a2331912ff11c13785be7dce3092f154a005624970f84e0200000000500cf5a601e74c1f0000000000076aab52636a6a5200000000", "6500006a5351", 0, 449533391, "535ba819d74770d4d613ee19369001576f98837e18e1777b8246238ff2381dd0"], + ["11414de403d7f6c0135a9df01cb108c1359b8d4e105be50a3dcba5e6be595c8817217490b20000000003005263ffffffff0c6becb9c3ad301c8dcd92f5cbc07c8bed7973573806d1489316fc77a829da03030000000700005253535352ffffffff2346d74ff9e12e5111aa8779a2025981850d4bf788a48de72baa2e321e4bc9ca00000000056352acab63cc585b64045e0385050000000009ab5253ab516aacac00efa9cf0300000000065200635151acbe80330400000000070063635100ab000be159050000000007525300655300ac00000000", "51656a0051ab", 0, 683137826, "d4737f3b58f3e5081b35f36f91acde89dda00a6a09d447e516b523e7a99264d5"], + ["1c6b5f29033fc139338658237a42456123727c8430019ca25bd71c6168a9e35a2bf54538d80100000008536aac52ac6a6a52ffffffff3fb36be74036ff0c940a0247c451d923c65f826793d0ac2bb3f01ecbec8033290100000007ab000051ab6363ffffffff5d9eca0cf711685105bd060bf7a67321eaef95367acffab36ce8dedddd632ee2000000000652ac6a63ac517167319e032d26de040000000003516363dc38fb010000000000b37b00000000000006ab520051ac534baba51f", "636300ababac6563", 0, -2049129935, "3282a2ec6b8c87c9303e6060c17b421687db1bd35fbfa0345b48f2490e15b6cc"], + ["978b9dad0214cfc7ce392d74d9dcc507350dc34007d72e4125861c63071ebf2cc0a6fd4856020000000651ac6a6aab52ffffffff47f20734e3370e733f87a6edab95a7a268ae44db7a8974e255614836b22938720200000008635265ac51516553ffffffff0137b2560100000000035252ac2f3363e9", "006aab6352", 1, 2014249801, "55611a5fb1483bce4c14c33ed15198130e788b72cd8929b2ceef4dd68b1806bf"], + ["442f1c8703ab39876153c241ab3d69f432ba6db4732bea5002be45c8ca10c3a2356fe0e9590300000001accb2b679cab7c58a660cb6d4b3452c21cd7251a1b77a52c300f655f5baeb6fa27ff5b79880300000003005252e5ccf55712bc8ed6179f6726f8a78f3018a7a0391594b7e286ef5ee99efdcde302a102cc0200000009006352526351536a63ffffffff04443f63030000000006536a63ab63651405fb020000000009ac535351525300ab6a9f172b000000000004ab535263ad5c50050000000008656a65ab630000ac00000000", "65636aab006552", 2, 2125838294, "b3ff10f21e71ebc8b25fe058c4074c42f08617e0dcc03f9e75d20539d3242644"], + ["2b3470dd028083910117f86614cdcfb459ee56d876572510be4df24c72e8f58c70d5f5948b03000000066aab65635265da2c3aac9d42c9baafd4b655c2f3efc181784d8cba5418e053482132ee798408ba43ccf90300000000ffffffff047dda4703000000000765516a52ac53009384a603000000000651636a63ab6a8cf57a03000000000352ab6a8cf6a405000000000952636a6a6565525100661e09cb", "ac520063ac6a6a52", 1, 1405647183, "9b360c3310d55c845ef537125662b9fe56840c72136891274e9fedfef56f9bb5"], + ["d74282b501be95d3c19a5d9da3d49c8a88a7049c573f3788f2c42fc6fa594f59715560b9b00000000009655353525265ac52ac9772121f028f8303030000000003510065af5f47040000000007ac516a6551630000000000", "acab53006363ac", 0, -1113209770, "2f482b97178f17286f693796a756f4d7bd2dfcdbecd4142528eec1c7a3e5101a"], + ["3a5644a9010f199f253f858d65782d3caec0ac64c3262b56893022b9796086275c9d4d097b02000000009d168f7603a67b30050000000007ac51536a0053acd9d88a050000000007655363535263ab3cf1f403000000000352ac6a00000000", "005363536565acac6a", 0, -1383947195, "6390ab0963cf611e0cea35a71dc958b494b084e6fd71d22217fdc5524787ade6"], + ["67b3cc43049d13007485a8133b90d94648bcf30e83ba174f5486ab42c9107c69c5530c5e1f0000000003005100ffffffff9870ebb65c14263282ea8d41e4f4f40df16b565c2cf86f1d22a9494cad03a67f01000000016a5a121bee5e359da548e808ae1ad6dfccae7c67cbb8898d811638a1f455a671e822f228ef030000000151c1fcc9f9825f27c0dde27ea709da62a80a2ff9f6b1b86a5874c50d6c37d39ae31fb6c8a0030000000163553b8786020ca74a00000000000665635153ab5275c0760000000000020052e659b05d", "636aab6a6a", 0, -342795451, "f77c3322c97b1681c17b1eba461fa27b07e04c1534e8aaf735a49cab72c7c2e2"], + ["bda1ff6804a3c228b7a12799a4c20917301dd501c67847d35da497533a606701ad31bf9d5e0300000001ac16a6c5d03cf516cd7364e4cbbf5aeccd62f8fd03cb6675883a0636a7daeb650423cb1291010000000500656553ac4a63c30b6a835606909c9efbae1b2597e9db020c5ecfc0642da6dc583fba4e84167539a8020000000865525353515200acffffffff990807720a5803c305b7da08a9f24b92abe343c42ac9e917a84e1f335aad785d00000000026a52ffffffff04981f20030000000001ab8c762200000000000253ab690b9605000000000151ce88b301000000000753526a6a51006500000000", "000052ac52530000", 1, -1809193140, "5299b0fb7fc16f40a5d6b337e71fcd1eb04d2600aefd22c06fe9c71fe0b0ba54"], + ["2ead28ff0243b3ab285e5d1067f0ec8724224402b21b9cef9be962a8b0d153d401be99bbee0000000004ac635153ffffffff6985987b7c1360c9fa8406dd6e0a61141709f0d5195f946da55ed83be4e3895301000000020053ffffffff016503d20500000000085251ac6a65656a6a00000000", "51abab", 1, 1723793403, "67483ee62516be17a2431a163e96fd88a08ff2ce8634a52e42c1bc04e30f3f8a"], + ["db4904e6026b6dd8d898f278c6428a176410d1ffbde75a4fa37cda12263108ccd4ca6137440100000007656a0000515263ffffffff1db7d5005c1c40da0ed17b74cf6b2a6ee2c33c9e0bacda76c0da2017dcac2fc70200000004abab6a53ffffffff0454cf2103000000000153463aef000000000009ab6a630065ab52636387e0ed050000000000e8d16f05000000000352ac63e4521b22", "", 1, 1027042424, "48315a95e49277ab6a2d561ee4626820b7bab919eea372b6bf4e9931ab221d04"], + ["dca31ad10461ead74751e83d9a81dcee08db778d3d79ad9a6d079cfdb93919ac1b0b61871102000000086500525365ab51ac7f7e9aed78e1ef8d213d40a1c50145403d196019985c837ffe83836222fe3e5955e177e70100000006525152525300ffffffff5e98482883cc08a6fe946f674cca479822f0576a43bf4113de9cbf414ca628060100000006ac53516a5253ffffffff07490b0b898198ec16c23b75d606e14fa16aa3107ef9818594f72d5776805ec502000000036a0052ffffffff01932a2803000000000865ab6551ac6a516a2687aa06", "635300ac", 2, -1880362326, "74d6a2fa7866fd8b74b2e34693e2d6fd690410384b7afdcd6461b1ae71d265ce"], + ["e14e1a9f0442ab44dfc5f6d945ad1ff8a376bc966aad5515421e96ddbe49e529614995cafc03000000055165515165fffffffff97582b8290e5a5cfeb2b0f018882dbe1b43f60b7f45e4dd21dbd3a8b0cfca3b0200000000daa267726fe075db282d694b9fee7d6216d17a8c1f00b2229085495c5dc5b260c8f8cd5d000000000363ac6affffffffaab083d22d0465471c896a438c6ac3abf4d383ae79420617a8e0ba8b9baa872b010000000963526563ac5363ababd948b5ce022113440200000000076a636552006a53229017040000000000e6f62ac8", "526353636a65", 3, -485265025, "1bc8ad76f9b7c366c5d052dc479d6a8a2015566d3a42e93ab12f727692c89d65"], + ["720d4693025ca3d347360e219e9bc746ef8f7bc88e8795162e5e2f0b0fc99dc17116fc937100000000046353520045cb1fd79824a100d30b6946eab9b219daea2b0cdca6c86367c0c36af98f19ac64f3575002000000008a1c881003ed16f3050000000008536a63630000abac45e0e704000000000151f6551a05000000000963536565515363abab00000000", "6553ab6a6a510000ab", 1, 1249091393, "a575fa4f59a8e90cd07de012c78fe8f981183bb170b9c50fcc292b8c164cbc3b"], + ["69df842a04c1410bfca10896467ce664cfa31c681a5dac10106b34d4b9d4d6d0dc1eac01c1000000000551536a5165269835ca4ad7268667b16d0a2df154ec81e304290d5ed69e0069b43f8c89e673328005e200000000076a5153006aacabffffffffc9314bd80b176488f3d634360fcba90c3a659e74a52e100ac91d3897072e3509010000000765abac51636363ffffffff0e0768b13f10f0fbd2fa3f68e4b4841809b3b5ba0e53987c3aaffcf09eee12bf0300000008ac535263526a53ac514f4c2402da8fab0400000000001ef15201000000000451526a52d0ec9aca", "525365ac52", 1, 313967049, "a72a760b361af41832d2c667c7488dc9702091918d11e344afc234a4aea3ec44"], + ["adf2340d03af5c589cb5d28c06635ac07dd0757b884d4777ba85a6a7c410408ad5efa8b19001000000045100ab00ffffffff808dc0231c96e6667c04786865727013922bcb7db20739b686f0c17f5ba70e8f0300000000fd2332a654b580881a5e2bfec8313f5aa878ae94312f37441bf2d226e7fc953dcf0c77ab000000000163aa73dc580412f8c2050000000005636aacac63da02d502000000000153e74b52020000000001536b293d030000000009636552ababacab526500000000", "000052ab52ababab", 0, -568651175, "2c45d021db545df7167ac03c9ee56473f2398d9b2b739cf3ff3e074501d324f8"], + ["e4fec9f10378a95199c1dd23c6228732c9de0d7997bf1c83918a5cfd36012476c0c3cba24002000000085165536500ac0000ad08ab93fb49d77d12a7ccdbb596bc5110876451b53a79fdce43104ff1c316ad63501de801000000046a6352ab76af9908463444aeecd32516a04dd5803e02680ed7f16307242a794024d93287595250f4000000000089807279041a82e603000000000200521429100200000000055253636a63f20b940400000000004049ed04000000000500ab5265ab43dfaf7d", "6563526aac", 2, -1923470368, "32f3c012eca9a823bebb9b282240aec40ca65df9f38da43b1dcfa0cac0c0df7e"], + ["4000d3600100b7a3ff5b41ec8d6ccdc8b2775ad034765bad505192f05d1f55d2bc39d0cbe10100000007ab5165ac6a5163ffffffff034949150100000000026a6a92c9f6000000000008ab6553ab6aab635200e697040000000007636a5353525365237ae7d2", "52000063", 0, -880046683, "c76146f68f43037289aaeb2bacf47408cddc0fb326b350eb4f5ef6f0f8564793"], + ["eabc0aa701fe489c0e4e6222d72b52f083166b49d63ad1410fb98caed027b6a71c02ab830c03000000075253ab63530065ffffffff01a5dc0b05000000000253533e820177", "", 0, 954499283, "1d849b92eedb9bf26bd4ced52ce9cb0595164295b0526842ab1096001fcd31b1"], + ["d48d55d304aad0139783b44789a771539d052db565379f668def5084daba0dfd348f7dcf6b00000000006826f59e5ffba0dd0ccbac89c1e2d69a346531d7f995dea2ca6d7e6d9225d81aec257c6003000000096a655200ac656552acffffffffa188ffbd5365cae844c8e0dea6213c4d1b2407274ae287b769ab0bf293e049eb0300000005ac6a6aab51ad1c407c5b116ca8f65ed496b476183f85f072c5f8a0193a4273e2015b1cc288bf03e9e2030000000252abffffffff04076f44040000000006655353abab53be6500050000000003ac65ac3c15040500000000095100ab536353516a52ed3aba04000000000900ac53ab53636aabac00000000", "5253526563acac", 2, -1506108646, "bbee17c8582514744bab5df50012c94b0db4aff5984d2e13a8d09421674404e2"], + ["9746f45b039bfe723258fdb6be77eb85917af808211eb9d43b15475ee0b01253d33fc3bfc502000000065163006a655312b12562dc9c54e11299210266428632a7d0ee31d04dfc7375dcad2da6e9c11947ced0e000000000009074095a5ac4df057554566dd04740c61490e1d3826000ad9d8f777a93373c8dddc4918a00000000025351ffffffff01287564030000000004636a00ab00000000", "52", 2, -1380411075, "84af1623366c4db68d81f452b86346832344734492b9c23fbb89015e516c60b2"], + ["8731b64903d735ba16da64af537eaf487b57d73977f390baac57c7b567cb2770dfa2ef65870100000001635aedd990c42645482340eacb0bfa4a0a9e888057389c728b5b6a8691cdeb1a6a67b45e140200000008ac53526a52516551ffffffff45c4f567c47b8d999916fd49642cbc5d10d43c304b99e32d044d35091679cb860100000003006a51ffffffff0176d6c200000000000000000000", "ab6a65ab53", 2, -1221546710, "ccfdba36d9445f4451fb7cbf0752cc89c23d4fc6fff0f3930d20e116f9db0b95"], + ["f5cfc52f016209ab1385e890c2865a74e93076595d1ca77cbe8fbf2022a2f2061a90fb0f3e010000000253acffffffff027de73f0200000000085252ac510052acac49cd6a020000000000e6c2cb56", "516552535300ab63", 0, -1195302704, "5532717402a2da01a1da912d824964024185ca7e8d4ad1748659dc393a14182b"], + ["df0a32ae01c4672fd1abd0b2623aae0a1a8256028df57e532f9a472d1a9ceb194267b6ee190200000009536a6a51516a525251b545f9e803469a2302000000000465526500810631040000000000441f5b050000000006530051006aaceb183c76", "536a635252ac6a", 0, 1601138113, "9a0435996cc58bdba09643927fe48c1fc908d491a050abbef8daec87f323c58f"], + ["d102d10c028b9c721abb259fe70bc68962f6cae384dabd77477c59cbeb1fb26266e091ba3e0100000002516affffffffe8d7305a74f43e30c772109849f4cd6fb867c7216e6d92e27605e69a0818899700000000026a65ecf82d58027db4620500000000026552c28ed3010000000001ab00000000", "0051ab515365", 1, -131815460, "1d1757a782cb5860302128bcbe9398243124a2f82d671a113f74f8e582c7a182"], + ["cef930ed01c36fcb1d62ceef931bef57098f27a77a4299904cc0cbb44504802d535fb11557010000000153ffffffff02c8657403000000000863ac655253520063d593380400000000046aab536a00000000", "656a0051ab6365ab53", 0, -351313308, "e69dba3efb5c02af2ab1087d0a990678784671f4744d01ca097d71aec14dd8e9"], + ["b1c0b71804dff30812b92eefb533ac77c4b9fdb9ab2f77120a76128d7da43ad70c20bbfb990200000002536392693e6001bc59411aebf15a3dc62a6566ec71a302141b0c730a3ecc8de5d76538b30f55010000000665535252ac514b740c6271fb9fe69fdf82bf98b459a7faa8a3b62f3af34943ad55df4881e0d93d3ce0ac0200000000c4158866eb9fb73da252102d1e64a3ce611b52e873533be43e6883137d0aaa0f63966f060000000001abffffffff04a605b604000000000851006a656a630052f49a0300000000000252515a94e1050000000009abac65ab0052abab00fd8dd002000000000651535163526a2566852d", "ac5363", 0, -1718831517, "b0dc030661783dd9939e4bf1a6dfcba809da2017e1b315a6312e5942d714cf05"], + ["6a270ee404ebc8d137cfd4bb6b92aa3702213a3139a579c1fc6f56fbc7edd9574ef17b13f30100000009ab00ab656565ababacffffffffaa65b1ab6c6d87260d9e27a472edceb7dd212483e72d90f08857abf1dbfd46d10100000000fffffffff93c4c9c84c4dbbe8a912b99a2830cfe3401aebc919041de063d660e585fc9f002000000096aabacab52ac6a53acfa6dcef3f28355a8d98eee53839455445eeee83eecd2c854e784efa53cee699dbfecaebd0100000003ab6a51ffffffff04f7d71b050000000009ac6a536aac6a6365513c37650500000000065265abab6a53fa742002000000000039ed82030000000009516aac635165ab51ab2fdabd17", "ab535252526563", 1, -1326210506, "1dec0d5eb921bf5b2df39c8576e19c38d0c17254a4a0b78ac4b5422bcc426258"], + ["3657e4260304ccdc19936e47bdf058d36167ee3d4eb145c52b224eff04c9eb5d1b4e434dfc0000000001ab58aefe57707c66328d3cceef2e6f56ab6b7465e587410c5f73555a513ace2b232793a74400000000036a006522e69d3a785b61ad41a635d59b3a06b2780a92173f85f8ed428491d0aaa436619baa9c4501000000046351abab2609629902eb7793050000000000a1b967040000000003525353a34d6192", "516a", 0, -1761874713, "0a2ff41f6d155d8d0e37cd9438f3b270df9f9214cda8e95c76d5a239ca189df2"], + ["a0eb6dc402994e493c787b45d1f946d267b09c596c5edde043e620ce3d59e95b2b5b93d43002000000096a5252526aac63ab6555694287a279e29ee491c177a801cd685b8744a2eab83824255a3bcd08fc0e3ea13fb8820000000009abab6365ab52ab0063ffffffff029e424a040000000008acab53ab516a636a23830f0400000000016adf49c1f9", "ac0065ac6500005252", 1, 669294500, "e05e3d383631a7ed1b78210c13c2eb26564e5577db7ddfcea2583c7c014091d4"], + ["6e67c0d3027701ef71082204c85ed63c700ef1400c65efb62ce3580d187fb348376a23e9710200000001655b91369d3155ba916a0bc6fe4f5d94cad461d899bb8aaac3699a755838bfc229d6828920010000000765536353526a52ffffffff04c0c792000000000005650052535372f79e000000000001527fc0ee010000000005ac5300ab65d1b3e902000000000251aba942b278", "6a5151", 0, 1741407676, "e657e2c8ec4ebc769ddd3198a83267b47d4f2a419fc737e813812acefad92ff7"], + ["8f53639901f1d643e01fc631f632b7a16e831d846a0184cdcda289b8fa7767f0c292eb221a00000000046a53abacffffffff037a2daa01000000000553ac6a6a51eac349020000000005ac526552638421b3040000000007006a005100ac63048a1492", "ac65", 0, 1033685559, "da86c260d42a692358f46893d6f91563985d86eeb9ea9e21cd38c2d8ffcfcc4d"], + ["491f99cb01bdfba1aa235e5538dac081fae9ce55f9622de483afe7e65105c2b0db75d360d200000000045251636340b60f0f041421330300000000096351ac000051636553ce2822040000000005516a00ac5180c8e40300000000025100caa8570400000000020000cfdc8da6", "6a5100516aab655365", 0, -953727341, "397c68803b7ce953666830b0221a5e2bcf897aa2ded8e36a6b76c497dcb1a2e1"], + ["b3cad3a7041c2c17d90a2cd994f6c37307753fa3635e9ef05ab8b1ff121ca11239a0902e700300000009ab635300006aac5163ffffffffcec91722c7468156dce4664f3c783afef147f0e6f80739c83b5f09d5a09a57040200000004516a6552ffffffff969d1c6daf8ef53a70b7cdf1b4102fb3240055a8eaeaed2489617cd84cfd56cf020000000352ab53ffffffff46598b6579494a77b593681c33422a99559b9993d77ca2fa97833508b0c169f80200000009655300655365516351ffffffff04d7ddf800000000000853536a65ac6351ab09f3420300000000056aab65abac33589d04000000000952656a65655151acac944d6f0400000000006a8004ba", "005165", 1, 1035865506, "fe1dc9e8554deecf8f50c417c670b839cc9d650722ebaaf36572418756075d58"], + ["e1cfd73b0125add9e9d699f5a45dca458355af175a7bd4486ebef28f1928d87864384d02df02000000036a0051ffffffff0357df030100000000036a5365777e2d04000000000763ab6a00005265f434a601000000000351655100000000", "ab53ab", 0, -1936500914, "950f4b4f72ccdf8a6a0f381265d6c8842fdb7e8b3df3e9742905f643b2432b69"], + ["cf781855040a755f5ba85eef93837236b34a5d3daeb2dbbdcf58bb811828d806ed05754ab8010000000351ac53ffffffffda1e264727cf55c67f06ebcc56dfe7fa12ac2a994fecd0180ce09ee15c480f7d00000000096351516a51acac00ab53dd49ff9f334befd6d6f87f1a832cddfd826a90b78fd8cf19a52cb8287788af94e939d6020000000700525251ac526310d54a7e8900ed633f0f6f0841145aae7ee0cbbb1e2a0cae724ee4558dbabfdc58ba6855010000000552536a53abfd1b101102c51f910500000000096300656a525252656a300bee010000000009ac52005263635151abe19235c9", "53005365", 2, 1422854188, "d5981bd4467817c1330da72ddb8760d6c2556cd809264b2d85e6d274609fc3a3"], + ["fea256ce01272d125e577c0a09570a71366898280dda279b021000db1325f27edda41a53460100000002ab53c752c21c013c2b3a01000000000000000000", "65", 0, 1145543262, "076b9f844f6ae429de228a2c337c704df1652c292b6c6494882190638dad9efd"] + ] + for k in t: + tx = Transaction(k[0]) + self.assertEqual(tx.sig_hash(k[2], k[1], k[3]), k[4]) + + def test_sighash_segwit(self): + """ + ["raw_transaction, script, input_index, hashType, signature_hash (result)"], + :return: + """ + print("\nNative P2WPKH") + raw_tx = "0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f0000000000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000" + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(1, 600000000, "1976a9141d0f172a0ecb48aee1be1f2687" + "d2963ae33f71a188ac", + SIGHASH_ALL), + "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670") + + + print("P2SH-P2WPKH") + raw_tx = "0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a54770100000000feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac92040000" + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(0, 1000000000, + "1976a91479091972186c449eb1ded22b78e40d009bdf008988ac", + SIGHASH_ALL), + "64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6") + print("Native P2WSH") + raw_tx = "0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000" + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(1, 4900000000, + "23210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac", + SIGHASH_SINGLE), + "fef7bd749cce710c5c052bd796df1af0d935e59cea63736268bcbe2d2134fc47") + + print("P2SH-P2WSH SIGHASH_ALL") + raw_tx = "010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000" + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(0, 987654321, + "cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae", + SIGHASH_ALL), + "185c0be5263dce5b4bb50a047973c1b6272bfbd0103a89444597dc40b248ee7c") + + print("P2SH-P2WSH SIGHASH_NONE") + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(0, 987654321, + "cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae", + SIGHASH_NONE), + "e9733bc60ea13c95c6527066bb975a2ff29a925e80aa14c213f686cbae5d2f36") + + print("P2SH-P2WSH SIGHASH_SINGLE") + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(0, 987654321, + "cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae", + SIGHASH_SINGLE), + "1e1f1c303dc025bd664acb72e583e933fae4cff9148bf78c157d1e8f78530aea") + + print("P2SH-P2WSH SIGHASH_ALL + SIGHASH_ANYONECANPAY") + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(0, 987654321, + "cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae", + SIGHASH_ALL + SIGHASH_ANYONECANPAY), + "2a67f03e63a6a422125878b40b82da593be8d4efaafe88ee528af6e5a9955c6e") + + print("P2SH-P2WSH SIGHASH_NONE + SIGHASH_ANYONECANPAY") + + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(0, 987654321, + "cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae", + SIGHASH_NONE + SIGHASH_ANYONECANPAY), + "781ba15f3779d5542ce8ecb5c18716733a5ee42a6f51488ec96154934e2c890a") + + print("P2SH-P2WSH SIGHASH_SINGLE + SIGHASH_ANYONECANPAY") + self.assertEqual(Transaction(raw_tx).sig_hash_segwit(0, 987654321, + "cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae", + SIGHASH_SINGLE + SIGHASH_ANYONECANPAY), + "511e8e52ed574121fc1b654970395502128263f62662e076dc6baf05c2e6a99b") + + diff --git a/pybtc/test/transaction_constructor.py b/pybtc/test/transaction_constructor.py new file mode 100644 index 0000000..059b621 --- /dev/null +++ b/pybtc/test/transaction_constructor.py @@ -0,0 +1,1092 @@ +import unittest +import os +import sys +parentPath = os.path.abspath("..") +if parentPath not in sys.path: + sys.path.insert(0, parentPath) + +from secp256k1 import ffi +import secp256k1 +from pybtc.functions import * +from pybtc.opcodes import * +from pybtc.transaction import * +from pybtc.address import * +from binascii import unhexlify +from pybtc import address_to_hash as address2hash160 + + +def decode_block_tx(block): + stream = get_stream(block) + stream.seek(80) + return {i: Transaction(stream) for i in range(var_int_to_int(read_var_int(stream)))} + + +class TransactionConstructorTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("\nTesting Transaction class [constructor]:\n") + + # def test_serialaize_and_perfomance(self): + # f = open('./test/raw_block.txt') + # fc = f.readline() + # qt = time.time() + # bt = decode_block_tx(fc[:-1]) + # self.assertEqual(time.time() - qt < 1, 1) + # print("decode block tx count: %s time: %s" % (len(bt), time.time() - qt)) + # for t in bt: + # raw_tx_legacy = bt[t].serialize(segwit=False) + # raw_tx_segwit = bt[t].serialize() + # bt[t] = bt[t].decode() + # # print(bt[t]["txId"], bt[t]["hash"], "segwit:", + # # True if "segwit" in bt[t] else False, end = " ") + # self.assertEqual(bt[t].serialize(segwit=False), raw_tx_legacy) + # self.assertEqual(bt[t].serialize(), raw_tx_segwit) + # self.assertEqual(rh2s(double_sha256(bt[t].serialize())), bt[t]["hash"]) + # self.assertEqual(rh2s(double_sha256(bt[t].serialize(segwit=False))), bt[t]["txId"]) + # # print("OK") + + def test_blockchain_constructor(self): + # non segwit transaction 110e34e7cba0d579a32c19429683dad9c3b2d4b03edec85c63a69ef0f9e6a12a + raw_tx = "01000000017a5cd38b31ed002fa41380624d4a8c168a2ea71d8668a9b3fea1d571357d5d00000000006b" \ + "483045022100bf7c75ec4c40d2fd1072567c31079ea96666b03f00cb8573f9d81818fb2a612f02204db0" \ + "7e03825f2d8a123682b53afdd7671fa31e34e2689b591d667ec6cc8cd646012102ca63094dd002a53748" \ + "eae1319c91fd9583bb93a6441621c39085789b354569e1ffffffff02204e00000000000017a9143e6f15" \ + "908582f42917ec31e39bf8722fc9d5db3f87763d0900000000001976a914a52dc1cff692810dfe9a918f" \ + "6d2dbd3504fb3ffb88ac00000000" + tx = Transaction(format="raw") + tx.add_input("005d7d3571d5a1feb3a968861da72e8a168c4a4d628013a42f00ed318bd35c7a", + script_sig="483045022100bf7c75ec4c40d2fd1072567c31079ea96666b03f00cb8573f9d81818fb" + "2a612f02204db07e03825f2d8a123682b53afdd7671fa31e34e2689b591d667ec6cc8c" + "d646012102ca63094dd002a53748eae1319c91fd9583bb93a6441621c39085789b354569e1") + tx.add_output(20000, "37P8thrtDXb6Di5E7f4FL3bpzum3fhUvT7") + tx.add_output(605558, "1G4PJum2iB4giFQFpQj8RqzfbKegvWEJXV") + self.assertEqual(tx.serialize(segwit=False, hex=True), raw_tx) + self.assertEqual(tx.serialize(segwit=True, hex=True), raw_tx) + self.assertEqual(tx["txId"], tx["hash"]) + self.assertEqual(rh2s(tx["txId"]), "110e34e7cba0d579a32c19429683dad9c3b2d4b03edec85c63a69ef0f9e6a12a") + + # from decoded + tx = Transaction() + tx.add_input("005d7d3571d5a1feb3a968861da72e8a168c4a4d628013a42f00ed318bd35c7a", + script_sig="483045022100bf7c75ec4c40d2fd1072567c31079ea96666b03f00cb8573f9d81818fb" + "2a612f02204db07e03825f2d8a123682b53afdd7671fa31e34e2689b591d667ec6cc8c" + "d646012102ca63094dd002a53748eae1319c91fd9583bb93a6441621c39085789b354569e1") + tx.add_output(20000, "37P8thrtDXb6Di5E7f4FL3bpzum3fhUvT7") + tx.add_output(605558, "1G4PJum2iB4giFQFpQj8RqzfbKegvWEJXV") + self.assertEqual(tx.serialize(segwit=False, hex=True), raw_tx) + self.assertEqual(tx.serialize(segwit=True, hex=True), raw_tx) + self.assertEqual(tx["txId"], tx["hash"]) + self.assertEqual(tx["txId"], "110e34e7cba0d579a32c19429683dad9c3b2d4b03edec85c63a69ef0f9e6a12a") + + tx.encode() + self.assertEqual(tx.serialize(segwit=False, hex=True), raw_tx) + self.assertEqual(tx.serialize(segwit=True, hex=True), raw_tx) + self.assertEqual(tx["txId"], tx["hash"]) + self.assertEqual(rh2s(tx["txId"]), "110e34e7cba0d579a32c19429683dad9c3b2d4b03edec85c63a69ef0f9e6a12a") + + tx.decode() + self.assertEqual(tx.serialize(segwit=False, hex=True), raw_tx) + self.assertEqual(tx.serialize(segwit=True, hex=True), raw_tx) + self.assertEqual(tx["txId"], tx["hash"]) + self.assertEqual(tx["txId"], "110e34e7cba0d579a32c19429683dad9c3b2d4b03edec85c63a69ef0f9e6a12a") + + # construct segwit transaction + raw_segwit_view = "0100000000010131f81b1b36f3baf0df1c4825363a427c13fee246f5275ab19bd3d9691cab2f77010" \ + "0000000ffffffff0428032f000000000017a91469f3772509d00c88afbdfd9a962573104c5572aa87" \ + "20a10700000000001976a914b97d5f71eac6f1b9b893815ee2d393cee5b939fc88ac166b060000000" \ + "00017a9148130201b6b9b07e34bae2f1a03ab470b1f6bddf08711df090000000000220020701a8d40" \ + "1c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d040047304402206bc09c33588" \ + "b92f245e18d70538c0eb350bfe3861cec518be85e4268eb1740b602207300db75d81f4a2de93b7c37" \ + "faa0e32a176ca444b24509553e342f70002e44ec014830450221009947103bd40e25b8a54b95624cf" \ + "77199ef674aab4ba53da47280f9208811cdd002207f9dbca0804be6f7c206953971af2a5e538d4b64" \ + "0ba8041264d24bb40e8542ee016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea3" \ + "68e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496" \ + "feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000" + raw_non_segwit_view = "010000000131f81b1b36f3baf0df1c4825363a427c13fee246f5275ab19bd3d9691cab2f77010" \ + "0000000ffffffff0428032f000000000017a91469f3772509d00c88afbdfd9a962573104c5572" \ + "aa8720a10700000000001976a914b97d5f71eac6f1b9b893815ee2d393cee5b939fc88ac166b0" \ + "6000000000017a9148130201b6b9b07e34bae2f1a03ab470b1f6bddf08711df09000000000022" \ + "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d00000000" + + tx = Transaction() + tx.add_input("772fab1c69d9d39bb15a27f546e2fe137c423a3625481cdff0baf3361b1bf831", 1, + tx_in_witness=["", + "304402206bc09c33588b92f245e18d70538c0eb350bfe3861cec518be85e4268eb1740b" + "602207300db75d81f4a2de93b7c37faa0e32a176ca444b24509553e342f70002e44ec01", + "30450221009947103bd40e25b8a54b95624cf77199ef674aab4ba53da47280f9208811c" + "dd002207f9dbca0804be6f7c206953971af2a5e538d4b640ba8041264d24bb40e8542ee01", + "52210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2" + "103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103" + "c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae"]) + tx.add_output(3081000, "3BMEXxajhZYe3xijDp4R9axzJ6Avywupwk") + tx.add_output(500000, "1HunCYemQiLVPMbqY1QdarDKPiVq2Y86aR") + tx.add_output(420630, "3DU6k6uJBaeSJqkjTYLHixKycrfAZQQ5pP") + tx.add_output(646929, "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej") + + self.assertEqual(tx.serialize(segwit=False, hex=True), raw_non_segwit_view) + self.assertEqual(tx.serialize(segwit=True, hex=True), raw_segwit_view) + self.assertEqual(tx["hash"], "56a3ad9e259676b347d7a90d4cf65a3a60c29e0b49dbad0831846bcaad7d5db2") + self.assertEqual(tx["txId"], "4e3895de573305e08b09926f410836ae30e9e3e909b92beea6a4dd7eb096609e") + + # from raw + tx = Transaction(format="raw") + tx.add_input("772fab1c69d9d39bb15a27f546e2fe137c423a3625481cdff0baf3361b1bf831", 1, + tx_in_witness=["", + "304402206bc09c33588b92f245e18d70538c0eb350bfe3861cec518be85e4268eb1740b" + "602207300db75d81f4a2de93b7c37faa0e32a176ca444b24509553e342f70002e44ec01", + "30450221009947103bd40e25b8a54b95624cf77199ef674aab4ba53da47280f9208811c" + "dd002207f9dbca0804be6f7c206953971af2a5e538d4b640ba8041264d24bb40e8542ee01", + "52210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2" + "103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103" + "c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae"]) + tx.add_output(3081000, "3BMEXxajhZYe3xijDp4R9axzJ6Avywupwk") + tx.add_output(500000, "1HunCYemQiLVPMbqY1QdarDKPiVq2Y86aR") + tx.add_output(420630, "3DU6k6uJBaeSJqkjTYLHixKycrfAZQQ5pP") + tx.add_output(646929, "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej") + self.assertEqual(tx.serialize(segwit=False, hex=True), raw_non_segwit_view) + self.assertEqual(tx.serialize(segwit=True, hex=True), raw_segwit_view) + self.assertEqual(rh2s(tx["hash"]), "56a3ad9e259676b347d7a90d4cf65a3a60c29e0b49dbad0831846bcaad7d5db2") + self.assertEqual(rh2s(tx["txId"]), "4e3895de573305e08b09926f410836ae30e9e3e909b92beea6a4dd7eb096609e") + + # remove 2 last outs and add using script + tx.del_output().del_output() + tx.add_output(420630, script_pub_key="a9148130201b6b9b07e34bae2f1a03ab470b1f6bddf087") + tx.add_output(646929, script_pub_key="0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d") + self.assertEqual(tx.serialize(segwit=False, hex=True), raw_non_segwit_view) + self.assertEqual(tx.serialize(segwit=True, hex=True), raw_segwit_view) + self.assertEqual(rh2s(tx["hash"]), "56a3ad9e259676b347d7a90d4cf65a3a60c29e0b49dbad0831846bcaad7d5db2") + self.assertEqual(rh2s(tx["txId"]), "4e3895de573305e08b09926f410836ae30e9e3e909b92beea6a4dd7eb096609e") + self.assertEqual(tx.decode()["vOut"][3]["address"], + "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej") + + # segwit inside p2sh 883f786b3a823b143227e67e47001c11eadf0264ee9149bd5283a6f87a3dcdea + tx = Transaction() + tx.add_input("376c1ed1c7d3108d17f80f3daa6c4e8eda5c83c7420d5ebf220bec723f17eccd", + script_sig="160014bed11faa92d17d45905c41ba984d1a9107cead5f", + tx_in_witness=["3045022100ec7467e47c94a2c33b13cee8a07a5893a9e312fd3cb59a3633315468c171c7" + "550220014f1be125744137ebb93c120c0e51c6a190e8fd148bf637345412343efbb3fd01", + "023170589b32f242682d1f69f67c9838be0afb557cbb9c42516780e60cdce5d005"]) + tx.add_output(16760, "1BviYPm6tjmAU3JzK7JgW4GcG1NPDwpcJA") + self.assertEqual(tx["hash"], "5052d63f0e94dfb811287ae7f1bce9689773fdb236a48d2a266aa9016190015a") + self.assertEqual(tx["txId"], "883f786b3a823b143227e67e47001c11eadf0264ee9149bd5283a6f87a3dcdea") + self.assertEqual(tx["size"], 218) + self.assertEqual(tx["vSize"], 136) + self.assertEqual(tx["weight"], 542) + self.assertEqual(tx["bSize"], 108) + + # coinbase transaction e94469dd87ac25ad9c4fe46f9bf51dbd587be0655bca87499d6faf35c432af46 + tx = Transaction() + tx.add_input(script_sig="03f5a407172f5669614254432f4d696e6564206279206a6e3734312f2cfabe6d6d978decb415" + "6738d7e170b52ba6d79129afb443cd1444215621f1b2fa0912389c01000000000000001095bc" + "4e04f95c206d2f9a5abc64050060", + tx_in_witness=["00" * 32]) + tx.add_output(2018213798, "18cBEMRxXHqzWWCxZNtU91F5sbUNKhL5PX") + tx.add_output(0, script_pub_key="6a24aa21a9edc00d472fceafe0fc49747df90d75f7324e3c83214b1a1308f3eda376848df481") + + self.assertEqual(tx["hash"], "906221165b1c5f236a787ba5dbd8c9d590c52d30a39ee557a504c5c64e70e920") + self.assertEqual(tx["txId"], "e94469dd87ac25ad9c4fe46f9bf51dbd587be0655bca87499d6faf35c432af46") + self.assertEqual(tx["size"], 258) + self.assertEqual(tx["vSize"], 231) + self.assertEqual(tx["weight"], 924) + self.assertEqual(tx["bSize"], 222) + + def test_delete_from_script(self): + s = BYTE_OPCODE["OP_FALSE"] + BYTE_OPCODE["OP_1"] + d = b"" + self.assertEqual(delete_from_script(s, d), s) + s = BYTE_OPCODE["OP_1"] + BYTE_OPCODE["OP_2"] + BYTE_OPCODE["OP_3"] + d = BYTE_OPCODE["OP_2"] + e = BYTE_OPCODE["OP_1"] + BYTE_OPCODE["OP_3"] + self.assertEqual(delete_from_script(s, d), e) + + s = BYTE_OPCODE["OP_3"] + BYTE_OPCODE["OP_1"] + BYTE_OPCODE["OP_3"] + s += BYTE_OPCODE["OP_3"] + BYTE_OPCODE["OP_4"] + BYTE_OPCODE["OP_3"] + d = BYTE_OPCODE["OP_3"] + e = BYTE_OPCODE["OP_1"] + BYTE_OPCODE["OP_4"] + self.assertEqual(delete_from_script(s, d), e) + + s = "0302ff03" + d = "0302ff03" + e = "" + self.assertEqual(delete_from_script(s, d), e) + + s = "0302ff030302ff03" + d = "0302ff03" + e = "" + self.assertEqual(delete_from_script(s, d), e) + + s = "0302ff030302ff03" + d = "02" + self.assertEqual(delete_from_script(s, d), s) + + s = "0302ff030302ff03" + d = "ff" + self.assertEqual(delete_from_script(s, d), s) + + s = "0302ff030302ff03" + d = "03" + e = "02ff0302ff03" + self.assertEqual(delete_from_script(s, d), e) + + s = "02feed5169" + d = "feed51" + e = s + self.assertEqual(delete_from_script(s, d), e) + + s = "02feed5169" + d = "02feed51" + e = "69" + self.assertEqual(delete_from_script(s, d), e) + # + s = "516902feed5169" + d = "feed51" + e = s + self.assertEqual(delete_from_script(s, d), e) + + s = "516902feed5169" + d = "02feed51" + e = "516969" + self.assertEqual(delete_from_script(s, d), e) + + s = BYTE_OPCODE["OP_0"] + BYTE_OPCODE["OP_0"] + BYTE_OPCODE["OP_1"] + s += BYTE_OPCODE["OP_1"] + d = BYTE_OPCODE["OP_0"] + BYTE_OPCODE["OP_1"] + e = d + self.assertEqual(delete_from_script(s, d), e) + + s = BYTE_OPCODE["OP_0"] + BYTE_OPCODE["OP_0"] + BYTE_OPCODE["OP_1"] + s += BYTE_OPCODE["OP_0"] + BYTE_OPCODE["OP_1"] + BYTE_OPCODE["OP_1"] + d = BYTE_OPCODE["OP_0"] + BYTE_OPCODE["OP_1"] + e = d + self.assertEqual(delete_from_script(s, d), e) + + s = "0003feed" + d = "03feed" + e = "00" + self.assertEqual(delete_from_script(s, d), e) + + s = "0003feed" + d = "00" + e = "03feed" + self.assertEqual(delete_from_script(s, d), e) + + def test_new_tx_constructor(self): + print("new_tx_constructor") + # private key cRiTUeUav1FMR4UbQh2gW9n8RfpNHLBHsEYXJYa4Rv6ZrCdTPGqv + # address mkH3NMrEcijyVutDhvV5fArXJ3A2sxspX9 + + result = "0100000001858a386d766fc546a68f454142d5912634988c9a192c725ade3a0e38f96ed137010000006a47304402201c26" \ + "cbc45d001eeae3c49628dde4520a673c3b29728764356184ade9c31b36a40220691677e7344ba11266e5872db6b5946834" \ + "33b864f2c187a0dc3ea33739d2dd6f012102a8fb85e98c99b79150df12fde488639d8445c57babef83d53c66c1e5c818ee" \ + "b4ffffffff01702a290a000000001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88ac00000000" + a = Address(PrivateKey("7b56e2b7bd189f4491d43a1d209e6268046df1741f61b6397349d7aa54978e76", testnet=True), + address_type="P2PKH") + tx = Transaction(testnet=True) + tx.add_input("37d16ef9380e3ade5a722c199a8c98342691d54241458fa646c56f766d388a85", 1, address=a) + tx.add_output(170470000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key="cRiTUeUav1FMR4UbQh2gW9n8RfpNHLBHsEYXJYa4Rv6ZrCdTPGqv") + print(tx["vIn"][0]["signatures"]) + self.assertEqual(result, tx.serialize()) + + result = "01000000029d05abe190f4a75455aa5ec940a0d524607ecd336e6dcc69c4c22f7ee817964a000000006b4830450221008" \ + "bac636fc13239b016363c362d561837b82a0a0860f3da70dfa1dbebe6ee73a00220077b738b9965dc00b0a7e649e7fda2" \ + "9615b456323cf2f6aae944ebed1c68e71a012102a8fb85e98c99b79150df12fde488639d8445c57babef83d53c66c1e5c" \ + "818eeb4ffffffffee535abe379c7535872f1a76cd84aa7f334bf3ee21696632049d339a17df89f8000000006b48304502" \ + "2100eace9a85848b8ed98b5b26fe42c8ced3d8e4a6cf7779d2275f1c7966b4f0f6700220189adf1333ae7fc6be5fe3fd8" \ + "4cb168e55ea4983c86145030b88ba25ddf916ee012103b5963945667335cda443ba88b6257a15d033a20b60eb2cc393e4" \ + "b4d9dc78cd5dffffffff0180b2e60e000000001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88ac00000000" + tx = Transaction(testnet=True) + tx.add_input("4a9617e87e2fc2c469cc6d6e33cd7e6024d5a040c95eaa5554a7f490e1ab059d", + 0, address="mkH3NMrEcijyVutDhvV5fArXJ3A2sxspX9") + tx.add_input("f889df179a339d0432666921eef34b337faa84cd761a2f8735759c37be5a53ee", + 0, address="mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.add_output(250000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key="cRiTUeUav1FMR4UbQh2gW9n8RfpNHLBHsEYXJYa4Rv6ZrCdTPGqv") + tx.sign_input(1, private_key="cSimowS3sa1eD762ZtRJUmQ7f9EqpqJa8qieXs4hKjkao2nipoTq") + print(tx["vIn"][0]["signatures"]) + print(tx["vIn"][1]["signatures"]) + self.assertEqual(result, tx.serialize()) + + result = "01000000019c5287d981ac92491a4555a0d135748c06fbc36ffe80b2806ce719d39262cc23000000006a47304402201b" \ + "db3fd4964b1e200e4167a5721bf4c141fa97177a0719ace9a508c24c923feb0220063f353306bcdf756f4d2c117fb185" \ + "035c14f841b8462091637451eba2c1d77c032103b5963945667335cda443ba88b6257a15d033a20b60eb2cc393e4b4d9" \ + "dc78cd5dffffffff014062b007000000001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88ac00000000" + tx = Transaction(testnet=True) + tx.add_input("23cc6292d319e76c80b280fe6fc3fb068c7435d1a055451a4992ac81d987529c", + 0, address="mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.add_output(129000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key="cSimowS3sa1eD762ZtRJUmQ7f9EqpqJa8qieXs4hKjkao2nipoTq", + sighash_type=SIGHASH_SINGLE) + self.assertEqual(result, tx.serialize()) + + result = "010000000252dc328cba19ac25711ea56755fe9e866e24feeab97fa9b31b2030c86f40a9b3000000006a4730440220" \ + "142022a671ebc2a51760920b5938f61f5f79a41db69380115a6d4c2765b444540220309fa9b0bd347561473cdce1a1" \ + "adc1b19fcfa07b7709c6ec115d11bb76f0d5fd012103b5963945667335cda443ba88b6257a15d033a20b60eb2cc393" \ + "e4b4d9dc78cd5dffffffffe28966244d618bada9429fc56ce8843b18ce039cecbb86ff03695a92fd34969200000000" \ + "6a473044022043e021bcb037a2c756fb2a3e49ecbcf9a9de74b04ab30252155587c2ef4fd0670220718b96ee51b611" \ + "2825be87e016ff4985188d70c7661af29dd558b4485ec034e9032102a8fb85e98c99b79150df12fde488639d8445c5" \ + "7babef83d53c66c1e5c818eeb4ffffffff0200e1f505000000001976a9145bfbbcfef367417bd85a5d51ae68a0221d" \ + "a3b45f88ac40084e05000000001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88ac00000000" + + tx = Transaction(testnet=True) + tx.add_input("b3a9406fc830201bb3a97fb9eafe246e869efe5567a51e7125ac19ba8c32dc52", + 0, address="mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.add_input("929634fd925a6903ff86bbec9c03ce183b84e86cc59f42a9ad8b614d246689e2", + 0, address="mkH3NMrEcijyVutDhvV5fArXJ3A2sxspX9") + tx.add_output(100000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.add_output(89000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + + tx.sign_input(1, private_key="cRiTUeUav1FMR4UbQh2gW9n8RfpNHLBHsEYXJYa4Rv6ZrCdTPGqv", + sighash_type=SIGHASH_SINGLE) + tx.sign_input(0, private_key="cSimowS3sa1eD762ZtRJUmQ7f9EqpqJa8qieXs4hKjkao2nipoTq", + sighash_type=SIGHASH_ALL) + print(tx["vIn"][0]["signatures"]) + print(tx["vIn"][1]["signatures"]) + self.assertEqual(result, tx.serialize()) + + # sighash single with sig-hash one + result = "010000000278be2e22c8880c01fe9d9d8e4a2f42f0f89d6b6d3f0f2dee79fd4b3be4ff9307000000006b483045022" \ + "100a45cab68bff1ef79b463ebffa3a3c546cd467e6aabb051c87c0116c968a5e2e602202b21d93705f768533b5a3e" \ + "0e17871ae4d8a61dfde213096cdf5e38abbf8ba0e7032103b5963945667335cda443ba88b6257a15d033a20b60eb2" \ + "cc393e4b4d9dc78cd5dffffffff8ae976106659e8bec5ef09fc84f989c7bab6035be984648bd1ea7b29981613cb00" \ + "0000006b483045022100a376f93ed693558f8c99bcb3adbb262aff585f240e897c82478178b6ad60f3ad0220546f2" \ + "376b72f2f07d16f6e0e2f71181bc3e134ff60336c733dda01e555300f2a032103b5963945667335cda443ba88b625" \ + "7a15d033a20b60eb2cc393e4b4d9dc78cd5dffffffff0100e1f505000000001976a9145bfbbcfef367417bd85a5d5" \ + "1ae68a0221da3b45f88ac00000000" + tx = Transaction(testnet=True) + tx.add_input("0793ffe43b4bfd79ee2d0f3f6d6b9df8f0422f4a8e9d9dfe010c88c8222ebe78", + 0, address="mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.add_input("cb131698297bead18b6484e95b03b6bac789f984fc09efc5bee859661076e98a", + 0, address="mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.add_output(100000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(1, private_key="cSimowS3sa1eD762ZtRJUmQ7f9EqpqJa8qieXs4hKjkao2nipoTq", + sighash_type=SIGHASH_SINGLE) + print(tx["vIn"][1]["signatures"]) + print(tx["vIn"][1]["signatures"]) + tx.sign_input(0, private_key="cSimowS3sa1eD762ZtRJUmQ7f9EqpqJa8qieXs4hKjkao2nipoTq", + sighash_type=SIGHASH_SINGLE) + print(tx["vIn"][0]["signatures"]) + self.assertEqual(result, tx.serialize()) + t = "0100000000010ae86eef67d8c6a4fa42c8d1ba56095cfd580675f5e23d4c3eb4e0cd94f749e76e0d00000023220020836874e10" \ + "976a55b3797305458e5062f610ef36d965ae90a2a6e1cf2b82196d6ffffffff490f6350a3dea457086e34431c9376f810d2cc13" \ + "45d80b6ca13774336b4a6d430c000000232200205f074989fce0d834b6d5f0f7458fd784c3fef6edf220d286f609572b351af54" \ + "4ffffffffb9d80c9a4c46950ca456a99ba8f332072ca8fc77283896bc515315ee3659b0b40000000023220020f0ebbea7b0628d" \ + "9deb464f8dff4a13ab600a9d152babd55397b935a15e69c6eaffffffff5e17c16acf59553c4f12e155b0c2ed890bc30305eea51" \ + "7e95b96aa56602e1e2d0100000023220020d41098b592f0444588603f6317fa221071a431488a43412e1947d17fd8cf08e7ffff" \ + "ffffe6bb632279123095c9c20cfa475dedc652ed9a145df8dbb97629713d5ea9360b14000000232200209e2cfbe506e1f4069d8" \ + "a210065977d5084942736620237689a505c00af3b0be5fffffffff6fabc0398da61b54655a5570c636c195cb7b430629c654806" \ + "64c247772a81a5a500000023220020eff46382a9e523f43b486fd9bcdca1b05283ffd821b942eb84eda4a6c9049c77ffffffffe" \ + "b7f7d50ee09fa1de8a9ad94e20a35afd568b724bda5e88bd95b9293c1d092200400000023220020aad3f8ee6f95dd7c3b18df80" \ + "aa0ce15cbd95119805460c5f2087af68b0576cb6ffffffff413956ecb16eb70a611a87af4308487b66ec2b24914fececb31cdd2" \ + "65629490c00000000232200203acbfd4896a9d6f1e80e0baceec00ca9053ebb0b414a431863e86bea40bcb8d7ffffffffbb81e5" \ + "985a904055bdd5056b94716595d64e7c557a19f7e210173134923582720100000023220020af64a9d1f1faf501dd97d934aae2a" \ + "a3463750dc7ffc843433392d61173447b1affffffff4d0b29f52473088a0877a5d324639d11be4292e8ae7869803f57494b7e25" \ + "5083c002000023220020c07933f89277461f4aa8292c82f90f51d5c08efaf85ee0a128862ee1c1f964a0ffffffff12b0ba677d0" \ + "00000001976a9142b94a5696f8414810804910a53e0d42d469cc68888acb0693001000000001976a91449c8bc27c91b6da00814" \ + "2d59b391b71241241fe188ac4059940e0000000017a914fa671ec312a6acd9a890bfc9b8e42e6d379dd26687509731000000000" \ + "017a9140476a4bb4062634cc88efec6faa8f67367c8517687001d10000000000017a914aec4c31d0266ab952f8e333f47572419" \ + "9c1b20c08768051f000000000017a91490348215c703df48a8b5f27b6edf4e7328a8eb8f87281f54000000000017a914ed11adb" \ + "24433a7bbeb86add7b305e00a461c7060877053f0000000000017a9145c82025b4aedd1e5c1ffb9787fbee925b2b23e4e87506b" \ + "6200000000001976a9147293926f5d57e79d2fb23e45150e00f9011716b888ace86df4050000000017a914129506924b8ee99bd" \ + "fafe905f6dc8aefd5582f0387a0db5b00000000001976a9145d608186223ef77bfda8ef29eb7c118a5c49be8788ac7007bb0400" \ + "00000017a914a14e4df199b84dc7bb2e1512c2b53bb9ccc3d6ad873847bc00000000001976a9143b10f41f5bb8123f388838cac" \ + "ac30e25a1335cbb88ac20a58f05000000001976a914aa6f6e369c0ece0fa308afe230b8a090cf3dc22988ac7098940300000000" \ + "17a91428725337b726536e770d9e2ff9c42e28aa3c183e8718f55c09000000001976a914ca7369dc4f594d93b71f98e8272d41a" \ + "e4db24d3988ac90ebba00000000001976a9143981663e21bd94c88b5c1c762fb7bae44af1449b88acd1c051b80000000017a914" \ + "ac6f85e29c73fe144e9cb4df66c3918a00d03c73870400473044022061ddd2863acb41f754067891991ffa8166391156b1a179a" \ + "c2c96f03c6868224102205be713dfdf859bf73f0e298066e2b4cea8a921eae048953e4f9b08216f4f348401463043021f32be97" \ + "e483265a3cea779a3e7b418c366c87ed19c0eea0687f24f83075bc58022048a9c9264077a48b9c5e869dd483b9682cc19743ec9" \ + "0538d6be4990412729ac90169522102bf32cdf437f8af4ec8705ff9bd9d394d95dbc17d4b0801d38167a32b5af59db721027de8" \ + "616c9e0a52189ab52411b098610a996531f40b6369d066f809a0427e9bb8210268d5f41dba5d8fa19a1fde213d902f31f3513ba" \ + "56502810ba8192d33c87b1c5d53ae040047304402206c11e7f30f743d4db157cb626afbf9f22d9e87926b006ca03f1122db5a7d" \ + "a4b8022053df5a6641dee8f1513bc27a702e4c64995ed297a034a8700a5ff4f9716a383e014830450221008cb3903927db38377" \ + "ade7eae0c496084616f59ed7e0ac40df101bf2137d7368802201aa96ca4c6feba0257a780250be3addf789ed59cd772da26a680" \ + "d481386d288b0169522102127eaf8c2ffc2fcab5342b9670cd7f81fe5909a6a68e5ec48f2a4526bb055c492102ba49de2128d2a" \ + "a98525ac45183c1c9b1d4cb5b490ca2c814de2ca9e1606e9f3e21020d9cd35f18382a88e0784900763bf2bdadc54ce972a1bace" \ + "934aa366e1fde6b353ae0400483045022100ee01fec412c5fc8df06b0f7eb13666b8fd209021a14a6514b57006fca31e0dfe022" \ + "00842c2689ec7fa86428a92408bf2a10174d3611cd2b0af104b36dbc453e05a860147304402204a5c38d17e4e3e3cb4c738f983" \ + "ecc7e7ab9f8640bda8b2ae563b44d487d6fd19022025d9f523c0b6879ba06dcac11f466d345670573f016b85d550b4960ab8b7f" \ + "124016952210338e8b783d0d6d1d8b30adbd214eb0549c5f06349dad0ce1e962c25630a025b7e21029ff6bff81992bc7ee875aa" \ + "380c6d7e246c7650c2e0cb27f92e1caaa6eb362be12103e5f2e69b19cc9ffce3f466982075a9a7ff521b10ab3b7be4c55d55851" \ + "341fa7153ae040047304402206fc8313bf245c5f670b1269e6db62304715a9ea8a0eb58cb8fd0beec4a2c966102204512f61e66" \ + "46634498d74fd5ed58b25d9accc961f307888a7d3ed2366d3b46b101483045022100cc5ed821dde97f29afbad747cbef27f30d2" \ + "9d2bdf5cf6ff5bfb08964ec042487022052429189e819e1096c7a8a6a00af3b5c3d11104ff98382164bc86ed02aa2b46d016952" \ + "2102497d2370e03cef2f476c4ed98475d45d35a4ba2c6d0999d7b47af0b897fff19b210283044c82fbda2789d06b1a70afab9a4" \ + "7b8b0a6be4ffc86c778ce55400e169a48210356d36f4a13c143e122ea76b586d7d8d79ec9ef65b092471b7d1d78acefa2fb5d53" \ + "ae0400483045022100ee66c86ece64814ea61bcbbd429047361c9d4f7653e36d3f558afc088808dd4402203d96a1a87b6fe65a9" \ + "443ae2b6601531f24b7cf54058ac84273bdbbc26b60c50a014830450221008e68ad34519549184aaa549a356bb8be7bd82b9594" \ + "eda0094124c0712d262a76022040129a89f28e9656f1496b8d1ef1510ca8819133f2959d7f4eb5433fb2d024ac0169522102d58" \ + "09edd69535048caefafb7e1bbfc31dd3a8119fa027c06ac4fff7c47cc5c992102e843efa57b829404c090ec568630e04956fb70" \ + "4491433092f2e5cbe5c6ea443d2102d6ea08ba5bf4756d8926f186e8ef47ebcbf41a115b068789401aa4de0c64644953ae04004" \ + "7304402202aac4fd3456f838d62dc050066937a8627a2e7c05bc6c82713f315f3ab63c94602201477eb1ac5e54a77c3a54890f2" \ + "9728ed65d205edd376041a6ab0fdd22a37ba1b01473044022028ce2682c1abe60b1256d6fd1b76f18f39a5046d2caf2d2c8f559" \ + "d399810f71202205c3d3ec147bb4a42f945f19548fcaa4668d4c7a9b12a00724243cb2e24b9daa901695221029904a08ded0330" \ + "3a3f88d260d4c22ac71f246da63458cb6e7a5441cc9b194c6a21027dc59859ba222701fd1a582e6e58cc35d3229effc72d3f98b" \ + "9832364ac20ca13210221d250c0b6c7dad36e6af341091be754bebadaed5a5f024e5b4bbd3cf08c46e053ae0400483045022100" \ + "b2bd905daef9777adecbf52a73b64eca6475401bf1a5e9a392b1858315a09897022053f44b586eaba0c58b6629e6ff047e237b3" \ + "38483c13980bc3caf9e3ed69b14e001483045022100dcdc4edf79acacdda43ffbc3f585572013ab331b237bf04798874b4cca4e" \ + "4801022042fb1b77e48acb3c7047ba020443e611d760d2b6cc544bf721d3dabf2e3fa3d201695221036bcd992017b6613195d33" \ + "ad328d9ea158b3f55a21f1fffffe31b31771f75f3f12103244b19fb816b23fa2292eb552f2e9877c0f409386d34fa93c11e9cf7" \ + "c9f70308210292a9db72e379443012a33e832c89dbe34dfa521686466451ce3d320885ce8f4153ae04004830450221009987ece" \ + "026511cf9afdd46d1de4bde25d55c2b4c82a761cedfce656cc6fc55f9022038e99c9607b131110c25363a366ce3724a796b2df2" \ + "01ba71d74b3debef7062c301483045022100ed38faf5ab45cde2621f63bc08670dc4e4c33cb8117a488764fd77ab45a2c485022" \ + "0792b72f562c0d21d5f697f760267410e3e41203455faef3c73519b32abd26e7401695221023c4ea281bbf7d5edbda342ef63a2" \ + "10bd4f29491d4132850233b84b8e8d00d12521021f69d49af87b294f22dc1093f4b83dc640e5731f8e4cea2788e9f610eb86c31" \ + "c21023e1110e93cb0f47e22be40fedbcc0a44411f1167817cde6c55c8dc21c039ed1e53ae0400463043021f689bb6058b3e2b5d" \ + "b0f83c53291e090dbd653ad64c7dc967fd3b88fed201ef022010db0c1741b9dcd8da21fce909e2753125b96e43da5fa6c3e4aba" \ + "b4834648c3a0147304402206dd1c33cfa870f865bf62690cb99ac059171c59753942b47c64989df0fd9f52d022001e057a08bc5" \ + "aa22260508424f1b3fa67fad3e365b67c27aeb8c592946b671930169522102add3216135f7e64cf4f391b3930bf36a18ae63cdb" \ + "7d2df49caaf1454975c757621036f5fcbd63200e086629e21f2e22cadcb4164a4cc3c889ed575a5ca7530c21a622102df9a83c1" \ + "5a3cd69a2f1787cbbfc41da8557268dec6e37d0647838ed4fde79adf53ae04004730440220389b3a4b11682a43524d10623e870" \ + "7303533dd772f063e39cc07660e0b31472c02206732c70619ee40f0af5fb7add47a3aa8b7cc7aa9d6df5344803c8d48e1cfc2bb" \ + "01483045022100df530268f3c9f243a89e22ef6f24bc80ae6642b483598d7ee0a6b4b79f2a8b9a02207fb4ec71b84df08d97fd0" \ + "87b8e15e8107cf7c9e63f1961ec96c9aa33a88c43910169522102a8c6438e2f6ec0c5702b55c5f1ea54f9356dc999a9c035c0f0" \ + "443a54d124c3262103e06283c613593286b3bffae9a3d5b890fe225617481d7e6572fadfc38513345b2103cd7fcf98e0640739a" \ + "298165e72bad79cbb3434d74649ab3a064d8631cf93f96c53ae00000000" + tx = Transaction(t) + self.assertEqual(t, tx.serialize()) + + def test_sign_multisig_inputs(self): + # sign 1 of 2 + a1 = Address("cQMtVcE77xqLAAJGPxoQX4ZxnvBxBitBMMQQr5RMBYh4K8kZDswn", testnet=1) + a2 = Address("cR3oXD6J1tDr2LhT6mKJYJc9qT2iv1dtpFLKkfR7qKnTC3P85w5T", testnet=1) + a = ScriptAddress.multisig(1,2,[a1,a2], testnet=True, witness_version=None) + redeem = "51210399179539f1ebedc809887a48fe802093a74435052ab7fb83d5861fca2f4582e22103d595ee4ba81f9863ff" \ + "dc06ea551467a49e290760d47ed547ea71544a9b8d10ad52ae" + self.assertEqual(a.address, '2MtBHb92gNV93Wd6wAiyrV4bBQbbnZspvUA') + tx = Transaction(testnet=True) + tx.add_input("6bff4e558bdfb9cf12ac1865a2895ea270b64e836520a7404aedab1478d4b85f", + 0, address="2MtBHb92gNV93Wd6wAiyrV4bBQbbnZspvUA", redeem_script=redeem) + tx.add_output(120000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key="cQMtVcE77xqLAAJGPxoQX4ZxnvBxBitBMMQQr5RMBYh4K8kZDswn", + sighash_type=SIGHASH_ALL) + print(tx["vIn"][0]["signatures"]) + r = "01000000015fb8d47814abed4a40a72065834eb670a25e89a26518ac12cfb9df8b554eff6b00000000920048304502210" \ + "08e7edc6f3fec3d2eb029e68f9340ad0549e24cd6e50e99b33a8f64bae42e44bd02207189c4f1088466754766b76ad731" \ + "3d96b34989769268c4b8cf461f4a6022bf44014751210399179539f1ebedc809887a48fe802093a74435052ab7fb83d58" \ + "61fca2f4582e22103d595ee4ba81f9863ffdc06ea551467a49e290760d47ed547ea71544a9b8d10ad52aeffffffff0100" \ + "0e2707000000001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88ac00000000" + self.assertEqual(r, tx.serialize()) + + # sign 2 of 2 + a1 = Address("cQMtVcE77xqLAAJGPxoQX4ZxnvBxBitBMMQQr5RMBYh4K8kZDswn", testnet=1) + a2 = Address("cR3oXD6J1tDr2LhT6mKJYJc9qT2iv1dtpFLKkfR7qKnTC3P85w5T", testnet=1) + a = ScriptAddress.multisig(2,2,[a1,a2], testnet=True, witness_version=None) + redeem = "52210399179539f1ebedc809887a48fe802093a74435052ab7fb83d5861fca2f4582e22103d595ee4ba81f9863ff" \ + "dc06ea551467a49e290760d47ed547ea71544a9b8d10ad52ae" + self.assertEqual(a.address, '2MxgNabrhi6kGzNCapEwnk7GYkNmDZGHr25') + tx = Transaction(testnet=True) + tx.add_input("cf43acc2202074d3bf3f5a8936ef0157e6e292e1e53dd3eb6f5644de237b5d89", + address="2MxgNabrhi6kGzNCapEwnk7GYkNmDZGHr25", + redeem_script=redeem) + tx.add_output(120000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key=[a1.private_key, a2.private_key]) + print(tx["vIn"][0]["signatures"]) + r = "0100000001895d7b23de44566febd33de5e192e2e65701ef36895a3fbfd3742020c2ac43cf00000000db00483045022100" \ + "a52f86f21a4b189cd172b2c6267149f15d9c02c7ac7cf72eb31d3c5fa475465e02203293d8683376c1574125f7fd36b75d" \ + "770c5c2930d148221aee3123f9c9fd158c01483045022100c1e19c1da2776cea4d57fe0221f34ec3a38719260633cdce96" \ + "def65eb79d6554022050738953714493d18e155750ffd9f2697381b618e74a1b82b5bf0e8c58a6b13f0147522103991795" \ + "39f1ebedc809887a48fe802093a74435052ab7fb83d5861fca2f4582e22103d595ee4ba81f9863ffdc06ea551467a49e29" \ + "0760d47ed547ea71544a9b8d10ad52aeffffffff01000e2707000000001976a9145bfbbcfef367417bd85a5d51ae68a022" \ + "1da3b45f88ac00000000" + self.assertEqual(tx.serialize(), r) + + r = "0100000001762a9a00d64c693795013b5ea5246e5407f37f4d5477f7839c857cea92e7f6d600000000da00483045022100" \ + "8da9cfb8b89c0374f9db6f5066115bc2a8cba54de67486bc09aaa5fdda92b559022057456f63dac1a9ede532e7e7659518" \ + "d0447229533470e0647baf1cab99b7986e01473044022042aefa2ff6c682e0a88ef421540a0b38422c45b182a9660d253c" \ + "9167dcaedea702202e4b2c2dba6d603b7d2024f0c4cbdeb8fe2f457c70c423d98f4f091ff48e6417014752210399179539" \ + "f1ebedc809887a48fe802093a74435052ab7fb83d5861fca2f4582e22103d595ee4ba81f9863ffdc06ea551467a49e2907" \ + "60d47ed547ea71544a9b8d10ad52aeffffffff010090d003000000001976a9145bfbbcfef367417bd85a5d51ae68a0221d" \ + "a3b45f88ac00000000" + tx = Transaction(testnet=True) + tx.add_input("d6f6e792ea7c859c83f777544d7ff307546e24a55e3b019537694cd6009a2a76", + address="2MxgNabrhi6kGzNCapEwnk7GYkNmDZGHr25", + redeem_script=redeem) + tx.add_output(64000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key=[a1.private_key, a2.private_key]) + self.assertEqual(tx.serialize(), r) + + tx = Transaction(testnet=True) + tx.add_input("d6f6e792ea7c859c83f777544d7ff307546e24a55e3b019537694cd6009a2a76", + address="2MxgNabrhi6kGzNCapEwnk7GYkNmDZGHr25", + redeem_script=redeem) + tx.add_output(64000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key=[a2.private_key, a1.private_key]) + self.assertEqual(tx.serialize(), r) + + # sign transaction step by step + + r = "0100000001b280dd126d2cafe8aa0e26b7360d5c6c51446b82e934c0b98f9e77318711243c00000000d9004730440220157" \ + "1a0d54361d7d6838c95263f6a4a8ee1f7315c0c2c57a7bf095716535d040602203ae9be582f6112eb45ac1b7388316b740e" \ + "2a6f0de24c640f5d00bda131c471a20147304402205758aa63e4ff3c5fdb4a4d32ddde90f851dfd3ff889e77c9ecb9af3cd" \ + "345360202207443b94ddddfc337a8b4812267a29b489e53c8a76f28158a70ed4d71c60039bb014752210399179539f1ebed" \ + "c809887a48fe802093a74435052ab7fb83d5861fca2f4582e22103d595ee4ba81f9863ffdc06ea551467a49e290760d47ed" \ + "547ea71544a9b8d10ad52aeffffffff01000e2707000000001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88" \ + "ac00000000" + + tx = Transaction(testnet=True) + tx.add_input("3c24118731779e8fb9c034e9826b44516c5c0d36b7260eaae8af2c6d12dd80b2", + address="2MxgNabrhi6kGzNCapEwnk7GYkNmDZGHr25", + redeem_script=redeem) + tx.add_output(120000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + # Alice sign + tx.sign_input(0, private_key=[a2.private_key]) + raw_tx = tx.serialize() + + # Bob turn + tx = Transaction(raw_tx, testnet=True) + tx.sign_input(0, private_key=[a1.private_key], + address="2MxgNabrhi6kGzNCapEwnk7GYkNmDZGHr25", + redeem_script=redeem) + assert tx.serialize() == r + self.assertEqual(tx.serialize(), r) + + tx = Transaction(testnet=True) + tx.add_input("3c24118731779e8fb9c034e9826b44516c5c0d36b7260eaae8af2c6d12dd80b2", + address="2MxgNabrhi6kGzNCapEwnk7GYkNmDZGHr25", + redeem_script=redeem) + tx.add_output(120000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + # Bob sign + tx.sign_input(0, private_key=[a1.private_key]) + # Bob serialaze tx and send to Alice + raw_tx = tx.serialize() + + # Alice turn + tx = Transaction(raw_tx, testnet=True) + tx.sign_input(0, private_key=[a2.private_key], + address="2MxgNabrhi6kGzNCapEwnk7GYkNmDZGHr25", + redeem_script=redeem) + self.assertEqual(tx.serialize(), r) + + # 10 from 15 + result = "01000000011c5dbac1a4028badbe2ec11db09682dbd9869e97cb9f9d4e83e5e169c25b1fcd00000000fd280300483045" \ + "0221008f649de02eb599f1c6b24a4719e85961f0c8b7b1e5fed544ea9afc03ff55f0410220494e49c7d7193ef7845475" \ + "92917005ab7bfa947f7c29bdfe869296d603ca1ba20147304402200ec9f3cb352a94a6df1227ff9c1b4236cf1a718d21" \ + "89591001935142d2a02bf5022069f48bcdbd2b9f9ecf0ce4170231aeb485264c7bfca86dd937c5840be7613a7d014830" \ + "45022100cb28f2d1ee5d1776d9f36dd07e7b76e86225ecc35088b02937cc7cf091cc10e402202617d6cb66a977dc2ee8" \ + "c58d3efd941dce595a7acc9ff9fdf374838a291b745b014830450221008d6e0f1d328e79ee93de4c31ffded81ecdbbe7" \ + "aa5c9a92949de91ef192a3e085022079de8336edf917d44030dc6428a4b6dc6d7991cc0b7844df01e38973eb16d68a01" \ + "4d0102542103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05a" \ + "af8443e3810483d5dbcf671512d9999f9c9772b0ce9da47a2102c711ad61c9fbd3600716b981d101cf0a000ab3524525" \ + "235c42f2cbcd8c17c6da21022388ccac4ff254b83e58f5013f86162fab940e4718d3bfede2622eb1aaa76ec721032d60" \ + "0f6d14d9d0014122ecb5ccba862da9842b68f71905652087138226a2b37921031963d545c640fed2400c6af7332ba9fd" \ + "06cdee09b72ae5fbff61a450340918492103bfebbdc81e1fd9ef1f1f04e53bd484298fb7381211cacb0dc46b33453102" \ + "4a7e210356399488ae0f1e13e8eef8b88b291e51f89041d9bf00acbaa5dfda4894f3c3952102c40b66c4671bc5ee03fc" \ + "22e84922ac7f2f8e063ee45628d28bb68ca38dc583d121023997c4745467ce88b747849191404b4fdb27323bbbc6e7e5" \ + "1cf63d22ba87015e21033add032f5d77c74c19d8dbe89c611917e263844974b13bc518817bc36f60afaf2102cfc901fd" \ + "07b9e187fea1842c68eb0ce319aea7fa4807abea7b7d3239a2dd64702102e94f4d60ee1912af627fdb5cf5650210af97" \ + "3c573a136e873da4816828fffcc02102576df3e588f34f592239a4b86d59e4cc0116b8f1b102cf36edf631a09c0ca963" \ + "2103b4bc5d45ed8219248cf1b62210b6c0ce71d86bb95b35d2e2a3cf456c483bac425faeffffffff01000e2707000000" \ + "001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88ac00000000" + + a1 = Address("cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt", address_type="P2PKH", testnet=True) + a2 = Address("cVgShyj2q4YKFX8VzCffuQcrJVYhp522NFozNi7ih2KgNVbnysKX", address_type="P2PKH", testnet=True) + a3 = Address("cQWBhFENcN8bKEBsUHvpCyCfWVHDLfn1M65Gd6nenQkpEqL4DNUH", address_type="P2PKH", testnet=True) + a4 = Address("cU6Av8QXbHH9diQJ63tSsrtPehQqCcJY6kEHF5UgrsSURChfiXq4", address_type="P2PKH", testnet=True) + a5 = Address("cT35A2N2m1UPSGXuAHm4xZPhfYMUREVqyKe6f1jJvugk2wsMefoi", address_type="P2PKH", testnet=True) + a6 = Address("cSGyUSV57VtJVRsobrG1nAmZpg9xZQ5eUcQnVvEmDH4VLwq4XwxX", address_type="P2PKH", testnet=True) + a7 = Address("cNhEs9VxjbxKuvfunmhnQPNSgTLCzwT339iP75r9UmhLNriL3R2i", address_type="P2PKH", testnet=True) + a8 = Address("cNEaZTTsHcVUYdrE8cRtqLJGdkGk3oghE9ZS6Zeb9y1T92rggKiT", address_type="P2PKH", testnet=True) + a9 = Address("cUwC2prwKErK7VB7VW1wybE4cjvvyPvUDXFGtNQeinM2sKmGxpGX", address_type="P2PKH", testnet=True) + a10 = Address("cVb6Jm2WJGWh9GDbRxtQ7KSsavqvGujhLYn29e6YQH12TaB49eXN", address_type="P2PKH", testnet=True) + a11 = Address("cV8tWtYmaxqoqZnYFthA5xizAK7AM4Tm2dnnFBRHLhTw4TA2QfJb", address_type="P2PKH", testnet=True) + a12 = Address("cP3zQV2ozq2pEUtFRapnPyhwTisbCug8QjwcuWMTdPLDAM5J4nMH", address_type="P2PKH", testnet=True) + a13 = Address("cPyKxfC98PhMjsSS43B43YqHmcUv18XeMyfeUNdy3iPokzW9T911", address_type="P2PKH", testnet=True) + a14 = Address("cUpMmtD81KTB9hHZ4YzGkMtghMh3pQxfKXTrApAyD6nVZWPHwE46", address_type="P2PKH", testnet=True) + a15 = Address("cRh1T62pjkUGh6NKEEsKJ87Korbp1rw2GNxdzwmcPk5dUzn36aRy", address_type="P2PKH", testnet=True) + a = ScriptAddress.multisig(4, 15, [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15], + testnet=True, witness_version=None) + self.assertEqual("2Mz8kUcHia2SYBe4dNYF7uKZcDWy7DHU3pZ", a.address) + redeem = "542103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05aaf844" \ + "3e3810483d5dbcf671512d9999f9c9772b0ce9da47a2102c711ad61c9fbd3600716b981d101cf0a000ab3524525235c" \ + "42f2cbcd8c17c6da21022388ccac4ff254b83e58f5013f86162fab940e4718d3bfede2622eb1aaa76ec721032d600f6" \ + "d14d9d0014122ecb5ccba862da9842b68f71905652087138226a2b37921031963d545c640fed2400c6af7332ba9fd06" \ + "cdee09b72ae5fbff61a450340918492103bfebbdc81e1fd9ef1f1f04e53bd484298fb7381211cacb0dc46b334531024" \ + "a7e210356399488ae0f1e13e8eef8b88b291e51f89041d9bf00acbaa5dfda4894f3c3952102c40b66c4671bc5ee03fc" \ + "22e84922ac7f2f8e063ee45628d28bb68ca38dc583d121023997c4745467ce88b747849191404b4fdb27323bbbc6e7e" \ + "51cf63d22ba87015e21033add032f5d77c74c19d8dbe89c611917e263844974b13bc518817bc36f60afaf2102cfc901" \ + "fd07b9e187fea1842c68eb0ce319aea7fa4807abea7b7d3239a2dd64702102e94f4d60ee1912af627fdb5cf5650210a" \ + "f973c573a136e873da4816828fffcc02102576df3e588f34f592239a4b86d59e4cc0116b8f1b102cf36edf631a09c0c" \ + "a9632103b4bc5d45ed8219248cf1b62210b6c0ce71d86bb95b35d2e2a3cf456c483bac425fae" + + tx = Transaction(testnet=1) + tx.add_input("cd1f5bc269e1e5834e9d9fcb979e86d9db8296b01dc12ebead8b02a4c1ba5d1c", 0) + tx.add_output(120000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key=[a1.private_key, a9.private_key], + redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=[a3.private_key], redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=[a15.private_key], redeem_script=redeem, witness_version=None) + self.assertEqual(tx.serialize(), result) + + # 15 from 15 + result = "0100000001967232c948bafa80eafc9459b2b7c2738cc87d14d7a1a3c980696389897da69700000000fd430600473044" \ + "0220696ad6a6ba02a3b0db932249c4e37d0462da11b3978b305c7af47e8f3af79dc5022049c14881f912502243028498" \ + "1ef1ba5b4e27cd4bc93767acb89e6329be7d0ddf0147304402200aae39bfa42043cfde4994610d5e193ff356a127ccba" \ + "317c3f25ef00c47ee5e602200f58ead8e69cfb5642924a891452eb8e166d868aa93fedc62d005b6f04bd1e9a01473044" \ + "02200a2953e9eec39d147f013d63320bf9ae272536794fba8719dd0dcb7b1efaa49102203ee41f5264737352727bccd7" \ + "6a32fecf3f56f66962dfa690d742361a327331db01483045022100ac93a6dcf823ea67489b58483618a5c878a8e18f08" \ + "9bd4ed9c0cf416207e855a022018f4dfafa887581bd466a0bb4cf6fa0ae984c7f3451c2bfc12673a9e5151df1a014830" \ + "45022100f3f42ac1e0384d317447cc34c5583f1ac56b3e18b057b2e971e9736ad389dc7e022042fc92864136bd37f26c" \ + "7e9e1f96b7ac79d4ac98ab9250a03e97cb0843b1b03701483045022100f6f420c77fae5e6eb7830727886e861596d755" \ + "97db5ea7351c0926b512f4402502204eb1c1958d627dbe7733f4ff6a1f3a5d531841db5ec9c955f414ec665b4c894101" \ + "47304402205004b556afb3ec48081938ef62b9b1c97bf71320c235a5d39d1aab3adb79545502203da05cbddab322c555" \ + "d8664dbf552adbac2fb59a0dc58f26cd080d64d2864a4a0147304402203da589e72cd1e7b1855ef9a545928c68b4ac1d" \ + "8bc05a5d25c60a29e1ed790ae702201400f3adcb3ac6dd45ba2002c1966cb14268d80afadb231b20eafdfeecf0bcbf01" \ + "483045022100fedb21c44371aa838c293596716399de122d03100ef2e828cfee5c1b8d841ab0022008cdf3d89abc5fef" \ + "2eaf88f96bedeac27df352f4e03db2fbcb247d642a9bd60e0147304402202b0872bfd3b28a7b0fc87e6d929b46efde32" \ + "d97d0029f66f93d2a5bbe287bcd60220131e082881fa1dc7c83c715ea936f03fefe2d5b87b630f5b818049aecdb9a1bb" \ + "01483045022100c1d9c33a0df2caa7ace6293e35dc91d9c863ae0dc7ccc315ca0a1fc33151981802203ca9c47e70c92b" \ + "1ef9fdcc28321ec96ccf18feec60bd2054ad4510d5872a6af7014730440220168e5b03e8f55bb46fb3329420c5c8aa55" \ + "1c1b77f1c23c585a3ea4127c2e508d022062c7745f038c83cad56f0c97afac0a7aabb56403e22b35fe45cad31227d149" \ + "e50148304502210088bac04a079105467d1fe38da55b1b116f586af87d09dc227024b4da0089d2b902204fd087024da0" \ + "a731a9f0f03ada61634670511de9b093d312d30c5627a4dcde44014730440220354ea1d887596083196bdcde56a0de99" \ + "d9d927802c6723544b219134809a1e2502202104071d382689bf0b75549f90ba65d28b1f733c38e783d977a17a107d81" \ + "365e0147304402202916e12169c5487dc650d5ed774568623e366ab278ccffd860ce9b18a6a6d7a1022047ceee8dd9ff" \ + "dd1f16ceae2574113adbbcdbb228699079762b44ad427fd68864014d01025f2103b4603330291721c0a8e9cae65124a7" \ + "099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05aaf8443e3810483d5dbcf671512d9999f9c9772b0ce" \ + "9da47a2102c711ad61c9fbd3600716b981d101cf0a000ab3524525235c42f2cbcd8c17c6da21022388ccac4ff254b83e" \ + "58f5013f86162fab940e4718d3bfede2622eb1aaa76ec721032d600f6d14d9d0014122ecb5ccba862da9842b68f71905" \ + "652087138226a2b37921031963d545c640fed2400c6af7332ba9fd06cdee09b72ae5fbff61a450340918492103bfebbd" \ + "c81e1fd9ef1f1f04e53bd484298fb7381211cacb0dc46b334531024a7e210356399488ae0f1e13e8eef8b88b291e51f8" \ + "9041d9bf00acbaa5dfda4894f3c3952102c40b66c4671bc5ee03fc22e84922ac7f2f8e063ee45628d28bb68ca38dc583" \ + "d121023997c4745467ce88b747849191404b4fdb27323bbbc6e7e51cf63d22ba87015e21033add032f5d77c74c19d8db" \ + "e89c611917e263844974b13bc518817bc36f60afaf2102cfc901fd07b9e187fea1842c68eb0ce319aea7fa4807abea7b" \ + "7d3239a2dd64702102e94f4d60ee1912af627fdb5cf5650210af973c573a136e873da4816828fffcc02102576df3e588" \ + "f34f592239a4b86d59e4cc0116b8f1b102cf36edf631a09c0ca9632103b4bc5d45ed8219248cf1b62210b6c0ce71d86b" \ + "b95b35d2e2a3cf456c483bac425faeffffffff01000e2707000000001976a9145bfbbcfef367417bd85a5d51ae68a022" \ + "1da3b45f88ac00000000" + + a1 = Address("cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt", address_type="P2PKH", testnet=True) + a2 = Address("cVgShyj2q4YKFX8VzCffuQcrJVYhp522NFozNi7ih2KgNVbnysKX", address_type="P2PKH", testnet=True) + a3 = Address("cQWBhFENcN8bKEBsUHvpCyCfWVHDLfn1M65Gd6nenQkpEqL4DNUH", address_type="P2PKH", testnet=True) + a4 = Address("cU6Av8QXbHH9diQJ63tSsrtPehQqCcJY6kEHF5UgrsSURChfiXq4", address_type="P2PKH", testnet=True) + a5 = Address("cT35A2N2m1UPSGXuAHm4xZPhfYMUREVqyKe6f1jJvugk2wsMefoi", address_type="P2PKH", testnet=True) + a6 = Address("cSGyUSV57VtJVRsobrG1nAmZpg9xZQ5eUcQnVvEmDH4VLwq4XwxX", address_type="P2PKH", testnet=True) + a7 = Address("cNhEs9VxjbxKuvfunmhnQPNSgTLCzwT339iP75r9UmhLNriL3R2i", address_type="P2PKH", testnet=True) + a8 = Address("cNEaZTTsHcVUYdrE8cRtqLJGdkGk3oghE9ZS6Zeb9y1T92rggKiT", address_type="P2PKH", testnet=True) + a9 = Address("cUwC2prwKErK7VB7VW1wybE4cjvvyPvUDXFGtNQeinM2sKmGxpGX", address_type="P2PKH", testnet=True) + a10 = Address("cVb6Jm2WJGWh9GDbRxtQ7KSsavqvGujhLYn29e6YQH12TaB49eXN", address_type="P2PKH", testnet=True) + a11 = Address("cV8tWtYmaxqoqZnYFthA5xizAK7AM4Tm2dnnFBRHLhTw4TA2QfJb", address_type="P2PKH", testnet=True) + a12 = Address("cP3zQV2ozq2pEUtFRapnPyhwTisbCug8QjwcuWMTdPLDAM5J4nMH", address_type="P2PKH", testnet=True) + a13 = Address("cPyKxfC98PhMjsSS43B43YqHmcUv18XeMyfeUNdy3iPokzW9T911", address_type="P2PKH", testnet=True) + a14 = Address("cUpMmtD81KTB9hHZ4YzGkMtghMh3pQxfKXTrApAyD6nVZWPHwE46", address_type="P2PKH", testnet=True) + a15 = Address("cRh1T62pjkUGh6NKEEsKJ87Korbp1rw2GNxdzwmcPk5dUzn36aRy", address_type="P2PKH", testnet=True) + a = ScriptAddress.multisig(15, 15, [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15], + testnet=True, witness_version=None) + print("15 from 15") + "2N5Z12YFKCzmk8jJKxRQG48ZeAo9fdMFXt6" + redeem = "5f2103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05aaf8443" \ + "e3810483d5dbcf671512d9999f9c9772b0ce9da47a2102c711ad61c9fbd3600716b981d101cf0a000ab3524525235c42" \ + "f2cbcd8c17c6da21022388ccac4ff254b83e58f5013f86162fab940e4718d3bfede2622eb1aaa76ec721032d600f6d14" \ + "d9d0014122ecb5ccba862da9842b68f71905652087138226a2b37921031963d545c640fed2400c6af7332ba9fd06cdee" \ + "09b72ae5fbff61a450340918492103bfebbdc81e1fd9ef1f1f04e53bd484298fb7381211cacb0dc46b334531024a7e21" \ + "0356399488ae0f1e13e8eef8b88b291e51f89041d9bf00acbaa5dfda4894f3c3952102c40b66c4671bc5ee03fc22e849" \ + "22ac7f2f8e063ee45628d28bb68ca38dc583d121023997c4745467ce88b747849191404b4fdb27323bbbc6e7e51cf63d" \ + "22ba87015e21033add032f5d77c74c19d8dbe89c611917e263844974b13bc518817bc36f60afaf2102cfc901fd07b9e1" \ + "87fea1842c68eb0ce319aea7fa4807abea7b7d3239a2dd64702102e94f4d60ee1912af627fdb5cf5650210af973c573a" \ + "136e873da4816828fffcc02102576df3e588f34f592239a4b86d59e4cc0116b8f1b102cf36edf631a09c0ca9632103b4" \ + "bc5d45ed8219248cf1b62210b6c0ce71d86bb95b35d2e2a3cf456c483bac425fae" + tx = Transaction(testnet=1) + tx.add_input("97a67d8989636980c9a3a1d7147dc88c73c2b7b25994fcea80faba48c9327296") + tx.add_output(120000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key=a1.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a2.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a3.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a4.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a5.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a6.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a7.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a8.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a9.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a10.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a11.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a12.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a13.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a14.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a15.private_key, redeem_script=redeem, witness_version=None) + print(tx["vIn"][0]["signatures"]) + raw_tx = tx.serialize() + self.assertEqual(tx.serialize(), result) + + # same tx random sign order + + tx = Transaction(testnet=1) + tx.add_input("97a67d8989636980c9a3a1d7147dc88c73c2b7b25994fcea80faba48c9327296") + tx.add_output(120000000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key=a1.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a11.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a4.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a3.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a9.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a6.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a7.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a8.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a5.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a12.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a2.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a10.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a15.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a14.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + + tx = Transaction(raw_tx, testnet=1) + tx.sign_input(0, private_key=a13.private_key, redeem_script=redeem, witness_version=None) + raw_tx = tx.serialize() + self.assertEqual(tx.serialize(), result) + + def test_sign_p2wpkh_inputs(self): + tx = Transaction(testnet=1, lock_time=17) + tx.add_input("9f96ade4b41d5433f4eda31e1738ec2b36f6e7d1420d94a6af99801a88f7f7ff", + 0, + sequence=4294967278) + tx.add_input("8ac60eb9575db5b2d987e29f301b5b819ea83a5c6579d282d189cc04b8e151ef", + 1) + tx.add_output(112340000, + script_pub_key="76a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac") + tx.add_output(223450000, + script_pub_key="76a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac") + unsigned_tx = "0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f0000000000eef" \ + "fffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff" \ + "02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001" \ + "976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000" + self.assertEqual(unsigned_tx, tx.serialize()) + # print(tx.serialize()) + + tx.sign_input(0, "bbc27228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866", + script_pub_key="2103c9f4836b9a4f77fc0d81f7bcb01b7f1b35916864b9476c241ce9fc198bd25432ac") + tx.sign_input(1, "619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9", + script_pub_key="00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1", + amount=600000000) + r = "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b" \ + "9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc" \ + "22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a" \ + "0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000" \ + "001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f" \ + "32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121" \ + "025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000" + self.assertEqual(r, tx.serialize()) + + # sign pubkey input + t = "0100000001729e7f0a0d7c680c274b76310d46ccbf2f2a05bd76d07f0556450e20b68465d700000000494830450221008655a5" \ + "a16f6563ebef7e9d085a62cdac99329b47ec9d5537de3f455b2a2da3ce02207ab34a1e223245d727a0e639ec8b0ec75ac04827" \ + "4f102598fd0a50e7854eff1301ffffffff01c005d901000000001976a91475a31c60acaf594e48a0955c2ec6396c2f7873cb88" \ + "ac00000000" + tx = Transaction(testnet=1) + tx.add_input("d76584b6200e4556057fd076bd052a2fbfcc460d31764b270c687c0d0a7f9e72") + tx.add_output(31000000, "mrExkdzwj7y5CW2BYSgFDPfJ8oWm2v49L2") + tx.sign_input(0, private_key="bb127228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866", + script_pub_key="2103bc85b4247004744d3e96f861802ec49ea4c64902ded840509879130356b4a0feac") + self.assertEqual(t, tx.serialize()) + + # sign p2wpkh + r = "01000000000101d7592de6f96f49ad6b66a718c5ea8d7e4c5a7198b7a9b904687b6e23b553b1b20000000000ffffffff01c027" \ + "0900000000001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88ac02483045022100888e7a282b18461cfca7af6d" \ + "6c33a75c0d19ad890697c56e4873763f4a07a7bd022041bfedfca7604f695109ea520337dce8eb9f6531c3f860e950a72c94ef" \ + "42672a01210377e4cd2648a68ec815e8df2fa4470101d1e8605245bb14e107a77335ddc0877800000000" + a = Address("cRZQF3fuaKZy2ivDJF9rCmL1h7VYhdhucQE6Vv6ZVbZYpjnDENur") + tx = Transaction(testnet=1) + tx.add_input("b2b153b5236e7b6804b9a9b798715a4c7e8deac518a7666bad496ff9e62d59d7", + address="tb1qksk0dunzsmpygj9jf37j77emkamn86g3g9vz00") + tx.add_output(600000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key="cRZQF3fuaKZy2ivDJF9rCmL1h7VYhdhucQE6Vv6ZVbZYpjnDENur", + sighash_type=SIGHASH_ALL, amount=700000) + self.assertEqual(r, tx.serialize()) + + r = "0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803" \ + "0000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c77" \ + "20a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830" \ + "ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000" + tx = Transaction() + tx.add_input("0000000000000000000000000000000000000000000000000000000000000100") + tx.add_output(1000, "17z5XUKfr1ZEfhHLqJ8VbcQdF5fNSnbcSW") + tx.sign_input(0, private_key="L5AQtV2HDm4xGsseLokK2VAT2EtYKcTm3c7HwqnJBFt9LdaQULsM", + script_pub_key="00144c9c3dfac4207d5d8cb89df5722cb3d712385e3f", amount=1000) + self.assertEqual(r, tx.serialize()) + + r = "01000000000101000100000000000000000000000000000000000000000000000000000000000000000000171600144c9c3dfac" \ + "4207d5d8cb89df5722cb3d712385e3fffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e" \ + "3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94c" \ + "d70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8" \ + "899efac102e5fc7100000000" + tx = Transaction() + tx.add_input("0000000000000000000000000000000000000000000000000000000000000100") + tx.add_output(1000, "17z5XUKfr1ZEfhHLqJ8VbcQdF5fNSnbcSW") + tx.sign_input(0, private_key="L5AQtV2HDm4xGsseLokK2VAT2EtYKcTm3c7HwqnJBFt9LdaQULsM", + redeem_script="00144c9c3dfac4207d5d8cb89df5722cb3d712385e3f", + amount=1000, witness_version=None) + + # sign P2SH-P2WPKH + ur = "0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a54770100000000feffffff02b8b4eb0" \ + "b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea" \ + "97fea7ad0402e8bd8ad6d77c88ac92040000" + tx = Transaction(ur) + tx.sign_input(0, private_key="eb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf", + redeem_script="001479091972186c449eb1ded22b78e40d009bdf0089", + amount=1000000000, witness_version=None) + r = "01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a54770100000017160014790919721" \ + "86c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d9" \ + "6388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebb" \ + "de1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870" \ + "540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000" + self.assertEqual(r, tx.serialize()) + + + # sign P2WSH-MULTISIG 1 from 3 + # + r = "010000000001018aea147516fb825c06e26c4a0fe7cbfe6a280c3e5c215e616def5741970f45160000000000ffffffff01c0270" \ + "900000000001976a9145bfbbcfef367417bd85a5d51ae68a0221da3b45f88ac0300483045022100df55ebb3874fee1a5993162f" \ + "22ab8484faf278b32340f1ccc43cd4ef60926d64022029522a37d65968b6b80090abf6beaa2d5b6a416b8a5cdc9ceb13e6b6997" \ + "9ed9a0169512103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05aaf84" \ + "43e3810483d5dbcf671512d9999f9c9772b0ce9da47a2102c711ad61c9fbd3600716b981d101cf0a000ab3524525235c42f2cbc" \ + "d8c17c6da53ae00000000" + a1 = Address("cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt", address_type="P2PKH", testnet=True) + a2 = Address("cVgShyj2q4YKFX8VzCffuQcrJVYhp522NFozNi7ih2KgNVbnysKX", address_type="P2PKH", testnet=True) + a3 = Address("cQWBhFENcN8bKEBsUHvpCyCfWVHDLfn1M65Gd6nenQkpEqL4DNUH", address_type="P2PKH", testnet=True) + am = ScriptAddress.multisig(1, 3, [a1, a2, a3], testnet=True) + self.assertEqual(am.address, "tb1qcmdwjnv7yv6csp3ft8xw06jzvkzgl8xvjv5wdn85nefqpq3m29rst82pm2") + redeem = "512103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05aaf8443e3" \ + "810483d5dbcf671512d9999f9c9772b0ce9da47a2102c711ad61c9fbd3600716b981d101cf0a000ab3524525235c42f2cb" \ + "cd8c17c6da53ae" + tx = Transaction(testnet=1) + tx.add_input("16450f974157ef6d615e215c3e0c286afecbe70f4a6ce2065c82fb167514ea8a") + tx.add_output(600000, "mouKMbHPwWLUCmgqKnkHT7PR3KdF4CNREh") + tx.sign_input(0, private_key=["cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt"], + redeem_script=redeem, amount=700000) + self.assertEqual(r, tx.serialize()) + + # sign P2SH-P2WSH-MULTISIG + t = "010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000ffffffff0200e9a4350" \ + "00000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e" \ + "6e84c138dbbd3c3ee41588ac00000000" + redeem = "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658" \ + "ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195" \ + "f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba0" \ + "4d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9" \ + "f0c19617681024306b56ae" + tx = Transaction(t) + tx.sign_input(0, private_key="730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1) + tx.sign_input(0, private_key="11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, sighash_type=SIGHASH_NONE) + tx.sign_input(0, private_key="77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, sighash_type=SIGHASH_SINGLE) + tx.sign_input(0, private_key="14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_ALL | SIGHASH_ANYONECANPAY) + tx.sign_input(0, private_key="fe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_NONE | SIGHASH_ANYONECANPAY) + tx.sign_input(0, private_key="428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_SINGLE | SIGHASH_ANYONECANPAY) + r = "0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f" \ + "7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae8" \ + "8dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac08004" \ + "7304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d09" \ + "6f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11" \ + "ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d9801" \ + "0a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e2" \ + "0fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156" \ + "c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13" \ + "613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08" \ + "824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576b" \ + "f6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99" \ + "a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761" \ + "b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de746831239" \ + "87e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b" \ + "09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000" + self.assertEqual(r, tx.serialize()) + + # sign same P2SH-P2WSH-MULTISIG random sign order + tx = Transaction(t) + tx.sign_input(0, private_key="428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_SINGLE | SIGHASH_ANYONECANPAY) + tx.sign_input(0, private_key="730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1) + tx.sign_input(0, private_key="fe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_NONE | SIGHASH_ANYONECANPAY) + tx.sign_input(0, private_key="14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_ALL | SIGHASH_ANYONECANPAY) + tx.sign_input(0, private_key="11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, sighash_type=SIGHASH_NONE) + tx.sign_input(0, private_key="77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, sighash_type=SIGHASH_SINGLE) + self.assertEqual(r, tx.serialize()) + + # sign same P2SH-P2WSH-MULTISIG random sign order with raw Transaction representatiob + tx = Transaction(t, format="raw") + tx.sign_input(0, private_key="428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_SINGLE | SIGHASH_ANYONECANPAY) + tx.sign_input(0, private_key="730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1) + tx.sign_input(0, private_key="fe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_NONE | SIGHASH_ANYONECANPAY) + tx.sign_input(0, private_key="14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, + sighash_type=SIGHASH_ALL | SIGHASH_ANYONECANPAY) + tx.sign_input(0, private_key="11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, sighash_type=SIGHASH_NONE) + tx.sign_input(0, private_key="77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661", + redeem_script=redeem, amount=987654321, p2sh_p2wsh=1, sighash_type=SIGHASH_SINGLE) + self.assertEqual(r, tx.serialize()) + + a1 = Address("cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt", address_type="P2PKH", testnet=True) + a2 = Address("cVgShyj2q4YKFX8VzCffuQcrJVYhp522NFozNi7ih2KgNVbnysKX", address_type="P2PKH", testnet=True) + a3 = Address("cQWBhFENcN8bKEBsUHvpCyCfWVHDLfn1M65Gd6nenQkpEqL4DNUH", address_type="P2PKH", testnet=True) + script = b"".join([OP_2, + op_push_data(a1.public_key.key), + op_push_data(a2.public_key.key), + op_push_data(a3.public_key.key), + OP_3, + OP_CHECKMULTISIG]) + assert a1.address == "mwJMtn5hW54pJC748EExvhRm6FRVmUZXQt" + tx = Transaction(testnet=True) + tx.add_input("d791f8386516bc464e7702159775734559d884a3fd50e45191c6207cdedac8ae", 0) + tx.add_output(64000000, script_pub_key=script) + tx.sign_input(0, private_key="cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt", + address="mwJMtn5hW54pJC748EExvhRm6FRVmUZXQt") + assert tx.serialize() == "0100000001aec8dade7c20c69151e450fda384d859457375971502774e46bc166538f891d7000000" \ + "006a47304402200edb1ded443ea8015390c38afeb0564b52f6f9895c45952461f6ccfaf6639b8402" \ + "206c0d3bfd2f7d8c68d5cc3c774a9403d843cd27e33148927e3f575607b91d05c2012103b4603330" \ + "291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cbffffffff010090d003000000" \ + "0069522103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2" \ + "ec7de7e811c05aaf8443e3810483d5dbcf671512d9999f9c9772b0ce9da47a2102c711ad61c9fbd3" \ + "600716b981d101cf0a000ab3524525235c42f2cbcd8c17c6da53ae00000000" + + "cfe002d20590e2400a26b2dd9e2e6af2369cbb1f5442af286485841798590068" + tx = Transaction(testnet=True) + tx.add_input("cfe002d20590e2400a26b2dd9e2e6af2369cbb1f5442af286485841798590068", 0) + tx.add_output(63000000, address="mwJMtn5hW54pJC748EExvhRm6FRVmUZXQt") + tx.sign_input(0, private_key=["cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt", + "cVgShyj2q4YKFX8VzCffuQcrJVYhp522NFozNi7ih2KgNVbnysKX"], + script_pub_key=script) + self.assertEqual(tx.serialize(), "0100000001680059981784856428af42541fbb9c36f26a2e9eddb2260a40e29005d202e" + "0cf000000009300483045022100a7383d84ee35fb965978144d9243ca0892a1be81ce70" + "058e70b2ba1ea5a762a7022058647d131fcec2e3a63e57fa475b779b94c81a95b5c164f" + "dfdbcee0124e3448c01483045022100b3945861a5a8a406bd575857e19accdb0f6385eb" + "f1c02938b35462cddeef400802205857f56d83e9ed7e98082d9127b8934262d3a046142" + "9747e865b06345bbf8f9e01ffffffff01c04dc103000000001976a914ad204de226b3d1" + "1a70dc53b4998f4603e138ff3f88ac00000000") + + tx = Transaction(testnet=True) + tx.add_input("cfe002d20590e2400a26b2dd9e2e6af2369cbb1f5442af286485841798590068", 0) + tx.add_output(63000000, address="mwJMtn5hW54pJC748EExvhRm6FRVmUZXQt") + tx.sign_input(0, private_key="cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt", + script_pub_key=script) + tx.sign_input(0, private_key="cVgShyj2q4YKFX8VzCffuQcrJVYhp522NFozNi7ih2KgNVbnysKX", + script_pub_key=script) + self.assertEqual(tx.serialize(), "0100000001680059981784856428af42541fbb9c36f26a2e9eddb2260a40e29005d202e" + "0cf000000009300483045022100a7383d84ee35fb965978144d9243ca0892a1be81ce70" + "058e70b2ba1ea5a762a7022058647d131fcec2e3a63e57fa475b779b94c81a95b5c164f" + "dfdbcee0124e3448c01483045022100b3945861a5a8a406bd575857e19accdb0f6385eb" + "f1c02938b35462cddeef400802205857f56d83e9ed7e98082d9127b8934262d3a046142" + "9747e865b06345bbf8f9e01ffffffff01c04dc103000000001976a914ad204de226b3d1" + "1a70dc53b4998f4603e138ff3f88ac00000000") + tx = Transaction(testnet=True) + tx.add_input("cfe002d20590e2400a26b2dd9e2e6af2369cbb1f5442af286485841798590068", 0) + tx.add_output(63000000, address="mwJMtn5hW54pJC748EExvhRm6FRVmUZXQt") + + tx.sign_input(0, private_key="cVgShyj2q4YKFX8VzCffuQcrJVYhp522NFozNi7ih2KgNVbnysKX", + script_pub_key=script) + tx.sign_input(0, private_key="cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt", + script_pub_key=script) + self.assertEqual(tx.serialize(), "0100000001680059981784856428af42541fbb9c36f26a2e9eddb2260a40e29005d202e" + "0cf000000009300483045022100a7383d84ee35fb965978144d9243ca0892a1be81ce70" + "058e70b2ba1ea5a762a7022058647d131fcec2e3a63e57fa475b779b94c81a95b5c164f" + "dfdbcee0124e3448c01483045022100b3945861a5a8a406bd575857e19accdb0f6385eb" + "f1c02938b35462cddeef400802205857f56d83e9ed7e98082d9127b8934262d3a046142" + "9747e865b06345bbf8f9e01ffffffff01c04dc103000000001976a914ad204de226b3d1" + "1a70dc53b4998f4603e138ff3f88ac00000000") + diff --git a/pybtc/test/transaction_deserialize.py b/pybtc/test/transaction_deserialize.py new file mode 100644 index 0000000..dc38887 --- /dev/null +++ b/pybtc/test/transaction_deserialize.py @@ -0,0 +1,293 @@ +import unittest +import os +import sys +import time +parentPath = os.path.abspath("..") +if parentPath not in sys.path: + sys.path.insert(0, parentPath) + +from pybtc.functions import * +from pybtc.transaction import * +from binascii import unhexlify +from pybtc import address_to_hash as address2hash160 + + +def decode_block_tx(block): + stream = get_stream(block) + stream.seek(80) + return {i: Transaction(stream, format="raw") for i in range(var_int_to_int(read_var_int(stream)))} + + +class TransactionDeserializeTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("\nTesting Transaction class deserialization:\n") + + def test_serialaize_and_perfomance(self): + f = open(ROOT_DIR + '/test/raw_block.txt') + fc = f.readline() + qt = time.time() + bt = decode_block_tx(fc[:-1]) + self.assertEqual(time.time() - qt < 1, 1) + print("decode block tx count: %s time: %s" % (len(bt), time.time() - qt)) + for t in bt: + raw_tx_legacy = bt[t].serialize(segwit=False) + raw_tx_segwit = bt[t].serialize() + bt[t] = bt[t].decode() + # print(bt[t]["txId"], bt[t]["hash"], "segwit:", + # True if "segwit" in bt[t] else False, end = " ") + self.assertEqual(bt[t].serialize(segwit=False), raw_tx_legacy) + self.assertEqual(bt[t].serialize(), raw_tx_segwit) + self.assertEqual(rh2s(double_sha256(bt[t].serialize())), bt[t]["hash"]) + self.assertEqual(rh2s(double_sha256(bt[t].serialize(segwit=False))), bt[t]["txId"]) + # print("OK") + + def test_segwit_deserialize(self): + non_segwit_view = "020000000140d43a99926d43eb0e619bf0b3d83b4a31f60c176beecfb9d35bf45e54d0f7420" \ + "100000017160014a4b4ca48de0b3fffc15404a1acdc8dbaae226955ffffffff0100e1f50500" \ + "00000017a9144a1154d50b03292b3024370901711946cb7cccc38700000000" + segwit_view = "0200000000010140d43a99926d43eb0e619bf0b3d83b4a31f60c176beecfb9d35bf45e54d0f7420" \ + "100000017160014a4b4ca48de0b3fffc15404a1acdc8dbaae226955ffffffff0100e1f505000000" \ + "0017a9144a1154d50b03292b3024370901711946cb7cccc387024830450221008604ef8f6d8afa8" \ + "92dee0f31259b6ce02dd70c545cfcfed8148179971876c54a022076d771d6e91bed212783c9b06e" \ + "0de600fab2d518fad6f15a2b191d7fbd262a3e0121039d25ab79f41f75ceaf882411fd41fa670a4" \ + "c672c23ffaf0e361a969cde0692e800000000" + print("Deserialize Segwit transaction") + ns = Transaction(non_segwit_view) + s = Transaction(segwit_view) + self.assertEqual(s.serialize(segwit=False, hex = True), non_segwit_view) + self.assertEqual(s.serialize(segwit=True, hex = True), segwit_view) + self.assertEqual(ns.serialize(segwit=False, hex = True), non_segwit_view) + + non_segwit_view = "01000000060c02c24bbfefd94cdc4f58a3f83f93e05b14ad968ec6aba54190c3dcba6eef1b00" \ + "000000da00483045022100f4dbf2ca7b5da97bd78818635d48004e6bf1a6f7e5e24bcecb7d93" \ + "f554e49eaf02200a05025d93475b6372d14bd8fe8366fe10570ade772b19d124d3b0175b9f6e" \ + "da0147304402202290feb53fc4cb077c5d3eed0ed5367fef4011ac708c1acaaa5003e4ed680d" \ + "df022012c52160ae6b85fc59ceed80c7cacd5358b80712371733de7c76fef552114ee6014752" \ + "2103ee30ea502d692ecfc79dfcb6fb2d6914fc70ba80db971beebacccdbaed40d7c52102f52d" \ + "b885d04dc43ca8562471759dd621b899faf508caba70963d9228bfd2415e52ae00000000dab0" \ + "20ee0a80a818e4d20a52aa7ba367a0a2d430d22c26ccb4572527e259e14a01000000d9004730" \ + "44022064745ac8cae859bb19305a550981b8d39b69efec55b9a423dca645cd3b5c845502205c" \ + "f375839d7f056235feb550a8138a03e75fa140503a2ce61fe239a3bfe4214501473044022072" \ + "8b0393d5427d8abb56a608c6b1a0b14c5455f3abeb56ce8a5c7f70035af71d022052a99e4e38" \ + "9790b364f6180caf1523d6da2b3daabe85952705023be2b5409b360147522103e296937dbdaf" \ + "dae4d0a45b33d9a691b0c0e71d97bd2ffc82da895a251f74bd7e2103ead7ad0c398f928cbe85" \ + "1a6b387a5e74d139487caf4d4ac3dc3d478254dbbb4452ae0000000067a6c2e2f14fc412b3f5" \ + "627fafac2fe43009bc403ec680839579444df2ce042b00000000da00483045022100d3bdc055" \ + "fa5dcce335a1d572b1c3ccb8cc9ba91960c6361c77e29ded716e233102200e7ebb43fd39fb98" \ + "c714098d4fda32d94cdbefdd96c0c918b788aacc6164953c0147304402202f4338d2710edb19" \ + "60dcf7136411f065a16bee4e44b86604d64c660315bc55040220238c1c3216feb31051f77982" \ + "97317819da1dfa830d24a6a9e38a37367a68ebd101475221037b2987df626510ce25e6ce5fdb" \ + "716705e23fecb7398b2cbb0a1c0af7ca5da717210345e358653b4580b5bd68d263089a0a2bf9" \ + "fcc1e145fcf2a3d4b9ab5cd7e1a76752ae000000004f28d63103dfb86a5d92d2daf328bbb35d" \ + "72239766a5853b7076a90d1745813200000000da00483045022100e89ac8215ee87186de284c" \ + "419b2522ebfb2ecb8063d0f91942f2ad63f383d3d4022036485902bb1f2e0b2cc645aab8781d" \ + "ef27f25e91d8256d48dd48d5cfca1a21c20147304402201449379f1d57f2b7ad1dc0882f5962" \ + "7287a6c32180ffa7637941b0eaa666dd4b022028eb0eed77e1b92de046098c855834a5feeade" \ + "a55d17160bc6d11d47184e8b51014752210283db605dc305201ab9be509a22d2c83b388002fb" \ + "54ecd82d86efe83c0a1d35822103146f745eff0ae31fe899aafd27d51d2c0f5b0c03f2f47b3c" \ + "65bb26ec7581ad8652ae0000000021cb3b00d1f22455e76e86872e00ef556578bcc112071e6a" \ + "5b4ac02ab682fdb301000000232200206ea344e9a4a8f8a8983479af2ae3ed29fab153955af1" \ + "4457780a304a6832b9c50000000016dcc4b40a514c43ed61d6c01a9006d7f21a6d30b99b3e58" \ + "0d21578e35002502000000002322002049ea1f7c280b32fee0dce2e1801df2218df59d64614c" \ + "4fe76c043ee2c80116700000000002005ed0b20000000017a91495c5c19257aa52bd4b702ba1" \ + "a5e29b8d72a75a3a876d6b4e010000000017a91487b6255a5df746188f0bd22ed0194a40ec98" \ + "f2de87be810700" + segwit_view = "010000000001060c02c24bbfefd94cdc4f58a3f83f93e05b14ad968ec6aba54190c3dcba6eef1b00" \ + "000000da00483045022100f4dbf2ca7b5da97bd78818635d48004e6bf1a6f7e5e24bcecb7d93f554" \ + "e49eaf02200a05025d93475b6372d14bd8fe8366fe10570ade772b19d124d3b0175b9f6eda014730" \ + "4402202290feb53fc4cb077c5d3eed0ed5367fef4011ac708c1acaaa5003e4ed680ddf022012c521" \ + "60ae6b85fc59ceed80c7cacd5358b80712371733de7c76fef552114ee60147522103ee30ea502d69" \ + "2ecfc79dfcb6fb2d6914fc70ba80db971beebacccdbaed40d7c52102f52db885d04dc43ca8562471" \ + "759dd621b899faf508caba70963d9228bfd2415e52ae00000000dab020ee0a80a818e4d20a52aa7b" \ + "a367a0a2d430d22c26ccb4572527e259e14a01000000d900473044022064745ac8cae859bb19305a" \ + "550981b8d39b69efec55b9a423dca645cd3b5c845502205cf375839d7f056235feb550a8138a03e7" \ + "5fa140503a2ce61fe239a3bfe42145014730440220728b0393d5427d8abb56a608c6b1a0b14c5455" \ + "f3abeb56ce8a5c7f70035af71d022052a99e4e389790b364f6180caf1523d6da2b3daabe85952705" \ + "023be2b5409b360147522103e296937dbdafdae4d0a45b33d9a691b0c0e71d97bd2ffc82da895a25" \ + "1f74bd7e2103ead7ad0c398f928cbe851a6b387a5e74d139487caf4d4ac3dc3d478254dbbb4452ae" \ + "0000000067a6c2e2f14fc412b3f5627fafac2fe43009bc403ec680839579444df2ce042b00000000" \ + "da00483045022100d3bdc055fa5dcce335a1d572b1c3ccb8cc9ba91960c6361c77e29ded716e2331" \ + "02200e7ebb43fd39fb98c714098d4fda32d94cdbefdd96c0c918b788aacc6164953c014730440220" \ + "2f4338d2710edb1960dcf7136411f065a16bee4e44b86604d64c660315bc55040220238c1c3216fe" \ + "b31051f7798297317819da1dfa830d24a6a9e38a37367a68ebd101475221037b2987df626510ce25" \ + "e6ce5fdb716705e23fecb7398b2cbb0a1c0af7ca5da717210345e358653b4580b5bd68d263089a0a" \ + "2bf9fcc1e145fcf2a3d4b9ab5cd7e1a76752ae000000004f28d63103dfb86a5d92d2daf328bbb35d" \ + "72239766a5853b7076a90d1745813200000000da00483045022100e89ac8215ee87186de284c419b" \ + "2522ebfb2ecb8063d0f91942f2ad63f383d3d4022036485902bb1f2e0b2cc645aab8781def27f25e" \ + "91d8256d48dd48d5cfca1a21c20147304402201449379f1d57f2b7ad1dc0882f59627287a6c32180" \ + "ffa7637941b0eaa666dd4b022028eb0eed77e1b92de046098c855834a5feeadea55d17160bc6d11d" \ + "47184e8b51014752210283db605dc305201ab9be509a22d2c83b388002fb54ecd82d86efe83c0a1d" \ + "35822103146f745eff0ae31fe899aafd27d51d2c0f5b0c03f2f47b3c65bb26ec7581ad8652ae0000" \ + "000021cb3b00d1f22455e76e86872e00ef556578bcc112071e6a5b4ac02ab682fdb3010000002322" \ + "00206ea344e9a4a8f8a8983479af2ae3ed29fab153955af14457780a304a6832b9c50000000016dc" \ + "c4b40a514c43ed61d6c01a9006d7f21a6d30b99b3e580d21578e35002502000000002322002049ea" \ + "1f7c280b32fee0dce2e1801df2218df59d64614c4fe76c043ee2c80116700000000002005ed0b200" \ + "00000017a91495c5c19257aa52bd4b702ba1a5e29b8d72a75a3a876d6b4e010000000017a91487b6" \ + "255a5df746188f0bd22ed0194a40ec98f2de87000000000400473044022100d0d2ded141c9369bcc" \ + "99de23d3d41d1d99d6cff47126df1b0c4d4797f947eacf021f790f1c112b3425ebc3251d719aae6e" \ + "f0f9830b688585275591a5353f1f973801483045022100bf06c762e6ab64258d2f2777a66fe32ddd" \ + "8f36e232b80bf5afa6ff9b9aa73ee0022049caf991fce808e60a9b17499f5e0dc11f6163e3ef7bca" \ + "8109b72b5695d674210147522103edd556806048b319d71f43466c4415001bb32d8afe3aac06532d" \ + "3ac210fd0e86210215e16727cf1389b4ee377487385f3ec595841a6bb747eb9c3a5cd559e9b1c8dc" \ + "52ae040047304402204e9cc87526e148d236d692fa70104d26b8df632f30f4e3be38a2e99cec76d0" \ + "f80220354ae575c3537c0ad2399a6037a9164b0cb147b12f262efc906649ca7950e2eb0147304402" \ + "203553bcd1565804ec71c997c87006bd91c639b74a004b19a239c7f551aab5635a0220753f74e065" \ + "c0b7cdf67d16b00f6a20dda7159a49f20aa493a7889b2851b2fea30147522103b09ac1fa65a55fa4" \ + "feadea57c4cf417d7490065d8b844ada60c242a441e0e3a42103c0625169b46dbbde3492db7c62f1" \ + "be8f582131467620cef17335306bad7ef88a52aebe810700" + print("Deserialize Segwit transaction 2") + ns = Transaction(non_segwit_view) + s = Transaction(segwit_view) + self.assertEqual(s.serialize(segwit=False,hex = True), non_segwit_view) + self.assertEqual(s.serialize(segwit=True, hex = True), segwit_view) + self.assertEqual(ns.serialize(segwit=False, hex = True), non_segwit_view) + + tx = "01000000014cee27ba570d2cca50bb9b3f7374c7eb24ec16ffec0a077c84c1cc23b0161804010000008b48304" \ + "502200f1100f78596c8d46fb2f39c570ce6945956a3dd33c48fbdbe53af1c383182ed022100a85b528ea21ee7" \ + "f39b2ec1568ac19f26f4dd4fb9d3dbf70587986de3c2c90fa801410426e4d0890ad5272b2b9a10ca3f518f7e0" \ + "25932caa62f13467e444df89ed25f24f4fc5075cad32f468c8f7f913e30057449d65623726e7102f5eaa326d4" \ + "86ebf7ffffffff020010000000000000006020e908000000001976a914947236437233a71cb033a53932008db" \ + "fe346388e88ac00000000" + Transaction(tx) + tx = "01000000011e6c87805dad469ed72b42668b858df90e6b007c6410a7bde65bb1cf687d8409000000006b48304" \ + "502204f3353cf129bb805fb90315aeb6d5ab8e0937129c4b0f1422495e42b6bf0e928022100cbdd2811a4c943" \ + "97aa731c224ee0c7290fea6bc17a9b3ce5957d9937c60f4f97012103e2a0e6a91fa985ce4dda7f048fca5ec82" \ + "64292aed9290594321aa53d37fdea32ffffffff0160e3160000000000fdaf0563ff054effffffff4da3054672" \ + "6f6d2061336136316665663433333039623966623233323235646637393130623033616663353436356239204" \ + "d6f6e205365702031372030303a30303a303020323030310a46726f6d3a205361746f736869204e616b616d6f" \ + "746f203c7361746f7368696e40676d782e636f6d3e0a446174653a204d6f6e2c2031322041756720323031332" \ + "030323a32383a3032202d303230300a5375626a6563743a205b50415443485d2052656d6f7665202853494e47" \ + "4c457c444f55424c4529425954450a0a492072656d6f76656420746869732066726f6d20426974636f696e206" \ + "96e20663165316662346264656638373863386663313536346661343138643434653735343161376538330a69" \ + "6e2053657074203720323031302c20616c6d6f73742074687265652079656172732061676f2e2042652077617" \ + "26e6564207468617420492068617665206e6f740a61637475616c6c7920746573746564207468697320706174" \ + "63682e0a2d2d2d0a206261636b656e64732f626974636f696e642f646573657269616c697a652e7079207c202" \ + "0202038202b2d2d2d2d2d2d2d0a20312066696c65206368616e6765642c203120696e73657274696f6e282b29" \ + "2c20372064656c6574696f6e73282d290a0a64696666202d2d67697420612f6261636b656e64732f626974636" \ + "f696e642f646573657269616c697a652e707920622f6261636b656e64732f626974636f696e642f6465736572" \ + "69616c697a652e70790a696e64657820363632303538332e2e38396239623162203130303634340a2d2d2d206" \ + "12f6261636b656e64732f626974636f696e642f646573657269616c697a652e70790a2b2b2b20622f6261636b" \ + "656e64732f626974636f696e642f646573657269616c697a652e70790a4040202d3238302c3130202b3238302" \ + "c38204040206f70636f646573203d20456e756d65726174696f6e28224f70636f646573222c205b0a20202020" \ + "20224f505f57495448494e222c20224f505f524950454d44313630222c20224f505f53484131222c20224f505" \ + "f534841323536222c20224f505f48415348313630222c0a2020202020224f505f48415348323536222c20224f" \ + "505f434f4445534550415241544f52222c20224f505f434845434b534947222c20224f505f434845434b53494" \ + "7564552494659222c20224f505f434845434b4d554c5449534947222c0a2020202020224f505f434845434b4d" \ + "554c5449534947564552494659222c0a2d2020202028224f505f53494e474c45425954455f454e44222c20307" \ + "84630292c0a2d2020202028224f505f444f55424c45425954455f424547494e222c20307846303030292c0a20" \ + "20202020224f505f5055424b4559222c20224f505f5055424b455948415348222c0a2d2020202028224f505f4" \ + "94e56414c49444f50434f4445222c20307846464646292c0a2b2020202028224f505f494e56414c49444f5043" \ + "4f4445222c2030784646292c0a205d290a200a200a4040202d3239332c3130202b3239312c362040402064656" \ + "6207363726970745f4765744f70286279746573293a0a202020202020202020766368203d204e6f6e650a2020" \ + "202020202020206f70636f6465203d206f72642862797465735b695d290a20202020202020202069202b3d203" \ + "10a2d20202020202020206966206f70636f6465203e3d206f70636f6465732e4f505f53494e474c4542595445" \ + "5f454e4420616e642069203c206c656e286279746573293a0a2d2020202020202020202020206f70636f64652" \ + "03c3c3d20380a2d2020202020202020202020206f70636f6465207c3d206f72642862797465735b695d290a2d" \ + "20202020202020202020202069202b3d20310a200a2020202020202020206966206f70636f6465203c3d206f7" \ + "0636f6465732e4f505f5055534844415441343a0a202020202020202020202020206e53697a65203d206f7063" \ + "6f64650a2d2d200a312e372e392e340a0a6800000000" + t= Transaction(tx) + tx = "0100000001c86c4ddc01f59b748e6a55a6d09c5bce7574fbdec721ca468768b5d6d9e3fb00000000006b48304" \ + "5022076b5504ad7aff614e32159ac055362a1197c9a5e50de48cf4f05c7547b39c0b5022100ea67efb2585aae" \ + "40a53363f48e3e38dfc7387b238f8716fa53a5f0ed51b7c314012102452928340bc618777d217a52f30d8e144" \ + "0d98f561c523a31834a1614106f3c15ffffffff025cf5352f0d0000001976a9141855d5890b8aec536ffc3e59" \ + "cb586e98b34b5b9288ac0bd32204000000001976a9146f3f6845da01e856a426c31dfeef188c06bf574d88ac0" \ + "0000000" + # Transaction(tx) + + tx = "02000000000117096abdf1191fc4e1aa92e66b0dcc04241cd3949d7cb8f6e3f8b7d2867f9cf80900000000171" \ + "600146ec7cb98e540f2d0b39bed94511d44a24be7f2f0feffffff146e022c0a8b94bb0b38ae93a3cda7265db7" \ + "3d4f658d10634acb4816c4131fcb01000000171600141d48006f03cdc922da829c479feecf3d6bc7d4d8fefff" \ + "fff290d1b0ff9d2eb2c3e09c23f05eb1edce4493d0722b9c6d677692f749ab1b6a50000000017160014acb529" \ + "ba2f57150b6c52781bbd82d224fcda9a33feffffff3b1ad0e2198759c7157c837af79351161630e7b389f43bc" \ + "2db501781a1562a850000000017160014116ba1a4ffec3012cd009de84db9a10a88169ecdfeffffff3b7d62e6" \ + "750593892af6f2cd789db8db3b8d5ec40d3a604aa50ef17010a05e7200000000171600140a2ecd45ea98ff976" \ + "641f11cfd65b489c2931e2efeffffff52f17014e779d564173ecb38e5911e5b43f2d593529729a62cb4768f3d" \ + "4acc39eb0000001716001410c090b35e7d62334c0aab64fd9459e58d2aace1feffffff52f17014e779d564173" \ + "ecb38e5911e5b43f2d593529729a62cb4768f3d4acc396501000017160014eba3843f4d612cd5f73b44d2d2b2" \ + "0a14bc402afffeffffff52f17014e779d564173ecb38e5911e5b43f2d593529729a62cb4768f3d4acc397c010" \ + "00017160014436e3e8e328425e04929c7624534405a1a8ec87efeffffff7987375451a860c131f5661ecfd6ac" \ + "f2206b9eeba90f6d7e2e2bf828fc74000701000000171600149bc9b2c23b4d3aaee5c206de8eb88f64e37d8f8" \ + "cfeffffff867a8c3c48e7995d70b7d39c25cd7b21749b2756f0aa5b0140a32e545baa1f100100000017160014" \ + "8698b478bcd14c7f12d5f43f9f566ba6cfe44172feffffff9790a339ebd0a0caa802cb9168635d738e075032c" \ + "1619f556b7634b2985ee4ce0000000017160014770cc4796bab516455a6e1f3b75343888050f1b2feffffff9c" \ + "bc483b0e911190880e48cb0fad167a33c8e73ecdded9f63e5001a54e0d9c460300000017160014d02d35e9276" \ + "4caf590cb0b309f40bf6ee0673de5feffffffa219e1f09e7c168ed469a9948d88248d7d2561514f22d6e47661" \ + "9fce90876c4b01000000171600144c9d756273fa839887413d8e57429a09263f7757feffffffbb99d3c6a586e" \ + "40ed80e782a0584febb15daf1622e2717daaed4c71e224a5745000000001716001429a23327092f771825a0d4" \ + "3c7c2187865df4d01ffeffffffbf4932f21c4bee27918fa0e400e4fa5e53dbc7893b334980ea5dd9044c6baf6" \ + "d01000000171600144b7063ed9a8f3d7fd14f18a399269256c5e6cbc1feffffffcba7ccd697116c1a259f1292" \ + "0334ec62c54e42fab865ebc1cbcbbabe42d20ab2010000001716001432d881b6893d2360a6cb65732829cfe45" \ + "292d642feffffffddcd78811d2b73feca247c787105c362a23f32da01472fd504579cb0e64c70a70100000017" \ + "160014e4e03eba879ef2f13abb38647767b4e8cbc94356feffffffe9a166d7e4b8372886160893f376084b9f0" \ + "c5b289d06774315cf7a15a0b95cc80000000017160014f3f1e21efa1acc3c6ca1786fe6a38462a38b5855feff" \ + "fffff0707a5ad2c3e052badcc40236b12fb866d203b73b6b7df1e8d5a5a60eece8f9030000001716001416b40" \ + "0b1168b387284c2925c3789700027a83932fefffffff0ff68934c0cd40d10ba612346f26c72fa4a67ea0b0b84" \ + "578729dca540a285e731000000171600140afb8e8d46deabffaeffe3402fd57537a445fa57fefffffff0ff689" \ + "34c0cd40d10ba612346f26c72fa4a67ea0b0b84578729dca540a285e70302000017160014d29b4da896e24b81" \ + "980f3dc5319302a3dec6a6f4fefffffffb6e1c56c1243d038bfdcab451a701e8766baf787aa8d74e6aeb87713" \ + "f67c0120100000017160014725752b632549054dbf0bedaaa091e12dabcc8f0feffffffffaf40d3cfbeefdecf" \ + "14db8bd5ec7ae6f8d1e69c222f951600d6b514ebf3e9420100000017160014330624c35e0e371c15acdcc6325" \ + "7dae5b1930088feffffff021cb81c00000000001976a914ce5cd304c7ba6f89e96aa6c4e92b7455b5359e4e88" \ + "ac51420f00000000001976a9142c997b4e8951e7b3e863bbb439b1050bf0fcdd1d88ac0247304402201f4c1c9" \ + "0d25365fa146106edf11416459b02d4d6d5f4537b37fe5cc523f3a63002206748a144f4012e838705edb505a5" \ + "ef556ecc91df615cab12786369c3d8ab6d3c012102b4323697c2fa1ff13e696f6bc5fe5f67c989cb91b8755e1" \ + "1a7c37213c94e957902483045022100dfe620ca3167e75fac002448069fbface366ee7c57f7f86e9a77113127" \ + "7c91b20220108a436df211fc21909c450e270c765c2c20814643f3804173be88d6863d51260121032522bbee5" \ + "1b2ccad81c4255e2d4eb516ea7943aa8656eaa8ad7b7cd6abcc97370247304402206a4a1836d79004b3430bd6" \ + "1d73e938f0bcc1a56c655b52444d4e047464db0592022067bd8d4965d55e261d1e4e38462f20a8a2610f5ac78" \ + "d551fc95a522b7144589a0121026baf81f20d6a50e6262f433875651e7b192c304105c6911276541e45a67f96" \ + "9402473044022057741ff3470fa4b70b204d621ed737097d3f6cec4a2e43d39c5d6c650117b28d02205b6c3b2" \ + "c92ec047c1c4d3fd7b785474345a038f9842d6a30048737cd471117ea012102fbf1d98a34bd3f1283c9f258f8" \ + "7a6baff2b65710d4f3b77d5589dacc155b6f8d02483045022100bc07cccf6ac51626147ccb0c1ffd91d0bbedb" \ + "6e5df3c798fd8035112bc92070c022034eb7a9658d9ed7b56256155151f8280e871e00e3aefa9b6ea8ae35a27" \ + "0c3b8d0121032004240c860bd92ebcf6c834cdc1d9d28fefe757245d61fe86a02c04994697cd0248304502210" \ + "0c62ecdebd1728f18a746cf1575cdf29cdf6b03dd86d9b7ead96c9a7341c8ad1702205cd92ace00bf53254e1d" \ + "bed3d10f675540dc3a1b1b3dc353ffe3901508bbbb0101210242ff69abeaea31b6fc6e1ea1625179003b9d0d8" \ + "2c729ec78df8ef5fb378e6bc002473044022026217dec2bbc97afbfeba833cf9fa323206c26037a5dce5221cb" \ + "323af142cb1e02206e2ef15be6da7b99e50339a8924de232693494154f792018b6cca4f9f307192e012103ea5" \ + "0f77697dd3467f4876382a447372cd03e5ec567385152e4e91c573c54cf49024730440220256d9ab9ce4c8efb" \ + "7628f7f56e0a59b81c0f973d6c9b89b3ac5c018c54d61a58022064f7c7084c3fb30f118187956e624ce4d4eef" \ + "7acee81a52be1ccd5683e661f6c0121024d812e6254577bdf98d2b52b36d548dfcf03c994b159309839d30c38" \ + "73ec15d5024830450221009618e1427a53dc66e26178416afe6465feb6882d6c4b4a0a3f6b6ce70965a40f022" \ + "03d1b0bdee921bb733674d5b373244c4676982eec20c0f7069917b0e2c1d20f6c012103f8c70a3b0a1bdd9ab4" \ + "0770a1532a2d0f2eb046e4eb56434ba1a9b214e19ed47a0247304402205e8d08cdae61f6c8ba2d17a18b6575e" \ + "4d5e2511f491621d4fa1bebbe89b7794e02200c565ab9379b57b731821e0c9172c65e3339e5a83dbc24d3ecff" \ + "79dc8879edc0012102d4c245cb72bc520be55959df9faea82c470a51942907ad83339ae70c5e2a8efa0247304" \ + "402207bc8e60dbf3ed02d9b08df09572716cf486e1f49927467131b05487f376eede4022040fd95d42a11456a" \ + "2a49eda376edcb0b71baa21cdd562236162806ad9e5d4a4701210287cd827827140bbd304b5feaa9a8c9e36d4" \ + "f5a1da292e16e207039b1fadc488402473044022052e177e94353f03a2bb8aed3a3cbc14cb1095b36d972b356" \ + "dd2e9ef12a38cb95022055624ef65618144c4ffc9125bedfd625594f2926d5c14f5805cf26d278e802f101210" \ + "25493a9da73c46838c6bad1414d1497a8216fbc8e0f46d981167d004b2cc4a6b802483045022100c09f346d36" \ + "af2ab4915e96f1088f431cea41854e6a605dfb86b0f87764269203022000fb0354e7d3d6b42ca8b2c59736a0c" \ + "a9c3f2cc5263c056abc84c7be62bd6184012103f86036ceb2bd6a57b9f39f5aa986e7fc6a0dd1f379e9549396" \ + "2aaf88b228b0b70247304402205be7111758fa4670778571af558ad85c802b9292503df389cd47cd063936185" \ + "f0220481965e1ba34cbf6e7b548af01a34c6185921a6120f07cfe437f33071c83c625012102414eb9f4393b9a" \ + "5f30f9d4ab2612a9782b062ec0a6b13dbbc5037b185ad8f72002483045022100db73b46fd12fbb17663750417" \ + "8f0aa784749b9cd20e7cbfc23586ad7e06fe7fc022038512998ce23ed4b1aff7d07e1654344bc11720976ac0a" \ + "3aeece7018999a35ee01210292e1e3b2079ce6ef363f633cffa07f9a0d316e67c0c8d50eea2da026d3cfc6070" \ + "2473044022000cd297f5b9aaa94e40210bfc47d10d9156be8ba3db665741d7c77c29118f355022033aa9c328e" \ + "90a12bf701167659db4cddbb091af7bb8ae4dc83fd0833667123a4012103c45c84d80cd594a9d014935248622" \ + "a33b8ee1c597334586273aab9a9ef1784d502483045022100a152152ee871ac06bd0f0e385b0e281188504ae9" \ + "40f54c86760ca0bc1bde6e8902207578d03e42670d5172fb589974853402e00136d2e07c9285171ad79435a94" \ + "17e012102cbd3cfc675393c20d9acc51086d8faff48621a216531446ac7c388dcd88decc40247304402200e64" \ + "ece9d74242f638db43fa600af34df9289ce93d1756bc5c3be77973b28d7a02205608d5a304efd41c8024a60bc" \ + "0f1ed44413941fa80239d01a1e95f15499c2bca0121028447cfc8b84edc759eace6dfbbd6138ebeb470da7819" \ + "5a96caf192750487c0c30247304402207244b3a176cf0a7203fbcab9e0f3be5eea21b9ce701a07140b7d591ec" \ + "19234f302205e5c6cc861576a871d55609a52f0895710812cb6a2aaa1279a5e01f2d1874779012102bd77789c" \ + "af99127c39f22ff5432be6c285c9c5bbbebc86cb35d4f1d5f6fa652302483045022100dbad3f4038a81323d97" \ + "f6f6347e31739b7f8d6331ca1fce17ee46f1c9d0b97da022005678968ff1946e1e368a04e87e8954ff5606c42" \ + "57c9a114940d32f39f6fbd1f01210322f53e7d73d997c1875db26464875ad797c6cffe80ba548ff524c360495" \ + "78fae02473044022075aec794771d9d133e9de71bf89e24227c08bf58dec8cdfff0cd781fa3bf9bed02200d26" \ + "e2b9535b9ea8e6aed0ba41aff6dd9f0181418679305c67b5bb888e526df40121020eb887a39d202928ba2abf1" \ + "d16df73aaa17daf9922fd3a3bf6554e730f9c88eb02483045022100dd2d2187fd37e5bf333c1bf0b4dae9f42d" \ + "ef626458bc9283fe6bdf991e9abcab02207e1954eaadbeed240e577aa0f7d329d53b5934edd1da0320964aace" \ + "da09af35f012102ff5bdd1e69f2363d95d80eeeced34bc0de8fc5df9f819cce6ed1d6805beff8ec0247304402" \ + "205ec43c7d919216ad16ed85d75f9d98d1695dddc5810ad0c5635d96b47588eeda02201d71c85602169a109e9" \ + "0e558125033075237d9177553bac1d1d24d8610cb9d0a012103f50abc70096bb6f6f8742e73c5bf0f1bd4d475" \ + "9c1dd2e4486b6fec52b3c8eda6daf10700" + + tx = Transaction(tx) + + diff --git a/pybtc/transaction.py b/pybtc/transaction.py new file mode 100644 index 0000000..85e437b --- /dev/null +++ b/pybtc/transaction.py @@ -0,0 +1,1109 @@ +import json +from struct import unpack, pack +from math import ceil +from io import BytesIO +from pybtc.constants import * +from pybtc.opcodes import * +from pybtc.functions.tools import (int_to_var_int, + read_var_int, + var_int_to_int, + rh2s, + s2rh, + bytes_from_hex, + get_stream) +from pybtc.functions.script import op_push_data, decode_script, parse_script, sign_message +from pybtc.functions.script import get_multisig_public_keys, read_opcode, is_valid_signature_encoding +from pybtc.functions.script import public_key_recovery, delete_from_script +from pybtc.functions.hash import hash160, sha256, double_sha256 +from pybtc.functions.address import hash_to_address, address_net_type, address_to_script +from pybtc.address import PrivateKey, Address, ScriptAddress, PublicKey + + + +class Transaction(dict): + """ + The class for Transaction object + + :param raw_tx: (optional) raw transaction in bytes or HEX encoded string, if no raw transaction provided + well be created new empty transaction template. + :param tx_format: "raw" or "decoded" format. Raw format is mean that all transaction represented in bytes + for best performance. + Decoded transaction is represented in human readable format using base68, hex, bech32, + asm and opcodes. By default "decoded" format using. + :param int version: transaction version for new template, by default 1. + :param int lock_time: transaction lock time for new template, by default 0. + :param boolean testnet: address type for "decoded" transaction representation. + + """ + def __init__(self, raw_tx=None, format="decoded", version=1, lock_time=0, testnet=False, auto_commit=True): + if format not in ("decoded", "raw"): + raise ValueError("format error, raw or decoded allowed") + self.auto_commit = auto_commit + self["format"] = format + self["testnet"] = testnet + self["segwit"] = False + self["txId"] = None + self["hash"] = None + self["version"] = version + self["size"] = 0 + self["vSize"] = 0 + self["bSize"] = 0 + self["lockTime"] = lock_time + self["vIn"] = dict() + self["vOut"] = dict() + self["rawTx"] = None + self["blockHash"] = None + self["confirmations"] = None + self["time"] = None + self["blockTime"] = None + self["blockIndex"] = None + self["coinbase"] = False + self["fee"] = None + self["data"] = None + self["amount"] = None + if raw_tx is None: + return + + self["amount"] = 0 + sw = sw_len = 0 + stream = self.get_stream(raw_tx) + start = stream.tell() + read = stream.read + tell = stream.tell + seek = stream.seek + # start deserialization + self["version"] = unpack(' 520 and input_verify): + raise TypeError("script_sig invalid") + + if not isinstance(v_out, int) or not (v_out <= 0xffffffff and v_out >= 0): + raise TypeError("v_out invalid") + if not isinstance(sequence, int) or not (sequence <= 0xffffffff and sequence >= 0): + raise TypeError("sequence invalid") + + if private_key: + if not isinstance(private_key, PrivateKey): + private_key = PrivateKey(private_key) + if amount: + if not isinstance(amount, int) or not amount >= 0 and amount <= MAX_AMOUNT: + raise TypeError("amount invalid") + + if tx_in_witness: + if not isinstance(tx_in_witness, list): + raise TypeError("tx_in_witness invalid") + l = 0 + witness = [] + for w in tx_in_witness: + if isinstance(w, str): + witness.append(bytes_from_hex(w) if self["format"] == "raw" else w) + else: + witness.append(w if self["format"] == "raw" else bytes_from_hex(w)) + l += 1 + len(w) + if len(w) >= 0x4c: + l += 1 + if len(w) > 0xff: + l += 1 + # witness script limit + if not l <= 10000: + raise TypeError("tx_in_witness invalid") + + if tx_id == b"\x00" * 32: + if not (v_out == 0xffffffff and sequence == 0xffffffff and len(script_sig) <= 100): + if input_verify: + raise TypeError("coinbase tx invalid") + self["coinbase"] = True + + # script_pub_key + if script_pub_key: + if isinstance(script_pub_key, str): + script_pub_key = bytes_from_hex(script_pub_key) + if not isinstance(script_pub_key, bytes): + raise TypeError("script_pub_key tx invalid") + + if redeem_script: + if isinstance(redeem_script, str): + redeem_script = bytes_from_hex(redeem_script) + if not isinstance(redeem_script, bytes): + raise TypeError("redeem_script tx invalid") + + if address is not None: + if isinstance(address, str): + net = True if address_net_type(address) == 'mainnet' else False + if not net != self["testnet"]: + raise TypeError("address invalid") + script = address_to_script(address) + elif type(address) in (Address, ScriptAddress): + script = address_to_script(address.address) + else: + raise TypeError("address invalid") + if script_pub_key: + if script_pub_key != script: + raise Exception("address not match script") + else: + script_pub_key = script + + k = len(self["vIn"]) + self["vIn"][k] = dict() + self["vIn"][k]["vOut"] = v_out + self["vIn"][k]["sequence"] = sequence + if self["format"] == "raw": + self["vIn"][k]["txId"] = tx_id + self["vIn"][k]["scriptSig"] = script_sig + if script_pub_key: + self["vIn"][k]["scriptPubKey"] = script_pub_key + if redeem_script: + self["vIn"][k]["redeemScript"] = redeem_script + else: + self["vIn"][k]["txId"] = rh2s(tx_id) + self["vIn"][k]["scriptSig"] = script_sig.hex() + self["vIn"][k]["scriptSigOpcodes"] = decode_script(script_sig) + self["vIn"][k]["scriptSigAsm"] = decode_script(script_sig, 1) + if script_pub_key: + self["vIn"][k]["scriptPubKey"] = script_pub_key.hex() + self["vIn"][k]["scriptPubKeyOpcodes"] = decode_script(script_pub_key) + self["vIn"][k]["scriptPubKeyAsm"] = decode_script(script_pub_key, 1) + if redeem_script: + self["vIn"][k]["redeemScript"] = redeem_script.hex() + self["vIn"][k]["redeemScriptOpcodes"] = decode_script(redeem_script) + self["vIn"][k]["redeemScriptAsm"] = decode_script(script_pub_key, 1) + if tx_in_witness: + self["segwit"] = True + self["vIn"][k]["txInWitness"] = witness + if amount: + self["vIn"][k]["value"] = amount + if private_key: + self["vIn"][k]["private_key"] = private_key + if self.auto_commit: + self.commit() + return self + + def add_output(self, amount, address=None, script_pub_key=None): + if address is None and script_pub_key is None: + raise Exception("unable to add output, address or script required") + if type(amount) != int: + raise TypeError("unable to add output, amount type error") + if amount < 0 or amount > MAX_AMOUNT: + raise Exception("unable to add output, amount value error") + if script_pub_key: + if isinstance(script_pub_key, str): + script_pub_key = bytes_from_hex(script_pub_key) + if not isinstance(script_pub_key, bytes): + raise TypeError("unable to add output, script_pub_key type error") + else: + if type(address) == Address: + address = address.address + script_pub_key = address_to_script(address) + + k = len(self["vOut"]) + self["vOut"][k] = dict() + self["vOut"][k]["value"] = amount + segwit = True if "segwit" in self else False + s = parse_script(script_pub_key, segwit) + self["vOut"][k]["nType"] = s["nType"] + self["vOut"][k]["type"] = s["type"] + + if self["format"] == "raw": + self["vOut"][k]["scriptPubKey"] = script_pub_key + if self["data"] is None: + if s["nType"] == 3: + self["data"] = s["data"] + if s["nType"] not in (3, 4, 7, 8): + self["vOut"][k]["addressHash"] = s["addressHash"] + self["vOut"][k]["reqSigs"] = s["reqSigs"] + else: + self["vOut"][k]["scriptPubKey"] = script_pub_key.hex() + if self["data"] is None: + if s["nType"] == 3: + self["data"] = s["data"].hex() + if s["nType"] not in (3, 4, 7, 8): + self["vOut"][k]["addressHash"] = s["addressHash"].hex() + self["vOut"][k]["reqSigs"] = s["reqSigs"] + self["vOut"][k]["scriptPubKeyOpcodes"] = decode_script(script_pub_key) + self["vOut"][k]["scriptPubKeyAsm"] = decode_script(script_pub_key, 1) + sh = True if self["vOut"][k]["nType"] in (1, 5) else False + witness_version = None if self["vOut"][k]["nType"] < 5 else 0 + if "addressHash" in self["vOut"][k]: + self["vOut"][k]["address"] = hash_to_address(self["vOut"][k]["addressHash"], + self["testnet"], + sh, + witness_version) + if self.auto_commit: + self.commit() + return self + + def del_output(self, n=None): + if not self["vOut"]: + return self + if n is None: + n = len(self["vOut"]) - 1 + new_out = dict() + c = 0 + for i in range(len(self["vOut"])): + if i != n: + new_out[c] = self["vOut"][i] + c += 1 + self["vOut"] = new_out + if self.auto_commit: + self.commit() + return self + + def del_input(self, n): + if not self["vIn"]: + return self + if n is None: + n = len(self["vIn"]) - 1 + new_in = dict() + c = 0 + for i in range(len(self["vIn"])): + if i != n: + new_in[c] = self["vIn"][i] + c += 1 + self["vIn"] = new_in + if self.auto_commit: + self.commit() + return self + + def sign_input(self, n, private_key=None, script_pub_key=None, + redeem_script=None, + sighash_type=SIGHASH_ALL, + address=None, amount=None, witness_version=0, + p2sh_p2wsh=False): + # private key + if not private_key: + try: + private_key = self["vIn"][n]["private_key"].key + except: + raise RuntimeError("no private key") + if isinstance(private_key, list): + public_key = [PublicKey(p).key for p in private_key] + private_key = [p.key if isinstance(p, PrivateKey) else PrivateKey(p).key for p in private_key] + else: + if not isinstance(private_key, PrivateKey): + private_key = PrivateKey(private_key) + public_key = [PublicKey(private_key).key] + private_key = [private_key.key] + + if address is not None: + if isinstance(address, str): + net = True if address_net_type(address) == 'mainnet' else False + if not net != self["testnet"]: + raise TypeError("address invalid") + script_pub_key = address_to_script(address) + elif type(address) in (Address, ScriptAddress): + script_pub_key = address_to_script(address.address) + # script pub key + if script_pub_key is None: + + if "scriptPubKey" in self["vIn"][n]: + script_pub_key = self["vIn"][n]["scriptPubKey"] + st = parse_script(script_pub_key) + elif redeem_script or "redeemScript" in self["vIn"][n]: + if witness_version is None or p2sh_p2wsh: + st = {"type": "P2SH"} + elif witness_version == 0: + st = {"type": "P2WSH"} + else: + raise RuntimeError("not implemented") + else: + raise RuntimeError("no scriptPubKey key") + else: + st = parse_script(script_pub_key) + if isinstance(script_pub_key, str): + script_pub_key = bytes.fromhex(script_pub_key) + + # sign input + if st["type"] == "PUBKEY": + script_sig = self.__sign_pubkey__(n, private_key, script_pub_key, sighash_type) + elif st["type"] == "P2PKH": + script_sig = self.__sign_p2pkh__(n, private_key, public_key, script_pub_key, sighash_type) + elif st["type"] == "P2SH": + script_sig = self.__sign_p2sh(n, private_key, public_key, redeem_script, sighash_type, amount, p2sh_p2wsh) + elif st["type"] == "P2WPKH": + script_sig = self.__sign_p2wpkh(n, private_key, public_key, script_pub_key, sighash_type, amount) + elif st["type"] == "P2WSH": + script_sig = self.__sign_p2wsh(n, private_key, public_key, script_pub_key, + redeem_script, sighash_type, amount) + elif st["type"] == "MULTISIG": + script_sig = self.__sign_bare_multisig__(n, private_key, public_key, script_pub_key, sighash_type) + else: + raise RuntimeError("not implemented") + + if self["format"] == "raw": + self["vIn"][n]["scriptSig"] = script_sig + else: + self["vIn"][n]["scriptSig"] = script_sig.hex() + self["vIn"][n]["scriptSigOpcodes"] = decode_script(script_sig) + self["vIn"][n]["scriptSigAsm"] = decode_script(script_sig, 1) + if self.auto_commit: + self.commit() + return self + + def __sign_bare_multisig__(self, n, private_key, public_key, script_pub_key, sighash_type): + sighash = self.sig_hash(n, script_pub_key=script_pub_key, sighash_type=sighash_type) + sighash = s2rh(sighash) if isinstance(sighash, str) else sighash + sig = [sign_message(sighash, p, 0) + bytes([sighash_type]) for p in private_key] + self["vIn"][n]['signatures'] = [s if self["format"] == "raw" else s.hex() for s in sig] + return b''.join(self.__get_bare_multisig_script_sig__(self["vIn"][n]["scriptSig"], + script_pub_key, + public_key, sig, + n)) + + def __sign_pubkey__(self, n, private_key, script_pub_key, sighash_type): + sighash = self.sig_hash(n, script_pub_key=script_pub_key, sighash_type=sighash_type) + sighash = s2rh(sighash) if isinstance(sighash, str) else sighash + signature = sign_message(sighash, private_key[0], 0) + bytes([sighash_type]) + self["vIn"][n]['signatures'] = [signature, ] if self["format"] == "raw" else [signature.hex(), ] + return b''.join([bytes([len(signature)]), signature]) + + def __sign_p2pkh__(self, n, private_key, public_key, script_pub_key, sighash_type): + sighash = self.sig_hash(n, script_pub_key=script_pub_key, sighash_type=sighash_type) + sighash = s2rh(sighash) if isinstance(sighash, str) else sighash + signature = sign_message(sighash, private_key[0], 0) + bytes([sighash_type]) + self["vIn"][n]['signatures'] = [signature, ] if self["format"] == "raw" else [signature.hex(), ] + script_sig = b''.join([bytes([len(signature)]), + signature, + bytes([len(public_key[0])]), + public_key[0]]) + return script_sig + + def __sign_p2sh(self, n, private_key, public_key, redeem_script, sighash_type, amount, p2sh_p2wsh): + if not redeem_script: + if "redeemScript" in self["vIn"][n]: + redeem_script = self["vIn"][n]["redeemScript"] + else: + raise RuntimeError("no redeem script") + if isinstance(redeem_script, str): + redeem_script = bytes.fromhex(redeem_script) + rst = parse_script(redeem_script) + + if p2sh_p2wsh: + return self.__sign_p2sh_p2wsh(n, private_key, + public_key, redeem_script, sighash_type, amount) + if rst["type"] == "MULTISIG": + return self.__sign_p2sh_multisig(n, private_key, public_key, redeem_script, sighash_type) + elif rst["type"] == "P2WPKH": + return self.__sign_p2sh_p2wpkh(n, private_key, public_key, redeem_script, sighash_type, amount) + else: + return self.__sign_p2sh_custom(n, private_key, public_key, redeem_script, sighash_type, amount) + + def __sign_p2sh_multisig(self, n, private_key, public_key, redeem_script, sighash_type): + sighash = self.sig_hash(n, script_pub_key=redeem_script, sighash_type=sighash_type) + sighash = s2rh(sighash) if isinstance(sighash, str) else sighash + sig = [sign_message(sighash, p, 0) + bytes([sighash_type]) for p in private_key] + self["vIn"][n]['signatures'] = [s if self["format"] == "raw" else s.hex() for s in sig] + return b''.join(self.__get_multisig_script_sig__(self["vIn"][n]["scriptSig"], + public_key, sig, + redeem_script, + redeem_script, + n)) + + def __sign_p2sh_p2wpkh(self, n, private_key, public_key, redeem_script, sighash_type, amount): + s = [b'\x19', OP_DUP, OP_HASH160, + op_push_data(hash160(public_key[0], 0)), + OP_EQUALVERIFY, OP_CHECKSIG] + if amount is None: + try: + amount = self["vIn"][n]["value"] + except: + raise RuntimeError("no input amount") + sighash = self.sig_hash_segwit(n, amount, script_pub_key=b"".join(s), sighash_type=sighash_type) + sighash = bytes.fromhex(sighash) if isinstance(sighash, str) else sighash + signature = sign_message(sighash, private_key[0], 0) + bytes([sighash_type]) + + self["segwit"] = True + if self["format"] == "raw": + self["vIn"][n]['txInWitness'] = [signature, public_key[0]] + else: + self["vIn"][n]['txInWitness'] = [signature.hex(), public_key[0].hex()] + + self["vIn"][n]['signatures'] = [signature,] if self["format"] == "raw" else [signature.hex(),] + + return op_push_data(redeem_script) + + def __sign_p2sh_p2wsh(self, n, private_key, public_key, + redeem_script, sighash_type, amount): + rst = parse_script(redeem_script) + if rst["type"] == "MULTISIG": + return self.__sign_p2sh_p2wsh_multisig(n, private_key, public_key, + redeem_script, sighash_type, amount) + else: + raise RuntimeError("not implemented") + + def __sign_p2sh_custom(self, n, private_key, public_key, redeem_script, sighash_type, amount): + raise RuntimeError("not implemented") + return b"" + + def __sign_p2wpkh(self, n, private_key, public_key, script_pub_key, sighash_type, amount): + s = [b'\x19', OP_DUP, OP_HASH160, script_pub_key[1:], OP_EQUALVERIFY, OP_CHECKSIG] + if amount is None: + try: + amount = self["vIn"][n]["value"] + except: + raise RuntimeError("no input amount") + sighash = self.sig_hash_segwit(n, amount, script_pub_key=b"".join(s), sighash_type=sighash_type) + sighash = bytes.fromhex(sighash) if isinstance(sighash, str) else sighash + signature = sign_message(sighash, private_key[0], 0) + bytes([sighash_type]) + self["segwit"] = True + if self["format"] == "raw": + self["vIn"][n]['txInWitness'] = [signature, + public_key[0]] + else: + self["vIn"][n]['txInWitness'] = [signature.hex(), + public_key[0].hex()] + self["vIn"][n]['signatures'] = [signature,] if self["format"] == "raw" else [signature.hex(),] + return b"" + + def __sign_p2wsh(self, n, private_key, public_key, script_pub_key, redeem_script, sighash_type, amount): + self["segwit"] = True + if not redeem_script: + if "redeemScript" in self["vIn"][n]: + redeem_script = self["vIn"][n]["redeemScript"] + else: + raise RuntimeError("no redeem script") + if isinstance(redeem_script, str): + redeem_script = bytes.fromhex(redeem_script) + rst = parse_script(redeem_script) + if amount is None: + try: + amount = self["vIn"][n]["value"] + except: + raise RuntimeError("no input amount") + if rst["type"] == "MULTISIG": + return self.__sign_p2wsh_multisig(n, private_key, public_key, + script_pub_key, redeem_script, sighash_type, amount) + else: + return self.__sign_p2wsh_custom(n, private_key, public_key, + script_pub_key, redeem_script, sighash_type, amount) + + def __sign_p2wsh_multisig(self, n, private_key, public_key, script_pub_key, redeem_script, sighash_type, amount): + script_code = int_to_var_int(len(redeem_script)) + redeem_script + sighash = self.sig_hash_segwit(n, amount, script_pub_key=script_code, sighash_type=sighash_type) + sighash = bytes.fromhex(sighash) if isinstance(sighash, str) else sighash + sig = [sign_message(sighash, p, 0) + bytes([sighash_type]) for p in private_key] + self["vIn"][n]['signatures'] = [s if self["format"] == "raw" else s.hex() for s in sig] + if "txInWitness" not in self["vIn"][n]: + self["vIn"][n]["txInWitness"] = [] + witness = self.__get_multisig_script_sig__(self["vIn"][n]["txInWitness"], + public_key, sig, script_code, redeem_script, n, amount) + if self["format"] == "raw": + self["vIn"][n]['txInWitness'] = list(witness) + else: + self["vIn"][n]["txInWitness"] = list([w.hex() for w in witness]) + return b"" + + def __sign_p2wsh_custom(self, n, private_key, public_key, script_pub_key, redeem_script, sighash_type, amount): + raise RuntimeError("not implemented __sign_p2wsh_custom") + + def __sign_p2sh_p2wsh_multisig(self, n, private_key, public_key, + redeem_script, sighash_type, amount): + self["segwit"] = True + script_code = int_to_var_int(len(redeem_script)) + redeem_script + sighash = self.sig_hash_segwit(n, amount, script_pub_key=script_code, sighash_type=sighash_type) + sighash = bytes.fromhex(sighash) if isinstance(sighash, str) else sighash + sig = [sign_message(sighash, p, 0) + bytes([sighash_type]) for p in private_key] + self["vIn"][n]['signatures'] = [s if self["format"] == "raw" else s.hex() for s in sig] + if "txInWitness" not in self["vIn"][n]: + self["vIn"][n]["txInWitness"] = [] + witness = self.__get_multisig_script_sig__(self["vIn"][n]["txInWitness"], + public_key, + sig, + script_code, + redeem_script, + n, + amount) + if self["format"] == "raw": + self["vIn"][n]['txInWitness'] = list(witness) + else: + self["vIn"][n]["txInWitness"] = list([w.hex() for w in witness]) + # calculate P2SH redeem script from P2WSH redeem script + return op_push_data(b"\x00" + op_push_data(sha256(redeem_script))) + + def __get_bare_multisig_script_sig__(self, script_sig, script_pub_key, + keys, signatures, n): + sig_map = {keys[i]:signatures[i] for i in range(len(keys))} + pub_keys = get_multisig_public_keys(script_pub_key) + s = get_stream(script_sig) + o, d = read_opcode(s) + while o: + o, d = read_opcode(s) + if d and is_valid_signature_encoding(d): + for i in range(4): + sighash = self.sig_hash(n, script_pub_key=script_pub_key, sighash_type=d[-1]) + sighash = s2rh(sighash) if isinstance(sighash, str) else sighash + pk = public_key_recovery(d[:-1], sighash, i, hex=0) + if pk in pub_keys: + sig_map[pk] = d + break + # recreate script sig + r = [OP_0] + for k in pub_keys: + try: + r.append(op_push_data(sig_map[k])) + except: + pass + return r + + def __get_multisig_script_sig__(self, script_sig, + keys, signatures, + script_code, + redeem_script, + n, amount=None): + sig_map = {keys[i]:signatures[i] for i in range(len(keys))} + pub_keys = get_multisig_public_keys(redeem_script) + p2wsh = True if isinstance(script_sig, list) else False + if not p2wsh: + s = get_stream(script_sig) + o, d = read_opcode(s) + while o: + o, d = read_opcode(s) + if d and is_valid_signature_encoding(d): + for i in range(4): + sighash = self.sig_hash(n, script_pub_key=script_code, sighash_type=d[-1]) + sighash = s2rh(sighash) if isinstance(sighash, str) else sighash + pk = public_key_recovery(d[:-1], sighash, i, hex=0) + if pk in pub_keys: + sig_map[pk] = d + break + # recreate script sig + r = [OP_0] + for k in pub_keys: + try: + r.append(op_push_data(sig_map[k])) + except: + pass + r += [op_push_data(redeem_script)] + else: + for w in script_sig: + if isinstance(w, str): + w = bytes.fromhex(w) + if w and is_valid_signature_encoding(w): + d = w[:-1] + for i in range(4): + sighash = self.sig_hash_segwit(n, amount, + script_pub_key=script_code, + sighash_type=w[-1]) + pk = public_key_recovery(d, sighash, i, hex=0) + if pk in pub_keys: + sig_map[pk] = w + break + r = [b""] + for k in pub_keys: + try: + r.append(sig_map[k]) + except: + pass + r += [redeem_script] + return r + + def sig_hash(self, n, script_pub_key=None, sighash_type=SIGHASH_ALL, preimage=False): + try: + self["vIn"][n] + except: + raise Exception("sig_hash error, input not exist") + + # check script_pub_key for input + if script_pub_key is not None: + script_code = script_pub_key + else: + if "scriptPubKey" not in self["vIn"][n]: + raise Exception("sig_hash error, scriptPubKey required") + script_code = self["vIn"][n]["scriptPubKey"] + if isinstance(script_code, str): + script_code = bytes.fromhex(script_code) + if not isinstance(script_code,bytes): + raise Exception("sig_hash error, script_code type error") + + # remove opcode separators + if ((sighash_type & 31) == SIGHASH_SINGLE) and (n >= (len(self["vOut"]))): + if self["format"] == "raw": + return b'\x01%s' % (b'\x00' * 31) + return rh2s(b'\x01%s' % (b'\x00' * 31)) + + script_code = delete_from_script(script_code, BYTE_OPCODE["OP_CODESEPARATOR"]) + pm = bytearray() + pm += b"%s%s" % (pack(' n and (sighash_type & 31) == SIGHASH_SINGLE: + continue + if (sighash_type & 31) == SIGHASH_SINGLE and (n != i): + pm += b"%s%s" % (b'\xff' * 8, b'\x00') + else: + pm += b"%s%s%s" % (self["vOut"][i]["value"].to_bytes(8, 'little'), + int_to_var_int(len(script_pub_key)), + script_pub_key) + pm += b"%s%s" % (self["lockTime"].to_bytes(4, 'little'), pack(b"